Commit Graph

24 Commits

Author SHA1 Message Date
Øystein Heskestad 7eda15d031 Allow routes to return QFuture<void> and write using responder
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>
2025-08-06 10:01:00 +02:00
Øystein Heskestad ad21d3176c Rename PlaceholdersCount to SpecialsCount and update documentation
The number of QHttpServerRequest and QHttpServerResponder classes is
now called SpecialsCount instead of PlaceholdersCount. This makes more
sense because each parameter that is either QHttpServerRequest or
QHttpServerResponder is matched with IsSpecial in the traits templates.

Update the documentation to refer to specials instead of placeholders.

Task-number: QTBUG-129103
Change-Id: Iec7d5787d3693289bdf9bad9b3e0b7172fe08d2a
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
2025-05-13 10:21:09 +02:00
Matthias Rauter 945a3c209c Use context object in QHttpServer::route
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>
2024-09-03 18:21:17 +02:00
Matthias Rauter 76e55a052f Set missinghandler callback with a context object and remove rvalue
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>
2024-08-30 17:57:37 +02:00
Øystein Heskestad bd5ac90224 QAbstractHttpServer: Remove QSslConfiguration and listen() methods
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>
2024-07-31 16:52:41 +02:00
Ievgenii Meshcheriakov 51c37b7ef7 Decay type passed to FunctionTraits
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>
2023-04-25 14:16:21 +02:00
Ievgenii Meshcheriakov 00d0ea9c21 tst_qhttpserverrouter: Don't attempt to forward a lambda capture
That doesn't work when view handler is a function reference..

Task-number: QTBUG-112484
Pick-to: 6.5
Change-Id: I937cbd959123aa22b3dde4a30451f9f9e726bbab
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-04-25 14:16:19 +02:00
Ievgenii Meshcheriakov 55d10201dc Add connection tracking
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>
2022-11-14 11:15:59 +01:00
Ievgenii Meshcheriakov 9da514a0fa QAbstractHttpServer: Convert missingHandler() to a pure virtual method
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>
2022-08-25 14:16:00 +02:00
Ievgenii Meshcheriakov 02d9cd1da2 QHttpServerRequest: Cleanup Method enum
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>
2022-08-09 14:14:34 +00:00
Ievgenii Meshcheriakov b5f8b59c70 Allow supplying non-temporary handler lambdas
Adjust one test case to use such a lambda.

Fixes: QTBUG-104481
Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: I96e30fd167b8c2f8240316bff9c283efdb910541
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-07-15 11:55:52 +02:00
Ievgenii Meshcheriakov 398aa128c2 FunctionTraitsHelper: Remove useless template specialization
The generic version works the same way as the zero arguments
specialization except for out-of-bound argument access.

Out-of-bound argument access was only used by tst_qhttpserverrouter
and is removed by this commit.

Task-number: QTBUG-100868
Pick-to: 6.4
Change-Id: I49b8d7623ed758b34f9726a497f86333d6002242
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2022-06-30 11:19:54 +02:00
Lucie Gérard 57b0db0896 Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
License files are organized under LICENSES directory.

Pick-to: 6.4
Task-number: QTBUG-67283
Change-Id: I657c36f679b9448ec68d411a492171bc39df1411
Reviewed-by: Jesus Fernandez <jsfdez@gmail.com>
2022-06-22 17:35:22 +02:00
Marc Mutz 845eedf66d QHttpServerRouter: use unqiue_ptr to accept rules
They're already stored in unique_ptr internally, so use the more
expressive pass-unique_ptr-by-value idiom to express ownership
transfer, so the docs don't need to mention it anymore.

Also fixes a theoretical memleak on failed vector::emplace_back().

Pick-to: 6.4
Task-number: QTBUG-100868
Change-Id: I32e386378fe177e4890deea44f0e937c8054c1c6
Reviewed-by: Jesus Fernandez <jsfdez@gmail.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
2022-06-22 16:17:36 +02:00
Marc Mutz cb25d34789 Fix std::forward uses
- in route() implementations, the viewHandler was passed by universal
  reference, however, it was then captured either by value (copying,
  which some viewHandlers may not support) or - yuck - by reference,
  creating a dangling pointer in case a temporary was passed. This
  error was also present in the example implementations in the docs
  and the test. To fix, std::forward the viewHandler into the mutable
  lambda and std::move() it inside the lambda into
  route.bindCaptured().

- One more case of RouterHandler being passed by rvalue ref and then
  std::forward()ed, fixed by taking by value and std::move()ing
  instead.

Pick-to: 6.4
Task-number: QTBUG-100868
Change-Id: I729f7e0c8fd0838679bcefc141fd5cea333d276b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Jesus Fernandez <jsfdez@gmail.com>
2022-06-22 10:15:42 +02:00
Mikhail Svetkin e0fa374411 Add QHttpServer::afterRequest
This function allows to register a function to be run after each request.

Task-number: QTBUG-77090
Change-Id: I40dd4c1e9a447fbe034149ffc1923c7c814cf0e9
Reviewed-by: Mikhail Svetkin <mikhail.svetkin@gmail.com>
2020-05-14 20:36:31 +02:00
Mikhail Svetkin 9719bf64bb Add dependencies file for Coin
Coin by default uses dev branch of qtbase.
Add 5.12 qtbase into the dependencies file

Change-Id: I849ea65e36c74f153dbd5531c01e3a3b00ab4fef
Reviewed-by: Mikhail Svetkin <mikhail.svetkin@gmail.com>
2020-04-19 00:01:36 +02:00
Mikhail Svetkin 43a04e17a1 Allow using QHttpServerRequest/Responder at the same time
Fixes: QTBUG-77088
Change-Id: I2208cee290d086339aba705f959c57e0f6a73a87
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2019-10-25 08:55:01 +02:00
Mikhail Svetkin 3eebefcd27 QHttpServerRouterViewTraits: Make it simpler and testable
Currently QHttpServerRouterViewTraits contains all helpers and tools
inside itself. It is hard to read and extend.

This patch:
- Moves all helper and tools to QtPrivate namespace
- Tries to "simplify" template magic
- Adds support for unit test

Change-Id: I6aa443b286c4c896b8dbfee85fffb638328868ad
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2019-10-24 11:56:21 +02:00
Mikhail Svetkin be06bd66b8 Accept a string as request method in QHttpServer::route()
Allow writing simpler source code.

For example:

httpserver.route("/", "GET|POST", [] () { return ""; })

Instead of:

httpserver.route("/", QHttpServerRequest::Method::Post | QHttpServerRequest::Method::Get, [] () { return ""; })

Change-Id: Id0a754eccaba6b5f9f3be6a3b975383eb94840a0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2019-04-04 20:50:09 +00:00
Maurice Kalinowski 572e0b1f6c Fix build on Windows
Change-Id: I7bb287dedfc146ba717a69170cec529d7ef7fadb
Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2019-02-28 10:08:19 +00:00
Jesus Fernandez 11fb154a84 Fix several build issues and fix the unit tests
It is required to have continuous integration enabled in the
repository.

Change-Id: I71728a6e89841640e77c50a05cf59f34d697f897
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2019-02-28 09:47:48 +00:00
Jesus Fernandez fe96330ca0 Fix license headers
Change-Id: Ie15244adb917e2938fe7897c30d4616218d26ac0
Reviewed-by: Mikhail Svetkin <mikhail.svetkin@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2019-01-31 11:31:21 +00:00
Mikhail Svetkin a856556784 Introduce QHttpServerRouter
Provide simple API for routing, parsing, capture and call callback

Change-Id: Ibd7c37282d00bd56f96d841db92b473a65a2bf5c
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io>
2019-01-23 10:46:43 +00:00