diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index 17d9c01bc44..8a0f941740c 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -652,6 +652,9 @@ public class HttpParser case CACHE_CONTROL: case USER_AGENT: add_to_connection_trie=_connectionFields!=null && _field==null; + break; + + default: break; } if (add_to_connection_trie && !_connectionFields.isFull() && _header!=null && _valueString!=null) @@ -1089,6 +1092,8 @@ public class HttpParser BufferUtil.clear(buffer); } return false; + default: break; + } // Request/response line @@ -1262,6 +1267,9 @@ public class HttpParser BufferUtil.clear(buffer); return false; } + + default: + break; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index 69433f5e3ab..fa44d560690 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -207,8 +207,29 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http // Can the parser progress (even with an empty buffer) boolean call_channel=_parser.parseNext(_requestBuffer==null?BufferUtil.EMPTY_BUFFER:_requestBuffer); - // If there is a request buffer, we are re-entering here - if (!call_channel && BufferUtil.isEmpty(_requestBuffer)) + // Parse the buffer + if (call_channel) + { + // Parse as much content as there is available before calling the channel + // this is both efficient (may queue many chunks), will correctly set available for 100 continues + // and will drive the parser to completion if all content is available. + while (_parser.inContentState()) + { + if (!_parser.parseNext(_requestBuffer==null?BufferUtil.EMPTY_BUFFER:_requestBuffer)) + break; + } + + // The parser returned true, which indicates the channel is ready to handle a request. + // Call the channel and this will either handle the request/response to completion OR, + // if the request suspends, the request/response will be incomplete so the outer loop will exit. + + _channel.run(); + + // Return if suspended or upgraded + if (_channel.getState().isSuspended() || getEndPoint().getConnection()!=this) + return; + } + else if (BufferUtil.isEmpty(_requestBuffer)) { if (_requestBuffer == null) _requestBuffer = _bufferPool.acquire(getInputBufferSize(), REQUEST_BUFFER_DIRECT); @@ -242,33 +263,15 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http releaseRequestBuffer(); return; } - - // Parse what we have read - call_channel=_parser.parseNext(_requestBuffer); } - - // Parse the buffer - if (call_channel) + else { - // Parse as much content as there is available before calling the channel - // this is both efficient (may queue many chunks), will correctly set available for 100 continues - // and will drive the parser to completion if all content is available. - while (_parser.inContentState()) - { - if (!_parser.parseNext(_requestBuffer==null?BufferUtil.EMPTY_BUFFER:_requestBuffer)) - break; - } - - // The parser returned true, which indicates the channel is ready to handle a request. - // Call the channel and this will either handle the request/response to completion OR, - // if the request suspends, the request/response will be incomplete so the outer loop will exit. - - _channel.run(); - - // Return if suspended or upgraded - if (_channel.getState().isSuspended() || getEndPoint().getConnection()!=this) - return; - } + // TODO work out how we can get here and a better way to handle it + LOG.warn("Unexpected state: "+this+ " "+_channel+" "+_channel.getRequest()); + getEndPoint().close(); + return; + } + System.err.println(_channel.getRequest()); } } catch (EofException e)