mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-27 01:27:30 +09:00
[network] Keep track of and check HTTP/2 header sizes.
This commit is contained in:
parent
f6204a7ca8
commit
1ddd3ea76b
2 changed files with 36 additions and 4 deletions
|
|
@ -90,6 +90,7 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio
|
||||||
, mClosed(false)
|
, mClosed(false)
|
||||||
, mCleanShutdown(false)
|
, mCleanShutdown(false)
|
||||||
, mTLSProfileConfirmed(false)
|
, mTLSProfileConfirmed(false)
|
||||||
|
, mAggregatedHeaderSize(0)
|
||||||
, mGoAwayReason(NO_HTTP_ERROR)
|
, mGoAwayReason(NO_HTTP_ERROR)
|
||||||
, mClientGoAwayReason(UNASSIGNED)
|
, mClientGoAwayReason(UNASSIGNED)
|
||||||
, mPeerGoAwayReason(UNASSIGNED)
|
, mPeerGoAwayReason(UNASSIGNED)
|
||||||
|
|
@ -1262,6 +1263,13 @@ Http2Session::RecvHeaders(Http2Session *self)
|
||||||
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
|
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t frameSize = self->mInputFrameDataSize - paddingControlBytes -
|
||||||
|
priorityLen - paddingLength;
|
||||||
|
if (self->mAggregatedHeaderSize + frameSize >
|
||||||
|
gHttpHandler->MaxHttpResponseHeaderSize()) {
|
||||||
|
LOG(("Http2Session %p header exceeds the limit\n", self));
|
||||||
|
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
if (!self->mInputFrameDataStream) {
|
if (!self->mInputFrameDataStream) {
|
||||||
// Cannot find stream. We can continue the session, but we need to
|
// Cannot find stream. We can continue the session, but we need to
|
||||||
// uncompress the header block to maintain the correct compression context
|
// uncompress the header block to maintain the correct compression context
|
||||||
|
|
@ -1274,7 +1282,7 @@ Http2Session::RecvHeaders(Http2Session *self)
|
||||||
self->GenerateRstStream(PROTOCOL_ERROR, self->mInputFrameID);
|
self->GenerateRstStream(PROTOCOL_ERROR, self->mInputFrameID);
|
||||||
|
|
||||||
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + priorityLen],
|
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + priorityLen],
|
||||||
self->mInputFrameDataSize - paddingControlBytes - priorityLen - paddingLength);
|
frameSize);
|
||||||
|
|
||||||
if (self->mInputFrameFlags & kFlag_END_HEADERS) {
|
if (self->mInputFrameFlags & kFlag_END_HEADERS) {
|
||||||
rv = self->UncompressAndDiscard(false);
|
rv = self->UncompressAndDiscard(false);
|
||||||
|
|
@ -1301,11 +1309,17 @@ Http2Session::RecvHeaders(Http2Session *self)
|
||||||
|
|
||||||
// queue up any compression bytes
|
// queue up any compression bytes
|
||||||
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + priorityLen],
|
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + priorityLen],
|
||||||
self->mInputFrameDataSize - paddingControlBytes - priorityLen - paddingLength);
|
frameSize);
|
||||||
|
|
||||||
self->mInputFrameDataStream->UpdateTransportReadEvents(self->mInputFrameDataSize);
|
self->mInputFrameDataStream->UpdateTransportReadEvents(self->mInputFrameDataSize);
|
||||||
self->mLastDataReadEpoch = self->mLastReadEpoch;
|
self->mLastDataReadEpoch = self->mLastReadEpoch;
|
||||||
|
|
||||||
|
if (!isContinuation) {
|
||||||
|
self->mAggregatedHeaderSize = frameSize;
|
||||||
|
} else {
|
||||||
|
self->mAggregatedHeaderSize += frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (!endHeadersFlag) { // more are coming - don't process yet
|
if (!endHeadersFlag) { // more are coming - don't process yet
|
||||||
self->ResetDownstreamState();
|
self->ResetDownstreamState();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -1613,6 +1627,15 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||||
self->mInputFrameDataSize));
|
self->mInputFrameDataSize));
|
||||||
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
|
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t frameSize = self->mInputFrameDataSize - paddingControlBytes -
|
||||||
|
promiseLen - paddingLength;
|
||||||
|
|
||||||
|
if (self->mAggregatedHeaderSize + frameSize >
|
||||||
|
gHttpHandler->MaxHttpResponseHeaderSize()) {
|
||||||
|
LOG(("Http2Session:RecvPushPromise %p header exceeds the limit\n", self));
|
||||||
|
RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
LOG3(("Http2Session::RecvPushPromise %p ID 0x%X assoc ID 0x%X "
|
LOG3(("Http2Session::RecvPushPromise %p ID 0x%X assoc ID 0x%X "
|
||||||
"paddingLength %d padded %d\n",
|
"paddingLength %d padded %d\n",
|
||||||
|
|
@ -1683,7 +1706,7 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||||
// Need to decompress the headers even though we aren't using them yet in
|
// Need to decompress the headers even though we aren't using them yet in
|
||||||
// order to keep the compression context consistent for other frames
|
// order to keep the compression context consistent for other frames
|
||||||
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + promiseLen],
|
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + promiseLen],
|
||||||
self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength);
|
frameSize);
|
||||||
if (self->mInputFrameFlags & kFlag_END_PUSH_PROMISE) {
|
if (self->mInputFrameFlags & kFlag_END_PUSH_PROMISE) {
|
||||||
rv = self->UncompressAndDiscard(true);
|
rv = self->UncompressAndDiscard(true);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
@ -1697,7 +1720,13 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + promiseLen],
|
self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + promiseLen],
|
||||||
self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength);
|
frameSize);
|
||||||
|
|
||||||
|
if (self->mInputFrameType != FRAME_TYPE_CONTINUATION) {
|
||||||
|
self->mAggregatedHeaderSize = frameSize;
|
||||||
|
} else {
|
||||||
|
self->mAggregatedHeaderSize += frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(self->mInputFrameFlags & kFlag_END_PUSH_PROMISE)) {
|
if (!(self->mInputFrameFlags & kFlag_END_PUSH_PROMISE)) {
|
||||||
LOG3(("Http2Session::RecvPushPromise not finishing processing for multi-frame push\n"));
|
LOG3(("Http2Session::RecvPushPromise not finishing processing for multi-frame push\n"));
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,9 @@ private:
|
||||||
// to make sure streams aren't shared across sessions.
|
// to make sure streams aren't shared across sessions.
|
||||||
uint64_t mSerial;
|
uint64_t mSerial;
|
||||||
|
|
||||||
|
// Aggregate size of continued headers (pushed and pulled)
|
||||||
|
uint32_t mAggregatedHeaderSize;
|
||||||
|
|
||||||
// If push is disabled, we want to be able to send PROTOCOL_ERRORs if we
|
// If push is disabled, we want to be able to send PROTOCOL_ERRORs if we
|
||||||
// receive a PUSH_PROMISE, but we have to wait for the SETTINGS ACK before
|
// receive a PUSH_PROMISE, but we have to wait for the SETTINGS ACK before
|
||||||
// we can actually tell the other end to go away. These help us keep track
|
// we can actually tell the other end to go away. These help us keep track
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue