QH2Connection: Fix issue with unity-build/odr
The static function appeared in two places, and in a unity-build this fails quite visibly. Change-Id: I60000d01194a2c79ca9c101f2a6d3f77f469f1a7 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io> Reviewed-by: Nodir Temirkhodjaev <nodir.temir@gmail.com> (cherry picked from commit a3a48815cc9430d6f5c736a312ea4ea5c0895205) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
be4f933c0a
commit
f6039b08b3
@ -504,6 +504,49 @@ void Decoder::handleStreamError(BitIStream &inputStream)
|
||||
// HTTP2 layer will end with session error/COMPRESSION_ERROR.
|
||||
}
|
||||
|
||||
std::optional<QUrl> makePromiseKeyUrl(const HttpHeader &requestHeader)
|
||||
{
|
||||
constexpr QByteArrayView names[] = { ":authority", ":method", ":path", ":scheme" };
|
||||
enum PseudoHeaderEnum
|
||||
{
|
||||
Authority,
|
||||
Method,
|
||||
Path,
|
||||
Scheme
|
||||
};
|
||||
std::array<std::optional<QByteArrayView>, std::size(names)> pseudoHeaders{};
|
||||
for (const auto &field : requestHeader) {
|
||||
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[index] = field.value;
|
||||
}
|
||||
}
|
||||
|
||||
auto optionalIsSet = [](const auto &x) { return x.has_value(); };
|
||||
if (!std::all_of(pseudoHeaders.begin(), pseudoHeaders.end(), optionalIsSet)) {
|
||||
// All four required, HTTP/2 8.1.2.3.
|
||||
return {};
|
||||
}
|
||||
|
||||
const QByteArrayView method = pseudoHeaders[Method].value();
|
||||
if (method.compare("get", Qt::CaseInsensitive) != 0 &&
|
||||
method.compare("head", Qt::CaseInsensitive) != 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QUrl url;
|
||||
url.setScheme(QLatin1StringView(pseudoHeaders[Scheme].value()));
|
||||
url.setAuthority(QLatin1StringView(pseudoHeaders[Authority].value()));
|
||||
url.setPath(QLatin1StringView(pseudoHeaders[Path].value()));
|
||||
|
||||
if (!url.isValid())
|
||||
return {};
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -18,8 +18,10 @@
|
||||
#include "hpacktable_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -112,6 +114,7 @@ private:
|
||||
FieldLookupTable lookupTable;
|
||||
};
|
||||
|
||||
std::optional<QUrl> makePromiseKeyUrl(const HttpHeader &requestHeader);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -21,49 +21,6 @@ Q_LOGGING_CATEGORY(qHttp2ConnectionLog, "qt.network.http2.connection", QtCritica
|
||||
using namespace Qt::StringLiterals;
|
||||
using namespace Http2;
|
||||
|
||||
static std::optional<QUrl> makeUrl(const HPack::HttpHeader &requestHeader)
|
||||
{
|
||||
constexpr QByteArrayView names[] = { ":authority", ":method", ":path", ":scheme" };
|
||||
enum PseudoHeaderEnum
|
||||
{
|
||||
Authority,
|
||||
Method,
|
||||
Path,
|
||||
Scheme
|
||||
};
|
||||
std::array<std::optional<QByteArrayView>, std::size(names)> pseudoHeaders{};
|
||||
for (const auto &field : requestHeader) {
|
||||
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[index] = field.value;
|
||||
}
|
||||
}
|
||||
|
||||
auto optionalIsSet = [](const auto &x) { return x.has_value(); };
|
||||
if (!std::all_of(pseudoHeaders.begin(), pseudoHeaders.end(), optionalIsSet)) {
|
||||
// All four required, HTTP/2 8.1.2.3.
|
||||
return {};
|
||||
}
|
||||
|
||||
const QByteArrayView method = pseudoHeaders[Method].value();
|
||||
if (method.compare("get", Qt::CaseInsensitive) != 0 &&
|
||||
method.compare("head", Qt::CaseInsensitive) != 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QUrl url;
|
||||
url.setScheme(QLatin1StringView(pseudoHeaders[Scheme].value()));
|
||||
url.setAuthority(QLatin1StringView(pseudoHeaders[Authority].value()));
|
||||
url.setPath(QLatin1StringView(pseudoHeaders[Path].value()));
|
||||
|
||||
if (!url.isValid())
|
||||
return {};
|
||||
return url;
|
||||
}
|
||||
|
||||
QHttp2Stream::QHttp2Stream(QHttp2Connection *connection, quint32 streamID) noexcept
|
||||
: QObject(connection), m_streamID(streamID)
|
||||
{
|
||||
@ -1297,7 +1254,7 @@ void QHttp2Connection::handleContinuedHEADERS()
|
||||
streamIt.value()->handleHEADERS(continuedFrames[0].flags(), decoder.decodedHeader());
|
||||
break;
|
||||
case FrameType::PUSH_PROMISE: {
|
||||
std::optional<QUrl> promiseKey = makeUrl(decoder.decodedHeader());
|
||||
std::optional<QUrl> promiseKey = HPack::makePromiseKeyUrl(decoder.decodedHeader());
|
||||
if (!promiseKey)
|
||||
return; // invalid URL/key !
|
||||
if (m_promisedStreams.contains(*promiseKey))
|
||||
|
@ -1468,54 +1468,12 @@ quint32 QHttp2ProtocolHandler::allocateStreamID()
|
||||
return streamID;
|
||||
}
|
||||
|
||||
static std::optional<QUrl> makeUrl(const HPack::HttpHeader &requestHeader)
|
||||
{
|
||||
constexpr QByteArrayView names[] = { ":authority", ":method", ":path", ":scheme" };
|
||||
enum PseudoHeaderEnum
|
||||
{
|
||||
Authority,
|
||||
Method,
|
||||
Path,
|
||||
Scheme
|
||||
};
|
||||
std::array<std::optional<QByteArrayView>, std::size(names)> pseudoHeaders{};
|
||||
for (const auto &field : requestHeader) {
|
||||
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[index] = field.value;
|
||||
}
|
||||
}
|
||||
|
||||
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 QByteArrayView method = pseudoHeaders[Method].value();
|
||||
if (method.compare("get", Qt::CaseInsensitive) != 0 &&
|
||||
method.compare("head", Qt::CaseInsensitive) != 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QUrl url;
|
||||
url.setScheme(QLatin1StringView(pseudoHeaders[Scheme].value()));
|
||||
url.setAuthority(QLatin1StringView(pseudoHeaders[Authority].value()));
|
||||
url.setPath(QLatin1StringView(pseudoHeaders[Path].value()));
|
||||
|
||||
if (!url.isValid())
|
||||
return {};
|
||||
return url;
|
||||
}
|
||||
|
||||
bool QHttp2ProtocolHandler::tryReserveStream(const Http2::Frame &pushPromiseFrame,
|
||||
const HPack::HttpHeader &requestHeader)
|
||||
{
|
||||
Q_ASSERT(pushPromiseFrame.type() == FrameType::PUSH_PROMISE);
|
||||
|
||||
const auto url = makeUrl(requestHeader);
|
||||
const auto url = HPack::makePromiseKeyUrl(requestHeader);
|
||||
if (!url.has_value())
|
||||
return false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user