diff options
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/http2/http2protocol_p.h | 3 | ||||
-rw-r--r-- | src/network/access/qhttp2protocolhandler.cpp | 10 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 57 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 4 | ||||
-rw-r--r-- | src/network/access/qnetworkdiskcache.cpp | 4 | ||||
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl.cpp | 84 | ||||
-rw-r--r-- | src/network/access/qnetworkreplywasmimpl_p.h | 2 |
7 files changed, 86 insertions, 78 deletions
diff --git a/src/network/access/http2/http2protocol_p.h b/src/network/access/http2/http2protocol_p.h index b0af5aa919..ed5f2bf561 100644 --- a/src/network/access/http2/http2protocol_p.h +++ b/src/network/access/http2/http2protocol_p.h @@ -133,9 +133,6 @@ enum Http2PredefinedParameters maxPayloadSize = (1 << 24) - 1, // HTTP/2 6.5.2 defaultSessionWindowSize = 65535, // HTTP/2 6.5.2 - // Using 1000 (rather arbitrarily), just to - // impose *some* upper limit: - maxPeerConcurrentStreams = 1000, maxConcurrentStreams = 100 // HTTP/2, 6.5.2 }; diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index f513139304..ddd661cc50 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -393,7 +393,8 @@ bool QHttp2ProtocolHandler::sendRequest() initReplyFromPushPromise(message, key); } - const auto streamsToUse = std::min<quint32>(maxConcurrentStreams - activeStreams.size(), + const auto streamsToUse = std::min<quint32>(maxConcurrentStreams > quint32(activeStreams.size()) + ? maxConcurrentStreams - quint32(activeStreams.size()) : 0, requests.size()); auto it = requests.begin(); for (quint32 i = 0; i < streamsToUse; ++i) { @@ -1084,13 +1085,8 @@ bool QHttp2ProtocolHandler::acceptSetting(Http2::Settings identifier, quint32 ne QMetaObject::invokeMethod(this, "resumeSuspendedStreams", Qt::QueuedConnection); } - if (identifier == Settings::MAX_CONCURRENT_STREAMS_ID) { - if (newValue > maxPeerConcurrentStreams) { - connectionError(PROTOCOL_ERROR, "SETTINGS invalid number of concurrent streams"); - return false; - } + if (identifier == Settings::MAX_CONCURRENT_STREAMS_ID) maxConcurrentStreams = newValue; - } if (identifier == Settings::MAX_FRAME_SIZE_ID) { if (newValue < Http2::minPayloadLimit || newValue > Http2::maxPayloadSize) { diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index b093eec161..1bef9157e6 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1120,31 +1120,50 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() int normalRequests = queuedRequests - preConnectRequests; neededOpenChannels = qMax(normalRequests, preConnectRequests); } + + if (neededOpenChannels <= 0) + return; + + QQueue<int> channelsToConnect; + + // use previously used channels first for (int i = 0; i < activeChannelCount && neededOpenChannels > 0; ++i) { - bool connectChannel = false; - if (channels[i].socket) { - if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) - || (channels[i].socket->state() == QAbstractSocket::HostLookupState) - || channels[i].pendingEncrypt) // pendingEncrypt == "EncryptingState" - neededOpenChannels--; - - if (neededOpenChannels <= 0) - break; - if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState)) - connectChannel = true; - } else { // not previously used channel - connectChannel = true; + if (!channels[i].socket) + continue; + + if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) + || (channels[i].socket->state() == QAbstractSocket::HostLookupState) + || channels[i].pendingEncrypt) { // pendingEncrypt == "EncryptingState" + neededOpenChannels--; + continue; } - if (connectChannel) { - if (networkLayerState == IPv4) - channels[i].networkLayerPreference = QAbstractSocket::IPv4Protocol; - else if (networkLayerState == IPv6) - channels[i].networkLayerPreference = QAbstractSocket::IPv6Protocol; - channels[i].ensureConnection(); + if (!channels[i].reply && !channels[i].isSocketBusy() + && (channels[i].socket->state() == QAbstractSocket::UnconnectedState)) { + channelsToConnect.enqueue(i); neededOpenChannels--; } } + + // use other channels + for (int i = 0; i < activeChannelCount && neededOpenChannels > 0; ++i) { + if (channels[i].socket) + continue; + + channelsToConnect.enqueue(i); + neededOpenChannels--; + } + + while (!channelsToConnect.isEmpty()) { + const int channel = channelsToConnect.dequeue(); + + if (networkLayerState == IPv4) + channels[channel].networkLayerPreference = QAbstractSocket::IPv4Protocol; + else if (networkLayerState == IPv6) + channels[channel].networkLayerPreference = QAbstractSocket::IPv6Protocol; + + channels[channel].ensureConnection(); + } } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 4e1aa541a8..7620ca1647 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -1286,6 +1286,10 @@ void QHttpNetworkConnectionChannel::_q_encrypted() connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { // we call setSpdyWasUsed(true) on the replies in the SPDY handler when the request is sent if (spdyRequestsToSend.count() > 0) { + // Similar to HTTP/1.1 counterpart below: + const auto &pairs = spdyRequestsToSend.values(); // (request, reply) + const auto &pair = pairs.first(); + emit pair.second->encrypted(); // In case our peer has sent us its settings (window size, max concurrent streams etc.) // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection). QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index 0fda4d8296..2a7f16637d 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -271,14 +271,12 @@ void QNetworkDiskCachePrivate::storeItem(QCacheItem *cacheItem) Q_ASSERT(!fileName.isEmpty()); if (QFile::exists(fileName)) { - if (!QFile::remove(fileName)) { + if (!removeFile(fileName)) { qWarning() << "QNetworkDiskCache: couldn't remove the cache file " << fileName; return; } } - if (currentCacheSize > 0) - currentCacheSize += 1024 + cacheItem->size(); currentCacheSize = q->expire(); if (!cacheItem->file) { QString templateName = tmpCacheFileName(); diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index 0fc5bbf5a8..505db44522 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -67,10 +67,6 @@ QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate() QNetworkReplyWasmImplPrivate::~QNetworkReplyWasmImplPrivate() { - if (m_fetch) { - emscripten_fetch_close(m_fetch); - m_fetch = 0; - } } QNetworkReplyWasmImpl::QNetworkReplyWasmImpl(QObject *parent) @@ -115,12 +111,14 @@ void QNetworkReplyWasmImpl::close() void QNetworkReplyWasmImpl::abort() { - Q_D( QNetworkReplyWasmImpl); + Q_D(QNetworkReplyWasmImpl); if (d->state == QNetworkReplyPrivate::Finished || d->state == QNetworkReplyPrivate::Aborted) return; d->state = QNetworkReplyPrivate::Aborted; - d->doAbort(); + d->m_fetch->userData = nullptr; + + d->emitReplyError(QNetworkReply::OperationCanceledError, QStringLiteral("Operation canceled")); close(); } @@ -198,11 +196,6 @@ void QNetworkReplyWasmImplPrivate::setReplyAttributes(quintptr data, int statusC handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusReason); } -void QNetworkReplyWasmImplPrivate::doAbort() const -{ - emscripten_fetch_close(m_fetch); -} - constexpr int getArraySize (int factor) { return 2 * factor + 1; } @@ -283,7 +276,6 @@ void QNetworkReplyWasmImplPrivate::emitReplyError(QNetworkReply::NetworkError er q->setError(errorCode, errorString); emit q->errorOccurred(errorCode); - emit q->finished(); } void QNetworkReplyWasmImplPrivate::emitDataReadProgress(qint64 bytesReceived, qint64 bytesTotal) @@ -316,6 +308,12 @@ void QNetworkReplyWasmImplPrivate::dataReceived(const QByteArray &buffer, int bu downloadBuffer.append(buffer, bufferSize); emit q->readyRead(); + + if (downloadBufferCurrentSize == totalDownloadSize) { + q->setFinished(true); + emit q->readChannelFinished(); + emit q->finished(); + } } //taken from qnetworkrequest.cpp @@ -447,16 +445,14 @@ void QNetworkReplyWasmImplPrivate::_q_bufferOutgoingData() void QNetworkReplyWasmImplPrivate::downloadSucceeded(emscripten_fetch_t *fetch) { - QNetworkReplyWasmImplPrivate *reply = - reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); - if (reply) { - QByteArray buffer(fetch->data, fetch->numBytes); - reply->dataReceived(buffer, buffer.size()); + auto reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); + if (!reply || reply->state == QNetworkReplyPrivate::Aborted) + return; + QByteArray buffer(fetch->data, fetch->numBytes); + reply->dataReceived(buffer, buffer.size()); - QByteArray statusText(fetch->statusText); - reply->setStatusCode(fetch->status, statusText); - reply->setReplyFinished(); - } + emscripten_fetch_close(fetch); + reply->m_fetch = nullptr; } void QNetworkReplyWasmImplPrivate::setStatusCode(int status, const QByteArray &statusText) @@ -466,32 +462,29 @@ void QNetworkReplyWasmImplPrivate::setStatusCode(int status, const QByteArray &s q->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusText); } -void QNetworkReplyWasmImplPrivate::setReplyFinished() -{ - Q_Q(QNetworkReplyWasmImpl); - q->setFinished(true); - emit q->readChannelFinished(); - emit q->finished(); -} - void QNetworkReplyWasmImplPrivate::stateChange(emscripten_fetch_t *fetch) { - if (fetch->readyState == /*HEADERS_RECEIVED*/ 2) { - size_t headerLength = emscripten_fetch_get_response_headers_length(fetch); - QByteArray str(headerLength, Qt::Uninitialized); - emscripten_fetch_get_response_headers(fetch, str.data(), str.size()); - QNetworkReplyWasmImplPrivate *reply = - reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); - reply->headersReceived(str); + if (fetch) { + if (!quintptr(fetch->userData)) + return; + auto reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); + if (reply->state != QNetworkReplyPrivate::Aborted) { + if (fetch->readyState == /*HEADERS_RECEIVED*/ 2) { + size_t headerLength = emscripten_fetch_get_response_headers_length(fetch); + QByteArray str(headerLength, Qt::Uninitialized); + emscripten_fetch_get_response_headers(fetch, str.data(), str.size()); + + reply->headersReceived(str); + } + } } } void QNetworkReplyWasmImplPrivate::downloadProgress(emscripten_fetch_t *fetch) { - QNetworkReplyWasmImplPrivate *reply = - reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); - Q_ASSERT(reply); - + auto reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); + if (!reply || reply->state == QNetworkReplyPrivate::Aborted) + return; if (fetch->status < 400) { uint64_t bytes = fetch->dataOffset + fetch->numBytes; uint64_t tBytes = fetch->totalBytes; // totalBytes can be 0 if server not reporting content length @@ -503,10 +496,13 @@ void QNetworkReplyWasmImplPrivate::downloadProgress(emscripten_fetch_t *fetch) void QNetworkReplyWasmImplPrivate::downloadFailed(emscripten_fetch_t *fetch) { - QNetworkReplyWasmImplPrivate *reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); + + auto reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fetch->userData); + if (reply) { + QString reasonStr; - if (fetch->status > 600 || reply->state == QNetworkReplyPrivate::Aborted) + if (fetch->status > 600) reasonStr = QStringLiteral("Operation canceled"); else reasonStr = QString::fromUtf8(fetch->statusText); @@ -514,10 +510,10 @@ void QNetworkReplyWasmImplPrivate::downloadFailed(emscripten_fetch_t *fetch) QByteArray statusText(fetch->statusText); reply->setStatusCode(fetch->status, statusText); reply->emitReplyError(reply->statusCodeFromHttp(fetch->status, reply->request.url()), reasonStr); + reply->m_fetch = nullptr; } - if (fetch->status >= 400) - emscripten_fetch_close(fetch); // Also free data on failure. + emscripten_fetch_close(fetch); } //taken from qhttpthreaddelegate.cpp diff --git a/src/network/access/qnetworkreplywasmimpl_p.h b/src/network/access/qnetworkreplywasmimpl_p.h index 53e9bc3375..db9fd5657e 100644 --- a/src/network/access/qnetworkreplywasmimpl_p.h +++ b/src/network/access/qnetworkreplywasmimpl_p.h @@ -137,8 +137,6 @@ public: QSharedPointer<QRingBuffer> outgoingDataBuffer; QByteArray requestData; - void doAbort() const; - static void downloadProgress(emscripten_fetch_t *fetch); static void downloadFailed(emscripten_fetch_t *fetch); static void downloadSucceeded(emscripten_fetch_t *fetch); |