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/13 20:18:08 UTC
svn commit: r1679255 - in /tomcat/trunk/java/org/apache/coyote/http2:
AbstractStream.java Constants.java Http2UpgradeHandler.java
LocalStrings.properties
Author: markt
Date: Wed May 13 18:18:07 2015
New Revision: 1679255
URL: http://svn.apache.org/r1679255
Log:
Process priority frames
Added:
tomcat/trunk/java/org/apache/coyote/http2/Constants.java (with props)
Modified:
tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.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/http2/AbstractStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java?rev=1679255&r1=1679254&r2=1679255&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java Wed May 13 18:18:07 2015
@@ -20,18 +20,23 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.res.StringManager;
+
/**
* Used to managed prioritisation.
*/
abstract class AbstractStream {
- private static final int DEFAULT_WEIGHT = 16;
+ private static final Log log = LogFactory.getLog(AbstractStream.class);
+ private static final StringManager sm = StringManager.getManager(AbstractStream.class);
private final Integer identifier;
private volatile AbstractStream parentStream = null;
private final Set<AbstractStream> childStreams = new HashSet<>();
- private volatile int weight = DEFAULT_WEIGHT;
+ private volatile int weight = Constants.DEFAULT_WEIGHT;
public Integer getIdentifier() {
return identifier;
@@ -43,7 +48,12 @@ abstract class AbstractStream {
}
- public void rePrioritise(Stream parent, boolean exclusive, int weight) {
+ public void rePrioritise(AbstractStream parent, boolean exclusive, int weight) {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("abstractStream.reprioritisation.debug", identifier,
+ Boolean.toString(exclusive), parent.getIdentifier(), Integer.toString(weight)));
+ }
+
// Check if new parent is a descendant of this stream
if (isDescendant(parent)) {
parent.detachFromParent();
Added: tomcat/trunk/java/org/apache/coyote/http2/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Constants.java?rev=1679255&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Constants.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http2/Constants.java Wed May 13 18:18:07 2015
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+public class Constants {
+
+ // Prioritisation
+ public static final int DEFAULT_WEIGHT = 16;
+}
Propchange: tomcat/trunk/java/org/apache/coyote/http2/Constants.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=1679255&r1=1679254&r2=1679255&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed May 13 18:18:07 2015
@@ -52,6 +52,7 @@ public class Http2UpgradeHandler extends
private static final Integer STREAM_ID_ZERO = Integer.valueOf(0);
+ private static final int FRAME_TYPE_PRIORITY = 2;
private static final int FRAME_TYPE_SETTINGS = 4;
private static final int FRAME_TYPE_WINDOW_UPDATE = 8;
@@ -67,6 +68,7 @@ public class Http2UpgradeHandler extends
private final ConnectionSettings remoteSettings = new ConnectionSettings();
private volatile long flowControlWindowSize = ConnectionSettings.DEFAULT_WINDOW_SIZE;
+ private volatile int maxRemoteStreamId = 0;
private final Map<Integer,Stream> streams = new HashMap<>();
@@ -186,6 +188,9 @@ public class Http2UpgradeHandler extends
int payloadSize = getPayloadSize(streamId, frameHeader);
switch (frameType) {
+ case FRAME_TYPE_PRIORITY:
+ processFramePriority(flags, streamId, payloadSize);
+ break;
case FRAME_TYPE_SETTINGS:
processFrameSettings(flags, streamId, payloadSize);
break;
@@ -200,6 +205,51 @@ public class Http2UpgradeHandler extends
}
+ private void processFramePriority(int flags, int streamId, int payloadSize) throws IOException {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("upgradeHandler.processFrame",
+ Integer.toString(FRAME_TYPE_PRIORITY), Integer.toString(flags),
+ Integer.toString(streamId), Integer.toString(payloadSize)));
+ }
+ // Validate the frame
+ if (streamId == 0) {
+ throw new Http2Exception(sm.getString("upgradeHandler.processFramePriority.invalidStream"),
+ 0, Http2Exception.PROTOCOL_ERROR);
+ }
+ if (payloadSize != 5) {
+ throw new Http2Exception(sm.getString("upgradeHandler.processFramePriority.invalidPayloadSize",
+ Integer.toString(payloadSize)), streamId, Http2Exception.FRAME_SIZE_ERROR);
+ }
+
+ byte[] payload = new byte[5];
+ readFully(payload);
+
+ boolean exclusive = (payload[0] & 0x80) > 0;
+ int parentStreamId = ((payload[0] & 0x7F) << 24) + ((payload[1] & 0xFF) << 16) +
+ ((payload[2] & 0xFF) << 8) + (payload[3] & 0xFF);
+ int weight = (payload[4] & 0xFF) + 1;
+
+ Stream stream = getStream(streamId);
+ AbstractStream parentStream;
+ if (parentStreamId == 0) {
+ parentStream = this;
+ } else {
+ parentStream = getStream(parentStreamId);
+ if (parentStream == null) {
+ parentStream = this;
+ weight = Constants.DEFAULT_WEIGHT;
+ exclusive = false;
+ }
+ }
+
+ if (stream == null) {
+ // Old stream. Already closed and dropped from the stream map.
+ } else {
+ stream.rePrioritise(parentStream, exclusive, weight);
+ }
+ }
+
+
private void processFrameSettings(int flags, int streamId, int payloadSize) throws IOException {
if (log.isDebugEnabled()) {
log.debug(sm.getString("upgradeHandler.processFrame",
@@ -276,19 +326,20 @@ public class Http2UpgradeHandler extends
if (streamId == 0) {
flowControlWindowSize += windowSizeIncrement;
} else {
- Integer key = Integer.valueOf(streamId);
- Stream stream = streams.get(key);
+ Stream stream = getStream(streamId);
if (stream == null) {
- stream = new Stream(key, this);
+ // Old stream already closed.
+ // Ignore
+ } else {
+ stream.incrementWindowSize(windowSizeIncrement);
}
- stream.incrementWindowSize(windowSizeIncrement);
}
}
private void processFrameUnknown(int streamId, int type, int payloadSize) throws IOException {
// Swallow the payload
- log.info("Swallowing [" + payloadSize + "] bytes of unknown frame type + [" + type +
+ log.info("Swallowing [" + payloadSize + "] bytes of unknown frame type [" + type +
"] from stream [" + streamId + "]");
swallowPayload(payloadSize);
}
@@ -423,6 +474,21 @@ public class Http2UpgradeHandler extends
}
}
+
+ private Stream getStream(int streamId) {
+ Integer key = Integer.valueOf(streamId);
+
+ if (streamId > maxRemoteStreamId) {
+ // Must be a new stream
+ maxRemoteStreamId = streamId;
+ Stream stream = new Stream(key, this);
+ streams.put(key, stream);
+ return stream;
+ } else {
+ return streams.get(key);
+ }
+ }
+
private void close() {
try {
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=1679255&r1=1679254&r2=1679255&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Wed May 13 18:18:07 2015
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+abstractStream.reprioritisation.debug=Reprioritising stream [{0}] with exclusive [{1}], parent [{2}] and weight [{3}]
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}]
@@ -33,6 +34,8 @@ upgradeHandler.connectionError=An error
upgradeHandler.payloadTooBig=The payload is [{0}] bytes long but the maximum frame size is [{1}]
upgradeHandler.processFrame=Processing frame of type [{0}] for stream [{2}] with flags [{1}] and payload size [{3}]
upgradeHandler.processFrame.ioerror=An I/O error occurred while reading an incoming HTTP/2 frame
+upgradeHandler.processFramePriority.invalidPayloadSize=Settings frame received with an invalid payload size of [{0}] (should be 5)
+upgradeHandler.processFramePriority.invalidStream=Settings frame received for stream [0]
upgradeHandler.processFrameSettings.ackWithNonZeroPayload=Settings frame received with the ACK flag set and payload present
upgradeHandler.processFrameSettings.invalidPayloadSize=Settings frame received with a payload size of [{0}] which is not a multiple of 6
upgradeHandler.processFrameSettings.invalidStream=Settings frame received for stream [{0}]
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org