blob: 3bbef8f96222d96c250f97c8802a7296e9845bd9 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 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 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;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
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.
*/
private 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();
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 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<ByteBuffer>)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", _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<ByteBuffer>)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", _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()
{
_host=null;
_port=0;
_bad=null;
_content=null;
_methodOrVersion=null;
_uriOrStatus=null;
_versionOrReason=null;
_fields.clear();
_hdr=null;
_val=null;
_headers=0;
_early=false;
_headerCompleted=false;
_messageCompleted=false;
_proxy=null;
}
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 String _proxy;
private class Handler implements HttpParser.RequestHandler<ByteBuffer>, HttpParser.ResponseHandler<ByteBuffer>, HttpParser.ProxyHandler
{
@Override
public boolean content(ByteBuffer ref)
{
if (_content==null)
_content="";
String c = BufferUtil.toString(ref,StandardCharsets.UTF_8);
_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();
_messageCompleted = false;
_headerCompleted = false;
_early=false;
return false;
}
@Override
public boolean parsedHeader(HttpField field)
{
_fields.add(field);
_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()
{
_content= null;
_headerCompleted = true;
return false;
}
@Override
public boolean 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;
_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;
}
}
}