From bbace99e943aec8ddccf2b562da0e7ac72a9d9f6 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Mon, 28 Aug 2023 18:29:46 +0300 Subject: QHttp2ProtocolHandler: reduce allocations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't use QMap for parsing. Indroduce local enum and use it with std::array Change-Id: I60fed6991ac415e4ff3827ae621f2c9b5071dcbe Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/access/qhttp2protocolhandler.cpp | 32 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src/network/access/qhttp2protocolhandler.cpp') diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 3ce4f2229a..9ac3f8fd84 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -1475,30 +1475,40 @@ quint32 QHttp2ProtocolHandler::allocateStreamID() static std::optional makeUrl(const HPack::HttpHeader &requestHeader) { - QMap pseudoHeaders; + constexpr QByteArrayView names[] = { ":authority", ":method", ":path", ":scheme" }; + enum PseudoHeaderEnum + { + Authority, + Method, + Path, + Scheme + }; + std::array, std::size(names)> pseudoHeaders{}; for (const auto &field : requestHeader) { - if (field.name == ":scheme" || field.name == ":path" - || field.name == ":authority" || field.name == ":method") { - if (field.value.isEmpty() || pseudoHeaders.contains(field.name)) + const auto it = std::find(std::begin(names), std::end(names), QByteArrayView(field.name)); + if (it != std::end(names)) { + const auto index = std::distance(std::begin(names), it); + if (field.value.isEmpty() || pseudoHeaders.at(index).has_value()) return {}; - pseudoHeaders[field.name] = field.value; + pseudoHeaders[index] = field.value; } } - if (pseudoHeaders.size() != 4) { + if (!std::all_of(pseudoHeaders.begin(), pseudoHeaders.end(), [](const auto &x) { return x.has_value();})) { // All four required, HTTP/2 8.1.2.3. return {}; } - const QByteArray method = pseudoHeaders[":method"]; + const QByteArrayView method = pseudoHeaders[Method].value(); if (method.compare("get", Qt::CaseInsensitive) != 0 && - method.compare("head", Qt::CaseInsensitive) != 0) + method.compare("head", Qt::CaseInsensitive) != 0) { return {}; + } QUrl url; - url.setScheme(QLatin1StringView(pseudoHeaders[":scheme"])); - url.setAuthority(QLatin1StringView(pseudoHeaders[":authority"])); - url.setPath(QLatin1StringView(pseudoHeaders[":path"])); + url.setScheme(QLatin1StringView(pseudoHeaders[Scheme].value())); + url.setAuthority(QLatin1StringView(pseudoHeaders[Authority].value())); + url.setPath(QLatin1StringView(pseudoHeaders[Path].value())); if (!url.isValid()) return {}; -- cgit v1.2.3