Fixed issue: NETTY-359 Missing support for HTTP 'Expect: 100-continue' header.
* Improved HttpHeaders.is100ContinueExpected() to conform to the RFC * HttpChunkAggregator now sends "HTTP/1.1 100 Continue" response automatically. * Added some TODO items which should be done in 4.0.
This commit is contained in:
parent
d093ed4a54
commit
57dc0b3bc8
@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.jboss.netty.handler.codec.http;
|
||||
|
||||
import static org.jboss.netty.channel.Channels.*;
|
||||
import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@ -27,6 +30,7 @@ import org.jboss.netty.channel.Channels;
|
||||
import org.jboss.netty.channel.MessageEvent;
|
||||
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
|
||||
import org.jboss.netty.handler.codec.frame.TooLongFrameException;
|
||||
import org.jboss.netty.util.CharsetUtil;
|
||||
|
||||
/**
|
||||
* A {@link ChannelHandler} that aggregates an {@link HttpMessage}
|
||||
@ -53,6 +57,9 @@ import org.jboss.netty.handler.codec.frame.TooLongFrameException;
|
||||
*/
|
||||
public class HttpChunkAggregator extends SimpleChannelUpstreamHandler {
|
||||
|
||||
private static final ChannelBuffer CONTINUE = ChannelBuffers.copiedBuffer(
|
||||
"HTTP/1.1 100 Continue\r\n\r\n", CharsetUtil.US_ASCII);
|
||||
|
||||
private final int maxContentLength;
|
||||
private HttpMessage currentMessage;
|
||||
|
||||
@ -82,6 +89,16 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler {
|
||||
|
||||
if (msg instanceof HttpMessage) {
|
||||
HttpMessage m = (HttpMessage) msg;
|
||||
|
||||
// Handle the 'Expect: 100-continue' header if necessary.
|
||||
// TODO: Respond with 413 Request Entity Too Large
|
||||
// and discard the traffic or close the connection.
|
||||
// No need to notify the upstream handlers - just log.
|
||||
// If decoding a response, just throw an exception.
|
||||
if (is100ContinueExpected(m)) {
|
||||
write(ctx, succeededFuture(ctx.getChannel()), CONTINUE.duplicate());
|
||||
}
|
||||
|
||||
if (m.isChunked()) {
|
||||
// A chunked message - remove 'Transfer-Encoding' header,
|
||||
// initialize the cumulative buffer, and wait for incoming chunks.
|
||||
@ -111,6 +128,10 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler {
|
||||
ChannelBuffer content = currentMessage.getContent();
|
||||
|
||||
if (content.readableBytes() > maxContentLength - chunk.getContent().readableBytes()) {
|
||||
// TODO: Respond with 413 Request Entity Too Large
|
||||
// and discard the traffic or close the connection.
|
||||
// No need to notify the upstream handlers - just log.
|
||||
// If decoding a response, just throw an exception.
|
||||
throw new TooLongFrameException(
|
||||
"HTTP content length exceeded " + maxContentLength +
|
||||
" bytes.");
|
||||
|
@ -679,6 +679,16 @@ public class HttpHeaders {
|
||||
* {@code "Expect: 100-continue"} header.
|
||||
*/
|
||||
public static boolean is100ContinueExpected(HttpMessage message) {
|
||||
// Expect: 100-continue is for requests only.
|
||||
if (!(message instanceof HttpRequest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It works only on HTTP/1.1 or later.
|
||||
if (message.getProtocolVersion().compareTo(HttpVersion.HTTP_1_1) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In most cases, there will be one or zero 'Expect' header.
|
||||
String value = message.getHeader(Names.EXPECT);
|
||||
if (value == null) {
|
||||
|
@ -536,6 +536,10 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
||||
|
||||
// Abort decoding if the header part is too large.
|
||||
if (headerSize >= maxHeaderSize) {
|
||||
// TODO: Respond with Bad Request and discard the traffic
|
||||
// or close the connection.
|
||||
// No need to notify the upstream handlers - just log.
|
||||
// If decoding a response, just throw an exception.
|
||||
throw new TooLongFrameException(
|
||||
"HTTP header is larger than " +
|
||||
maxHeaderSize + " bytes.");
|
||||
@ -581,6 +585,10 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
||||
}
|
||||
else {
|
||||
if (lineLength >= maxLineLength) {
|
||||
// TODO: Respond with Bad Request and discard the traffic
|
||||
// or close the connection.
|
||||
// No need to notify the upstream handlers - just log.
|
||||
// If decoding a response, just throw an exception.
|
||||
throw new TooLongFrameException(
|
||||
"An HTTP line is larger than " + maxLineLength +
|
||||
" bytes.");
|
||||
|
Loading…
Reference in New Issue
Block a user