From 60f471f4b6269827fe2fcaa1f8fbe73db4abe8eb Mon Sep 17 00:00:00 2001 From: Juha Vuolle Date: Wed, 7 Feb 2024 12:10:21 +0200 Subject: Replace QHttpHeaders::toListOfPairs() usage with iteration ... as a more computationally effective way, which was not present at the time those usages were introduced. As a drive-by add spaces around a binary operator Task-number: QTBUG-122017 Pick-to: 6.7 Change-Id: I0528c995d1a3c1fe171486c5c313697d1706ee10 Reviewed-by: Marc Mutz --- src/network/access/qhttp2protocolhandler.cpp | 29 +++++++++++++++------------- src/network/access/qhttpnetworkrequest.cpp | 10 +++++----- src/network/access/qnetworkreplyhttpimpl.cpp | 7 +++++-- 3 files changed, 26 insertions(+), 20 deletions(-) (limited to 'src/network/access') diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index f69390e47a..08dfa02624 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -60,9 +60,11 @@ HPack::HttpHeader build_headers(const QHttpNetworkRequest &request, quint32 maxH if (size.second > maxHeaderListSize) return HttpHeader(); // Bad, we cannot send this request ... - const auto requestHeader = request.header().toListOfPairs(); - for (const auto &field : requestHeader) { - const HeaderSize delta = entry_size(field.first, field.second); + const QHttpHeaders requestHeader = request.header(); + for (qsizetype i = 0; i < requestHeader.size(); ++i) { + const auto name = requestHeader.nameAt(i); + const auto value = requestHeader.valueAt(i); + const HeaderSize delta = entry_size(name, value); if (!delta.first) // Overflow??? break; if (std::numeric_limits::max() - delta.second < size.second) @@ -71,18 +73,19 @@ HPack::HttpHeader build_headers(const QHttpNetworkRequest &request, quint32 maxH if (size.second > maxHeaderListSize) break; - if (field.first.compare("connection", Qt::CaseInsensitive) == 0 || - field.first.compare("host", Qt::CaseInsensitive) == 0 || - field.first.compare("keep-alive", Qt::CaseInsensitive) == 0 || - field.first.compare("proxy-connection", Qt::CaseInsensitive) == 0 || - field.first.compare("transfer-encoding", Qt::CaseInsensitive) == 0) + if (name.compare("connection", Qt::CaseInsensitive) == 0 || + name.compare("host", Qt::CaseInsensitive) == 0 || + name.compare("keep-alive", Qt::CaseInsensitive) == 0 || + name.compare("proxy-connection", Qt::CaseInsensitive) == 0 || + name.compare("transfer-encoding", Qt::CaseInsensitive) == 0) continue; // Those headers are not valid (section 3.2.1) - from QSpdyProtocolHandler // TODO: verify with specs, which fields are valid to send .... - // toLower - 8.1.2 .... "header field names MUST be converted to lowercase prior - // to their encoding in HTTP/2. - // A request or response containing uppercase header field names - // MUST be treated as malformed (Section 8.1.2.6)". - header.emplace_back(field.first.toLower(), field.second); + // + // Note: RFC 7450 8.1.2 (HTTP/2) states that header field names must be lower-cased + // prior to their encoding in HTTP/2; header name fields in QHttpHeaders are already + // lower-cased + header.emplace_back(QByteArray{name.data(), name.size()}, + QByteArray{value.data(), value.size()}); } return header; diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp index bc3eb67adc..7a4ffb1684 100644 --- a/src/network/access/qhttpnetworkrequest.cpp +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -112,9 +112,9 @@ QByteArray QHttpNetworkRequest::uri(bool throughProxy) const QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy) { - const QList > fields = request.header().toListOfPairs(); + const QHttpHeaders headers = request.header(); QByteArray ba; - ba.reserve(40 + fields.size()*25); // very rough lower bound estimation + ba.reserve(40 + headers.size() * 25); // very rough lower bound estimation ba += request.methodName(); ba += ' '; @@ -126,10 +126,10 @@ QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request ba += QByteArray::number(request.minorVersion()); ba += "\r\n"; - for (const auto& [name, value] : fields) { - ba += name; + for (qsizetype i = 0; i < headers.size(); ++i) { + ba += headers.nameAt(i); ba += ": "; - ba += value; + ba += headers.valueAt(i); ba += "\r\n"; } if (request.d->operation == QHttpNetworkRequest::Post) { diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 84d9e08b91..a5f2d91f0d 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1364,7 +1364,10 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QHttpHeaders &hm, const bool autoDecompress = request.rawHeader("accept-encoding").isEmpty(); const bool shouldDecompress = isCompressed && autoDecompress; // reconstruct the HTTP header - for (const auto &[key, originValue] : hm.toListOfPairs()) { + for (qsizetype i = 0; i < hm.size(); ++i) { + const auto key = hm.nameAt(i); + const auto originValue = hm.valueAt(i); + QByteArray value = q->rawHeader(key); // Reset any previous "location" header set in the reply. In case of @@ -1398,7 +1401,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QHttpHeaders &hm, value += ", "; } value += originValue; - q->setRawHeader(key, value); + q->setRawHeader({key.data(), key.size()}, value); } q->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode); -- cgit v1.2.3