Author: markt
Date: Tue Feb  7 10:18:10 2012
New Revision: 1241410

URL: http://svn.apache.org/viewvc?rev=1241410&view=rev
Log:
Use a lighter weight processor for upgrades.
Note that extending the Http11 processors is a hack that I think can be removed 
with some further refactoring of the connectors.

Added:
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java
      - copied, changed from r1241407, 
tomcat/trunk/java/org/apache/coyote/http11/UpgradeInbound.java
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeOutbound.java
      - copied, changed from r1241407, 
tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
Removed:
    tomcat/trunk/java/org/apache/coyote/http11/UpgradeInbound.java
    tomcat/trunk/java/org/apache/coyote/http11/UpgradeInputStream.java
    tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java
    tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutputStream.java
Modified:
    tomcat/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java
    tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java
    tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java
    tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java
    tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
    tomcat/trunk/java/org/apache/coyote/AbstractProtocol.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/Http11AprProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.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/Http11Processor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java

Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Tue Feb  7 
10:18:10 2012
@@ -74,7 +74,7 @@ import org.apache.catalina.core.AsyncCon
 import org.apache.catalina.util.ParameterMap;
 import org.apache.catalina.util.StringParser;
 import org.apache.coyote.ActionCode;
-import org.apache.coyote.http11.UpgradeInbound;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.ExceptionUtils;

Modified: tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java Tue Feb  
7 10:18:10 2012
@@ -41,7 +41,7 @@ import javax.servlet.http.Part;
 
 import org.apache.catalina.Globals;
 import org.apache.catalina.security.SecurityUtil;
-import org.apache.coyote.http11.UpgradeInbound;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.tomcat.util.res.StringManager;
 
 /**

Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java Tue Feb  
7 10:18:10 2012
@@ -22,8 +22,9 @@ import java.io.InputStreamReader;
 import java.io.Reader;
 
 import org.apache.catalina.util.Conversions;
-import org.apache.coyote.http11.UpgradeInbound;
-import org.apache.coyote.http11.UpgradeOutbound;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
+import org.apache.coyote.http11.upgrade.UpgradeOutbound;
+import org.apache.coyote.http11.upgrade.UpgradeProcessor;
 import org.apache.tomcat.util.buf.B2CConverter;
 import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
 
@@ -41,7 +42,7 @@ public abstract class StreamInbound impl
     // frames
     // TODO
 
-    private InputStream is = null;
+    private UpgradeProcessor processor = null;
     private WsOutbound outbound;
 
     @Override
@@ -51,8 +52,8 @@ public abstract class StreamInbound impl
 
 
     @Override
-    public void setInputStream(InputStream is) {
-        this.is = is;
+    public void setUpgradeProcessor(UpgradeProcessor processor) {
+        this.processor = processor;
     }
 
     public WsOutbound getStreamOutbound() {
@@ -64,7 +65,7 @@ public abstract class StreamInbound impl
         // Must be start the start of a frame
 
         // Read the first byte
-        int i = is.read();
+        int i = processor.read();
 
         fin = (i & 0x80) > 0;
 
@@ -80,7 +81,7 @@ public abstract class StreamInbound impl
         validateOpCode(opCode);
 
         // Read the next byte
-        i = is.read();
+        i = processor.read();
 
         // Client data must be masked and this isn't
         if ((i & 0x80) == 0) {
@@ -91,19 +92,20 @@ public abstract class StreamInbound impl
         payloadLength = i & 0x7F;
         if (payloadLength == 126) {
             byte[] extended = new byte[2];
-            is.read(extended);
+            processor.read(extended);
             payloadLength = Conversions.byteArrayToLong(extended);
         } else if (payloadLength == 127) {
             byte[] extended = new byte[8];
-            is.read(extended);
+            processor.read(extended);
             payloadLength = Conversions.byteArrayToLong(extended);
         }
 
         byte[] mask = new byte[4];
-        is.read(mask);
+        processor.read(mask);
 
         if (opCode == 1 || opCode == 2) {
-            WsInputStream wsIs = new WsInputStream(is, mask, payloadLength);
+            WsInputStream wsIs = new WsInputStream(processor, mask,
+                    payloadLength);
             if (opCode == 2) {
                 onBinaryData(wsIs);
             } else {
@@ -123,7 +125,7 @@ public abstract class StreamInbound impl
         // TODO: Handle control frames appearing in the middle of a multi-frame
         //       message
 
-        return SocketState.UPGRADE;
+        return SocketState.UPGRADED;
     }
 
     protected abstract void onBinaryData(InputStream is) throws IOException;

Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java Tue Feb  
7 10:18:10 2012
@@ -17,17 +17,19 @@
 package org.apache.catalina.websocket;
 
 import java.io.IOException;
-import java.io.InputStream;
+
+import org.apache.coyote.http11.upgrade.UpgradeProcessor;
 
 public class WsInputStream extends java.io.InputStream {
 
-    private InputStream wrapped;
+    private UpgradeProcessor processor;
     private byte[] mask;
     private long remaining;
     private long read;
 
-    public WsInputStream(InputStream wrapped, byte[] mask, long remaining) {
-        this.wrapped = wrapped;
+    public WsInputStream(UpgradeProcessor processor, byte[] mask,
+            long remaining) {
+        this.processor = processor;
         this.mask = mask;
         this.remaining = remaining;
         this.read = 0;
@@ -42,7 +44,7 @@ public class WsInputStream extends java.
         remaining--;
         read++;
 
-        int masked = wrapped.read();
+        int masked = processor.read();
         return masked ^ mask[(int) ((read - 1) % 4)];
     }
 

Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java (original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java Tue Feb  7 
10:18:10 2012
@@ -20,7 +20,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 
-import org.apache.coyote.http11.UpgradeOutbound;
+import org.apache.coyote.http11.upgrade.UpgradeOutbound;
 import org.apache.tomcat.util.buf.B2CConverter;
 
 public class WsOutbound {

Modified: tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProcessor.java Tue Feb  7 
10:18:10 2012
@@ -19,6 +19,7 @@ package org.apache.coyote;
 import java.io.IOException;
 import java.util.concurrent.Executor;
 
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
 import org.apache.tomcat.util.net.SocketStatus;
@@ -31,12 +32,20 @@ import org.apache.tomcat.util.net.Socket
 public abstract class AbstractProcessor<S> implements ActionHook, Processor {
 
     protected Adapter adapter;
-    protected final AsyncStateMachine asyncStateMachine;
-    protected final AbstractEndpoint endpoint;
-    protected final Request request;
-    protected final Response response;
+    protected AsyncStateMachine asyncStateMachine;
+    protected AbstractEndpoint endpoint;
+    protected Request request;
+    protected Response response;
 
 
+    /**
+     * Intended for use by the Upgrade sub-classes that have no need to
+     * initialise the request, response, etc.
+     */
+    protected AbstractProcessor() {
+        // NOOP
+    }
+
     public AbstractProcessor(AbstractEndpoint endpoint) {
         this.endpoint = endpoint;
         asyncStateMachine = new AsyncStateMachine(this);
@@ -96,7 +105,7 @@ public abstract class AbstractProcessor<
 
 
     public boolean isAsync() {
-        return asyncStateMachine.isAsync();
+        return (asyncStateMachine != null && asyncStateMachine.isAsync());
     }
 
 
@@ -131,4 +140,6 @@ public abstract class AbstractProcessor<
      * upgrade.
      */
     public abstract SocketState upgradeDispatch() throws IOException;
+
+    public abstract UpgradeInbound getUpgradeInbound();
 }

Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Tue Feb  7 
10:18:10 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.coyote;
 
+import java.io.IOException;
 import java.net.InetAddress;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -28,6 +29,7 @@ import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.juli.logging.Log;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.modeler.Registry;
@@ -576,9 +578,18 @@ public abstract class AbstractProtocol i
                     // closed. If it works, the socket will be re-added to the
                     // poller
                     release(socket, processor, false, false);
-                } else if (state == SocketState.UPGRADE) {
+                } else if (state == SocketState.UPGRADED) {
                     // Need to keep the connection associated with the 
processor
-                    longPoll(socket, processor);
+                    upgradePoll(socket, processor);
+                } else if (state == SocketState.UPGRADING) {
+                    // Get the UpgradeInbound handler
+                    UpgradeInbound inbound = processor.getUpgradeInbound();
+                    // Release the Http11 processor to be re-used
+                    release(socket, processor, false, false);
+                    // Create the light-weight upgrade processor
+                    processor = createUpgradeProcessor(socket, inbound);
+                    // Need to keep the connection associated with the 
processor
+                    upgradePoll(socket, processor);
                 } else {
                     // Connection closed. OK to recycle the processor.
                     release(socket, processor, true, false);
@@ -610,9 +621,12 @@ public abstract class AbstractProtocol i
         protected abstract P createProcessor();
         protected abstract void initSsl(SocketWrapper<S> socket, P processor);
         protected abstract void longPoll(SocketWrapper<S> socket, P processor);
+        protected abstract void upgradePoll(SocketWrapper<S> socket,
+                P processor);
         protected abstract void release(SocketWrapper<S> socket, P processor,
                 boolean socketClosing, boolean addToPoller);
-
+        protected abstract P createUpgradeProcessor(SocketWrapper<S> socket,
+                UpgradeInbound inbound) throws IOException;
 
         protected void register(AbstractProcessor<S> processor) {
             if (getProtocol().getDomain() != null) {
@@ -645,8 +659,12 @@ public abstract class AbstractProtocol i
             if (getProtocol().getDomain() != null) {
                 synchronized (this) {
                     try {
-                        RequestInfo rp =
-                            processor.getRequest().getRequestProcessor();
+                        Request r = processor.getRequest();
+                        if (r == null) {
+                            // Probably an UpgradeProcessor
+                            return;
+                        }
+                        RequestInfo rp = r.getRequestProcessor();
                         rp.setGlobalProcessor(null);
                         ObjectName rpName = rp.getRpName();
                         if (getLog().isDebugEnabled()) {

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Tue Feb  
7 10:18:10 2012
@@ -33,6 +33,7 @@ import org.apache.coyote.OutputBuffer;
 import org.apache.coyote.Request;
 import org.apache.coyote.RequestInfo;
 import org.apache.coyote.Response;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.juli.logging.Log;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.buf.ByteChunk;
@@ -521,6 +522,14 @@ public abstract class AbstractAjpProcess
     }
 
 
+    @Override
+    public UpgradeInbound getUpgradeInbound() {
+        // Should never reach this code but in case we do...
+        throw new IllegalStateException(
+                sm.getString("ajpprocessor.httpupgrade.notsupported"));
+    }
+
+
     /**
      * Recycle the processor, ready for the next request which may be on the
      * same connection or a different connection.

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Tue Feb  7 
10:18:10 2012
@@ -17,6 +17,7 @@
 package org.apache.coyote.ajp;
 
 import org.apache.coyote.AbstractProtocol;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.tomcat.util.net.SocketWrapper;
 import org.apache.tomcat.util.res.StringManager;
 
@@ -86,5 +87,17 @@ public abstract class AbstractAjpProtoco
             connections.put(socket.getSocket(), processor);
             socket.setAsync(true);
         }
+
+        @Override
+        protected void upgradePoll(SocketWrapper<S> socket, P processor) {
+            // TODO Should never happen. ISE?
+        }
+
+        @Override
+        protected P createUpgradeProcessor(SocketWrapper<S> socket,
+                UpgradeInbound inbound) {
+            // 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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Tue 
Feb  7 10:18:10 2012
@@ -36,6 +36,7 @@ import org.apache.coyote.http11.filters.
 import org.apache.coyote.http11.filters.SavedRequestInputFilter;
 import org.apache.coyote.http11.filters.VoidInputFilter;
 import org.apache.coyote.http11.filters.VoidOutputFilter;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.juli.logging.Log;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.buf.Ascii;
@@ -60,6 +61,14 @@ public abstract class AbstractHttp11Proc
     protected static final StringManager sm =
         StringManager.getManager(Constants.Package);
 
+    /**
+     * Intended for use by the Upgrade sub-classes that have no need to
+     * initialise the request, response, etc.
+     */
+    protected AbstractHttp11Processor() {
+        // NOOP
+    }
+
     /*
      * Tracks how many internal filters are in the filter library so they
      * are skipped when looking for pluggable filters.
@@ -835,11 +844,6 @@ public abstract class AbstractHttp11Proc
             ((AtomicBoolean) param).set(asyncStateMachine.isAsyncTimingOut());
         } else if (actionCode == ActionCode.UPGRADE) {
             upgradeInbound = (UpgradeInbound) param;
-            upgradeInbound.setInputStream(
-                    new UpgradeInputStream(getInputBuffer()));
-            upgradeInbound.setUpgradeOutbound(
-                    new UpgradeOutbound(
-                            new UpgradeOutputStream(getOutputBuffer())));
             // Stop further HTTP output
             getOutputBuffer().finished = true;
         } else {
@@ -1066,8 +1070,7 @@ public abstract class AbstractHttp11Proc
         } else if (isAsync() || comet) {
             return SocketState.LONG;
         } else if (isUpgrade()) {
-            // May be data on the connection to process
-            return upgradeDispatch();
+            return SocketState.UPGRADING;
         } else {
             if (sendfileInProgress) {
                 return SocketState.SENDFILE;
@@ -1579,22 +1582,15 @@ public abstract class AbstractHttp11Proc
 
     @Override
     public SocketState upgradeDispatch() throws IOException {
-        SocketState result = upgradeInbound.onData();
-        AbstractInputBuffer<S> ib = getInputBuffer();
-        while (result == SocketState.UPGRADE) {
-            // Check to see if there is more data to process
-            if (ib.available() == 0) {
-                // Read any data that might be available
-                // Note: This will block for BIO regardless
-                ib.fill(false);
-            }
-            if (ib.available() == 0) {
-                // Still no data available, exit this loop
-                break;
-            }
-            result = upgradeInbound.onData();
-        }
-        return result;
+        // Should never reach this code but in case we do...
+        // TODO
+        throw new IOException(
+                sm.getString("TODO"));
+    }
+
+
+    public UpgradeInbound getUpgradeInbound() {
+        return upgradeInbound;
     }
 
 
@@ -1652,9 +1648,15 @@ public abstract class AbstractHttp11Proc
 
 
     public final void recycle() {
-        getInputBuffer().recycle();
-        getOutputBuffer().recycle();
-        asyncStateMachine.recycle();
+        if (getInputBuffer() != null) {
+            getInputBuffer().recycle();
+        }
+        if (getOutputBuffer() != null) {
+            getOutputBuffer().recycle();
+        }
+        if (asyncStateMachine != null) {
+            asyncStateMachine.recycle();
+        }
         upgradeInbound = null;
         remoteAddr = null;
         remoteHost = null;

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Tue Feb  
7 10:18:10 2012
@@ -57,6 +57,15 @@ public class Http11AprProcessor extends 
     // ----------------------------------------------------------- Constructors
 
 
+    /**
+     * Intended for use by the Upgrade sub-classes that have no need to
+     * initialise the request, response, etc.
+     */
+    protected Http11AprProcessor() {
+        // NOOP
+    }
+
+
     public Http11AprProcessor(int headerBufferSize, AprEndpoint endpoint,
             int maxTrailerSize) {
 

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Tue Feb  
7 10:18:10 2012
@@ -16,7 +16,11 @@
  */
 package org.apache.coyote.http11;
 
+import java.io.IOException;
+
 import org.apache.coyote.AbstractProtocol;
+import org.apache.coyote.http11.upgrade.UpgradeAprProcessor;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.net.AbstractEndpoint;
@@ -241,6 +245,14 @@ public class Http11AprProtocol extends A
         }
 
         @Override
+        protected void upgradePoll(SocketWrapper<Long> socket,
+                Http11AprProcessor processor) {
+            connections.put(socket.getSocket(), processor);
+            ((AprEndpoint) proto.endpoint).getPoller().add(
+                    socket.getSocket().longValue(), false);
+        }
+
+        @Override
         protected Http11AprProcessor createProcessor() {
             Http11AprProcessor processor = new Http11AprProcessor(
                     proto.getMaxHttpHeaderSize(), (AprEndpoint)proto.endpoint,
@@ -263,5 +275,12 @@ public class Http11AprProtocol extends A
             register(processor);
             return processor;
         }
+
+        @Override
+        protected Http11AprProcessor createUpgradeProcessor(
+                SocketWrapper<Long> socket, UpgradeInbound inbound)
+                throws IOException {
+            return new UpgradeAprProcessor(socket, inbound);
+        }
     }
 }

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Tue Feb  
7 10:18:10 2012
@@ -62,6 +62,15 @@ public class Http11NioProcessor extends 
     // ----------------------------------------------------------- Constructors
 
 
+    /**
+     * Intended for use by the Upgrade sub-classes that have no need to
+     * initialise the request, response, etc.
+     */
+    protected Http11NioProcessor() {
+        // NOOP
+    }
+
+
     public Http11NioProcessor(int maxHttpHeaderSize, NioEndpoint endpoint,
             int maxTrailerSize) {
 

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Tue Feb  
7 10:18:10 2012
@@ -16,11 +16,14 @@
  */
 package org.apache.coyote.http11;
 
+import java.io.IOException;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.SocketChannel;
 import java.util.Iterator;
 
 import org.apache.coyote.AbstractProtocol;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
+import org.apache.coyote.http11.upgrade.UpgradeNioProcessor;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.net.AbstractEndpoint;
@@ -279,5 +282,25 @@ public class Http11NioProtocol extends A
             register(processor);
             return processor;
         }
+
+        @Override
+        protected Http11NioProcessor createUpgradeProcessor(
+                SocketWrapper<NioChannel> socket, UpgradeInbound inbound)
+                throws IOException {
+            return new UpgradeNioProcessor(socket, inbound,
+                    ((Http11NioProtocol) 
getProtocol()).getEndpoint().getSelectorPool());
+        }
+
+        @Override
+        protected void upgradePoll(SocketWrapper<NioChannel> socket,
+                Http11NioProcessor processor) {
+            connections.put(socket.getSocket(), processor);
+
+            SelectionKey key = socket.getSocket().getIOChannel().keyFor(
+                    socket.getSocket().getPoller().getSelector());
+            key.interestOps(SelectionKey.OP_READ);
+            ((KeyAttachment) socket).interestOps(
+                    SelectionKey.OP_READ);
+        }
     }
 }

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Tue Feb  7 
10:18:10 2012
@@ -49,6 +49,15 @@ public class Http11Processor extends Abs
    // ------------------------------------------------------------ Constructor
 
 
+    /**
+     * Intended for use by the Upgrade sub-classes that have no need to
+     * initialise the request, response, etc.
+     */
+    protected Http11Processor() {
+        // NOOP
+    }
+
+
     public Http11Processor(int headerBufferSize, JIoEndpoint endpoint,
             int maxTrailerSize) {
 

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=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java Tue Feb  7 
10:18:10 2012
@@ -16,9 +16,12 @@
  */
 package org.apache.coyote.http11;
 
+import java.io.IOException;
 import java.net.Socket;
 
 import org.apache.coyote.AbstractProtocol;
+import org.apache.coyote.http11.upgrade.UpgradeBioProcessor;
+import org.apache.coyote.http11.upgrade.UpgradeInbound;
 import org.apache.juli.logging.Log;
 import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.JIoEndpoint;
@@ -180,5 +183,18 @@ public class Http11Protocol extends Abst
             register(processor);
             return processor;
         }
+
+        @Override
+        protected Http11Processor createUpgradeProcessor(
+                SocketWrapper<Socket> socket, UpgradeInbound inbound)
+                throws IOException {
+            return new UpgradeBioProcessor(socket, inbound);
+        }
+
+        @Override
+        protected void upgradePoll(SocketWrapper<Socket> socket,
+                Http11Processor processor) {
+            connections.put(socket.getSocket(), processor);
+        }
     }
 }

Added: 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java?rev=1241410&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java 
(added)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java 
Tue Feb  7 10:18:10 2012
@@ -0,0 +1,123 @@
+/*
+ *  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.coyote.http11.upgrade;
+
+import java.io.IOException;
+
+import org.apache.coyote.http11.Http11AprProcessor;
+import org.apache.tomcat.jni.Socket;
+import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
+import org.apache.tomcat.util.net.SocketStatus;
+import org.apache.tomcat.util.net.SocketWrapper;
+
+/**
+ * Implementation note: The need to extend Http11Processor could probably be
+ * removed if the Processor interface was expanded to cover all of the methods
+ * required by the AbstractProtocol. That would simplify the code and further
+ * reduce the size of instances of this class.
+ */
+public class UpgradeAprProcessor extends Http11AprProcessor
+        implements UpgradeProcessor {
+
+    long socket;
+
+    public UpgradeAprProcessor(SocketWrapper<Long> wrapper,
+            UpgradeInbound inbound) {
+        this.socket = wrapper.getSocket().longValue();
+
+        this.upgradeInbound = inbound;
+        upgradeInbound.setUpgradeProcessor(this);
+        upgradeInbound.setUpgradeOutbound(new UpgradeOutbound(this));
+        // Remove the default - no need for it here
+        this.compressableMimeTypes = null;
+    }
+
+
+    @Override
+    public SocketState upgradeDispatch() throws IOException {
+        return upgradeInbound.onData();
+    }
+
+
+    /*
+     * Output methods
+     */
+    @Override
+    public void flush() throws IOException {
+        // NOOP
+    }
+
+
+    @Override
+    public void write(int b) throws IOException {
+        Socket.send(socket, new byte[] {(byte) b}, 0, 1);
+    }
+
+
+    /*
+     * Input methods
+     */
+    @Override
+    public int read() throws IOException {
+        byte[] bytes = new byte[1];
+        Socket.recv(socket, bytes, 0, 1);
+        return bytes[0];
+    }
+
+
+    @Override
+    public int read(byte[] bytes) throws IOException {
+        return Socket.recv(socket, bytes, 0, bytes.length);
+    }
+
+
+    /*
+     * None of the following NO-OP methods are strictly necessary - assuming 
the
+     * there are no bugs in the connector code that cause upgraded connections
+     * to be treated as Http11, Comet or Async. These NO-OP methods are here 
for
+     * safety and to aid debugging during development.
+     */
+
+    @Override
+    public SocketState event(SocketStatus status) throws IOException {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState process(SocketWrapper<Long> socketWrapper)
+            throws IOException {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState asyncDispatch(SocketStatus status) {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState asyncPostProcess() {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+}

Added: 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java?rev=1241410&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java 
(added)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java 
Tue Feb  7 10:18:10 2012
@@ -0,0 +1,123 @@
+/*
+ *  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.coyote.http11.upgrade;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import org.apache.coyote.http11.Http11Processor;
+import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
+import org.apache.tomcat.util.net.SocketStatus;
+import org.apache.tomcat.util.net.SocketWrapper;
+
+/**
+ * Implementation note: The need to extend Http11Processor could probably be
+ * removed if the Processor interface was expanded to cover all of the methods
+ * required by the AbstractProtocol. That would simplify the code and further
+ * reduce the size of instances of this class.
+ */
+public class UpgradeBioProcessor extends Http11Processor
+        implements UpgradeProcessor{
+
+    private InputStream inputStream;
+    private OutputStream outputStream;
+
+    public UpgradeBioProcessor(SocketWrapper<Socket> wrapper,
+            UpgradeInbound inbound) throws IOException {
+        this.inputStream = wrapper.getSocket().getInputStream();
+        this.outputStream = wrapper.getSocket().getOutputStream();
+        this.upgradeInbound = inbound;
+        upgradeInbound.setUpgradeProcessor(this);
+        upgradeInbound.setUpgradeOutbound(new UpgradeOutbound(this));
+        // Remove the default - no need for it here
+        this.compressableMimeTypes = null;
+    }
+
+
+    @Override
+    public SocketState upgradeDispatch() throws IOException {
+        return upgradeInbound.onData();
+    }
+
+
+    /*
+     * Output methods
+     */
+    @Override
+    public void flush() throws IOException {
+        outputStream.flush();
+    }
+
+
+    @Override
+    public void write(int b) throws IOException {
+        outputStream.write(b);
+    }
+
+
+    /*
+     * Input methods
+     */
+    @Override
+    public int read() throws IOException {
+        return inputStream.read();
+    }
+
+
+    @Override
+    public int read(byte[] bytes) throws IOException {
+        return inputStream.read(bytes);
+    }
+
+
+    /*
+     * None of the following NO-OP methods are strictly necessary - assuming 
the
+     * there are no bugs in the connector code that cause upgraded connections
+     * to be treated as Http11, Comet or Async. These NO-OP methods are here 
for
+     * safety and to aid debugging during development.
+     */
+
+    @Override
+    public SocketState event(SocketStatus status) throws IOException {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState process(SocketWrapper<Socket> socketWrapper)
+            throws IOException {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState asyncDispatch(SocketStatus status) {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState asyncPostProcess() {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+}

Copied: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java 
(from r1241407, tomcat/trunk/java/org/apache/coyote/http11/UpgradeInbound.java)
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java?p2=tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java&p1=tomcat/trunk/java/org/apache/coyote/http11/UpgradeInbound.java&r1=1241407&r2=1241410&rev=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/UpgradeInbound.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java Tue 
Feb  7 10:18:10 2012
@@ -14,22 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.coyote.http11;
+package org.apache.coyote.http11.upgrade;
 
 import java.io.IOException;
-import java.io.InputStream;
 
 import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
 
 /**
  * Receives notification that there is data to be read on the upgraded
  * connection and processes it.
- *
- * TODO: Move this to a more appropriate package (TBD).
  */
 public interface UpgradeInbound {
 
-    void setInputStream(InputStream is);
+    void setUpgradeProcessor(UpgradeProcessor processor);
 
     SocketState onData() throws IOException;
 

Added: 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java?rev=1241410&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java 
(added)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java 
Tue Feb  7 10:18:10 2012
@@ -0,0 +1,228 @@
+/*
+ *  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.coyote.http11.upgrade;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.channels.Selector;
+
+import org.apache.coyote.http11.Http11NioProcessor;
+import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
+import org.apache.tomcat.util.net.NioChannel;
+import org.apache.tomcat.util.net.NioEndpoint;
+import org.apache.tomcat.util.net.NioSelectorPool;
+import org.apache.tomcat.util.net.SocketStatus;
+import org.apache.tomcat.util.net.SocketWrapper;
+
+/**
+ * Implementation note: The need to extend Http11Processor could probably be
+ * removed if the Processor interface was expanded to cover all of the methods
+ * required by the AbstractProtocol. That would simplify the code and further
+ * reduce the size of instances of this class.
+ */
+public class UpgradeNioProcessor extends Http11NioProcessor
+        implements UpgradeProcessor {
+
+    private NioChannel nioChannel;
+    private NioSelectorPool pool;
+
+    public UpgradeNioProcessor(SocketWrapper<NioChannel> wrapper,
+            UpgradeInbound inbound, NioSelectorPool pool) {
+        this.nioChannel = wrapper.getSocket();
+        this.pool = pool;
+
+        this.upgradeInbound = inbound;
+        upgradeInbound.setUpgradeProcessor(this);
+        upgradeInbound.setUpgradeOutbound(new UpgradeOutbound(this));
+        // Remove the default - no need for it here
+        this.compressableMimeTypes = null;
+    }
+
+
+    @Override
+    public SocketState upgradeDispatch() throws IOException {
+        return upgradeInbound.onData();
+    }
+
+
+    /*
+     * Output methods
+     */
+    @Override
+    public void flush() throws IOException {
+        NioEndpoint.KeyAttachment att =
+                (NioEndpoint.KeyAttachment) nioChannel.getAttachment(false);
+        if (att == null) {
+            throw new IOException("Key must be cancelled");
+        }
+        long writeTimeout = att.getTimeout();
+        Selector selector = null;
+        try {
+            selector = pool.get();
+        } catch ( IOException x ) {
+            //ignore
+        }
+        try {
+            do {
+                if (nioChannel.flush(true, selector, writeTimeout)) {
+                    break;
+                }
+            } while (true);
+        } finally {
+            if (selector != null) {
+                pool.put(selector);
+            }
+        }
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        writeToSocket(new byte[] {(byte) b});
+    }
+
+    /*
+     * Input methods
+     */
+    @Override
+    public int read() throws IOException {
+        byte[] bytes = new byte[1];
+        readSocket(true, bytes, 0, 1);
+        return bytes[0];
+    }
+
+    @Override
+    public int read(byte[] bytes) throws IOException {
+        return readSocket(true, bytes, 0, bytes.length);
+    }
+
+
+    /*
+     * Adapted from the NioInputBuffer.
+     */
+    private int readSocket(boolean block, byte[] bytes, int offset, int len)
+            throws IOException {
+
+        int nRead = 0;
+        nioChannel.getBufHandler().getReadBuffer().clear();
+        nioChannel.getBufHandler().getReadBuffer().limit(len);
+        if (block) {
+            Selector selector = null;
+            try {
+                selector = pool.get();
+            } catch ( IOException x ) {
+                // Ignore
+            }
+            try {
+                NioEndpoint.KeyAttachment att =
+                        (NioEndpoint.KeyAttachment) 
nioChannel.getAttachment(false);
+                if (att == null) {
+                    throw new IOException("Key must be cancelled.");
+                }
+                nRead = pool.read(nioChannel.getBufHandler().getReadBuffer(),
+                        nioChannel, selector, att.getTimeout());
+            } catch (EOFException eof) {
+                nRead = -1;
+            } finally {
+                if (selector != null) {
+                    pool.put(selector);
+                }
+            }
+        } else {
+            nRead = 
nioChannel.read(nioChannel.getBufHandler().getReadBuffer());
+        }
+        if (nRead > 0) {
+            nioChannel.getBufHandler().getReadBuffer().flip();
+            nioChannel.getBufHandler().getReadBuffer().limit(nRead);
+            nioChannel.getBufHandler().getReadBuffer().get(bytes, offset, 
nRead);
+            return nRead;
+        } else if (nRead == -1) {
+            //return false;
+            throw new EOFException(sm.getString("iib.eof.error"));
+        } else {
+            return 0;
+        }
+    }
+
+
+    /*
+     * Adapted from the NioOutputBuffer
+     */
+    private synchronized int writeToSocket(byte[] bytes) throws IOException {
+
+        nioChannel.getBufHandler().getWriteBuffer().clear();
+        nioChannel.getBufHandler().getWriteBuffer().put(bytes);
+        nioChannel.getBufHandler().getWriteBuffer().flip();
+
+        int written = 0;
+        NioEndpoint.KeyAttachment att =
+                (NioEndpoint.KeyAttachment) nioChannel.getAttachment(false);
+        if (att == null) {
+            throw new IOException("Key must be cancelled");
+        }
+        long writeTimeout = att.getTimeout();
+        Selector selector = null;
+        try {
+            selector = pool.get();
+        } catch ( IOException x ) {
+            //ignore
+        }
+        try {
+            written = pool.write(nioChannel.getBufHandler().getWriteBuffer(),
+                    nioChannel, selector, writeTimeout, true);
+        } finally {
+            if (selector != null) {
+                pool.put(selector);
+            }
+        }
+        return written;
+    }
+
+    /*
+     * None of the following NO-OP methods are strictly necessary - assuming 
the
+     * there are no bugs in the connector code that cause upgraded connections
+     * to be treated as Http11, Comet or Async. These NO-OP methods are here 
for
+     * safety and to aid debugging during development.
+     */
+
+    @Override
+    public SocketState event(SocketStatus status) throws IOException {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState process(SocketWrapper<NioChannel> socketWrapper)
+            throws IOException {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState asyncDispatch(SocketStatus status) {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+
+
+    @Override
+    public SocketState asyncPostProcess() {
+        // TODO Log an error
+        return SocketState.CLOSED;
+    }
+}

Copied: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeOutbound.java 
(from r1241407, tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java)
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeOutbound.java?p2=tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeOutbound.java&p1=tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java&r1=1241407&r2=1241410&rev=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeOutbound.java Tue 
Feb  7 10:18:10 2012
@@ -14,33 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.coyote.http11;
+package org.apache.coyote.http11.upgrade;
 
 import java.io.IOException;
 import java.io.OutputStream;
 
+
 /**
  * Allows data to be written to the upgraded connection.
  *
- * TODO: Move this to a more appropriate package (TBD).
- *
  * TODO: Override more methods for efficiency.
  */
 public class UpgradeOutbound extends OutputStream {
 
     @Override
     public void flush() throws IOException {
-        os.flush();
+        processor.flush();
     }
 
-    private OutputStream os;
+    private UpgradeProcessor processor;
 
-    public UpgradeOutbound(OutputStream os) {
-        this.os = os;
+    public UpgradeOutbound(UpgradeProcessor processor) {
+        this.processor = processor;
     }
 
     @Override
     public void write(int b) throws IOException {
-        os.write(b);
+        processor.write(b);
     }
 }

Added: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java?rev=1241410&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java 
(added)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java 
Tue Feb  7 10:18:10 2012
@@ -0,0 +1,30 @@
+/*
+ *  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.coyote.http11.upgrade;
+
+import java.io.IOException;
+
+public interface UpgradeProcessor {
+
+    // Output methods
+    public void flush() throws IOException;
+    public void write(int b) throws IOException;
+
+    // Input methods
+    public int read() throws IOException;
+    public int read(byte[] bytes) throws IOException;
+}

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Tue Feb  
7 10:18:10 2012
@@ -55,7 +55,7 @@ public abstract class AbstractEndpoint {
         public enum SocketState {
             // TODO Add a new state to the AsyncStateMachine and remove
             //      ASYNC_END (if possible)
-            OPEN, CLOSED, LONG, ASYNC_END, SENDFILE, UPGRADE
+            OPEN, CLOSED, LONG, ASYNC_END, SENDFILE, UPGRADING, UPGRADED
         }
 
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=1241410&r1=1241409&r2=1241410&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Tue Feb  7 
10:18:10 2012
@@ -320,7 +320,9 @@ public class JIoEndpoint extends Abstrac
                         } catch (IOException e) {
                             // Ignore
                         }
-                    } else if (state == SocketState.OPEN){
+                    } else if (state == SocketState.OPEN ||
+                            state == SocketState.UPGRADING  ||
+                            state == SocketState.UPGRADED){
                         socket.setKeptAlive(true);
                         socket.access();
                         launch = true;



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to