144 lines
4.9 KiB
Diff
144 lines
4.9 KiB
Diff
--- tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:18 1852701
|
|
+++ tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:22 1852702
|
|
@@ -54,6 +54,8 @@
|
|
// This default is defined by the HTTP/2 specification
|
|
static final int DEFAULT_INITIAL_WINDOW_SIZE = (1 << 16) - 1;
|
|
|
|
+ static final int DEFAULT_OVERHEAD_COUNT_FACTOR = 1;
|
|
+
|
|
private static final String HTTP_UPGRADE_NAME = "h2c";
|
|
private static final String ALPN_NAME = "h2";
|
|
private static final byte[] ALPN_IDENTIFIER = ALPN_NAME.getBytes(StandardCharsets.UTF_8);
|
|
@@ -79,6 +81,8 @@
|
|
private int maxHeaderSize = Constants.DEFAULT_MAX_HEADER_SIZE;
|
|
private int maxTrailerCount = Constants.DEFAULT_MAX_TRAILER_COUNT;
|
|
private int maxTrailerSize = Constants.DEFAULT_MAX_TRAILER_SIZE;
|
|
+ private int overheadCountFactor = DEFAULT_OVERHEAD_COUNT_FACTOR;
|
|
+
|
|
private boolean initiatePingDisabled = false;
|
|
private boolean useSendfile = true;
|
|
// Compression
|
|
@@ -306,6 +310,16 @@
|
|
}
|
|
|
|
|
|
+ public int getOverheadCountFactor() {
|
|
+ return overheadCountFactor;
|
|
+ }
|
|
+
|
|
+
|
|
+ public void setOverheadCountFactor(int overheadCountFactor) {
|
|
+ this.overheadCountFactor = overheadCountFactor;
|
|
+ }
|
|
+
|
|
+
|
|
public void setInitiatePingDisabled(boolean initiatePingDisabled) {
|
|
this.initiatePingDisabled = initiatePingDisabled;
|
|
}
|
|
--- tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:18 1852701
|
|
+++ tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:22 1852702
|
|
@@ -30,6 +30,7 @@
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
import javax.servlet.http.WebConnection;
|
|
@@ -139,6 +140,9 @@
|
|
private AtomicInteger streamConcurrency = null;
|
|
private Queue<StreamRunnable> queuedRunnable = null;
|
|
|
|
+ // Track 'overhead' frames vs 'request/response' frames
|
|
+ private final AtomicLong overheadCount = new AtomicLong(-10);
|
|
+
|
|
|
|
Http2UpgradeHandler(Http2Protocol protocol, Adapter adapter, Request coyoteRequest) {
|
|
super (STREAM_ID_ZERO);
|
|
@@ -330,6 +334,10 @@
|
|
}
|
|
}
|
|
|
|
+ if (overheadCount.get() > 0) {
|
|
+ throw new ConnectionException("Too much overhead", Http2Error.ENHANCE_YOUR_CALM);
|
|
+ }
|
|
+
|
|
if (activeRemoteStreamCount.get() == 0) {
|
|
// No streams currently active. Use the keep-alive
|
|
// timeout for the connection.
|
|
@@ -638,6 +646,9 @@
|
|
log.debug(sm.getString("upgradeHandler.writeBody", connectionId, stream.getIdentifier(),
|
|
Integer.toString(len)));
|
|
}
|
|
+
|
|
+ reduceOverheadCount();
|
|
+
|
|
// Need to check this now since sending end of stream will change this.
|
|
boolean writeable = stream.canWrite();
|
|
byte[] header = new byte[9];
|
|
@@ -1193,6 +1204,16 @@
|
|
}
|
|
|
|
|
|
+ private void reduceOverheadCount() {
|
|
+ overheadCount.decrementAndGet();
|
|
+ }
|
|
+
|
|
+
|
|
+ private void increaseOverheadCount() {
|
|
+ overheadCount.addAndGet(getProtocol().getOverheadCountFactor());
|
|
+ }
|
|
+
|
|
+
|
|
// ----------------------------------------------- Http2Parser.Input methods
|
|
|
|
@Override
|
|
@@ -1247,6 +1268,7 @@
|
|
|
|
@Override
|
|
public ByteBuffer startRequestBodyFrame(int streamId, int payloadSize) throws Http2Exception {
|
|
+ reduceOverheadCount();
|
|
Stream stream = getStream(streamId, true);
|
|
stream.checkState(FrameType.DATA);
|
|
stream.receivedData(payloadSize);
|
|
@@ -1291,6 +1313,8 @@
|
|
// determines if a new stream is created or if this stream is ignored.
|
|
checkPauseState();
|
|
|
|
+ reduceOverheadCount();
|
|
+
|
|
if (connectionState.get().isNewStreamAllowed()) {
|
|
Stream stream = getStream(streamId, false);
|
|
if (stream == null) {
|
|
@@ -1340,6 +1364,9 @@
|
|
throw new ConnectionException(sm.getString("upgradeHandler.dependency.invalid",
|
|
getConnectionId(), Integer.valueOf(streamId)), Http2Error.PROTOCOL_ERROR);
|
|
}
|
|
+
|
|
+ increaseOverheadCount();
|
|
+
|
|
Stream stream = getStream(streamId, false);
|
|
if (stream == null) {
|
|
stream = createRemoteStream(streamId);
|
|
@@ -1384,6 +1411,9 @@
|
|
|
|
@Override
|
|
public void setting(Setting setting, long value) throws ConnectionException {
|
|
+
|
|
+ increaseOverheadCount();
|
|
+
|
|
// Special handling required
|
|
if (setting == Setting.INITIAL_WINDOW_SIZE) {
|
|
long oldValue = remoteSettings.getInitialWindowSize();
|
|
@@ -1425,6 +1455,9 @@
|
|
|
|
@Override
|
|
public void pingReceive(byte[] payload, boolean ack) throws IOException {
|
|
+ if (!ack) {
|
|
+ increaseOverheadCount();
|
|
+ }
|
|
pingManager.receivePing(payload, ack);
|
|
}
|
|
|
|
|