simplified startRequest

This commit is contained in:
Greg Wilkins 2014-06-09 14:12:46 +02:00
parent bedfda03d2
commit b2296cc2d4
11 changed files with 53 additions and 68 deletions

View File

@ -33,7 +33,7 @@ import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** A Parser for HTTP 0.9, 1.0 and 1.1 /** A Parser for 1.0 and 1.1
* <p> * <p>
* The is parser parses HTTP client and server messages from buffers * The is parser parses HTTP client and server messages from buffers
* passed in the {@link #parseNext(ByteBuffer)} method. The parsed * passed in the {@link #parseNext(ByteBuffer)} method. The parsed
@ -142,6 +142,7 @@ public class HttpParser
private String _methodString; private String _methodString;
private HttpVersion _version; private HttpVersion _version;
private ByteBuffer _uri=ByteBuffer.allocate(INITIAL_URI_LENGTH); // Tune? private ByteBuffer _uri=ByteBuffer.allocate(INITIAL_URI_LENGTH); // Tune?
private HttpURI _httpURI=new HttpURI(StandardCharsets.UTF_8);
private EndOfContent _endOfContent; private EndOfContent _endOfContent;
private long _contentLength; private long _contentLength;
private long _contentPosition; private long _contentPosition;
@ -618,11 +619,7 @@ public class HttpParser
{ {
// HTTP/0.9 // HTTP/0.9
_uri.flip(); _uri.flip();
handle=_requestHandler.startRequest(_method,_methodString,_uri,null)||handle; throw new BadMessage("HTTP/0.9 not supported");
setState(State.END);
BufferUtil.clear(buffer);
handle=_handler.headerComplete()||handle;
handle=_handler.messageComplete()||handle;
} }
else else
{ {
@ -713,11 +710,7 @@ public class HttpParser
{ {
// HTTP/0.9 // HTTP/0.9
_uri.flip(); _uri.flip();
handle=_requestHandler.startRequest(_method,_methodString,_uri, null)||handle; throw new BadMessage("HTTP/0.9 not supported");
setState(State.END);
BufferUtil.clear(buffer);
handle=_handler.headerComplete()||handle;
handle=_handler.messageComplete()||handle;
} }
} }
else if (ch<0) else if (ch<0)
@ -744,7 +737,13 @@ public class HttpParser
setState(State.HEADER); setState(State.HEADER);
_uri.flip(); _uri.flip();
handle=_requestHandler.startRequest(_method,_methodString,_uri, _version)||handle;
if (_method == HttpMethod.CONNECT)
_httpURI.parseConnect(_uri.array(),_uri.arrayOffset()+_uri.position(),_uri.remaining());
else
_httpURI.parse(_uri.array(),_uri.arrayOffset()+_uri.position(),_uri.remaining());
handle=_requestHandler.startRequest(_methodString,_httpURI, _version)||handle;
continue; continue;
} }
else if (ch>=HttpTokens.SPACE) else if (ch>=HttpTokens.SPACE)
@ -1567,6 +1566,7 @@ public class HttpParser
_contentChunk=null; _contentChunk=null;
_headerBytes=0; _headerBytes=0;
_host=false; _host=false;
_httpURI.clear();
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
@ -1637,17 +1637,18 @@ public class HttpParser
void proxied(String protocol, String sAddr, String dAddr, int sPort, int dPort); void proxied(String protocol, String sAddr, String dAddr, int sPort, int dPort);
} }
public interface RequestHandler<T> extends HttpHandler<T> public interface RequestHandler<T> extends HttpHandler<T>
{ {
/** /**
* This is the method called by parser when the HTTP request line is parsed * This is the method called by parser when the HTTP request line is parsed
* @param method The method as enum if of a known type * @param method The method
* @param methodString The method as a string
* @param uri The raw bytes of the URI. These are copied into a ByteBuffer that will not be changed until this parser is reset and reused. * @param uri The raw bytes of the URI. These are copied into a ByteBuffer that will not be changed until this parser is reset and reused.
* @param version * @param version
* @return true if handling parsing should return. * @return true if handling parsing should return.
*/ */
public abstract boolean startRequest(HttpMethod method, String methodString, ByteBuffer uri, HttpVersion version); public abstract boolean startRequest(String method, HttpURI uri, HttpVersion version);
/** /**
* This is the method called by the parser after it has parsed the host header (and checked it's format). This is * This is the method called by the parser after it has parsed the host header (and checked it's format). This is

View File

@ -256,10 +256,10 @@ public class HttpTester
private String _uri; private String _uri;
@Override @Override
public boolean startRequest(HttpMethod method, String methodString, ByteBuffer uri, HttpVersion version) public boolean startRequest(String method, HttpURI uri, HttpVersion version)
{ {
_method=methodString; _method=method;
_uri=BufferUtil.toUTF8String(uri); _uri=uri.toString();
_version=version; _version=version;
return false; return false;
} }

View File

@ -86,10 +86,8 @@ public class HttpParserTest
HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser parser= new HttpParser(handler); HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer); parseAll(parser,buffer);
assertEquals("GET", _methodOrVersion);
assertEquals("/999", _uriOrStatus); assertEquals("HTTP/0.9 not supported", _bad);
assertEquals(null, _versionOrReason);
assertEquals(-1, _headers);
} }
@Test @Test
@ -101,10 +99,7 @@ public class HttpParserTest
HttpParser.RequestHandler<ByteBuffer> handler = new Handler(); HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser parser= new HttpParser(handler); HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer); parseAll(parser,buffer);
assertEquals("POST", _methodOrVersion); assertEquals("HTTP/0.9 not supported", _bad);
assertEquals("/222", _uriOrStatus);
assertEquals(null, _versionOrReason);
assertEquals(-1, _headers);
} }
@Test @Test
@ -1504,14 +1499,14 @@ public class HttpParserTest
} }
@Override @Override
public boolean startRequest(HttpMethod httpMethod, String method, ByteBuffer uri, HttpVersion version) public boolean startRequest(String method, HttpURI uri, HttpVersion version)
{ {
_fields.clear(); _fields.clear();
_headers= -1; _headers= -1;
_hdr= new String[10]; _hdr= new String[10];
_val= new String[10]; _val= new String[10];
_methodOrVersion= method; _methodOrVersion= method;
_uriOrStatus= BufferUtil.toUTF8String(uri); _uriOrStatus= uri.toString();
_versionOrReason= version==null?null:version.asString(); _versionOrReason= version==null?null:version.asString();
fields=new HttpFields(); fields=new HttpFields();

View File

@ -12,7 +12,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-hpack</artifactId> <artifactId>http2-hpack</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>

View File

@ -45,7 +45,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-common</artifactId> <artifactId>http2-common</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http2.server;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
@ -41,12 +42,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel<ByteBuffer>
public void requestStart(HeadersFrame frame) public void requestStart(HeadersFrame frame)
{ {
// TODO: extract method, etc. // TODO: extract method, etc.
HttpMethod httpMethod = null;
String method = null; String method = null;
ByteBuffer uri = BufferUtil.toBuffer(0); HttpURI uri = new HttpURI("/foo/bar");
HttpVersion version = null; HttpVersion version = null;
startRequest(httpMethod, method, uri, version); startRequest(method, uri, version);
// TODO: See SPDY's // TODO: See SPDY's
} }

View File

@ -36,7 +36,6 @@ import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.http.HttpGenerator.ResponseInfo;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpURI;
@ -99,7 +98,6 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
private final HttpConfiguration _configuration; private final HttpConfiguration _configuration;
private final EndPoint _endPoint; private final EndPoint _endPoint;
private final HttpTransport _transport; private final HttpTransport _transport;
private final HttpURI _uri;
private final HttpChannelState _state; private final HttpChannelState _state;
private final Request _request; private final Request _request;
private final Response _response; private final Response _response;
@ -115,7 +113,6 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
_endPoint = endPoint; _endPoint = endPoint;
_transport = transport; _transport = transport;
_uri = new HttpURI(URIUtil.__CHARSET);
_state = new HttpChannelState(this); _state = new HttpChannelState(this);
input.init(_state); input.init(_state);
_request = new Request(this, input); _request = new Request(this, input);
@ -232,7 +229,6 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
_expect102Processing = false; _expect102Processing = false;
_request.recycle(); _request.recycle();
_response.recycle(); _response.recycle();
_uri.clear();
} }
@Override @Override
@ -255,7 +251,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
{ {
threadName = Thread.currentThread().getName(); threadName = Thread.currentThread().getName();
Thread.currentThread().setName(threadName + " - " + _uri); Thread.currentThread().setName(threadName + " - " + _request.getUri());
} }
HttpChannelState.Action action = _state.handling(); HttpChannelState.Action action = _state.handling();
@ -363,7 +359,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
if (e instanceof EofException) if (e instanceof EofException)
LOG.debug(e); LOG.debug(e);
else else
LOG.warn(String.valueOf(_uri), e); LOG.warn(String.valueOf(_request.getUri()), e);
_state.error(e); _state.error(e);
_request.setHandled(true); _request.setHandled(true);
handleException(e); handleException(e);
@ -492,38 +488,34 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
} }
@Override @Override
public boolean startRequest(HttpMethod httpMethod, String method, ByteBuffer uri, HttpVersion version) public boolean startRequest(String method, HttpURI uri, HttpVersion version)
{ {
_expect = false; _expect = false;
_expect100Continue = false; _expect100Continue = false;
_expect102Processing = false; _expect102Processing = false;
_request.setTimeStamp(System.currentTimeMillis()); _request.setTimeStamp(System.currentTimeMillis());
_request.setMethod(httpMethod, method); _request.setMethod(method);
if (httpMethod == HttpMethod.CONNECT) _request.setUri(uri);
_uri.parseConnect(uri.array(),uri.arrayOffset()+uri.position(),uri.remaining());
else
_uri.parse(uri.array(),uri.arrayOffset()+uri.position(),uri.remaining());
_request.setUri(_uri);
String path; String path;
try try
{ {
path = _uri.getDecodedPath(); path = uri.getDecodedPath();
} }
catch (Exception e) catch (Exception e)
{ {
LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1"); LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1");
LOG.ignore(e); LOG.ignore(e);
path = _uri.getDecodedPath(StandardCharsets.ISO_8859_1); path = uri.getDecodedPath(StandardCharsets.ISO_8859_1);
} }
String info = URIUtil.canonicalPath(path); String info = URIUtil.canonicalPath(path);
if (info == null) if (info == null)
{ {
if( path==null && _uri.getScheme()!=null &&_uri.getHost()!=null) if( path==null && uri.getScheme()!=null &&uri.getHost()!=null)
{ {
info = "/"; info = "/";
_request.setRequestURI(""); _request.setRequestURI("");
@ -610,7 +602,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
@Override @Override
public boolean parsedHostHeader(String host, int port) public boolean parsedHostHeader(String host, int port)
{ {
if (_uri.getHost()==null) if (_request.getUri().getHost()==null)
{ {
_request.setServerName(host); _request.setServerName(host);
_request.setServerPort(port); _request.setServerPort(port);

View File

@ -182,8 +182,7 @@ public class Request implements HttpServletRequest
private CookieCutter _cookies; private CookieCutter _cookies;
private DispatcherType _dispatcherType; private DispatcherType _dispatcherType;
private int _inputState = __NONE; private int _inputState = __NONE;
private HttpMethod _httpMethod; private String _httpMethod;
private String _httpMethodString;
private MultiMap<String> _queryParameters; private MultiMap<String> _queryParameters;
private MultiMap<String> _contentParameters; private MultiMap<String> _contentParameters;
private MultiMap<String> _parameters; private MultiMap<String> _parameters;
@ -813,7 +812,7 @@ public class Request implements HttpServletRequest
@Override @Override
public String getMethod() public String getMethod()
{ {
return _httpMethodString; return _httpMethod;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -1631,8 +1630,7 @@ public class Request implements HttpServletRequest
_context = null; _context = null;
_newContext=false; _newContext=false;
_serverName = null; _serverName = null;
_httpMethod=null; _httpMethod = null;
_httpMethodString = null;
_pathInfo = null; _pathInfo = null;
_port = 0; _port = 0;
_httpVersion = HttpVersion.HTTP_1_1; _httpVersion = HttpVersion.HTTP_1_1;
@ -1875,16 +1873,15 @@ public class Request implements HttpServletRequest
* @param method * @param method
* The method to set. * The method to set.
*/ */
public void setMethod(HttpMethod httpMethod, String method) public void setMethod(String method)
{ {
_httpMethod=httpMethod; _httpMethod = method;
_httpMethodString = method;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean isHead() public boolean isHead()
{ {
return HttpMethod.HEAD==_httpMethod; return HttpMethod.HEAD.asString().equals(_httpMethod);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -30,8 +30,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.SelectChannelEndPoint; import org.eclipse.jetty.io.SelectChannelEndPoint;
@ -105,10 +105,10 @@ public class ExtendedServerTest extends HttpServerTestBase
return new HttpChannelOverHttp(getConnector(), getHttpConfiguration(), getEndPoint(), this, httpInput) return new HttpChannelOverHttp(getConnector(), getHttpConfiguration(), getEndPoint(), this, httpInput)
{ {
@Override @Override
public boolean startRequest(HttpMethod httpMethod, String method, ByteBuffer uri, HttpVersion version) public boolean startRequest(String method, HttpURI uri, HttpVersion version)
{ {
getRequest().setAttribute("DispatchedAt",((ExtendedEndPoint)getEndPoint()).getLastSelected()); getRequest().setAttribute("DispatchedAt",((ExtendedEndPoint)getEndPoint()).getLastSelected());
return super.startRequest(httpMethod,method,uri,version); return super.startRequest(method,uri,version);
} }
}; };
} }

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
@ -180,12 +181,10 @@ public class HttpChannelOverSPDY extends HttpChannel<DataInfo>
HttpMethod httpMethod = HttpMethod.fromString(methodHeader.getValue()); HttpMethod httpMethod = HttpMethod.fromString(methodHeader.getValue());
HttpVersion httpVersion = HttpVersion.fromString(versionHeader.getValue()); HttpVersion httpVersion = HttpVersion.fromString(versionHeader.getValue());
// TODO should handle URI as byte buffer as some bad clients send WRONG encodings in query string HttpURI uri = new HttpURI(uriHeader.getValue());
// that we have to deal with
ByteBuffer uri = BufferUtil.toBuffer(uriHeader.getValue());
LOG.debug("HTTP > {} {} {}", httpMethod, uriHeader.getValue(), httpVersion); LOG.debug("HTTP > {} {} {}", httpMethod, uriHeader.getValue(), httpVersion);
startRequest(httpMethod, httpMethod.asString(), uri, httpVersion); startRequest(methodHeader.getValue(), uri, httpVersion);
Fields.Field schemeHeader = headers.get(HTTPSPDYHeader.SCHEME.name(version)); Fields.Field schemeHeader = headers.get(HTTPSPDYHeader.SCHEME.name(version));
if (schemeHeader != null) if (schemeHeader != null)

View File

@ -29,6 +29,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
@ -81,13 +82,13 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
} }
@Override @Override
public boolean startRequest(HttpMethod method, String methodString, ByteBuffer uri, HttpVersion httpVersion) public boolean startRequest(String methodString, HttpURI uri, HttpVersion httpVersion)
{ {
Connector connector = getConnector(); Connector connector = getConnector();
String scheme = connector.getConnectionFactory(SslConnectionFactory.class) != null ? "https" : "http"; String scheme = connector.getConnectionFactory(SslConnectionFactory.class) != null ? "https" : "http";
headers.put(HTTPSPDYHeader.SCHEME.name(version), scheme); headers.put(HTTPSPDYHeader.SCHEME.name(version), scheme);
headers.put(HTTPSPDYHeader.METHOD.name(version), methodString); headers.put(HTTPSPDYHeader.METHOD.name(version), methodString);
headers.put(HTTPSPDYHeader.URI.name(version), BufferUtil.toUTF8String(uri)); // TODO handle bad encodings headers.put(HTTPSPDYHeader.URI.name(version), uri.toString());
headers.put(HTTPSPDYHeader.VERSION.name(version), httpVersion.asString()); headers.put(HTTPSPDYHeader.VERSION.name(version), httpVersion.asString());
return false; return false;
} }