From 4ce65f36212e7a97b902958ad6c56611091c83f5 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Tue, 17 Nov 2009 05:39:01 +0000 Subject: [PATCH] Resolved issue: NETTY-251 Add support for HTTP trailing headers * Modified HttpMessageDecoder to generate HttpChunkTrailer with trailing headers * Trailing headers are not merged into HttpMessage anymore for correctness --- .../http/snoop/HttpRequestHandler.java | 13 +++++ .../codec/http/HttpMessageDecoder.java | 53 ++++++++----------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java b/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java index ec75b059d0..31ae94ff00 100644 --- a/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java +++ b/src/main/java/org/jboss/netty/example/http/snoop/HttpRequestHandler.java @@ -34,6 +34,7 @@ import org.jboss.netty.handler.codec.http.CookieDecoder; import org.jboss.netty.handler.codec.http.CookieEncoder; import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpChunk; +import org.jboss.netty.handler.codec.http.HttpChunkTrailer; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponse; @@ -106,6 +107,18 @@ public class HttpRequestHandler extends SimpleChannelUpstreamHandler { if (chunk.isLast()) { readingChunks = false; responseContent.append("END OF CONTENT\r\n"); + + HttpChunkTrailer trailer = (HttpChunkTrailer) chunk; + if (!trailer.getHeaderNames().isEmpty()) { + responseContent.append("\r\n"); + for (String name: trailer.getHeaderNames()) { + for (String value: trailer.getHeaders(name)) { + responseContent.append("TRAILING HEADER: " + name + " = " + value + "\r\n"); + } + } + responseContent.append("\r\n"); + } + writeResponse(e); } else { responseContent.append("CHUNK: " + chunk.getContent().toString("UTF-8") + "\r\n"); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java index eac3fae941..a3fcf536e7 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java @@ -15,7 +15,6 @@ */ package org.jboss.netty.handler.codec.http; -import java.util.ArrayList; import java.util.List; import org.jboss.netty.buffer.ChannelBuffer; @@ -328,14 +327,14 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder names = new ArrayList(4); - List values = new ArrayList(4); + HttpChunkTrailer trailer = new DefaultHttpChunkTrailer(); do { char firstChar = line.charAt(0); if (lastHeader != null && (firstChar == ' ' || firstChar == '\t')) { - int lastPos = values.size() - 1; - String newString = values.get(lastPos) + line.trim(); - values.set(lastPos, newString); + List current = trailer.getHeaders(lastHeader); + if (current.size() != 0) { + int lastPos = current.size() - 1; + String newString = current.get(lastPos) + line.trim(); + current.set(lastPos, newString); + } else { + // Content-Length, Transfer-Encoding, or Trailer + } } else { String[] header = splitHeader(line); - names.add(header[0]); - values.add(header[1]); - lastHeader = header[0]; + String name = header[0]; + if (!name.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH) && + !name.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING) && + !name.equalsIgnoreCase(HttpHeaders.Names.TRAILER)) { + trailer.addHeader(name, header[1]); + } + lastHeader = name; } line = readHeader(buffer); } while (line.length() != 0); - // Merge the trailing headers into the message. - HttpMessage message = this.message; - for (int i = 0; i < names.size(); i ++) { - String name = names.get(i); - String value = values.get(i); - - // Discard the prohibited headers. - if (name.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH)) { - continue; - } - if (name.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING)) { - continue; - } - if (name.equalsIgnoreCase(HttpHeaders.Names.TRAILER)) { - continue; - } - - message.addHeader(name, value); - } + return trailer; } + + return HttpChunk.LAST_CHUNK; } private String readHeader(ChannelBuffer buffer) throws TooLongFrameException {