Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2013-08-09 06:10:30 +0000
committerGreg Wilkins2013-08-09 06:11:59 +0000
commit7c2095725f2661cb58a33b66617c66ff268ae469 (patch)
tree12c226e22266c2ba110ef851868a9883887c2993
parentb17696325b78654fbbff8137cafaa72bb50a9a15 (diff)
downloadorg.eclipse.jetty.project-7c2095725f2661cb58a33b66617c66ff268ae469.tar.gz
org.eclipse.jetty.project-7c2095725f2661cb58a33b66617c66ff268ae469.tar.xz
org.eclipse.jetty.project-7c2095725f2661cb58a33b66617c66ff268ae469.zip
414640 HTTP header value encoding
Allow URL to be any encoding (pass the bytes and by default assume UTF-8), the header values are in ISO_8859_1 and everything else must be US_ASCII
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java21
-rw-r--r--jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java70
2 files changed, 84 insertions, 7 deletions
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index 64315710b5..99c2231996 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -240,6 +240,7 @@ public class HttpParser
return _state == state;
}
+ /* ------------------------------------------------------------------------------- */
private static class BadMessage extends Error
{
private final int _code;
@@ -806,8 +807,6 @@ public class HttpParser
{
// process each character
byte ch=next(buffer);
- if (ch<0)
- throw new BadMessage("Illegal character");
if (ch==0)
continue;
@@ -917,6 +916,8 @@ public class HttpParser
break;
}
}
+ else if (ch<=HttpTokens.SPACE)
+ throw new BadMessage();
else
{
if (buffer.hasRemaining())
@@ -981,6 +982,8 @@ public class HttpParser
break;
case HEADER_NAME:
+ if (ch<0)
+ throw new BadMessage();
switch(ch)
{
case HttpTokens.LINE_FEED:
@@ -990,7 +993,6 @@ public class HttpParser
_header=HttpHeader.CACHE.get(_headerString);
}
setState(State.HEADER);
-
break;
case HttpTokens.COLON:
@@ -1001,10 +1003,11 @@ public class HttpParser
}
setState(State.HEADER_VALUE);
break;
+
case HttpTokens.SPACE:
case HttpTokens.TAB:
- _string.append((char)ch);
break;
+
default:
{
_string.append((char)ch);
@@ -1016,6 +1019,12 @@ public class HttpParser
break;
case HEADER_IN_NAME:
+ if (ch<HttpTokens.SPACE)
+ {
+
+ }
+ if (ch<0)
+ throw new BadMessage("Illegal character");
switch(ch)
{
case HttpTokens.LINE_FEED:
@@ -1091,7 +1100,7 @@ public class HttpParser
break;
default:
{
- _string.append((char)ch);
+ _string.append((char)(0xff&ch));
_length=_string.length();
setState(State.HEADER_IN_VALUE);
}
@@ -1140,7 +1149,7 @@ public class HttpParser
_valueString=null;
_field=null;
}
- _string.append((char)ch);
+ _string.append((char)(0xff&ch));
_length++;
}
break;
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java
index b65e10a12a..51b0de6037 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
@@ -29,6 +30,8 @@ import java.util.List;
import org.eclipse.jetty.http.HttpParser.State;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -314,6 +317,71 @@ public class HttpParserTest
}
@Test
+ public void testEncodedHeader() throws Exception
+ {
+ ByteBuffer buffer=BufferUtil.allocate(4096);
+ BufferUtil.flipToFill(buffer);
+ BufferUtil.put(BufferUtil.toBuffer("GET "),buffer);
+ buffer.put("/foo/\u0690/".getBytes(StringUtil.__UTF8_CHARSET));
+ BufferUtil.put(BufferUtil.toBuffer(" HTTP/1.0\r\n"),buffer);
+ BufferUtil.put(BufferUtil.toBuffer("Header1: "),buffer);
+ buffer.put("\u00e6 \u00e6".getBytes(StringUtil.__ISO_8859_1_CHARSET));
+ BufferUtil.put(BufferUtil.toBuffer(" \r\n\r\n"),buffer);
+ BufferUtil.flipToFlush(buffer,0);
+
+ HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
+ HttpParser parser= new HttpParser(handler);
+ parseAll(parser,buffer);
+
+ assertEquals("GET", _methodOrVersion);
+ assertEquals("/foo/\u0690/", _uriOrStatus);
+ assertEquals("HTTP/1.0", _versionOrReason);
+ assertEquals("Header1", _hdr[0]);
+ assertEquals("\u00e6 \u00e6", _val[0]);
+ assertEquals(0, _h);
+ assertEquals(null,_bad);
+ }
+
+
+
+ @Test
+ public void testBadMethodEncoding() throws Exception
+ {
+ ByteBuffer buffer= BufferUtil.toBuffer(
+ "G\u00e6T / HTTP/1.0\r\nHeader0: value0\r\n\n\n");
+
+ HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
+ HttpParser parser= new HttpParser(handler);
+ parseAll(parser,buffer);
+ assertThat(_bad,Matchers.notNullValue());
+ }
+
+ @Test
+ public void testBadVersionEncoding() throws Exception
+ {
+ ByteBuffer buffer= BufferUtil.toBuffer(
+ "GET / H\u00e6P/1.0\r\nHeader0: value0\r\n\n\n");
+
+ HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
+ HttpParser parser= new HttpParser(handler);
+ parseAll(parser,buffer);
+ assertThat(_bad,Matchers.notNullValue());
+ }
+
+
+ @Test
+ public void testBadHeaderEncoding() throws Exception
+ {
+ ByteBuffer buffer= BufferUtil.toBuffer(
+ "GET / HTTP/1.0\r\nH\u00e6der0: value0\r\n\n\n");
+
+ HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
+ HttpParser parser= new HttpParser(handler);
+ parseAll(parser,buffer);
+ assertThat(_bad,Matchers.notNullValue());
+ }
+
+ @Test
public void testSplitHeaderParse() throws Exception
{
ByteBuffer buffer= BufferUtil.toBuffer(
@@ -1125,7 +1193,7 @@ public class HttpParserTest
@Override
public void badMessage(int status, String reason)
{
- _bad=reason;
+ _bad=reason==null?(""+status):reason;
}
@Override

Back to the top