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
This commit is contained in:
parent
e81d0e5414
commit
4ce65f3621
@ -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.CookieEncoder;
|
||||||
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||||
import org.jboss.netty.handler.codec.http.HttpChunk;
|
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.HttpHeaders;
|
||||||
import org.jboss.netty.handler.codec.http.HttpRequest;
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
@ -106,6 +107,18 @@ public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
|
|||||||
if (chunk.isLast()) {
|
if (chunk.isLast()) {
|
||||||
readingChunks = false;
|
readingChunks = false;
|
||||||
responseContent.append("END OF CONTENT\r\n");
|
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);
|
writeResponse(e);
|
||||||
} else {
|
} else {
|
||||||
responseContent.append("CHUNK: " + chunk.getContent().toString("UTF-8") + "\r\n");
|
responseContent.append("CHUNK: " + chunk.getContent().toString("UTF-8") + "\r\n");
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.jboss.netty.handler.codec.http;
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
@ -328,14 +327,14 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case READ_CHUNK_FOOTER: {
|
case READ_CHUNK_FOOTER: {
|
||||||
readTrailingHeaders(buffer);
|
HttpChunkTrailer trailer = readTrailingHeaders(buffer);
|
||||||
if (maxChunkSize == 0) {
|
if (maxChunkSize == 0) {
|
||||||
// Chunked encoding disabled.
|
// Chunked encoding disabled.
|
||||||
return reset();
|
return reset();
|
||||||
} else {
|
} else {
|
||||||
reset();
|
reset();
|
||||||
// The last chunk, which is empty
|
// The last chunk, which is empty
|
||||||
return HttpChunk.LAST_CHUNK;
|
return trailer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -434,49 +433,41 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
return nextState;
|
return nextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readTrailingHeaders(ChannelBuffer buffer) throws TooLongFrameException {
|
private HttpChunkTrailer readTrailingHeaders(ChannelBuffer buffer) throws TooLongFrameException {
|
||||||
headerSize = 0;
|
headerSize = 0;
|
||||||
String line = readHeader(buffer);
|
String line = readHeader(buffer);
|
||||||
String lastHeader = null;
|
String lastHeader = null;
|
||||||
if (line.length() != 0) {
|
if (line.length() != 0) {
|
||||||
List<String> names = new ArrayList<String>(4);
|
HttpChunkTrailer trailer = new DefaultHttpChunkTrailer();
|
||||||
List<String> values = new ArrayList<String>(4);
|
|
||||||
do {
|
do {
|
||||||
char firstChar = line.charAt(0);
|
char firstChar = line.charAt(0);
|
||||||
if (lastHeader != null && (firstChar == ' ' || firstChar == '\t')) {
|
if (lastHeader != null && (firstChar == ' ' || firstChar == '\t')) {
|
||||||
int lastPos = values.size() - 1;
|
List<String> current = trailer.getHeaders(lastHeader);
|
||||||
String newString = values.get(lastPos) + line.trim();
|
if (current.size() != 0) {
|
||||||
values.set(lastPos, newString);
|
int lastPos = current.size() - 1;
|
||||||
|
String newString = current.get(lastPos) + line.trim();
|
||||||
|
current.set(lastPos, newString);
|
||||||
|
} else {
|
||||||
|
// Content-Length, Transfer-Encoding, or Trailer
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
String[] header = splitHeader(line);
|
String[] header = splitHeader(line);
|
||||||
names.add(header[0]);
|
String name = header[0];
|
||||||
values.add(header[1]);
|
if (!name.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH) &&
|
||||||
lastHeader = header[0];
|
!name.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING) &&
|
||||||
|
!name.equalsIgnoreCase(HttpHeaders.Names.TRAILER)) {
|
||||||
|
trailer.addHeader(name, header[1]);
|
||||||
|
}
|
||||||
|
lastHeader = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = readHeader(buffer);
|
line = readHeader(buffer);
|
||||||
} while (line.length() != 0);
|
} while (line.length() != 0);
|
||||||
|
|
||||||
// Merge the trailing headers into the message.
|
return trailer;
|
||||||
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 HttpChunk.LAST_CHUNK;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readHeader(ChannelBuffer buffer) throws TooLongFrameException {
|
private String readHeader(ChannelBuffer buffer) throws TooLongFrameException {
|
||||||
|
Loading…
Reference in New Issue
Block a user