Add test to ensure that a route can be added that will be executed
asynchronously and can send back data to the client in multiple parts.
Task-number: QTBUG-108127
Change-Id: I3262da98559ff1a458e0305dff729da8538ecae5
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Add support for route handlers that return QFuture<void> and
respond using QHttpServerResponder&& argument in another thread.
For an HTTP/2 connection multiple requests can be responded to at
the same time, but for an HTTP/1.x connection the requests are
handled one at a time in the order they appear. For CPU intensive
requests the HTTP/1.x connections can still benefit from the
QHttpServer thread being relieved of the work.
The socket I/O is always handled in the thread that QHttpServer
belongs to.
Now that QHttpServerRequest is copyable make it possible to pass it
by value to the route handlers.
Add tests including invalid route() calls that are conditionally
enabled, and will static_assert when enabled.
Renamed Valid to Value and removed old Value, and as a
consequence removed usages of Valid from tests.
[ChangeLog] Added support for routes handlers that return
QFuture<void> and respond using QHttpServerResponder&& argument
in another thread.
Task-number: QTBUG-108127
Change-Id: I58e3c07f5eb54b3f9443e569151b82827ef8f5f8
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
HTTP/1.x can only handle responding to a single request at a time on
the same socket. Do not proceed to the next incoming request until
reading from a QIODevice is done to prevent out of order writes.
Failing test now succeeds.
Task-number: QTBUG-138611
Pick-to: 6.10 6.9 6.8
Change-Id: Ia0eb96b57080c8373960932fac217315f621cbfe
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Because HTTP/1.x connections can only respond to a single request at a
time, and the QHttpServer proceeds to the next incoming connection as
soon as it has started writing from a QIODevice, the response data is
received out of order.
Task-number: QTBUG-138611
Pick-to: 6.10 6.9 6.8
Change-Id: I9979f8414efc62c5561efa6152359ac807008f40
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Add missing include guards and skip tests that need the concurrency
feature.
Pick-to: 6.10 6.9 6.8
Change-Id: I8e8c0ef91b8359bf9fb6416f19f70f6c02dc88a9
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
When handling HTTP(S)/1.1 clients use chunked transfer encoding
for sequential QIODevices, because sequential QIODevices don't
know their length. The failure to do so caused clients to hang.
When handling HTTP(S)/1.0 clients disconnect after write because
such clients don't support chunked transfer encoding.
Removed expect_fail from tests that now work.
Fixes: QTBUG-137330
Pick-to: 6.10 6.9 6.8
Change-Id: Ie7a0e106c5475b8298697cdee0ba080acab3ce97
Reviewed-by: Lena Biliaieva <lena.biliaieva@qt.io>
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
The mock QIODevice SequentialIODevice in test now emits
readChannelFinished() when all data is available.
Now it also adds data multiple times with a delay instead
of having it available from the time of construction.
A new test is added to ensure that large amounts of data
can be read.
Task-number: QTBUG-137330
Pick-to: 6.10 6.9 6.8
Change-Id: Ibea47feefeffebd64a43a1a1ec5f00687b246ea6
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
Reading from an empty sequential QIODevice when writing to an
HTTP/1.1 or HTTPS/1.1 client hangs the client. Add tests that
are expected to fail.
Task-number: QTBUG-137330
Pick-to: 6.10 6.9 6.8
Change-Id: I90e5826c05119fe950166b3da06df1aac093ab01
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
To prevent test from affecting subsequent tests set keep-alive timeout
back to default settings after performing test.
Task-number: QTBUG-75087
Change-Id: I0f1d5cb1cb6fca727571d7781bb85fa0612dfd06
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
Reading from a sequential QIODevice when writing to a HTTP/1.1 or
HTTPS/1.1 client hangs the client. Add tests that are expected to
fail.
Task-number: QTBUG-137330
Pick-to: 6.10 6.9 6.8
Change-Id: I2607c3d18da18ca1ecd94936dfbe219f5fc98b7d
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
Make QHttpServerRequest copyable and update the traits templates to
handle this. Make QHttpServer::sendResponse() for futures copy the
QHtppServerRequest instead of passing it by reference and update
test that was expected to fail. Add QHttpServerRequest::create()
to create QHttpServerRequest from QHttpServerParser.
[ChangeLog][QtHttpServerRequest] Made QHttpServerRequest copyable
Task-number: QTBUG-133519
Change-Id: I3af08b4e2a579691fbf3b3150fcf553a5615ac62
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Implicit capture of this via [=] is deprecated in C++20.
This patch avoids the compiler warning
tst_qhttpserver.cpp:488:34: warning: implicit capture of ‘this’
via ‘[=]’ is deprecated in C++20 [-Wdeprecated]
488 | return QtConcurrent::run([=]() {
Amends: 7c6ff5fab9
Pick-to: 6.9 6.8
Change-Id: Id8467dc58fbabe1f36dec894ee101ef5853b4c73
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
Each QHttpServerHttp[12]ProtocolHandler has a single
QHttpServerRequest object, causing issues with concurrent route
handlers as the protocol handlers overwrite the same request.
Add a test to demonstrate that the QHttpServerRequest object changes
between the start of route handlers and the execution of
afterRequestHandlers when a long-running handler returns
QFuture<QHttpServerResponse>.
Task-number: QTBUG-133519
Pick-to: 6.9 6.8
Change-Id: I2293c4790db9d04ea15246da3df244b1ed35b026
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Our approach with a temporary keychain stopped working on macOS 15,
where we fortunately have a new option when importing a PKCS12 blob.
But it is possible to build using SDK 14 and then run on macOS 15,
where our trick would fail. In this case, skip the test/SSL usage.
Task-number: QTBUG-130500
Pick-to: 6.8
Change-Id: Iebe31d2d6affa686ccb4287cd80c2c5683cc787a
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Use a context object and QtPrivate:makeCallableObject instead
of std::function when adding routes.
The rvalue was exchanged with a reference in the callback signature
because QMetaObject::invokeMethod is not prepared to handle rvalues.
The context object is used for two purposes, to ensure that a
rule does not outlive the context object, and also it is posssible
to use it as an object to call a member function on.
Pick-to: 6.8
Change-Id: Ibc5478f2dab77f4aa4891819b1c7743c9767849e
Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
The QHttpServer tests has two tests with the data tag "arg:string".
Rename one of them.
Pick-to: 6.8
Change-Id: I26565be5dff17f95300fed9b6bc9db19b5df3618
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Use QtPrivate::makeCallableObject() and a context object instead
of std::function() when calling afterRequest(). It's signature is
now constrained to take both request and response in that particular
order.
The rvalue was exchanged with a reference in the callback signature
because QMetaObject::invokeMethod is not prepared to handle rvalues.
The function is renamed to addAfterRequestHander() to clarify
its function.
Pick-to: 6.8
Task-Id: QTBUG-128113
Change-Id: If3af3b811f54fe4be2b14d5c768b3a61b4f32bb6
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Use QtPrivate::makeCallableObject() and a context object instead
of std::function() when calling setMissingHandler(). Also added
clearMissingHandler() to set the handler back to the default behavior.
The rvalue was exchanged with a reference in the callback signature
because QMetaObject::invokeMethod is not prepared to handle rvalues.
Pick-to: 6.8
Task-Id: QTBUG-128113
Change-Id: If02c67a0ee200b458d9f8051a23a9307fce6e59a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
The route convenience method of QHttpServer was a purely variadic
template function. However, it expected a strict syntax of (QString,
Method, Rule parameters..., Functor). The Rule parameters are
forwarded to the constructor of the Rule that is created. This was
not documented.
The Functor is expected to follow some rules too. This is checked by
QHttpServerRouterViewTraits.
This change expresses the synatax in the function declaration as
(QString, Method, Functor) and removes the possibility to forward
parameters to the constructor of rule. The route method now returns a
pointer to the new rule, which can be used to set parameters instead.
Constraints to the Functor are still checked by QHttp...ViewTraits.
Pick-to: 6.8
Task-Id: QTBUG-128113
Change-Id: Id3d075a46e86169521bafd3ecb4c9c58ba8dff2c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Replaced all headers-related methods with only setter and getter to make
the class interface simpler and more consistent with other classes
consuming QHttpHeaders.
Resulted from API-review
Task-number: QTBUG-125859
Pick-to: 6.8
Change-Id: Ic41b471813969711bb07302a8929784bc425c84e
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
To keep the API lean, remove the SSL confguration and listen()
methods.
Instead using listen() on a QAbstractHttpServer, a user should
create an instance of a QTcpServer or QSslServer, then call
listen() on it before calling bind() on a QAbstractHttpServer
with it as an argument.
Task-number: QTBUG-125859
Pick-to: 6.8
Change-Id: I366c0a01d8b7ee3802e0bdd63b9d84813338f478
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Previously tst_QHttpServer only covered HTTP/1.1 and partially HTTPS/1.1.
Now all tst_QHttpServer tests are run for HTTP/1.1, HTTPS/1.1, and HTTP/2.
Fixes: QTBUG-122457
Pick-to: 6.8
Change-Id: I068a90545365a85e62e990a14bda38e43a4bbc64
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The QHttpServerResponder class is too low level and HTTP 1.1 specific
to be used for both HTTP 1.1 and 2. Remove the low level functions and
add member functions for sending data without having to know the
total length of the data before sending it.
To respond with data with length not known before response is
generated, call one of the writeBeginChunked functions, followed by
as many calls to writeChunk as needed, and finish with a call to one
of the writeEndChunked functions.
The HTTP 1.1 implementation has been moved from QHttpServerResponder
to QHttpServerResponderPrivate.
Fixes: QTBUG-124866
Change-Id: Ie4dd6982bbbb14a5403ebcdfe85626deb5fb2cc5
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Added withHeaders() method to pass headers to the QHttpServerResponse object.
Removed methods using QHttpServerResponder::HeaderList because it will be also replaced by QHttpHeaders.
Added headers() method for convenience.
Updated tests and examples.
Fixes: QTBUG-107749
Change-Id: Ia9ce631a17b1b60e84ffc85e09215ac262407144
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
By adding it to the default build flags via .cmake.conf.
This amends commit f0832a1fe4.
Change-Id: Idca0dedc94691eae5db9c844b16293e7064da509
Reviewed-by: Mikhail Svetkin <mikhail.svetkin@gmail.com>
This allows for uniform handling of functions, function
pointers and function pointer references.
Update tst_qhttpserverrouter to use a static function in
addition to lambdas.
Update tst_qhttpserver to use lambda variables, functions,
function pointers, and a class with a custom call operator
for route handlers.
Fixes: QTBUG-112484
Pick-to: 6.5
Change-Id: I19713105c1bacf3365057b70d17e6211e05f8ab9
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This allows to send more than a single response to a client.
Add an expected-failure (due to QTBUG-108068) test that produces
multiple responses.
[ChangeLog][QHttpServerResponse][Potentially Source-Incompatible Changes]
QHttpServerResponse::write() method was removed in favor of new
QHttpServerResponder::writeResponse().
Task-number: QTBUG-105202
Change-Id: I79f3297d1a4360634715be8593a6b146304d481f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Introduce private QHttpServerStream class that handles connection
state. This is the only class that contains a connected QTcpSocket.
Make other classes use QHttpServerResponder to communicate
with clients. Stop processing of further requests as long as a
QHttpServerResponder object for the current request is active.
Add a regression test to tst_qhttpserver.
[ChangeLog][Potentially Source-Incompatible Changes] Most public
methods that accepted a QTcpSocket are now accepting
QHttpServerResponder instead.
Task-number: QTBUG-105202
Change-Id: Ib8db7fdc65b59077411b09277f2b1948fde4848b
Reviewed-by: André Klitzing <aklitzing@gmail.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This ensures that there is exactly one handler. This also should make
it easier to rework the response handling.
Pick-to: 6.4
Change-Id: I5771d94a0b2436b2ff2b745335184a80f4b2cf31
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Add a status code to overloaded constructor of the QHttpServerResponse
Pick-to: 6.4
Fixes: QTBUG-105366
Change-Id: I3ac95df744484319e02ac6f7e24899e0b0368334
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
Add a value for TRACE method from RFC 7231.
Rename value All to AnyKnown.
Document the enum.
Fixes: QTBUG-105306
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: Ibfc41d006df3dd7f2620cd9b2395b6b1b8ce6384
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Also make the test non-private.
Pick-to: 6.4
Change-Id: I17eacc80e2b96443a4b8637d5e0df5bc88d583e2
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Use Q_AUTOTEST_EXPORT for stuff used by the tests.
Mark tst_qhttpser, tst_qhttpserverresponder and
tst_qhttpserverresponse as private because they are using
private APIs.
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: I6ecee7ae76fe7e9dc9ab7eceb1ae1c74cc07ef79
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
The server socket may contain data for multiple requests
if the network client is performing HTTP pipelining.
This patch retriggers socket's readyRead() signal after
processing a request so that the server can handle next
pipelined request.
Pick-to: 6.4
Change-Id: Ifadd9cd5ff043b513ec7b831d4156d8ad5dece79
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This support was implemented by duplicating enum values for
QHttpServerRequest::Method. Among other things this causes
build errors on Windows due to Windows API defining DELETE.
There is also no compile time checking for valideness of
methods supplied as strings.
This partially reverts be06bd66b8.
Fixes: QTBUG-104710
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: I47977c5979d00a1847a210b10c9f77f753880344
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Remove QHttpServerFutureResponse and use QFuture<QHttpServerResponse>
instead.
Test for feature 'future' instead of 'concurrent' when only QFuture
is used.
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: Iba318e89221afa69e46b3341ce222125421a22c6
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Moving out the lambda may make it unusable for the subsequent requests.
Adjust the router API to use a const reference to the lambda.
Remove mutable annotation from the routeHandler lambda because it
is not needed anymore.
Add a regression test to verify the behavior.
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: I19f91c6a61e9155378e5ff34cbdb9b27d09fce2c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This test is using QtConcurrent::run(). This call does not seem
to require linking with the library. But this is not documented,
so let's link anyway.
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: I623133c478fdeda173cb9b7bcf6cd167f46526af
Reviewed-by: Marc Mutz <marc.mutz@qt.io>