#1792 Accept ISO-8859-1 in Response reason
This commit is contained in:
parent
7be350370c
commit
ca750cf582
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.http.HttpTokens.EndOfContent;
|
|||
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||
import org.eclipse.jetty.util.ArrayTrie;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Trie;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
|
@ -618,8 +619,8 @@ public class HttpParser
|
|||
while (_state.ordinal()<State.HEADER.ordinal() && buffer.hasRemaining() && !handle)
|
||||
{
|
||||
// process each character
|
||||
byte ch=next(buffer);
|
||||
if (ch==0)
|
||||
byte b=next(buffer);
|
||||
if (b==0)
|
||||
break;
|
||||
|
||||
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
|
||||
|
@ -642,7 +643,7 @@ public class HttpParser
|
|||
switch (_state)
|
||||
{
|
||||
case METHOD:
|
||||
if (ch == SPACE)
|
||||
if (b == SPACE)
|
||||
{
|
||||
_length=_string.length();
|
||||
_methodString=takeString();
|
||||
|
@ -651,19 +652,19 @@ public class HttpParser
|
|||
_methodString=legacyString(_methodString,method.asString());
|
||||
setState(State.SPACE1);
|
||||
}
|
||||
else if (ch < SPACE)
|
||||
else if (b < SPACE)
|
||||
{
|
||||
if (ch==LINE_FEED)
|
||||
if (b==LINE_FEED)
|
||||
throw new BadMessageException("No URI");
|
||||
else
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
throw new IllegalCharacterException(_state,b,buffer);
|
||||
}
|
||||
else
|
||||
_string.append((char)ch);
|
||||
_string.append((char)b);
|
||||
break;
|
||||
|
||||
case RESPONSE_VERSION:
|
||||
if (ch == HttpTokens.SPACE)
|
||||
if (b == HttpTokens.SPACE)
|
||||
{
|
||||
_length=_string.length();
|
||||
String version=takeString();
|
||||
|
@ -672,19 +673,19 @@ public class HttpParser
|
|||
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Unknown Version");
|
||||
setState(State.SPACE1);
|
||||
}
|
||||
else if (ch < HttpTokens.SPACE)
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
else if (b < HttpTokens.SPACE)
|
||||
throw new IllegalCharacterException(_state,b,buffer);
|
||||
else
|
||||
_string.append((char)ch);
|
||||
_string.append((char)b);
|
||||
break;
|
||||
|
||||
case SPACE1:
|
||||
if (ch > HttpTokens.SPACE || ch<0)
|
||||
if (b > HttpTokens.SPACE || b<0)
|
||||
{
|
||||
if (_responseHandler!=null)
|
||||
{
|
||||
setState(State.STATUS);
|
||||
setResponseStatus(ch-'0');
|
||||
setResponseStatus(b-'0');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -712,25 +713,25 @@ public class HttpParser
|
|||
buffer.position(i-buffer.arrayOffset());
|
||||
}
|
||||
else
|
||||
_uri.append(ch);
|
||||
_uri.append(b);
|
||||
}
|
||||
}
|
||||
else if (ch < HttpTokens.SPACE)
|
||||
else if (b < HttpTokens.SPACE)
|
||||
{
|
||||
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,_requestHandler!=null?"No URI":"No Status");
|
||||
}
|
||||
break;
|
||||
|
||||
case STATUS:
|
||||
if (ch == HttpTokens.SPACE)
|
||||
if (b == HttpTokens.SPACE)
|
||||
{
|
||||
setState(State.SPACE2);
|
||||
}
|
||||
else if (ch>='0' && ch<='9')
|
||||
else if (b>='0' && b<='9')
|
||||
{
|
||||
_responseStatus=_responseStatus*10+(ch-'0');
|
||||
_responseStatus=_responseStatus*10+(b-'0');
|
||||
}
|
||||
else if (ch < HttpTokens.SPACE && ch>=0)
|
||||
else if (b < HttpTokens.SPACE && b>=0)
|
||||
{
|
||||
setState(State.HEADER);
|
||||
handle=_responseHandler.startResponse(_version, _responseStatus, null)||handle;
|
||||
|
@ -742,11 +743,11 @@ public class HttpParser
|
|||
break;
|
||||
|
||||
case URI:
|
||||
if (ch == HttpTokens.SPACE)
|
||||
if (b == HttpTokens.SPACE)
|
||||
{
|
||||
setState(State.SPACE2);
|
||||
}
|
||||
else if (ch < HttpTokens.SPACE && ch>=0)
|
||||
else if (b < HttpTokens.SPACE && b>=0)
|
||||
{
|
||||
// HTTP/0.9
|
||||
if (complianceViolation(RFC7230,"HTTP/0.9"))
|
||||
|
@ -758,15 +759,15 @@ public class HttpParser
|
|||
}
|
||||
else
|
||||
{
|
||||
_uri.append(ch);
|
||||
_uri.append(b);
|
||||
}
|
||||
break;
|
||||
|
||||
case SPACE2:
|
||||
if (ch > HttpTokens.SPACE)
|
||||
if (b > HttpTokens.SPACE)
|
||||
{
|
||||
_string.setLength(0);
|
||||
_string.append((char)ch);
|
||||
_string.append((char)b);
|
||||
if (_responseHandler!=null)
|
||||
{
|
||||
_length=1;
|
||||
|
@ -806,7 +807,7 @@ public class HttpParser
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (ch == HttpTokens.LINE_FEED)
|
||||
else if (b == HttpTokens.LINE_FEED)
|
||||
{
|
||||
if (_responseHandler!=null)
|
||||
{
|
||||
|
@ -825,12 +826,12 @@ public class HttpParser
|
|||
handle= handleHeaderContentMessage() || handle;
|
||||
}
|
||||
}
|
||||
else if (ch<0)
|
||||
else if (b<0)
|
||||
throw new BadMessageException();
|
||||
break;
|
||||
|
||||
case REQUEST_VERSION:
|
||||
if (ch == HttpTokens.LINE_FEED)
|
||||
if (b == HttpTokens.LINE_FEED)
|
||||
{
|
||||
if (_version==null)
|
||||
{
|
||||
|
@ -852,25 +853,25 @@ public class HttpParser
|
|||
handle=_requestHandler.startRequest(_methodString,_uri.toString(), _version)||handle;
|
||||
continue;
|
||||
}
|
||||
else if (ch>=HttpTokens.SPACE)
|
||||
_string.append((char)ch);
|
||||
else if (b>=HttpTokens.SPACE)
|
||||
_string.append((char)b);
|
||||
else
|
||||
throw new BadMessageException();
|
||||
|
||||
break;
|
||||
|
||||
case REASON:
|
||||
if (ch == HttpTokens.LINE_FEED)
|
||||
if (b == HttpTokens.LINE_FEED)
|
||||
{
|
||||
String reason=takeString();
|
||||
setState(State.HEADER);
|
||||
handle=_responseHandler.startResponse(_version, _responseStatus, reason)||handle;
|
||||
continue;
|
||||
}
|
||||
else if (ch>=HttpTokens.SPACE)
|
||||
else if (b>=HttpTokens.SPACE || ((b<0) && (b>=-96)))
|
||||
{
|
||||
_string.append((char)ch);
|
||||
if (ch!=' '&&ch!='\t')
|
||||
_string.append((char)(0xff&b));
|
||||
if (b!=' '&&b!='\t')
|
||||
_length=_string.length();
|
||||
}
|
||||
else
|
||||
|
@ -1008,8 +1009,8 @@ public class HttpParser
|
|||
while ((_state==State.HEADER || _state==State.TRAILER) && buffer.hasRemaining())
|
||||
{
|
||||
// process each character
|
||||
byte ch=next(buffer);
|
||||
if (ch==0)
|
||||
byte b=next(buffer);
|
||||
if (b==0)
|
||||
break;
|
||||
|
||||
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
|
||||
|
@ -1024,7 +1025,7 @@ public class HttpParser
|
|||
switch (_fieldState)
|
||||
{
|
||||
case FIELD:
|
||||
switch(ch)
|
||||
switch(b)
|
||||
{
|
||||
case HttpTokens.COLON:
|
||||
case HttpTokens.SPACE:
|
||||
|
@ -1127,7 +1128,7 @@ public class HttpParser
|
|||
default:
|
||||
{
|
||||
// now handle the ch
|
||||
if (ch<HttpTokens.SPACE)
|
||||
if (b<HttpTokens.SPACE)
|
||||
throw new BadMessageException();
|
||||
|
||||
// process previous header
|
||||
|
@ -1185,15 +1186,15 @@ public class HttpParser
|
|||
{
|
||||
// Header and value
|
||||
int pos=buffer.position()+n.length()+v.length()+1;
|
||||
byte b=buffer.get(pos);
|
||||
byte peek=buffer.get(pos);
|
||||
|
||||
if (b==HttpTokens.CARRIAGE_RETURN || b==HttpTokens.LINE_FEED)
|
||||
if (peek==HttpTokens.CARRIAGE_RETURN || peek==HttpTokens.LINE_FEED)
|
||||
{
|
||||
_field=field;
|
||||
_valueString=v;
|
||||
setState(FieldState.IN_VALUE);
|
||||
|
||||
if (b==HttpTokens.CARRIAGE_RETURN)
|
||||
if (peek==HttpTokens.CARRIAGE_RETURN)
|
||||
{
|
||||
_cr=true;
|
||||
buffer.position(pos+1);
|
||||
|
@ -1216,7 +1217,7 @@ public class HttpParser
|
|||
// New header
|
||||
setState(FieldState.IN_NAME);
|
||||
_string.setLength(0);
|
||||
_string.append((char)ch);
|
||||
_string.append((char)b);
|
||||
_length=1;
|
||||
|
||||
}
|
||||
|
@ -1224,7 +1225,7 @@ public class HttpParser
|
|||
break;
|
||||
|
||||
case IN_NAME:
|
||||
if (ch==HttpTokens.COLON)
|
||||
if (b==HttpTokens.COLON)
|
||||
{
|
||||
if (_headerString==null)
|
||||
{
|
||||
|
@ -1237,7 +1238,7 @@ public class HttpParser
|
|||
break;
|
||||
}
|
||||
|
||||
if (ch>HttpTokens.SPACE)
|
||||
if (b>HttpTokens.SPACE)
|
||||
{
|
||||
if (_header!=null)
|
||||
{
|
||||
|
@ -1246,13 +1247,13 @@ public class HttpParser
|
|||
_headerString=null;
|
||||
}
|
||||
|
||||
_string.append((char)ch);
|
||||
if (ch>HttpTokens.SPACE)
|
||||
_string.append((char)b);
|
||||
if (b>HttpTokens.SPACE)
|
||||
_length=_string.length();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch==HttpTokens.LINE_FEED && !complianceViolation(RFC7230,"name only header"))
|
||||
if (b==HttpTokens.LINE_FEED && !complianceViolation(RFC7230,"name only header"))
|
||||
{
|
||||
if (_headerString==null)
|
||||
{
|
||||
|
@ -1268,21 +1269,21 @@ public class HttpParser
|
|||
break;
|
||||
}
|
||||
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
throw new IllegalCharacterException(_state,b,buffer);
|
||||
|
||||
case VALUE:
|
||||
if (ch>HttpTokens.SPACE || ch<0)
|
||||
if (b>HttpTokens.SPACE || b<0)
|
||||
{
|
||||
_string.append((char)(0xff&ch));
|
||||
_string.append((char)(0xff&b));
|
||||
_length=_string.length();
|
||||
setState(FieldState.IN_VALUE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch==HttpTokens.SPACE || ch==HttpTokens.TAB)
|
||||
if (b==HttpTokens.SPACE || b==HttpTokens.TAB)
|
||||
break;
|
||||
|
||||
if (ch==HttpTokens.LINE_FEED)
|
||||
if (b==HttpTokens.LINE_FEED)
|
||||
{
|
||||
_value=null;
|
||||
_string.setLength(0);
|
||||
|
@ -1292,10 +1293,10 @@ public class HttpParser
|
|||
setState(FieldState.FIELD);
|
||||
break;
|
||||
}
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
throw new IllegalCharacterException(_state,b,buffer);
|
||||
|
||||
case IN_VALUE:
|
||||
if (ch>=HttpTokens.SPACE || ch<0 || ch==HttpTokens.TAB)
|
||||
if (b>=HttpTokens.SPACE || b<0 || b==HttpTokens.TAB)
|
||||
{
|
||||
if (_valueString!=null)
|
||||
{
|
||||
|
@ -1303,13 +1304,13 @@ public class HttpParser
|
|||
_valueString=null;
|
||||
_field=null;
|
||||
}
|
||||
_string.append((char)(0xff&ch));
|
||||
if (ch>HttpTokens.SPACE || ch<0)
|
||||
_string.append((char)(0xff&b));
|
||||
if (b>HttpTokens.SPACE || b<0)
|
||||
_length=_string.length();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch==HttpTokens.LINE_FEED)
|
||||
if (b==HttpTokens.LINE_FEED)
|
||||
{
|
||||
if (_length > 0)
|
||||
{
|
||||
|
@ -1321,7 +1322,7 @@ public class HttpParser
|
|||
break;
|
||||
}
|
||||
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
throw new IllegalCharacterException(_state,b,buffer);
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(_state.toString());
|
||||
|
|
|
@ -155,7 +155,7 @@ public class HttpGeneratorServerTest
|
|||
assertEquals(HttpGenerator.Result.NEED_INFO, result);
|
||||
assertEquals(HttpGenerator.State.START, gen.getState());
|
||||
|
||||
MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 10);
|
||||
MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, "ØÆ", new HttpFields(), 10);
|
||||
info.getFields().add("Content-Type", "test/data;\r\nextra=value");
|
||||
info.getFields().add("Last-Modified", DateGenerator.__01Jan1970);
|
||||
|
||||
|
@ -176,7 +176,7 @@ public class HttpGeneratorServerTest
|
|||
|
||||
assertEquals(10, gen.getContentPrepared());
|
||||
|
||||
assertThat(response, containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(response, containsString("HTTP/1.1 200 ØÆ"));
|
||||
assertThat(response, containsString("Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT"));
|
||||
assertThat(response, containsString("Content-Type: test/data; extra=value"));
|
||||
assertThat(response, containsString("Content-Length: 10"));
|
||||
|
|
|
@ -573,7 +573,9 @@ public class HttpParserTest
|
|||
BufferUtil.put(BufferUtil.toBuffer(" HTTP/1.0\r\n"), buffer);
|
||||
BufferUtil.put(BufferUtil.toBuffer("Header1: "), buffer);
|
||||
buffer.put("\u00e6 \u00e6".getBytes(StandardCharsets.ISO_8859_1));
|
||||
BufferUtil.put(BufferUtil.toBuffer(" \r\n\r\n"), buffer);
|
||||
BufferUtil.put(BufferUtil.toBuffer(" \r\nHeader2: "), buffer);
|
||||
buffer.put((byte)-1);
|
||||
BufferUtil.put(BufferUtil.toBuffer("\r\n\r\n"), buffer);
|
||||
BufferUtil.flipToFlush(buffer, 0);
|
||||
|
||||
HttpParser.RequestHandler handler = new Handler();
|
||||
|
@ -585,7 +587,9 @@ public class HttpParserTest
|
|||
Assert.assertEquals("HTTP/1.0", _versionOrReason);
|
||||
Assert.assertEquals("Header1", _hdr[0]);
|
||||
Assert.assertEquals("\u00e6 \u00e6", _val[0]);
|
||||
Assert.assertEquals(0, _headers);
|
||||
Assert.assertEquals("Header2", _hdr[1]);
|
||||
Assert.assertEquals(""+(char)255, _val[1]);
|
||||
Assert.assertEquals(1, _headers);
|
||||
Assert.assertEquals(null, _bad);
|
||||
}
|
||||
|
||||
|
@ -1304,6 +1308,22 @@ public class HttpParserTest
|
|||
Assert.assertTrue(_messageCompleted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseReasonIso8859_1() throws Exception
|
||||
{
|
||||
ByteBuffer buffer = BufferUtil.toBuffer(
|
||||
"HTTP/1.1 302 déplacé temporairement\r\n"
|
||||
+ "Content-Length: 0\r\n"
|
||||
+ "\r\n",StandardCharsets.ISO_8859_1);
|
||||
|
||||
HttpParser.ResponseHandler handler = new Handler();
|
||||
HttpParser parser = new HttpParser(handler);
|
||||
parser.parseNext(buffer);
|
||||
Assert.assertEquals("HTTP/1.1", _methodOrVersion);
|
||||
Assert.assertEquals("302", _uriOrStatus);
|
||||
Assert.assertEquals("déplacé temporairement", _versionOrReason);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeekEOF() throws Exception
|
||||
{
|
||||
|
|
|
@ -1056,5 +1056,4 @@ public class StringUtil
|
|||
{
|
||||
return object==null?null:String.valueOf(object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue