summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@qt.io>2024-02-27 10:43:11 +0200
committerJuha Vuolle <juha.vuolle@qt.io>2024-03-07 23:38:09 +0200
commitd8f6425fef1050525480afec662a417a7645c22e (patch)
tree386232daae4927ab67dbb8d0040ccba36d22e68b /src/network
parent269187bfa272f9456aad6a6233100d846915f175 (diff)
Add a QHttpHeaders convenience method for unique header name setting
The function replaces one of the found entries with the new value, and removes any other entries. If no entries are found, a new entry will be appended. The replacement search is done for performance reasons; it's cheaper to replace an existing value. All in all the function is a more convenient and performant alternative for this sequence (which proved to be common while porting QtNetwork internals to QHttpHeaders): header.removeAll(<headername>); header.append(<headername>, <value>); [ChangeLog][QtNetwork][QHttpHeaders] Added replaceOrAppend() convenience method, which either replaces previous entries with a single entry, or appends a new one if no entries existed Fixes: QTBUG-122175 Change-Id: I03957645d7e916a732ac7b8d3ae724bb6b16af87 Reviewed-by: Lena Biliaieva <lena.biliaieva@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpheaders.cpp59
-rw-r--r--src/network/access/qhttpheaders.h3
2 files changed, 62 insertions, 0 deletions
diff --git a/src/network/access/qhttpheaders.cpp b/src/network/access/qhttpheaders.cpp
index 4a65e662cf..c63da899a8 100644
--- a/src/network/access/qhttpheaders.cpp
+++ b/src/network/access/qhttpheaders.cpp
@@ -789,6 +789,7 @@ public:
// we can define common methods which 'detach()' the private itself.
using Self = QExplicitlySharedDataPointer<QHttpHeadersPrivate>;
static void removeAll(Self &d, const HeaderName &name);
+ static void replaceOrAppend(Self &d, const HeaderName &name, const QByteArray &value);
void combinedValue(const HeaderName &name, QByteArray &result) const;
void values(const HeaderName &name, QList<QByteArray> &result) const;
@@ -852,6 +853,23 @@ QByteArrayView QHttpHeadersPrivate::value(const HeaderName &name, QByteArrayView
return defaultValue;
}
+void QHttpHeadersPrivate::replaceOrAppend(Self &d, const HeaderName &name, const QByteArray &value)
+{
+ d.detach();
+ auto it = std::find_if(d->headers.begin(), d->headers.end(), headerNameMatches(name));
+ if (it != d->headers.end()) {
+ // Found something to replace => replace, and then rearrange any remaining
+ // matches to the end and erase them
+ it->value = value;
+ d->headers.erase(
+ std::remove_if(it + 1, d->headers.end(), headerNameMatches(name)),
+ d->headers.end());
+ } else {
+ // Found nothing to replace => append
+ d->headers.append(Header{name, value});
+ }
+}
+
/*!
Creates a new QHttpHeaders object.
*/
@@ -1217,6 +1235,47 @@ bool QHttpHeaders::replace(qsizetype i, WellKnownHeader name, QAnyStringView new
}
/*!
+ \since 6.8
+
+ If QHttpHeaders already contains \a name, replaces its value with
+ \a newValue and removes possible additional \a name entries.
+ If \a name didn't exist, appends a new entry. Returns \c true
+ if successful.
+
+ This function is a convenience method for setting a unique
+ \a name : \a newValue header. For most headers the relative order does not
+ matter, which allows reusing an existing entry if one exists.
+
+ \sa replaceOrAppend(QAnyStringView, QAnyStringView)
+*/
+bool QHttpHeaders::replaceOrAppend(WellKnownHeader name, QAnyStringView newValue)
+{
+ if (isEmpty())
+ return append(name, newValue);
+
+ if (!isValidHttpHeaderValueField(newValue))
+ return false;
+
+ QHttpHeadersPrivate::replaceOrAppend(d, HeaderName{name}, normalizedValue(newValue));
+ return true;
+}
+
+/*!
+ \overload replaceOrAppend(WellKnownHeader, QAnyStringView)
+*/
+bool QHttpHeaders::replaceOrAppend(QAnyStringView name, QAnyStringView newValue)
+{
+ if (isEmpty())
+ return append(name, newValue);
+
+ if (!isValidHttpHeaderNameField(name) || !isValidHttpHeaderValueField(newValue))
+ return false;
+
+ QHttpHeadersPrivate::replaceOrAppend(d, HeaderName{name}, normalizedValue(newValue));
+ return true;
+}
+
+/*!
Returns whether the headers contain header with \a name.
\sa contains(QHttpHeaders::WellKnownHeader)
diff --git a/src/network/access/qhttpheaders.h b/src/network/access/qhttpheaders.h
index fb426eed80..97dc415e55 100644
--- a/src/network/access/qhttpheaders.h
+++ b/src/network/access/qhttpheaders.h
@@ -219,6 +219,9 @@ public:
Q_NETWORK_EXPORT bool replace(qsizetype i, QAnyStringView name, QAnyStringView newValue);
Q_NETWORK_EXPORT bool replace(qsizetype i, WellKnownHeader name, QAnyStringView newValue);
+ Q_NETWORK_EXPORT bool replaceOrAppend(QAnyStringView name, QAnyStringView newValue);
+ Q_NETWORK_EXPORT bool replaceOrAppend(WellKnownHeader name, QAnyStringView newValue);
+
Q_NETWORK_EXPORT bool contains(QAnyStringView name) const;
Q_NETWORK_EXPORT bool contains(WellKnownHeader name) const;