diff options
author | Juha Vuolle <juha.vuolle@qt.io> | 2024-02-27 10:43:11 +0200 |
---|---|---|
committer | Juha Vuolle <juha.vuolle@qt.io> | 2024-03-07 23:38:09 +0200 |
commit | d8f6425fef1050525480afec662a417a7645c22e (patch) | |
tree | 386232daae4927ab67dbb8d0040ccba36d22e68b /src/network | |
parent | 269187bfa272f9456aad6a6233100d846915f175 (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.cpp | 59 | ||||
-rw-r--r-- | src/network/access/qhttpheaders.h | 3 |
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; |