diff options
-rw-r--r-- | tests/auto/network/access/http2/http2srv.cpp | 32 | ||||
-rw-r--r-- | tests/auto/network/access/http2/http2srv.h | 4 | ||||
-rw-r--r-- | tests/auto/network/access/http2/tst_http2.cpp | 4 |
3 files changed, 34 insertions, 6 deletions
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp index b0bae13bad..1f9ffb8985 100644 --- a/tests/auto/network/access/http2/http2srv.cpp +++ b/tests/auto/network/access/http2/http2srv.cpp @@ -212,13 +212,30 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize) const quint32 offset = it->second; Q_ASSERT(offset < quint32(responseBody.size())); - const quint32 bytes = std::min<quint32>(windowSize, responseBody.size() - offset); + quint32 bytesToSend = std::min<quint32>(windowSize, responseBody.size() - offset); + quint32 bytesSent = 0; const quint32 frameSizeLimit(clientSetting(Settings::MAX_FRAME_SIZE_ID, Http2::maxFrameSize)); const uchar *src = reinterpret_cast<const uchar *>(responseBody.constData() + offset); - const bool last = offset + bytes == quint32(responseBody.size()); + const bool last = offset + bytesToSend == quint32(responseBody.size()); + + // The payload can significantly exceed frameSizeLimit. Internally, writer + // will do needed fragmentation, but if some test failed, there is no need + // to wait for writer to send all DATA frames, we check 'interrupted' and + // stop early instead. + const quint32 framesInChunk = 10; + while (bytesToSend) { + if (interrupted.loadAcquire()) + return; + const quint32 chunkSize = std::min<quint32>(framesInChunk * frameSizeLimit, bytesToSend); + writer.start(FrameType::DATA, FrameFlag::EMPTY, streamID); + writer.writeDATA(*socket, frameSizeLimit, src, chunkSize); + src += chunkSize; + bytesToSend -= chunkSize; + bytesSent += chunkSize; + } - writer.start(FrameType::DATA, FrameFlag::EMPTY, streamID); - writer.writeDATA(*socket, frameSizeLimit, src, bytes); + if (interrupted.loadAcquire()) + return; if (last) { writer.start(FrameType::DATA, FrameFlag::END_STREAM, streamID); @@ -230,7 +247,7 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize) Q_ASSERT(closedStreams.find(streamID) == closedStreams.end()); closedStreams.insert(streamID); } else { - it->second += bytes; + it->second += bytesSent; } } @@ -819,6 +836,11 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody) } } +void Http2Server::stopSendingDATAFrames() +{ + interrupted.storeRelease(1); +} + void Http2Server::processRequest() { Q_ASSERT(continuedRequest.size()); diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h index 14b41cc67d..87a17ced8b 100644 --- a/tests/auto/network/access/http2/http2srv.h +++ b/tests/auto/network/access/http2/http2srv.h @@ -40,6 +40,7 @@ #include <QtCore/qscopedpointer.h> #include <QtNetwork/qtcpserver.h> #include <QtCore/qbytearray.h> +#include <QtCore/qatomic.h> #include <QtCore/qglobal.h> #include <vector> @@ -96,6 +97,8 @@ public: Q_INVOKABLE void sendResponse(quint32 streamID, bool emptyBody); + void stopSendingDATAFrames(); + private: void processRequest(); @@ -191,6 +194,7 @@ private: // may still be sending DATA frames. See tst_Http2::earlyResponse(). bool redirectWhileReading = false; quint16 targetPort = 0; + QAtomicInt interrupted; protected slots: void ignoreErrorSlot(); }; diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index fa56a35c29..49daedf32c 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -132,8 +132,10 @@ struct ServerDeleter { static void cleanup(Http2Server *srv) { - if (srv) + if (srv) { + srv->stopSendingDATAFrames(); QMetaObject::invokeMethod(srv, "deleteLater", Qt::QueuedConnection); + } } }; |