Add QNetworkRequest attribute support to QNetworkRequestFactory

[ChangeLog][QtNetwork][QNetworkRequestFactory] Add QNetworkRequest
attribute support to QNetworkRequestFactory

Fixes: QTBUG-122397
Change-Id: Ie73f104cdad9f8f0721d8ee28f79095bfb04fb3c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
Juha Vuolle 2024-02-26 11:59:37 +02:00
parent d83b535068
commit 0119f0a43b
4 changed files with 156 additions and 0 deletions

View File

@ -506,6 +506,96 @@ QNetworkRequest::Priority QNetworkRequestFactory::priority() const
return d->priority;
}
/*!
\since 6.8
Sets the value associated with \a attribute to \a value.
If the attribute is already set, the previous value is
replaced. The attributes are set to any future requests
created by this factory.
\sa attribute(), clearAttribute(), clearAttributes(),
QNetworkRequest::Attribute
*/
void QNetworkRequestFactory::setAttribute(QNetworkRequest::Attribute attribute,
const QVariant &value)
{
if (attribute == QNetworkRequest::HttpStatusCodeAttribute
|| attribute == QNetworkRequest::HttpReasonPhraseAttribute
|| attribute == QNetworkRequest::RedirectionTargetAttribute
|| attribute == QNetworkRequest::ConnectionEncryptedAttribute
|| attribute == QNetworkRequest::SourceIsFromCacheAttribute
|| attribute == QNetworkRequest::HttpPipeliningWasUsedAttribute
|| attribute == QNetworkRequest::Http2WasUsedAttribute
|| attribute == QNetworkRequest::OriginalContentLengthAttribute)
{
qCWarning(lcQrequestfactory, "%i is a reply-only attribute, ignoring.", attribute);
return;
}
d.detach();
d->attributes.insert(attribute, value);
}
/*!
\since 6.8
Returns the value associated with \a attribute. If the
attribute has not been set, returns a default-constructed \l QVariant.
\sa attribute(QNetworkRequest::Attribute, const QVariant &),
setAttribute(), clearAttributes(), QNetworkRequest::Attribute
*/
QVariant QNetworkRequestFactory::attribute(QNetworkRequest::Attribute attribute) const
{
return d->attributes.value(attribute);
}
/*!
\since 6.8
Returns the value associated with \a attribute. If the
attribute has not been set, returns \a defaultValue.
\sa attribute(), setAttribute(), clearAttributes(),
QNetworkRequest::Attribute
*/
QVariant QNetworkRequestFactory::attribute(QNetworkRequest::Attribute attribute,
const QVariant &defaultValue) const
{
return d->attributes.value(attribute, defaultValue);
}
/*!
\since 6.8
Clears \a attribute set to this factory.
\sa attribute(), setAttribute()
*/
void QNetworkRequestFactory::clearAttribute(QNetworkRequest::Attribute attribute)
{
if (!d->attributes.contains(attribute))
return;
d.detach();
d->attributes.remove(attribute);
}
/*!
\since 6.8
Clears any attributes set to this factory.
\sa attribute(), setAttribute()
*/
void QNetworkRequestFactory::clearAttributes()
{
if (d->attributes.isEmpty())
return;
d.detach();
d->attributes.clear();
}
QNetworkRequestFactoryPrivate::QNetworkRequestFactoryPrivate()
= default;
@ -539,6 +629,10 @@ QNetworkRequest QNetworkRequestFactoryPrivate::newRequest(const QUrl &url) const
request.setTransferTimeout(transferTimeout);
request.setPriority(priority);
for (const auto &[attribute, value] : attributes.asKeyValueRange())
request.setAttribute(attribute, value);
return request;
}

View File

@ -11,6 +11,7 @@
#include <QtCore/qshareddata.h>
#include <QtCore/qurlquery.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
#include <chrono>
@ -77,6 +78,13 @@ public:
Q_NETWORK_EXPORT void setPriority(QNetworkRequest::Priority priority);
Q_NETWORK_EXPORT QNetworkRequest::Priority priority() const;
Q_NETWORK_EXPORT QVariant attribute(QNetworkRequest::Attribute attribute) const;
Q_NETWORK_EXPORT QVariant attribute(QNetworkRequest::Attribute attribute,
const QVariant &defaultValue) const;
Q_NETWORK_EXPORT void setAttribute(QNetworkRequest::Attribute attribute, const QVariant &value);
Q_NETWORK_EXPORT void clearAttribute(QNetworkRequest::Attribute attribute);
Q_NETWORK_EXPORT void clearAttributes();
private:
#ifndef QT_NO_DEBUG_STREAM
friend Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QNetworkRequestFactory &reply);

View File

@ -20,9 +20,11 @@
#if QT_CONFIG(ssl)
#include <QtNetwork/qsslconfiguration.h>
#endif
#include <QtCore/qhash.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qurl.h>
#include <QtCore/qurlquery.h>
#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
@ -46,6 +48,7 @@ public:
QUrlQuery queryParameters;
QNetworkRequest::Priority priority = QNetworkRequest::NormalPriority;
std::chrono::milliseconds transferTimeout{0};
QHash<QNetworkRequest::Attribute, QVariant> attributes;
};
QT_END_NAMESPACE

View File

@ -27,6 +27,7 @@ private Q_SLOTS:
void timeout();
void userInfo();
void priority();
void attributes();
private:
const QUrl url1{u"http://foo.io"_s};
@ -368,5 +369,55 @@ void tst_QNetworkRequestFactory::priority()
QCOMPARE(request.priority(), QNetworkRequest::HighPriority);
}
void tst_QNetworkRequestFactory::attributes()
{
const auto attribute1 = QNetworkRequest::Attribute::BackgroundRequestAttribute;
const auto attribute2 = QNetworkRequest::User;
QNetworkRequestFactory factory;
QNetworkRequest request;
// Empty factory
QVERIFY(!factory.attribute(attribute1).isValid());
request = factory.createRequest();
QVERIFY(!request.attribute(attribute1).isValid());
// (Re-)set and clear individual attribute
factory.setAttribute(attribute1, true);
QVERIFY(factory.attribute(attribute1).isValid());
QCOMPARE(factory.attribute(attribute1).toBool(), true);
request = factory.createRequest();
QVERIFY(request.attribute(attribute1).isValid());
QCOMPARE(request.attribute(attribute1).toBool(), true);
// Replace previous value
factory.setAttribute(attribute1, false);
QVERIFY(factory.attribute(attribute1).isValid());
QCOMPARE(factory.attribute(attribute1).toBool(), false);
request = factory.createRequest();
QVERIFY(request.attribute(attribute1).isValid());
QCOMPARE(request.attribute(attribute1).toBool(), false);
// Clear individual attribute
factory.clearAttribute(attribute1);
QVERIFY(!factory.attribute(attribute1).isValid());
// Getter default value
QCOMPARE(factory.attribute(attribute2, 111).toInt(), 111); // default value returned
factory.setAttribute(attribute2, 222);
QCOMPARE(factory.attribute(attribute2, 111).toInt(), 222); // actual value returned
factory.clearAttribute(attribute2);
QCOMPARE(factory.attribute(attribute2, 111).toInt(), 111); // default value returned
// Clear attributes
factory.setAttribute(attribute1, true);
factory.setAttribute(attribute2, 333);
QVERIFY(factory.attribute(attribute1).isValid());
QVERIFY(factory.attribute(attribute2).isValid());
factory.clearAttributes();
QVERIFY(!factory.attribute(attribute1).isValid());
QVERIFY(!factory.attribute(attribute2).isValid());
request = factory.createRequest();
QVERIFY(!request.attribute(attribute1).isValid());
QVERIFY(!request.attribute(attribute2).isValid());
}
QTEST_MAIN(tst_QNetworkRequestFactory)
#include "tst_qnetworkrequestfactory.moc"