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;
|
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.List;
|
||||||
import java.util.Map.Entry;
|
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.MessageEvent;
|
||||||
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
|
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
|
||||||
import org.jboss.netty.handler.codec.frame.TooLongFrameException;
|
import org.jboss.netty.handler.codec.frame.TooLongFrameException;
|
||||||
|
import org.jboss.netty.util.CharsetUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ChannelHandler} that aggregates an {@link HttpMessage}
|
* 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 {
|
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 final int maxContentLength;
|
||||||
private HttpMessage currentMessage;
|
private HttpMessage currentMessage;
|
||||||
|
|
||||||
@ -82,6 +89,16 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler {
|
|||||||
|
|
||||||
if (msg instanceof HttpMessage) {
|
if (msg instanceof HttpMessage) {
|
||||||
HttpMessage m = (HttpMessage) msg;
|
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()) {
|
if (m.isChunked()) {
|
||||||
// A chunked message - remove 'Transfer-Encoding' header,
|
// A chunked message - remove 'Transfer-Encoding' header,
|
||||||
// initialize the cumulative buffer, and wait for incoming chunks.
|
// initialize the cumulative buffer, and wait for incoming chunks.
|
||||||
@ -111,6 +128,10 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler {
|
|||||||
ChannelBuffer content = currentMessage.getContent();
|
ChannelBuffer content = currentMessage.getContent();
|
||||||
|
|
||||||
if (content.readableBytes() > maxContentLength - chunk.getContent().readableBytes()) {
|
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(
|
throw new TooLongFrameException(
|
||||||
"HTTP content length exceeded " + maxContentLength +
|
"HTTP content length exceeded " + maxContentLength +
|
||||||
" bytes.");
|
" bytes.");
|
||||||
|
@ -679,6 +679,16 @@ public class HttpHeaders {
|
|||||||
* {@code "Expect: 100-continue"} header.
|
* {@code "Expect: 100-continue"} header.
|
||||||
*/
|
*/
|
||||||
public static boolean is100ContinueExpected(HttpMessage message) {
|
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.
|
// In most cases, there will be one or zero 'Expect' header.
|
||||||
String value = message.getHeader(Names.EXPECT);
|
String value = message.getHeader(Names.EXPECT);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
@ -536,6 +536,10 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
|
|
||||||
// Abort decoding if the header part is too large.
|
// Abort decoding if the header part is too large.
|
||||||
if (headerSize >= maxHeaderSize) {
|
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(
|
throw new TooLongFrameException(
|
||||||
"HTTP header is larger than " +
|
"HTTP header is larger than " +
|
||||||
maxHeaderSize + " bytes.");
|
maxHeaderSize + " bytes.");
|
||||||
@ -581,6 +585,10 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (lineLength >= maxLineLength) {
|
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(
|
throw new TooLongFrameException(
|
||||||
"An HTTP line is larger than " + maxLineLength +
|
"An HTTP line is larger than " + maxLineLength +
|
||||||
" bytes.");
|
" bytes.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user