| // |
| // ======================================================================== |
| // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.http; |
| |
| import static org.junit.Assert.*; |
| |
| import java.nio.ByteBuffer; |
| import java.nio.charset.StandardCharsets; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.jetty.http.HttpParser.State; |
| import org.eclipse.jetty.util.BufferUtil; |
| import org.hamcrest.Matchers; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * |
| */ |
| public class HttpParserTest |
| { |
| /* ------------------------------------------------------------------------------- */ |
| /** |
| * Parse until {@link State#END} state. |
| * If the parser is already in the END state, then it is {@link HttpParser#reset()} and re-parsed. |
| * @param parser The parser to test |
| * @throws IllegalStateException If the buffers have already been partially parsed. |
| */ |
| public static void parseAll(HttpParser parser, ByteBuffer buffer) |
| { |
| if (parser.isState(State.END)) |
| parser.reset(); |
| if (!parser.isState(State.START)) |
| throw new IllegalStateException("!START"); |
| |
| // continue parsing |
| int remaining=buffer.remaining(); |
| while (!parser.isState(State.END) && remaining>0) |
| { |
| int was_remaining=remaining; |
| parser.parseNext(buffer); |
| remaining=buffer.remaining(); |
| if (remaining==was_remaining) |
| break; |
| } |
| } |
| |
| @Test |
| public void HttpMethodTest() |
| { |
| assertNull(HttpMethod.lookAheadGet(BufferUtil.toBuffer("Wibble "))); |
| assertNull(HttpMethod.lookAheadGet(BufferUtil.toBuffer("GET"))); |
| assertNull(HttpMethod.lookAheadGet(BufferUtil.toBuffer("MO"))); |
| |
| assertEquals(HttpMethod.GET,HttpMethod.lookAheadGet(BufferUtil.toBuffer("GET "))); |
| assertEquals(HttpMethod.MOVE,HttpMethod.lookAheadGet(BufferUtil.toBuffer("MOVE "))); |
| |
| ByteBuffer b = BufferUtil.allocateDirect(128); |
| BufferUtil.append(b,BufferUtil.toBuffer("GET")); |
| assertNull(HttpMethod.lookAheadGet(b)); |
| |
| BufferUtil.append(b,BufferUtil.toBuffer(" ")); |
| assertEquals(HttpMethod.GET,HttpMethod.lookAheadGet(b)); |
| } |
| |
| @Test |
| public void testLineParse_Mock_IP() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("POST /mock/127.0.0.1 HTTP/1.1\015\012" + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/mock/127.0.0.1", _uriOrStatus); |
| assertEquals("HTTP/1.1", _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testLineParse0() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("POST /foo HTTP/1.0\015\012" + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/foo", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testLineParse1() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("GET /999\015\012"); |
| |
| _versionOrReason= null; |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/999", _uriOrStatus); |
| assertEquals(null, _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testLineParse2() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("POST /222 \015\012"); |
| |
| _versionOrReason= null; |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/222", _uriOrStatus); |
| assertEquals(null, _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testLineParse3() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("POST /fo\u0690 HTTP/1.0\015\012" + "\015\012",StandardCharsets.UTF_8); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/fo\u0690", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testLineParse4() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("POST /foo?param=\u0690 HTTP/1.0\015\012" + "\015\012",StandardCharsets.UTF_8); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/foo?param=\u0690", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testLongURLParse() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("POST /123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/ HTTP/1.0\015\012" + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testConnect() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer("CONNECT 192.168.1.2:80 HTTP/1.1\015\012" + "\015\012"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("CONNECT", _methodOrVersion); |
| assertEquals("192.168.1.2:80", _uriOrStatus); |
| assertEquals("HTTP/1.1", _versionOrReason); |
| assertEquals(-1, _headers); |
| } |
| |
| @Test |
| public void testSimple() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" + |
| "Host: localhost\015\012" + |
| "Connection: close\015\012" + |
| "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Connection", _hdr[1]); |
| assertEquals("close", _val[1]); |
| assertEquals(1, _headers); |
| } |
| |
| @Test |
| public void testHeaderParseDirect() throws Exception |
| { |
| ByteBuffer b0= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" + |
| "Host: localhost\015\012" + |
| "Header1: value1\015\012" + |
| "Header 2 : value 2a \015\012" + |
| " value 2b \015\012" + |
| "Header3: \015\012" + |
| "Header4 \015\012" + |
| " value4\015\012" + |
| "Server5 : notServer\015\012" + |
| "Host Header: notHost\015\012" + |
| "Connection: close\015\012" + |
| "Accept-Encoding: gzip, deflated\015\012" + |
| "Accept: unknown\015\012" + |
| "\015\012"); |
| ByteBuffer buffer = BufferUtil.allocateDirect(b0.capacity()); |
| int pos=BufferUtil.flipToFill(buffer); |
| BufferUtil.put(b0,buffer); |
| BufferUtil.flipToFlush(buffer,pos); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Header1", _hdr[1]); |
| assertEquals("value1", _val[1]); |
| assertEquals("Header 2", _hdr[2]); |
| assertEquals("value 2a value 2b", _val[2]); |
| assertEquals("Header3", _hdr[3]); |
| assertEquals(null, _val[3]); |
| assertEquals("Header4", _hdr[4]); |
| assertEquals("value4", _val[4]); |
| assertEquals("Server5", _hdr[5]); |
| assertEquals("notServer", _val[5]); |
| assertEquals("Host Header", _hdr[6]); |
| assertEquals("notHost", _val[6]); |
| assertEquals("Connection", _hdr[7]); |
| assertEquals("close", _val[7]); |
| assertEquals("Accept-Encoding", _hdr[8]); |
| assertEquals("gzip, deflated", _val[8]); |
| assertEquals("Accept", _hdr[9]); |
| assertEquals("unknown", _val[9]); |
| assertEquals(9, _headers); |
| } |
| |
| @Test |
| public void testHeaderParseCRLF() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" + |
| "Host: localhost\015\012" + |
| "Header1: value1\015\012" + |
| "Header 2 : value 2a \015\012" + |
| " value 2b \015\012" + |
| "Header3: \015\012" + |
| "Header4 \015\012" + |
| " value4\015\012" + |
| "Server5 : notServer\015\012" + |
| "Host Header: notHost\015\012" + |
| "Connection: close\015\012" + |
| "Accept-Encoding: gzip, deflated\015\012" + |
| "Accept: unknown\015\012" + |
| "\015\012"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Header1", _hdr[1]); |
| assertEquals("value1", _val[1]); |
| assertEquals("Header 2", _hdr[2]); |
| assertEquals("value 2a value 2b", _val[2]); |
| assertEquals("Header3", _hdr[3]); |
| assertEquals(null, _val[3]); |
| assertEquals("Header4", _hdr[4]); |
| assertEquals("value4", _val[4]); |
| assertEquals("Server5", _hdr[5]); |
| assertEquals("notServer", _val[5]); |
| assertEquals("Host Header", _hdr[6]); |
| assertEquals("notHost", _val[6]); |
| assertEquals("Connection", _hdr[7]); |
| assertEquals("close", _val[7]); |
| assertEquals("Accept-Encoding", _hdr[8]); |
| assertEquals("gzip, deflated", _val[8]); |
| assertEquals("Accept", _hdr[9]); |
| assertEquals("unknown", _val[9]); |
| assertEquals(9, _headers); |
| } |
| |
| |
| |
| @Test |
| public void testHeaderParseLF() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\n" + |
| "Host: localhost\n" + |
| "Header1: value1\n" + |
| "Header 2 : value 2a \n" + |
| " value 2b \n" + |
| "Header3: \n" + |
| "Header4 \n" + |
| " value4\n" + |
| "Server5 : notServer\n" + |
| "Host Header: notHost\n" + |
| "Connection: close\n" + |
| "Accept-Encoding: gzip, deflated\n" + |
| "Accept: unknown\n" + |
| "\n"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Header1", _hdr[1]); |
| assertEquals("value1", _val[1]); |
| assertEquals("Header 2", _hdr[2]); |
| assertEquals("value 2a value 2b", _val[2]); |
| assertEquals("Header3", _hdr[3]); |
| assertEquals(null, _val[3]); |
| assertEquals("Header4", _hdr[4]); |
| assertEquals("value4", _val[4]); |
| assertEquals("Server5", _hdr[5]); |
| assertEquals("notServer", _val[5]); |
| assertEquals("Host Header", _hdr[6]); |
| assertEquals("notHost", _val[6]); |
| assertEquals("Connection", _hdr[7]); |
| assertEquals("close", _val[7]); |
| assertEquals("Accept-Encoding", _hdr[8]); |
| assertEquals("gzip, deflated", _val[8]); |
| assertEquals("Accept", _hdr[9]); |
| assertEquals("unknown", _val[9]); |
| assertEquals(9, _headers); |
| } |
| |
| @Test |
| public void testQuoted() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\n" + |
| "Name0: \"value0\"\t\n" + |
| "Name1: \"value\t1\"\n" + |
| "Name2: \"value\t2A\",\"value,2B\"\t\n" + |
| "\n"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Name0", _hdr[0]); |
| assertEquals("\"value0\"", _val[0]); |
| assertEquals("Name1", _hdr[1]); |
| assertEquals("\"value\t1\"", _val[1]); |
| assertEquals("Name2", _hdr[2]); |
| assertEquals("\"value\t2A\",\"value,2B\"", _val[2]); |
| assertEquals(2, _headers); |
| } |
| |
| @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(StandardCharsets.UTF_8)); |
| 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.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, _headers); |
| 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 testHeaderTab() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\r\n" + |
| "Host: localhost\r\n" + |
| "Header: value\talternate\r\n" + |
| "\n\n"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.1", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Header", _hdr[1]); |
| assertEquals("value\talternate", _val[1]); |
| } |
| |
| @Test |
| public void testNonStrict() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "get / http/1.0\015\012" + |
| "HOST: localhost\015\012" + |
| "cOnNeCtIoN: ClOsE\015\012"+ |
| "\015\012"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler,-1,false); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Connection", _hdr[1]); |
| assertEquals("close", _val[1]); |
| assertEquals(1, _headers); |
| } |
| |
| @Test |
| public void testStrict() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "gEt / http/1.0\015\012" + |
| "HOST: localhost\015\012" + |
| "cOnNeCtIoN: ClOsE\015\012"+ |
| "\015\012"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler,-1,true); |
| parseAll(parser,buffer); |
| |
| assertEquals("gEt", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("HOST", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("cOnNeCtIoN", _hdr[1]); |
| assertEquals("ClOsE", _val[1]); |
| assertEquals(1, _headers); |
| } |
| |
| @Test |
| public void testSplitHeaderParse() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "XXXXSPLIT / HTTP/1.0\015\012" + |
| "Host: localhost\015\012" + |
| "Header1: value1\015\012" + |
| "Header2 : value 2a \015\012" + |
| " value 2b \015\012" + |
| "Header3: \015\012" + |
| "Header4 \015\012" + |
| " value4\015\012" + |
| "Server5: notServer\015\012" + |
| "\015\012ZZZZ"); |
| buffer.position(2); |
| buffer.limit(buffer.capacity()-2); |
| buffer=buffer.slice(); |
| |
| for (int i=0;i<buffer.capacity()-4;i++) |
| { |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| // System.err.println(BufferUtil.toDetailString(buffer)); |
| buffer.position(2); |
| buffer.limit(2+i); |
| |
| if (!parser.parseNext(buffer)) |
| { |
| // consumed all |
| assertEquals(0,buffer.remaining()); |
| |
| // parse the rest |
| buffer.limit(buffer.capacity()-2); |
| parser.parseNext(buffer); |
| } |
| |
| assertEquals("SPLIT", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Header1", _hdr[1]); |
| assertEquals("value1", _val[1]); |
| assertEquals("Header2", _hdr[2]); |
| assertEquals("value 2a value 2b", _val[2]); |
| assertEquals("Header3", _hdr[3]); |
| assertEquals(null, _val[3]); |
| assertEquals("Header4", _hdr[4]); |
| assertEquals("value4", _val[4]); |
| assertEquals("Server5", _hdr[5]); |
| assertEquals("notServer", _val[5]); |
| assertEquals(5, _headers); |
| } |
| } |
| |
| |
| @Test |
| public void testChunkParse() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET /chunk HTTP/1.0\015\012" |
| + "Header1: value1\015\012" |
| + "Transfer-Encoding: chunked\015\012" |
| + "\015\012" |
| + "a;\015\012" |
| + "0123456789\015\012" |
| + "1a\015\012" |
| + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012" |
| + "0\015\012" |
| + "\015\012"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/chunk", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(1, _headers); |
| assertEquals("Header1", _hdr[0]); |
| assertEquals("value1", _val[0]); |
| assertEquals("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content); |
| |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testStartEOF() throws Exception |
| { |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.atEOF(); |
| parser.parseNext(BufferUtil.EMPTY_BUFFER); |
| |
| assertTrue(_early); |
| assertEquals(null,_bad); |
| } |
| |
| @Test |
| public void testEarlyEOF() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET /uri HTTP/1.0\015\012" |
| + "Content-Length: 20\015\012" |
| + "\015\012" |
| + "0123456789"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.atEOF(); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/uri", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("0123456789", _content); |
| |
| assertTrue(_early); |
| } |
| |
| @Test |
| public void testChunkEarlyEOF() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET /chunk HTTP/1.0\015\012" |
| + "Header1: value1\015\012" |
| + "Transfer-Encoding: chunked\015\012" |
| + "\015\012" |
| + "a;\015\012" |
| + "0123456789\015\012"); |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.atEOF(); |
| parseAll(parser,buffer); |
| |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/chunk", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(1, _headers); |
| assertEquals("Header1", _hdr[0]); |
| assertEquals("value1", _val[0]); |
| assertEquals("0123456789", _content); |
| |
| assertTrue(_early); |
| |
| } |
| |
| |
| @Test |
| public void testMultiParse() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET /mp HTTP/1.0\015\012" |
| + "Connection: Keep-Alive\015\012" |
| + "Header1: value1\015\012" |
| + "Transfer-Encoding: chunked\015\012" |
| + "\015\012" |
| + "a;\015\012" |
| + "0123456789\015\012" |
| + "1a\015\012" |
| + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012" |
| + "0\015\012" |
| |
| + "\015\012" |
| |
| + "POST /foo HTTP/1.0\015\012" |
| + "Connection: Keep-Alive\015\012" |
| + "Header2: value2\015\012" |
| + "Content-Length: 0\015\012" |
| + "\015\012" |
| |
| + "PUT /doodle HTTP/1.0\015\012" |
| + "Connection: close\015\012" |
| + "Header3: value3\015\012" |
| + "Content-Length: 10\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/mp", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(2, _headers); |
| assertEquals("Header1", _hdr[1]); |
| assertEquals("value1", _val[1]); |
| assertEquals("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content); |
| |
| parser.reset(); |
| init(); |
| parser.parseNext(buffer); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/foo", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(2, _headers); |
| assertEquals("Header2", _hdr[1]); |
| assertEquals("value2", _val[1]); |
| assertEquals(null, _content); |
| |
| parser.reset(); |
| init(); |
| parser.parseNext(buffer); |
| parser.atEOF(); |
| assertEquals("PUT", _methodOrVersion); |
| assertEquals("/doodle", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(2, _headers); |
| assertEquals("Header3", _hdr[1]); |
| assertEquals("value3", _val[1]); |
| assertEquals("0123456789", _content); |
| } |
| |
| |
| @Test |
| public void testMultiParseEarlyEOF() throws Exception |
| { |
| ByteBuffer buffer0= BufferUtil.toBuffer( |
| "GET /mp HTTP/1.0\015\012" |
| + "Connection: Keep-Alive\015\012"); |
| |
| ByteBuffer buffer1= BufferUtil.toBuffer("Header1: value1\015\012" |
| + "Transfer-Encoding: chunked\015\012" |
| + "\015\012" |
| + "a;\015\012" |
| + "0123456789\015\012" |
| + "1a\015\012" |
| + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012" |
| + "0\015\012" |
| |
| + "\015\012" |
| |
| + "POST /foo HTTP/1.0\015\012" |
| + "Connection: Keep-Alive\015\012" |
| + "Header2: value2\015\012" |
| + "Content-Length: 0\015\012" |
| + "\015\012" |
| |
| + "PUT /doodle HTTP/1.0\015\012" |
| + "Connection: close\015\012" |
| + "Header3: value3\015\012" |
| + "Content-Length: 10\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer0); |
| parser.atEOF(); |
| parser.parseNext(buffer1); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/mp", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(2, _headers); |
| assertEquals("Header1", _hdr[1]); |
| assertEquals("value1", _val[1]); |
| assertEquals("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", _content); |
| |
| parser.reset(); |
| init(); |
| parser.parseNext(buffer1); |
| assertEquals("POST", _methodOrVersion); |
| assertEquals("/foo", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(2, _headers); |
| assertEquals("Header2", _hdr[1]); |
| assertEquals("value2", _val[1]); |
| assertEquals(null, _content); |
| |
| parser.reset(); |
| init(); |
| parser.parseNext(buffer1); |
| assertEquals("PUT", _methodOrVersion); |
| assertEquals("/doodle", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals(2, _headers); |
| assertEquals("Header3", _hdr[1]); |
| assertEquals("value3", _val[1]); |
| assertEquals("0123456789", _content); |
| } |
| |
| @Test |
| public void testResponseParse0() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 200 Correct\015\012" |
| + "Content-Length: 10\015\012" |
| + "Content-Type: text/plain\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("200", _uriOrStatus); |
| assertEquals("Correct", _versionOrReason); |
| assertEquals(10,_content.length()); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testResponseParse1() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 304 Not-Modified\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("304", _uriOrStatus); |
| assertEquals("Not-Modified", _versionOrReason); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testResponseParse2() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 204 No-Content\015\012" |
| + "Header: value\015\012" |
| + "\015\012" |
| |
| + "HTTP/1.1 200 Correct\015\012" |
| + "Content-Length: 10\015\012" |
| + "Content-Type: text/plain\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("204", _uriOrStatus); |
| assertEquals("No-Content", _versionOrReason); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| |
| parser.reset(); |
| init(); |
| |
| parser.parseNext(buffer); |
| parser.atEOF(); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("200", _uriOrStatus); |
| assertEquals("Correct", _versionOrReason); |
| assertEquals(_content.length(), 10); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| |
| @Test |
| public void testResponseParse3() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 200\015\012" |
| + "Content-Length: 10\015\012" |
| + "Content-Type: text/plain\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("200", _uriOrStatus); |
| assertEquals(null, _versionOrReason); |
| assertEquals(_content.length(), 10); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testResponseParse4() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 200 \015\012" |
| + "Content-Length: 10\015\012" |
| + "Content-Type: text/plain\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("200", _uriOrStatus); |
| assertEquals(null, _versionOrReason); |
| assertEquals(_content.length(), 10); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testResponseEOFContent() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 200 \015\012" |
| + "Content-Type: text/plain\015\012" |
| + "\015\012" |
| + "0123456789\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.atEOF(); |
| parser.parseNext(buffer); |
| |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("200", _uriOrStatus); |
| assertEquals(null, _versionOrReason); |
| assertEquals(12,_content.length()); |
| assertEquals("0123456789\015\012",_content); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testResponse304WithContentLength() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 304 found\015\012" |
| + "Content-Length: 10\015\012" |
| + "\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("304", _uriOrStatus); |
| assertEquals("found", _versionOrReason); |
| assertEquals(null,_content); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testResponse101WithTransferEncoding() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 101 switching protocols\015\012" |
| + "Transfer-Encoding: chunked\015\012" |
| + "\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("101", _uriOrStatus); |
| assertEquals("switching protocols", _versionOrReason); |
| assertEquals(null,_content); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| } |
| |
| @Test |
| public void testSeekEOF() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 200 OK\015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012" |
| + "\015\012" // extra CRLF ignored |
| + "HTTP/1.1 400 OK\015\012"); // extra data causes close ?? |
| |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals("HTTP/1.1", _methodOrVersion); |
| assertEquals("200", _uriOrStatus); |
| assertEquals("OK", _versionOrReason); |
| assertEquals(null,_content); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| |
| parser.reset(); |
| parser.parseNext(buffer); |
| assertFalse(buffer.hasRemaining()); |
| assertTrue(parser.isClosed()); |
| } |
| |
| |
| |
| @Test |
| public void testNoURI() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET\015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("No URI",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| |
| @Test |
| public void testNoURI2() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET \015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("No URI",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testUnknownReponseVersion() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HPPT/7.7 200 OK\015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("Unknown Version",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testNoStatus() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1\015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("No Status",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testNoStatus2() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "HTTP/1.1 \015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.ResponseHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("No Status",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testBadRequestVersion() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HPPT/7.7\015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("Unknown Version",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| |
| buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.01\015\012" |
| + "Content-Length: 0\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| handler = new Handler();handler = new Handler(); |
| parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals(null,_methodOrVersion); |
| assertEquals("Unknown Version",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testBadCR() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\r\n" |
| + "Content-Length: 0\r" |
| + "Connection: close\r" |
| + "\r"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals("Bad EOL",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| |
| |
| buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\r" |
| + "Content-Length: 0\r" |
| + "Connection: close\r" |
| + "\r"); |
| |
| handler = new Handler(); |
| parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals("Bad EOL",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| |
| |
| |
| @Test |
| public void testBadContentLength0() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" |
| + "Content-Length: abc\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals("GET",_methodOrVersion); |
| assertEquals("Bad Content-Length",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testBadContentLength1() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" |
| + "Content-Length: 9999999999999999999999999999999999999999999999\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals("GET",_methodOrVersion); |
| assertEquals("Bad Content-Length",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testBadContentLength2() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" |
| + "Content-Length: 1.5\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| |
| parser.parseNext(buffer); |
| assertEquals("GET",_methodOrVersion); |
| assertEquals("Bad Content-Length",_bad); |
| assertFalse(buffer.hasRemaining()); |
| assertEquals(HttpParser.State.CLOSED,parser.getState()); |
| } |
| |
| @Test |
| public void testHost() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: host\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("host",_host); |
| assertEquals(0,_port); |
| } |
| |
| @Test |
| public void testUriHost11() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET http://host/ HTTP/1.1\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("No Host",_bad); |
| assertEquals("http://host/",_uriOrStatus); |
| assertEquals(0,_port); |
| } |
| |
| @Test |
| public void testUriHost10() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET http://host/ HTTP/1.0\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| Assert.assertNull(_bad); |
| assertEquals("http://host/",_uriOrStatus); |
| assertEquals(0,_port); |
| } |
| |
| @Test |
| public void testNoHost() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("No Host",_bad); |
| } |
| |
| @Test |
| public void testIPHost() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: 192.168.0.1\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("192.168.0.1",_host); |
| assertEquals(0,_port); |
| } |
| |
| @Test |
| public void testIPv6Host() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: [::1]\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("[::1]",_host); |
| assertEquals(0,_port); |
| } |
| |
| @Test |
| public void testBadIPv6Host() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: [::1\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("Bad IPv6 Host header",_bad); |
| } |
| |
| @Test |
| public void testHostPort() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: myhost:8888\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("myhost",_host); |
| assertEquals(8888,_port); |
| } |
| |
| @Test |
| public void testHostBadPort() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: myhost:xxx\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("Bad Host header",_bad); |
| } |
| |
| @Test |
| public void testIPHostPort() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: 192.168.0.1:8888\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("192.168.0.1",_host); |
| assertEquals(8888,_port); |
| } |
| |
| @Test |
| public void testIPv6HostPort() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| + "Host: [::1]:8888\015\012" |
| + "Connection: close\015\012" |
| + "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| assertEquals("[::1]",_host); |
| assertEquals(8888,_port); |
| } |
| |
| @Test |
| public void testCachedField() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.1\r\n"+ |
| "Host: www.smh.com.au\r\n"+ |
| "\r\n"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| assertEquals("www.smh.com.au",parser.getFieldCache().get("Host: www.smh.com.au").getValue()); |
| HttpField field=_fields.get(0); |
| |
| //System.err.println(parser.getFieldCache()); |
| |
| buffer.position(0); |
| parseAll(parser,buffer); |
| assertTrue(field==_fields.get(0)); |
| |
| } |
| |
| @Test |
| public void testProxyProtocol() throws Exception |
| { |
| ByteBuffer buffer=BufferUtil |
| .toBuffer("PROXY TCP4 107.47.45.254 10.0.1.116 27689 80\015\012" |
| +"GET / HTTP/1.1\015\012" |
| +"Host: localhost \015\012" |
| +"Connection: close\015\012"+"\015\012"+"\015\012"); |
| |
| Handler handler=new Handler(); |
| HttpParser parser=new HttpParser((HttpParser.RequestHandler)handler); |
| parseAll(parser, buffer); |
| |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.1", _versionOrReason); |
| assertEquals("PROXY TCP4 107.47.45.254 10.0.1.116 27689 80", handler._proxy); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Connection", _hdr[1]); |
| assertEquals("close", _val[1]); |
| assertEquals(1, _headers); |
| } |
| |
| @Test |
| public void testSplitProxyHeaderParseTest() throws Exception |
| { |
| Handler handler=new Handler(); |
| HttpParser parser=new HttpParser((HttpParser.RequestHandler)handler); |
| |
| ByteBuffer buffer=BufferUtil.toBuffer("PROXY TCP4 207.47.45.254 10.0.1.116 27689 80\015\012"); |
| parser.parseNext(buffer); |
| |
| buffer=BufferUtil.toBuffer( |
| "GET / HTTP/1.1\015\012" |
| +"Host: localhost \015\012" |
| +"Connection: close\015\012" |
| +"\015\012" |
| +"\015\012"); |
| |
| parser.parseNext(buffer); |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.1", _versionOrReason); |
| assertEquals("PROXY TCP4 207.47.45.254 10.0.1.116 27689 80", handler._proxy); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Connection", _hdr[1]); |
| assertEquals("close", _val[1]); |
| assertEquals(1, _headers); |
| } |
| |
| |
| @Test |
| public void testFolded() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "GET / HTTP/1.0\015\012" + |
| "Host: localhost\015\012" + |
| "Connection: close\015\012" + |
| "Content-Type: application/soap+xml; charset=utf-8; \015\012"+ |
| "\taction=\"xxx\" \015\012" + |
| "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| assertEquals("GET", _methodOrVersion); |
| assertEquals("/", _uriOrStatus); |
| assertEquals("HTTP/1.0", _versionOrReason); |
| assertEquals("Host", _hdr[0]); |
| assertEquals("localhost", _val[0]); |
| assertEquals("Connection", _hdr[1]); |
| assertEquals("close", _val[1]); |
| assertEquals("Content-Type", _hdr[2]); |
| assertEquals("application/soap+xml; charset=utf-8; action=\"xxx\"", _val[2]); |
| assertEquals(2, _headers); |
| } |
| |
| |
| @Test |
| public void testParseRequest() throws Exception |
| { |
| ByteBuffer buffer = BufferUtil.toBuffer( |
| "GET / HTTP/1.1\r\n" + |
| "Host: localhost\r\n" + |
| "Header1: value1\r\n" + |
| "Connection: close\r\n" + |
| "Accept-Encoding: gzip, deflated\r\n" + |
| "Accept: unknown\r\n" + |
| "\r\n"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parser.parseNext(buffer); |
| |
| assertEquals("GET",_methodOrVersion); |
| assertEquals("/",_uriOrStatus); |
| assertEquals("HTTP/1.1",_versionOrReason); |
| assertEquals("Host",_hdr[0]); |
| assertEquals("localhost",_val[0]); |
| assertEquals("Connection",_hdr[2]); |
| assertEquals("close",_val[2]); |
| assertEquals("Accept-Encoding",_hdr[3]); |
| assertEquals("gzip, deflated",_val[3]); |
| assertEquals("Accept",_hdr[4]); |
| assertEquals("unknown",_val[4]); |
| } |
| |
| |
| @Test |
| public void testHTTP2Preface() throws Exception |
| { |
| ByteBuffer buffer= BufferUtil.toBuffer( |
| "PRI * HTTP/2.0\015\012" + |
| "\015\012" + |
| "SM\015\012"+ |
| "\015\012"); |
| |
| HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); |
| HttpParser parser= new HttpParser(handler); |
| parseAll(parser,buffer); |
| |
| assertTrue(_headerCompleted); |
| assertTrue(_messageCompleted); |
| assertEquals("PRI", _methodOrVersion); |
| assertEquals("*", _uriOrStatus); |
| assertEquals("HTTP/2.0", _versionOrReason); |
| assertEquals(-1, _headers); |
| assertEquals(null, _bad); |
| } |
| |
| |
| @Before |
| public void init() |
| { |
| _bad=null; |
| _content=null; |
| _methodOrVersion=null; |
| _uriOrStatus=null; |
| _versionOrReason=null; |
| _hdr=null; |
| _val=null; |
| _headers=0; |
| _headerCompleted=false; |
| _messageCompleted=false; |
| } |
| |
| private String _host; |
| private int _port; |
| private String _bad; |
| private String _content; |
| private String _methodOrVersion; |
| private String _uriOrStatus; |
| private String _versionOrReason; |
| private List<HttpField> _fields=new ArrayList<>(); |
| private String[] _hdr; |
| private String[] _val; |
| private int _headers; |
| |
| private boolean _early; |
| private boolean _headerCompleted; |
| private boolean _messageCompleted; |
| |
| private class Handler implements HttpParser.RequestHandler<ByteBuffer>, HttpParser.ResponseHandler<ByteBuffer>, HttpParser.ProxyHandler |
| { |
| private HttpFields fields; |
| String _proxy; |
| |
| @Override |
| public boolean content(ByteBuffer ref) |
| { |
| if (_content==null) |
| _content=""; |
| String c = BufferUtil.toString(ref,StandardCharsets.UTF_8); |
| //System.err.println("content '"+c+"'"); |
| _content= _content + c; |
| ref.position(ref.limit()); |
| return false; |
| } |
| |
| @Override |
| public boolean startRequest(HttpMethod httpMethod, String method, ByteBuffer uri, HttpVersion version) |
| { |
| _fields.clear(); |
| _headers= -1; |
| _hdr= new String[10]; |
| _val= new String[10]; |
| _methodOrVersion= method; |
| _uriOrStatus= BufferUtil.toUTF8String(uri); |
| _versionOrReason= version==null?null:version.asString(); |
| |
| fields=new HttpFields(); |
| _messageCompleted = false; |
| _headerCompleted = false; |
| _early=false; |
| return false; |
| } |
| |
| @Override |
| public boolean parsedHeader(HttpField field) |
| { |
| _fields.add(field); |
| //System.err.println("header "+name+": "+value); |
| _hdr[++_headers]= field.getName(); |
| _val[_headers]= field.getValue(); |
| return false; |
| } |
| |
| @Override |
| public boolean parsedHostHeader(String host,int port) |
| { |
| _host=host; |
| _port=port; |
| return false; |
| } |
| |
| @Override |
| public boolean headerComplete() |
| { |
| //System.err.println("headerComplete"); |
| _content= null; |
| String s0=fields.toString(); |
| String s1=fields.toString(); |
| if (!s0.equals(s1)) |
| { |
| throw new IllegalStateException(); |
| } |
| |
| _headerCompleted = true; |
| return false; |
| } |
| |
| @Override |
| public boolean messageComplete() |
| { |
| //System.err.println("messageComplete"); |
| _messageCompleted = true; |
| return true; |
| } |
| |
| @Override |
| public void badMessage(int status, String reason) |
| { |
| _bad=reason==null?(""+status):reason; |
| } |
| |
| @Override |
| public boolean startResponse(HttpVersion version, int status, String reason) |
| { |
| _fields.clear(); |
| _methodOrVersion = version.asString(); |
| _uriOrStatus = Integer.toString(status); |
| _versionOrReason = reason; |
| |
| fields=new HttpFields(); |
| _hdr= new String[9]; |
| _val= new String[9]; |
| |
| _messageCompleted = false; |
| _headerCompleted = false; |
| return false; |
| } |
| |
| @Override |
| public void earlyEOF() |
| { |
| _early=true; |
| } |
| |
| @Override |
| public int getHeaderCacheSize() |
| { |
| return 512; |
| } |
| |
| @Override |
| public void proxied(String protocol, String sAddr, String dAddr, int sPort, int dPort) |
| { |
| _proxy="PROXY "+protocol+" "+sAddr+" "+dAddr+" "+sPort+" "+dPort; |
| } |
| } |
| } |