461350 Update HttpParser IllegalCharacter handling to RFC7230

This commit is contained in:
Greg Wilkins 2015-03-05 19:54:25 +11:00
parent 213d6e1fbd
commit f4ad0dce98
2 changed files with 78 additions and 26 deletions

View File

@ -22,6 +22,7 @@ import static org.eclipse.jetty.http.HttpTokens.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.EnumSet;
import org.eclipse.jetty.util.ArrayTernaryTrie;
@ -343,42 +344,93 @@ public class HttpParser
return _state == state;
}
/* ------------------------------------------------------------------------------- */
enum CharState { ILLEGAL, CR, LF, LEGAL }
private final static CharState[] __charState;
static
{
// token = 1*tchar
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
// / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
// / DIGIT / ALPHA
// ; any VCHAR, except delimiters
// quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
// qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text
// obs-text = %x80-FF
// comment = "(" *( ctext / quoted-pair / comment ) ")"
// ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text
// quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
__charState=new CharState[256];
Arrays.fill(__charState,CharState.ILLEGAL);
__charState[LINE_FEED]=CharState.LF;
__charState[CARRIAGE_RETURN]=CharState.CR;
__charState[TAB]=CharState.LEGAL;
__charState[SPACE]=CharState.LEGAL;
__charState['!']=CharState.LEGAL;
__charState['#']=CharState.LEGAL;
__charState['$']=CharState.LEGAL;
__charState['%']=CharState.LEGAL;
__charState['&']=CharState.LEGAL;
__charState['\'']=CharState.LEGAL;
__charState['*']=CharState.LEGAL;
__charState['+']=CharState.LEGAL;
__charState['-']=CharState.LEGAL;
__charState['.']=CharState.LEGAL;
__charState['^']=CharState.LEGAL;
__charState['_']=CharState.LEGAL;
__charState['`']=CharState.LEGAL;
__charState['|']=CharState.LEGAL;
__charState['~']=CharState.LEGAL;
__charState['"']=CharState.LEGAL;
__charState['\\']=CharState.LEGAL;
__charState['(']=CharState.LEGAL;
__charState[')']=CharState.LEGAL;
Arrays.fill(__charState,0x21,0x27+1,CharState.LEGAL);
Arrays.fill(__charState,0x2A,0x5B+1,CharState.LEGAL);
Arrays.fill(__charState,0x5D,0x7E+1,CharState.LEGAL);
Arrays.fill(__charState,0x80,0xFF+1,CharState.LEGAL);
}
/* ------------------------------------------------------------------------------- */
private byte next(ByteBuffer buffer)
{
byte ch = buffer.get();
if (_cr)
CharState s = __charState[0xff & ch];
switch(s)
{
if (ch!=LINE_FEED)
throw new BadMessageException("Bad EOL");
_cr=false;
return ch;
}
case ILLEGAL:
throw new IllegalCharacterException(_state,ch,buffer);
case LF:
_cr=false;
break;
case CR:
if (_cr)
throw new BadMessageException("Bad EOL");
if (ch>=0 && ch<SPACE)
{
if (ch==CARRIAGE_RETURN)
{
_cr=true;
if (buffer.hasRemaining())
{
if(_maxHeaderBytes>0 && _state.ordinal()<State.END.ordinal())
_headerBytes++;
ch=buffer.get();
if (ch!=LINE_FEED)
throw new BadMessageException("Bad EOL");
return next(buffer);
}
else
{
_cr=true;
// Can return 0 here to indicate the need for more characters,
// because a real 0 in the buffer would cause a BadMessage below
return 0;
}
}
// Only LF or TAB acceptable special characters
else if (!(ch==LINE_FEED || ch==TAB))
throw new IllegalCharacterException(_state,ch,buffer);
// Can return 0 here to indicate the need for more characters,
// because a real 0 in the buffer would cause a BadMessage below
return 0;
case LEGAL:
if (_cr)
throw new BadMessageException("Bad EOL");
}
return ch;

View File

@ -188,8 +188,8 @@ public class ConnectionOpenCloseTest extends AbstractHttpTest
server.start();
final AtomicInteger callbacks = new AtomicInteger();
final CountDownLatch openLatch = new CountDownLatch(1);
final CountDownLatch closeLatch = new CountDownLatch(1);
final CountDownLatch openLatch = new CountDownLatch(2);
final CountDownLatch closeLatch = new CountDownLatch(2);
connector.addBean(new Connection.Listener.Adapter()
{
@Override