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:
parent
13a1b73cd1
commit
04430cd6d3
@ -674,6 +674,53 @@ public class HttpHeaders {
|
|||||||
message.setHeader(Names.HOST, value);
|
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 final int BUCKET_SIZE = 17;
|
||||||
|
|
||||||
private static int hash(String name) {
|
private static int hash(String name) {
|
||||||
|
@ -221,7 +221,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
|
|
||||||
switch (nextState) {
|
switch (nextState) {
|
||||||
case READ_FIXED_LENGTH_CONTENT:
|
case READ_FIXED_LENGTH_CONTENT:
|
||||||
if (contentLength > maxChunkSize) {
|
if (contentLength > maxChunkSize || HttpHeaders.is100ContinueExpected(message)) {
|
||||||
// Generate HttpMessage first. HttpChunks will follow.
|
// Generate HttpMessage first. HttpChunks will follow.
|
||||||
checkpoint(State.READ_FIXED_LENGTH_CONTENT_AS_CHUNKS);
|
checkpoint(State.READ_FIXED_LENGTH_CONTENT_AS_CHUNKS);
|
||||||
message.setChunked(true);
|
message.setChunked(true);
|
||||||
@ -232,13 +232,15 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READ_VARIABLE_LENGTH_CONTENT:
|
case READ_VARIABLE_LENGTH_CONTENT:
|
||||||
if (buffer.readableBytes() > maxChunkSize) {
|
if (buffer.readableBytes() > maxChunkSize || HttpHeaders.is100ContinueExpected(message)) {
|
||||||
// Generate HttpMessage first. HttpChunks will follow.
|
// Generate HttpMessage first. HttpChunks will follow.
|
||||||
checkpoint(State.READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS);
|
checkpoint(State.READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS);
|
||||||
message.setChunked(true);
|
message.setChunked(true);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
break;
|
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
|
// We return null here, this forces decode to be called again where we will decode the content
|
||||||
|
Loading…
x
Reference in New Issue
Block a user