BasicLineParser implements LineParser { ProtocolVersion parseProtocolVersion( final CharArrayBuffer buffer, final ParserCursor cursor) throws ParseException { final String protoname = this.protocol.getProtocol(); final int protolength = protoname.length(); this.tokenizer.skipWhiteSpace(buffer, cursor); final int pos = cursor.getPos(); if (pos + protolength + 4 > cursor.getUpperBound()) { throw new ParseException("Invalid protocol version", buffer, cursor.getLowerBound(), cursor.getUpperBound(), cursor.getPos()); } boolean ok = true; for (int i = 0; ok && (i < protolength); i++) { ok = buffer.charAt(pos + i) == protoname.charAt(i); } if (ok) { ok = buffer.charAt(pos + protolength) == '/'; } if (!ok) { throw new ParseException("Invalid protocol version", buffer, cursor.getLowerBound(), cursor.getUpperBound(), cursor.getPos()); } cursor.updatePos(pos + protolength + 1); final String token1 = this.tokenizer.parseToken(buffer, cursor, FULL_STOP); final int major; try { major = Integer.parseInt(token1); } catch (final NumberFormatException e) { throw new ParseException("Invalid protocol major version number", buffer, cursor.getLowerBound(), cursor.getUpperBound(), cursor.getPos()); } if (cursor.atEnd()) { throw new ParseException("Invalid protocol version", buffer, cursor.getLowerBound(), cursor.getUpperBound(), cursor.getPos()); } cursor.updatePos(cursor.getPos() + 1); final String token2 = this.tokenizer.parseToken(buffer, cursor, BLANKS); final int minor; try { minor = Integer.parseInt(token2); } catch (final NumberFormatException e) { throw new ParseException("Invalid protocol minor version number", buffer, cursor.getLowerBound(), cursor.getUpperBound(), cursor.getPos()); } return HttpVersion.get(major, minor); } BasicLineParser(final ProtocolVersion proto);  BasicLineParser(); @Override RequestLine parseRequestLine(final CharArrayBuffer buffer); @Override StatusLine parseStatusLine(final CharArrayBuffer buffer); @Override Header parseHeader(final CharArrayBuffer buffer); final static BasicLineParser INSTANCE; }
@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) { } 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) { } 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) { } 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) { } 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) { } 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) { } 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) { } 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) { } 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) { } }