Fixed issue: NETTY-359 Missing support for HTTP 'Expect: 100-continue' header.

* Added HttpHeaders.is/set100ContinueExpected()
* HttpMessageDecoder converts unchunked messages into chunked ones if Expect: 100-continue header exists.
This commit is contained in:
Trustin Lee 2010-10-17 18:34:03 +00:00
parent 13a1b73cd1
commit 04430cd6d3
2 changed files with 51 additions and 2 deletions

View File

@ -674,6 +674,53 @@ public class HttpHeaders {
message.setHeader(Names.HOST, value);
}
/**
* Returns {@code true} if and only if the specified message contains the
* {@code "Expect: 100-continue"} header.
*/
public static boolean is100ContinueExpected(HttpMessage message) {
// In most cases, there will be one or zero 'Expect' header.
String value = message.getHeader(Names.EXPECT);
if (value == null) {
return false;
}
if (Values.CONTINUE.equalsIgnoreCase(value)) {
return true;
}
// Multiple 'Expect' headers. Search through them.
for (String v: message.getHeaders(Names.EXPECT)) {
if (Values.CONTINUE.equalsIgnoreCase(v)) {
return true;
}
}
return false;
}
/**
* Sets the {@code "Expect: 100-continue"} header to the specified message.
* If there is any existing {@code "Expect"} header, they are replaced with
* the new one.
*/
public static void set100ContinueExpected(HttpMessage message) {
set100ContinueExpected(message, true);
}
/**
* Sets or removes the {@code "Expect: 100-continue"} header to / from the
* specified message. If the specified {@code value} is {@code true},
* the {@code "Expect: 100-continue"} header is set and all other previous
* {@code "Expect"} headers are removed. Otherwise, all {@code "Expect"}
* headers are removed completely.
*/
public static void set100ContinueExpected(HttpMessage message, boolean set) {
if (set) {
message.setHeader(Names.EXPECT, Values.CONTINUE);
} else {
message.removeHeader(Names.EXPECT);
}
}
private static final int BUCKET_SIZE = 17;
private static int hash(String name) {

View File

@ -221,7 +221,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
switch (nextState) {
case READ_FIXED_LENGTH_CONTENT:
if (contentLength > maxChunkSize) {
if (contentLength > maxChunkSize || HttpHeaders.is100ContinueExpected(message)) {
// Generate HttpMessage first. HttpChunks will follow.
checkpoint(State.READ_FIXED_LENGTH_CONTENT_AS_CHUNKS);
message.setChunked(true);
@ -232,13 +232,15 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
}
break;
case READ_VARIABLE_LENGTH_CONTENT:
if (buffer.readableBytes() > maxChunkSize) {
if (buffer.readableBytes() > maxChunkSize || HttpHeaders.is100ContinueExpected(message)) {
// Generate HttpMessage first. HttpChunks will follow.
checkpoint(State.READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS);
message.setChunked(true);
return message;
}
break;
default:
throw new IllegalStateException("Unexpected state: " + nextState);
}
}
// We return null here, this forces decode to be called again where we will decode the content