Change QFormDataBuilderPrivate to store a vector of
QFormDataPartBuilderPrivates and pimplify QFormDataPartBuilder such that
it stores a pointer to the QFormDataBuilderPrivate and an index into the
vector. This makes it robust against QFDP::m_parts reallocations and we
can make QFDBP copyable which has the benefit that if the user wants to
"go back" to an earlier part, she can do so by storing the result of the
original part() call by value.
Found in API review.
Task-number: QTBUG-125985
Change-Id: I56e9018e539457e9494751bdb62509f84a680889
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit aca8235c753d673abe7442cdf8b628fe4e05c471)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We have the encrypted() signal that lets users do extra checks on the
established connection. It is emitted as BlockingQueued, so the HTTP
thread stalls until it is done emitting. Users can potentially call
abort() on the QNetworkReply at that point, which is passed as a Queued
call back to the HTTP thread. That means that any currently queued
signal emission will be processed before the abort() call is processed.
In the case of HTTP2 it is a little special since it is multiplexed and
the code is built to start requests as they are available. This means
that, while the code worked fine for HTTP1, since one connection only
has one request, it is not working for HTTP2, since we try to send more
requests in-between the encrypted() signal and the abort() call.
This patch changes the code to delay any communication until the
encrypted() signal has been emitted and processed, for HTTP2 only.
It's done by adding a few booleans, both to know that we have to return
early and so we can keep track of what events arose and what we need to
resume once enough time has passed that any abort() call must have been
processed.
Fixes: QTBUG-126610
Pick-to: 6.7 6.5 6.2 5.15 5.12
Change-Id: Ic25a600c278203256e35f541026f34a8783235ae
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit b1e75376cc3adfc7da5502a277dfe9711f3e0536)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't want to have to rely on QDebug:toString() and the private
QFormDataPartBuilder::build() function for checks, so use the
framework originally introduced by Máté for the the moveSemantics()
test for picksUtf8NameEncodingIfAsciiDoesNotSuffice(), too.
Requires to revert the needles from QString back to QByteArray.
This completes the port away from QFormDataPartBuilder::build() use in
the tests, allowing us to remove the tst_QFormDataBuilder friend
declaration and unexport build().
Task-number: QTBUG-125985
Change-Id: Icae84f54c6f768e097b36b4c4f964eeb6d676809
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit d0b0fe76663a4c7fe007cb66afa936ea7fe3d918)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't want to have to rely on QDebug:toString() and the private
QFormDataPartBuilder::build() function for checks, so use the
framework originally introduced by Máté for the the moveSemantics()
test for specifyMimeType(), too.
Requires to actually open the QBuffer and to revert the needles from
QString back to QByteArray.
Also anchor the needle between two CRLFs, because they each represent
one full header field. This is like anchoring a regex with ^~~~$.
As a drive-by, use QVERIFY2().
Task-number: QTBUG-125985
Change-Id: I8f7830e49d05044ef7388338498c96334a489c90
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 9bcf320fc1d3b484a39d692fd2c69c96f05e63e4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't want to have to rely on QDebug:toString() and the private
QFormDataPartBuilder::build() function for checks, so use the
framework originally introduced by Máté for the the moveSemantics()
test for setHeadersDoesNotAffectHeaderFieldsManagedByBuilder(), too.
Requires to actually open the QBuffer and to revert the needles from
QString back to QByteArray.
Also anchor the needles with a CRLF on each side, because they each
represent one full header field. This is like anchoring a regex using
^~~~$.
As a drive-by, fix indentation and brace placement of initializer_list
QList consruction and rely on CTAD to deduce QByteArrayList from QList{}.
Task-number: QTBUG-125985
Change-Id: I405b5d67212e906a3b914d9e5b815835bdee5bc6
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit ab859d5f96855eeec50f3b39c925203ba7def73f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't want to have to rely on QDebug:toString() and the private
QFormDataPartBuilder::build() function for checks, so use the
framework originally introduced by Máté for the the moveSemantics()
test for picksUtf8FilenameEncodingIfAsciiDontSuffice(), too.
Requires to actually open the QBuffer and to revert the needles from
QString back to QByteArray.
Task-number: QTBUG-125985
Change-Id: I13c41e8df86296ae8652c460039798eb529d4628
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 2541f1945d2a64de7b2c13465a178ef70d96da89)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't want to have to rely on QDebug:toString() and the private
QFormDataPartBuilder::build() function for checks, so use the
framework originally introduced by Máté for the the moveSemantics()
test for escapesBackslashAndQuotesInFilenameAndName(), too.
Requires to actually open dummy_file (so make it a QBuffer, because
there's no file of that name in the filesystem) and to revert the
needles from QString back to QByteArray.
Task-number: QTBUG-125985
Change-Id: I888b3cac45ed24b2e877dc1642a95e3f1d64f2ff
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 14f68c9d44472966a66b5cf3b16f4fc7f60068ca)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't want to have to rely on QDebug:toString() and the private
QFormDataPartBuilder::build() function for checks, so use the
framework originally introduced by Máté for the the moveSemantics()
test for generateQHttpPartWithDevice(), too.
Requires to actually open data_file and to revert the needles from
QString back to QByteArray.
Task-number: QTBUG-125985
Change-Id: Ie4518fedb58530ae98b44f1ba9e000e6f088ba86
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 4b21146ded83badfeb9f2c905f6602ff460adc63)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Packages everything needed to build the actual serialization into a
helper function that's parametrized with a function_ref. Said helper
provides the function_ref with a default-constructed QFormDataBuilder
as an argument to the function, but since we're checking move
semantics here, it also expects to receive, via the return type, the
builder object to eventually use for building. This need not be the
same as the one it originally supplied.
If this looks a bit complicated, it's a necessary evil for
conveniently rolling out this way of performing the test to the rest
of the test functions, to eventually, finally get rid of using QDebug
to introspect individual QHttpParts when, in reality, we're only
interested in the QHttpMultiPart's wire serialization (iow: the
observable behavior).
Centralize the QSKIP in the helper function. This increases compile
coverage of the rest of the code, but requires QTEST_THROW_ON_SKIP,
so add a check for that alongside the QTEST_THROW_ON_FAIL one.
Task-number: QTBUG-125985
Change-Id: Ib6217a02159c79f48f0036e90d7bbbf43e69d0ba
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 9fcafa715ecb1c6e45fc51d599178bbde3cc1b12)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
... so we don't have to guess around when the follow-up
checkBodyPartsAreEquivalent() fails.
Task-number: QTBUG-125985
Change-Id: I008eb7a1fa1c5457a5405838730d9e98b1cc20b4
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 4da130838ba0a0f4f7c659f8c58f7bb4304b032c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
And adjust the encoding of 'name' parameter to always
use UTF-8 / ASCII. This aligns with how other frameworks
behave. Also amended docs to recommend ASCII for 'name'.
Found in API review.
Change-Id: I54d1148bf95dece54b75c76914c49985da05e0b2
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 6b23a3c5e4316c5f889ea5e9bbfd785b78716268)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The RFCs around these encodings are loose and allow
several ways for dealing with non-ASCII characters.
The encoding introduced in this commit should be
interoperable and aligns with other frameworks
(checked Curl, JS FormData, Postman, and Python
requests).
This consists of several adjustments:
1. Enclose the filename attribute in double quotes
2. If filename contains only ASCII characters, use them as-is
3. If filename contains characters beyond ASCII:
3.1. Encode them directly as raw UTF-8 to filename=
3.2. Set an additional filename*= parameter with
percent encoded UTF-8. This is a legacy encoding
for compatibility.
Task-number: QTBUG-125985
Change-Id: I5a6ad5388e4bb69e142caa7f6de7127526f441ad
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 8c8a0c06d4f77ba8a707ec0a101b423543bf30f0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Hide the construction details of QFormDataPartBuilder, change
the verification to be QString based instead of QByteArray based,
and use raw string literals (where useful) for readability.
Task-number: QTBUG-114647
Change-Id: I16fb6c943cf6fd7385e78bbffe3b2780ab0a6ac8
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit cb8abb718da4e18232de525ef1bb611f3a5dd929)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
UTF-8 doesn't per se contain illegal characters from
an HTTP header RFC point of view. UTF-8 is the dominant
character encoding outside of ASCII, and is used
directly at least with HTTP multipart headers.
[ChangeLog][QtNetwork][QHttpHeaders] Allows UTF-8 in header
values now.
Task-number: QTBUG-125985
Pick-to: 6.7
Change-Id: I2d8d8f00855c96c1d2ba190f2e27e2d48fcd4975
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit f39b39b8c72b5c3428396d5e74cf15cafd5bbc42)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The test requires allocating 4GB of memory to handle a big file.
On a 32b architecture, this leads to a std::bad_alloc exception and
abort in result (tested on VxWorks 24.03 on an imx6 board).
Because of that, the test can't work properly and it can't be
blacklisted.
Work around the issue by skipping the test.
Pick-to: 6.7
Task-number: QTBUG-115777
Change-Id: I46002a27aed09706cd61d2e2c8d4bd1e12a16c36
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 4d2744e4345193cdf7ec2bbf06b0a0d169827d8b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Test the setHeaders method and the option of manually setting the mime
type.
Task-number: QTBUG-114647
Change-Id: I86644b243830259156e60239adf370e5894450dc
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit 132498a69a626be6feaf1855cf63dd79d1ac9445)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Version 903a83ff7bfc3148e3692e09396f9f3bdc9462ef, fetched on
2024-06-05.
[ChangeLog][Third-Party Code] Updated the public suffix list to upstream
SHA 903a83ff7bfc3148e3692e09396f9f3bdc9462ef.
Pick-to: 6.7 6.5 6.2 5.15
Task-number: QTBUG-126060
Change-Id: I96320b5df1a3573ab9198ad412fc1eca55204c02
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit c0d5c1b2fef140a44b6512ee79ba7fb67187a39c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't need the bodyName member, because it's the same as
originalBodyName, just encoded, and we can delay the encoding to
build() time.
This is not worse than the old code, since we anyway toString() the
QAnyStringView unconditionally.
So we don't need to visit the QASV and implement RFC2232 encoding for
all three view types, we can just use the QString version, after
toString().
This not only has the advantage of less code and not storing duplicate
data, but we now also encode u8"ä.txt" the same as "ä.txt"_L1 and
u"ä.txt", ie. using latin1, as required by Postel's Law, and not as
UTF-8, as the old code did.
Change-Id: If82a33a1cd09b859b3a4450a60083b1d3aedf7bc
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Constructing and composing a QHttpMultipart contains some aspects that
are possible candidates for automating, such as setting the headers
manually for each included part. As a reference, when issuing a default
multipart with CURL, one does not need to manually set the headers.
Add the class QFormDataPartBuilder to simplify the construction of
QHttpPart objects.
Add the class QFormDataBuilder to simplify the construction of
QHttpMultiPart objects.
[ChangeLog][QtNetwork][QFormDataBuilder] New class to help constructing
multipart/form-data QHttpMultiParts.
Fixes: QTBUG-114647
Change-Id: Ie035dabc01a9818d65a67c239807b50001fd984a
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
[ChangeLog][QtNetwork][QNetworkAccessManager] QNetworkAccessManager now
supports using full local server name, as in, named pipes on Windows or path to
socket objects on Unix.
Task-number: QTBUG-102855
Change-Id: Ifc743f5025b3d8d0b558ecffff437881897915d9
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Nothing there should rely on the network testing server.
Part of this will also be testing the local/unix domain socket support.
Task-number: QTBUG-102855
Change-Id: Icf3b0bd9370ec62e003862caf4cd3ed38d875bac
Reviewed-by: Mate Barany <mate.barany@qt.io>
Functional fix will come later via separate tasks.
Task-number: QTBUG-122999
Change-Id: Ib805740c87ff21cea5a186add71cc594ab4d4df1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Replace QNetworkHeadersPrivate's main headers storage, which was
RawHeadersList, with QHttpHeaders. Replace internal usage of raw and
cooked header methods with the QHttpHeaders API.
[ChangeLog][QtNetwork][QNetworkRequest] Header value added by
QNetworkRequest::setRawHeader() method is trimmed now.
Task-number: QTBUG-107751
Change-Id: I8882978afa430651e6c798a4fed00beef6c4cfd2
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Now developer build tests compile, but some are not working.
Functional fix will come later via separate tasks.
Task-number: QTBUG-122999
Change-Id: I70487b46c1b32ba4279cb02a4978e4f55ac0d310
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
As part of QTBUG-114647 we are planning to introduce a deduction
mechanism that could deduce the contentType header and the
contentDisposition headers based on the arguments (and the MIME
database).
In case of non-trivial types this deduction may give the wrong result
and without QDebug support it might be a bit tedious to check.
The debug output displays some information about the body device if
one is attached, otherwise it displays the size of the body.
Task-number: QTBUG-114647
Change-Id: Ia693b078ff5b9f8ea57fbf3c385edaec47886ff1
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This is RFC2822 grammar (except that line folding is not
allowed).
RFC9110 doesn't allow it anymore, but it might make sense to accept it
nonetheless (Postel's Law).
Pick-to: 6.7
Task-number: QTBUG-123544
Change-Id: Ie990cd332c7603dbdae29c19b2804bd33a058ca0
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
[ChangeLog][QtNetwork][QNetworkCacheMetaData] Added headers() and
setHeaders() methods to QNetworkCacheMetaData to provide an interface
to work with QHttpHeaders.
Task-number: QTBUG-107751
Change-Id: I1dfed5c2e03f4912de0da96156425cd6b713c1d5
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
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>
The old code was based on QString::split and e.g. didn't handle
escapes in quoted-strings.
Write a modern recursive-descent parser to parse out type/subtype and
charset parameter. Since we don't, yet, support CFWS (see below),
recursion depth is strictly limited, so we're not susceptible to
recursion bombs here.
It currently handles only RFC9110-style grammar, but can be easily
extended to support CFWS (RFC2822-style comments and folding
white-space) or RFC2231-style continuuations, if needed.
It's a bit more general than strictly required, because I expect this
to be reused elsewhere ere long.
Pick-to: 6.7
Fixes: QTBUG-120307
Change-Id: I309928dc350a043672dffb4a259b457764c031be
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
... incl. some that fail.
This is in preparation of a patch that makes the parser more
compliant.
Pick-to: 6.7
Task-number: QTBUG-120307
Change-Id: Ic47b23132f2a7ea81b6c480bfb036bc2daff05da
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
When adding/fixing parts earlier it was missed that it was not handling
the _unsupported_ case, when authentication is not handled and there is
no resend. But there _is_ a challenge header.
Pick-to: 6.7 6.6 6.5
Fixes: QTBUG-123891
Change-Id: I21470df0ce2528bad3babffc6e9f19b7afd29d20
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Virtually all callers of this function (will) pass rvalues, so take
the std::function by value (reaping C++17 guaranteed copy elision) and
std::move() into the member variable ("perfect sink").
Like for many owning types, moves are much cheaper than copies for
std::function, because the external state is merely tranferred between
objects, and not copied.
Amends e560adef21.
Pick-to: 6.7
Change-Id: I269b54e51ba09ac595ac4e4f255209778819adad
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
HttpTestServer::Handler is declared to take the first argument by
reference to const, not by value, so use the same parameter passing
for the lambdas passed to setHandler().
Avoids copying the (rather large) argument when invoked through the
std::function wrapper, and silences clazy-function-args-by-ref.
Pick-to: 6.7
Change-Id: I726d0b98a7fcb3b1b33c5bde203035f593c39bdd
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Move some deleteLater() calls to before the first QCOMPARE/QVERIFY
macros, so they get executed even if the macros return on failure.
This isn't an all-encompassing solution, but I lack the time to port
all this to smart pointers, and this is some improvement.
As a drive-by, port QVERIFY(opt.has_value()) to QCOMPARE(opt, nullopt).
Task-number: QTBUG-120307
Pick-to: 6.7
Change-Id: Ia5a2cabd273a779938b22badc91b109fcc545203
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
We want to get rid of the other one, it's all internal
API anyway.
Task-number: QTBUG-102855
Change-Id: I2b621c20f4dd7c8bf5f07db8db908c2b7b86976f
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
In some cases calls to QFile::open are made outside of a testfunction
(so we can't use QVERIFY), or even in standalone executables that are
executed by tests. Make them fail "visibly".
Change-Id: Iec4d56f6d874be16aa2e9ad6974eeec2a98caa3f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
It was overlooked in testing, but it would emit a signal for new
incoming stream even if the server was just replying with HEADERS on a
stream the client had initiated. Or vice-versa.
Pick-to: 6.7
Change-Id: Ie7b3a45729a78106da1d8c058e15705cc7dcc53b
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Wrap the call in QVERIFY.
tst_QTextStream::read0d0d0a was also faulty as it *never* opened
the file because of a broken path. Fix it with QFINDTESTDATA.
Change-Id: I61a8f83beddf098d37fda13cb3bfb4aaa4913fc5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The old code allocated QSignalSpies on the heap and stored them in a
non-owning container, so if one of the many check macros trigger,
those objects would be leaked. Ditto QNetworkReplies. The code also
used dynamically-sized containers for statically-sized data; a common
anti-pattern.
Hold the sample QUrls in a C array instead, QSignalSpies in C arrays
of std::optional (to delay initialization) and QNetworkReplies in a C
array of std::unique_ptr with the existing QScopedPointerDeleteLater
deleter.
Pick-to: 6.7
Change-Id: I7305115af15c079abba6d45c5de8db2198ea7a6d
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Turn the QSignalSpy deletions from deferred (via deleteLater()) into
immediate ones. This is ok: QSignalSpy is using itself as a context
object in QMetaObject::connect(), so the connection thus established
to the monitored signal will be atomically severed if either sender or
receiver are destroyed. There never was a need to defer deletion of
the signal spy, so don't.
Found by making QSignalSpy's inheritance from QObject private.
Pick-to: 6.7 6.6 6.5
Change-Id: I962d28c3a78f356d234324fed68716f2f1052100
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
We have implemented the same functionality recently for POST, in this
patch implement it for PUT.
Task-number: QTBUG-108309
Change-Id: I34c41538054fec836d0d1d1dbb44fabab9bc0e9a
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Actually this has already worked if a nullptr was casted as a
QIODevice*. Add an overload with a nullptr_t type, that does
this behind the scenes.
Fixes: QTBUG-108309
Change-Id: I2d4b17ae94cf4de2c42257d471ef901c8994fee5
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>