diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java index f1748337b72..54819e430ed 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpTransportOverFCGI.java @@ -49,6 +49,36 @@ public class HttpTransportOverFCGI implements HttpTransport @Override public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) + { + if (info!=null) + commit(info,content,lastContent,callback); + else + { + if (head) + { + if (lastContent) + { + Generator.Result result = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback); + flusher.flush(result); + } + else + { + // Skip content generation + callback.succeeded(); + } + } + else + { + Generator.Result result = generateResponseContent(content, lastContent, callback); + flusher.flush(result); + } + + if (lastContent && shutdown) + flusher.shutdown(); + } + } + + private void commit(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback) { boolean head = this.head = info.isHead(); boolean shutdown = this.shutdown = info.getHttpFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); @@ -78,32 +108,6 @@ public class HttpTransportOverFCGI implements HttpTransport flusher.shutdown(); } - @Override - public void send(ByteBuffer content, boolean lastContent, Callback callback) - { - if (head) - { - if (lastContent) - { - Generator.Result result = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback); - flusher.flush(result); - } - else - { - // Skip content generation - callback.succeeded(); - } - } - else - { - Generator.Result result = generateResponseContent(content, lastContent, callback); - flusher.flush(result); - } - - if (lastContent && shutdown) - flusher.shutdown(); - } - protected Generator.Result generateResponseHeaders(HttpGenerator.ResponseInfo info, Callback callback) { return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getHttpFields(), callback); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java index 7db1fa64ff0..881acbd679b 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java @@ -29,10 +29,12 @@ package org.eclipse.jetty.http; *
302 Moved Temporarily
")100 Continue
*/
@@ -696,7 +709,7 @@ public class HttpStatus
/*
* --------------------------------------------------------------------
* Success messages in 2xx series. As defined by ... RFC 1945 - HTTP/1.0
- * RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+ * RFC 7231 - HTTP/1.1 RFC 2518 - WebDAV
*/
/** 200 OK
*/
@@ -719,7 +732,7 @@ public class HttpStatus
/*
* --------------------------------------------------------------------
* Redirection messages in 3xx series. As defined by ... RFC 1945 -
- * HTTP/1.0 RFC 2616 - HTTP/1.1
+ * HTTP/1.0 RFC 7231 - HTTP/1.1
*/
/** 300 Mutliple Choices
*/
@@ -738,11 +751,13 @@ public class HttpStatus
USE_PROXY(USE_PROXY_305, "Use Proxy"),
/** 307 Temporary Redirect
*/
TEMPORARY_REDIRECT(TEMPORARY_REDIRECT_307, "Temporary Redirect"),
+ /** 308 Permanent Redirect
*/
+ PERMANET_REDIRECT(PERMANENT_REDIRECT_308, "Permanent Redirect"),
/*
* --------------------------------------------------------------------
* Client Error messages in 4xx series. As defined by ... RFC 1945 -
- * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+ * HTTP/1.0 RFC 7231 - HTTP/1.1 RFC 2518 - WebDAV
*/
/** 400 Bad Request
*/
@@ -791,7 +806,7 @@ public class HttpStatus
/*
* --------------------------------------------------------------------
* Server Error messages in 5xx series. As defined by ... RFC 1945 -
- * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+ * HTTP/1.0 RFC 7231 - HTTP/1.1 RFC 2518 - WebDAV
*/
/** 500 Server Error
*/
@@ -844,7 +859,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Informational
message category as defined in the RFC 1945 - HTTP/1.0,
- * and RFC 2616 -
+ * and RFC 7231 -
* HTTP/1.1.
*
* @return true if within range of codes that belongs to
@@ -859,7 +874,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Success
message category as defined in the RFC 1945 - HTTP/1.0,
- * and RFC 2616 -
+ * and RFC 7231 -
* HTTP/1.1.
*
* @return true if within range of codes that belongs to
@@ -874,7 +889,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Redirection
message category as defined in the RFC 1945 - HTTP/1.0,
- * and RFC 2616 -
+ * and RFC 7231 -
* HTTP/1.1.
*
* @return true if within range of codes that belongs to
@@ -889,7 +904,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Client Error
message category as defined in the RFC 1945 - HTTP/1.0,
- * and RFC 2616 -
+ * and RFC 7231 -
* HTTP/1.1.
*
* @return true if within range of codes that belongs to
@@ -904,7 +919,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Server Error
message category as defined in the RFC 1945 - HTTP/1.0,
- * and RFC 2616 -
+ * and RFC 7231 -
* HTTP/1.1.
*
* @return true if within range of codes that belongs to
@@ -958,7 +973,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Informational
message category as defined in the RFC 1945 - HTTP/1.0, and RFC 2616 - HTTP/1.1.
+ * href="http://tools.ietf.org/html/rfc7231">RFC 7231 - HTTP/1.1.
*
* @param code
* the code to test.
@@ -974,7 +989,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Success
message category as defined in the RFC 1945 - HTTP/1.0, and RFC 2616 - HTTP/1.1.
+ * href="http://tools.ietf.org/html/rfc7231">RFC 7231 - HTTP/1.1.
*
* @param code
* the code to test.
@@ -990,7 +1005,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Redirection
message category as defined in the RFC 1945 - HTTP/1.0, and RFC 2616 - HTTP/1.1.
+ * href="http://tools.ietf.org/html/rfc7231">RFC 7231 - HTTP/1.1.
*
* @param code
* the code to test.
@@ -1006,7 +1021,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Client Error
message category as defined in the RFC 1945 - HTTP/1.0, and RFC 2616 - HTTP/1.1.
+ * href="http://tools.ietf.org/html/rfc7231">RFC 7231 - HTTP/1.1.
*
* @param code
* the code to test.
@@ -1022,7 +1037,7 @@ public class HttpStatus
* Simple test against an code to determine if it falls into the
* Server Error
message category as defined in the RFC 1945 - HTTP/1.0, and RFC 2616 - HTTP/1.1.
+ * href="http://tools.ietf.org/html/rfc7231">RFC 7231 - HTTP/1.1.
*
* @param code
* the code to test.
diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java
index 29abe5fe40a..22a44885926 100644
--- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java
+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java
@@ -95,6 +95,8 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF
HttpTransportOverHTTP2 transport = new HttpTransportOverHTTP2((IStream)stream, frame);
HttpInputOverHTTP2 input = new HttpInputOverHTTP2();
+
+ // TODO pool HttpChannels per connection - maybe associate with thread?
HttpChannelOverHTTP2 channel = new HttpChannelOverHTTP2(connector, httpConfiguration, endPoint, transport, input, stream);
stream.setAttribute(CHANNEL_ATTRIBUTE, channel);
diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java
index 900736f7f38..2e0f6122c01 100644
--- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java
+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java
@@ -45,7 +45,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel
private static final HttpField ACCEPT_ENCODING_GZIP = new HttpField(HttpHeader.ACCEPT_ENCODING,"gzip");
private static final HttpField SERVER_VERSION=new HttpField(HttpHeader.SERVER,HttpConfiguration.SERVER_VERSION);
private static final HttpField POWERED_BY=new HttpField(HttpHeader.X_POWERED_BY,HttpConfiguration.SERVER_VERSION);
- private final Stream stream;
+ private final Stream stream; // TODO recycle channel for new Stream?
public HttpChannelOverHTTP2(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input, Stream stream)
{
diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java
index e9e8ad69b1e..55b9daa67e8 100644
--- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java
+++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java
@@ -85,9 +85,8 @@ public class HttpTransportOverHTTP2 implements HttpTransport
HeadersFrame frame = new HeadersFrame(stream.getId(), metaData, null, endStream);
stream.headers(frame, callback);
}
-
- @Override
- public void send(ByteBuffer content, boolean lastContent, Callback callback)
+
+ private void send(ByteBuffer content, boolean lastContent, Callback callback)
{
if (LOG.isDebugEnabled())
{
@@ -98,6 +97,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport
stream.data(frame, callback);
}
+
@Override
public void completed()
{
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 a07d1032f3f..94e89d42c7c 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
@@ -534,7 +534,7 @@ public class HttpChannel implements Runnable
else if (info==null)
{
// This is a normal write
- _transport.send(content, complete, callback);
+ _transport.send(null,content, complete, callback);
}
else
{
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 d020d582484..535ce6324a0 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
@@ -443,13 +443,6 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
_sendCallback.iterate();
}
- @Override
- public void send(ByteBuffer content, boolean lastContent, Callback callback)
- {
- _sendCallback.reset(null,content,lastContent,callback);
- _sendCallback.iterate();
- }
-
private class SendCallback extends IteratingCallback
{
private ResponseInfo _info;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
index 7058425f659..d04a43e9bc3 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
@@ -26,8 +26,6 @@ import org.eclipse.jetty.util.Callback;
public interface HttpTransport
{
void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback);
-
- void send(ByteBuffer content, boolean lastContent, Callback callback);
void completed();
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 43bc0f2dc1e..4b1c23d4929 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
@@ -149,7 +149,7 @@ public class Request implements HttpServletRequest
private boolean _handled = false;
private boolean _paramsExtracted;
private boolean _requestedSessionIdFromCookie = false;
- private volatile Attributes _attributes;
+ private Attributes _attributes;
private Authentication _authentication;
private String _characterEncoding;
private ContextHandler.Context _context;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index 15164a50c25..e68b6a0a4cc 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -90,12 +90,6 @@ public class ResponseTest
{
callback.succeeded();
}
-
- @Override
- public void send(ByteBuffer responseBodyContent, boolean lastContent, Callback callback)
- {
- send(null,responseBodyContent, lastContent, callback);
- }
@Override
public void completed()
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java
index 520ad181cdd..88b690c0484 100644
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java
+++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java
@@ -89,14 +89,6 @@ public class HttpTransportOverSPDY implements HttpTransport
return requestHeaders;
}
-
- @Override
- public void send(ByteBuffer responseBodyContent, boolean lastContent, Callback callback)
- {
- // TODO can this be more efficient?
- send(null, responseBodyContent, lastContent, callback);
- }
-
@Override
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, final Callback callback)
{
@@ -165,7 +157,6 @@ public class HttpTransportOverSPDY implements HttpTransport
}
else if (!lastContent && !hasContent && info == null)
throw new IllegalStateException("not lastContent, no content and no responseInfo!");
-
}
private void sendReply(HttpGenerator.ResponseInfo info, Callback callback, boolean close)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java
new file mode 100644
index 00000000000..1159b93237b
--- /dev/null
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java
@@ -0,0 +1,173 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+
+package org.eclipse.jetty.util.thread;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+
+/* ------------------------------------------------------------ */
+/** Strategies to execute Producers
+ */
+public abstract class ExecutionStrategy implements Runnable
+{
+ public interface Producer
+ {
+ /**
+ * Produce a task to run
+ * @return A task to run or null if we are complete.
+ */
+ Runnable produce();
+
+ /**
+ * Check if there is more to produce. This method may not return valid
+ * results until {@link #produce()} has been called.
+ * @return true if this Producer may produce more tasks from {@link #produce()}
+ */
+ boolean isMoreToProduce();
+
+ /**
+ * Called to signal production is completed
+ */
+ void onCompleted();
+ }
+
+ protected final Producer _producer;
+ protected final Executor _executor;
+
+ protected ExecutionStrategy(Producer producer, Executor executor)
+ {
+ _producer=producer;
+ _executor=executor;
+ }
+
+ /* ------------------------------------------------------------ */
+ /** Simple iterative strategy.
+ * Iterate over production until complete and execute each task.
+ */
+ public static class Iterative extends ExecutionStrategy
+ {
+ public Iterative(Producer producer, Executor executor)
+ {
+ super(producer,executor);
+ }
+
+ public void run()
+ {
+ try
+ {
+ // Iterate until we are complete
+ loop: while (true)
+ {
+ // produce a task
+ Runnable task=_producer.produce();
+
+ // if there is no task, break the loop
+ if (task==null)
+ break loop;
+
+ // If we are still producing,
+ if (_producer.isMoreToProduce())
+ // execute the task
+ _executor.execute(task);
+ else
+ {
+ // last task so we can run ourselves
+ task.run();
+ break loop;
+ }
+ }
+ }
+ finally
+ {
+ _producer.onCompleted();
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * A Strategy that allows threads to run the tasks that they have produced,
+ * so execution is done with a hot cache (ie threads eat what they kill).
+ */
+ public static class EatWhatYouKill extends ExecutionStrategy
+ {
+ private final AtomicInteger _threads = new AtomicInteger(0);
+ private final AtomicReference