diff --git a/java/org/apache/coyote/http2/Http2AsyncParser.java b/java/org/apache/coyote/http2/Http2AsyncParser.java
index d01497051da7..6e6065fcf664 100644
--- a/java/org/apache/coyote/http2/Http2AsyncParser.java
+++ b/java/org/apache/coyote/http2/Http2AsyncParser.java
@@ -278,36 +278,39 @@ public void completed(Long result, Void attachment) {
readUnknownFrame(streamId, frameTypeId, flags, payloadSize, payload);
}
}
- // See if there is a new 9 byte header and continue parsing if possible
- if (payload.remaining() >= 9) {
- int position = payload.position();
- payloadSize = ByteUtil.getThreeBytes(payload, position);
- frameTypeId = ByteUtil.getOneByte(payload, position + 3);
- frameType = FrameType.valueOf(frameTypeId);
- flags = ByteUtil.getOneByte(payload, position + 4);
- streamId = ByteUtil.get31Bits(payload, position + 5);
- streamException = false;
- if (payload.remaining() - 9 >= payloadSize) {
- continueParsing = true;
- // Now go over frame header
- payload.position(payload.position() + 9);
- try {
- validateFrame(null, frameType, streamId, flags, payloadSize);
- } catch (StreamException e) {
- error = e;
- streamException = true;
- } catch (Http2Exception e) {
- error = e;
- continueParsing = false;
+ if (!upgradeHandler.isOverheadLimitExceeded()) {
+ // See if there is a new 9 byte header and continue parsing if possible
+ if (payload.remaining() >= 9) {
+ int position = payload.position();
+ payloadSize = ByteUtil.getThreeBytes(payload, position);
+ frameTypeId = ByteUtil.getOneByte(payload, position + 3);
+ frameType = FrameType.valueOf(frameTypeId);
+ flags = ByteUtil.getOneByte(payload, position + 4);
+ streamId = ByteUtil.get31Bits(payload, position + 5);
+ streamException = false;
+ if (payload.remaining() - 9 >= payloadSize) {
+ continueParsing = true;
+ // Now go over frame header
+ payload.position(payload.position() + 9);
+ try {
+ validateFrame(null, frameType, streamId, flags, payloadSize);
+ } catch (StreamException e) {
+ error = e;
+ streamException = true;
+ } catch (Http2Exception e) {
+ error = e;
+ continueParsing = false;
+ }
}
}
}
} while (continueParsing);
} catch (RuntimeException | IOException | Http2Exception e) {
error = e;
- }
- if (payload.hasRemaining()) {
- socketWrapper.unRead(payload);
+ } finally {
+ if (payload.hasRemaining()) {
+ socketWrapper.unRead(payload);
+ }
}
}
if (state == CompletionState.DONE) {
diff --git a/java/org/apache/coyote/http2/Http2Protocol.java b/java/org/apache/coyote/http2/Http2Protocol.java
index 46b49d926ccb..7a27088b5ead 100644
--- a/java/org/apache/coyote/http2/Http2Protocol.java
+++ b/java/org/apache/coyote/http2/Http2Protocol.java
@@ -54,8 +54,10 @@ public class Http2Protocol implements UpgradeProtocol {
// Maximum amount of streams which can be concurrently executed over
// a single connection
static final int DEFAULT_MAX_CONCURRENT_STREAM_EXECUTION = 20;
-
+ // Default factor used when adjusting overhead count for overhead frames
static final int DEFAULT_OVERHEAD_COUNT_FACTOR = 10;
+ // Default factor used when adjusting overhead count for reset frames
+ static final int DEFAULT_OVERHEAD_RESET_FACTOR = 50;
// Not currently configurable. This makes the practical limit for
// overheadCountFactor to be ~20. The exact limit will vary with traffic
// patterns.
@@ -86,6 +88,7 @@ public class Http2Protocol implements UpgradeProtocol {
private int maxHeaderCount = Constants.DEFAULT_MAX_HEADER_COUNT;
private int maxTrailerCount = Constants.DEFAULT_MAX_TRAILER_COUNT;
private int overheadCountFactor = DEFAULT_OVERHEAD_COUNT_FACTOR;
+ private int overheadResetFactor = DEFAULT_OVERHEAD_RESET_FACTOR;
private int overheadContinuationThreshold = DEFAULT_OVERHEAD_CONTINUATION_THRESHOLD;
private int overheadDataThreshold = DEFAULT_OVERHEAD_DATA_THRESHOLD;
private int overheadWindowUpdateThreshold = DEFAULT_OVERHEAD_WINDOW_UPDATE_THRESHOLD;
@@ -292,6 +295,20 @@ public void setOverheadCountFactor(int overheadCountFactor) {
}
+ public int getOverheadResetFactor() {
+ return overheadResetFactor;
+ }
+
+
+ public void setOverheadResetFactor(int overheadResetFactor) {
+ if (overheadResetFactor < 0) {
+ this.overheadResetFactor = 0;
+ } else {
+ this.overheadResetFactor = overheadResetFactor;
+ }
+ }
+
+
public int getOverheadContinuationThreshold() {
return overheadContinuationThreshold;
}
diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index 0b2f554fccea..3285a4674368 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -380,7 +380,7 @@ public SocketState upgradeDispatch(SocketEvent status) {
stream.close(se);
}
} finally {
- if (overheadCount.get() > 0) {
+ if (isOverheadLimitExceeded()) {
throw new ConnectionException(
sm.getString("upgradeHandler.tooMuchOverhead", connectionId),
Http2Error.ENHANCE_YOUR_CALM);
@@ -1494,6 +1494,11 @@ private void updateOverheadCount(FrameType frameType, int increment) {
}
+ boolean isOverheadLimitExceeded() {
+ return overheadCount.get() > 0;
+ }
+
+
// ----------------------------------------------- Http2Parser.Input methods
@Override
@@ -1767,6 +1772,7 @@ public void reset(int streamId, long errorCode) throws Http2Exception {
log.debug(sm.getString("upgradeHandler.reset.receive", getConnectionId(), Integer.toString(streamId),
Long.toString(errorCode)));
}
+ increaseOverheadCount(FrameType.RST, getProtocol().getOverheadResetFactor());
AbstractNonZeroStream abstractNonZeroStream = getAbstractNonZeroStream(streamId, true);
abstractNonZeroStream.checkState(FrameType.RST);
if (abstractNonZeroStream instanceof Stream) {
diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
index bc77a3d085bd..0b8865418c44 100644
--- a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
+++ b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
@@ -43,6 +43,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import javax.sql.XAConnection;
+
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -364,8 +366,10 @@ public Constructor> getProxyConstructor(boolean xa) throws NoSuchMethodExcepti
//cache the constructor
if (proxyClassConstructor == null ) {
Class> proxyClass = xa ?
- Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class, javax.sql.XAConnection.class}) :
- Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class});
+ Proxy.getProxyClass(ConnectionPool.class.getClassLoader(),
+ new Class[] {Connection.class, javax.sql.PooledConnection.class, XAConnection.class}) :
+ Proxy.getProxyClass(ConnectionPool.class.getClassLoader(),
+ new Class[] {Connection.class, javax.sql.PooledConnection.class});
proxyClassConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
}
return proxyClassConstructor;
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 2be4fd7904e9..6754b87f3389 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,15 @@
issues do not "pop up" wrt. others).
-->
-10 * overheadCountFactor
. The count is
decreased by 20 for each data frame sent or received and each headers frame
received. The count is increased by the overheadCountFactor
- for each setting received, priority frame received and ping received. If
+ for each setting, priority, priority update and ping frame received. If
the overhead count exceeds zero, the connection is closed. A value of less
than 1
disables this protection. In normal usage a value of
approximately 20
or higher will close the connection before
@@ -147,6 +147,13 @@
10
will be used.
The amount by which the overhead count (see
+ overheadCountFactor) will be increased for each reset
+ frame received. If not specified, a default value of 50
will
+ be used. A value of less than zero will be treated as zero.
The threshold below which the average payload size of the current and
previous non-final DATA
frames will trigger an increase in