Better white space handling in HTTP
This commit is contained in:
parent
0198da7b6c
commit
9cdc4a959e
@ -58,24 +58,33 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
* @apiviz.exclude
|
* @apiviz.exclude
|
||||||
*/
|
*/
|
||||||
protected enum State {
|
protected enum State {
|
||||||
|
SKIP_CONTROL_CHARS,
|
||||||
READ_INITIAL,
|
READ_INITIAL,
|
||||||
READ_HEADER,
|
READ_HEADER,
|
||||||
READ_CONTENT,
|
READ_CONTENT,
|
||||||
READ_FIXED_LENGTH_CONTENT,
|
READ_FIXED_LENGTH_CONTENT,
|
||||||
READ_CHUNK_SIZE,
|
READ_CHUNK_SIZE,
|
||||||
READ_CHUNKED_CONTENT,
|
READ_CHUNKED_CONTENT,
|
||||||
READ_CRLF,;
|
READ_CRLF;
|
||||||
}
|
}
|
||||||
|
|
||||||
private State nextState;
|
private State nextState;
|
||||||
|
|
||||||
protected HttpMessageDecoder() {
|
protected HttpMessageDecoder() {
|
||||||
super(State.READ_INITIAL);
|
super(State.SKIP_CONTROL_CHARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
|
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
case SKIP_CONTROL_CHARS: {
|
||||||
|
try {
|
||||||
|
skipControlCharacters(buffer);
|
||||||
|
checkpoint(State.READ_INITIAL);
|
||||||
|
} finally {
|
||||||
|
checkpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
case READ_INITIAL: {
|
case READ_INITIAL: {
|
||||||
readInitial(buffer);
|
readInitial(buffer);
|
||||||
}
|
}
|
||||||
@ -144,10 +153,21 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
message.setContent(content);
|
message.setContent(content);
|
||||||
content = null;
|
content = null;
|
||||||
nextState = null;
|
nextState = null;
|
||||||
checkpoint(State.READ_INITIAL);
|
checkpoint(State.SKIP_CONTROL_CHARS);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void skipControlCharacters(ChannelBuffer buffer) {
|
||||||
|
for (;;) {
|
||||||
|
char c = (char) buffer.readUnsignedByte();
|
||||||
|
if (!Character.isISOControl(c) &&
|
||||||
|
!Character.isWhitespace(c)) {
|
||||||
|
buffer.readerIndex(buffer.readerIndex() - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void readChunkedContent(Channel channel, ChannelBuffer buffer) {
|
private void readChunkedContent(Channel channel, ChannelBuffer buffer) {
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
content = ChannelBuffers.dynamicBuffer(
|
content = ChannelBuffers.dynamicBuffer(
|
||||||
|
@ -125,8 +125,9 @@ public class HttpMethod implements Comparable<HttpMethod> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < name.length(); i ++) {
|
for (int i = 0; i < name.length(); i ++) {
|
||||||
if (Character.isISOControl(name.charAt(i))) {
|
if (Character.isISOControl(name.charAt(i)) ||
|
||||||
throw new IllegalArgumentException("control character in name");
|
Character.isWhitespace(name.charAt(i))) {
|
||||||
|
throw new IllegalArgumentException("invalid character in name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +95,9 @@ public class HttpVersion implements Comparable<HttpVersion> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < protocolName.length(); i ++) {
|
for (int i = 0; i < protocolName.length(); i ++) {
|
||||||
if (Character.isISOControl(protocolName.charAt(i))) {
|
if (Character.isISOControl(protocolName.charAt(i)) ||
|
||||||
throw new IllegalArgumentException("control character in protocolName");
|
Character.isWhitespace(protocolName.charAt(i))) {
|
||||||
|
throw new IllegalArgumentException("invalid character in protocolName");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user