diff options
-rw-r--r-- | examples/httpserver/afterrequest/doc/afterrequest.rst | 5 | ||||
-rw-r--r-- | examples/httpserver/afterrequest/main.py | 36 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml | 16 | ||||
-rw-r--r-- | sources/pyside6/PySide6/glue/qhttpserver.cpp | 50 |
4 files changed, 106 insertions, 1 deletions
diff --git a/examples/httpserver/afterrequest/doc/afterrequest.rst b/examples/httpserver/afterrequest/doc/afterrequest.rst new file mode 100644 index 000000000..0e81a6707 --- /dev/null +++ b/examples/httpserver/afterrequest/doc/afterrequest.rst @@ -0,0 +1,5 @@ +HTTP Server After Request Example +================================= + +A Python application that demonstrates the analogous example in C++ +`AfterRequest Example <https://doc.qt.io/qt-6/qthttpserver-afterrequest-example.html>`_ diff --git a/examples/httpserver/afterrequest/main.py b/examples/httpserver/afterrequest/main.py new file mode 100644 index 000000000..e68c992ec --- /dev/null +++ b/examples/httpserver/afterrequest/main.py @@ -0,0 +1,36 @@ +# Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com> +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +"""PySide6 port of the /httpserver/afterrequest from from Qt""" + +import sys + +from PySide6.QtCore import QCoreApplication +from PySide6.QtNetwork import QHostAddress +from PySide6.QtHttpServer import QHttpServer + + +def route(request): + return "Hello world" + + +def after_request(response, request): + response.setHeader(b"Server", b"Super server!") + + +if __name__ == '__main__': + app = QCoreApplication(sys.argv) + httpServer = QHttpServer() + httpServer.route("/", route) + + httpServer.afterRequest(after_request) + + port = httpServer.listen(QHostAddress.Any) + if port == 0: + print("Server failed to listen on a port.", file=sys.stderr) + sys.exit(-1) + + print(f"Running on http://127.0.0.1:{port}/ (Press CTRL+\\ to quit)") + + sys.exit(app.exec()) diff --git a/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml b/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml index 9f4ea243f..adb334462 100644 --- a/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml +++ b/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml @@ -9,7 +9,21 @@ <typedef-type name="QFutureHttpServerResponse" source="QFuture<QHttpServerResponse>"/> <object-type name="QAbstractHttpServer"/> - <object-type name="QHttpServer"/> + <object-type name="QHttpServer"> + <extra-includes> + <include file-name="QtHttpServer/QHttpServerRequest" location="global"/> + <include file-name="QtHttpServer/QHttpServerRouterRule" location="global"/> + </extra-includes> + <add-function signature="route(const QString &@rule@, PyCallable @callback@)" + return-type="bool"> + <inject-code class="target" position="beginning" file="../glue/qhttpserver.cpp" + snippet="qhttpserver-route"/> + </add-function> + <add-function signature="afterRequest(PyCallable @callback@)"> + <inject-code class="target" position="beginning" file="../glue/qhttpserver.cpp" + snippet="qhttpserver-afterrequest"/> + </add-function> + </object-type> <object-type name="QHttpServerFutureResponse"/> <object-type name="QHttpServerResponder"> <enum-type name="StatusCode"/> diff --git a/sources/pyside6/PySide6/glue/qhttpserver.cpp b/sources/pyside6/PySide6/glue/qhttpserver.cpp new file mode 100644 index 000000000..b6e485e2c --- /dev/null +++ b/sources/pyside6/PySide6/glue/qhttpserver.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +/********************************************************************* + * INJECT CODE + ********************************************************************/ + +// Note: Lambdas need to be inline, QTBUG-104481 +// @snippet qhttpserver-route +QString rule = %CONVERTTOCPP[QString](%PYARG_1); +auto *callable = %PYARG_2; + +bool cppResult = %CPPSELF.%FUNCTION_NAME(rule, + [callable](const QHttpServerRequest &request) -> QString { + Shiboken::GilState state; + auto *requestPtr = &request; + Shiboken::AutoDecRef arglist(PyTuple_New(1)); + PyTuple_SET_ITEM(arglist, 0, + %CONVERTTOPYTHON[QHttpServerRequest *](requestPtr)); + PyObject *ret = PyObject_CallObject(callable, arglist); + if (PyErr_Occurred()) + PyErr_Print(); + if (ret == nullptr) + return QString{}; + QString cppResult = %CONVERTTOCPP[QString](ret); + return cppResult; +}); + +%PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +// @snippet qhttpserver-route + +// @snippet qhttpserver-afterrequest +auto *callable = %PYARG_1; + +%CPPSELF.%FUNCTION_NAME([callable](QHttpServerResponse &&response, + const QHttpServerRequest &request) { + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(2)); + auto *responsePtr = &response; + auto *requestPtr = &request; + PyTuple_SET_ITEM(arglist, 0, + %CONVERTTOPYTHON[QHttpServerResponse *](responsePtr)); + PyTuple_SET_ITEM(arglist, 1, + %CONVERTTOPYTHON[QHttpServerRequest *](requestPtr)); + PyObject_CallObject(callable, arglist); + if (PyErr_Occurred()) + PyErr_Print(); + return std::move(response); +}); +// @snippet qhttpserver-afterrequest |