diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2023-03-06 16:23:23 +0100 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2023-04-01 00:36:58 +0200 |
commit | 7822b89aef30404164bc6f6f790d0cc563e10cbf (patch) | |
tree | 2bf61b54753c2634dacc9393f7d5d1b45f62a797 /src/network/access/qhttp2protocolhandler.cpp | |
parent | a81ea3d11432a86d0411c9d8806607c6f3ed7573 (diff) |
Http2: Don't skip checking flag for trailing HEADERS frame if PRIORITY
If the trailing frame just had PRIORITY we would early-return, though
this meant we didn't check if the frame had the END_STREAM flag set,
leading some requests to certain servers to hang.
Fixes: QTBUG-111417
Pick-to: 6.5 6.4 6.2
Change-Id: Iac174dc5aeca30d5d19fae35f303983de9841847
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Diffstat (limited to 'src/network/access/qhttp2protocolhandler.cpp')
-rw-r--r-- | src/network/access/qhttp2protocolhandler.cpp | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index f41cde067a..93be8412db 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -964,7 +964,12 @@ void QHttp2ProtocolHandler::handleContinuedHEADERS() } std::vector<uchar> hpackBlock(assemble_hpack_block(continuedFrames)); - if (!hpackBlock.size()) { + const bool hasHeaderFields = !hpackBlock.empty(); + if (hasHeaderFields) { + HPack::BitIStream inputStream{&hpackBlock[0], &hpackBlock[0] + hpackBlock.size()}; + if (!decoder.decodeHeaderFields(inputStream)) + return connectionError(COMPRESSION_ERROR, "HPACK decompression failed"); + } else if (firstFrameType == FrameType::PUSH_PROMISE) { // It could be a PRIORITY sent in HEADERS - already handled by this // point in handleHEADERS. If it was PUSH_PROMISE (HTTP/2 8.2.1): // "The header fields in PUSH_PROMISE and any subsequent CONTINUATION @@ -973,21 +978,16 @@ void QHttp2ProtocolHandler::handleContinuedHEADERS() // not include a complete and valid set of header fields or the :method // pseudo-header field identifies a method that is not safe, it MUST // respond with a stream error (Section 5.4.2) of type PROTOCOL_ERROR." - if (firstFrameType == FrameType::PUSH_PROMISE) - resetPromisedStream(continuedFrames[0], Http2::PROTOCOL_ERROR); - + resetPromisedStream(continuedFrames[0], Http2::PROTOCOL_ERROR); return; } - HPack::BitIStream inputStream{&hpackBlock[0], &hpackBlock[0] + hpackBlock.size()}; - if (!decoder.decodeHeaderFields(inputStream)) - return connectionError(COMPRESSION_ERROR, "HPACK decompression failed"); - switch (firstFrameType) { case FrameType::HEADERS: if (activeStreams.contains(streamID)) { Stream &stream = activeStreams[streamID]; - updateStream(stream, decoder.decodedHeader()); + if (hasHeaderFields) + updateStream(stream, decoder.decodedHeader()); // Needs to resend the request; we should finish and delete the current stream const bool needResend = stream.request().d->needResendWithCredentials; // No DATA frames. Or needs to resend. |