HttpParser { public boolean parseNext(ByteBuffer buffer) { if (DEBUG) LOG.debug("parseNext s={} {}", state, BufferUtils.toDetailString(buffer)); try { if (state == State.START) { version = null; method = null; methodString = null; endOfContent = EndOfContent.UNKNOWN_CONTENT; header = null; if (quickStart(buffer)) return true; } if (state.ordinal() >= State.START.ordinal() && state.ordinal() < State.HEADER.ordinal()) { if (parseLine(buffer)) return true; } if (state == State.HEADER) { if (parseFields(buffer)) return true; } if (state.ordinal() >= State.CONTENT.ordinal() && state.ordinal() < State.TRAILER.ordinal()) { if (responseStatus > 0 && headResponse) { setState(State.END); return handleContentMessage(); } else { if (parseContent(buffer)) return true; } } if (state == State.TRAILER) { if (parseFields(buffer)) return true; } if (state == State.END) { while (buffer.remaining() > 0 && buffer.get(buffer.position()) <= HttpTokens.SPACE) buffer.get(); } else if (isClose() || isClosed()) { BufferUtils.clear(buffer); } if (eof && !buffer.hasRemaining()) { switch (state) { case CLOSED: break; case START: setState(State.CLOSED); handler.earlyEOF(); break; case END: case CLOSE: setState(State.CLOSED); break; case EOF_CONTENT: case TRAILER: if (fieldState == FieldState.FIELD) { setState(State.CLOSED); return handleContentMessage(); } setState(State.CLOSED); handler.earlyEOF(); break; case CONTENT: case CHUNKED_CONTENT: case CHUNK_SIZE: case CHUNK_PARAMS: case CHUNK: setState(State.CLOSED); handler.earlyEOF(); break; default: if (DEBUG) LOG.debug("{} EOF in {}", this, state); setState(State.CLOSED); handler.badMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400)); break; } } } catch (BadMessageException x) { BufferUtils.clear(buffer); badMessage(x); } catch (Throwable x) { BufferUtils.clear(buffer); badMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400, requestHandler != null ? "Bad Request" : "Bad Response", x)); } return false; } HttpParser(RequestHandler handler);  HttpParser(ResponseHandler handler);  HttpParser(RequestHandler handler, int maxHeaderBytes);  HttpParser(ResponseHandler handler, int maxHeaderBytes); @Deprecated  HttpParser(RequestHandler handler, int maxHeaderBytes, boolean strict); @Deprecated  HttpParser(ResponseHandler handler, int maxHeaderBytes, boolean strict);  HttpParser(RequestHandler handler, HttpCompliance compliance);  HttpParser(RequestHandler handler, int maxHeaderBytes, HttpCompliance compliance);  HttpParser(ResponseHandler handler, int maxHeaderBytes, HttpCompliance compliance); private  HttpParser(RequestHandler requestHandler, ResponseHandler responseHandler, int maxHeaderBytes, HttpCompliance compliance); HttpHandler getHandler(); long getContentLength(); long getContentRead(); void setHeadResponse(boolean head); State getState(); boolean inContentState(); boolean inHeaderState(); boolean isChunking(); boolean isStart(); boolean isClose(); boolean isClosed(); boolean isIdle(); boolean isComplete(); boolean isState(State state); boolean parseNext(ByteBuffer buffer); boolean isAtEOF(); void atEOF(); void close(); void reset(); Trie<HttpField> getFieldCache(); @Override String toString(); static final LazyLogger LOG; @Deprecated
    final static String STRICT; final static int INITIAL_URI_LENGTH; final static Trie<HttpField> CACHE; }
@Test void testIPv6HostPort() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: [::1]:8888\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("[::1]", host); assertEquals(8888, port); }
@Test void testEmptyHostPort() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host:\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertNull(host); assertNull(bad); }
@Test void testParseRequest() { ByteBuffer buffer = BufferUtils.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 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 @DisplayName("should parse 101 successfully.") void test101SwitchingProtocols() { ByteBuffer buffer1 = BufferUtils.toBuffer("HTTP/1.1 101 Switching Protocols\r\n\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer1); assertEquals(-1, headers); assertTrue(headerCompleted); assertTrue(messageCompleted); }
@Test void testSplitHeaderParse() { ByteBuffer buffer = BufferUtils.toBuffer( "XXXXSPLIT / HTTP/1.0\r\n" + "Host: localhost\r\n" + "Header1: value1\r\n" + "Header2: value 2a \r\n" + "Header3: 3\r\n" + "Header4:value4\r\n" + "Server5: notServer\r\n" + "\r\nZZZZ"); buffer.position(2); buffer.limit(buffer.capacity() - 2); buffer = buffer.slice(); for (int i = 0; i < buffer.capacity() - 4; i++) { HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); buffer.position(2); buffer.limit(2 + i); if (!parser.parseNext(buffer)) { assertEquals(0, buffer.remaining()); 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", val[2]); assertEquals("Header3", hdr[3]); assertEquals("3", val[3]); assertEquals("Header4", hdr[4]); assertEquals("value4", val[4]); assertEquals("Server5", hdr[5]); assertEquals("notServer", val[5]); assertEquals(5, headers); } }
@Test void testResponseParse0() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 200 Correct\r\n" + "Content-Length: 10\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "0123456789\r\n"); HttpParser.ResponseHandler 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 void testResponseParse1() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 304 Not-Modified\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.ResponseHandler 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 void testResponseParse3() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 200\r\n" + "Content-Length: 10\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", methodOrVersion); assertEquals("200", uriOrStatus); assertNull(versionOrReason); assertEquals(content.length(), 10); assertTrue(headerCompleted); assertTrue(messageCompleted); }
@Test void testResponseParse4() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 200 \r\n" + "Content-Length: 10\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "0123456789\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", methodOrVersion); assertEquals("200", uriOrStatus); assertNull(versionOrReason); assertEquals(content.length(), 10); assertTrue(headerCompleted); assertTrue(messageCompleted); }
@Test void testResponse304WithContentLength() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 304 found\r\n" + "Content-Length: 10\r\n" + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", methodOrVersion); assertEquals("304", uriOrStatus); assertEquals("found", versionOrReason); assertNull(content); assertTrue(headerCompleted); assertTrue(messageCompleted); }
@Test void testResponse101WithTransferEncoding() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 101 switching protocols\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", methodOrVersion); assertEquals("101", uriOrStatus); assertEquals("switching protocols", versionOrReason); assertNull(content); assertTrue(headerCompleted); assertTrue(messageCompleted); }
@Test void testResponseReasonIso8859_1() { ByteBuffer buffer = BufferUtils.toBuffer( "HTTP/1.1 302 déplacé temporairement\r\n" + "Content-Length: 0\r\n" + "\r\n", StandardCharsets.ISO_8859_1); HttpParser.ResponseHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("HTTP/1.1", methodOrVersion); assertEquals("302", uriOrStatus); assertEquals("déplacé temporairement", versionOrReason); }
@Test void testHost() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: host\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("host", host); assertEquals(0, port); }
@Test void testUriHost11() { ByteBuffer buffer = BufferUtils.toBuffer( "GET http: + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("No Host", bad); assertEquals("http: assertEquals(0, port); }
@Test void testUriHost10() { ByteBuffer buffer = BufferUtils.toBuffer( "GET http: + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertNull(bad); assertEquals("http: assertEquals(0, port); }
@Test void testNoHost() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("No Host", bad); }
@Test void testIPHost() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: 192.168.0.1\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("192.168.0.1", host); assertEquals(0, port); }
@Test void testIPv6Host() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: [::1]\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("[::1]", host); assertEquals(0, port); }
@Test void testBadIPv6Host() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: [::1\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertTrue(bad.contains("Bad")); }
@Test void testHostPort() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: myhost:8888\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("myhost", host); assertEquals(8888, port); }
@Test void testHostBadPort() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: myhost:testBadPort\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertTrue(bad.contains("Bad Host")); assertFalse(messageCompleted); }
@Test void testIPHostPort() { ByteBuffer buffer = BufferUtils.toBuffer( "GET / HTTP/1.1\r\n" + "Host: 192.168.0.1:8888\r\n" + "Connection: close\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); parser.parseNext(buffer); assertEquals("192.168.0.1", host); assertEquals(8888, port); }