From c7f25b0928aba0ac06b4f74d4553ce6a85746861 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 26 Apr 2012 10:03:21 +1000 Subject: [PATCH] jetty-9 work in progress --- .../org/eclipse/jetty/http/HttpParser.java | 14 +- .../jetty/http/HttpGeneratorServerTest.java | 3 +- .../eclipse/jetty/http/HttpParserTest.java | 2 +- .../eclipse/jetty/io/ByteArrayEndPoint.java | 1 - .../java/org/eclipse/jetty/io/Connection.java | 1 - .../jetty/io/SelectChannelEndPoint.java | 3 +- .../jetty/io/SelectableConnection.java | 25 +- .../org/eclipse/jetty/io/SelectorManager.java | 6 +- .../jetty/server/AbstractConnector.java | 85 +++++-- .../org/eclipse/jetty/server/Connector.java | 3 +- .../org/eclipse/jetty/server/Dispatcher.java | 6 +- .../org/eclipse/jetty/server/HttpChannel.java | 225 ++++++++---------- .../eclipse/jetty/server/HttpConnection.java | 215 +++++++++++------ .../org/eclipse/jetty/server/HttpOutput.java | 6 +- .../eclipse/jetty/server/NCSARequestLog.java | 2 +- .../org/eclipse/jetty/server/Request.java | 145 ++++++++--- .../org/eclipse/jetty/server/Response.java | 138 +++++++---- .../jetty/server/handler/ConnectHandler.java | 8 +- .../jetty/server/handler/ContextHandler.java | 3 +- .../jetty/server/handler/DefaultHandler.java | 9 +- .../NetworkTrafficSelectChannelConnector.java | 2 +- .../server/nio/SelectChannelConnector.java | 41 ++-- .../org/eclipse/jetty/util/ArrayQueue.java | 1 + 23 files changed, 567 insertions(+), 377 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index 7beba41d2fc..4a9477fd35c 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -342,7 +342,7 @@ public class HttpParser return_from_parse|=_requestHandler.startRequest(_field0,_field1,null); _persistent=false; _state=State.SEEKING_EOF; - return_from_parse|=_handler.headerComplete(); + return_from_parse|=_handler.headerComplete(false,false); return_from_parse|=_handler.messageComplete(_contentPosition); } break; @@ -369,7 +369,7 @@ public class HttpParser return_from_parse|=_requestHandler.startRequest(_field0, _field1, null); _persistent=false; _state=State.SEEKING_EOF; - return_from_parse|=_handler.headerComplete(); + return_from_parse|=_handler.headerComplete(false,false); return_from_parse|=_handler.messageComplete(_contentPosition); } } @@ -522,23 +522,23 @@ public class HttpParser { case EOF_CONTENT: _state=State.EOF_CONTENT; - return_from_parse|=_handler.headerComplete(); // May recurse here ! + return_from_parse|=_handler.headerComplete(true,false); break; case CHUNKED_CONTENT: _state=State.CHUNKED_CONTENT; - return_from_parse|=_handler.headerComplete(); // May recurse here ! + return_from_parse|=_handler.headerComplete(true,_persistent); break; case NO_CONTENT: - return_from_parse|=_handler.headerComplete(); + return_from_parse|=_handler.headerComplete(false,_persistent); _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?State.END:State.SEEKING_EOF; return_from_parse|=_handler.messageComplete(_contentPosition); break; default: _state=State.CONTENT; - return_from_parse|=_handler.headerComplete(); // May recurse here ! + return_from_parse|=_handler.headerComplete(true,_persistent); break; } } @@ -942,7 +942,7 @@ public class HttpParser { public boolean content(ByteBuffer ref) throws IOException; - public boolean headerComplete() throws IOException; + public boolean headerComplete(boolean hasBody,boolean persistent) throws IOException; public boolean messageComplete(long contentLength) throws IOException; 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 1e345a5ac8e..bc26624e29c 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 @@ -51,7 +51,6 @@ public class HttpGeneratorServerTest return false; } - @Override public boolean earlyEOF() { @@ -59,7 +58,7 @@ public class HttpGeneratorServerTest } @Override - public boolean headerComplete() throws IOException + public boolean headerComplete(boolean hasBody,boolean persistent) throws IOException { _content= null; return false; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index bce0f5ab815..d688da87402 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -504,7 +504,7 @@ public class HttpParserTest } @Override - public boolean headerComplete() + public boolean headerComplete(boolean hasBody,boolean persistent) { //System.err.println("headerComplete"); _content= null; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java index 5147668895f..b2a8cb0d236 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java @@ -34,7 +34,6 @@ public class ByteArrayEndPoint implements EndPoint protected boolean _closed; protected boolean _growOutput; protected int _maxIdleTime; - protected Connection _connection; /* ------------------------------------------------------------ */ /** diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java index c4de0328ed0..3bb524c03a1 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java @@ -19,7 +19,6 @@ public interface Connection { EndPoint getEndPoint(); - int getMaxIdleTime(); /** diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java index ec6b462d4e7..5933a21a074 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java @@ -104,7 +104,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Selectable /** Called by selectSet to schedule handling * */ - public void selected() throws IOException + public void onSelected() throws IOException { _lock.lock(); _selected=true; @@ -293,7 +293,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements Selectable return l; } - /* ------------------------------------------------------------ */ /** * Updates selection key. This method schedules a call to doUpdateKey to do the keyChange diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectableConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectableConnection.java index 9a266a5d449..226aa1eb1e8 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectableConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectableConnection.java @@ -20,7 +20,7 @@ public abstract class SelectableConnection implements Connection private final Condition _readable=_lock.newCondition(); private final Condition _writeable=_lock.newCondition(); private Thread _readBlocked; - private boolean _writeBlocked; + private Thread _writeBlocked; private final Runnable _reader=new Runnable() { @@ -84,7 +84,7 @@ public abstract class SelectableConnection implements Connection try { if (_readBlocked!=null) - _readable.signalAll(); + _readable.signal(); else return _reader; } @@ -100,8 +100,8 @@ public abstract class SelectableConnection implements Connection _lock.lock(); try { - if (_writeBlocked) - _writeable.signalAll(); + if (_writeBlocked!=null) + _writeable.signal(); else return _writer; } @@ -119,13 +119,8 @@ public abstract class SelectableConnection implements Connection try { if (_readBlocked!=null) - { - System.err.println("Already blocked by "+_readBlocked); - for (StackTraceElement e :_readBlocked.getStackTrace()) - System.err.println(" at "+e); - - throw new IllegalStateException(); - } + throw new IllegalStateException("already blocked by "+_readBlocked); + _readBlocked=Thread.currentThread(); _endp.setReadInterested(true); readable=_readable.await(getMaxIdleTime(),TimeUnit.SECONDS); @@ -150,9 +145,9 @@ public abstract class SelectableConnection implements Connection boolean writeable=false; try { - if (_writeBlocked) - throw new IllegalStateException(); - _writeBlocked=true; + if (_writeBlocked!=null) + throw new IllegalStateException("already blocked by "+_writeBlocked); + _writeBlocked=Thread.currentThread(); _endp.setWriteInterested(true); writeable=_writeable.await(getMaxIdleTime(),TimeUnit.SECONDS); } @@ -164,7 +159,7 @@ public abstract class SelectableConnection implements Connection { if (!writeable) _endp.setWriteInterested(false); - _writeBlocked=false; + _writeBlocked=null; _lock.unlock(); } return writeable; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java index f2b377bd2d0..c6dd98f9a8b 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java @@ -605,7 +605,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa if (att instanceof SelectChannelEndPoint) { if (key.isReadable()||key.isWritable()) - ((SelectChannelEndPoint)att).selected(); + ((SelectChannelEndPoint)att).onSelected(); } else if (key.isConnectable()) { @@ -627,7 +627,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa key.interestOps(SelectionKey.OP_READ); SelectChannelEndPoint endpoint = createEndPoint(channel,key); key.attach(endpoint); - endpoint.selected(); + endpoint.onSelected(); } else { @@ -642,7 +642,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa SelectChannelEndPoint endpoint = createEndPoint(channel,key); key.attach(endpoint); if (key.isReadable()) - endpoint.selected(); + endpoint.onSelected(); } key = null; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index b33ba39a3b7..8b69863b37b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -15,6 +15,7 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.concurrent.atomic.AtomicLong; @@ -109,12 +110,14 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* ------------------------------------------------------------ */ /* */ + @Override public Server getServer() { return _server; } /* ------------------------------------------------------------ */ + @Override public void setServer(Server server) { _server = server; @@ -128,7 +131,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* ------------------------------------------------------------ */ /** Set the ThreadPool. - * The threadpool passed is added via {@link #addBean(Object)} so that + * The threadpool passed is added via {@link #addBean(Object)} so that * it's lifecycle may be managed as a {@link AggregateLifeCycle}. * @param threadPool the threadPool to set */ @@ -142,6 +145,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* ------------------------------------------------------------ */ /** */ + @Override public void setHost(String host) { _host = host; @@ -150,18 +154,21 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* ------------------------------------------------------------ */ /* */ + @Override public String getHost() { return _host; } /* ------------------------------------------------------------ */ + @Override public void setPort(int port) { _port = port; } /* ------------------------------------------------------------ */ + @Override public int getPort() { return _port; @@ -171,6 +178,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Returns the maxIdleTime. */ + @Override public int getMaxIdleTime() { return _maxIdleTime; @@ -196,6 +204,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht * @param maxIdleTime * The maxIdleTime to set. */ + @Override public void setMaxIdleTime(int maxIdleTime) { _maxIdleTime = maxIdleTime; @@ -225,6 +234,8 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht * @return Returns the maxIdleTime when resources are low. * @deprecated */ + @Deprecated + @Override public final int getLowResourceMaxIdleTime() { return getLowResourcesMaxIdleTime(); @@ -236,6 +247,8 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht * The maxIdleTime to set when resources are low. * @deprecated */ + @Deprecated + @Override public final void setLowResourceMaxIdleTime(int maxIdleTime) { setLowResourcesMaxIdleTime(maxIdleTime); @@ -396,14 +409,15 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ - public void customize(EndPoint endpoint, Request request) throws IOException + @Override + public void customize(Request request) throws IOException { if (isForwarded()) - checkForwardedHeaders(endpoint,request); + checkForwardedHeaders(request); } /* ------------------------------------------------------------ */ - protected void checkForwardedHeaders(EndPoint endpoint, Request request) throws IOException + protected void checkForwardedHeaders(Request request) throws IOException { HttpFields httpFields = request.getConnection().getRequestFields(); @@ -453,23 +467,8 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } if (forwardedFor != null) - { - request.setRemoteAddr(forwardedFor); - InetAddress inetAddress = null; - - if (_useDNS) - { - try - { - inetAddress = InetAddress.getByName(forwardedFor); - } - catch (UnknownHostException e) - { - LOG.ignore(e); - } - } - - request.setRemoteHost(inetAddress == null?forwardedFor:inetAddress.getHostName()); + { + request.setRemoteAddr(new InetSocketAddress(forwardedFor,request.getRemotePort())); } if (forwardedProto != null) @@ -502,6 +501,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + @Override public void persist(EndPoint endpoint) throws IOException { } @@ -510,6 +510,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* * @see org.eclipse.jetty.server.Connector#getConfidentialPort() */ + @Override public int getConfidentialPort() { return _confidentialPort; @@ -520,6 +521,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* * @see org.eclipse.jetty.server.Connector#getConfidentialScheme() */ + @Override public String getConfidentialScheme() { return _confidentialScheme; @@ -529,6 +531,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server .Request) */ + @Override public boolean isIntegral(Request request) { return false; @@ -538,6 +541,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* * @see org.eclipse.jetty.server.Connector#getConfidentialPort() */ + @Override public int getIntegralPort() { return _integralPort; @@ -547,6 +551,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* * @see org.eclipse.jetty.server.Connector#getIntegralScheme() */ + @Override public String getIntegralScheme() { return _integralScheme; @@ -556,6 +561,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /* * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request) */ + @Override public boolean isConfidential(Request request) { return _forwarded && request.getScheme().equalsIgnoreCase(HttpScheme.HTTPS.toString()); @@ -610,6 +616,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + @Override public boolean getResolveNames() { return _useDNS; @@ -795,91 +802,109 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht _forwardedSslSessionIdHeader = forwardedSslSessionId; } + @Override public int getRequestBufferSize() { return _buffers.getRequestBufferSize(); } + @Override public void setRequestBufferSize(int requestBufferSize) { _buffers.setRequestBufferSize(requestBufferSize); } + @Override public int getRequestHeaderSize() { return _buffers.getRequestHeaderSize(); } + @Override public void setRequestHeaderSize(int requestHeaderSize) { _buffers.setRequestHeaderSize(requestHeaderSize); } + @Override public int getResponseBufferSize() { return _buffers.getResponseBufferSize(); } + @Override public void setResponseBufferSize(int responseBufferSize) { _buffers.setResponseBufferSize(responseBufferSize); } + @Override public int getResponseHeaderSize() { return _buffers.getResponseHeaderSize(); } + @Override public void setResponseHeaderSize(int responseHeaderSize) { _buffers.setResponseHeaderSize(responseHeaderSize); } + @Override public Type getRequestBufferType() { return _buffers.getRequestBufferType(); } + @Override public Type getRequestHeaderType() { return _buffers.getRequestHeaderType(); } + @Override public Type getResponseBufferType() { return _buffers.getResponseBufferType(); } + @Override public Type getResponseHeaderType() { return _buffers.getResponseHeaderType(); } + @Override public void setRequestBuffers(Buffers requestBuffers) { _buffers.setRequestBuffers(requestBuffers); } + @Override public void setResponseBuffers(Buffers responseBuffers) { _buffers.setResponseBuffers(responseBuffers); } + @Override public Buffers getRequestBuffers() { return _buffers.getRequestBuffers(); } + @Override public Buffers getResponseBuffers() { return _buffers.getResponseBuffers(); } + @Override public void setMaxBuffers(int maxBuffers) { _buffers.setMaxBuffers(maxBuffers); } + @Override public int getMaxBuffers() { return _buffers.getMaxBuffers(); @@ -908,6 +933,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + @Override public void run() { Thread current = Thread.currentThread(); @@ -966,6 +992,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + @Override public String getName() { if (_name == null) @@ -983,6 +1010,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Get the number of requests handled by this connector since last call of statsReset(). If setStatsOn(false) then this is undefined. */ + @Override public int getRequests() { return (int)_requestStats.getTotal(); @@ -992,6 +1020,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Returns the connectionsDurationTotal. */ + @Override public long getConnectionsDurationTotal() { return _connectionDurationStats.getTotal(); @@ -1001,6 +1030,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Number of connections accepted by the server since statsReset() called. Undefined if setStatsOn(false). */ + @Override public int getConnections() { return (int)_connectionStats.getTotal(); @@ -1010,6 +1040,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Number of connections currently open that were opened since statsReset() called. Undefined if setStatsOn(false). */ + @Override public int getConnectionsOpen() { return (int)_connectionStats.getCurrent(); @@ -1019,6 +1050,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Maximum number of connections opened simultaneously since statsReset() called. Undefined if setStatsOn(false). */ + @Override public int getConnectionsOpenMax() { return (int)_connectionStats.getMax(); @@ -1028,6 +1060,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Mean duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false). */ + @Override public double getConnectionsDurationMean() { return _connectionDurationStats.getMean(); @@ -1037,6 +1070,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Maximum duration in milliseconds of an open connection since statsReset() called. Undefined if setStatsOn(false). */ + @Override public long getConnectionsDurationMax() { return _connectionDurationStats.getMax(); @@ -1046,6 +1080,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Standard deviation of duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false). */ + @Override public double getConnectionsDurationStdDev() { return _connectionDurationStats.getStdDev(); @@ -1055,6 +1090,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Mean number of requests per connection since statsReset() called. Undefined if setStatsOn(false). */ + @Override public double getConnectionsRequestsMean() { return _requestStats.getMean(); @@ -1064,6 +1100,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Maximum number of requests per connection since statsReset() called. Undefined if setStatsOn(false). */ + @Override public int getConnectionsRequestsMax() { return (int)_requestStats.getMax(); @@ -1073,6 +1110,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Standard deviation of number of requests per connection since statsReset() called. Undefined if setStatsOn(false). */ + @Override public double getConnectionsRequestsStdDev() { return _requestStats.getStdDev(); @@ -1082,6 +1120,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * Reset statistics. */ + @Override public void statsReset() { updateNotEqual(_statsStartedAt,-1,System.currentTimeMillis()); @@ -1092,6 +1131,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + @Override public void setStatsOn(boolean on) { if (on && _statsStartedAt.get() != -1) @@ -1108,6 +1148,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return True if statistics collection is turned on. */ + @Override public boolean getStatsOn() { return _statsStartedAt.get() != -1; @@ -1117,6 +1158,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht /** * @return Timestamp stats were started at. */ + @Override public long getStatsOnMs() { long start = _statsStartedAt.get(); @@ -1194,6 +1236,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + @Override public boolean isLowResources() { if (_threadPool != null) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java index 95c30b15139..9b1e9e3d6d9 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java @@ -179,11 +179,10 @@ public interface Connector extends LifeCycle /** Customize a request for an endpoint. * Called on every request to allow customization of the request for * the particular endpoint (eg security properties from a SSL connection). - * @param endpoint * @param request * @throws IOException */ - void customize(EndPoint endpoint, Request request) throws IOException; + void customize(Request request) throws IOException; /* ------------------------------------------------------------ */ /** Persist an endpoint. diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java index 5c5866250c5..e8b5b2a8d89 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java @@ -93,6 +93,7 @@ public class Dispatcher implements RequestDispatcher /* * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ + @Override public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException { forward(request, response, DispatcherType.FORWARD); @@ -111,9 +112,10 @@ public class Dispatcher implements RequestDispatcher /* * @see javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ + @Override public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException { - Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentHttpChannel().getRequest(); + Request baseRequest=(request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest(); if (!(request instanceof HttpServletRequest)) @@ -194,7 +196,7 @@ public class Dispatcher implements RequestDispatcher */ protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch) throws ServletException, IOException { - Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentHttpChannel().getRequest(); + Request baseRequest=(request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest(); Response base_response=baseRequest.getResponse(); response.resetBuffer(); base_response.fwdReset(); 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 73aad5e756d..960b898c386 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 @@ -39,6 +39,7 @@ import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.io.UncheckedPrintWriter; @@ -74,6 +75,7 @@ public abstract class HttpChannel private int _requests; private final Server _server; + private final Connection _connection; private final HttpURI _uri; private final HttpFields _requestFields; @@ -100,64 +102,19 @@ public abstract class HttpChannel private boolean _expect102Processing = false; private boolean _host = false; - public HttpParser.RequestHandler getRequestHandler() - { - return _handler; - } - - public HttpGenerator.ResponseInfo getResponseInfo() - { - return _info; - } private final RequestHandler _handler = new RequestHandler(); - private final HttpGenerator.ResponseInfo _info = new HttpGenerator.ResponseInfo() - { - @Override - public HttpVersion getHttpVersion() - { - return getRequest().getHttpVersion(); - } - - @Override - public HttpFields getHttpFields() - { - return _responseFields; - } - - @Override - public long getContentLength() - { - return _response.getLongContentLength(); - } - - @Override - public boolean isHead() - { - return getRequest().isHead(); - } - - @Override - public int getStatus() - { - return _response.getStatus(); - } - - @Override - public String getReason() - { - return _response.getReason(); - } - }; + private final HttpGenerator.ResponseInfo _info = new Info(); /* ------------------------------------------------------------ */ /** Constructor * */ - public HttpChannel(Server server) + public HttpChannel(Server server,Connection connection) { _server = server; + _connection = connection; _uri = new HttpURI(URIUtil.__CHARSET); _requestFields = new HttpFields(); _responseFields = new HttpFields(server.getMaxCookieVersion()); @@ -165,11 +122,24 @@ public abstract class HttpChannel _response = new Response(this); _async = _request.getAsyncContinuation(); } + + /* ------------------------------------------------------------ */ + public Connection getConnection() + { + return _connection; + } /* ------------------------------------------------------------ */ - abstract public InetSocketAddress getLocalAddress(); - abstract public InetSocketAddress getRemoteAddress(); - abstract public long getMaxIdleTime(); + public HttpParser.RequestHandler getRequestHandler() + { + return _handler; + } + + /* ------------------------------------------------------------ */ + public HttpGenerator.ResponseInfo getResponseInfo() + { + return _info; + } /* ------------------------------------------------------------ */ /** @@ -228,6 +198,18 @@ public abstract class HttpChannel return _response; } + /* ------------------------------------------------------------ */ + public InetSocketAddress getLocalAddress() + { + return getConnection().getEndPoint().getLocalAddress(); + } + + /* ------------------------------------------------------------ */ + public InetSocketAddress getRemoteAddress() + { + return getConnection().getEndPoint().getRemoteAddress(); + } + /* ------------------------------------------------------------ */ /** * Get the inputStream from the connection. @@ -369,7 +351,7 @@ public abstract class HttpChannel if (_async.isInitial()) { _request.setDispatcherType(DispatcherType.REQUEST); - customize(_request); + getConnector().customize(_request); server.handle(this); } else @@ -435,18 +417,13 @@ public abstract class HttpChannel // do anything special here other than make the connection not persistent _expect100Continue = false; if (!_response.isCommitted()) - setPersistent(false); + _response.addHeader(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE.toString()); } - if (error) - setPersistent(false); - else if (!_response.isCommitted() && !_request.isHandled()) + if (!error && !_response.isCommitted() && !_request.isHandled()) _response.sendError(HttpServletResponse.SC_NOT_FOUND); _response.complete(); - if (isPersistent()) - persist(); - _request.setHandled(true); } } @@ -508,10 +485,7 @@ public abstract class HttpChannel { synchronized (_inputQ.lock()) { - ByteBuffer content=null; - long start=-1; - long timeout=-1; - + ByteBuffer content=null; while(content==null) { content=_inputQ.peekUnsafe(); @@ -526,41 +500,8 @@ public abstract class HttpChannel // check for EOF if (_inputEOF) return -1; - - // block for content - if (start<0) - { - start=System.currentTimeMillis(); - timeout=getMaxIdleTime(); - } - else - { - long now=System.currentTimeMillis(); - timeout=timeout-(now-start); - start=now; - } - if (timeout<=0) - throw new SocketTimeoutException(">"+getMaxIdleTime()+"ms"); - try - { - // Alternate approach would be to - // blockReadable - // read and then runParser - // runParser - // This would be better for a client - - setReadInterested(true); - _inputQ.wait(timeout); - } - catch(InterruptedException e) - { - LOG.ignore(e); - } - finally - { - setReadInterested(false); - } - content=_inputQ.peekUnsafe(); + + blockForContent(); } } @@ -586,6 +527,7 @@ public abstract class HttpChannel } /* ------------------------------------------------------------ */ + @Override public String toString() { return String.format("%s r=%d", @@ -593,6 +535,48 @@ public abstract class HttpChannel _requests); } + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + private final class Info implements HttpGenerator.ResponseInfo + { + @Override + public HttpVersion getHttpVersion() + { + return getRequest().getHttpVersion(); + } + + @Override + public HttpFields getHttpFields() + { + return _responseFields; + } + + @Override + public long getContentLength() + { + return _response.getLongContentLength(); + } + + @Override + public boolean isHead() + { + return getRequest().isHead(); + } + + @Override + public int getStatus() + { + return _response.getStatus(); + } + + @Override + public String getReason() + { + return _response.getReason(); + } + } + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ @@ -704,7 +688,7 @@ public abstract class HttpChannel } @Override - public boolean headerComplete() throws IOException + public boolean headerComplete(boolean hasBody,boolean persistent) throws IOException { _requests++; switch (_version) @@ -712,10 +696,8 @@ public abstract class HttpChannel case HTTP_0_9: break; case HTTP_1_0: - if (isPersistent()) - { + if (persistent) _responseFields.add(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE); - } if (_server.getSendDateHeader()) _responseFields.putDateField(HttpHeader.DATE.toString(),_request.getTimeStamp()); @@ -723,10 +705,9 @@ public abstract class HttpChannel case HTTP_1_1: - if (!isPersistent()) - { + if (!persistent) _responseFields.add(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE); - } + if (_server.getSendDateHeader()) _responseFields.putDateField(HttpHeader.DATE.toString(),_request.getTimeStamp()); @@ -760,18 +741,14 @@ public abstract class HttpChannel @Override public boolean content(ByteBuffer ref) throws IOException { - synchronized (_inputQ) - { - _inputQ.addUnsafe(ref); - _inputQ.notifyAll(); - } + _inputQ.add(ref); return true; } @Override public boolean messageComplete(long contentLength) throws IOException { - synchronized (_inputQ) + synchronized (_inputQ.lock()) { _inputEOF=true; } @@ -857,7 +834,7 @@ public abstract class HttpChannel // Process content. if (content instanceof ByteBuffer) { - throw new IllegalArgumentException("not implemented!"); + send((ByteBuffer)content); } else if (content instanceof InputStream) { @@ -871,16 +848,22 @@ public abstract class HttpChannel } - + public abstract Connector getConnector(); + + public abstract long getMaxIdleTime(); + public abstract void asyncDispatch(); public abstract void scheduleTimeout(Task timeout, long timeoutMs); public abstract void cancelTimeout(Task timeout); - - protected abstract int write(ByteBuffer content,boolean volatileContent) throws IOException; + protected abstract void blockForContent() throws IOException; + + protected abstract int write(ByteBuffer content) throws IOException; + + protected abstract int send(ByteBuffer content) throws IOException; protected abstract void sendError(int status, String reason, String content, boolean close) throws IOException; @@ -893,20 +876,10 @@ public abstract class HttpChannel protected abstract void resetBuffer(); protected abstract boolean isResponseCommitted(); - - protected abstract boolean isPersistent(); - protected abstract void setPersistent(boolean persistent); - protected abstract void flushResponse() throws IOException; - protected abstract void completeResponse(); + protected abstract void completeResponse() throws IOException; - protected abstract Connector getConnector(); - - protected abstract void persist(); - protected abstract void customize(Request request); - - protected abstract void setReadInterested(boolean interested); } 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 fb8d0c2b945..3b1ef45500b 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 @@ -14,13 +14,7 @@ package org.eclipse.jetty.server; import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.InetSocketAddress; import java.nio.ByteBuffer; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import org.eclipse.jetty.http.HttpException; import org.eclipse.jetty.http.HttpFields; @@ -31,7 +25,6 @@ import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.SelectableConnection; import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.SelectableEndPoint; import org.eclipse.jetty.util.BufferUtil; @@ -41,7 +34,7 @@ import org.eclipse.jetty.util.thread.Timeout.Task; /** */ -public abstract class HttpConnection extends SelectableConnection +public class HttpConnection extends SelectableConnection { private static final Logger LOG = Log.getLogger(HttpConnection.class); @@ -182,7 +175,8 @@ public abstract class HttpConnection extends SelectableConnection /* ------------------------------------------------------------ */ - public void processInput() + @Override + public void doRead() { Connection connection = this; boolean progress=true; @@ -191,9 +185,6 @@ public abstract class HttpConnection extends SelectableConnection { setCurrentConnection(this); - // don't check for idle while dispatched (unless blocking IO is done). - getSelectableEndPoint().setCheckForIdle(false); - // While progress and the connection has not changed while (progress && connection==this) { @@ -208,7 +199,21 @@ public abstract class HttpConnection extends SelectableConnection // If we parse to an event, call the connection if (BufferUtil.hasContent(_requestBuffer) && _parser.parseNext(_requestBuffer)) - _channel.handleRequest(); + { + // don't check for idle while dispatched (unless blocking IO is done). + getSelectableEndPoint().setCheckForIdle(false); + try + { + _channel.handleRequest(); + } + finally + { + // If we are not suspended + if (!_channel.getRequest().getAsyncContinuation().isAsyncStarted()) + // reenable idle checking unless request is suspended + getSelectableEndPoint().setCheckForIdle(true); + } + } } catch (HttpException e) @@ -218,8 +223,8 @@ public abstract class HttpConnection extends SelectableConnection } finally { - // Return empty request buffer - if (_requestBuffer!=null && !_requestBuffer.hasRemaining()) + // Return empty request buffer if all has been consumed + if (_requestBuffer!=null && !_requestBuffer.hasRemaining() && _channel.available()==0) { _connector.getRequestBuffers().returnBuffer(_requestBuffer); _requestBuffer=null; @@ -252,26 +257,93 @@ public abstract class HttpConnection extends SelectableConnection } catch(IOException e) { - // TODO + LOG.warn(e); } finally { setCurrentConnection(null); - // If we are not suspended - if (!_channel.getRequest().getAsyncContinuation().isAsyncStarted()) - { - // reenable idle checking unless request is suspended - getSelectableEndPoint().setCheckForIdle(true); - } } } + + /* ------------------------------------------------------------ */ + private int send(HttpGenerator.ResponseInfo info, ByteBuffer content) throws IOException + { + if (_generator.isCommitted() || BufferUtil.hasContent(_responseBuffer) || _toFlush!=0) + throw new IllegalStateException("!send after append"); + if (_generator.isComplete()) + throw new EofException(); + + long prepared=_generator.getContentPrepared(); + + do + { + if (LOG.isDebugEnabled()) + LOG.debug("{}: send({},{},{})@{}", + this, + BufferUtil.toSummaryString(_responseHeader), + BufferUtil.toSummaryString(_responseBuffer), + BufferUtil.toSummaryString(content), + _generator.getState()); + + HttpGenerator.Result result=_generator.generate(info,_responseHeader,null,_responseBuffer,content,Action.COMPLETE); + if (LOG.isDebugEnabled()) + LOG.debug("{}: {} ({},{},{})@{}", + this, + result, + BufferUtil.toSummaryString(_responseHeader), + BufferUtil.toSummaryString(_responseBuffer), + BufferUtil.toSummaryString(content), + _generator.getState()); + + switch(result) + { + case NEED_HEADER: + _responseHeader=_connector.getResponseBuffers().getHeader(); + break; + + case NEED_BUFFER: + _responseBuffer=_connector.getResponseBuffers().getBuffer(); + break; + + case NEED_CHUNK: + throw new IllegalStateException("!chunk when content length known"); + + case FLUSH: + _toFlush= + (BufferUtil.hasContent(_responseHeader)?8:0)+ + (BufferUtil.hasContent(_chunk)?4:0)+ + (BufferUtil.hasContent(_responseBuffer)?2:0); + flush(true); + break; + + case FLUSH_CONTENT: + _content=content; + _toFlush= + (BufferUtil.hasContent(_responseHeader)?8:0)+ + (BufferUtil.hasContent(_chunk)?4:0)+ + (BufferUtil.hasContent(_content)?1:0); + flush(false); + break; + + case SHUTDOWN_OUT: + getEndPoint().shutdownOutput(); + break; + + case OK: + break; + } + } + while(BufferUtil.hasContent(content)); + + return (int)(prepared-_generator.getContentPrepared()); + } /* ------------------------------------------------------------ */ - private int generate(ByteBuffer content, Action action, boolean volatileContent) throws IOException + private int write(HttpGenerator.ResponseInfo info, ByteBuffer content, Action action) throws IOException { - if (!_generator.isComplete()) + if (_generator.isComplete()) throw new EofException(); long prepared=_generator.getContentPrepared(); @@ -290,7 +362,7 @@ public abstract class HttpConnection extends SelectableConnection BufferUtil.toSummaryString(content), action,_generator.getState()); - HttpGenerator.Result result=_generator.generate(_channel.getResponseInfo(),_responseHeader,_chunk,_responseBuffer,content,action); + HttpGenerator.Result result=_generator.generate(info,_responseHeader,_chunk,_responseBuffer,content,action); if (LOG.isDebugEnabled()) LOG.debug("{}: {} ({},{},{},{},{})@{}", this, @@ -330,7 +402,7 @@ public abstract class HttpConnection extends SelectableConnection (BufferUtil.hasContent(_responseHeader)?8:0)+ (BufferUtil.hasContent(_chunk)?4:0)+ (BufferUtil.hasContent(_content)?1:0); - flush(volatileContent); + flush(false); break; case SHUTDOWN_OUT: @@ -435,19 +507,7 @@ public abstract class HttpConnection extends SelectableConnection { private HttpOverHttpChannel(Server server) { - super(server); - } - - @Override - public InetSocketAddress getLocalAddress() - { - return _endp.getLocalAddress(); - } - - @Override - public InetSocketAddress getRemoteAddress() - { - return _endp.getRemoteAddress(); + super(server,HttpConnection.this); } @Override @@ -478,16 +538,15 @@ public abstract class HttpConnection extends SelectableConnection } @Override - protected int write(ByteBuffer content, boolean volatileContent) throws IOException + protected int write(ByteBuffer content) throws IOException { - return HttpConnection.this.generate(content,Action.PREPARE,volatileContent); + return HttpConnection.this.write(getResponseInfo(),content,Action.PREPARE); } @Override - protected void setPersistent(boolean persistent) + protected int send(ByteBuffer content) throws IOException { - _parser.setPersistent(persistent); - _generator.setPersistent(persistent); + return HttpConnection.this.send(getResponseInfo(),content); } @Override @@ -533,14 +592,8 @@ public abstract class HttpConnection extends SelectableConnection if (close) _generator.setPersistent(false); - ByteBuffer buf=BufferUtil.toBuffer(content); - - if (_responseHeader==null) - _responseHeader=_connector.getResponseBuffers().getHeader(); - if (_responseBuffer==null) - _responseBuffer=_connector.getResponseBuffers().getBuffer(); - - _generator.generate(response,_responseHeader,null,_responseBuffer,buf,Action.COMPLETE); + HttpConnection.this.send(response,BufferUtil.toBuffer(content)); + } @@ -558,24 +611,12 @@ public abstract class HttpConnection extends SelectableConnection } - @Override - protected void persist() - { - // TODO Auto-generated method stub - - } - @Override protected boolean isResponseCommitted() { return _generator.isCommitted(); } - @Override - protected boolean isPersistent() - { - return _generator.isPersistent(); - } @Override protected void increaseContentBufferSize(int size) @@ -594,7 +635,7 @@ public abstract class HttpConnection extends SelectableConnection } @Override - protected Connector getConnector() + public Connector getConnector() { return _connector; } @@ -602,27 +643,45 @@ public abstract class HttpConnection extends SelectableConnection @Override protected void flushResponse() throws IOException { - HttpConnection.this.generate(null,Action.FLUSH,false); + HttpConnection.this.write(getResponseInfo(),null,Action.FLUSH); } @Override - protected void customize(Request request) + protected void completeResponse() throws IOException { - // TODO Auto-generated method stub - - } - - @Override - protected void completeResponse() - { - // TODO Auto-generated method stub - + HttpConnection.this.write(getResponseInfo(),null,Action.COMPLETE); } @Override - protected void setReadInterested(boolean interested) + protected void blockForContent() throws IOException { - _endp.setReadInterested(interested); + // While progress and the connection has not changed + while (!_endp.isInputShutdown()) + { + try + { + // Wait until we can read + blockReadable(); + + // We will need a buffer to read into + if (_requestBuffer==null) + _requestBuffer=_connector.getRequestBuffers().getBuffer(); + + // If we parse to an event, return + if (BufferUtil.hasContent(_requestBuffer) && _parser.parseNext(_requestBuffer)) + return; + } + finally + { + // Return empty request buffer + if (_requestBuffer!=null && !_requestBuffer.hasRemaining() && _channel.available()==0) + { + _connector.getRequestBuffers().returnBuffer(_requestBuffer); + _requestBuffer=null; + } + } + } } + }; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java index 4b5b2437be0..d9684407f77 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java @@ -105,7 +105,7 @@ public class HttpOutput extends ServletOutputStream if (_closed) throw new IOException("Closed"); - _written+=_channel.write(ByteBuffer.wrap(b,off,len),true); + _written+=_channel.write(ByteBuffer.wrap(b,off,len)); _channel.getResponse().checkAllContentWritten(_written); } @@ -119,7 +119,7 @@ public class HttpOutput extends ServletOutputStream if (_closed) throw new IOException("Closed"); - _written+=_channel.write(ByteBuffer.wrap(b),true); + _written+=_channel.write(ByteBuffer.wrap(b)); _channel.getResponse().checkAllContentWritten(_written); } @@ -133,7 +133,7 @@ public class HttpOutput extends ServletOutputStream if (_closed) throw new IOException("Closed"); - _written+=_channel.write(ByteBuffer.wrap(new byte[]{(byte)b}),true); + _written+=_channel.write(ByteBuffer.wrap(new byte[]{(byte)b})); _channel.getResponse().checkAllContentWritten(_written); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java index 6d25d7d15ba..78cac3aaed0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java @@ -485,7 +485,7 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog if (_logDateCache != null) buf.append(_logDateCache.format(request.getTimeStamp())); else - buf.append(request.getTimeStampBuffer().toString()); + buf.write(request.getTimeStampBuffer().toString()); buf.append("] \""); buf.append(request.getMethod()); 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 e09b7054344..e30ad553bfe 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 @@ -24,6 +24,7 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.security.Principal; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; @@ -113,14 +114,13 @@ public class Request implements HttpServletRequest public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig"; private static final Logger LOG = Log.getLogger(Request.class); - private static final String __ASYNC_FWD = "org.eclipse.asyncfwd"; private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); private static final int __NONE = 0, _STREAM = 1, __READER = 2; private final HttpChannel _channel; private HttpFields _fields; private final AsyncContinuation _async = new AsyncContinuation(); - + private boolean _asyncSupported = true; private volatile Attributes _attributes; private Authentication _authentication; @@ -160,12 +160,11 @@ public class Request implements HttpServletRequest private long _timeStamp; private long _dispatchTime; - private ByteBuffer _timeStampBuffer; private HttpURI _uri; - + private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime - - + + /* ------------------------------------------------------------ */ public Request(HttpChannel channel) { @@ -174,6 +173,12 @@ public class Request implements HttpServletRequest _async.setConnection(channel); } + /* ------------------------------------------------------------ */ + public HttpChannel getHttpChannel() + { + return _channel; + } + /* ------------------------------------------------------------ */ public void addEventListener(final EventListener listener) { @@ -283,10 +288,10 @@ public class Request implements HttpServletRequest else if (_parameters != _baseParameters) { // Merge parameters (needed if parameters extracted after a forward). - Iterator iter = _baseParameters.entrySet().iterator(); + Iterator iter = _baseParameters.entrySet().iterator(); while (iter.hasNext()) { - Map.Entry entry = (Map.Entry)iter.next(); + Map.Entry entry = (Map.Entry)iter.next(); String name = (String)entry.getKey(); Object values = entry.getValue(); for (int i = 0; i < LazyList.size(values); i++) @@ -303,6 +308,7 @@ public class Request implements HttpServletRequest } /* ------------------------------------------------------------ */ + @Override public AsyncContext getAsyncContext() { if (_async.isInitial() && !_async.isAsyncStarted()) @@ -315,11 +321,12 @@ public class Request implements HttpServletRequest { return _async; } - + /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletRequest#getAttribute(java.lang.String) */ + @Override public Object getAttribute(String name) { Object attr = (_attributes == null)?null:_attributes.getAttribute(name); @@ -332,6 +339,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getAttributeNames() */ + @Override public Enumeration getAttributeNames() { if (_attributes == null) @@ -365,11 +373,12 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getAuthType() */ + @Override public String getAuthType() { if (_authentication instanceof Authentication.Deferred) setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); - + if (_authentication instanceof Authentication.User) return ((Authentication.User)_authentication).getAuthMethod(); return null; @@ -379,6 +388,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getCharacterEncoding() */ + @Override public String getCharacterEncoding() { return _characterEncoding; @@ -397,6 +407,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getContentLength() */ + @Override public int getContentLength() { return (int)_fields.getLongField(HttpHeader.CONTENT_LENGTH.toString()); @@ -406,6 +417,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getContentType() */ + @Override public String getContentType() { return _fields.getStringField(HttpHeader.CONTENT_TYPE); @@ -424,6 +436,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getContextPath() */ + @Override public String getContextPath() { return _contextPath; @@ -433,6 +446,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getCookies() */ + @Override public Cookie[] getCookies() { if (_cookiesExtracted) @@ -440,7 +454,7 @@ public class Request implements HttpServletRequest _cookiesExtracted = true; - Enumeration enm = _fields.getValues(HttpHeader.COOKIE.toString()); + Enumeration enm = _fields.getValues(HttpHeader.COOKIE.toString()); // Handle no cookies if (enm != null) @@ -462,12 +476,14 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) */ + @Override public long getDateHeader(String name) { return _fields.getDateField(name); } /* ------------------------------------------------------------ */ + @Override public DispatcherType getDispatcherType() { return _dispatcherType; @@ -477,6 +493,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String) */ + @Override public String getHeader(String name) { return _fields.getStringField(name); @@ -486,6 +503,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getHeaderNames() */ + @Override public Enumeration getHeaderNames() { return _fields.getFieldNames(); @@ -495,9 +513,10 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String) */ + @Override public Enumeration getHeaders(String name) { - Enumeration e = _fields.getValues(name); + Enumeration e = _fields.getValues(name); if (e == null) return Collections.enumeration(Collections.EMPTY_LIST); return e; @@ -516,6 +535,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getInputStream() */ + @Override public ServletInputStream getInputStream() throws IOException { if (_inputState != __NONE && _inputState != _STREAM) @@ -528,6 +548,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) */ + @Override public int getIntHeader(String name) { return (int)_fields.getLongField(name); @@ -538,6 +559,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getLocale() */ + @Override public Locale getLocale() { Enumeration enm = _fields.getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators); @@ -547,7 +569,7 @@ public class Request implements HttpServletRequest return Locale.getDefault(); // sort the list in quality order - List acceptLanguage = HttpFields.qualityList(enm); + List acceptLanguage = HttpFields.qualityList(enm); if (acceptLanguage.size() == 0) return Locale.getDefault(); @@ -574,7 +596,8 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getLocales() */ - public Enumeration getLocales() + @Override + public Enumeration getLocales() { Enumeration enm = _fields.getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators); @@ -589,13 +612,13 @@ public class Request implements HttpServletRequest if (acceptLanguage.size() == 0) return Collections.enumeration(__defaultLocale); - Object langs = null; + List langs = new ArrayList(); int size = acceptLanguage.size(); // convert to locals for (int i = 0; i < size; i++) { - String language = (String)acceptLanguage.get(i); + String language = acceptLanguage.get(i); language = HttpFields.valueParameters(language,null); String country = ""; int dash = language.indexOf('-'); @@ -604,30 +627,31 @@ public class Request implements HttpServletRequest country = language.substring(dash + 1).trim(); language = language.substring(0,dash).trim(); } - langs = LazyList.ensureSize(langs,size); - langs = LazyList.add(langs,new Locale(language,country)); + langs.add(new Locale(language,country)); } if (LazyList.size(langs) == 0) return Collections.enumeration(__defaultLocale); - return Collections.enumeration(LazyList.getList(langs)); + return Collections.enumeration(langs); } /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletRequest#getLocalAddr() */ + @Override public String getLocalAddr() { InetSocketAddress local=_channel.getLocalAddress(); return local.getAddress().getHostAddress(); } - + /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletRequest#getLocalName() */ + @Override public String getLocalName() { InetSocketAddress local=_channel.getLocalAddress(); @@ -638,6 +662,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getLocalPort() */ + @Override public int getLocalPort() { InetSocketAddress local=_channel.getLocalAddress(); @@ -648,6 +673,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getMethod() */ + @Override public String getMethod() { return _method; @@ -657,6 +683,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getParameter(java.lang.String) */ + @Override public String getParameter(String name) { if (!_paramsExtracted) @@ -668,6 +695,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getParameterMap() */ + @Override public Map getParameterMap() { if (!_paramsExtracted) @@ -680,6 +708,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getParameterNames() */ + @Override public Enumeration getParameterNames() { if (!_paramsExtracted) @@ -700,6 +729,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) */ + @Override public String[] getParameterValues(String name) { if (!_paramsExtracted) @@ -714,6 +744,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getPathInfo() */ + @Override public String getPathInfo() { return _pathInfo; @@ -723,6 +754,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getPathTranslated() */ + @Override public String getPathTranslated() { if (_pathInfo == null || _context == null) @@ -734,6 +766,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getProtocol() */ + @Override public String getProtocol() { return _httpVersion.toString(); @@ -758,6 +791,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getQueryString() */ + @Override public String getQueryString() { if (_queryString == null && _uri != null) @@ -774,6 +808,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getReader() */ + @Override public BufferedReader getReader() throws IOException { if (_inputState != __NONE && _inputState != __READER) @@ -807,6 +842,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getRealPath(java.lang.String) */ + @Override public String getRealPath(String path) { if (_context == null) @@ -818,6 +854,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getRemoteAddr() */ + @Override public String getRemoteAddr() { InetSocketAddress remote=_remote; @@ -830,6 +867,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getRemoteHost() */ + @Override public String getRemoteHost() { InetSocketAddress remote=_remote; @@ -842,6 +880,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getRemotePort() */ + @Override public int getRemotePort() { InetSocketAddress remote=_remote; @@ -854,6 +893,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getRemoteUser() */ + @Override public String getRemoteUser() { Principal p = getUserPrincipal(); @@ -866,6 +906,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String) */ + @Override public RequestDispatcher getRequestDispatcher(String path) { if (path == null || _context == null) @@ -890,6 +931,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() */ + @Override public String getRequestedSessionId() { return _requestedSessionId; @@ -899,6 +941,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getRequestURI() */ + @Override public String getRequestURI() { if (_requestURI == null && _uri != null) @@ -910,6 +953,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getRequestURL() */ + @Override public StringBuffer getRequestURL() { final StringBuffer url = new StringBuffer(48); @@ -971,6 +1015,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getScheme() */ + @Override public String getScheme() { return _scheme; @@ -980,6 +1025,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getServerName() */ + @Override public String getServerName() { // Return already determined host @@ -1008,7 +1054,7 @@ public class Request implements HttpServletRequest break loop; case ':': - _serverName = hostPort.substring(0,i); + _serverName = hostPort.substring(0,i); try { _port = StringUtil.toInt(hostPort.substring(i+1)); @@ -1028,7 +1074,7 @@ public class Request implements HttpServletRequest return _serverName; } } - + if (_serverName == null || _port < 0) { _serverName = hostPort; @@ -1063,6 +1109,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#getServerPort() */ + @Override public int getServerPort() { if (_port <= 0) @@ -1092,6 +1139,7 @@ public class Request implements HttpServletRequest } /* ------------------------------------------------------------ */ + @Override public ServletContext getServletContext() { return _context; @@ -1111,6 +1159,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getServletPath() */ + @Override public String getServletPath() { if (_servletPath == null) @@ -1128,6 +1177,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getSession() */ + @Override public HttpSession getSession() { return getSession(true); @@ -1137,6 +1187,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getSession(boolean) */ + @Override public HttpSession getSession(boolean create) { if (_session != null) @@ -1223,6 +1274,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() */ + @Override public Principal getUserPrincipal() { if (_authentication instanceof Authentication.Deferred) @@ -1253,6 +1305,7 @@ public class Request implements HttpServletRequest return _handled; } + @Override public boolean isAsyncStarted() { return _async.isAsyncStarted(); @@ -1260,6 +1313,7 @@ public class Request implements HttpServletRequest /* ------------------------------------------------------------ */ + @Override public boolean isAsyncSupported() { return _asyncSupported; @@ -1269,6 +1323,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() */ + @Override public boolean isRequestedSessionIdFromCookie() { return _requestedSessionId != null && _requestedSessionIdFromCookie; @@ -1278,6 +1333,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() */ + @Override public boolean isRequestedSessionIdFromUrl() { return _requestedSessionId != null && !_requestedSessionIdFromCookie; @@ -1287,6 +1343,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() */ + @Override public boolean isRequestedSessionIdFromURL() { return _requestedSessionId != null && !_requestedSessionIdFromCookie; @@ -1296,6 +1353,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() */ + @Override public boolean isRequestedSessionIdValid() { if (_requestedSessionId == null) @@ -1309,6 +1367,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#isSecure() */ + @Override public boolean isSecure() { return _channel.getConnector().isConfidential(this); @@ -1318,6 +1377,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) */ + @Override public boolean isUserInRole(String role) { if (_authentication instanceof Authentication.Deferred) @@ -1383,7 +1443,6 @@ public class Request implements HttpServletRequest _scheme = URIUtil.HTTP; _servletPath = null; _timeStamp = 0; - _timeStampBuffer = null; _uri = null; if (_baseParameters != null) _baseParameters.clear(); @@ -1402,6 +1461,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String) */ + @Override public void removeAttribute(String name) { Object old_value = _attributes == null?null:_attributes.getAttribute(name); @@ -1457,6 +1517,7 @@ public class Request implements HttpServletRequest * * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) */ + @Override public void setAttribute(String name, Object value) { Object old_value = _attributes == null?null:_attributes.getAttribute(name); @@ -1483,7 +1544,7 @@ public class Request implements HttpServletRequest final ByteBuffer byteBuffer = (ByteBuffer)value; throw new IOException("not implemented"); //((HttpChannel.Output)getServletResponse().getOutputStream()).sendResponse(byteBuffer); - + } catch (IOException e) { @@ -1544,6 +1605,7 @@ public class Request implements HttpServletRequest /* * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) */ + @Override public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException { if (_inputState != __NONE) @@ -1645,7 +1707,7 @@ public class Request implements HttpServletRequest _httpMethod=httpMethod; _method = method; } - + /* ------------------------------------------------------------ */ public boolean isHead() { @@ -1844,6 +1906,7 @@ public class Request implements HttpServletRequest } /* ------------------------------------------------------------ */ + @Override public AsyncContext startAsync() throws IllegalStateException { if (!_asyncSupported) @@ -1853,6 +1916,7 @@ public class Request implements HttpServletRequest } /* ------------------------------------------------------------ */ + @Override public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { if (!_asyncSupported) @@ -1869,70 +1933,75 @@ public class Request implements HttpServletRequest } /* ------------------------------------------------------------ */ + @Override public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { if (_authentication instanceof Authentication.Deferred) { setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response)); - return !(_authentication instanceof Authentication.ResponseSent); + return !(_authentication instanceof Authentication.ResponseSent); } response.sendError(HttpStatus.UNAUTHORIZED_401); return false; } /* ------------------------------------------------------------ */ + @Override public Part getPart(String name) throws IOException, ServletException - { + { if (getContentType() == null || !getContentType().startsWith("multipart/form-data")) return null; - + if (_multiPartInputStream == null) - { - _multiPartInputStream = new MultiPartInputStream(getInputStream(), - getContentType(),(MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT), + { + _multiPartInputStream = new MultiPartInputStream(getInputStream(), + getContentType(),(MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT), (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); } return _multiPartInputStream.getPart(name); } /* ------------------------------------------------------------ */ + @Override public Collection getParts() throws IOException, ServletException { if (getContentType() == null || !getContentType().startsWith("multipart/form-data")) return Collections.emptyList(); - + if (_multiPartInputStream == null) { - _multiPartInputStream = new MultiPartInputStream(getInputStream(), - getContentType(),(MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT), + _multiPartInputStream = new MultiPartInputStream(getInputStream(), + getContentType(),(MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT), (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); } return _multiPartInputStream.getParts(); } /* ------------------------------------------------------------ */ + @Override public void login(String username, String password) throws ServletException { - if (_authentication instanceof Authentication.Deferred) + if (_authentication instanceof Authentication.Deferred) { _authentication=((Authentication.Deferred)_authentication).login(username,password); if (_authentication == null) throw new ServletException(); - } - else + } + else { throw new ServletException("Authenticated as "+_authentication); } } /* ------------------------------------------------------------ */ + @Override public void logout() throws ServletException { if (_authentication instanceof Authentication.User) ((Authentication.User)_authentication).logout(); _authentication=Authentication.UNAUTHENTICATED; } - + /* ------------------------------------------------------------ */ /** * Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and 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 68c678e6169..8070f9c0da3 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 @@ -4,11 +4,11 @@ // 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 +// 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. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.server; @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Locale; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletOutputStream; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; @@ -60,11 +61,11 @@ public class Response implements HttpServletResponse public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include."; /** - * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie + * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie * will be set as HTTP ONLY. */ public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__"; - + private final HttpChannel _channel; private final HttpFields _fields; private int _status=SC_OK; @@ -77,8 +78,8 @@ public class Response implements HttpServletResponse private PrintWriter _writer; private long _contentLength=-1; - - + + /* ------------------------------------------------------------ */ /** * @@ -115,16 +116,17 @@ public class Response implements HttpServletResponse { _fields.addSetCookie(cookie); } - + /* ------------------------------------------------------------ */ /* * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie) */ + @Override public void addCookie(Cookie cookie) { String comment=cookie.getComment(); boolean http_only=false; - + if (comment!=null) { int i=comment.indexOf(HTTP_ONLY_COMMENT); @@ -151,6 +153,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String) */ + @Override public boolean containsHeader(String name) { return _fields.containsKey(name); @@ -160,13 +163,14 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String) */ + @Override public String encodeURL(String url) { final Request request=_channel.getRequest(); SessionManager sessionManager = request.getSessionManager(); if (sessionManager==null) return url; - + HttpURI uri = null; if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url)) { @@ -174,21 +178,21 @@ public class Response implements HttpServletResponse String path = uri.getPath(); path = (path == null?"":path); int port=uri.getPort(); - if (port<0) + if (port<0) port = HttpScheme.HTTPS.toString().equalsIgnoreCase(uri.getScheme())?443:80; if (!request.getServerName().equalsIgnoreCase(uri.getHost()) || request.getServerPort()!=port || !path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts return url; } - + String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix(); if (sessionURLPrefix==null) return url; if (url==null) return null; - + // should not encode if cookies in evidence if (request.isRequestedSessionIdFromCookie()) { @@ -221,8 +225,8 @@ public class Response implements HttpServletResponse if (uri == null) uri = new HttpURI(url); - - + + // Already encoded int prefix=url.indexOf(sessionURLPrefix); if (prefix!=-1) @@ -241,14 +245,14 @@ public class Response implements HttpServletResponse int suffix=url.indexOf('?'); if (suffix<0) suffix=url.indexOf('#'); - if (suffix<0) - { - return url+ + if (suffix<0) + { + return url+ ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path sessionURLPrefix+id; } - - + + return url.substring(0,suffix)+ ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path sessionURLPrefix+id+url.substring(suffix); @@ -258,12 +262,14 @@ public class Response implements HttpServletResponse /** * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String) */ + @Override public String encodeRedirectURL(String url) { return encodeURL(url); } /* ------------------------------------------------------------ */ + @Override @Deprecated public String encodeUrl(String url) { @@ -271,6 +277,7 @@ public class Response implements HttpServletResponse } /* ------------------------------------------------------------ */ + @Override @Deprecated public String encodeRedirectUrl(String url) { @@ -281,6 +288,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String) */ + @Override public void sendError(int code, String message) throws IOException { if (_channel.isIncluding()) @@ -319,10 +327,10 @@ public class Response implements HttpServletResponse error_handler = _channel.getServer().getBean(ErrorHandler.class); if (error_handler!=null) { - request.setAttribute(Dispatcher.ERROR_STATUS_CODE,new Integer(code)); - request.setAttribute(Dispatcher.ERROR_MESSAGE, message); - request.setAttribute(Dispatcher.ERROR_REQUEST_URI, request.getRequestURI()); - request.setAttribute(Dispatcher.ERROR_SERVLET_NAME,request.getServletName()); + request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(code)); + request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); + request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); + request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME,request.getServletName()); error_handler.handle(null,_channel.getRequest(),_channel.getRequest(),this ); } else @@ -385,6 +393,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#sendError(int) */ + @Override public void sendError(int sc) throws IOException { if (sc==102) @@ -411,6 +420,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String) */ + @Override public void sendRedirect(String location) throws IOException { if (_channel.isIncluding()) @@ -459,7 +469,7 @@ public class Response implements HttpServletResponse location=buf.toString(); } } - + resetBuffer(); setHeader(HttpHeader.LOCATION,location); setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); @@ -471,6 +481,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long) */ + @Override public void setDateHeader(String name, long date) { if (!_channel.isIncluding()) @@ -481,6 +492,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long) */ + @Override public void addDateHeader(String name, long date) { if (!_channel.isIncluding()) @@ -499,9 +511,9 @@ public class Response implements HttpServletResponse { if (_channel.isIncluding()) return; - + _fields.put(name, value); - + if (HttpHeader.CONTENT_LENGTH==name) { if (value==null) @@ -515,6 +527,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String) */ + @Override public void setHeader(String name, String value) { if (HttpHeader.CONTENT_TYPE.is(name)) @@ -541,15 +554,17 @@ public class Response implements HttpServletResponse /* ------------------------------------------------------------ */ + @Override public Collection getHeaderNames() { final HttpFields fields=_fields; return fields.getFieldNamesCollection(); } - + /* ------------------------------------------------------------ */ /* */ + @Override public String getHeader(String name) { return _fields.getStringField(name); @@ -558,12 +573,13 @@ public class Response implements HttpServletResponse /* ------------------------------------------------------------ */ /* */ + @Override public Collection getHeaders(String name) { final HttpFields fields=_fields; Collection i = fields.getValuesCollection(name); if (i==null) - return Collections.EMPTY_LIST; + return Collections.emptyList(); return i; } @@ -571,6 +587,26 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String) */ + public void addHeader(HttpHeader name, String value) + { + if (_channel.isIncluding()) + return; + + _fields.add(name, value); + if (HttpHeader.CONTENT_LENGTH==name) + { + if (value==null) + _contentLength=-1l; + else + _contentLength=Long.parseLong(value); + } + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String) + */ + @Override public void addHeader(String name, String value) { if (_channel.isIncluding()) @@ -595,6 +631,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int) */ + @Override public void setIntHeader(String name, int value) { if (!_channel.isIncluding()) @@ -609,6 +646,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int) */ + @Override public void addIntHeader(String name, int value) { if (!_channel.isIncluding()) @@ -623,6 +661,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#setStatus(int) */ + @Override public void setStatus(int sc) { setStatus(sc,null); @@ -632,6 +671,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.http.HttpServletResponse#setStatus(int, java.lang.String) */ + @Override public void setStatus(int sc, String sm) { if (sc<=0) @@ -647,13 +687,14 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#getCharacterEncoding() */ + @Override public String getCharacterEncoding() { if (_characterEncoding==null) _characterEncoding=StringUtil.__ISO_8859_1; return _characterEncoding; } - + /* ------------------------------------------------------------ */ String getSetCharacterEncoding() { @@ -664,6 +705,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#getContentType() */ + @Override public String getContentType() { return _contentType; @@ -673,6 +715,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#getOutputStream() */ + @Override public ServletOutputStream getOutputStream() throws IOException { if (_outputState==Output.WRITER) @@ -699,6 +742,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#getWriter() */ + @Override public PrintWriter getWriter() throws IOException { if (_outputState==Output.STREAM) @@ -730,6 +774,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#setContentLength(int) */ + @Override public void setContentLength(int len) { // Protect from setting after committed as default handling @@ -738,12 +783,12 @@ public class Response implements HttpServletResponse if (isCommitted() || _channel.isIncluding()) return; _contentLength=len; - _fields.putLongField(HttpHeader.CONTENT_LENGTH.toString(), (long)len); - + _fields.putLongField(HttpHeader.CONTENT_LENGTH.toString(), len); + if (_contentLength>0) checkAllContentWritten(_channel.getOutputStream().getWritten()); } - + /* ------------------------------------------------------------ */ public void checkAllContentWritten(long written) { @@ -792,6 +837,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String) */ + @Override public void setCharacterEncoding(String encoding) { if (_channel.isIncluding()) @@ -824,11 +870,12 @@ public class Response implements HttpServletResponse } } } - + /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletResponse#setContentType(java.lang.String) */ + @Override public void setContentType(String contentType) { if (isCommitted() || _channel.isIncluding()) @@ -847,7 +894,7 @@ public class Response implements HttpServletResponse _contentType=contentType; _mimeType=MimeTypes.CACHE.get(contentType); String charset=_mimeType==null?MimeTypes.getCharsetFromContentType(contentType):_mimeType.getCharset().toString(); - + if (charset!=null) _characterEncoding=charset; else if (_characterEncoding!=null) @@ -855,7 +902,7 @@ public class Response implements HttpServletResponse _contentType=contentType+";charset="+_characterEncoding; _mimeType=null; } - + _fields.put(HttpHeader.CONTENT_TYPE,_contentType); } } @@ -864,6 +911,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#setBufferSize(int) */ + @Override public void setBufferSize(int size) { if (isCommitted()) @@ -875,6 +923,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#getBufferSize() */ + @Override public int getBufferSize() { return _channel.getContentBufferSize(); @@ -884,6 +933,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#flushBuffer() */ + @Override public void flushBuffer() throws IOException { _channel.flushResponse(); @@ -893,6 +943,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#reset() */ + @Override public void reset() { resetBuffer(); @@ -900,9 +951,9 @@ public class Response implements HttpServletResponse _status=200; _reason=null; _contentLength=-1; - + HttpFields response_fields=_fields; - + response_fields.clear(); String connection=_channel.getRequestFields().getStringField(HttpHeader.CONNECTION); if (connection!=null) @@ -932,7 +983,7 @@ public class Response implements HttpServletResponse } } } - + /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletResponse#reset() @@ -949,18 +1000,19 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#resetBuffer() */ + @Override public void resetBuffer() { if (isCommitted()) throw new IllegalStateException("Committed"); - + switch(_outputState) { case STREAM: case WRITER: _channel.getOutputStream().reset(); } - + _channel.resetBuffer(); } @@ -968,6 +1020,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#isCommitted() */ + @Override public boolean isCommitted() { return _channel.isResponseCommitted(); @@ -977,6 +1030,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#setLocale(java.util.Locale) */ + @Override public void setLocale(Locale locale) { if (locale == null || isCommitted() ||_channel.isIncluding()) @@ -1001,6 +1055,7 @@ public class Response implements HttpServletResponse /* * @see javax.servlet.ServletResponse#getLocale() */ + @Override public Locale getLocale() { if (_locale==null) @@ -1013,6 +1068,7 @@ public class Response implements HttpServletResponse * @return The HTTP status code that has been set for this request. This will be 200 * ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the setStatus methods. */ + @Override public int getStatus() { return _status; @@ -1050,7 +1106,7 @@ public class Response implements HttpServletResponse return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+ _fields.toString(); } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java index c9c25ab7561..668c0c54990 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java @@ -482,8 +482,8 @@ public class ConnectHandler extends HandlerWrapper public String toString() { StringBuilder builder = new StringBuilder("ProxyToServer"); - builder.append("(:").append(_endPoint.getLocalPort()); - builder.append("<=>:").append(_endPoint.getRemotePort()); + builder.append("(:").write(_endPoint.getLocalPort()); + builder.append("<=>:").write(_endPoint.getRemotePort()); return builder.append(")").toString(); } @@ -699,8 +699,8 @@ public class ConnectHandler extends HandlerWrapper public String toString() { StringBuilder builder = new StringBuilder("ClientToProxy"); - builder.append("(:").append(_endPoint.getLocalPort()); - builder.append("<=>:").append(_endPoint.getRemotePort()); + builder.append("(:").write(_endPoint.getLocalPort()); + builder.append("<=>:").write(_endPoint.getRemotePort()); return builder.append(")").toString(); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 155ff7e53d6..31e8c94a9d0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -60,6 +60,7 @@ import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HandlerContainer; +import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.Attributes; @@ -877,7 +878,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server. // Check the connector if (_connectors != null && _connectors.size() > 0) { - String connector = AbstractHttpConnection.getCurrentHttpChannel().getConnector().getName(); + String connector = HttpChannel.getCurrentHttpChannel().getConnector().getName(); if (connector == null || !_connectors.contains(connector)) return false; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java index 9af6f1a81e0..e2971321e04 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java @@ -76,6 +76,7 @@ public class DefaultHandler extends AbstractHandler /* * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) */ + @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (response.isCommitted() || baseRequest.isHandled()) @@ -88,15 +89,15 @@ public class DefaultHandler extends AbstractHandler // little cheat for common request if (_serveIcon && _favicon!=null && method.equals(HttpMethod.GET) && request.getRequestURI().equals("/favicon.ico")) { - if (request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE)==_faviconModified) + if (request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.toString())==_faviconModified) response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); else { response.setStatus(HttpServletResponse.SC_OK); response.setContentType("image/x-icon"); response.setContentLength(_favicon.length); - response.setDateHeader(HttpHeader.LAST_MODIFIED, _faviconModified); - response.setHeader(HttpHeader.CACHE_CONTROL,"max-age=360000,public"); + response.setDateHeader(HttpHeader.LAST_MODIFIED.toString(), _faviconModified); + response.setHeader(HttpHeader.CACHE_CONTROL.toString(),"max-age=360000,public"); response.getOutputStream().write(_favicon); } return; @@ -110,7 +111,7 @@ public class DefaultHandler extends AbstractHandler } response.setStatus(HttpServletResponse.SC_NOT_FOUND); - response.setContentType(MimeTypes.TEXT_HTML); + response.setContentType(MimeTypes.Type.TEXT_HTML.toString()); ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java index 8129a9ddda2..73acefe707f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java @@ -55,7 +55,7 @@ public class NetworkTrafficSelectChannelConnector extends SelectChannelConnector protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key) throws IOException { NetworkTrafficSelectChannelEndPoint endPoint = new NetworkTrafficSelectChannelEndPoint(channel, selectSet, key, _maxIdleTime, listeners); - endPoint.setConnection(selectSet.getManager().newConnection(channel,endPoint, key.attachment())); + endPoint.setSelectableConnection(selectSet.getManager().newConnection(channel,endPoint, key.attachment())); endPoint.notifyOpened(); return endPoint; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java index 2dda923bae4..05850212263 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java @@ -24,9 +24,11 @@ import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.SelectChannelEndPoint; +import org.eclipse.jetty.io.SelectableConnection; import org.eclipse.jetty.io.SelectableEndPoint; import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SelectorManager.SelectSet; +import org.eclipse.jetty.server.HttpConnection; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.thread.ThreadPool; @@ -115,19 +117,10 @@ public class SelectChannelConnector extends AbstractNIOConnector /* ------------------------------------------------------------------------------- */ @Override - public void customize(EndPoint endpoint, Request request) throws IOException + public void customize(Request request) throws IOException { request.setTimeStamp(System.currentTimeMillis()); - endpoint.setMaxIdleTime(_maxIdleTime); - super.customize(endpoint, request); - } - - /* ------------------------------------------------------------------------------- */ - @Override - public void persist(EndPoint endpoint) throws IOException - { - endpoint.setCheckForIdle(true); - super.persist(endpoint); + super.customize(request); } /* ------------------------------------------------------------ */ @@ -251,20 +244,20 @@ public class SelectChannelConnector extends AbstractNIOConnector protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException { SelectChannelEndPoint endp= new SelectChannelEndPoint(channel,selectSet,key, SelectChannelConnector.this._maxIdleTime); - endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment())); + endp.setSelectableConnection(selectSet.getManager().newConnection(channel,endp, key.attachment())); return endp; } /* ------------------------------------------------------------------------------- */ protected void endPointClosed(SelectableEndPoint endpoint) { - connectionClosed(endpoint.getConnection()); + connectionClosed(endpoint.getSelectableConnection()); } /* ------------------------------------------------------------------------------- */ - protected Connection newConnection(SocketChannel channel,final EndPoint endpoint) + protected SelectableConnection newConnection(SocketChannel channel,final SelectableEndPoint endpoint) { - return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer()); + return new HttpConnection(SelectChannelConnector.this,endpoint,getServer()); } @@ -283,7 +276,7 @@ public class SelectChannelConnector extends AbstractNIOConnector } @Override - protected void endPointClosed(final SelectableEndPoint endpoint) + protected void endPointClosed(SelectChannelEndPoint endpoint) { SelectChannelConnector.this.endPointClosed(endpoint); } @@ -292,25 +285,27 @@ public class SelectChannelConnector extends AbstractNIOConnector protected void endPointOpened(SelectChannelEndPoint endpoint) { // TODO handle max connections and low resources - connectionOpened(endpoint.getConnection()); + connectionOpened(endpoint.getSelectableConnection()); } @Override - protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection) - { - connectionUpgraded(oldConnection,endpoint.getConnection()); + protected void endPointUpgraded(SelectChannelEndPoint endpoint, Connection oldConnection) + { + connectionUpgraded(oldConnection,endpoint.getSelectableConnection()); } @Override - public Connection newConnection(SocketChannel channel,AsyncEndPoint endpoint, Object attachment) - { + public SelectableConnection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint, Object attachment) + { return SelectChannelConnector.this.newConnection(channel,endpoint); } @Override protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey sKey) throws IOException - { + { return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey); } + + } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java index f0a6911f3da..fd6c363bdc2 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayQueue.java @@ -135,6 +135,7 @@ public class ArrayQueue extends AbstractList implements Queue } } + /* ------------------------------------------------------------ */ @SuppressWarnings("unchecked") private E at(int index) {