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: [email protected]
For additional commands, e-mail: [email protected]