/* * ==================================================================== * 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 * . * */ 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.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 = this.parser.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("GET", 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("GET", 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("GET", 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 } } }