You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/05/12 14:02:16 UTC

svn commit: r1678919 - in /tomcat/trunk/java/org/apache/coyote/http2: Http2UpgradeHandler.java LocalStrings.properties

Author: markt
Date: Tue May 12 12:02:15 2015
New Revision: 1678919

URL: http://svn.apache.org/r1678919
Log:
Add some code to read & validate the byte sequence at the start of the client preface.

Modified:
    tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
    tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties

Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1678919&r1=1678918&r2=1678919&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Tue May 12 12:02:15 2015
@@ -17,6 +17,7 @@
 package org.apache.coyote.http2;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 import javax.servlet.http.WebConnection;
 
@@ -26,18 +27,38 @@ import org.apache.juli.logging.LogFactor
 import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
 import org.apache.tomcat.util.net.SocketStatus;
 import org.apache.tomcat.util.net.SocketWrapperBase;
+import org.apache.tomcat.util.res.StringManager;
 
 /**
  * This represents an HTTP/2 connection from a client to Tomcat. It is designed
  * on the basis that there will never be more than one thread performing I/O at
  * a time.
+ * <br>
+ * Currently, it appears that Firefox needs to be configured with
+ * network.http.spdy.enforce-tls-profile=false in order for FireFox to be able
+ * to connect. I'm not sure what is going wrong here since as far as I have
+ * found that only requires TLSv1.2. openssl s_client and Wireshark confirm that
+ * TLSv1.2 is used and it still doesn't work if I limit the HTTPS connector to
+ * TLSv1.2. There looks to be some other restriction being applied.
+ *
  */
 public class Http2UpgradeHandler implements InternalHttpUpgradeHandler {
 
     private static final Log log = LogFactory.getLog(Http2UpgradeHandler.class);
+    private static final StringManager sm = StringManager.getManager(Http2UpgradeHandler.class);
+    private static final byte[] CLIENT_PREFACE_START_EXPECTED;
 
-    private SocketWrapperBase<?> socketWrapper;
+    private volatile SocketWrapperBase<?> socketWrapper;
     private volatile boolean initialized = false;
+    private volatile byte[] clientPrefaceStartData = new byte[CLIENT_PREFACE_START_EXPECTED.length];
+    private volatile int clientPrefaceStartBytesRead = 0;
+    private volatile boolean readFirstFrame = false;
+
+
+    static {
+        CLIENT_PREFACE_START_EXPECTED =
+                "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1);
+    }
 
 
     @Override
@@ -59,16 +80,22 @@ public class Http2UpgradeHandler impleme
             init(null);
         }
 
+        if (clientPrefaceStartBytesRead < CLIENT_PREFACE_START_EXPECTED.length) {
+            readClientPrefaceStart();
+            if (clientPrefaceStartBytesRead == -1) {
+                // A fatal (for this connection) error occurred
+                close();
+                return SocketState.CLOSED;
+            }
+            // Preface start has been read and validated. No need to keep this
+            // buffer hanging around in memory.
+            clientPrefaceStartData = null;
+        }
+
         // TODO This is for debug purposes to make sure ALPN is working.
         log.fatal("TODO: Handle SocketStatus: " + status);
 
-        try {
-            socketWrapper.close();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-
+        close();
         return SocketState.CLOSED;
     }
 
@@ -77,4 +104,43 @@ public class Http2UpgradeHandler impleme
     public void destroy() {
         // NO-OP
     }
+
+
+    private void close() {
+        try {
+            socketWrapper.close();
+        } catch (IOException ioe) {
+            log.debug(sm.getString("upgradeHandler.socketCloseFailed"), ioe);
+        }
+    }
+
+
+    private void readClientPrefaceStart() {
+        int read = 0;
+        try {
+            read = socketWrapper.read(false, clientPrefaceStartData, clientPrefaceStartBytesRead,
+                    clientPrefaceStartData.length - clientPrefaceStartBytesRead);
+        } catch (IOException ioe) {
+            log.error(sm.getString("upgradeHandler.prefaceErrorIo"), ioe);
+            clientPrefaceStartBytesRead = -1;
+            return;
+        }
+
+        if (read == -1) {
+            log.error(sm.getString("upgradeHandler.prefaceErrorEos",
+                    Integer.toString(clientPrefaceStartBytesRead)));
+            clientPrefaceStartBytesRead = -1;
+            return;
+        }
+
+        for (int i = clientPrefaceStartBytesRead; i < (clientPrefaceStartBytesRead + read); i++) {
+            if (clientPrefaceStartData[i] != CLIENT_PREFACE_START_EXPECTED[i]) {
+                log.error(sm.getString("upgradeHandler.prefaceErrorMismatch",
+                        new String(clientPrefaceStartData, StandardCharsets.ISO_8859_1)));
+                clientPrefaceStartBytesRead = -1;
+                return;
+            }
+        }
+        clientPrefaceStartBytesRead += read;
+    }
 }

Modified: tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties?rev=1678919&r1=1678918&r2=1678919&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Tue May 12 12:02:15 2015
@@ -17,4 +17,9 @@ hpack.integerEncodedOverTooManyOctets=HP
 
 hpackdecoder.zeroNotValidHeaderTableIndex=Zero is not a valid header table index
 
-hpackhuffman.huffmanEncodedHpackValueDidNotEndWithEOS=Huffman encoded value in HPACK headers did not end with EOS padding
\ No newline at end of file
+hpackhuffman.huffmanEncodedHpackValueDidNotEndWithEOS=Huffman encoded value in HPACK headers did not end with EOS padding
+
+upgradeHandler.socketCloseFailed=Error closing socket
+upgradeHandler.prefaceErrorEos=Unexpected end of stream while reading opening client preface byte sequence. Only [{0}] bytes read.
+upgradeHandler.prefaceErrorIo=Failed to read opening client preface byte sequence
+upgradeHandler.prefaceErrorMismatch=An unexpected byte sequence was received at the start of the client preface [{0}]
\ No newline at end of file



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