svn commit: r1487618 - /tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
Author: markt Date: Wed May 29 19:54:47 2013 New Revision: 1487618 URL: http://svn.apache.org/r1487618 Log: More test code - sorry for the noise Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java?rev=1487618&r1=1487617&r2=1487618&view=diff == --- tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Wed May 29 19:54:47 2013 @@ -202,7 +202,6 @@ public class InternalNioOutputBuffer ext if (length == 0) return; -System.out.println("addToBB"); // Try to flush any data in the socket's write buffer first boolean dataLeft = flushBuffer(isBlocking()); - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
svn commit: r1487604 - /tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
Author: markt Date: Wed May 29 19:27:43 2013 New Revision: 1487604 URL: http://svn.apache.org/r1487604 Log: Simplify Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1487604&r1=1487603&r2=1487604&view=diff == --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Wed May 29 19:27:43 2013 @@ -1542,13 +1542,10 @@ public abstract class AbstractHttp11Proc asyncStateMachine.asyncOperation(); try { if (outputBuffer.hasDataToWrite()) { -//System.out.println("Attempting data flush!!"); -outputBuffer.flushBuffer(false); -} -//return if we have more data to write -if (outputBuffer.hasDataToWrite()) { -registerForEvent(false, true); -return SocketState.LONG; +if (outputBuffer.flushBuffer(false)) { +registerForEvent(false, true); +return SocketState.LONG; +} } } catch (IOException x) { if (getLog().isDebugEnabled()) { - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
svn commit: r1487600 - /tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
Author: markt Date: Wed May 29 19:13:10 2013 New Revision: 1487600 URL: http://svn.apache.org/r1487600 Log: Remove some accidentally committed test code Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java?rev=1487600&r1=1487599&r2=1487600&view=diff == --- tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Wed May 29 19:13:10 2013 @@ -161,10 +161,6 @@ public class InternalNioOutputBuffer ext // Still have data to write registerWriteInterest(); } -if (written == 0) { -(new Exception("written == 0")).printStackTrace(); -} -System.out.println("Total written " + bytesWritten.addAndGet(written)); return written; } - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
svn commit: r1487598 - in /tomcat/trunk/java/org/apache/coyote: ActionCode.java Response.java http11/AbstractHttp11Processor.java http11/InternalNioOutputBuffer.java
Author: markt Date: Wed May 29 19:10:43 2013 New Revision: 1487598 URL: http://svn.apache.org/r1487598 Log: Simplify. Buffered data left over after a non-blcoking write is written in the processor Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java tomcat/trunk/java/org/apache/coyote/Response.java tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=1487598&r1=1487597&r2=1487598&view=diff == --- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Wed May 29 19:10:43 2013 @@ -213,12 +213,6 @@ public enum ActionCode { NB_WRITE_INTEREST, /** - * Flush the lower level buffers and re-register the socket with the poller - * if the buffers cannot be completely flushed. - */ -NB_WRITE_FLUSH, - -/** * Indicates if the request body has been fully read. */ REQUEST_BODY_FULLY_READ Modified: tomcat/trunk/java/org/apache/coyote/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1487598&r1=1487597&r2=1487598&view=diff == --- tomcat/trunk/java/org/apache/coyote/Response.java (original) +++ tomcat/trunk/java/org/apache/coyote/Response.java Wed May 29 19:10:43 2013 @@ -595,16 +595,9 @@ public final class Response { } public void onWritePossible() throws IOException { -// Flush the lower level buffers -// If data left in buffers wait for next onWritePossible. Socket will -// have been placed in poller if buffers weren't emptied. -AtomicBoolean isDataLeftInBuffers = new AtomicBoolean(true); -action(ActionCode.NB_WRITE_FLUSH, isDataLeftInBuffers); -if (isDataLeftInBuffers.get()) { -return; -} - -// No data in lower level buffers. Ready for app to write more data. +// Any buffered data left over from a previous non-blocking write is +// written in the Processor so if this point is reached the app is able +// to write data. boolean fire = false; synchronized (fireListenerLock) { if (fireListener) { Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1487598&r1=1487597&r2=1487598&view=diff == --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Wed May 29 19:10:43 2013 @@ -821,14 +821,6 @@ public abstract class AbstractHttp11Proc // TODO throw new IllegalStateException(); } -} else if (actionCode == ActionCode.NB_WRITE_FLUSH) { -AtomicBoolean isDataLeftInBuffers = (AtomicBoolean)param; -try { -isDataLeftInBuffers.set(getOutputBuffer().flushBuffer(false)); -} catch (IOException e) { -// TODO -throw new IllegalStateException(); -} } else if (actionCode == ActionCode.NB_READ_INTEREST) { registerForEvent(true, false); } else if (actionCode == ActionCode.UPGRADE) { Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java?rev=1487598&r1=1487597&r2=1487598&view=diff == --- tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Wed May 29 19:10:43 2013 @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Iterator; +import java.util.concurrent.atomic.AtomicLong; import org.apache.coyote.OutputBuffer; import org.apache.coyote.Response; @@ -82,6 +83,8 @@ public class InternalNioOutputBuffer ext */ protected volatile boolean flipped = false; +private final AtomicLong bytesWritten = new AtomicLong(0); + // - Public Methods /** @@ -96,6 +99,7 @@ public class InternalNioOutputBuffer ext socket = null; } flipped = false; +bytesWritten.set(0); } @@ -157,6 +161,10 @@ public class InternalNio
Re: AsyncContext.dispatch(path) invoked more than once
2013/5/28 Konstantin Kolinko wrote: > > > I think that your patch is wrong. > > Looking at how ActionCode.ASYNC_DISPATCH is handled in different > connector implementations in Tomcat 7, the code is like the following: > > if (asyncStateMachine.asyncDispatch()) { > ((AprEndpoint)endpoint).processSocketAsync(this.socket, > SocketStatus.OPEN); > } > > In your example dispatching does not happen immediately as > asyncDispatch() call returns "false" and asyncStateMachine state > changes to AsyncState.MUST_DISPATCH. Thus your patch works. > > But, there is a case when the call returns "true" and dispatching > happens immediately. Such dispatching will be broken. Thanks for pointing this. > > BTW, I wonder if the following can be an alternative: > > if (this.dispatch != null) throw new IllegalStateException(".."); Unfortunately this will break another scenario: Servlet1 does dispatch to Servlet2 AsyncContext asyncContext = request.startAsync(request, response); asyncContext .dispatch("/Servlet2"); Servlet2 does dispatch to resourceA AsyncContext asyncContext = request.startAsync(request, response); asyncContext .dispatch("/Servlet2"); < here we still do not have invocation to AsyncContextImpl.recycle and AsyncContextImpl.dispatch field is not null So if we introduce a null check we will break double dispatch scenario. The solution might be to separate the check for state and the actual action invocation. Wdyt? Violeta > > Best regards, > Konstantin Kolinko > > - > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > For additional commands, e-mail: dev-h...@tomcat.apache.org >
svn commit: r1487556 - /tomcat/trunk/java/org/apache/coyote/Response.java
Author: markt Date: Wed May 29 17:26:10 2013 New Revision: 1487556 URL: http://svn.apache.org/r1487556 Log: Fix logic error Modified: tomcat/trunk/java/org/apache/coyote/Response.java Modified: tomcat/trunk/java/org/apache/coyote/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1487556&r1=1487555&r2=1487556&view=diff == --- tomcat/trunk/java/org/apache/coyote/Response.java (original) +++ tomcat/trunk/java/org/apache/coyote/Response.java Wed May 29 17:26:10 2013 @@ -586,7 +586,7 @@ public final class Response { synchronized (fireListenerLock) { if (fireListener) { // isReady() has already returned false -return true; +return false; } action(ActionCode.NB_WRITE_INTEREST, isReady); fireListener = !isReady.get(); - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
svn commit: r1487523 - in /tomcat/trunk/java/org/apache: catalina/connector/ coyote/ coyote/http11/
Author: markt Date: Wed May 29 15:55:28 2013 New Revision: 1487523 URL: http://svn.apache.org/r1487523 Log: Align onWritePossible behaviour with the spec. This passes the unit tests on Windows. Still some TODOs to resolve once I have checked this passes the tests on other platforms (including the CI system) Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/connector/OutputBuffer.java tomcat/trunk/java/org/apache/coyote/ActionCode.java tomcat/trunk/java/org/apache/coyote/Response.java tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java tomcat/trunk/java/org/apache/coyote/http11/AbstractOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/InternalAprOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/InternalOutputBuffer.java Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1487523&r1=1487522&r2=1487523&view=diff == --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Wed May 29 15:55:28 2013 @@ -356,7 +356,7 @@ public class CoyoteAdapter implements Ad request.getContext().getLoader().getClassLoader(); try { Thread.currentThread().setContextClassLoader(newCL); -res.getWriteListener().onWritePossible(); +res.onWritePossible(); } finally { Thread.currentThread().setContextClassLoader(oldCL); } Modified: tomcat/trunk/java/org/apache/catalina/connector/OutputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/OutputBuffer.java?rev=1487523&r1=1487522&r2=1487523&view=diff == --- tomcat/trunk/java/org/apache/catalina/connector/OutputBuffer.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/OutputBuffer.java Wed May 29 15:55:28 2013 @@ -22,7 +22,6 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.HashMap; -import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.WriteListener; @@ -647,13 +646,7 @@ public class OutputBuffer extends Writer public boolean isReady() { -if (coyoteResponse.getWriteListener() == null) { -throw new IllegalStateException("not in non blocking mode."); -} -// Assume write is not possible -AtomicBoolean isReady = new AtomicBoolean(false); -coyoteResponse.action(ActionCode.NB_WRITE_INTEREST, isReady); -return isReady.get(); +return coyoteResponse.isReady(); } Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=1487523&r1=1487522&r2=1487523&view=diff == --- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Wed May 29 15:55:28 2013 @@ -213,6 +213,12 @@ public enum ActionCode { NB_WRITE_INTEREST, /** + * Flush the lower level buffers and re-register the socket with the poller + * if the buffers cannot be completely flushed. + */ +NB_WRITE_FLUSH, + +/** * Indicates if the request body has been fully read. */ REQUEST_BODY_FULLY_READ Modified: tomcat/trunk/java/org/apache/coyote/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1487523&r1=1487522&r2=1487523&view=diff == --- tomcat/trunk/java/org/apache/coyote/Response.java (original) +++ tomcat/trunk/java/org/apache/coyote/Response.java Wed May 29 15:55:28 2013 @@ -548,6 +548,8 @@ public final class Response { } protected volatile WriteListener listener; +private boolean fireListener = false; +private final Object fireListenerLock = new Object(); public WriteListener getWriteListener() { return listener; @@ -573,4 +575,45 @@ public final class Response { this.listener = listener; } + +public boolean isReady() { +if (listener == null) { +// TODO i18n +throw new IllegalStateException("not in non blocking mode."); +} +// Assume write is not possible +AtomicBoolean isReady = new At
[Bug 54997] SSL Handshake implementation in AsycnChannelWrapperSecure does not handle SSLEngineResult.Status.BUFFER_UNDERFLOW and SSLEngineResult.Status.BUFFER_OVERFLOW states
https://issues.apache.org/bugzilla/show_bug.cgi?id=54997 --- Comment #3 from Niki Dokovski --- Thanks Mark, It works just fine. -- You are receiving this mail because: You are the assignee for the bug. - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
[Bug 54997] SSL Handshake implementation in AsycnChannelWrapperSecure does not handle SSLEngineResult.Status.BUFFER_UNDERFLOW and SSLEngineResult.Status.BUFFER_OVERFLOW states
https://issues.apache.org/bugzilla/show_bug.cgi?id=54997 Mark Thomas changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #2 from Mark Thomas --- Thanks for the report. I applied a different patch as I wanted to avoid duplicate code as far as possible. The issue should be fixed in trunk but feel free to re-open the issue if that is not the case. -- You are receiving this mail because: You are the assignee for the bug. - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
svn commit: r1487430 - /tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java
Author: markt Date: Wed May 29 10:17:20 2013 New Revision: 1487430 URL: http://svn.apache.org/r1487430 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54997 Handle BUFFER_UNDERFLOW during SSL handshake. Modified: tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java?rev=1487430&r1=1487429&r2=1487430&view=diff == --- tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/AsyncChannelWrapperSecure.java Wed May 29 10:17:20 2013 @@ -317,6 +317,9 @@ public class AsyncChannelWrapperSecure i private final WrapperFuture hFuture; +private HandshakeStatus handshakeStatus; +private Status resultStatus; + public WebSocketSslHandshakeThread(WrapperFuture hFuture) { this.hFuture = hFuture; } @@ -328,8 +331,9 @@ public class AsyncChannelWrapperSecure i // So the first compact does the right thing socketReadBuffer.position(socketReadBuffer.limit()); -HandshakeStatus handshakeStatus = -sslEngine.getHandshakeStatus(); +handshakeStatus = sslEngine.getHandshakeStatus(); +resultStatus = Status.OK; + boolean handshaking = true; while(handshaking) { @@ -338,7 +342,7 @@ public class AsyncChannelWrapperSecure i socketWriteBuffer.clear(); SSLEngineResult r = sslEngine.wrap(DUMMY, socketWriteBuffer); -handshakeStatus = checkResult(r, true); +checkResult(r, true); socketWriteBuffer.flip(); Future fWrite = socketChannel.write(socketWriteBuffer); @@ -347,7 +351,8 @@ public class AsyncChannelWrapperSecure i } case NEED_UNWRAP: { socketReadBuffer.compact(); -if (socketReadBuffer.position() == 0) { +if (socketReadBuffer.position() == 0 || +resultStatus == Status.BUFFER_UNDERFLOW) { Future fRead = socketChannel.read(socketReadBuffer); fRead.get(); @@ -355,7 +360,7 @@ public class AsyncChannelWrapperSecure i socketReadBuffer.flip(); SSLEngineResult r = sslEngine.unwrap(socketReadBuffer, DUMMY); -handshakeStatus = checkResult(r, false); +checkResult(r, false); break; } case NEED_TASK: { @@ -383,10 +388,14 @@ public class AsyncChannelWrapperSecure i hFuture.complete(null); } -private HandshakeStatus checkResult(SSLEngineResult result, -boolean wrap) throws SSLException { +private void checkResult(SSLEngineResult result, boolean wrap) +throws SSLException { + +handshakeStatus = result.getHandshakeStatus(); +resultStatus = result.getStatus(); -if (result.getStatus() != Status.OK) { +if (resultStatus != Status.OK && +(wrap || resultStatus != Status.BUFFER_UNDERFLOW)) { throw new SSLException("TODO"); } if (wrap && result.bytesConsumed() != 0) { @@ -395,7 +404,6 @@ public class AsyncChannelWrapperSecure i if (!wrap && result.bytesProduced() != 0) { throw new SSLException("TODO"); } -return result.getHandshakeStatus(); } } - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org