Author: markt
Date: Mon Mar 27 10:59:54 2017
New Revision: 1788890
URL: http://svn.apache.org/viewvc?rev=1788890&view=rev
Log:
Improve sendfile handling when requests are pipelined.
Added:
tomcat/trunk/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
(with props)
Modified:
tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/SendfileDataBase.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Mon Mar 27
10:59:54 2017
@@ -868,10 +868,9 @@ public abstract class AbstractProtocol<S
wrapper.registerReadInterest();
} else if (state == SocketState.SENDFILE) {
// Sendfile in progress. If it fails, the socket will be
- // closed. If it works, the socket will be re-added to the
- // poller
- connections.remove(socket);
- release(processor);
+ // closed. If it works, the socket either be added to the
+ // poller (or equivalent) to await more data or processed
+ // if there are any pipe-lined requests remaining.
} else if (state == SocketState.UPGRADED) {
// Don't add sockets back to the poller if this was a
// non-blocking write otherwise the poller may trigger
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Mar 27
10:59:54 2017
@@ -55,6 +55,7 @@ import org.apache.tomcat.util.log.UserDa
import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.net.SendfileDataBase;
+import org.apache.tomcat.util.net.SendfileKeepAliveState;
import org.apache.tomcat.util.net.SendfileState;
import org.apache.tomcat.util.net.SocketWrapperBase;
import org.apache.tomcat.util.res.StringManager;
@@ -1312,7 +1313,15 @@ public class Http11Processor extends Abs
SendfileState result = SendfileState.DONE;
// Do sendfile as needed: add socket to sendfile and end
if (sendfileData != null && !getErrorState().isError()) {
- sendfileData.keepAlive = keepAlive;
+ if (keepAlive) {
+ if (available(false) == 0) {
+ sendfileData.keepAliveState = SendfileKeepAliveState.OPEN;
+ } else {
+ sendfileData.keepAliveState =
SendfileKeepAliveState.PIPELINED;
+ }
+ } else {
+ sendfileData.keepAliveState = SendfileKeepAliveState.NONE;
+ }
result = socketWrapper.processSendfile(sendfileData);
switch (result) {
case ERROR:
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Mon Mar 27
10:59:54 2017
@@ -2064,20 +2064,33 @@ public class AprEndpoint extends Abstrac
state.length -= nw;
if (state.length == 0) {
remove(state);
- if (state.keepAlive) {
+ switch (state.keepAliveState) {
+ case NONE: {
+ // Close the socket since this is
+ // the end of the not keep-alive request.
+ closeSocket(state.socket);
+ break;
+ }
+ case PIPELINED: {
// Destroy file descriptor pool, which
should close the file
Pool.destroy(state.fdpool);
- Socket.timeoutSet(state.socket,
- getConnectionTimeout() * 1000);
- // If all done put the socket back in the
- // poller for processing of further
requests
- getPoller().add(
- state.socket,
getKeepAliveTimeout(),
+ Socket.timeoutSet(state.socket,
getConnectionTimeout() * 1000);
+ // Process the pipelined request data
+ if (!processSocket(state.socket,
SocketEvent.OPEN_READ)) {
+ closeSocket(state.socket);
+ }
+ break;
+ }
+ case OPEN: {
+ // Destroy file descriptor pool, which
should close the file
+ Pool.destroy(state.fdpool);
+ Socket.timeoutSet(state.socket,
getConnectionTimeout() * 1000);
+ // Put the socket back in the poller for
+ // processing of further requests
+ getPoller().add(state.socket,
getKeepAliveTimeout(),
Poll.APR_POLLIN);
- } else {
- // Close the socket since this is
- // the end of not keep-alive request.
- closeSocket(state.socket);
+ break;
+ }
}
}
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Mon Mar 27
10:59:54 2017
@@ -447,17 +447,24 @@ public class Nio2Endpoint extends Abstra
} catch (IOException e) {
// Ignore
}
- if (attachment.keepAlive) {
- if (!isInline()) {
+ if (isInline()) {
+ attachment.doneInline = true;
+ } else {
+ switch (attachment.keepAliveState) {
+ case NONE: {
+
getEndpoint().processSocket(Nio2SocketWrapper.this,
+ SocketEvent.DISCONNECT, false);
+ break;
+ }
+ case PIPELINED: {
+
getEndpoint().processSocket(Nio2SocketWrapper.this,
+ SocketEvent.OPEN_READ, true);
+ break;
+ }
+ case OPEN: {
awaitBytes();
- } else {
- attachment.doneInline = true;
+ break;
}
- } else {
- if (!isInline()) {
-
getEndpoint().processSocket(Nio2SocketWrapper.this, SocketEvent.DISCONNECT,
false);
- } else {
- attachment.doneInline = true;
}
}
return;
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Mon Mar 27
10:59:54 2017
@@ -837,16 +837,30 @@ public class NioEndpoint extends Abstrac
// responsible for registering the socket for the
// appropriate event(s) if sendfile completes.
if (!calledByProcessor) {
- if (sd.keepAlive) {
- if (log.isDebugEnabled()) {
- log.debug("Connection is keep alive,
registering back for OP_READ");
- }
- reg(sk,socketWrapper,SelectionKey.OP_READ);
- } else {
+ switch (sd.keepAliveState) {
+ case NONE: {
if (log.isDebugEnabled()) {
log.debug("Send file connection is being
closed");
}
close(sc, sk);
+ break;
+ }
+ case PIPELINED: {
+ if (log.isDebugEnabled()) {
+ log.debug("Connection is keep alive,
processing pipe-lined data");
+ }
+ if (!processSocket(socketWrapper,
SocketEvent.OPEN_READ, true)) {
+ close(sc, sk);
+ }
+ break;
+ }
+ case OPEN: {
+ if (log.isDebugEnabled()) {
+ log.debug("Connection is keep alive,
registering back for OP_READ");
+ }
+ reg(sk,socketWrapper,SelectionKey.OP_READ);
+ break;
+ }
}
}
return SendfileState.DONE;
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SendfileDataBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SendfileDataBase.java?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SendfileDataBase.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SendfileDataBase.java Mon Mar
27 10:59:54 2017
@@ -21,10 +21,10 @@ public abstract class SendfileDataBase {
/**
* Is the current request being processed on a keep-alive connection? This
* determines if the socket is closed once the send file completes or if
- * processing continues with the next request on the connection (or waiting
- * for that next request to arrive).
+ * processing continues with the next request on the connection or waiting
+ * for that next request to arrive.
*/
- public boolean keepAlive;
+ public SendfileKeepAliveState keepAliveState = SendfileKeepAliveState.NONE;
/**
* The full path to the file that contains the data to be written to the
Added: tomcat/trunk/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java?rev=1788890&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
(added)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
Mon Mar 27 10:59:54 2017
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+public enum SendfileKeepAliveState {
+
+ /**
+ * Keep-alive is not in use. The socket can be closed when the response has
+ * been written.
+ */
+ NONE,
+
+ /**
+ * Keep-alive is in use and there is pipelined data in the input buffer to
+ * be read as soon as the current response has been written.
+ */
+ PIPELINED,
+
+ /**
+ * Keep-alive is in use. The socket should be added to the poller (or
+ * equivalent) to await more data as soon as the current response has been
+ * written.
+ */
+ OPEN
+}
Propchange:
tomcat/trunk/java/org/apache/tomcat/util/net/SendfileKeepAliveState.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1788890&r1=1788889&r2=1788890&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Mar 27 10:59:54 2017
@@ -145,6 +145,9 @@
subsequent requests experiencing an <code>IllegalStateException</code>.
(markt)
</fix>
+ <fix>
+ Improve sendfile handling when requests are pipelined. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]