From 31e448ffd677d9360c4132a63b08fe53c860cf7c Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 24 Oct 2014 15:51:20 +1100 Subject: [PATCH] Removed duplication of HttpGenerator$Info vs http.MetaData Use MetaData throughout code base --- .../jetty/client/http/HttpSenderOverHTTP.java | 4 +- .../fcgi/server/HttpChannelOverFCGI.java | 2 +- .../fcgi/server/HttpTransportOverFCGI.java | 15 +- .../org/eclipse/jetty/http/HttpGenerator.java | 155 ++++-------------- .../java/org/eclipse/jetty/http/MetaData.java | 102 +++++++++++- .../jetty/http/HttpGeneratorClientTest.java | 22 +-- .../http/HttpGeneratorServerHTTPTest.java | 6 +- .../jetty/http/HttpGeneratorServerTest.java | 49 +++--- .../org/eclipse/jetty/http/HttpTester.java | 20 +-- .../jetty/http2/hpack/MetaDataBuilder.java | 15 +- .../http2/server/HttpChannelOverHTTP2.java | 7 +- .../http2/server/HttpTransportOverHTTP2.java | 11 +- .../org/eclipse/jetty/server/HttpChannel.java | 33 ++-- .../jetty/server/HttpChannelOverHttp.java | 4 +- .../jetty/server/HttpChannelState.java | 1 + .../eclipse/jetty/server/HttpConnection.java | 20 ++- .../eclipse/jetty/server/HttpTransport.java | 2 +- .../org/eclipse/jetty/server/Request.java | 4 + .../org/eclipse/jetty/server/Response.java | 6 +- .../eclipse/jetty/server/ResponseTest.java | 5 +- .../server/http/HttpTransportOverSPDY.java | 7 +- .../server/proxy/ProxyHTTPSPDYConnection.java | 15 +- .../http/HttpTransportOverSPDYTest.java | 27 +-- 23 files changed, 279 insertions(+), 253 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java index b4717531985..edc7e127f5e 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java @@ -28,6 +28,8 @@ import org.eclipse.jetty.client.HttpSender; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpGenerator; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Callback; @@ -57,7 +59,7 @@ public class HttpSenderOverHTTP extends HttpSender String query = request.getQuery(); if (query != null) path += "?" + query; - HttpGenerator.RequestInfo requestInfo = new HttpGenerator.RequestInfo(request.getVersion(), request.getHeaders(), contentLength, request.getMethod(), path); + MetaData.Request requestInfo = new MetaData.Request(request.getMethod(), new HttpURI(path), request.getVersion(), request.getHeaders(), contentLength); try { diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java index d99e709ffb7..65aabc5be06 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java @@ -88,7 +88,7 @@ public class HttpChannelOverFCGI extends HttpChannel if (query != null && query.length() > 0) uri += "?" + query; // TODO https? - onRequest(new MetaData.Request(method, HttpScheme.HTTP.asString(), hostPort, uri, HttpVersion.fromString(version), fields)); + onRequest(new MetaData.Request(method, HttpScheme.HTTP.asString(), hostPort, uri, HttpVersion.fromString(version), fields,Long.MIN_VALUE)); } private HttpField convertHeader(HttpField field) diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java index 5e0b7e6d813..9d2869a1d3d 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java @@ -26,6 +26,7 @@ import org.eclipse.jetty.fcgi.generator.ServerGenerator; import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.util.BufferUtil; @@ -48,10 +49,10 @@ public class HttpTransportOverFCGI implements HttpTransport } @Override - public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) + public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) { if (info!=null) - commit(info,content,lastContent,callback); + commit(info,head,content,lastContent,callback); else { if (head) @@ -88,10 +89,10 @@ public class HttpTransportOverFCGI implements HttpTransport // LOG.debug("ignore push in {}",this); } - private void commit(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) + private void commit(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) { - boolean head = this.head = info.isHead(); - boolean shutdown = this.shutdown = info.getHttpFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); + this.head = head; + boolean shutdown = this.shutdown = info.getFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); if (head) { @@ -118,9 +119,9 @@ public class HttpTransportOverFCGI implements HttpTransport flusher.shutdown(); } - protected Generator.Result generateResponseHeaders(HttpGenerator.ResponseInfo info, Callback callback) + protected Generator.Result generateResponseHeaders(MetaData.Response info, Callback callback) { - return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getHttpFields(), callback); + return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getFields(), callback); } protected Generator.Result generateResponseContent(ByteBuffer buffer, boolean lastContent, Callback callback) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index d5387ad6c5d..46509e15f49 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -47,10 +47,10 @@ public class HttpGenerator private final static byte[] __colon_space = new byte[] {':',' '}; private final static HttpHeaderValue[] CLOSE = {HttpHeaderValue.CLOSE}; - public static final ResponseInfo CONTINUE_100_INFO = new ResponseInfo(HttpVersion.HTTP_1_1,null,-1,100,null,false); - public static final ResponseInfo PROGRESS_102_INFO = new ResponseInfo(HttpVersion.HTTP_1_1,null,-1,102,null,false); - public final static ResponseInfo RESPONSE_500_INFO = - new ResponseInfo(HttpVersion.HTTP_1_1,new HttpFields(){{put(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE);}},0,HttpStatus.INTERNAL_SERVER_ERROR_500,null,false); + public static final MetaData.Response CONTINUE_100_INFO = new MetaData.Response(HttpVersion.HTTP_1_1,100,null,null,-1); + public static final MetaData.Response PROGRESS_102_INFO = new MetaData.Response(HttpVersion.HTTP_1_1,102,null,null,-1); + public final static MetaData.Response RESPONSE_500_INFO = + new MetaData.Response(HttpVersion.HTTP_1_1,HttpStatus.INTERNAL_SERVER_ERROR_500,null,new HttpFields(){{put(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE);}},0); // states public enum State { START, COMMITTED, COMPLETING, COMPLETING_1XX, END } @@ -199,7 +199,7 @@ public class HttpGenerator } /* ------------------------------------------------------------ */ - public Result generateRequest(RequestInfo info, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException + public Result generateRequest(MetaData.Request info, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException { switch(_state) { @@ -214,7 +214,7 @@ public class HttpGenerator // If we have not been told our persistence, set the default if (_persistent==null) - _persistent=(info.getHttpVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal()); + _persistent=(info.getVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal()); // prepare the header int pos=BufferUtil.flipToFill(header); @@ -223,12 +223,12 @@ public class HttpGenerator // generate ResponseLine generateRequestLine(info,header); - if (info.getHttpVersion()==HttpVersion.HTTP_0_9) + if (info.getVersion()==HttpVersion.HTTP_0_9) _noContent=true; else generateHeaders(info,header,content,last); - boolean expect100 = info.getHttpFields().contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString()); + boolean expect100 = info.getFields().contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString()); if (expect100) { @@ -328,7 +328,13 @@ public class HttpGenerator } /* ------------------------------------------------------------ */ - public Result generateResponse(ResponseInfo info, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException + public Result generateResponse(MetaData.Response info, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException + { + return generateResponse(info,false,header,chunk,content,last); + } + + /* ------------------------------------------------------------ */ + public Result generateResponse(MetaData.Response info, boolean head, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException { switch(_state) { @@ -338,7 +344,7 @@ public class HttpGenerator return Result.NEED_INFO; // Handle 0.9 - if (info.getHttpVersion() == HttpVersion.HTTP_0_9) + if (info.getVersion() == HttpVersion.HTTP_0_9) { _persistent = false; _endOfContent=EndOfContent.EOF_CONTENT; @@ -354,7 +360,7 @@ public class HttpGenerator // If we have not been told our persistence, set the default if (_persistent==null) - _persistent=(info.getHttpVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal()); + _persistent=(info.getVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal()); // prepare the header int pos=BufferUtil.flipToFill(header); @@ -388,7 +394,7 @@ public class HttpGenerator if (len>0) { _contentPrepared+=len; - if (isChunking() && !info.isHead()) + if (isChunking() && !head) prepareChunk(header,len); } _state = last?State.COMPLETING:State.COMMITTED; @@ -503,17 +509,17 @@ public class HttpGenerator } /* ------------------------------------------------------------ */ - private void generateRequestLine(RequestInfo request,ByteBuffer header) + private void generateRequestLine(MetaData.Request request,ByteBuffer header) { header.put(StringUtil.getBytes(request.getMethod())); header.put((byte)' '); - header.put(StringUtil.getBytes(request.getUri())); - switch(request.getHttpVersion()) + header.put(StringUtil.getBytes(request.getURIString())); + switch(request.getVersion()) { case HTTP_1_0: case HTTP_1_1: header.put((byte)' '); - header.put(request.getHttpVersion().toBytes()); + header.put(request.getVersion().toBytes()); break; default: throw new IllegalStateException(); @@ -522,7 +528,7 @@ public class HttpGenerator } /* ------------------------------------------------------------ */ - private void generateResponseLine(ResponseInfo response, ByteBuffer header) + private void generateResponseLine(MetaData.Response response, ByteBuffer header) { // Look for prepared response line int status=response.getStatus(); @@ -572,10 +578,10 @@ public class HttpGenerator } /* ------------------------------------------------------------ */ - private void generateHeaders(Info _info,ByteBuffer header,ByteBuffer content,boolean last) + private void generateHeaders(MetaData _info,ByteBuffer header,ByteBuffer content,boolean last) { - final RequestInfo request=(_info instanceof RequestInfo)?(RequestInfo)_info:null; - final ResponseInfo response=(_info instanceof ResponseInfo)?(ResponseInfo)_info:null; + final MetaData.Request request=(_info instanceof MetaData.Request)?(MetaData.Request)_info:null; + final MetaData.Response response=(_info instanceof MetaData.Response)?(MetaData.Response)_info:null; // default field values int send=_send; @@ -586,9 +592,9 @@ public class HttpGenerator StringBuilder connection = null; // Generate fields - if (_info.getHttpFields() != null) + if (_info.getFields() != null) { - for (HttpField field : _info.getHttpFields()) + for (HttpField field : _info.getFields()) { String v = field.getValue(); if (v==null || v.length()==0) @@ -617,7 +623,7 @@ public class HttpGenerator case TRANSFER_ENCODING: { - if (_info.getHttpVersion() == HttpVersion.HTTP_1_1) + if (_info.getVersion() == HttpVersion.HTTP_1_1) transfer_encoding = field; // Do NOT add yet! break; @@ -671,7 +677,7 @@ public class HttpGenerator case KEEP_ALIVE: { - if (_info.getHttpVersion() == HttpVersion.HTTP_1_0) + if (_info.getVersion() == HttpVersion.HTTP_1_0) { keep_alive = true; if (response!=null) @@ -763,7 +769,7 @@ public class HttpGenerator // For a request with HTTP 1.0 & Connection: keep-alive // we *must* close the connection, otherwise the client // has no way to detect the end of the content. - if (!isPersistent() || _info.getHttpVersion().ordinal() < HttpVersion.HTTP_1_1.ordinal()) + if (!isPersistent() || _info.getVersion().ordinal() < HttpVersion.HTTP_1_1.ordinal()) _endOfContent = EndOfContent.EOF_CONTENT; } break; @@ -834,7 +840,7 @@ public class HttpGenerator // If this is a response, work out persistence if (response!=null) { - if (!isPersistent() && (close || _info.getHttpVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal())) + if (!isPersistent() && (close || _info.getVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal())) { if (connection==null) header.put(CONNECTION_CLOSE); @@ -949,103 +955,6 @@ public class HttpGenerator } } - public static class Info - { - final HttpVersion _httpVersion; - final HttpFields _httpFields; - final long _contentLength; - - private Info(HttpVersion httpVersion, HttpFields httpFields, long contentLength) - { - _httpVersion = httpVersion; - _httpFields = httpFields; - _contentLength = contentLength; - } - - public HttpVersion getHttpVersion() - { - return _httpVersion; - } - public HttpFields getHttpFields() - { - return _httpFields; - } - public long getContentLength() - { - return _contentLength; - } - } - - public static class RequestInfo extends Info - { - private final String _method; - private final String _uri; - - public RequestInfo(HttpVersion httpVersion, HttpFields httpFields, long contentLength, String method, String uri) - { - super(httpVersion,httpFields,contentLength); - _method = method; - _uri = uri; - } - - public String getMethod() - { - return _method; - } - - public String getUri() - { - return _uri; - } - - @Override - public String toString() - { - return String.format("RequestInfo{%s %s %s,%d}",_method,_uri,_httpVersion,_contentLength); - } - } - - public static class ResponseInfo extends Info - { - private final int _status; - private final String _reason; - private final boolean _head; - - public ResponseInfo(HttpVersion httpVersion, HttpFields httpFields, long contentLength, int status, String reason, boolean head) - { - super(httpVersion,httpFields,contentLength); - _status = status; - _reason = reason; - _head = head; - } - - public boolean isInformational() - { - return _status>=100 && _status<200; - } - - public int getStatus() - { - return _status; - } - - public String getReason() - { - return _reason; - } - - public boolean isHead() - { - return _head; - } - - @Override - public String toString() - { - return String.format("ResponseInfo{%s %s %s,%d,%b}",_httpVersion,_status,_reason,_contentLength,_head); - } - } - private static void putSanitisedName(String s,ByteBuffer buffer) { int l=s.length(); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java index 30405fe92b6..68ac39ab516 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java @@ -24,6 +24,7 @@ public class MetaData implements Iterable { private HttpVersion _httpVersion; private HttpFields _fields; + long _contentLength=Long.MIN_VALUE; /* ------------------------------------------------------------ */ public MetaData() @@ -36,6 +37,14 @@ public class MetaData implements Iterable _httpVersion = version; _fields = fields; } + + /* ------------------------------------------------------------ */ + public MetaData(HttpVersion version, HttpFields fields, long contentLength) + { + _httpVersion = version; + _fields = fields; + _contentLength=contentLength; + } /* ------------------------------------------------------------ */ public boolean isRequest() @@ -83,8 +92,21 @@ public class MetaData implements Iterable public void setFields(HttpFields fields) { _fields = fields; + _contentLength=Long.MIN_VALUE; } + /* ------------------------------------------------------------ */ + public long getContentLength() + { + if (_contentLength==Long.MIN_VALUE) + { + HttpField cl = _fields.getField(HttpHeader.CONTENT_LENGTH); + _contentLength=(cl==null)?-1:cl.getLongValue(); + } + + return _contentLength; + } + /* ------------------------------------------------------------ */ public Iterator iterator() { @@ -135,7 +157,7 @@ public class MetaData implements Iterable public Request() { } - + /* ------------------------------------------------------------ */ /** * @param method @@ -145,7 +167,19 @@ public class MetaData implements Iterable */ public Request(String method, HttpURI uri, HttpVersion version, HttpFields fields) { - super(version,fields); + this(method,uri,version,fields,Long.MIN_VALUE); + } + + /* ------------------------------------------------------------ */ + /** + * @param method + * @param uri + * @param version + * @param fields + */ + public Request(String method, HttpURI uri, HttpVersion version, HttpFields fields, long contentLength) + { + super(version,fields,contentLength); _method = method; _uri = uri; } @@ -155,11 +189,17 @@ public class MetaData implements Iterable { this(method,new HttpURI(scheme==null?null:scheme.asString(),hostPort.getHost(),hostPort.getPort(),uri),version,fields); } + + /* ------------------------------------------------------------ */ + public Request(String method, HttpScheme scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields, long contentLength) + { + this(method,new HttpURI(scheme==null?null:scheme.asString(),hostPort.getHost(),hostPort.getPort(),uri),version,fields,contentLength); + } /* ------------------------------------------------------------ */ - public Request(String method, String scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields) + public Request(String method, String scheme, HostPortHttpField hostPort, String uri, HttpVersion version, HttpFields fields, long contentLength) { - this(method,new HttpURI(scheme,hostPort.getHost(),hostPort.getPort(),uri),version,fields); + this(method,new HttpURI(scheme,hostPort.getHost(),hostPort.getPort(),uri),version,fields,contentLength); } /* ------------------------------------------------------------ */ @@ -195,6 +235,15 @@ public class MetaData implements Iterable { return _uri; } + + /* ------------------------------------------------------------ */ + /** Get the uri. + * @return the uri + */ + public String getURIString() + { + return _uri==null?null:_uri.toString(); + } /* ------------------------------------------------------------ */ /** Set the uri. @@ -242,6 +291,7 @@ public class MetaData implements Iterable public static class Response extends MetaData { private int _status; + private String _reason; public Response() { @@ -255,7 +305,31 @@ public class MetaData implements Iterable */ public Response(HttpVersion version, int status, HttpFields fields) { - super(version,fields); + this(version,status,fields,Long.MIN_VALUE); + } + + /* ------------------------------------------------------------ */ + /** + * @param version + * @param fields + * @param status + */ + public Response(HttpVersion version, int status, HttpFields fields,long contentLength) + { + super(version,fields,contentLength); + _status=status; + } + + /* ------------------------------------------------------------ */ + /** + * @param version + * @param fields + * @param status + */ + public Response(HttpVersion version, int status, String reason, HttpFields fields,long contentLength) + { + super(version,fields,contentLength); + _reason=reason; _status=status; } @@ -274,6 +348,15 @@ public class MetaData implements Iterable { return _status; } + + /* ------------------------------------------------------------ */ + /** Get the reason. + * @return the status + */ + public String getReason() + { + return _reason; + } /* ------------------------------------------------------------ */ /** Set the status. @@ -284,6 +367,15 @@ public class MetaData implements Iterable _status = status; } + /* ------------------------------------------------------------ */ + /** Set the reason. + * @param reason the reason to set + */ + public void setReason(String reason) + { + _reason = reason; + } + /* ------------------------------------------------------------ */ @Override public int hashCode() diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java index a9631fe9def..ca4b50c3d3a 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java @@ -29,16 +29,16 @@ public class HttpGeneratorClientTest { public final static String[] connect={null,"keep-alive","close"}; - class Info extends HttpGenerator.RequestInfo + class Info extends MetaData.Request { Info(String method,String uri) { - super(HttpVersion.HTTP_1_1,new HttpFields(),-1,method,uri); + super(method,new HttpURI(uri),HttpVersion.HTTP_1_1,new HttpFields(),-1); } public Info(String method,String uri, int contentLength) { - super(HttpVersion.HTTP_1_1,new HttpFields(),contentLength,method,uri); + super(method,new HttpURI(uri),HttpVersion.HTTP_1_1,new HttpFields(),contentLength); } } @@ -54,8 +54,8 @@ public class HttpGeneratorClientTest Assert.assertEquals(HttpGenerator.State.START, gen.getState()); Info info = new Info("GET","/index.html"); - info.getHttpFields().add("Host","something"); - info.getHttpFields().add("User-Agent","test"); + info.getFields().add("Host","something"); + info.getFields().add("User-Agent","test"); Assert.assertTrue(!gen.isChunking()); result=gen.generateRequest(info,null,null,null, true); @@ -94,8 +94,8 @@ public class HttpGeneratorClientTest Assert.assertEquals(HttpGenerator.State.START, gen.getState()); Info info = new Info("POST","/index.html"); - info.getHttpFields().add("Host","something"); - info.getHttpFields().add("User-Agent","test"); + info.getFields().add("Host","something"); + info.getFields().add("User-Agent","test"); result=gen.generateRequest(info,null,null,content0, true); Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result); @@ -140,8 +140,8 @@ public class HttpGeneratorClientTest Assert.assertEquals(HttpGenerator.State.START, gen.getState()); Info info = new Info("POST","/index.html"); - info.getHttpFields().add("Host","something"); - info.getHttpFields().add("User-Agent","test"); + info.getFields().add("Host","something"); + info.getFields().add("User-Agent","test"); result=gen.generateRequest(info,null,null,content0, false); Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result); @@ -212,8 +212,8 @@ public class HttpGeneratorClientTest Assert.assertEquals(HttpGenerator.State.START, gen.getState()); Info info = new Info("POST","/index.html",58); - info.getHttpFields().add("Host","something"); - info.getHttpFields().add("User-Agent","test"); + info.getFields().add("Host","something"); + info.getFields().add("User-Agent","test"); result=gen.generateRequest(info,null,null,content0, false); Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java index 12360231fc8..a6932c411a8 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java @@ -145,7 +145,7 @@ public class HttpGeneratorServerHTTPTest } ByteBuffer header = null; ByteBuffer chunk = null; - HttpGenerator.ResponseInfo info = null; + MetaData.Response info = null; loop: while (true) @@ -157,12 +157,12 @@ public class HttpGeneratorServerHTTPTest // Generate boolean last = !BufferUtil.hasContent(content); - HttpGenerator.Result result = gen.generateResponse(info, header, chunk, content, last); + HttpGenerator.Result result = gen.generateResponse(info, _head, header, chunk, content, last); switch (result) { case NEED_INFO: - info = new HttpGenerator.ResponseInfo(HttpVersion.fromVersion(version), _fields, _contentLength, _code, reason, _head); + info = new MetaData.Response(HttpVersion.fromVersion(version), _code, reason, _fields, _contentLength); continue; case NEED_HEADER: diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java index 03992957e46..6961950876e 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java @@ -26,7 +26,6 @@ import static org.junit.Assert.assertThat; import java.nio.ByteBuffer; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.util.BufferUtil; import org.junit.Assert; import org.junit.Test; @@ -46,9 +45,9 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), 10, 200, null, false); - info.getHttpFields().add("Content-Type", "test/data"); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 10); + info.getFields().add("Content-Type", "test/data"); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); result = gen.generateResponse(info, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); @@ -81,9 +80,9 @@ public class HttpGeneratorServerTest HttpGenerator gen = new HttpGenerator(); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), 10, 204, "Foo", false); - info.getHttpFields().add("Content-Type", "test/data"); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 204, "Foo", new HttpFields(), 10); + info.getFields().add("Content-Type", "test/data"); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); HttpGenerator.Result result = gen.generateResponse(info, header, null, content, true); @@ -118,9 +117,9 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), 10, 200, null, false); - info.getHttpFields().add("Content-Type", "test/data;\r\nextra=value"); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 10); + info.getFields().add("Content-Type", "test/data;\r\nextra=value"); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); result = gen.generateResponse(info, null, null, content, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); @@ -150,11 +149,11 @@ public class HttpGeneratorServerTest public void testSendServerXPoweredBy() throws Exception { ByteBuffer header = BufferUtil.allocate(8096); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), -1, 200, null, false); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); HttpFields fields = new HttpFields(); fields.add(HttpHeader.SERVER, "SomeServer"); fields.add(HttpHeader.X_POWERED_BY, "SomePower"); - ResponseInfo infoF = new ResponseInfo(HttpVersion.HTTP_1_1, fields, -1, 200, null, false); + MetaData.Response infoF = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, fields, -1); String head; HttpGenerator gen = new HttpGenerator(true, true); @@ -205,8 +204,8 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), -1, 200, null, false); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); result = gen.generateResponse(info, null, null, null, true); assertEquals(HttpGenerator.Result.NEED_HEADER, result); @@ -238,10 +237,10 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), -1, 101, null, false); - info.getHttpFields().add("Upgrade", "WebSocket"); - info.getHttpFields().add("Connection", "Upgrade"); - info.getHttpFields().add("Sec-WebSocket-Accept", "123456789=="); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 101, null, new HttpFields(), -1); + info.getFields().add("Upgrade", "WebSocket"); + info.getFields().add("Connection", "Upgrade"); + info.getFields().add("Sec-WebSocket-Accept", "123456789=="); result = gen.generateResponse(info, header, null, null, true); assertEquals(HttpGenerator.Result.FLUSH, result); @@ -273,8 +272,8 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), -1, 200, null, false); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), -1); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); result = gen.generateResponse(info, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -333,8 +332,8 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), 59, 200, null, false); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 59); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); result = gen.generateResponse(info, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -396,8 +395,8 @@ public class HttpGeneratorServerTest assertEquals(HttpGenerator.Result.NEED_INFO, result); assertEquals(HttpGenerator.State.START, gen.getState()); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_1, new HttpFields(), 59, 200, null, false); - info.getHttpFields().add("Last-Modified", DateGenerator.__01Jan1970); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_1, 200, null, new HttpFields(), 59); + info.getFields().add("Last-Modified", DateGenerator.__01Jan1970); result = gen.generateResponse(info, null, null, content0, false); assertEquals(HttpGenerator.Result.NEED_HEADER, result); assertEquals(HttpGenerator.State.START, gen.getState()); @@ -441,7 +440,7 @@ public class HttpGeneratorServerTest fields.put(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE); String customValue = "test"; fields.add(HttpHeader.CONNECTION, customValue); - ResponseInfo info = new ResponseInfo(HttpVersion.HTTP_1_0, fields, -1, 200, "OK", false); + MetaData.Response info = new MetaData.Response(HttpVersion.HTTP_1_0, 200, "OK", fields, -1); ByteBuffer header = BufferUtil.allocate(4096); HttpGenerator.Result result = generator.generateResponse(info, header, null, null, true); Assert.assertSame(HttpGenerator.Result.FLUSH, result); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java index 5ecf7b84498..49df1bcdedc 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java @@ -24,8 +24,6 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import org.eclipse.jetty.http.HttpGenerator.RequestInfo; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; @@ -180,7 +178,7 @@ public class HttpTester try { HttpGenerator generator = new HttpGenerator(); - HttpGenerator.Info info = getInfo(); + MetaData info = getInfo(); // System.err.println(info.getClass()); // System.err.println(info); @@ -192,9 +190,9 @@ public class HttpTester loop: while(!generator.isEnd()) { - HttpGenerator.Result result = info instanceof RequestInfo - ?generator.generateRequest((RequestInfo)info,header,chunk,content,true) - :generator.generateResponse((ResponseInfo)info,header,chunk,content,true); + HttpGenerator.Result result = info instanceof MetaData.Request + ?generator.generateRequest((MetaData.Request)info,header,chunk,content,true) + :generator.generateResponse((MetaData.Response)info,false,header,chunk,content,true); switch(result) { case NEED_HEADER: @@ -239,7 +237,7 @@ public class HttpTester } } - abstract public HttpGenerator.Info getInfo(); + abstract public MetaData getInfo(); @Override public int getHeaderCacheSize() @@ -284,9 +282,9 @@ public class HttpTester } @Override - public HttpGenerator.RequestInfo getInfo() + public MetaData.Request getInfo() { - return new HttpGenerator.RequestInfo(_version,this,_content==null?0:_content.size(),_method,_uri); + return new MetaData.Request(_method,new HttpURI(_uri),_version,this,_content==null?0:_content.size()); } @Override @@ -346,9 +344,9 @@ public class HttpTester } @Override - public HttpGenerator.ResponseInfo getInfo() + public MetaData.Response getInfo() { - return new HttpGenerator.ResponseInfo(_version,this,_content==null?-1:_content.size(),_status,_reason,false); + return new MetaData.Response(_version,_status,_reason,this,_content==null?-1:_content.size()); } @Override diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java index 5f1df1b8390..8d0a4c77f3f 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java @@ -40,7 +40,8 @@ public class MetaDataBuilder private String _method; private HttpScheme _scheme; private HostPortHttpField _authority; - private String _path; + private String _path; + private long _contentLength=Long.MIN_VALUE; private HttpFields _fields = new HttpFields(10); @@ -123,6 +124,11 @@ public class MetaDataBuilder case C_PATH: _path = field.getValue(); break; + + case CONTENT_LENGTH: + _contentLength = field.getLongValue(); + _fields.add(field); + break; default: if (field.getName().charAt(0)!=':') @@ -144,10 +150,10 @@ public class MetaDataBuilder _fields = new HttpFields(Math.max(10,fields.size()+5)); if (_method!=null) - return new MetaData.Request(_method,_scheme,_authority,_path,HttpVersion.HTTP_2,fields); + return new MetaData.Request(_method,_scheme,_authority,_path,HttpVersion.HTTP_2,fields,_contentLength); if (_status!=0) - return new MetaData.Response(HttpVersion.HTTP_2,_status,fields); - return new MetaData(HttpVersion.HTTP_2,fields); + return new MetaData.Response(HttpVersion.HTTP_2,_status,fields,_contentLength); + return new MetaData(HttpVersion.HTTP_2,fields,_contentLength); } finally { @@ -157,6 +163,7 @@ public class MetaDataBuilder _authority=null; _path=null; _size=0; + _contentLength=Long.MIN_VALUE; } } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index 7bd6762eb4a..a72dade3de7 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -24,7 +24,6 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpGenerator; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.MetaData; @@ -108,13 +107,13 @@ public class HttpChannelOverHTTP2 extends HttpChannel } @Override - protected void commit(ResponseInfo info) + protected void commit(MetaData.Response info) { if (LOG.isDebugEnabled()) { LOG.debug("HTTP2 Commit Response #{}/{}:{}{} {} {}{}{}", - stream.getId(),Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), info.getHttpVersion(), info.getStatus(), info.getReason(), - System.lineSeparator(), info.getHttpFields()); + stream.getId(),Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), info.getVersion(), info.getStatus(), info.getReason(), + System.lineSeparator(), info.getFields()); } } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index dda7850f72d..a70bef3dbdd 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -64,9 +64,9 @@ public class HttpTransportOverHTTP2 implements HttpTransport } @Override - public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) + public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) { - boolean isHeadRequest = HttpMethod.HEAD.is(request.getMethod()); + boolean isHeadRequest = head; // info != null | content != 0 | last = true => commit + send/end // info != null | content != 0 | last = false => commit + send @@ -143,17 +143,16 @@ public class HttpTransportOverHTTP2 implements HttpTransport }); } - private void commit(HttpGenerator.ResponseInfo info, boolean endStream, Callback callback) + private void commit(MetaData.Response info, boolean endStream, Callback callback) { if (LOG.isDebugEnabled()) { LOG.debug("HTTP2 Response #{}:{}{} {}{}{}", stream.getId(), System.lineSeparator(), HttpVersion.HTTP_2, info.getStatus(), - System.lineSeparator(), info.getHttpFields()); + System.lineSeparator(), info.getFields()); } - MetaData metaData = new MetaData.Response(HttpVersion.HTTP_2, info.getStatus(), info.getHttpFields()); - HeadersFrame frame = new HeadersFrame(stream.getId(), metaData, null, endStream); + HeadersFrame frame = new HeadersFrame(stream.getId(), info, null, endStream); stream.headers(frame, callback); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java index 1846ae83d51..b64a7ddcee6 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java @@ -31,7 +31,6 @@ import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpGenerator; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpStatus; @@ -95,6 +94,8 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor private final HttpChannelState _state; private final Request _request; private final Response _response; + private MetaData.Response _committedInfo; + private RequestLog _requestLog; public HttpChannel(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input) { @@ -204,11 +205,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor throw new UnsupportedOperationException(); } - public void reset() + public void recycle() { _committed.set(false); _request.recycle(); _response.recycle(); + _committedInfo=null; + _requestLog=null; } @Override @@ -427,8 +430,8 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor { HttpFields fields = new HttpFields(); fields.add(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE); - ResponseInfo info = new ResponseInfo(_request.getHttpVersion(), fields, 0, HttpStatus.INTERNAL_SERVER_ERROR_500, null, _request.isHead()); - boolean committed = sendResponse(info, null, true); + MetaData.Response info = new MetaData.Response(_request.getHttpVersion(), HttpStatus.INTERNAL_SERVER_ERROR_500, null, fields, 0); + boolean committed = sendResponse(info,null, true); if (!committed) LOG.warn("Could not send response error 500: "+x); _request.getAsyncContext().complete(); @@ -502,6 +505,12 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor _request.getHttpInput().messageComplete(); } + public void onCompleted() + { + if (_requestLog!=null) + _requestLog.log(_request,_response); + } + public void onEarlyEOF() { _request.getHttpInput().earlyEOF(); @@ -523,7 +532,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor if (handler!=null) content=handler.badMessageError(status,reason,fields); - sendResponse(new ResponseInfo(HttpVersion.HTTP_1_1,fields,0,status,reason,false),content ,true); + sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1,status,reason,fields,0),content ,true); } } catch (IOException e) @@ -539,7 +548,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } } - protected boolean sendResponse(ResponseInfo info, ByteBuffer content, boolean complete, final Callback callback) + protected boolean sendResponse(MetaData.Response info, ByteBuffer content, boolean complete, final Callback callback) { boolean committing = _committed.compareAndSet(false, true); if (committing) @@ -554,12 +563,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor final Callback committed = (status<200&&status>=100)?new Commit100Callback(callback):new CommitCallback(callback); // committing write - _transport.send(info, content, complete, committed); + _committedInfo=info; + _transport.send(info, _request.isHead(), content, complete, committed); } else if (info==null) { // This is a normal write - _transport.send(null,content, complete, callback); + _transport.send(null,_request.isHead(), content, complete, callback); } else { @@ -568,7 +578,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor return committing; } - protected boolean sendResponse(ResponseInfo info, ByteBuffer content, boolean complete) throws IOException + protected boolean sendResponse(MetaData.Response info, ByteBuffer content, boolean complete) throws IOException { try(Blocker blocker = _response.getHttpOutput().acquireWriteBlockingCallback()) { @@ -585,7 +595,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } } - protected void commit (ResponseInfo info) + protected void commit (MetaData.Response info) { if (LOG.isDebugEnabled()) LOG.debug("Commit {} to {}",info,this); @@ -666,8 +676,9 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } else { + _committed.set(false); LOG.warn("Commit failed",x); - _transport.send(HttpGenerator.RESPONSE_500_INFO,null,true,new Callback() + sendResponse(HttpGenerator.RESPONSE_500_INFO,null,true,new Callback() { @Override public void succeeded() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index 968d95f223e..5020229a4f0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -61,9 +61,9 @@ class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandl } @Override - public void reset() + public void recycle() { - super.reset(); + super.recycle(); _expect = false; _expect100Continue = false; _expect102Processing = false; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index 912a51ee095..40077e0a6db 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -514,6 +514,7 @@ public class HttpChannelState event.completed(); } + _channel.onCompleted(); } protected void recycle() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index b9cc0eb8cef..748d34c60f4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -24,9 +24,9 @@ import java.nio.channels.WritePendingException; import java.util.concurrent.RejectedExecutionException; import org.eclipse.jetty.http.HttpGenerator; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; @@ -333,7 +333,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http onClose(); getEndPoint().setConnection(connection); connection.onOpen(); - _channel.reset(); + _channel.recycle(); _parser.reset(); _generator.reset(); releaseRequestBuffer(); @@ -351,7 +351,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http _channel.getRequest().getHttpInput().consumeAll(); // Reset the channel, parsers and generator - _channel.reset(); + _channel.recycle(); if (_generator.isPersistent() && !_parser.isClosed()) _parser.reset(); else @@ -433,7 +433,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http } @Override - public void send(ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) + public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) { if (info == null) { @@ -451,13 +451,14 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http _generator.setPersistent(false); } - if(_sendCallback.reset(info,content,lastContent,callback)) + if(_sendCallback.reset(info,head,content,lastContent,callback)) _sendCallback.iterate(); } private class SendCallback extends IteratingCallback { - private ResponseInfo _info; + private MetaData.Response _info; + private boolean _head; private ByteBuffer _content; private boolean _lastContent; private Callback _callback; @@ -469,11 +470,12 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http super(true); } - private boolean reset(ResponseInfo info, ByteBuffer content, boolean last, Callback callback) + private boolean reset(MetaData.Response info, boolean head, ByteBuffer content, boolean last, Callback callback) { if (reset()) { _info = info; + _head = head; _content = content; _lastContent = last; _callback = callback; @@ -498,7 +500,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http ByteBuffer chunk = _chunk; while (true) { - HttpGenerator.Result result = _generator.generateResponse(_info, _header, chunk, _content, _lastContent); + HttpGenerator.Result result = _generator.generateResponse(_info, _head, _header, chunk, _content, _lastContent); if (LOG.isDebugEnabled()) LOG.debug("{} generate: {} ({},{},{})@{}", this, @@ -541,7 +543,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http case FLUSH: { // Don't write the chunk or the content if this is a HEAD response, or any other type of response that should have no content - if (_channel.getRequest().isHead() || _generator.isNoContent()) + if (_head || _generator.isNoContent()) { BufferUtil.clear(chunk); BufferUtil.clear(_content); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java index fb3471e0052..d4233744d2e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java @@ -26,7 +26,7 @@ import org.eclipse.jetty.util.Callback; public interface HttpTransport { - void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback); + void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback); void push (MetaData.Request request); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 938937f76ae..93a8fcb2a2b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -507,6 +507,8 @@ public class Request implements HttpServletRequest @Override public int getContentLength() { + if (_metadata.getContentLength()!=Long.MIN_VALUE) + return (int)_metadata.getContentLength(); return (int)_metadata.getFields().getLongField(HttpHeader.CONTENT_LENGTH.toString()); } @@ -517,6 +519,8 @@ public class Request implements HttpServletRequest @Override public long getContentLengthLong() { + if (_metadata.getContentLength()!=Long.MIN_VALUE) + return _metadata.getContentLength(); return _metadata.getFields().getLongField(HttpHeader.CONTENT_LENGTH.toString()); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index 1f412851787..48687815983 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -41,13 +41,13 @@ import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpGenerator; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpScheme; 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.http.PreEncodedHttpField; import org.eclipse.jetty.io.RuntimeIOException; @@ -1239,9 +1239,9 @@ public class Response implements HttpServletResponse _out.resetBuffer(); } - protected ResponseInfo newResponseInfo() + protected MetaData.Response newResponseInfo() { - return new ResponseInfo(_channel.getRequest().getHttpVersion(), _fields, getLongContentLength(), getStatus(), getReason(), _channel.getRequest().isHead()); + return new MetaData.Response(_channel.getRequest().getHttpVersion(), getStatus(), getReason(), _fields, getLongContentLength()); } @Override diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index 53454ffdee4..c6225e8afbb 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -36,7 +36,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpGenerator.ResponseInfo; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; @@ -85,7 +84,7 @@ public class ResponseTest _channel = new HttpChannel(connector, new HttpConfiguration(), endp, new HttpTransport() { @Override - public void send(ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) + public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) { callback.succeeded(); } @@ -787,7 +786,7 @@ public class ResponseTest private Response newResponse() { - _channel.reset(); + _channel.recycle(); _channel.getRequest().setMetaData(new MetaData.Request("GET",new HttpURI("/path/info"),HttpVersion.HTTP_1_0,new HttpFields())); return new Response(_channel, _channel.getResponse().getHttpOutput()); } diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java index c85e04a30ac..b880d12dc4d 100644 --- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java +++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java @@ -31,6 +31,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.server.Connector; @@ -90,7 +91,7 @@ public class HttpTransportOverSPDY implements HttpTransport } @Override - public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, final Callback callback) + public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, final Callback callback) { if (LOG.isDebugEnabled()) LOG.debug("Sending {} {} {} {} last={}", this, stream, info, BufferUtil.toDetailString(content), lastContent); @@ -171,7 +172,7 @@ public class HttpTransportOverSPDY implements HttpTransport } - private void sendReply(HttpGenerator.ResponseInfo info, Callback callback, boolean close) + private void sendReply(MetaData.Response info, Callback callback, boolean close) { Fields headers = new Fields(); @@ -190,7 +191,7 @@ public class HttpTransportOverSPDY implements HttpTransport LOG.debug("HTTP < {} {}", httpVersion, httpStatus); // TODO merge the two Field classes into one - HttpFields fields = info.getHttpFields(); + HttpFields fields = info.getFields(); if (fields != null) { for (int i = 0; i < fields.size(); ++i) diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java index 119c6cc2a7c..4e5a7894d39 100644 --- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java +++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPSPDYConnection.java @@ -30,6 +30,7 @@ import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpParser; 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.HttpConfiguration; @@ -191,9 +192,9 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse @Override public void rst(RstInfo rstInfo, Callback handler) { - HttpGenerator.ResponseInfo info = new HttpGenerator.ResponseInfo(HttpVersion.fromString(headers.get - ("version").getValue()), null, 0, 502, "SPDY reset received from upstream server", false); - send(info, null, true, Callback.Adapter.INSTANCE); + MetaData.Response info = new MetaData.Response(HttpVersion.fromString(headers.get + ("version").getValue()), 502, "SPDY reset received from upstream server", null, 0); + send(info, false, null, true, Callback.Adapter.INSTANCE); } @Override @@ -261,10 +262,10 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse // TODO: handle better the HEAD last parameter long contentLength = fields.getLongField(HttpHeader.CONTENT_LENGTH.asString()); - HttpGenerator.ResponseInfo info = new HttpGenerator.ResponseInfo(httpVersion, fields, contentLength, code, - reason, false); + MetaData.Response info = new MetaData.Response(httpVersion, code, reason, fields, + contentLength); - send(info, null, replyInfo.isClose(), new Adapter() + send(info, false, null, replyInfo.isClose(), new Adapter() { @Override public void failed(Throwable x) @@ -300,7 +301,7 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse // Data buffer must be copied, as the ByteBuffer is pooled ByteBuffer byteBuffer = dataInfo.asByteBuffer(false); - send(null, byteBuffer, dataInfo.isClose(), new Adapter() + send(null, false, byteBuffer, dataInfo.isClose(), new Adapter() { @Override public void failed(Throwable x) diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java index db2eb53f2a7..1043b05139d 100644 --- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java +++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDYTest.java @@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; @@ -71,7 +72,7 @@ public class HttpTransportOverSPDYTest @Mock Session session; @Mock - HttpGenerator.ResponseInfo responseInfo; + MetaData.Response responseInfo; Random random = new Random(); short version = SPDY.V3; @@ -97,7 +98,7 @@ public class HttpTransportOverSPDYTest ByteBuffer content = null; boolean lastContent = true; - httpTransportOverSPDY.send(null, content, lastContent, callback); + httpTransportOverSPDY.send(null, false, content, lastContent, callback); ArgumentCaptor dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture()); @@ -114,7 +115,7 @@ public class HttpTransportOverSPDYTest boolean lastContent = true; - httpTransportOverSPDY.send(null, content, lastContent, callback); + httpTransportOverSPDY.send(null, false, content, lastContent, callback); ArgumentCaptor dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture()); @@ -130,7 +131,7 @@ public class HttpTransportOverSPDYTest ByteBuffer content = BufferUtil.EMPTY_BUFFER; boolean lastContent = true; - httpTransportOverSPDY.send(null, content, lastContent, callback); + httpTransportOverSPDY.send(null, false, content, lastContent, callback); ArgumentCaptor dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture()); @@ -146,7 +147,7 @@ public class HttpTransportOverSPDYTest ByteBuffer content = createRandomByteBuffer(); boolean lastContent = false; - httpTransportOverSPDY.send(null, content, lastContent, callback); + httpTransportOverSPDY.send(null, false, content, lastContent, callback); ArgumentCaptor dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).data(dataInfoCaptor.capture(), callbackCaptor.capture()); @@ -161,7 +162,7 @@ public class HttpTransportOverSPDYTest { ByteBuffer content = null; boolean lastContent = false; - httpTransportOverSPDY.send(null, content, lastContent, callback); + httpTransportOverSPDY.send(null, false, content, lastContent, callback); } @Test(expected = IllegalStateException.class) @@ -169,7 +170,7 @@ public class HttpTransportOverSPDYTest { ByteBuffer content = BufferUtil.EMPTY_BUFFER; boolean lastContent = false; - httpTransportOverSPDY.send(null, content, lastContent, callback); + httpTransportOverSPDY.send(null, false, content, lastContent, callback); } @Test @@ -178,7 +179,7 @@ public class HttpTransportOverSPDYTest ByteBuffer content = null; boolean lastContent = false; - httpTransportOverSPDY.send(responseInfo, content, lastContent, callback); + httpTransportOverSPDY.send(responseInfo, false, content, lastContent, callback); ArgumentCaptor replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture()); @@ -198,7 +199,7 @@ public class HttpTransportOverSPDYTest // when stream.isClosed() is called a 2nd time, the reply has closed the stream already when(stream.isClosed()).thenReturn(false).thenReturn(true); - httpTransportOverSPDY.send(responseInfo, content, lastContent, callback); + httpTransportOverSPDY.send(responseInfo, false, content, lastContent, callback); ArgumentCaptor replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture()); @@ -214,7 +215,7 @@ public class HttpTransportOverSPDYTest ByteBuffer content = createRandomByteBuffer(); boolean lastContent = true; - httpTransportOverSPDY.send(responseInfo, content, lastContent, callback); + httpTransportOverSPDY.send(responseInfo, false, content, lastContent, callback); ArgumentCaptor replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture()); @@ -234,7 +235,7 @@ public class HttpTransportOverSPDYTest ByteBuffer content = createRandomByteBuffer(); boolean lastContent = false; - httpTransportOverSPDY.send(responseInfo, content, lastContent, callback); + httpTransportOverSPDY.send(responseInfo, false, content, lastContent, callback); ArgumentCaptor replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(Callback.class); verify(stream, times(1)).reply(replyInfoCaptor.capture(), callbackCaptor.capture()); @@ -257,12 +258,12 @@ public class HttpTransportOverSPDYTest ByteBuffer content = createRandomByteBuffer(); boolean lastContent = false; - httpTransportOverSPDY.send(responseInfo, content, lastContent, callback); + httpTransportOverSPDY.send(responseInfo, false, content, lastContent, callback); ArgumentCaptor replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class); verify(stream, times(1)).reply(replyInfoCaptor.capture(), any(Callback.class)); assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false)); - httpTransportOverSPDY.send(HttpGenerator.RESPONSE_500_INFO, null, true, new Callback.Adapter() + httpTransportOverSPDY.send(HttpGenerator.RESPONSE_500_INFO, false, null, true, new Callback.Adapter() { @Override public void failed(Throwable x)