tst_Http2: Test SETTINGS_HEADER_TABLE_SIZE handling
This somewhat duplicates some other tests, namely the QHttp2Connection one, but tst_http2 is our only coverage of the HTTP/2 code prior to 6.8. This change adds a test where the server sets the SETTINGS_HEADER_TABLE_SIZE to 0, effectively disabling the dynamic table. We, in an earlier patch, makes the HPack table error out if a new header entry is about to be added if the table has not been resized below a changed 'max'. So, we take advantage of that here and set the new 'max' capacity without resizing the table, or updating dynamic capacity causing it to fail if the client doesn't send the expected Dynamic Table Size Update. Task-number: QTBUG-132277 Pick-to: 6.8 6.5 Change-Id: I1ca8ca7828d5b83606e7adbcfc13c154fa1e3cab Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit f7c3acd27ff48b24f99086be206acbe7e00e3208) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
aae66d7518
commit
9a1edf52d4
@ -191,6 +191,9 @@ void Http2Server::sendServerSettings()
|
||||
writer.append(it.value());
|
||||
if (it.key() == Settings::INITIAL_WINDOW_SIZE_ID)
|
||||
streamRecvWindowSize = it.value();
|
||||
if (it.key() == Settings::HEADER_TABLE_SIZE_ID) {
|
||||
pendingMaxTableSizeUpdate = it.value();
|
||||
}
|
||||
}
|
||||
writer.write(*socket);
|
||||
// Now, let's update our peer on a session recv window size:
|
||||
@ -669,6 +672,13 @@ void Http2Server::handleSETTINGS()
|
||||
return;
|
||||
}
|
||||
|
||||
// The client ACKed our setting, including the new decoder table size,
|
||||
// so we can update it now:
|
||||
if (pendingMaxTableSizeUpdate) {
|
||||
decoder.setMaxDynamicTableSize(*pendingMaxTableSizeUpdate);
|
||||
pendingMaxTableSizeUpdate.reset();
|
||||
}
|
||||
|
||||
waitingClientAck = false;
|
||||
emit serverSettingsAcked();
|
||||
return;
|
||||
|
@ -213,6 +213,8 @@ private:
|
||||
|
||||
bool sendTrailingHEADERS = false;
|
||||
int informationalStatusCode = 0;
|
||||
|
||||
std::optional<quint32> pendingMaxTableSizeUpdate;
|
||||
protected slots:
|
||||
void ignoreErrorSlot();
|
||||
};
|
||||
|
@ -113,6 +113,8 @@ private slots:
|
||||
|
||||
void limitedConcurrentStreamsAllowed();
|
||||
|
||||
void maxHeaderTableSize();
|
||||
|
||||
protected slots:
|
||||
// Slots to listen to our in-process server:
|
||||
void serverStarted(quint16 port);
|
||||
@ -1637,6 +1639,55 @@ void tst_Http2::limitedConcurrentStreamsAllowed()
|
||||
QCOMPARE(finishedCount, TotalRequests);
|
||||
}
|
||||
|
||||
void tst_Http2::maxHeaderTableSize()
|
||||
{
|
||||
clearHTTP2State();
|
||||
serverPort = 0;
|
||||
|
||||
H2Type connectionType = H2Type::h2Direct;
|
||||
RawSettings maxHeaderTableSize{ { Http2::Settings::HEADER_TABLE_SIZE_ID, 0 } };
|
||||
ServerPtr targetServer(newServer(maxHeaderTableSize, connectionType));
|
||||
|
||||
QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection);
|
||||
runEventLoop();
|
||||
|
||||
QVERIFY(serverPort != 0);
|
||||
|
||||
nRequests = 1;
|
||||
|
||||
const auto url = requestUrl(connectionType);
|
||||
QNetworkRequest request(url);
|
||||
request.setAttribute(QNetworkRequest::Http2DirectAttribute, true);
|
||||
|
||||
constexpr int extraRequests = 5;
|
||||
std::array<std::unique_ptr<QNetworkReply>, extraRequests> replies;
|
||||
for (qint32 i = 0; i < 1 + extraRequests; ++i) {
|
||||
for (qint32 j = 0; j < 100; ++j) {
|
||||
request.setRawHeader("x-test" + QByteArray::number(j),
|
||||
"Hello World" + QByteArray::number(i));
|
||||
}
|
||||
std::unique_ptr<QNetworkReply> reply{ manager->get(request) };
|
||||
reply->ignoreSslErrors();
|
||||
connect(reply.get(), &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
||||
|
||||
if (i == 0) {
|
||||
runEventLoop();
|
||||
STOP_ON_FAILURE
|
||||
QCOMPARE(reply->error(), QNetworkReply::NoError);
|
||||
nRequests = extraRequests;
|
||||
} else {
|
||||
replies[i - 1] = std::move(reply);
|
||||
}
|
||||
}
|
||||
|
||||
runEventLoop();
|
||||
STOP_ON_FAILURE
|
||||
|
||||
QCOMPARE(nRequests, 0);
|
||||
for (const auto &reply : replies)
|
||||
QCOMPARE(reply->error(), QNetworkReply::NoError);
|
||||
}
|
||||
|
||||
void tst_Http2::serverStarted(quint16 port)
|
||||
{
|
||||
serverPort = port;
|
||||
|
Loading…
x
Reference in New Issue
Block a user