Add QHttpHeaders to QNetworkRequest
Added headers() and setHeaders() methods to QNetworkRequest. [ChangeLog][QtNetwork][QNetworkRequest] Added headers() and setHeaders() methods to QNetworkRequest, which provide an interface to work with QHttpHeaders. Task-number: QTBUG-107751 Change-Id: I2e1dc7cb2efab5903eb7ff23b75d01aefe13273d Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>bb10
parent
979836382e
commit
fa456ad550
|
|
@ -22,6 +22,7 @@ qt_internal_add_module(Network
|
|||
access/qnetworkfile.cpp access/qnetworkfile_p.h
|
||||
access/qhttpheaders.cpp access/qhttpheaders.h
|
||||
access/qhttpheaderparser.cpp access/qhttpheaderparser_p.h
|
||||
access/qhttpheadershelper.cpp access/qhttpheadershelper_p.h
|
||||
access/qnetworkreply.cpp access/qnetworkreply.h access/qnetworkreply_p.h
|
||||
access/qnetworkreplydataimpl.cpp access/qnetworkreplydataimpl_p.h
|
||||
access/qnetworkreplyfileimpl.cpp access/qnetworkreplyfileimpl_p.h
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
#ifndef QHTTPHEADERS_H
|
||||
#define QHTTPHEADERS_H
|
||||
|
||||
#include <QtNetwork/qnetworkrequest.h>
|
||||
#include <QtNetwork/qtnetworkglobal.h>
|
||||
#include <QtCore/qmetaobject.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#include "qhttpheadershelper_p.h"
|
||||
|
||||
#include <QtNetwork/qhttpheaders.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
bool QHttpHeadersHelper::compareStrict(const QHttpHeaders &left, const QHttpHeaders &right)
|
||||
{
|
||||
if (left.size() != right.size())
|
||||
return false;
|
||||
|
||||
for (qsizetype i = 0; i < left.size(); ++i) {
|
||||
if (left.nameAt(i) != right.nameAt(i))
|
||||
return false;
|
||||
if (left.valueAt(i) != right.valueAt(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#ifndef QHTTPHEADERSHELPER_H
|
||||
#define QHTTPHEADERSHELPER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Network Access API. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpHeaders;
|
||||
|
||||
namespace QHttpHeadersHelper {
|
||||
Q_NETWORK_EXPORT bool compareStrict(const QHttpHeaders &left, const QHttpHeaders &right);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPHEADERSHELPER_H
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
#include "qplatformdefs.h"
|
||||
#include "qnetworkcookie.h"
|
||||
#include "qsslconfiguration.h"
|
||||
#include "qhttpheadershelper_p.h"
|
||||
#if QT_CONFIG(http)
|
||||
#include "qhttp1configuration.h"
|
||||
#include "qhttp2configuration.h"
|
||||
|
|
@ -475,6 +476,7 @@ public:
|
|||
&& decompressedSafetyCheckThreshold == other.decompressedSafetyCheckThreshold
|
||||
#endif
|
||||
&& transferTimeout == other.transferTimeout
|
||||
&& QHttpHeadersHelper::compareStrict(httpHeaders, other.httpHeaders)
|
||||
;
|
||||
// don't compare cookedHeaders
|
||||
}
|
||||
|
|
@ -600,6 +602,43 @@ void QNetworkRequest::setUrl(const QUrl &url)
|
|||
d->url = url;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.8
|
||||
|
||||
Returns headers that are set in this network request.
|
||||
|
||||
\sa setHeaders()
|
||||
*/
|
||||
QHttpHeaders QNetworkRequest::headers() const
|
||||
{
|
||||
return d->headers();
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.8
|
||||
|
||||
Sets \a newHeaders as headers in this network request, overriding
|
||||
any previously set headers.
|
||||
|
||||
If some headers correspond to the known headers, the values will
|
||||
be parsed and the corresponding parsed form will also be set.
|
||||
|
||||
\sa headers(), KnownHeaders
|
||||
*/
|
||||
void QNetworkRequest::setHeaders(QHttpHeaders &&newHeaders)
|
||||
{
|
||||
d->setHeaders(std::move(newHeaders));
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 6.8
|
||||
*/
|
||||
void QNetworkRequest::setHeaders(const QHttpHeaders &newHeaders)
|
||||
{
|
||||
d->setHeaders(newHeaders);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the value of the known network header \a header if it is
|
||||
present in this request. If it is not present, returns QVariant()
|
||||
|
|
@ -1401,6 +1440,33 @@ void QNetworkHeadersPrivate::setCookedHeader(QNetworkRequest::KnownHeaders heade
|
|||
}
|
||||
}
|
||||
|
||||
QHttpHeaders QNetworkHeadersPrivate::headers() const
|
||||
{
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
void QNetworkHeadersPrivate::setHeaders(const QHttpHeaders &newHeaders)
|
||||
{
|
||||
httpHeaders = newHeaders;
|
||||
}
|
||||
|
||||
void QNetworkHeadersPrivate::setHeaders(QHttpHeaders &&newHeaders)
|
||||
{
|
||||
httpHeaders = std::move(newHeaders);
|
||||
}
|
||||
|
||||
void QNetworkHeadersPrivate::setHeader(QHttpHeaders::WellKnownHeader name, QByteArrayView value)
|
||||
{
|
||||
httpHeaders.replaceOrAppend(name, value);
|
||||
}
|
||||
|
||||
void QNetworkHeadersPrivate::clearHeaders()
|
||||
{
|
||||
httpHeaders.clear();
|
||||
rawHeaders.clear();
|
||||
cookedHeaders.clear();
|
||||
}
|
||||
|
||||
void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const QByteArray &value)
|
||||
{
|
||||
auto firstEqualsKey = [&key](const RawHeaderPair &header) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#define QNETWORKREQUEST_H
|
||||
|
||||
#include <QtNetwork/qtnetworkglobal.h>
|
||||
#include <QtNetwork/qhttpheaders.h>
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUrl>
|
||||
|
|
@ -119,6 +120,10 @@ public:
|
|||
QUrl url() const;
|
||||
void setUrl(const QUrl &url);
|
||||
|
||||
QHttpHeaders headers() const;
|
||||
void setHeaders(const QHttpHeaders &newHeaders);
|
||||
void setHeaders(QHttpHeaders &&newHeaders);
|
||||
|
||||
// "cooked" headers
|
||||
QVariant header(KnownHeaders header) const;
|
||||
void setHeader(KnownHeaders header, const QVariant &value);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/qhttpheaders.h>
|
||||
#include "qnetworkrequest.h"
|
||||
#include "QtCore/qbytearray.h"
|
||||
#include "QtCore/qlist.h"
|
||||
|
|
@ -36,6 +37,7 @@ public:
|
|||
typedef QHash<QNetworkRequest::Attribute, QVariant> AttributesMap;
|
||||
|
||||
RawHeadersList rawHeaders;
|
||||
QHttpHeaders httpHeaders;
|
||||
CookedHeadersMap cookedHeaders;
|
||||
AttributesMap attributes;
|
||||
QPointer<QObject> originatingObject;
|
||||
|
|
@ -47,6 +49,13 @@ public:
|
|||
void setAllRawHeaders(const RawHeadersList &list);
|
||||
void setCookedHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
|
||||
|
||||
QHttpHeaders headers() const;
|
||||
void setHeaders(const QHttpHeaders &newHeaders);
|
||||
void setHeaders(QHttpHeaders &&newHeaders);
|
||||
void setHeader(QHttpHeaders::WellKnownHeader name, QByteArrayView value);
|
||||
|
||||
void clearHeaders();
|
||||
|
||||
static QDateTime fromHttpDate(const QByteArray &value);
|
||||
static QByteArray toHttpDate(const QDateTime &dt);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ add_subdirectory(qrestaccessmanager)
|
|||
if(QT_FEATURE_private_tests)
|
||||
add_subdirectory(qhttp2connection)
|
||||
add_subdirectory(qhttpheaderparser)
|
||||
add_subdirectory(qhttpheadershelper)
|
||||
add_subdirectory(qhttpnetworkconnection)
|
||||
add_subdirectory(qhttpnetworkreply)
|
||||
add_subdirectory(hpack)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(tst_qhttpheadershelper LANGUAGES CXX)
|
||||
find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
|
||||
endif()
|
||||
|
||||
qt_internal_add_test(tst_qhttpheadershelper
|
||||
SOURCES
|
||||
tst_qhttpheadershelper.cpp
|
||||
LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include <QtNetwork/qhttpheaders.h>
|
||||
#include <QtNetwork/private/qhttpheadershelper_p.h>
|
||||
|
||||
#include <QtTest/qtest.h>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
class tst_QHttpHeadersHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void testCompareStrict();
|
||||
|
||||
private:
|
||||
static constexpr QAnyStringView n1{"name1"};
|
||||
static constexpr QAnyStringView n2{"name2"};
|
||||
static constexpr QAnyStringView v1{"value1"};
|
||||
static constexpr QAnyStringView v2{"value2"};
|
||||
static constexpr QAnyStringView N1{"NAME1"};
|
||||
static constexpr QAnyStringView N2{"NAME2"};
|
||||
static constexpr QAnyStringView V1{"VALUE1"};
|
||||
static constexpr QAnyStringView V2{"VALUE2"};
|
||||
};
|
||||
|
||||
void tst_QHttpHeadersHelper::testCompareStrict()
|
||||
{
|
||||
using namespace QHttpHeadersHelper;
|
||||
|
||||
// Basic comparisons
|
||||
QHttpHeaders h1;
|
||||
QHttpHeaders h2;
|
||||
QVERIFY(compareStrict(h1, h2)); // empties
|
||||
h1.append(n1, v1);
|
||||
QVERIFY(compareStrict(h1, h1)); // self
|
||||
h2.append(n1, v1);
|
||||
QVERIFY(compareStrict(h1, h2));
|
||||
h1.append(n2, v2);
|
||||
QVERIFY(!compareStrict(h1, h2));
|
||||
h1.removeAll(n2);
|
||||
QVERIFY(compareStrict(h1, h2));
|
||||
|
||||
// Order-sensitivity
|
||||
h1.clear();
|
||||
h2.clear();
|
||||
// Same headers but in different order
|
||||
h1.append(n1, v1);
|
||||
h1.append(n2, v2);
|
||||
h2.append(n2, v2);
|
||||
h2.append(n1, v1);
|
||||
QVERIFY(!compareStrict(h1, h2));
|
||||
|
||||
// Different number of headers
|
||||
h1.clear();
|
||||
h2.clear();
|
||||
h1.append(n1, v1);
|
||||
h2.append(n1, v1);
|
||||
h2.append(n2, v2);
|
||||
QVERIFY(!compareStrict(h1, h2));
|
||||
|
||||
// Same header name, multiple values
|
||||
h1.clear();
|
||||
h2.clear();
|
||||
h1.append(n1, v1);
|
||||
h1.append(n1, v2);
|
||||
h2.append(n1, v1);
|
||||
QVERIFY(!compareStrict(h1, h2));
|
||||
h2.append(n1, v2);
|
||||
QVERIFY(compareStrict(h1, h2));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHttpHeadersHelper)
|
||||
#include "tst_qhttpheadershelper.moc"
|
||||
|
|
@ -31,6 +31,8 @@ private slots:
|
|||
void rawHeaderParsing_data();
|
||||
void rawHeaderParsing();
|
||||
void originatingObject();
|
||||
void setHeaders_data();
|
||||
void setHeaders();
|
||||
|
||||
void removeHeader();
|
||||
};
|
||||
|
|
@ -552,5 +554,32 @@ void tst_QNetworkRequest::originatingObject()
|
|||
QVERIFY(!request.originatingObject());
|
||||
}
|
||||
|
||||
void tst_QNetworkRequest::setHeaders_data()
|
||||
{
|
||||
QTest::addColumn<QHttpHeaders>("h");
|
||||
QTest::newRow("null") << QHttpHeaders();
|
||||
QHttpHeaders headers;
|
||||
headers.append("name1", "value1");
|
||||
QTest::newRow("valid") << headers;
|
||||
}
|
||||
|
||||
void tst_QNetworkRequest::setHeaders()
|
||||
{
|
||||
QFETCH(QHttpHeaders, h);
|
||||
|
||||
QNetworkRequest r1;
|
||||
|
||||
auto result = r1.headers();
|
||||
QVERIFY(result.isEmpty());
|
||||
|
||||
r1.setHeaders(h);
|
||||
QCOMPARE(r1.headers().toListOfPairs(), h.toListOfPairs());
|
||||
|
||||
QNetworkRequest r2;
|
||||
auto tmp = h;
|
||||
r2.setHeaders(std::move(tmp));
|
||||
QCOMPARE(r2.headers().toListOfPairs(), h.toListOfPairs());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QNetworkRequest)
|
||||
#include "tst_qnetworkrequest.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue