Author: remm Date: Mon Nov 3 11:36:28 2014 New Revision: 1636324 URL: http://svn.apache.org/r1636324 Log: Allow HTTP upgrade process to complete without data corruption when additional content is sent along with the upgrade header.
Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java tomcat/trunk/java/org/apache/coyote/InputBuffer.java tomcat/trunk/java/org/apache/coyote/Processor.java tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java tomcat/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/Nio2Processor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/NioProcessor.java tomcat/trunk/java/org/apache/coyote/spdy/SpdyProcessor.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=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Mon Nov 3 11:36:28 2014 @@ -18,6 +18,7 @@ package org.apache.coyote; import java.io.IOException; import java.net.InetAddress; +import java.nio.ByteBuffer; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -666,11 +667,13 @@ public abstract class AbstractProtocol<S // Get the HTTP upgrade handler HttpUpgradeHandler httpUpgradeHandler = processor.getHttpUpgradeHandler(); + // Retrieve leftover input + ByteBuffer leftoverInput = processor.getLeftoverInput(); // Release the Http11 processor to be re-used release(wrapper, processor, false, false); // Create the upgrade processor processor = createUpgradeProcessor( - wrapper, httpUpgradeHandler); + wrapper, leftoverInput, httpUpgradeHandler); // Mark the connection as upgraded wrapper.setUpgraded(true); // Associate with the processor with the connection @@ -776,7 +779,7 @@ public abstract class AbstractProtocol<S Processor<S> processor, boolean socketClosing, boolean addToPoller); protected abstract Processor<S> createUpgradeProcessor( - SocketWrapper<S> socket, + SocketWrapper<S> socket, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor) throws IOException; protected void register(AbstractProcessor<S> processor) { Modified: tomcat/trunk/java/org/apache/coyote/InputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/InputBuffer.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/InputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/InputBuffer.java Mon Nov 3 11:36:28 2014 @@ -27,9 +27,6 @@ import org.apache.tomcat.util.buf.ByteCh * * This class is used only in the protocol implementation. All reading from * Tomcat ( or adapter ) should be done using Request.doRead(). - * - * - * @author Remy Maucherat */ public interface InputBuffer { Modified: tomcat/trunk/java/org/apache/coyote/Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Processor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/Processor.java Mon Nov 3 11:36:28 2014 @@ -17,6 +17,7 @@ package org.apache.coyote; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.concurrent.Executor; import javax.servlet.http.HttpUpgradeHandler; @@ -54,4 +55,10 @@ public interface Processor<S> { void recycle(boolean socketClosing); void setSslSupport(SSLSupport sslSupport); + + /** + * Allows retrieving additional input during the upgrade process + * @return leftover bytes + */ + ByteBuffer getLeftoverInput(); } Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Mon Nov 3 11:36:28 2014 @@ -1084,6 +1084,12 @@ public abstract class AbstractAjpProcess } + @Override + public ByteBuffer getLeftoverInput() { + return null; + } + + /** * Get more request body data from the web server and store it in the * internal buffer. Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Mon Nov 3 11:36:28 2014 @@ -16,6 +16,8 @@ */ package org.apache.coyote.ajp; +import java.nio.ByteBuffer; + import javax.servlet.http.HttpUpgradeHandler; import org.apache.coyote.AbstractProtocol; @@ -99,7 +101,7 @@ public abstract class AbstractAjpProtoco } @Override - protected P createUpgradeProcessor(SocketWrapper<S> socket, + protected P createUpgradeProcessor(SocketWrapper<S> socket, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeHandler) { // TODO should fail - throw IOE return null; 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=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Mon Nov 3 11:36:28 2014 @@ -18,6 +18,7 @@ package org.apache.coyote.http11; import java.io.IOException; import java.io.InterruptedIOException; +import java.nio.ByteBuffer; import java.util.Locale; import java.util.StringTokenizer; import java.util.concurrent.atomic.AtomicBoolean; @@ -1792,7 +1793,6 @@ public abstract class AbstractHttp11Proc SocketWrapper<S> socketWrapper); - @Override public final void recycle(boolean isSocketClosing) { getAdapter().checkRecycled(request, response); @@ -1813,4 +1813,11 @@ public abstract class AbstractHttp11Proc } protected abstract void recycleInternal(); + + + @Override + public ByteBuffer getLeftoverInput() { + return inputBuffer.getLeftover(); + } + } Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java Mon Nov 3 11:36:28 2014 @@ -17,6 +17,7 @@ package org.apache.coyote.http11; import java.io.IOException; +import java.nio.ByteBuffer; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -390,6 +391,15 @@ public abstract class AbstractInputBuffe } } + ByteBuffer getLeftover() { + int available = lastValid - pos; + if (available > 0) { + return ByteBuffer.wrap(buf, pos, available); + } else { + return null; + } + } + /** * Is standard Servlet blocking IO being used for input? */ Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Mon Nov 3 11:36:28 2014 @@ -17,6 +17,7 @@ package org.apache.coyote.http11; import java.io.IOException; +import java.nio.ByteBuffer; import javax.servlet.http.HttpUpgradeHandler; @@ -330,11 +331,11 @@ public class Http11AprProtocol extends A @Override protected Processor<Long> createUpgradeProcessor( - SocketWrapper<Long> socket, + SocketWrapper<Long> socket, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor) throws IOException { - return new AprProcessor(socket, httpUpgradeProcessor, - (AprEndpoint) proto.endpoint, + return new AprProcessor(socket, leftoverInput, + httpUpgradeProcessor, (AprEndpoint) proto.endpoint, proto.getUpgradeAsyncWriteBufferSize()); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java Mon Nov 3 11:36:28 2014 @@ -17,6 +17,7 @@ package org.apache.coyote.http11; import java.io.IOException; +import java.nio.ByteBuffer; import java.nio.channels.ReadPendingException; import javax.net.ssl.SSLEngine; @@ -257,11 +258,11 @@ public class Http11Nio2Protocol extends @Override protected Processor<Nio2Channel> createUpgradeProcessor( - SocketWrapper<Nio2Channel> socket, + SocketWrapper<Nio2Channel> socket, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor) throws IOException { - return new Nio2Processor(proto.endpoint, socket, httpUpgradeProcessor, - proto.getUpgradeAsyncWriteBufferSize()); + return new Nio2Processor(proto.endpoint, socket, leftoverInput, + httpUpgradeProcessor, proto.getUpgradeAsyncWriteBufferSize()); } @Override Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Mon Nov 3 11:36:28 2014 @@ -557,4 +557,5 @@ public class Http11NioProcessor extends public void setSslSupport(SSLSupport sslSupport) { this.sslSupport = sslSupport; } + } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Mon Nov 3 11:36:28 2014 @@ -17,6 +17,7 @@ package org.apache.coyote.http11; import java.io.IOException; +import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.Iterator; @@ -289,10 +290,10 @@ public class Http11NioProtocol extends A @Override protected Processor<NioChannel> createUpgradeProcessor( - SocketWrapper<NioChannel> socket, + SocketWrapper<NioChannel> socket, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor) throws IOException { - return new NioProcessor(socket, httpUpgradeProcessor, + return new NioProcessor(socket, leftoverInput, httpUpgradeProcessor, proto.getEndpoint().getSelectorPool(), proto.getUpgradeAsyncWriteBufferSize()); } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java Mon Nov 3 11:36:28 2014 @@ -18,6 +18,7 @@ package org.apache.coyote.http11; import java.io.IOException; import java.net.Socket; +import java.nio.ByteBuffer; import javax.servlet.http.HttpUpgradeHandler; @@ -197,10 +198,10 @@ public class Http11Protocol extends Abst @Override protected Processor<Socket> createUpgradeProcessor( - SocketWrapper<Socket> socket, + SocketWrapper<Socket> socket, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor) throws IOException { - return new BioProcessor(socket, httpUpgradeProcessor, + return new BioProcessor(socket, leftoverInput, httpUpgradeProcessor, proto.getUpgradeAsyncWriteBufferSize()); } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java Mon Nov 3 11:36:28 2014 @@ -17,6 +17,7 @@ package org.apache.coyote.http11.upgrade; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.concurrent.Executor; import javax.servlet.ServletInputStream; @@ -178,4 +179,9 @@ public abstract class AbstractProcessor< public final void setSslSupport(SSLSupport sslSupport) { // NOOP } + + @Override + public ByteBuffer getLeftoverInput() { + return null; + } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprProcessor.java Mon Nov 3 11:36:28 2014 @@ -16,6 +16,8 @@ */ package org.apache.coyote.http11.upgrade; +import java.nio.ByteBuffer; + import javax.servlet.http.HttpUpgradeHandler; import org.apache.juli.logging.Log; @@ -32,11 +34,11 @@ public class AprProcessor extends Abstra private static final int INFINITE_TIMEOUT = -1; - public AprProcessor(SocketWrapper<Long> wrapper, + public AprProcessor(SocketWrapper<Long> wrapper, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor, AprEndpoint endpoint, int asyncWriteBufferSize) { super(httpUpgradeProcessor, - new AprServletInputStream(wrapper), + new AprServletInputStream(wrapper, leftoverInput), new AprServletOutputStream(wrapper, asyncWriteBufferSize, endpoint)); Socket.timeoutSet(wrapper.getSocket().longValue(), INFINITE_TIMEOUT); Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java Mon Nov 3 11:36:28 2014 @@ -18,6 +18,7 @@ package org.apache.coyote.http11.upgrade import java.io.EOFException; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; @@ -34,13 +35,18 @@ public class AprServletInputStream exten private final SocketWrapper<Long> wrapper; private final long socket; + private ByteBuffer leftoverInput; private volatile boolean eagain = false; private volatile boolean closed = false; - public AprServletInputStream(SocketWrapper<Long> wrapper) { + public AprServletInputStream(SocketWrapper<Long> wrapper, ByteBuffer leftoverInput) { this.wrapper = wrapper; this.socket = wrapper.getSocket().longValue(); + if (leftoverInput != null) { + this.leftoverInput = ByteBuffer.allocate(leftoverInput.remaining()); + this.leftoverInput.put(leftoverInput); + } } @@ -52,6 +58,17 @@ public class AprServletInputStream exten throw new IOException(sm.getString("apr.closed", Long.valueOf(socket))); } + if (leftoverInput != null) { + if (leftoverInput.remaining() < len) { + len = leftoverInput.remaining(); + } + leftoverInput.get(b, off, len); + if (leftoverInput.remaining() == 0) { + leftoverInput = null; + } + return len; + } + Lock readLock = wrapper.getBlockingStatusReadLock(); WriteLock writeLock = wrapper.getBlockingStatusWriteLock(); Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioProcessor.java Mon Nov 3 11:36:28 2014 @@ -18,6 +18,7 @@ package org.apache.coyote.http11.upgrade import java.io.IOException; import java.net.Socket; +import java.nio.ByteBuffer; import javax.servlet.http.HttpUpgradeHandler; @@ -33,10 +34,10 @@ public class BioProcessor extends Abstra private static final int INFINITE_TIMEOUT = 0; - public BioProcessor(SocketWrapper<Socket> wrapper, + public BioProcessor(SocketWrapper<Socket> wrapper, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor, int asyncWriteBufferSize) throws IOException { - super(httpUpgradeProcessor, new BioServletInputStream(wrapper), + super(httpUpgradeProcessor, new BioServletInputStream(wrapper, leftoverInput), new BioServletOutputStream(wrapper, asyncWriteBufferSize)); wrapper.getSocket().setSoTimeout(INFINITE_TIMEOUT); Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioServletInputStream.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/BioServletInputStream.java Mon Nov 3 11:36:28 2014 @@ -19,22 +19,39 @@ package org.apache.coyote.http11.upgrade import java.io.IOException; import java.io.InputStream; import java.net.Socket; +import java.nio.ByteBuffer; import org.apache.tomcat.util.net.SocketWrapper; public class BioServletInputStream extends AbstractServletInputStream { private final InputStream inputStream; + private ByteBuffer leftoverInput; - public BioServletInputStream(SocketWrapper<Socket> wrapper) + public BioServletInputStream(SocketWrapper<Socket> wrapper, ByteBuffer leftoverInput) throws IOException { inputStream = wrapper.getSocket().getInputStream(); + if (leftoverInput != null) { + this.leftoverInput = ByteBuffer.allocate(leftoverInput.remaining()); + this.leftoverInput.put(leftoverInput); + } } @Override protected int doRead(boolean block, byte[] b, int off, int len) throws IOException { - return inputStream.read(b, off, len); + if (leftoverInput != null) { + if (leftoverInput.remaining() < len) { + len = leftoverInput.remaining(); + } + leftoverInput.get(b, off, len); + if (leftoverInput.remaining() == 0) { + leftoverInput = null; + } + return len; + } else { + return inputStream.read(b, off, len); + } } @Override Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/Nio2Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/Nio2Processor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/Nio2Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/Nio2Processor.java Mon Nov 3 11:36:28 2014 @@ -16,6 +16,8 @@ */ package org.apache.coyote.http11.upgrade; +import java.nio.ByteBuffer; + import javax.servlet.http.HttpUpgradeHandler; import org.apache.juli.logging.Log; @@ -33,7 +35,7 @@ public class Nio2Processor extends Abstr private static final int INFINITE_TIMEOUT = -1; public Nio2Processor(AbstractEndpoint<Nio2Channel> endpoint, - SocketWrapper<Nio2Channel> wrapper, + SocketWrapper<Nio2Channel> wrapper, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor, int asyncWriteBufferSize) { super(httpUpgradeProcessor, @@ -41,5 +43,8 @@ public class Nio2Processor extends Abstr new Nio2ServletOutputStream(wrapper, asyncWriteBufferSize, endpoint)); wrapper.setTimeout(INFINITE_TIMEOUT); + if (leftoverInput != null) { + wrapper.getSocket().getBufHandler().getReadBuffer().put(leftoverInput); + } } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/NioProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/NioProcessor.java Mon Nov 3 11:36:28 2014 @@ -16,6 +16,8 @@ */ package org.apache.coyote.http11.upgrade; +import java.nio.ByteBuffer; + import javax.servlet.http.HttpUpgradeHandler; import org.apache.juli.logging.Log; @@ -32,7 +34,7 @@ public class NioProcessor extends Abstra private static final int INFINITE_TIMEOUT = -1; - public NioProcessor(SocketWrapper<NioChannel> wrapper, + public NioProcessor(SocketWrapper<NioChannel> wrapper, ByteBuffer leftoverInput, HttpUpgradeHandler httpUpgradeProcessor, NioSelectorPool pool, int asyncWriteBufferSize) { super(httpUpgradeProcessor, @@ -40,5 +42,15 @@ public class NioProcessor extends Abstra new NioServletOutputStream(wrapper, asyncWriteBufferSize, pool)); wrapper.setTimeout(INFINITE_TIMEOUT); + if (leftoverInput != null) { + ByteBuffer readBuffer = wrapper.getSocket().getBufHandler().getReadBuffer(); + if (readBuffer.remaining() > 0) { + readBuffer.flip(); + } else { + readBuffer.clear(); + } + readBuffer.put(leftoverInput); + readBuffer.flip(); + } } } Modified: tomcat/trunk/java/org/apache/coyote/spdy/SpdyProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/spdy/SpdyProcessor.java?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/spdy/SpdyProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/spdy/SpdyProcessor.java Mon Nov 3 11:36:28 2014 @@ -19,6 +19,7 @@ package org.apache.coyote.spdy; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; +import java.nio.ByteBuffer; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -534,6 +535,11 @@ public class SpdyProcessor<S> extends Ab } @Override + public ByteBuffer getLeftoverInput() { + return null; + } + + @Override public SocketState upgradeDispatch(SocketStatus status) throws IOException { return null; } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1636324&r1=1636323&r2=1636324&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Mon Nov 3 11:36:28 2014 @@ -45,6 +45,14 @@ issues to not "pop up" wrt. others). --> <section name="Tomcat 8.0.16 (markt)"> + <subsection name="Coyote"> + <changelog> + <fix> + Allow HTTP upgrade process to complete without data corruption when + additional content is sent along with the upgrade header. (remm) + </fix> + </changelog> + </subsection> </section> <section name="Tomcat 8.0.15 (markt)"> <subsection name="Catalina"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org