diff options
author | Greg Wilkins | 2013-08-09 06:10:30 +0000 |
---|---|---|
committer | Greg Wilkins | 2013-08-09 06:11:59 +0000 |
commit | 7c2095725f2661cb58a33b66617c66ff268ae469 (patch) | |
tree | 12c226e22266c2ba110ef851868a9883887c2993 | |
parent | b17696325b78654fbbff8137cafaa72bb50a9a15 (diff) | |
download | org.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.java | 21 | ||||
-rw-r--r-- | jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java | 70 |
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 |