blob: 52f679fa9505a60c9fec466d106a5d9c1a94bb7e [file] [log] [blame]
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.core5.http.message;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.util.CharArrayBuffer;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Tests for {@link BasicLineParser}.
*
*/
public class TestBasicLineParser {
private BasicLineParser parser;
@Before
public void setup() {
this.parser = BasicLineParser.INSTANCE;
}
@Test
public void testRLParse() throws Exception {
final CharArrayBuffer buf = new CharArrayBuffer(64);
//typical request line
buf.clear();
buf.append("GET /stuff HTTP/1.1");
RequestLine requestline = this.parser.parseRequestLine(buf);
Assert.assertEquals("GET /stuff HTTP/1.1", requestline.toString());
Assert.assertEquals(Method.GET.name(), requestline.getMethod());
Assert.assertEquals("/stuff", requestline.getUri());
Assert.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
//Lots of blanks
buf.clear();
buf.append(" GET /stuff HTTP/1.1 ");
requestline = this.parser.parseRequestLine(buf);
Assert.assertEquals("GET /stuff HTTP/1.1", requestline.toString());
Assert.assertEquals(Method.GET.name(), requestline.getMethod());
Assert.assertEquals("/stuff", requestline.getUri());
Assert.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
//this is not strictly valid, but is lenient
buf.clear();
buf.append("\rGET /stuff HTTP/1.1");
requestline = this.parser.parseRequestLine(buf);
Assert.assertEquals(Method.GET.name(), requestline.getMethod());
Assert.assertEquals("/stuff", requestline.getUri());
Assert.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
}
@Test
public void testRLParseFailure() throws Exception {
final CharArrayBuffer buf = new CharArrayBuffer(64);
buf.clear();
buf.append(" ");
try {
this.parser.parseRequestLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append(" GET");
try {
this.parser.parseRequestLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("GET /stuff");
try {
this.parser.parseRequestLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("GET/stuff HTTP/1.1");
try {
this.parser.parseRequestLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("GET /stuff HTTP/1.1 Oooooooooooppsie");
try {
this.parser.parseRequestLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
}
@Test
public void testSLParse() throws Exception {
final CharArrayBuffer buf = new CharArrayBuffer(64);
//typical status line
buf.clear();
buf.append("HTTP/1.1 200 OK");
StatusLine statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals("HTTP/1.1 200 OK", statusLine.toString());
Assert.assertEquals(HttpVersion.HTTP_1_1, statusLine.getProtocolVersion());
Assert.assertEquals(200, statusLine.getStatusCode());
Assert.assertEquals("OK", statusLine.getReasonPhrase());
//status line with multi word reason phrase
buf.clear();
buf.append("HTTP/1.1 404 Not Found");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals(404, statusLine.getStatusCode());
Assert.assertEquals("Not Found", statusLine.getReasonPhrase());
//reason phrase can be anyting
buf.clear();
buf.append("HTTP/1.1 404 Non Trouve");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals("Non Trouve", statusLine.getReasonPhrase());
//its ok to end with a \n\r
buf.clear();
buf.append("HTTP/1.1 404 Not Found\r\n");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals("Not Found", statusLine.getReasonPhrase());
//this is valid according to the Status-Line BNF
buf.clear();
buf.append("HTTP/1.1 200 ");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals(200, statusLine.getStatusCode());
Assert.assertEquals("", statusLine.getReasonPhrase());
//this is not strictly valid, but is lenient
buf.clear();
buf.append("HTTP/1.1 200");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals(200, statusLine.getStatusCode());
Assert.assertEquals("", statusLine.getReasonPhrase());
//this is not strictly valid, but is lenient
buf.clear();
buf.append("HTTP/1.1 200 OK");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals(200, statusLine.getStatusCode());
Assert.assertEquals("OK", statusLine.getReasonPhrase());
//this is not strictly valid, but is lenient
buf.clear();
buf.append("\nHTTP/1.1 200 OK");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals(200, statusLine.getStatusCode());
Assert.assertEquals("OK", statusLine.getReasonPhrase());
Assert.assertEquals(HttpVersion.HTTP_1_1, statusLine.getProtocolVersion());
//this is not strictly valid, but is lenient
buf.clear();
buf.append(" HTTP/1.1 200 OK");
statusLine = this.parser.parseStatusLine(buf);
Assert.assertEquals(200, statusLine.getStatusCode());
Assert.assertEquals("OK", statusLine.getReasonPhrase());
Assert.assertEquals(HttpVersion.HTTP_1_1, statusLine.getProtocolVersion());
}
@Test
public void testSLParseFailure() throws Exception {
final CharArrayBuffer buf = new CharArrayBuffer(64);
buf.clear();
buf.append("xxx 200 OK");
try {
this.parser.parseStatusLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("HTTP/1.1 xxx OK");
try {
this.parser.parseStatusLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("HTTP/1.1 ");
try {
this.parser.parseStatusLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("HTTP/1.1");
try {
this.parser.parseStatusLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
buf.clear();
buf.append("HTTP/1.1 -200 OK");
try {
this.parser.parseStatusLine(buf);
Assert.fail();
} catch (final ParseException e) {
// expected
}
}
@Test
public void testHttpVersionParsing() throws Exception {
final CharArrayBuffer buffer = new CharArrayBuffer(16);
buffer.append("HTTP/1.1");
ParserCursor cursor = new ParserCursor(0, buffer.length());
HttpVersion version = (HttpVersion) parser.parseProtocolVersion(buffer, cursor);
Assert.assertEquals("HTTP protocol name", "HTTP", version.getProtocol());
Assert.assertEquals("HTTP major version number", 1, version.getMajor());
Assert.assertEquals("HTTP minor version number", 1, version.getMinor());
Assert.assertEquals("HTTP version number", "HTTP/1.1", version.toString());
Assert.assertEquals(buffer.length(), cursor.getPos());
Assert.assertTrue(cursor.atEnd());
buffer.clear();
buffer.append("HTTP/1.123 123");
cursor = new ParserCursor(0, buffer.length());
version = (HttpVersion) parser.parseProtocolVersion(buffer, cursor);
Assert.assertEquals("HTTP protocol name", "HTTP", version.getProtocol());
Assert.assertEquals("HTTP major version number", 1, version.getMajor());
Assert.assertEquals("HTTP minor version number", 123, version.getMinor());
Assert.assertEquals("HTTP version number", "HTTP/1.123", version.toString());
Assert.assertEquals(' ', buffer.charAt(cursor.getPos()));
Assert.assertEquals(buffer.length() - 4, cursor.getPos());
Assert.assertFalse(cursor.atEnd());
}
@Test
public void testInvalidHttpVersionParsing() throws Exception {
final CharArrayBuffer buffer = new CharArrayBuffer(16);
buffer.clear();
buffer.append(" ");
ParserCursor cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTT");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("crap");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTTP/crap");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTTP/1");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTTP/1234");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTTP/1.");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTTP/whatever.whatever whatever");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("HTTP/1.whatever whatever");
cursor = new ParserCursor(0, buffer.length());
try {
this.parser.parseProtocolVersion(buffer, cursor);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
}
@Test
public void testHeaderParse() throws Exception {
final CharArrayBuffer buf = new CharArrayBuffer(64);
//typical request line
buf.clear();
buf.append("header: blah");
Header header = this.parser.parseHeader(buf);
Assert.assertEquals("header", header.getName());
Assert.assertEquals("blah", header.getValue());
//Lots of blanks
buf.clear();
buf.append(" header: blah ");
header = this.parser.parseHeader(buf);
Assert.assertEquals("header", header.getName());
Assert.assertEquals("blah", header.getValue());
}
@Test
public void testInvalidHeaderParsing() throws Exception {
final CharArrayBuffer buffer = new CharArrayBuffer(16);
buffer.clear();
buffer.append("");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("blah");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append(":");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append(" :");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append(": blah");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append(" : blah");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
buffer.clear();
buffer.append("header : blah");
try {
this.parser.parseHeader(buffer);
Assert.fail("ParseException should have been thrown");
} catch (final ParseException e) {
//expected
}
}
}