Refactored HttpChannel to not have direct HttpParser dependency

This commit is contained in:
Greg Wilkins 2014-06-17 00:02:50 +02:00
parent 334db9fe72
commit 272e1d8da5
55 changed files with 617 additions and 613 deletions

View File

@ -35,7 +35,7 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.CompletableCallback;
public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.ResponseHandler<ByteBuffer>
public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.ResponseHandler
{
private final HttpParser parser = new HttpParser(this);
private ByteBuffer buffer;

View File

@ -71,7 +71,7 @@ public class ResponseContentParser extends StreamContentParser
parsers.remove(request);
}
private class ResponseParser implements HttpParser.ResponseHandler<ByteBuffer>
private class ResponseParser implements HttpParser.ResponseHandler
{
private final HttpFields fields = new HttpFields();
private ClientParser.Listener listener;
@ -292,7 +292,7 @@ public class ResponseContentParser extends StreamContentParser
// Methods overridden to make them visible here
private static class FCGIHttpParser extends HttpParser
{
private FCGIHttpParser(ResponseHandler<ByteBuffer> handler)
private FCGIHttpParser(ResponseHandler handler)
{
super(handler, 65 * 1024, true);
reset();

View File

@ -27,10 +27,14 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpChannel;
@ -40,18 +44,19 @@ import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
public class HttpChannelOverFCGI extends HttpChannel
{
private static final Logger LOG = Log.getLogger(HttpChannelOverFCGI.class);
private final List<HttpField> fields = new ArrayList<>();
private final HttpFields fields = new HttpFields();
private final Dispatcher dispatcher;
private String method;
private String path;
private String query;
private String version;
private HostPortHttpField host;
public HttpChannelOverFCGI(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput<ByteBuffer> input)
public HttpChannelOverFCGI(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input)
{
super(connector, configuration, endPoint, transport, input);
this.dispatcher = new Dispatcher(connector.getExecutor(), this);
@ -67,26 +72,25 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
query = field.getValue();
else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(field.getName()))
version = field.getValue();
else if (field.getHeader()==HttpHeader.HOST)
{
host=new HostPortHttpField(HttpHeader.HOST,HttpHeader.HOST.asString(),field.getValue());
fields.add(host);
}
else
fields.add(field);
}
@Override
public boolean headerComplete()
public void onRequest()
{
String uri = path;
if (query != null && query.length() > 0)
uri += "?" + query;
startRequest(method, new HttpURI(uri),HttpVersion.fromString(version));
for (HttpField fcgiField : fields)
{
HttpField httpField = convertHeader(fcgiField);
if (httpField != null)
parsedHeader(httpField);
}
return super.headerComplete();
if (host==null)
onRequest(new MetaData.Request(HttpVersion.fromString(version),method,new HttpURI(uri),fields,null,0));
else
onRequest(new MetaData.Request(HttpVersion.fromString(version),method,new HttpURI(uri),fields,host.getHost(),host.getPort()));
}
private HttpField convertHeader(HttpField field)

View File

@ -29,9 +29,10 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.ByteBufferQueuedHttpInput;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpInput;
import org.eclipse.jetty.server.QueuedHttpInput;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -122,7 +123,7 @@ public class ServerFCGIConnection extends AbstractConnection
// TODO: handle flags
HttpChannelOverFCGI channel = new HttpChannelOverFCGI(connector, configuration, getEndPoint(),
new HttpTransportOverFCGI(connector.getByteBufferPool(), flusher, request, sendStatus200),
new ByteBufferQueuedHttpInput());
new QueuedHttpInput());
HttpChannelOverFCGI existing = channels.putIfAbsent(request, channel);
if (existing != null)
throw new IllegalStateException();
@ -148,8 +149,8 @@ public class ServerFCGIConnection extends AbstractConnection
LOG.debug("Request {} headers on {}", request, channel);
if (channel != null)
{
if (channel.headerComplete())
channel.dispatch();
channel.onRequest();
channel.dispatch();
}
}
@ -161,8 +162,8 @@ public class ServerFCGIConnection extends AbstractConnection
LOG.debug("Request {} {} content {} on {}", request, stream, buffer, channel);
if (channel != null)
{
if (channel.content(buffer))
channel.dispatch();
// TODO avoid creating content all the time
channel.onContent(new HttpInput.Content(buffer));
}
return false;
}
@ -175,8 +176,8 @@ public class ServerFCGIConnection extends AbstractConnection
LOG.debug("Request {} end on {}", request, channel);
if (channel != null)
{
if (channel.messageComplete())
channel.dispatch();
channel.onRequestComplete();
channel.dispatch();
}
}
@ -188,7 +189,7 @@ public class ServerFCGIConnection extends AbstractConnection
LOG.debug("Request {} failure on {}: {}", request, channel, failure);
if (channel != null)
{
channel.badMessage(400, failure.toString());
channel.onBadMessage(400, failure.toString());
}
}
}

View File

@ -20,33 +20,33 @@
package org.eclipse.jetty.http;
/* ------------------------------------------------------------------------------- */
class BadMessage extends Error
public class BadMessage extends Error
{
final int _code;
final String _reason;
BadMessage()
public BadMessage()
{
this(400,null);
}
BadMessage(int code)
public BadMessage(int code)
{
this(code,null);
}
BadMessage(String reason)
public BadMessage(String reason)
{
this(400,reason);
}
BadMessage(int code,String reason)
public BadMessage(int code,String reason)
{
_code=code;
_reason=reason;
}
BadMessage(int code,String reason,Throwable cause)
public BadMessage(int code,String reason,Throwable cause)
{
super(cause);
_code=code;

View File

@ -122,9 +122,9 @@ public class HttpParser
}
private final boolean DEBUG=LOG.isDebugEnabled(); // Cache debug to help branch prediction
private final HttpHandler<ByteBuffer> _handler;
private final RequestHandler<ByteBuffer> _requestHandler;
private final ResponseHandler<ByteBuffer> _responseHandler;
private final HttpHandler _handler;
private final RequestHandler _requestHandler;
private final ResponseHandler _responseHandler;
private final int _maxHeaderBytes;
private final boolean _strict;
private HttpField _field;
@ -207,31 +207,31 @@ public class HttpParser
}
/* ------------------------------------------------------------------------------- */
public HttpParser(RequestHandler<ByteBuffer> handler)
public HttpParser(RequestHandler handler)
{
this(handler,-1,__STRICT);
}
/* ------------------------------------------------------------------------------- */
public HttpParser(ResponseHandler<ByteBuffer> handler)
public HttpParser(ResponseHandler handler)
{
this(handler,-1,__STRICT);
}
/* ------------------------------------------------------------------------------- */
public HttpParser(RequestHandler<ByteBuffer> handler,int maxHeaderBytes)
public HttpParser(RequestHandler handler,int maxHeaderBytes)
{
this(handler,maxHeaderBytes,__STRICT);
}
/* ------------------------------------------------------------------------------- */
public HttpParser(ResponseHandler<ByteBuffer> handler,int maxHeaderBytes)
public HttpParser(ResponseHandler handler,int maxHeaderBytes)
{
this(handler,maxHeaderBytes,__STRICT);
}
/* ------------------------------------------------------------------------------- */
public HttpParser(RequestHandler<ByteBuffer> handler,int maxHeaderBytes,boolean strict)
public HttpParser(RequestHandler handler,int maxHeaderBytes,boolean strict)
{
_handler=handler;
_requestHandler=handler;
@ -241,7 +241,7 @@ public class HttpParser
}
/* ------------------------------------------------------------------------------- */
public HttpParser(ResponseHandler<ByteBuffer> handler,int maxHeaderBytes,boolean strict)
public HttpParser(ResponseHandler handler,int maxHeaderBytes,boolean strict)
{
_handler=handler;
_requestHandler=null;
@ -799,20 +799,11 @@ public class HttpParser
case HOST:
_host=true;
HostPortHttpField hpfield;
if (_field!=null)
if (!(_field instanceof HostPortHttpField))
{
hpfield = (HostPortHttpField)_field;
}
else
{
_field=hpfield=new HostPortHttpField(_header,_strict?_headerString:_header.asString(),_valueString);
_field=new HostPortHttpField(_header,_strict?_headerString:_header.asString(),_valueString);
add_to_connection_trie=_connectionFields!=null;
}
if (_requestHandler!=null)
_requestHandler.parsedHostHeader(hpfield.getHost(),hpfield.getPort());
break;
case CONNECTION:
@ -1241,20 +1232,40 @@ public class HttpParser
{
BufferUtil.clear(buffer);
LOG.warn("badMessage: "+e._code+(e.getReason()!=null?" "+e.getReason():"")+" for "+_handler);
if (DEBUG)
LOG.debug(e);
Throwable cause = e.getCause();
boolean stack = (cause instanceof RuntimeException) || (cause instanceof Error) || LOG.isDebugEnabled();
if (stack)
LOG.warn("bad HTTP parsed: "+e._code+(e.getReason()!=null?" "+e.getReason():"")+" for "+_handler,e);
else
LOG.warn("bad HTTP parsed: "+e._code+(e.getReason()!=null?" "+e.getReason():"")+" for "+_handler);
setState(State.CLOSED);
_handler.badMessage(e.getCode(), e.getReason());
return false;
}
catch(Exception e)
catch(NumberFormatException|IllegalStateException e)
{
BufferUtil.clear(buffer);
LOG.warn("parse exception: "+e.toString()+" for "+_handler);
if (DEBUG)
LOG.debug(e);
if (_state.ordinal()<=State.END.ordinal())
{
setState(State.CLOSED);
_handler.badMessage(400,null);
}
else
{
_handler.earlyEOF();
setState(State.CLOSED);
}
return false;
}
catch(Exception|Error e)
{
BufferUtil.clear(buffer);
LOG.warn("badMessage: "+e.toString()+" for "+_handler);
if (DEBUG)
LOG.debug(e);
LOG.warn("parse exception: "+e.toString()+" for "+_handler,e);
if (_state.ordinal()<=State.END.ordinal())
{
@ -1507,9 +1518,9 @@ public class HttpParser
* headerComplete then messageComplete) from the same point in the parsing
* then it is sufficient for the caller to process the events only once.
*/
public interface HttpHandler<T>
public interface HttpHandler
{
public boolean content(T item);
public boolean content(ByteBuffer item);
public boolean headerComplete();
@ -1547,7 +1558,7 @@ public class HttpParser
public interface RequestHandler<T> extends HttpHandler<T>
public interface RequestHandler extends HttpHandler
{
/**
* This is the method called by parser when the HTTP request line is parsed
@ -1558,15 +1569,9 @@ public class HttpParser
*/
public 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
* called after the {@link HttpHandler#parsedHeader(HttpField)} methods and before
* HttpHandler#headerComplete();
*/
public void parsedHostHeader(String host,int port);
}
public interface ResponseHandler<T> extends HttpHandler<T>
public interface ResponseHandler extends HttpHandler
{
/**
* This is the method called by parser when the HTTP request line is parsed

View File

@ -73,7 +73,7 @@ public class HttpTester
}
public abstract static class Message extends HttpFields implements HttpParser.HttpHandler<ByteBuffer>
public abstract static class Message extends HttpFields implements HttpParser.HttpHandler
{
ByteArrayOutputStream _content;
HttpVersion _version=HttpVersion.HTTP_1_0;
@ -249,7 +249,7 @@ public class HttpTester
}
public static class Request extends Message implements HttpParser.RequestHandler<ByteBuffer>
public static class Request extends Message implements HttpParser.RequestHandler
{
private String _method;
private String _uri;
@ -299,14 +299,9 @@ public class HttpTester
{
put(name,value);
}
@Override
public void parsedHostHeader(String host,int port)
{
}
}
public static class Response extends Message implements HttpParser.ResponseHandler<ByteBuffer>
public static class Response extends Message implements HttpParser.ResponseHandler
{
private int _status;
private String _reason;

View File

@ -776,6 +776,15 @@ public class HttpURI
return _rawString;
}
public boolean equals(Object o)
{
if (o==this)
return true;
if (!(o instanceof HttpURI))
return false;
return toString().equals(o.toString());
}
public void writeTo(Utf8StringBuilder buf)
{
buf.append(_raw,_scheme,_end-_scheme);

View File

@ -17,26 +17,29 @@
//
package org.eclipse.jetty.http2.hpack;
package org.eclipse.jetty.http;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
/* ------------------------------------------------------------ */
/**
*/
public class MetaData implements Iterable<HttpField>
{
private final HttpVersion _version;
private final HttpFields _fields;
public MetaData(HttpFields fields)
public MetaData(HttpVersion version,HttpFields fields)
{
_fields=fields;
_version=version;
}
public HttpVersion getHttpVersion()
{
return _version;
}
public boolean isRequest()
@ -99,19 +102,34 @@ public class MetaData implements Iterable<HttpField>
{
private final String _method;
private final HttpScheme _scheme;
private final String _authority;
private final String _host;
private final int _port;
private final String _path;
private final HttpURI _uri;
public Request(HttpScheme scheme, String method, String authority, String host, int port, String path, HttpFields fields)
public Request(HttpVersion version, String method, HttpURI uri, HttpFields fields,String host, int port)
{
super(fields);
_authority=authority;
super(version,fields);
_host=host;
_port=port;
_method=method;
_path=path;
_uri=uri;
String scheme=uri.getScheme();
if (scheme==null)
_scheme=HttpScheme.HTTP;
else
{
HttpScheme s = HttpScheme.CACHE.get(scheme);
_scheme=s==null?HttpScheme.HTTP:s;
}
}
public Request(HttpVersion version, HttpScheme scheme, String method, String authority, String host, int port, String path, HttpFields fields)
{
super(version,fields);
_host=host;
_port=port;
_method=method;
_uri=new HttpURI(path); // TODO - this is not so efficient!
_scheme=scheme;
}
@ -137,11 +155,6 @@ public class MetaData implements Iterable<HttpField>
return _scheme;
}
public String getAuthority()
{
return _authority;
}
public String getHost()
{
return _host;
@ -152,9 +165,9 @@ public class MetaData implements Iterable<HttpField>
return _port;
}
public String getPath()
public HttpURI getURI()
{
return _path;
return _uri;
}
@Override
@ -165,8 +178,7 @@ public class MetaData implements Iterable<HttpField>
Request r = (Request)o;
if (!_method.equals(r._method) ||
!_scheme.equals(r._scheme) ||
!_authority.equals(r._authority) ||
!_path.equals(r._path))
!_uri.equals(r._uri))
return false;
return super.equals(o);
}
@ -174,7 +186,7 @@ public class MetaData implements Iterable<HttpField>
@Override
public String toString()
{
return _method+" "+_scheme+"://"+_authority+_path+" HTTP/2\n"+super.toString();
return _method+" "+_scheme+"://"+_host+':'+_port+_uri+" HTTP/2\n"+super.toString();
}
}
@ -186,9 +198,9 @@ public class MetaData implements Iterable<HttpField>
{
private final int _status;
public Response(int status, HttpFields fields)
public Response(HttpVersion version, int status, HttpFields fields)
{
super(fields);
super(version,fields);
_status=status;
}

View File

@ -216,7 +216,7 @@ public class HttpGeneratorServerHTTPTest
}
}
private class Handler implements HttpParser.ResponseHandler<ByteBuffer>
private class Handler implements HttpParser.ResponseHandler
{
@Override
public boolean content(ByteBuffer ref)

View File

@ -68,7 +68,7 @@ public class HttpParserTest
{
ByteBuffer buffer= BufferUtil.toBuffer("POST /foo HTTP/1.0\015\012" + "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("POST", _methodOrVersion);
@ -83,7 +83,7 @@ public class HttpParserTest
ByteBuffer buffer= BufferUtil.toBuffer("GET /999\015\012");
_versionOrReason= null;
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -96,7 +96,7 @@ public class HttpParserTest
ByteBuffer buffer= BufferUtil.toBuffer("POST /222 \015\012");
_versionOrReason= null;
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("HTTP/0.9 not supported", _bad);
@ -107,7 +107,7 @@ public class HttpParserTest
{
ByteBuffer buffer= BufferUtil.toBuffer("POST /fo\u0690 HTTP/1.0\015\012" + "\015\012",StandardCharsets.UTF_8);
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("POST", _methodOrVersion);
@ -121,7 +121,7 @@ public class HttpParserTest
{
ByteBuffer buffer= BufferUtil.toBuffer("POST /foo?param=\u0690 HTTP/1.0\015\012" + "\015\012",StandardCharsets.UTF_8);
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("POST", _methodOrVersion);
@ -135,7 +135,7 @@ public class HttpParserTest
{
ByteBuffer buffer= BufferUtil.toBuffer("POST /123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/123456789abcdef/ HTTP/1.0\015\012" + "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("POST", _methodOrVersion);
@ -148,7 +148,7 @@ public class HttpParserTest
public void testConnect() throws Exception
{
ByteBuffer buffer= BufferUtil.toBuffer("CONNECT 192.168.1.2:80 HTTP/1.1\015\012" + "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("CONNECT", _methodOrVersion);
@ -166,7 +166,7 @@ public class HttpParserTest
"Connection: close\015\012" +
"\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -192,7 +192,7 @@ public class HttpParserTest
" extra\015\012" +
"\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -210,7 +210,7 @@ public class HttpParserTest
" Name: value\015\012" +
"\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -270,7 +270,7 @@ public class HttpParserTest
BufferUtil.put(b0,buffer);
BufferUtil.flipToFlush(buffer,pos);
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -316,7 +316,7 @@ public class HttpParserTest
"Accept-Encoding: gzip, deflated\015\012" +
"Accept: unknown\015\012" +
"\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -364,7 +364,7 @@ public class HttpParserTest
"Accept-Encoding: gzip, deflated\n" +
"Accept: unknown\n" +
"\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -403,7 +403,7 @@ public class HttpParserTest
"Name1: \"value\t1\"\n" +
"Name2: \"value\t2A\",\"value,2B\"\t\n" +
"\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -432,7 +432,7 @@ public class HttpParserTest
BufferUtil.put(BufferUtil.toBuffer(" \r\n\r\n"),buffer);
BufferUtil.flipToFlush(buffer,0);
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -453,7 +453,7 @@ public class HttpParserTest
ByteBuffer buffer= BufferUtil.toBuffer(
"G\u00e6T / HTTP/1.0\r\nHeader0: value0\r\n\n\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertThat(_bad,Matchers.notNullValue());
@ -465,7 +465,7 @@ public class HttpParserTest
ByteBuffer buffer= BufferUtil.toBuffer(
"GET / H\u00e6P/1.0\r\nHeader0: value0\r\n\n\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertThat(_bad,Matchers.notNullValue());
@ -478,7 +478,7 @@ public class HttpParserTest
ByteBuffer buffer= BufferUtil.toBuffer(
"GET / HTTP/1.0\r\nH\u00e6der0: value0\r\n\n\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertThat(_bad,Matchers.notNullValue());
@ -493,7 +493,7 @@ public class HttpParserTest
"Header: value\talternate\r\n" +
"\n\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -514,7 +514,7 @@ public class HttpParserTest
"HOST: localhost\015\012" +
"cOnNeCtIoN: ClOsE\015\012"+
"\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler,-1,false);
parseAll(parser,buffer);
@ -536,7 +536,7 @@ public class HttpParserTest
"HOST: localhost\015\012" +
"cOnNeCtIoN: ClOsE\015\012"+
"\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler,-1,true);
parseAll(parser,buffer);
@ -568,7 +568,7 @@ public class HttpParserTest
for (int i=0;i<buffer.capacity()-4;i++)
{
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
// System.err.println(BufferUtil.toDetailString(buffer));
@ -618,7 +618,7 @@ public class HttpParserTest
+ "1a\015\012"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ\015\012"
+ "0\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
@ -634,7 +634,7 @@ public class HttpParserTest
@Test
public void testStartEOF() throws Exception
{
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.atEOF();
parser.parseNext(BufferUtil.EMPTY_BUFFER);
@ -651,7 +651,7 @@ public class HttpParserTest
+ "Content-Length: 20\015\012"
+ "\015\012"
+ "0123456789");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.atEOF();
parseAll(parser,buffer);
@ -674,7 +674,7 @@ public class HttpParserTest
+ "\015\012"
+ "a;\015\012"
+ "0123456789\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.atEOF();
parseAll(parser,buffer);
@ -722,7 +722,7 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("GET", _methodOrVersion);
@ -790,7 +790,7 @@ public class HttpParserTest
+ "0123456789\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer0);
parser.atEOF();
@ -836,7 +836,7 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -855,7 +855,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -879,7 +879,7 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -912,7 +912,7 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -933,7 +933,7 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -953,7 +953,7 @@ public class HttpParserTest
+ "\015\012"
+ "0123456789\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.atEOF();
parser.parseNext(buffer);
@ -975,7 +975,7 @@ public class HttpParserTest
+ "Content-Length: 10\015\012"
+ "\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -994,7 +994,7 @@ public class HttpParserTest
+ "Transfer-Encoding: chunked\015\012"
+ "\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("HTTP/1.1", _methodOrVersion);
@ -1017,7 +1017,7 @@ public class HttpParserTest
+ "HTTP/1.1 400 OK\015\012"); // extra data causes close ??
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1045,7 +1045,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1065,7 +1065,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1084,7 +1084,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1103,7 +1103,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1122,7 +1122,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.ResponseHandler<ByteBuffer> handler = new Handler();
HttpParser.ResponseHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1141,7 +1141,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1175,7 +1175,7 @@ public class HttpParserTest
+ "Connection: close\r"
+ "\r");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1211,7 +1211,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1230,7 +1230,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1249,7 +1249,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
@ -1268,7 +1268,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("host",_host);
@ -1283,7 +1283,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("No Host",_bad);
@ -1298,7 +1298,7 @@ public class HttpParserTest
"GET http://host/ HTTP/1.0\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
Assert.assertNull(_bad);
@ -1314,7 +1314,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("No Host",_bad);
@ -1329,7 +1329,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("192.168.0.1",_host);
@ -1345,7 +1345,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("::1",_host);
@ -1361,7 +1361,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
Assert.assertThat(_bad,Matchers.containsString("Bad"));
@ -1376,7 +1376,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("myhost",_host);
@ -1392,7 +1392,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
Assert.assertThat(_bad,Matchers.containsString("Bad Host"));
@ -1407,7 +1407,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("192.168.0.1",_host);
@ -1423,7 +1423,7 @@ public class HttpParserTest
+ "Connection: close\015\012"
+ "\015\012");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parser.parseNext(buffer);
assertEquals("::1",_host);
@ -1438,7 +1438,7 @@ public class HttpParserTest
"Host: www.smh.com.au\r\n"+
"\r\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser.RequestHandler handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("www.smh.com.au",parser.getFieldCache().get("Host: www.smh.com.au").getValue());
@ -1540,7 +1540,7 @@ public class HttpParserTest
private boolean _headerCompleted;
private boolean _messageCompleted;
private class Handler implements HttpParser.RequestHandler<ByteBuffer>, HttpParser.ResponseHandler<ByteBuffer>, HttpParser.ProxyHandler
private class Handler implements HttpParser.RequestHandler, HttpParser.ResponseHandler, HttpParser.ProxyHandler
{
private HttpFields fields;
String _proxy;
@ -1582,13 +1582,13 @@ public class HttpParserTest
//System.err.println("header "+name+": "+value);
_hdr[++_headers]= field.getName();
_val[_headers]= field.getValue();
}
@Override
public void parsedHostHeader(String host,int port)
{
_host=host;
_port=port;
if (field instanceof HostPortHttpField)
{
HostPortHttpField hpfield = (HostPortHttpField)field;
_host=hpfield.getHost();
_port=hpfield.getPort();
}
}
@Override

View File

@ -18,7 +18,7 @@
package org.eclipse.jetty.http2.frames;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http.MetaData;
public class HeadersFrame extends Frame
{

View File

@ -18,7 +18,7 @@
package org.eclipse.jetty.http2.frames;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http.MetaData;
public class PushPromiseFrame extends Frame
{

View File

@ -20,12 +20,12 @@ package org.eclipse.jetty.http2.generator;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.frames.Flag;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;

View File

@ -25,7 +25,7 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;

View File

@ -20,8 +20,8 @@ package org.eclipse.jetty.http2.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackDecoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;

View File

@ -20,10 +20,10 @@ package org.eclipse.jetty.http2.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.frames.Flag;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.util.BufferUtil;
public class HeadersBodyParser extends BodyParser

View File

@ -21,7 +21,7 @@ package org.eclipse.jetty.http2.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http.MetaData;
public class PushPromiseBodyParser extends BodyParser
{

View File

@ -25,10 +25,11 @@ import java.util.List;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
import org.eclipse.jetty.http2.generator.HeadersGenerator;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
@ -50,7 +51,7 @@ public class HeadersGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0, HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
// Iterate a few times to be sure generator and parser are properly reset.
final List<HeadersFrame> frames = new ArrayList<>();
@ -84,10 +85,9 @@ public class HeadersGenerateParseTest
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getAuthority(), request.getAuthority());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getPath(), request.getPath());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
HttpField field = fields.getField(j);
@ -105,7 +105,7 @@ public class HeadersGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0, HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
final List<HeadersFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
@ -135,10 +135,9 @@ public class HeadersGenerateParseTest
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getAuthority(), request.getAuthority());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getPath(), request.getPath());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
HttpField field = fields.getField(j);

View File

@ -25,10 +25,11 @@ import java.util.List;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.generator.HeaderGenerator;
import org.eclipse.jetty.http2.generator.PushPromiseGenerator;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
@ -51,7 +52,7 @@ public class PushPromiseGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0, HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
// Iterate a few times to be sure generator and parser are properly reset.
final List<PushPromiseFrame> frames = new ArrayList<>();
@ -85,10 +86,9 @@ public class PushPromiseGenerateParseTest
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getAuthority(), request.getAuthority());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getPath(), request.getPath());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
HttpField field = fields.getField(j);
@ -107,7 +107,7 @@ public class PushPromiseGenerateParseTest
HttpFields fields = new HttpFields();
fields.put("Accept", "text/html");
fields.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0, HttpScheme.HTTP, "GET", "localhost:8080", "localhost", 8080, "/path", fields);
final List<PushPromiseFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
@ -137,10 +137,9 @@ public class PushPromiseGenerateParseTest
MetaData.Request request = (MetaData.Request)frame.getMetaData();
Assert.assertSame(metaData.getScheme(), request.getScheme());
Assert.assertEquals(metaData.getMethod(), request.getMethod());
Assert.assertEquals(metaData.getAuthority(), request.getAuthority());
Assert.assertEquals(metaData.getHost(), request.getHost());
Assert.assertEquals(metaData.getPort(), request.getPort());
Assert.assertEquals(metaData.getPath(), request.getPath());
Assert.assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
{
HttpField field = fields.getField(j);

View File

@ -26,6 +26,7 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;

View File

@ -25,6 +25,7 @@ import java.util.EnumSet;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.eclipse.jetty.io.ByteBufferPool.Lease;
import org.eclipse.jetty.util.BufferUtil;
@ -136,8 +137,8 @@ public class HpackEncoder
// TODO optimise these to avoid HttpField creation
encode(buffer,new HttpField(":scheme",request.getScheme().asString()));
encode(buffer,new HttpField(":method",request.getMethod()));
encode(buffer,new HttpField(":authority",request.getAuthority())); // TODO look for host header?
encode(buffer,new HttpField(":path",request.getPath()));
encode(buffer,new HttpField(":authority",request.getPort()>0?(request.getHost()+':'+request.getPort()):request.getHost()));
encode(buffer,new HttpField(":path",request.getURI().getPath()));
}
else if (metadata.isResponse())

View File

@ -24,6 +24,8 @@ import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
@ -105,10 +107,10 @@ public class MetaDataBuilder
HttpFields fields = _fields;
_fields = new HttpFields(Math.max(10,fields.size()+5));
if (_method!=null)
return new MetaData.Request(_scheme,_method,_authority,_host,_port,_path,fields);
return new MetaData.Request(HttpVersion.HTTP_2_0,_scheme,_method,_authority,_host,_port,_path,fields);
if (_status!=0)
return new MetaData.Response(_status,fields);
return new MetaData(fields);
return new MetaData.Response(HttpVersion.HTTP_2_0,_status,fields);
return new MetaData(HttpVersion.HTTP_2_0,fields);
}
finally
{

View File

@ -25,6 +25,7 @@ import java.util.Iterator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.Test;
@ -52,8 +53,8 @@ public class HpackDecoderTest
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertFalse(request.iterator().hasNext());
@ -65,8 +66,8 @@ public class HpackDecoderTest
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
Iterator<HttpField> iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("cache-control","no-cache"),iterator.next());
@ -81,8 +82,8 @@ public class HpackDecoderTest
assertEquals("GET",request.getMethod());
assertEquals(HttpScheme.HTTPS,request.getScheme());
assertEquals("/index.html",request.getPath());
assertEquals("www.example.com",request.getAuthority());
assertEquals("/index.html",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("custom-key","custom-value"),iterator.next());
@ -102,8 +103,8 @@ public class HpackDecoderTest
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
assertFalse(request.iterator().hasNext());
@ -115,8 +116,8 @@ public class HpackDecoderTest
assertEquals("GET", request.getMethod());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
assertEquals("/",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
Iterator<HttpField> iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("cache-control","no-cache"),iterator.next());
@ -130,8 +131,8 @@ public class HpackDecoderTest
assertEquals("GET",request.getMethod());
assertEquals(HttpScheme.HTTPS,request.getScheme());
assertEquals("/index.html",request.getPath());
assertEquals("www.example.com",request.getAuthority());
assertEquals("/index.html",request.getURI().getPath());
assertEquals("www.example.com",request.getHost());
iterator=request.iterator();
assertTrue(iterator.hasNext());
assertEquals(new HttpField("custom-key","custom-value"),iterator.next());

View File

@ -25,6 +25,8 @@ import java.util.HashSet;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.eclipse.jetty.util.BufferUtil;
import org.hamcrest.Matchers;
@ -68,7 +70,7 @@ public class HpackEncoderTest
// encode them
ByteBuffer buffer = BufferUtil.allocate(4096);
int pos = BufferUtil.flipToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,pos);
// something was encoded!
@ -87,7 +89,7 @@ public class HpackEncoderTest
// encode exact same fields again!
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// nothing should be encoded!
@ -110,7 +112,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -134,7 +136,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -161,7 +163,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -189,7 +191,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -223,7 +225,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -244,7 +246,7 @@ public class HpackEncoderTest
// encode
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!
@ -256,7 +258,7 @@ public class HpackEncoderTest
// encode again
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,new MetaData(fields));
encoder.encode(buffer,new MetaData(HttpVersion.HTTP_2_0,fields));
BufferUtil.flipToFlush(buffer,0);
// something was encoded!

View File

@ -23,10 +23,11 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpVersion;
import org.junit.Assert;
import org.junit.Test;
import org.eclipse.jetty.http2.hpack.MetaData.Response;
import org.eclipse.jetty.http2.hpack.MetaData.Request;
import org.eclipse.jetty.http.MetaData.Request;
import org.eclipse.jetty.http.MetaData.Response;
import org.eclipse.jetty.util.BufferUtil;
@ -45,7 +46,7 @@ public class HpackTest
fields0.add(HttpHeader.SERVER,"jetty");
fields0.add(HttpHeader.SET_COOKIE,"abcdefghijklmnopqrstuvwxyz");
fields0.add("custom-key","custom-value");
Response original0 = new Response(200,fields0);
Response original0 = new Response(HttpVersion.HTTP_2_0,200,fields0);
BufferUtil.clearToFill(buffer);
encoder.encode(buffer,original0);
@ -60,15 +61,14 @@ public class HpackTest
BufferUtil.flipToFlush(buffer,0);
Response decoded0b = (Response)decoder.decode(buffer);
Assert.assertEquals(original0,decoded0b);
Assert.assertEquals(original0,decoded0b);
HttpFields fields1 = new HttpFields();
fields1.add(HttpHeader.CONTENT_TYPE,"text/plain");
fields1.add(HttpHeader.CONTENT_LENGTH,"1234");
fields1.add(HttpHeader.SERVER,"jetty");
fields1.add("custom-key","other-value");
Response original1 = new Response(200,fields1);
Response original1 = new Response(HttpVersion.HTTP_2_0,200,fields1);
// Same again?
BufferUtil.clearToFill(buffer);

View File

@ -23,13 +23,10 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector;
@ -42,12 +39,13 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class HttpChannelOverHTTP2 extends HttpChannel<ByteBufferCallback>
public class HttpChannelOverHTTP2 extends HttpChannel
{
private static final Logger LOG = Log.getLogger(HttpChannelOverHTTP2.class);
private static final HttpField ACCEPT_ENCODING_GZIP = new HttpField(HttpHeader.ACCEPT_ENCODING,"gzip");
private final Stream stream;
public HttpChannelOverHTTP2(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput<ByteBufferCallback> input, Stream stream)
public HttpChannelOverHTTP2(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input, Stream stream)
{
super(connector, configuration, endPoint, transport, input);
this.stream = stream;
@ -58,88 +56,66 @@ public class HttpChannelOverHTTP2 extends HttpChannel<ByteBufferCallback>
MetaData metaData = frame.getMetaData();
if (!metaData.isRequest())
{
badMessage(400, null);
onBadMessage(400, null);
return;
}
MetaData.Request requestMetaData = (MetaData.Request)metaData;
String method = requestMetaData.getMethod();
HttpURI uri = new HttpURI(requestMetaData.getPath());
HttpVersion version = HttpVersion.HTTP_2_0;
startRequest(method, uri, version);
HttpScheme scheme = requestMetaData.getScheme();
if (scheme != null)
{
getRequest().setScheme(scheme.asString());
}
parsedHostHeader(requestMetaData.getHost(), requestMetaData.getPort());
MetaData.Request request = (MetaData.Request)metaData;
// The specification says user agents MUST support gzip encoding.
// Based on that, some browser does not send the header, but it's
// important that applications can find it (e.g. GzipFilter).
boolean hasAcceptEncodingGzip = false;
HttpFields fields = requestMetaData.getFields();
for (int i = 0; i < fields.size(); ++i)
{
HttpField field = fields.getField(i);
if (HttpHeader.ACCEPT_ENCODING.is(field.getName()))
hasAcceptEncodingGzip = field.getValue().contains("gzip");
parsedHeader(field);
}
if (!hasAcceptEncodingGzip)
parsedHeader(new HttpField(HttpHeader.ACCEPT_ENCODING, "gzip"));
headerComplete();
HttpFields fields = request.getFields();
if (!fields.contains(ACCEPT_ENCODING_GZIP))
fields.add(ACCEPT_ENCODING_GZIP);
onRequest(request);
if (frame.isEndStream())
{
messageComplete();
onRequestComplete();
}
if (LOG.isDebugEnabled())
{
StringBuilder headers = new StringBuilder();
for (HttpField field : fields)
{
headers.append(field).append(System.lineSeparator());
}
LOG.debug("HTTP2 Request #{}:{}{} {} {}{}{}",
stream.getId(), System.lineSeparator(), method, uri, version, System.lineSeparator(), headers);
stream.getId(), System.lineSeparator(), request.getMethod(), request.getURI(), request.getHttpVersion(), System.lineSeparator(), fields);
}
// TODO: pending refactoring of HttpChannel API.
// Here we "cheat", knowing that headerComplete() will always return true
// and that content() and messageComplete() will always return false.
// This is the only place where we process the channel.
execute(this);
}
public void requestContent(DataFrame frame, Callback callback)
public void requestContent(DataFrame frame, final Callback callback)
{
// We must copy the data since we do not know when its bytes will be consumed.
ByteBufferPool byteBufferPool = getByteBufferPool();
final ByteBufferPool byteBufferPool = getByteBufferPool();
ByteBuffer original = frame.getData();
final ByteBuffer copy = byteBufferPool.acquire(original.remaining(), original.isDirect());
BufferUtil.clearToFill(copy);
copy.put(original).flip();
// TODO: pending refactoring of HttpChannel API (see above).
content(new ByteBufferCallback(byteBufferPool, copy, callback));
onContent(new HttpInput.Content(copy)
{
@Override
public void succeeded()
{
byteBufferPool.release(copy);
callback.succeeded();
}
@Override
public void failed(Throwable x)
{
byteBufferPool.release(copy);
callback.failed(x);
}
});
if (frame.isEndStream())
{
messageComplete();
onRequestComplete();
}
}
@Override
public boolean messageComplete()
{
super.messageComplete();
return false;
}
}

View File

@ -18,39 +18,8 @@
package org.eclipse.jetty.http2.server;
import java.nio.ByteBuffer;
import org.eclipse.jetty.server.QueuedHttpInput;
public class HttpInputOverHTTP2 extends QueuedHttpInput<ByteBufferCallback>
public class HttpInputOverHTTP2 extends QueuedHttpInput
{
@Override
protected int remaining(ByteBufferCallback item)
{
return item.getByteBuffer().remaining();
}
@Override
protected int get(ByteBufferCallback item, byte[] buffer, int offset, int length)
{
ByteBuffer byteBuffer = item.getByteBuffer();
length = Math.min(byteBuffer.remaining(), length);
byteBuffer.get(buffer, offset, length);
return length;
}
@Override
protected void consume(ByteBufferCallback item, int length)
{
ByteBuffer byteBuffer = item.getByteBuffer();
byteBuffer.position(byteBuffer.position() + length);
if (!byteBuffer.hasRemaining())
onContentConsumed(item);
}
@Override
protected void onContentConsumed(ByteBufferCallback item)
{
item.succeeded();
}
}

View File

@ -24,10 +24,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
@ -85,7 +85,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport
stream.getId(), System.lineSeparator(), HttpVersion.HTTP_2_0, info.getStatus(), System.lineSeparator(), info.getHttpFields());
}
MetaData metaData = new MetaData.Response(info.getStatus(), info.getHttpFields());
MetaData metaData = new MetaData.Response(HttpVersion.HTTP_2_0, info.getStatus(), info.getHttpFields());
HeadersFrame frame = new HeadersFrame(stream.getId(), metaData, null, endStream);
stream.headers(frame, callback);
}

View File

@ -29,6 +29,7 @@ import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@ -37,6 +38,8 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
@ -46,7 +49,6 @@ import org.eclipse.jetty.http2.generator.Generator;
import org.eclipse.jetty.http2.hpack.HpackContext;
import org.eclipse.jetty.http2.hpack.HpackDecoder;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.http2.parser.ErrorCode;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.http2.parser.PrefaceParser;
@ -103,7 +105,7 @@ public class HTTP2ServerTest
String host = "localhost";
int port = connector.getLocalPort();
HttpFields fields = new HttpFields();
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, HttpMethod.GET.asString(),
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0, HttpScheme.HTTP, HttpMethod.GET.asString(),
host + ":" + port, host, port, path, fields);
HeadersFrame request = new HeadersFrame(1, metaData, null, true);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
@ -152,7 +154,7 @@ public class HTTP2ServerTest
String host = "localhost";
int port = connector.getLocalPort();
HttpFields fields = new HttpFields();
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, HttpMethod.GET.asString(),
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0, HttpScheme.HTTP, HttpMethod.GET.asString(),
host + ":" + port, host, port, path, fields);
HeadersFrame request = new HeadersFrame(1, metaData, null, true);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
@ -215,7 +217,7 @@ public class HTTP2ServerTest
String host = "localhost";
int port = connector.getLocalPort();
HttpFields fields = new HttpFields();
MetaData.Request metaData = new MetaData.Request(HttpScheme.HTTP, HttpMethod.GET.asString(),
MetaData.Request metaData = new MetaData.Request(HttpVersion.HTTP_2_0,HttpScheme.HTTP, HttpMethod.GET.asString(),
host + ":" + port, host, port, path, fields);
HeadersFrame request = new HeadersFrame(1, metaData, null, true);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);

View File

@ -323,7 +323,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
public void sessionCreated(HttpSessionEvent se)
{
//if current request is authenticated, then as we have just created the session, mark it as secure, as it has not yet been returned to a user
HttpChannel<?> channel = HttpChannel.getCurrentHttpChannel();
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
if (channel == null)
return;

View File

@ -147,7 +147,7 @@ public class AsyncContextState implements AsyncContext
@Override
public boolean hasOriginalRequestAndResponse()
{
HttpChannel<?> channel=state().getHttpChannel();
HttpChannel channel=state().getHttpChannel();
return channel.getRequest()==getRequest() && channel.getResponse()==getResponse();
}

View File

@ -1,53 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server;
import java.nio.ByteBuffer;
/**
* <p>An implementation of HttpInput using {@link ByteBuffer} as items.</p>
*/
public class ByteBufferQueuedHttpInput extends QueuedHttpInput<ByteBuffer>
{
@Override
protected int remaining(ByteBuffer item)
{
return item.remaining();
}
@Override
protected int get(ByteBuffer item, byte[] buffer, int offset, int length)
{
int l = Math.min(item.remaining(), length);
item.get(buffer, offset, l);
return l;
}
@Override
protected void consume(ByteBuffer item, int length)
{
item.position(item.position()+length);
}
@Override
protected void onContentConsumed(ByteBuffer item)
{
}
}

View File

@ -30,6 +30,7 @@ import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.http.BadMessage;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
@ -40,6 +41,7 @@ import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ChannelEndPoint;
@ -67,24 +69,24 @@ import org.eclipse.jetty.util.thread.Scheduler;
* HttpTransport.completed().
*
*/
public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
public class HttpChannel implements Runnable
{
private static final Logger LOG = Log.getLogger(HttpChannel.class);
private static final ThreadLocal<HttpChannel<?>> __currentChannel = new ThreadLocal<>();
private static final ThreadLocal<HttpChannel> __currentChannel = new ThreadLocal<>();
/* ------------------------------------------------------------ */
/** Get the current channel that this thread is dispatched to.
* @see Request#getAttribute(String) for a more general way to access the HttpChannel
* @return the current HttpChannel or null
*/
public static HttpChannel<?> getCurrentHttpChannel()
public static HttpChannel getCurrentHttpChannel()
{
return __currentChannel.get();
}
protected static HttpChannel<?> setCurrentHttpChannel(HttpChannel<?> channel)
protected static HttpChannel setCurrentHttpChannel(HttpChannel channel)
{
HttpChannel<?> last=__currentChannel.get();
HttpChannel last=__currentChannel.get();
if (channel==null)
__currentChannel.remove();
else
@ -103,7 +105,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
private final Response _response;
private HttpVersion _version = HttpVersion.HTTP_1_1;
public HttpChannel(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput<T> input)
public HttpChannel(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input)
{
_connector = connector;
_configuration = configuration;
@ -183,12 +185,6 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
return _endPoint.getRemoteAddress();
}
@Override
public int getHeaderCacheSize()
{
return _configuration.getHeaderCacheSize();
}
/**
* If the associated response has the Expect header set to 100 Continue,
* then accessing the input stream indicates that the handler/servlet
@ -222,7 +218,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
{
LOG.debug("{} handle enter", this);
final HttpChannel<?>last = setCurrentHttpChannel(this);
final HttpChannel last = setCurrentHttpChannel(this);
String threadName = null;
if (LOG.isDebugEnabled())
@ -455,13 +451,35 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
);
}
@Override
public boolean startRequest(String method, HttpURI uri, HttpVersion version)
public void onRequest(MetaData.Request request)
{
_requests.incrementAndGet();
// TODO directly inject MetaData.Request to Request
_request.setTimeStamp(System.currentTimeMillis());
_request.setMethod(method);
_request.setUri(uri);
_request.setHttpVersion(_version = request.getHttpVersion());
_request.setMethod(request.getMethod());
_request.setScheme(request.getScheme().asString());
HttpURI uri = request.getURI();
String uriHost=uri.getHost();
if (uriHost!=null)
{
// Give precidence to authority in absolute URI
_request.setServerName(uriHost);
_request.setServerPort(uri.getPort());
}
else
{
_request.setServerName(request.getHost());
_request.setServerPort(request.getPort());
}
_request.setUri(request.getURI());
String path;
try
@ -475,7 +493,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
path = uri.getDecodedPath(StandardCharsets.ISO_8859_1);
}
String info = URIUtil.canonicalPath(path);
String info = URIUtil.canonicalPath(path); // TODO should this be done prior to decoding???
if (info == null)
{
@ -485,93 +503,62 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
_request.setRequestURI("");
}
else
{
badMessage(400,null);
return true;
}
throw new BadMessage(400,"Bad URI");
}
_request.setPathInfo(info);
_version = version;
_request.setHttpVersion(_version);
return false;
}
@Override
public void parsedHeader(HttpField field)
{
HttpHeader header=field.getHeader();
String value=field.getValue();
if (value == null)
value = "";
if (header != null)
// TODO avoid playing in headers
for (HttpField field : request.getFields())
{
switch (header)
HttpHeader header=field.getHeader();
String value=field.getValue();
if (value == null)
value = "";
if (header != null)
{
case CONTENT_TYPE:
MimeTypes.Type mime = MimeTypes.CACHE.get(value);
String charset = (mime == null || mime.getCharset() == null) ? MimeTypes.getCharsetFromContentType(value) : mime.getCharset().toString();
if (charset != null)
_request.setCharacterEncodingUnchecked(charset);
break;
default:
switch (header)
{
case CONTENT_TYPE:
MimeTypes.Type mime = MimeTypes.CACHE.get(value);
String charset = (mime == null || mime.getCharset() == null) ? MimeTypes.getCharsetFromContentType(value) : mime.getCharset().toString();
if (charset != null)
_request.setCharacterEncodingUnchecked(charset);
break;
default:
}
}
if (field.getName()!=null)
_request.getHttpFields().add(field);
}
if (field.getName()!=null)
_request.getHttpFields().add(field);
}
@Override
public void parsedHostHeader(String host, int port)
{
if (_request.getUri().getHost()==null)
{
_request.setServerName(host);
_request.setServerPort(port);
}
}
@Override
public boolean headerComplete()
{
_requests.incrementAndGet();
// TODO make this a better field for h2 hpack generation
if (_configuration.getSendDateHeader())
_response.getHttpFields().put(_connector.getServer().getDateField());
return true;
}
@Override
public boolean content(T item)
public void onContent(HttpInput.Content content)
{
if (LOG.isDebugEnabled())
LOG.debug("{} content {}", this, item);
@SuppressWarnings("unchecked")
HttpInput<T> input = (HttpInput<T>)_request.getHttpInput();
input.content(item);
return false;
LOG.debug("{} content {}", this, content);
HttpInput input = (HttpInput)_request.getHttpInput();
input.content(content);
}
@Override
public boolean messageComplete()
public void onRequestComplete()
{
LOG.debug("{} messageComplete", this);
LOG.debug("{} onRequestComplete", this);
_request.getHttpInput().messageComplete();
return true;
}
@Override
public void earlyEOF()
public void onEarlyEOF()
{
_request.getHttpInput().earlyEOF();
}
@Override
public void badMessage(int status, String reason)
public void onBadMessage(int status, String reason)
{
if (status < 400 || status > 599)
status = HttpStatus.BAD_REQUEST_400;

View File

@ -23,7 +23,9 @@ import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
@ -32,22 +34,29 @@ import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.EndPoint;
/**
* A HttpChannel customized to be transported over the HTTP/1 protocol
*/
class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.ProxyHandler
class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandler, HttpParser.ProxyHandler
{
/**
*
*/
private final HttpConnection _httpConnection;
private String _method;
private HttpURI _uri;
private HttpVersion _version;
private final HttpFields _fields = new HttpFields();
private HostPortHttpField _hostPort;
private HttpField _connection;
private boolean _expect = false;
private boolean _expect100Continue = false;
private boolean _expect102Processing = false;
public HttpChannelOverHttp(HttpConnection httpConnection, Connector connector, HttpConfiguration config, EndPoint endPoint, HttpTransport transport, HttpInput<ByteBuffer> input)
public HttpChannelOverHttp(HttpConnection httpConnection, Connector connector, HttpConfiguration config, EndPoint endPoint, HttpTransport transport, HttpInput input)
{
super(connector,config,endPoint,transport,input);
_httpConnection = httpConnection;
@ -60,6 +69,12 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
_expect = false;
_expect100Continue = false;
_expect102Processing = false;
_method=null;
_uri=null;
_version=null;
_hostPort=null;
_connection=null;
_fields.clear();
}
@Override
@ -77,15 +92,19 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
@Override
public boolean startRequest(String method, HttpURI uri, HttpVersion version)
{
_method=method;
_uri=uri;
_version=version;
_expect = false;
_expect100Continue = false;
_expect102Processing = false;
return super.startRequest(method,uri,version);
return false;
}
@Override
public void proxied(String protocol, String sAddr, String dAddr, int sPort, int dPort)
{
_method=HttpMethod.CONNECT.asString();
Request request = getRequest();
request.setAttribute("PROXY", protocol);
request.setServerName(sAddr);
@ -99,44 +118,64 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
{
HttpHeader header=field.getHeader();
String value=field.getValue();
if (getRequest().getHttpVersion().getVersion()==HttpVersion.HTTP_1_1.getVersion() && header == HttpHeader.EXPECT)
if (header!=null)
{
HttpHeaderValue expect = HttpHeaderValue.CACHE.get(value);
switch (expect == null ? HttpHeaderValue.UNKNOWN : expect)
switch(header)
{
case CONTINUE:
_expect100Continue = true;
case CONNECTION:
_connection=field;
break;
case PROCESSING:
_expect102Processing = true;
case HOST:
_hostPort=(HostPortHttpField)field;
break;
default:
String[] values = field.getValues();
for (int i = 0; values != null && i < values.length; i++)
case EXPECT:
{
if (getRequest().getHttpVersion().getVersion()==HttpVersion.HTTP_1_1.getVersion())
{
expect = HttpHeaderValue.CACHE.get(values[i].trim());
if (expect == null)
_expect = true;
else
HttpHeaderValue expect = HttpHeaderValue.CACHE.get(value);
switch (expect == null ? HttpHeaderValue.UNKNOWN : expect)
{
switch (expect)
{
case CONTINUE:
_expect100Continue = true;
break;
case PROCESSING:
_expect102Processing = true;
break;
default:
_expect = true;
}
case CONTINUE:
_expect100Continue = true;
break;
case PROCESSING:
_expect102Processing = true;
break;
default:
String[] values = field.getValues();
for (int i = 0; values != null && i < values.length; i++)
{
expect = HttpHeaderValue.CACHE.get(values[i].trim());
if (expect == null)
_expect = true;
else
{
switch (expect)
{
case CONTINUE:
_expect100Continue = true;
break;
case PROCESSING:
_expect102Processing = true;
break;
default:
_expect = true;
}
}
}
}
}
break;
}
default:
break;
}
}
super.parsedHeader(field);
_fields.add(field);
}
/**
@ -177,13 +216,14 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
if (getRequest().getMethod()==null)
_httpConnection.close();
else
super.earlyEOF();
onEarlyEOF();
}
@Override
public boolean content(ByteBuffer item)
public boolean content(ByteBuffer content)
{
super.content(item);
// TODO avoid creating the Content object with wrapper?
onContent(new HttpInput.Content(content));
return true;
}
@ -191,24 +231,33 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
public void badMessage(int status, String reason)
{
_httpConnection._generator.setPersistent(false);
super.badMessage(status,reason);
onBadMessage(status,reason);
}
@Override
public boolean headerComplete()
{
boolean persistent;
HttpVersion version = getHttpVersion();
switch (version)
switch (_version)
{
case HTTP_1_0:
{
persistent = getRequest().getHttpFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString());
if (_connection!=null)
{
if (_connection.contains(HttpHeaderValue.KEEP_ALIVE.asString()))
persistent=true;
else
persistent=_fields.contains(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString());
}
else
persistent=false;
if (!persistent)
persistent = HttpMethod.CONNECT.is(getRequest().getMethod());
if (persistent)
getResponse().getHttpFields().add(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE);
break;
}
@ -219,8 +268,17 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
badMessage(HttpStatus.EXPECTATION_FAILED_417,null);
return true;
}
persistent = !getRequest().getHttpFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
if (_connection!=null)
{
if (_connection.contains(HttpHeaderValue.CLOSE.asString()))
persistent=false;
else
persistent=!_fields.contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); // handle multiple connection fields
}
else
persistent=true;
if (!persistent)
persistent = HttpMethod.CONNECT.is(getRequest().getMethod());
if (!persistent)
@ -237,7 +295,11 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
if (!persistent)
_httpConnection._generator.setPersistent(false);
return super.headerComplete();
if (_hostPort==null)
onRequest(new MetaData.Request(_version,_method,_uri,_fields,null,0));
else
onRequest(new MetaData.Request(_version,_method,_uri,_fields,_hostPort.getHost(),_hostPort.getPort()));
return true;
}
@Override
@ -257,7 +319,17 @@ class HttpChannelOverHttp extends HttpChannel<ByteBuffer> implements HttpParser.
@Override
public boolean messageComplete()
{
super.messageComplete();
onRequestComplete();
return false;
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.http.HttpParser.HttpHandler#getHeaderCacheSize()
*/
@Override
public int getHeaderCacheSize()
{
return getHttpConfiguration().getHeaderCacheSize();
}
}

View File

@ -84,7 +84,7 @@ public class HttpChannelState
}
private final boolean DEBUG=LOG.isDebugEnabled();
private final HttpChannel<?> _channel;
private final HttpChannel _channel;
private List<AsyncListener> _asyncListeners;
private State _state;
@ -95,7 +95,7 @@ public class HttpChannelState
private long _timeoutMs=DEFAULT_TIMEOUT;
private AsyncContextEvent _event;
protected HttpChannelState(HttpChannel<?> channel)
protected HttpChannelState(HttpChannel channel)
{
_channel=channel;
_state=State.IDLE;
@ -626,7 +626,7 @@ public class HttpChannelState
return _channel.getRequest();
}
public HttpChannel<?> getHttpChannel()
public HttpChannel getHttpChannel()
{
return _channel;
}

View File

@ -97,7 +97,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
_connector = connector;
_bufferPool = _connector.getByteBufferPool();
_generator = newHttpGenerator();
HttpInput<ByteBuffer> input = newHttpInput();
HttpInput input = newHttpInput();
_channel = newHttpChannel(input);
_parser = newHttpParser();
LOG.debug("New HTTP Connection {}", this);
@ -108,12 +108,12 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
return new HttpGenerator(_config.getSendServerVersion(),_config.getSendXPoweredBy());
}
protected HttpInput<ByteBuffer> newHttpInput()
protected HttpInput newHttpInput()
{
return new HttpInputOverHTTP(this);
}
protected HttpChannelOverHttp newHttpChannel(HttpInput<ByteBuffer> httpInput)
protected HttpChannelOverHttp newHttpChannel(HttpInput httpInput)
{
return new HttpChannelOverHttp(this, _connector, _config, getEndPoint(), this, httpInput);
}
@ -123,7 +123,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
return new HttpParser(newRequestHandler(), getHttpConfiguration().getRequestHeaderSize());
}
protected HttpParser.RequestHandler<ByteBuffer> newRequestHandler()
protected HttpParser.RequestHandler newRequestHandler()
{
return _channel;
}
@ -138,7 +138,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
return _connector;
}
public HttpChannel<?> getHttpChannel()
public HttpChannel getHttpChannel()
{
return _channel;
}

View File

@ -19,12 +19,15 @@
package org.eclipse.jetty.server;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Objects;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -36,10 +39,35 @@ import org.eclipse.jetty.util.log.Logger;
* state that tells whether an EOF has arrived.
* Only once the content has been consumed the content state is moved to the EOF state.
*/
public abstract class HttpInput<T> extends ServletInputStream implements Runnable
public abstract class HttpInput extends ServletInputStream implements Runnable
{
private final static Logger LOG = Log.getLogger(HttpInput.class);
public static class Content extends Callback.Adapter
{
private final ByteBuffer _content;
public Content(ByteBuffer content)
{
_content=content;
}
public ByteBuffer getContent()
{
return _content;
}
public boolean hasContent()
{
return _content.hasRemaining();
}
public int remaining()
{
return _content.remaining();
}
}
private final byte[] _oneByteBuffer = new byte[1];
private final Object _lock;
private HttpChannelState _channelState;
@ -93,7 +121,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
{
synchronized (lock())
{
T item = getNextContent();
Content item = getNextContent();
return item == null ? 0 : remaining(item);
}
}
@ -115,7 +143,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
{
synchronized (lock())
{
T item = getNextContent();
Content item = getNextContent();
if (item == null)
{
_contentState.waitForContent(this);
@ -137,9 +165,9 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
* @throws IOException
* @see #nextContent()
*/
protected T getNextContent() throws IOException
protected Content getNextContent() throws IOException
{
T content = nextContent();
Content content = nextContent();
if (content == null)
{
synchronized (lock())
@ -164,32 +192,48 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
* @return the content or null if none available.
* @throws IOException if retrieving the content fails
*/
protected abstract T nextContent() throws IOException;
protected abstract Content nextContent() throws IOException;
/**
* @param item the content
* @return how many bytes remain in the given content
*/
protected abstract int remaining(T item);
protected int remaining(Content item)
{
return item.remaining();
}
/**
* Copies the given content into the given byte buffer.
*
* @param item the content to copy from
* @param content the content to copy from
* @param buffer the buffer to copy into
* @param offset the buffer offset to start copying from
* @param length the space available in the buffer
* @return the number of bytes actually copied
*/
protected abstract int get(T item, byte[] buffer, int offset, int length);
protected int get(Content content, byte[] buffer, int offset, int length)
{
int l = Math.min(content.remaining(), length);
content.getContent().get(buffer, offset, l);
return l;
}
/**
* Consumes the given content.
* Calls the content succeeded if all content consumed.
*
* @param item the content to consume
* @param content the content to consume
* @param length the number of bytes to consume
*/
protected abstract void consume(T item, int length);
protected void consume(Content content, int length)
{
ByteBuffer buffer = content.getContent();
buffer.position(buffer.position()+length);
if (length>0 && !buffer.hasRemaining())
content.succeeded();
}
/**
* Blocks until some content or some end-of-file event arrives.
@ -203,7 +247,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
*
* @param item the content to add
*/
public abstract void content(T item);
public abstract void content(Content content);
protected boolean onAsyncRead()
{
@ -273,7 +317,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
{
while (!isFinished())
{
T item = getNextContent();
Content item = getNextContent();
if (item == null)
_contentState.waitForContent(this);
else
@ -387,7 +431,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
try
{
T item = getNextContent();
Content item = getNextContent();
available = item != null && remaining(item) > 0;
}
catch (Exception e)
@ -420,7 +464,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
protected static abstract class State
{
public void waitForContent(HttpInput<?> in) throws IOException
public void waitForContent(HttpInput in) throws IOException
{
}
@ -438,7 +482,7 @@ public abstract class HttpInput<T> extends ServletInputStream implements Runnabl
protected static final State STREAM = new State()
{
@Override
public void waitForContent(HttpInput<?> input) throws IOException
public void waitForContent(HttpInput input) throws IOException
{
input.blockForContent();
}

View File

@ -27,13 +27,14 @@ import org.eclipse.jetty.util.SharedBlockingCallback;
import org.eclipse.jetty.util.SharedBlockingCallback.Blocker;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.server.HttpInput.Content;
public class HttpInputOverHTTP extends HttpInput<ByteBuffer> implements Callback
public class HttpInputOverHTTP extends HttpInput implements Callback
{
private static final Logger LOG = Log.getLogger(HttpInputOverHTTP.class);
private final SharedBlockingCallback _readBlocker = new SharedBlockingCallback();
private final HttpConnection _httpConnection;
private ByteBuffer _content;
private Content _content;
/**
* @param httpConnection
@ -78,10 +79,10 @@ public class HttpInputOverHTTP extends HttpInput<ByteBuffer> implements Callback
}
@Override
protected ByteBuffer nextContent() throws IOException
protected Content nextContent() throws IOException
{
// If we have some content available, return it
if (BufferUtil.hasContent(_content))
if (_content!=null && _content.hasContent())
return _content;
// No - then we are going to need to parse some more content
@ -89,37 +90,16 @@ public class HttpInputOverHTTP extends HttpInput<ByteBuffer> implements Callback
_httpConnection.parseContent();
// If we have some content available, return it
if (BufferUtil.hasContent(_content))
if (_content!=null && _content.hasContent())
return _content;
return null;
}
@Override
protected int remaining(ByteBuffer item)
public void content(Content item)
{
return item.remaining();
}
@Override
protected int get(ByteBuffer item, byte[] buffer, int offset, int length)
{
int l = Math.min(item.remaining(), length);
item.get(buffer, offset, l);
return l;
}
@Override
protected void consume(ByteBuffer item, int length)
{
item.position(item.position()+length);
}
@Override
public void content(ByteBuffer item)
{
if (BufferUtil.hasContent(_content))
if (_content!=null && _content.hasContent())
throw new IllegalStateException();
_content=item;
}

View File

@ -54,7 +54,7 @@ import org.eclipse.jetty.util.log.Logger;
public class HttpOutput extends ServletOutputStream implements Runnable
{
private static Logger LOG = Log.getLogger(HttpOutput.class);
private final HttpChannel<?> _channel;
private final HttpChannel _channel;
private final SharedBlockingCallback _writeblock=new SharedBlockingCallback();
private long _written;
private ByteBuffer _aggregate;
@ -77,14 +77,14 @@ public class HttpOutput extends ServletOutputStream implements Runnable
enum OutputState { OPEN, ASYNC, READY, PENDING, UNREADY, ERROR, CLOSED }
private final AtomicReference<OutputState> _state=new AtomicReference<>(OutputState.OPEN);
public HttpOutput(HttpChannel<?> channel)
public HttpOutput(HttpChannel channel)
{
_channel = channel;
_bufferSize = _channel.getHttpConfiguration().getOutputBufferSize();
_commitSize=_bufferSize/4;
}
public HttpChannel<?> getHttpChannel()
public HttpChannel getHttpChannel()
{
return _channel;
}

View File

@ -35,17 +35,17 @@ import org.eclipse.jetty.util.log.Logger;
* To assist the caller, subclasses may override methods {@link #onAsyncRead()}, {@link #onContentConsumed(Object)}
* that can be implemented so that the caller will know when buffers are queued and consumed.
*/
public abstract class QueuedHttpInput<T> extends HttpInput<T>
public class QueuedHttpInput extends HttpInput
{
private final static Logger LOG = Log.getLogger(QueuedHttpInput.class);
private final ArrayQueue<T> _inputQ = new ArrayQueue<>(lock());
private final ArrayQueue<Content> _inputQ = new ArrayQueue<>(lock());
public QueuedHttpInput()
{
}
public void content(T item)
public void content(Content item)
{
// The buffer is not copied here. This relies on the caller not recycling the buffer
// until the it is consumed. The onContentConsumed and onAllContentConsumed() callbacks are
@ -68,10 +68,10 @@ public abstract class QueuedHttpInput<T> extends HttpInput<T>
{
synchronized (lock())
{
T item = _inputQ.pollUnsafe();
Content item = _inputQ.pollUnsafe();
while (item != null)
{
onContentConsumed(item);
item.failed(null);
item = _inputQ.pollUnsafe();
}
super.recycle();
@ -79,17 +79,16 @@ public abstract class QueuedHttpInput<T> extends HttpInput<T>
}
@Override
protected T nextContent()
protected Content nextContent()
{
synchronized (lock())
{
// Items are removed only when they are fully consumed.
T item = _inputQ.peekUnsafe();
Content item = _inputQ.peekUnsafe();
// Skip consumed items at the head of the queue.
while (item != null && remaining(item) == 0)
{
_inputQ.pollUnsafe();
onContentConsumed(item);
LOG.debug("{} consumed {}", this, item);
item = _inputQ.peekUnsafe();
}
@ -116,13 +115,6 @@ public abstract class QueuedHttpInput<T> extends HttpInput<T>
}
}
/**
* Callback that signals that the given content has been consumed.
*
* @param item the consumed content
*/
protected abstract void onContentConsumed(T item);
public void earlyEOF()
{
synchronized (lock())

View File

@ -126,10 +126,10 @@ public class Request implements HttpServletRequest
private static final Collection<Locale> __defaultLocale = Collections.singleton(Locale.getDefault());
private static final int __NONE = 0, _STREAM = 1, __READER = 2;
private final HttpChannel<?> _channel;
private final HttpChannel _channel;
private final HttpFields _fields=new HttpFields();
private final List<ServletRequestAttributeListener> _requestAttributeListeners=new ArrayList<>();
private final HttpInput<?> _input;
private final HttpInput _input;
public static class MultiPartCleanerListener implements ServletRequestListener
{
@ -209,7 +209,7 @@ public class Request implements HttpServletRequest
private AsyncContextState _async;
/* ------------------------------------------------------------ */
public Request(HttpChannel<?> channel, HttpInput<?> input)
public Request(HttpChannel channel, HttpInput input)
{
_channel = channel;
_input = input;
@ -222,7 +222,7 @@ public class Request implements HttpServletRequest
}
/* ------------------------------------------------------------ */
public HttpInput<?> getHttpInput()
public HttpInput getHttpInput()
{
return _input;
}
@ -502,7 +502,7 @@ public class Request implements HttpServletRequest
/**
* @return Returns the connection.
*/
public HttpChannel<?> getHttpChannel()
public HttpChannel getHttpChannel()
{
return _channel;
}

View File

@ -108,7 +108,7 @@ public class Response implements HttpServletResponse
*/
public final static String HTTP_ONLY_COMMENT = "__HTTP_ONLY__";
private final HttpChannel<?> _channel;
private final HttpChannel _channel;
private final HttpFields _fields = new HttpFields();
private final AtomicInteger _include = new AtomicInteger();
private HttpOutput _out;
@ -124,13 +124,13 @@ public class Response implements HttpServletResponse
private long _contentLength = -1;
public Response(HttpChannel<?> channel, HttpOutput out)
public Response(HttpChannel channel, HttpOutput out)
{
_channel = channel;
_out = out;
}
protected HttpChannel<?> getHttpChannel()
protected HttpChannel getHttpChannel()
{
return _channel;
}

View File

@ -442,7 +442,7 @@ public class Server extends HandlerWrapper implements Attributes
* or after the entire request has been received (for short requests of known length), or
* on the dispatch of an async request.
*/
public void handle(HttpChannel<?> connection) throws IOException, ServletException
public void handle(HttpChannel connection) throws IOException, ServletException
{
final String target=connection.getRequest().getPathInfo();
final Request request=connection.getRequest();
@ -484,7 +484,7 @@ public class Server extends HandlerWrapper implements Attributes
* or after the entire request has been received (for short requests of known length), or
* on the dispatch of an async request.
*/
public void handleAsync(HttpChannel<?> connection) throws IOException, ServletException
public void handleAsync(HttpChannel connection) throws IOException, ServletException
{
final HttpChannelState state = connection.getRequest().getHttpChannelState();
final AsyncContextEvent event = state.getAsyncContextEvent();

View File

@ -201,7 +201,7 @@ public class IPAccessHandler extends HandlerWrapper
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
HttpChannel<?> channel = baseRequest.getHttpChannel();
HttpChannel channel = baseRequest.getHttpChannel();
if (channel!=null)
{
EndPoint endp=channel.getEndPoint();

View File

@ -100,7 +100,7 @@ public class ExtendedServerTest extends HttpServerTestBase
}
@Override
protected HttpChannelOverHttp newHttpChannel(HttpInput<ByteBuffer> httpInput)
protected HttpChannelOverHttp newHttpChannel(HttpInput httpInput)
{
return new HttpChannelOverHttp(this, getConnector(), getHttpConfiguration(), getEndPoint(), this, httpInput)
{

View File

@ -163,7 +163,7 @@ public class HttpConnectionTest
public void testBadPathDotDotPath() throws Exception
{
String response=connector.getResponses("GET /ooops/../../path HTTP/1.0\nHost: localhost:80\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad Request");
checkContains(response,0,"HTTP/1.1 400 Bad URI");
}
@Test
@ -178,28 +178,28 @@ public class HttpConnectionTest
public void testBadPathEncodedDotDotPath() throws Exception
{
String response=connector.getResponses("GET /ooops/%2e%2e/%2e%2e/path HTTP/1.0\nHost: localhost:80\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad Request");
checkContains(response,0,"HTTP/1.1 400 Bad URI");
}
@Test
public void testBadDotDotPath() throws Exception
{
String response=connector.getResponses("GET ../path HTTP/1.0\nHost: localhost:80\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad Request");
checkContains(response,0,"HTTP/1.1 400 Bad URI");
}
@Test
public void testBadSlashDotDotPath() throws Exception
{
String response=connector.getResponses("GET /../path HTTP/1.0\nHost: localhost:80\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad Request");
checkContains(response,0,"HTTP/1.1 400 Bad URI");
}
@Test
public void testEncodedBadDotDotPath() throws Exception
{
String response=connector.getResponses("GET %2e%2e/path HTTP/1.0\nHost: localhost:80\n\n");
checkContains(response,0,"HTTP/1.1 400 Bad Request");
checkContains(response,0,"HTTP/1.1 400 Bad URI");
}
@Test

View File

@ -24,6 +24,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
@ -43,16 +44,17 @@ public class HttpWriterTest
{
_bytes = BufferUtil.allocate(2048);
final ByteBufferPool bufferPool = new MappedByteBufferPool();
HttpChannel<?> channel = new HttpChannel<ByteBuffer>(null,new HttpConfiguration(),null,null,new ByteBufferQueuedHttpInput())
final ByteBufferPool pool = new ArrayByteBufferPool();
HttpChannel channel = new HttpChannel(null,new HttpConfiguration(),null,null,new QueuedHttpInput())
{
@Override
public ByteBufferPool getByteBufferPool()
{
return bufferPool;
return pool;
}
};
_httpOut = new HttpOutput(channel)
{
@Override

View File

@ -25,7 +25,7 @@ public class QueuedHttpInputTest
@Test
public void testNoContentMessageComplete() throws Exception
{
ByteBufferQueuedHttpInput input = new ByteBufferQueuedHttpInput();
QueuedHttpInput input = new QueuedHttpInput();
input.messageComplete();
input.getNextContent();

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@ -779,9 +781,9 @@ public class RequestTest
"\n",
200, TimeUnit.MILLISECONDS
);
assertTrue(response.indexOf("200")>0);
assertFalse(response.indexOf("Connection: close")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,Matchers.not(containsString("Connection: close")));
assertThat(response,containsString("Hello World"));
response=_connector.getResponses(
"GET / HTTP/1.1\n"+
@ -789,9 +791,9 @@ public class RequestTest
"Connection: close\n"+
"\n"
);
assertTrue(response.indexOf("200")>0);
assertTrue(response.indexOf("Connection: close")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,containsString("Connection: close"));
assertThat(response,containsString("Hello World"));
response=_connector.getResponses(
"GET / HTTP/1.1\n"+
@ -800,18 +802,18 @@ public class RequestTest
"\n"
);
assertTrue(response.indexOf("200")>0);
assertTrue(response.indexOf("Connection: close")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,containsString("Connection: close"));
assertThat(response,containsString("Hello World"));
response=_connector.getResponses(
"GET / HTTP/1.0\n"+
"Host: whatever\n"+
"\n"
);
assertTrue(response.indexOf("200")>0);
assertFalse(response.indexOf("Connection: close")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,not(containsString("Connection: close")));
assertThat(response,containsString("Hello World"));
response=_connector.getResponses(
"GET / HTTP/1.0\n"+
@ -819,8 +821,8 @@ public class RequestTest
"Connection: Other, close\n"+
"\n"
);
assertTrue(response.indexOf("200")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,containsString("Hello World"));
response=_connector.getResponses(
"GET / HTTP/1.0\n"+
@ -829,9 +831,9 @@ public class RequestTest
"\n",
200, TimeUnit.MILLISECONDS
);
assertTrue(response.indexOf("200")>0);
assertTrue(response.indexOf("Connection: keep-alive")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,Matchers.containsString("Connection: keep-alive"));
assertThat(response,containsString("Hello World"));
_handler._checker = new RequestTester()
{
@ -851,9 +853,9 @@ public class RequestTest
"\n",
200, TimeUnit.MILLISECONDS
);
assertTrue(response.indexOf("200")>0);
assertTrue(response.indexOf("Connection: TE,Other")>0);
assertTrue(response.indexOf("Hello World")>0);
assertThat(response,containsString("200"));
assertThat(response,containsString("Connection: TE,Other"));
assertThat(response,containsString("Hello World"));
response=_connector.getResponses(
"GET / HTTP/1.1\n"+

View File

@ -66,7 +66,7 @@ import org.junit.Test;
public class ResponseTest
{
private Server _server;
private HttpChannel<ByteBuffer> _channel;
private HttpChannel _channel;
@Before
public void init() throws Exception
@ -80,8 +80,8 @@ public class ResponseTest
_server.start();
AbstractEndPoint endp = new ByteArrayEndPoint(_scheduler, 5000);
ByteBufferQueuedHttpInput input = new ByteBufferQueuedHttpInput();
_channel = new HttpChannel<ByteBuffer>(connector, new HttpConfiguration(), endp, new HttpTransport()
QueuedHttpInput input = new QueuedHttpInput();
_channel = new HttpChannel(connector, new HttpConfiguration(), endp, new HttpTransport()
{
@Override
public void send(ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)

View File

@ -364,7 +364,7 @@ public class AsyncGzipFilter extends UserAgentFilter implements GzipFactory
request.setAttribute(ETAG,etag.substring(0,dd)+(etag.endsWith("\"")?"\"":""));
}
HttpChannel<?> channel = HttpChannel.getCurrentHttpChannel();
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
HttpOutput out = channel.getResponse().getHttpOutput();
if (!(out instanceof GzipHttpOutput))
{

View File

@ -52,7 +52,7 @@ public class GzipHttpOutput extends HttpOutput
private GzipFactory _factory;
private ByteBuffer _buffer;
public GzipHttpOutput(HttpChannel<?> channel)
public GzipHttpOutput(HttpChannel channel)
{
super(channel);
}

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class HttpChannelOverSPDY extends HttpChannel<DataInfo>
public class HttpChannelOverSPDY extends HttpChannel
{
private static final Logger LOG = Log.getLogger(HttpChannelOverSPDY.class);

View File

@ -21,7 +21,7 @@ package org.eclipse.jetty.spdy.server.http;
import org.eclipse.jetty.server.QueuedHttpInput;
import org.eclipse.jetty.spdy.api.DataInfo;
public class HttpInputOverSPDY extends QueuedHttpInput<DataInfo>
public class HttpInputOverSPDY extends QueuedHttpInput
{
@Override
protected int remaining(DataInfo item)