Author: markt
Date: Tue May 12 20:16:58 2015
New Revision: 1679047

URL: http://svn.apache.org/r1679047
Log:
Refactor connection preface handling into a separate class.

Added:
    tomcat/trunk/java/org/apache/coyote/http2/ConnectionPrefaceParser.java   
(with props)
Modified:
    tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
    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/http11/AbstractHttp11Protocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1679047&r1=1679046&r2=1679047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Tue 
May 12 20:16:58 2015
@@ -37,6 +37,7 @@ import org.apache.coyote.UpgradeProtocol
 import org.apache.coyote.http11.upgrade.InternalHttpUpgradeHandler;
 import org.apache.coyote.http11.upgrade.UpgradeProcessorExternal;
 import org.apache.coyote.http11.upgrade.UpgradeProcessorInternal;
+import org.apache.coyote.http2.Http2Protocol;
 import org.apache.tomcat.util.net.AbstractEndpoint;
 import org.apache.tomcat.util.net.SSLHostConfig;
 import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -52,7 +53,7 @@ public abstract class AbstractHttp11Prot
         //       This is disabled by default otherwise it will break the
         //       APR/native connector with clients that support h2 with ALPN
         //       (because the Http2Protocol is only stubbed out)
-        //addUpgradeProtocol(new Http2Protocol());
+        addUpgradeProtocol(new Http2Protocol());
     }
 
 

Added: tomcat/trunk/java/org/apache/coyote/http2/ConnectionPrefaceParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/ConnectionPrefaceParser.java?rev=1679047&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/ConnectionPrefaceParser.java 
(added)
+++ tomcat/trunk/java/org/apache/coyote/http2/ConnectionPrefaceParser.java Tue 
May 12 20:16:58 2015
@@ -0,0 +1,77 @@
+/*
+ *  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.http2;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.net.SocketWrapperBase;
+import org.apache.tomcat.util.res.StringManager;
+
+/**
+ * Parser for the initial part of the client connection preface received by the
+ * server.
+ */
+public class ConnectionPrefaceParser {
+
+    private static final Log log = 
LogFactory.getLog(ConnectionPrefaceParser.class);
+    private static final StringManager sm = 
StringManager.getManager(ConnectionPrefaceParser.class);
+
+    private static final byte[] EXPECTED =
+            "PRI * 
HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1);
+
+    private volatile byte[] data = new byte[EXPECTED.length];
+    private volatile int pos = 0;
+    private volatile boolean error = false;
+
+
+    public boolean parse(SocketWrapperBase<?> socketWrapper) {
+        int read = 0;
+        try {
+            read = socketWrapper.read(false, data, pos, EXPECTED.length - pos);
+        } catch (IOException ioe) {
+            log.error(sm.getString("connectionPrefaceParser.ioError"), ioe);
+            error = true;
+            return false;
+        }
+
+        if (read == -1) {
+            log.error(sm.getString("connectionPrefaceParser.eos", 
Integer.toString(pos)));
+            error = true;
+            return false;
+        }
+
+        for (int i = pos; i < (pos + read); i++) {
+            if (data[i] != EXPECTED[i]) {
+                log.error(sm.getString("connectionPrefaceParser.mismatch",
+                        new String(data, StandardCharsets.ISO_8859_1)));
+                error = true;
+                return false;
+            }
+        }
+
+        pos += read;
+        return pos == EXPECTED.length;
+    }
+
+
+    public boolean isError() {
+        return error;
+    }
+}

Propchange: 
tomcat/trunk/java/org/apache/coyote/http2/ConnectionPrefaceParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=1679047&r1=1679046&r2=1679047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Tue May 
12 20:16:58 2015
@@ -17,7 +17,6 @@
 package org.apache.coyote.http2;
 
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 
 import javax.servlet.http.WebConnection;
 
@@ -43,21 +42,14 @@ public class Http2UpgradeHandler impleme
 
     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 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 ConnectionPrefaceParser connectionPrefaceParser =
+            new ConnectionPrefaceParser();
     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
     public void init(WebConnection unused) {
         initialized = true;
@@ -79,17 +71,21 @@ public class Http2UpgradeHandler impleme
 
         switch(status) {
         case OPEN_READ:
-            if (clientPrefaceStartBytesRead < 
CLIENT_PREFACE_START_EXPECTED.length) {
-                readClientPrefaceStart();
-                if (clientPrefaceStartBytesRead == -1) {
-                    // A fatal (for this connection) error occurred
-                    close();
-                    return SocketState.CLOSED;
+            // Gets set to null once the connection preface has been
+            // successfully parsed.
+            if (connectionPrefaceParser != null) {
+                if (!connectionPrefaceParser.parse(socketWrapper)) {
+                    if (connectionPrefaceParser.isError()) {
+                        close();
+                        return SocketState.CLOSED;
+                    } else {
+                        // Incomplete
+                        return SocketState.LONG;
+                    }
                 }
-                // Preface start has been read and validated. No need to keep 
this
-                // buffer hanging around in memory.
-                clientPrefaceStartData = null;
             }
+            connectionPrefaceParser = null;
+
             // TODO process frames
             break;
         case OPEN_WRITE:
@@ -133,34 +129,4 @@ public class Http2UpgradeHandler impleme
             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=1679047&r1=1679046&r2=1679047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Tue May 
12 20:16:58 2015
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+connectionPrefaceParser.eos=Unexpected end of stream while reading opening 
client preface byte sequence. Only [{0}] bytes read.
+connectionPrefaceParser.ioError=Failed to read opening client preface byte 
sequence
+connectionPrefaceParser.mismatch=An unexpected byte sequence was received at 
the start of the client preface [{0}]
+
 hpack.integerEncodedOverTooManyOctets=HPACK variable length integer encoded 
over too many octets, max is {0}
 
 hpackdecoder.zeroNotValidHeaderTableIndex=Zero is not a valid header table 
index
@@ -20,6 +24,4 @@ hpackdecoder.zeroNotValidHeaderTableInde
 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
+upgradeHandler.unexpectedStatus=An unexpected value of status ([{0}]) was 
passed to this method
\ No newline at end of file



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

Reply via email to