--- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -371,12 +371,12 @@ bool QHttp2ProtocolHandler::sendRequest( } } - if (!prefaceSent && !sendClientPreface()) - return false; - if (!requests.size()) return true; + if (!prefaceSent && !sendClientPreface()) + return false; + m_channel->state = QHttpNetworkConnectionChannel::WritingState; // Check what was promised/pushed, maybe we do not have to send a request // and have a response already? --- a/src/network/access/qhttpnetworkconnectionchannel.cpp 2020-10-27 09:02:11.000000000 +0100 +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp 2024-08-16 22:36:07.819945304 +0200 @@ -255,6 +255,10 @@ bool QHttpNetworkConnectionChannel::sendRequest() { Q_ASSERT(!protocolHandler.isNull()); + if (waitingForPotentialAbort) { + needInvokeSendRequest = true; + return false; // this return value is unused + } return protocolHandler->sendRequest(); } @@ -270,18 +274,27 @@ Q_ASSERT(!protocolHandler.isNull()); if (reply) protocolHandler->sendRequest(); + sendRequest(); }, Qt::ConnectionType::QueuedConnection); } void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(!protocolHandler.isNull()); + if (waitingForPotentialAbort) { + needInvokeReceiveReply = true; + return; + } protocolHandler->_q_receiveReply(); } void QHttpNetworkConnectionChannel::_q_readyRead() { Q_ASSERT(!protocolHandler.isNull()); + if (waitingForPotentialAbort) { + needInvokeReadyRead = true; + return; + } protocolHandler->_q_readyRead(); } @@ -1299,6 +1312,27 @@ } } +void QHttpNetworkConnectionChannel::checkAndResumeCommunication() +{ + Q_ASSERT(connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 + || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct); + + // Because HTTP/2 requires that we send a SETTINGS frame as the first thing we do, and respond + // to a SETTINGS frame with an ACK, we need to delay any handling until we can ensure that any + // effects from emitting encrypted() have been processed. + // This function is called after encrypted() was emitted, so check for changes. + + if (!reply && spdyRequestsToSend.isEmpty()) + abort(); + waitingForPotentialAbort = false; + if (needInvokeReadyRead) + _q_readyRead(); + if (needInvokeReceiveReply) + _q_receiveReply(); + if (needInvokeSendRequest) + sendRequest(); +} + void QHttpNetworkConnectionChannel::requeueSpdyRequests() { QList spdyPairs = spdyRequestsToSend.values(); --- a/src/network/access/qhttpnetworkconnectionchannel_p.h 2020-10-27 09:02:11.000000000 +0100 +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h 2024-08-16 22:40:50.519943219 +0200 @@ -107,6 +107,10 @@ QAbstractSocket *socket; bool ssl; bool isInitialized; + bool waitingForPotentialAbort = false; + bool needInvokeReceiveReply = false; + bool needInvokeReadyRead = false; + bool needInvokeSendRequest = false; ChannelState state; QHttpNetworkRequest request; // current request, only used for HTTP QHttpNetworkReply *reply; // current reply for this request, only used for HTTP @@ -187,6 +191,8 @@ void closeAndResendCurrentRequest(); void resendCurrentRequest(); + void checkAndResumeCommunication(); + bool isSocketBusy() const; bool isSocketWriting() const; bool isSocketWaiting() const;