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>
The "HTTP RFC 9110 5.3 Field Order" states that the values combined
with comma can be followed up by an optional whitespace, and for
consistency recommends "comma SP". This is also what eg. 'MDN Web
Headers' class does.
Fixes: QTBUG-122650
Pick-to: 6.7
Change-Id: I3391c86018090f0b8721929b64a7e3029e98ac85
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
According to QUIP-18 [1], all tests file should be
LicenseRef-Qt-Commercial OR GPL-3.0-only
[1]: https://contribute.qt-project.org/quips/18
Pick-to: 6.7
Task-number: QTBUG-121787
Change-Id: I9657df5d660820e56c96d511ea49d321c54682e8
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
We need a way for users to consume the complete contents of
QHttpHeaders.
Until now, the only way was
for (const auto &name : h.names())
use(h.value/combinedValue(name));
which is quadratic.
Adding the usual iterators and operator[] would require us to
expose the underlying value_type, which we're not ready to do, yet.
So we added nameAt() and valueAt() functions in previous commits to
enable efficient indexed iteration without the need to expose a
value_type. Having added those, we can now remove names(), which had
the wrong value_type (QByteArrays are by definition UTF-8 in Qt, while
header names are L1), and is no longer needed to facilitate iteration.
In QNetworkRequestFactory, temporarily use toMultiMap() because we
need the combinedValue() of all headers here. The fix will be to make
QNetworkRequest QHttpHeaders-aware, but that's a Qt 6.8 thing, even
though we should still de-pessimize this code for Qt 6.7 with private
API.
Resulted from API-review.
Pick-to: 6.7
Change-Id: I65086ef4c62e22554ae7325a846bebc08b44916f
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
We need a way for users to consume the complete contents of
QHttpHeaders.
For now, the only way is
for (const auto &name : h.names())
use(h.value/combinedValue(name));
which is quadratic.
Adding the usual iterators and operator[] would require us to
expose the underlying value_type, which we're not ready to do, yet.
So add nameAt() and (in a previous commit) valueAt() functions to
enable efficient indexed iteration without the need to expose a
value_type.
Return by QLatin1StringView, not QAnyStringView, because that
statically encodes the actual encoding used (and required by HTTP
specs and promised by the class documentation, so it won't need to
change). For the setters, we want to be accomodating QString,
QByteArray, etc, which is why those take QAnyStringView.
Resulted from API-review.
Pick-to: 6.7
Change-Id: I0153c5aad0f6260b5dbc963de0aaf4ef42fdd4f1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
We need a way for users to consume the complete contents of
QHttpHeaders.
For now, the only way is
for (const auto &name : h.names())
use(h.value/combinedValue(name));
which is quadratic.
Adding the usual iterators and operator[] would require us to
expose the underlying value_type, which we're not ready to do, yet.
So add valueAt() and (in a follow-up) nameAt() functions to enable
efficient indexed iteration without the need to expose a value_type.
Resulted from API-review
Pick-to: 6.7
Change-Id: I863f59618cea5682386ce26b66b4b1655eac7950
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
A QMultiMap is used, while only qset.h is included.
FTBFS w/o precompiled headers.
Include qmap.h as well.
Pick-to: 6.7 6.6 6.5
Change-Id: I5f6e1d204bfa94cc6a81f6883c7a7b0ee1e9963c
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
There's several ways to compare HTTP headers, and arguably
the need for it is not very high. For the time being users can use
different accessors and compare in ways that make sense for
their use cases.
Consequently since HTTP headers are no longer trivially comparable,
it makes also comparing the request factories more 'moot' because
headers are a central piece of request information. So removed
comparison from request factory as well.
These comparisons can be restored later if a clear understanding
on it's need, and on how it should be best done, emerges.
Resulted from API-review
Pick-to: 6.7
Change-Id: Idb5ab3710268b52a8e59656db8cc7de82f0ae511
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
The vast majority of header fields appear only once, but there was no
efficient way to get that value: values() returns as a
QList<QByteArray> (allocating) while combinedValue() returns a
QByteArray constructed from values().join() (also allocating).
It follows that the QHttpHeaders API is incomplete (lacks an efficient
basis of operations in EoP terms).
Add a value() function that returns either the value or a
user-provided fall-back as a QByteArrayView. Unlike values() and
combinedValue(), this function can be noexcept, greatly improving
codegen for callers.
Found in API review.
Pick-to: 6.7
Task-number: QTBUG-107042
Change-Id: I2da20815fd46fdd7f150c224f41eee53abed313e
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Clean up the C'n'P in the test a bit before adding tests of new
functions.
Pick-to: 6.7
Task-number: QTBUG-107042
Change-Id: I2da20815fd46fdd7f150c224f41eee53abed313d
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
New QHttpHeaders class for use in place of
std::pair<QBA,QBA>, QMap<QBA>, and QMultiMap/Hash<QBA,QBA>
to represent HTTP headers.
[ChangeLog][QtNetwork][QHttpHeaders] New QHttpHeaders class
Task-number: QTBUG-107042
Change-Id: I54766886a491acfc9a813a3414322a75011acb9d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>