Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package qt6-httpserver for openSUSE:Factory checked in at 2024-04-08 17:38:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qt6-httpserver (Old) and /work/SRC/openSUSE:Factory/.qt6-httpserver.new.1905 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qt6-httpserver" Mon Apr 8 17:38:58 2024 rev:14 rq:1165784 version:6.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/qt6-httpserver/qt6-httpserver.changes 2024-03-28 14:21:17.032872614 +0100 +++ /work/SRC/openSUSE:Factory/.qt6-httpserver.new.1905/qt6-httpserver.changes 2024-04-08 17:51:12.047313303 +0200 @@ -1,0 +2,6 @@ +Tue Apr 2 13:39:41 UTC 2024 - Christophe Marin <christo...@krop.fr> + +- Update to 6.7.0: + * https://www.qt.io/blog/qt-6.7-released + +------------------------------------------------------------------- Old: ---- qthttpserver-everywhere-src-6.6.3.tar.xz New: ---- qthttpserver-everywhere-src-6.7.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qt6-httpserver.spec ++++++ --- /var/tmp/diff_new_pack.aAEDxs/_old 2024-04-08 17:51:12.599333677 +0200 +++ /var/tmp/diff_new_pack.aAEDxs/_new 2024-04-08 17:51:12.599333677 +0200 @@ -16,8 +16,8 @@ # -%define real_version 6.6.3 -%define short_version 6.6 +%define real_version 6.7.0 +%define short_version 6.7 %define tar_name qthttpserver-everywhere-src %define tar_suffix %{nil} # @@ -27,7 +27,7 @@ %endif # Name: qt6-httpserver%{?pkg_suffix} -Version: 6.6.3 +Version: 6.7.0 Release: 0 Summary: Qt HTTP Server License: GPL-3.0-only ++++++ qthttpserver-everywhere-src-6.6.3.tar.xz -> qthttpserver-everywhere-src-6.7.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/.cmake.conf new/qthttpserver-everywhere-src-6.7.0/.cmake.conf --- old/qthttpserver-everywhere-src-6.6.3/.cmake.conf 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/.cmake.conf 2024-03-22 20:46:09.000000000 +0100 @@ -1,2 +1,4 @@ -set(QT_REPO_MODULE_VERSION "6.6.3") +set(QT_REPO_MODULE_VERSION "6.7.0") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") +set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1") +list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_CONTEXTLESS_CONNECT=1") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/.tag new/qthttpserver-everywhere-src-6.7.0/.tag --- old/qthttpserver-everywhere-src-6.6.3/.tag 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/.tag 2024-03-22 20:46:09.000000000 +0100 @@ -1 +1 @@ -19d4435d4ef523f4a5c30c6484a2f11739fc3fec +5336cc98bca36c3243c6ef1fca3547925bfc0604 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/coin/axivion/ci_config_linux.json new/qthttpserver-everywhere-src-6.7.0/coin/axivion/ci_config_linux.json --- old/qthttpserver-everywhere-src-6.6.3/coin/axivion/ci_config_linux.json 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/coin/axivion/ci_config_linux.json 2024-03-22 20:46:09.000000000 +0100 @@ -1,9 +1,5 @@ { "Project": { - "Git": { - "_active": true, - "sourceserver_gitdir": "/data/axivion/databases/$(env:TESTED_MODULE_COIN).git" - }, "BuildSystemIntegration": { "child_order": [ "GCCSetup", @@ -31,29 +27,14 @@ "build/lib/lib*.so*.ir" ], "ir": "build/$(env:TESTED_MODULE_COIN).ir" - }, - "Project-GlobalOptions": { - "directory": "../work/qt/$(env:TESTED_MODULE_COIN)", - "ir": "build/$(env:TESTED_MODULE_COIN).ir", - "name": "qt_$(env:TESTED_MODULE_COIN)_dev_$(env:TARGET_OS_COIN)" - } - }, - "Results": { - "Dashboard": { - "dashboard_url": "https://axivion-srv.ci.qt.io/axivion/" - }, - "Database": { - "ci_mode": { - "directory": "/data/axivion/databases" - } } }, "_Format": "1.0", - "_Version": "trunk-9e0ef9c5818", + "_Version": "7.6.2", "_VersionNum": [ 7, 6, - 9999, - 11489 + 2, + 12725 ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/dependencies.yaml new/qthttpserver-everywhere-src-6.7.0/dependencies.yaml --- old/qthttpserver-everywhere-src-6.6.3/dependencies.yaml 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/dependencies.yaml 2024-03-22 20:46:09.000000000 +0100 @@ -1,7 +1,7 @@ dependencies: ../qtbase: - ref: afdec885058c92e24604f398a926297222da06f3 + ref: 98602c26fc97eb41e3dd7548194ca637420a31b9 required: true ../qtwebsockets: - ref: 26db5812958bc8bcf6e333357760c3023631eae3 + ref: 45d5cdde4c187a499745b5bb5fc14a8cef149679 required: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/doc/config/qthttpserver.qdocconf new/qthttpserver-everywhere-src-6.7.0/doc/config/qthttpserver.qdocconf --- old/qthttpserver-everywhere-src-6.6.3/doc/config/qthttpserver.qdocconf 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/doc/config/qthttpserver.qdocconf 2024-03-22 20:46:09.000000000 +0100 @@ -47,6 +47,3 @@ navigation.landingpage = "Qt HTTP Server" manifestmeta.highlighted.names = "QtHttpServer/Simple HTTP Server" - -# Fail the documentation build if there are more warnings than the limit -warninglimit = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/examples/httpserver/colorpalette/utils.h new/qthttpserver-everywhere-src-6.7.0/examples/httpserver/colorpalette/utils.h --- old/qthttpserver-everywhere-src-6.6.3/examples/httpserver/colorpalette/utils.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/examples/httpserver/colorpalette/utils.h 2024-03-22 20:46:09.000000000 +0100 @@ -57,12 +57,11 @@ } static QByteArray getValueFromHeader(const QList<QPair<QByteArray, QByteArray>> &headers, - const QString &keyToFind) + QByteArrayView headerName) { for (const auto &[key, value] : headers) { - if (key == keyToFind) { + if (key.compare(headerName, Qt::CaseInsensitive) == 0) return value; - } } return QByteArray(); } @@ -70,7 +69,7 @@ static std::optional<QString> getTokenFromRequest(const QHttpServerRequest &request) { std::optional<QString> token; - if (auto bytes = getValueFromHeader(request.headers(), "TOKEN"); !bytes.isEmpty()) { + if (auto bytes = getValueFromHeader(request.headers(), "token"); !bytes.isEmpty()) { token = bytes; } return token; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qabstracthttpserver.cpp new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qabstracthttpserver.cpp --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qabstracthttpserver.cpp 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qabstracthttpserver.cpp 2024-03-22 20:46:09.000000000 +0100 @@ -12,6 +12,9 @@ #include <QtCore/qloggingcategory.h> #include <QtNetwork/qtcpserver.h> +#include <QtNetwork/qtcpsocket.h> +#include <QtNetwork/qlocalserver.h> +#include <QtNetwork/qlocalsocket.h> #if QT_CONFIG(ssl) #include <QtNetwork/qsslserver.h> @@ -43,6 +46,22 @@ new QHttpServerStream(q, socket); } + +#if QT_CONFIG(localserver) +/*! + \internal +*/ +void QAbstractHttpServerPrivate::handleNewLocalConnections() +{ + Q_Q(QAbstractHttpServer); + auto localServer = qobject_cast<QLocalServer *>(q->sender()); + Q_ASSERT(localServer); + + while (auto socket = localServer->nextPendingConnection()) + new QHttpServerStream(q, socket); +} +#endif + /*! \class QAbstractHttpServer \since 6.4 @@ -172,6 +191,21 @@ Qt::UniqueConnection); } +#if QT_CONFIG(localserver) +void QAbstractHttpServer::bind(QLocalServer *server) +{ + Q_D(QAbstractHttpServer); + + if (!server->isListening()) + qCWarning(lcHttpServer) << "The local server" << server << "is not listening."; + server->setParent(this); + + QObjectPrivate::connect(server, &QLocalServer::newConnection, + d, &QAbstractHttpServerPrivate::handleNewLocalConnections, + Qt::UniqueConnection); +} +#endif + /*! Returns list of child TCP servers of this HTTP server. @@ -179,8 +213,20 @@ */ QList<QTcpServer *> QAbstractHttpServer::servers() const { - return findChildren<QTcpServer *>().toVector(); + return findChildren<QTcpServer *>(); +} + +#if QT_CONFIG(localserver) +/*! + Returns list of child TCP servers of this HTTP server. + + \sa serverPorts() + */ +QList<QLocalServer *> QAbstractHttpServer::localServers() const +{ + return findChildren<QLocalServer *>(); } +#endif #if defined(QT_WEBSOCKETS_LIB) /*! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qabstracthttpserver.h new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qabstracthttpserver.h --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qabstracthttpserver.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qabstracthttpserver.h 2024-03-22 20:46:09.000000000 +0100 @@ -18,6 +18,10 @@ #include <QtWebSockets/qwebsocket.h> #endif // defined(QT_WEBSOCKETS_LIB) +#if QT_CONFIG(localserver) +#include <QtNetwork/qlocalserver.h> +#endif + #include <memory> QT_BEGIN_NAMESPACE @@ -45,6 +49,11 @@ void bind(QTcpServer *server = nullptr); QList<QTcpServer *> servers() const; +#if QT_CONFIG(localserver) + void bind(QLocalServer *server); + QList<QLocalServer *> localServers() const; +#endif + #if QT_CONFIG(ssl) void sslSetup(const QSslCertificate &certificate, const QSslKey &privateKey, QSsl::SslProtocol protocol = QSsl::SecureProtocols); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qabstracthttpserver_p.h new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qabstracthttpserver_p.h --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qabstracthttpserver_p.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qabstracthttpserver_p.h 2024-03-22 20:46:09.000000000 +0100 @@ -49,6 +49,10 @@ void handleNewConnections(); +#if QT_CONFIG(localserver) + void handleNewLocalConnections(); +#endif + #if QT_CONFIG(ssl) QSslConfiguration sslConfiguration; bool sslEnabled = false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserver.cpp new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserver.cpp --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserver.cpp 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserver.cpp 2024-03-22 20:46:09.000000000 +0100 @@ -72,7 +72,8 @@ optional special arguments: \c {const QHttpServerRequest&} and \c {QHttpServerResponder&&}. These special arguments must be the last in the parameter list, but in any order, and there can be none, one, or both - of them present. + of them present. Only handlers with \c void return type can accept + \c {QHttpServerResponder&&} arguments. Examples: @@ -92,8 +93,9 @@ \endcode - The request handler may return \c {QFuture<QHttpServerResponse>} if - asynchronous processing is desired: + Requests are processed sequentially inside the \c {QHttpServer}'s thread + by default. The request handler may return \c {QFuture<QHttpServerResponse>} + if asynchronous processing is desired: \code server.route("/feature/", [] (int id) { @@ -103,6 +105,10 @@ }); \endcode + The body of \c QFuture is executed asynchronously, but all the network + communication is executed sequentially. + \c {QHttpServerResponder&&} special argument is not available for routes + returning a \c {QFuture}. \sa QHttpServerRouter::addRule */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserver.h new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserver.h --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserver.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserver.h 2024-03-22 20:46:09.000000000 +0100 @@ -95,14 +95,14 @@ const QHttpServerRequest &request) { if constexpr (ViewTraits::Arguments::Last::IsRequest::Value) { if constexpr (ViewTraits::Arguments::Count == 2) - return std::move(viewHandler(std::move(resp), request)); + return viewHandler(std::move(resp), request); else static_assert(dependent_false_v<ViewTraits>); } else if constexpr (ViewTraits::Arguments::Last::IsResponse::Value) { if constexpr (ViewTraits::Arguments::Count == 1) - return std::move(viewHandler(std::move(resp))); + return viewHandler(std::move(resp)); else if constexpr (ViewTraits::Arguments::Count == 2) - return std::move(viewHandler(request, std::move(resp))); + return viewHandler(request, std::move(resp)); else static_assert(dependent_false_v<ViewTraits>); } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverrequest.cpp new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverrequest.cpp --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverrequest.cpp 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverrequest.cpp 2024-03-22 20:46:09.000000000 +0100 @@ -114,7 +114,7 @@ /*! \internal */ -qsizetype QHttpServerRequestPrivate::readRequestLine(QAbstractSocket *socket) +qsizetype QHttpServerRequestPrivate::readRequestLine(QIODevice *socket) { if (fragment.isEmpty()) { // reserve bytes for the request line. This is better than always append() which reallocs @@ -176,7 +176,7 @@ /*! \internal */ -qsizetype QHttpServerRequestPrivate::readHeader(QAbstractSocket *socket) +qsizetype QHttpServerRequestPrivate::readHeader(QIODevice *socket) { if (fragment.isEmpty()) { // according to @@ -267,7 +267,7 @@ /*! \internal */ -qsizetype QHttpServerRequestPrivate::sendContinue(QAbstractSocket *socket) +qsizetype QHttpServerRequestPrivate::sendContinue(QIODevice *socket) { qsizetype ret = socket->write("HTTP/1.1 100 Continue\r\n\r\n"); state = State::ReadingData; @@ -289,10 +289,29 @@ clear(); } +#if QT_CONFIG(ssl) +/*! + \internal +*/ +QHttpServerRequestPrivate::QHttpServerRequestPrivate(const QHostAddress &remoteAddress, + quint16 remotePort, + const QHostAddress &localAddress, + quint16 localPort, + const QSslConfiguration &sslConfiguration) + : remoteAddress(remoteAddress), + remotePort(remotePort), + localAddress(localAddress), + localPort(localPort), + sslConfiguration(sslConfiguration) +{ + clear(); +} +#endif + /*! \internal */ -bool QHttpServerRequestPrivate::parse(QAbstractSocket *socket) +bool QHttpServerRequestPrivate::parse(QIODevice *socket) { qsizetype read; @@ -358,7 +377,7 @@ */ // note this function can only be used for non-chunked, non-compressed with // known content length -qsizetype QHttpServerRequestPrivate::readBodyFast(QAbstractSocket *socket) +qsizetype QHttpServerRequestPrivate::readBodyFast(QIODevice *socket) { qsizetype toBeRead = qMin(socket->bytesAvailable(), bodyLength - contentRead); @@ -387,7 +406,7 @@ /*! \internal */ -qsizetype QHttpServerRequestPrivate::readRequestBodyRaw(QAbstractSocket *socket, qsizetype size) +qsizetype QHttpServerRequestPrivate::readRequestBodyRaw(QIODevice *socket, qsizetype size) { // FIXME get rid of this function and just use readBodyFast and give it socket->bytesAvailable() qsizetype bytes = 0; @@ -418,7 +437,7 @@ /*! \internal */ -qsizetype QHttpServerRequestPrivate::readRequestBodyChunked(QAbstractSocket *socket) +qsizetype QHttpServerRequestPrivate::readRequestBodyChunked(QIODevice *socket) { qsizetype bytes = 0; while (socket->bytesAvailable()) { @@ -480,7 +499,7 @@ /*! \internal */ -qsizetype QHttpServerRequestPrivate::getChunkSize(QAbstractSocket *socket, qsizetype *chunkSize) +qsizetype QHttpServerRequestPrivate::getChunkSize(QIODevice *socket, qsizetype *chunkSize) { qsizetype bytes = 0; char crlf[2]; @@ -565,6 +584,19 @@ : d(new QHttpServerRequestPrivate(remoteAddress, remotePort, localAddress, localPort)) {} +#if QT_CONFIG(ssl) +/*! + \internal +*/ +QHttpServerRequest::QHttpServerRequest(const QHostAddress &remoteAddress, quint16 remotePort, + const QHostAddress &localAddress, quint16 localPort, + const QSslConfiguration &sslConfiguration) + : d(new QHttpServerRequestPrivate(remoteAddress, remotePort, + localAddress, localPort, + sslConfiguration)) +{} +#endif + /*! Destroys a QHttpServerRequest */ @@ -657,6 +689,20 @@ return d->localPort; } +#if QT_CONFIG(ssl) +/*! + Returns the configuration of the established TLS connection. + The configurations will return true for isNull() if the connection + is not using TLS. + + \since 6.7 +*/ +QSslConfiguration QHttpServerRequest::sslConfiguration() const +{ + return d->sslConfiguration; +} +#endif + QT_END_NAMESPACE #include "moc_qhttpserverrequest.cpp" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverrequest.h new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverrequest.h --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverrequest.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverrequest.h 2024-03-22 20:46:09.000000000 +0100 @@ -10,6 +10,9 @@ #include <QtCore/qurl.h> #include <QtCore/qurlquery.h> #include <QtNetwork/qhostaddress.h> +#if QT_CONFIG(ssl) +#include <QtNetwork/qsslconfiguration.h> +#endif #include <memory> @@ -58,6 +61,9 @@ Q_HTTPSERVER_EXPORT quint16 remotePort() const; Q_HTTPSERVER_EXPORT QHostAddress localAddress() const; Q_HTTPSERVER_EXPORT quint16 localPort() const; +#if QT_CONFIG(ssl) + Q_HTTPSERVER_EXPORT QSslConfiguration sslConfiguration() const; +#endif private: Q_DISABLE_COPY(QHttpServerRequest) @@ -70,6 +76,13 @@ quint16 remotePort, const QHostAddress &localAddress, quint16 localPort); +#if QT_CONFIG(ssl) + Q_HTTPSERVER_EXPORT explicit QHttpServerRequest(const QHostAddress &remoteAddress, + quint16 remotePort, + const QHostAddress &localAddress, + quint16 localPort, + const QSslConfiguration &sslConfiguration); +#endif std::unique_ptr<QHttpServerRequestPrivate> d; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverrequest_p.h new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverrequest_p.h --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverrequest_p.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverrequest_p.h 2024-03-22 20:46:09.000000000 +0100 @@ -25,6 +25,11 @@ public: QHttpServerRequestPrivate(const QHostAddress &remoteAddress, quint16 remotePort, const QHostAddress &localAddress, quint16 localPort); +#if QT_CONFIG(ssl) + QHttpServerRequestPrivate(const QHostAddress &remoteAddress, quint16 remotePort, + const QHostAddress &localAddress, quint16 localPort, + const QSslConfiguration &sslConfiguration); +#endif quint16 port = 0; @@ -42,15 +47,15 @@ QHttpHeaderParser parser; bool parseRequestLine(QByteArrayView line); - qsizetype readRequestLine(QAbstractSocket *socket); - qsizetype readHeader(QAbstractSocket *socket); - qsizetype sendContinue(QAbstractSocket *socket); - qsizetype readBodyFast(QAbstractSocket *socket); - qsizetype readRequestBodyRaw(QAbstractSocket *socket, qsizetype size); - qsizetype readRequestBodyChunked(QAbstractSocket *socket); - qsizetype getChunkSize(QAbstractSocket *socket, qsizetype *chunkSize); + qsizetype readRequestLine(QIODevice *socket); + qsizetype readHeader(QIODevice *socket); + qsizetype sendContinue(QIODevice *socket); + qsizetype readBodyFast(QIODevice *socket); + qsizetype readRequestBodyRaw(QIODevice *socket, qsizetype size); + qsizetype readRequestBodyChunked(QIODevice *socket); + qsizetype getChunkSize(QIODevice *socket, qsizetype *chunkSize); - bool parse(QAbstractSocket *socket); + bool parse(QIODevice *socket); void clear(); @@ -62,6 +67,9 @@ quint16 remotePort; QHostAddress localAddress; quint16 localPort; +#if QT_CONFIG(ssl) + QSslConfiguration sslConfiguration; +#endif bool handling{false}; qsizetype bodyLength; qsizetype contentRead; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverresponder.cpp new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverresponder.cpp --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverresponder.cpp 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverresponder.cpp 2024-03-22 20:46:09.000000000 +0100 @@ -189,7 +189,7 @@ /*! \internal */ -template <qint64 BUFFERSIZE = 512> +template <qint64 BUFFERSIZE = 128 * 1024> struct IOChunkedTransfer { // TODO This is not the fastest implementation, as it does read & write @@ -208,16 +208,16 @@ IOChunkedTransfer(QIODevice *input, QIODevice *output) : source(input), sink(output), - bytesWrittenConnection(QObject::connect(sink.data(), &QIODevice::bytesWritten, [this] () { + bytesWrittenConnection(QObject::connect(sink.data(), &QIODevice::bytesWritten, sink.data(), [this]() { writeToOutput(); })), - readyReadConnection(QObject::connect(source.data(), &QIODevice::readyRead, [this] () { + readyReadConnection(QObject::connect(source.data(), &QIODevice::readyRead, source.data(), [this]() { readFromInput(); })) { Q_ASSERT(!source->atEnd()); // TODO error out QObject::connect(sink.data(), &QObject::destroyed, source.data(), &QObject::deleteLater); - QObject::connect(source.data(), &QObject::destroyed, [this] () { + QObject::connect(source.data(), &QObject::destroyed, source.data(), [this]() { delete this; }); readFromInput(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverstream.cpp new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverstream.cpp --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverstream.cpp 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverstream.cpp 2024-03-22 20:46:09.000000000 +0100 @@ -9,6 +9,7 @@ #include <QtCore/qmetaobject.h> #include <QtCore/qthread.h> #include <QtCore/qloggingcategory.h> +#include <QtNetwork/qlocalsocket.h> #include <QtNetwork/qtcpsocket.h> #include <private/qhttpserverrequest_p.h> @@ -27,7 +28,12 @@ socket->startTransaction(); if (!request.d->parse(socket)) { - socket->disconnectFromHost(); + if (tcpSocket) + tcpSocket->disconnectFromHost(); +#if QT_CONFIG(localserver) + else if (localSocket) + localSocket->disconnectFromServer(); +#endif return; } @@ -39,28 +45,31 @@ QHttpServerResponder responder(this); #if defined(QT_WEBSOCKETS_LIB) - if (request.d->upgrade) { // Upgrade - const auto &upgradeValue = request.value(QByteArrayLiteral("upgrade")); - if (upgradeValue.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) { - static const auto signal = - QMetaMethod::fromSignal(&QAbstractHttpServer::newWebSocketConnection); - if (server->isSignalConnected(signal) && server->handleRequest(request, responder)) { - // Socket will now be managed by websocketServer - socket->disconnect(); - socket->rollbackTransaction(); - server->d_func()->websocketServer.handleConnection(socket); - Q_EMIT socket->readyRead(); - } else { - qWarning(lcHttpServerStream, - "WebSocket received but no slots connected to " - "QWebSocketServer::newConnection or request not handled"); - server->missingHandler(request, std::move(responder)); - socket->disconnectFromHost(); + if (auto *tcpSocket = qobject_cast<QTcpSocket*>(socket)) { + if (request.d->upgrade) { // Upgrade + const auto &upgradeValue = request.value(QByteArrayLiteral("upgrade")); + if (upgradeValue.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) { + static const auto signal = + QMetaMethod::fromSignal(&QAbstractHttpServer::newWebSocketConnection); + if (server->isSignalConnected(signal) + && server->handleRequest(request, responder)) { + // Socket will now be managed by websocketServer + socket->disconnect(); + socket->rollbackTransaction(); + server->d_func()->websocketServer.handleConnection(tcpSocket); + Q_EMIT socket->readyRead(); + } else { + qWarning(lcHttpServerStream, + "WebSocket received but no slots connected to " + "QWebSocketServer::newConnection or request not handled"); + server->missingHandler(request, std::move(responder)); + tcpSocket->disconnectFromHost(); + } + return; } - return; } } -#endif +#endif // QT_WEBSOCKETS_LIB socket->commitTransaction(); @@ -68,9 +77,9 @@ server->missingHandler(request, std::move(responder)); if (handlingRequest) - disconnect(socket, &QTcpSocket::readyRead, this, &QHttpServerStream::handleReadyRead); + disconnect(socket, &QIODevice::readyRead, this, &QHttpServerStream::handleReadyRead); else if (socket->bytesAvailable() > 0) - QMetaObject::invokeMethod(socket, &QAbstractSocket::readyRead, Qt::QueuedConnection); + QMetaObject::invokeMethod(socket, &QIODevice::readyRead, Qt::QueuedConnection); } void QHttpServerStream::socketDisconnected() @@ -79,18 +88,46 @@ deleteLater(); } -QHttpServerStream::QHttpServerStream(QAbstractHttpServer *server, QTcpSocket *socket) +QHttpServerRequest QHttpServerStream::initRequestFromSocket(QTcpSocket *tcpSocket) +{ + if (tcpSocket) { +#if QT_CONFIG(ssl) + if (auto *ssl = qobject_cast<const QSslSocket *>(tcpSocket)) { + return QHttpServerRequest(ssl->peerAddress(), ssl->peerPort(), + ssl->localAddress(), ssl->localPort(), + ssl->sslConfiguration()); + } +#endif + return QHttpServerRequest(tcpSocket->peerAddress(), tcpSocket->peerPort(), + tcpSocket->localAddress(), tcpSocket->localPort()); + } + + return QHttpServerRequest(QHostAddress::LocalHost, 0, QHostAddress::LocalHost, 0); +} + +QHttpServerStream::QHttpServerStream(QAbstractHttpServer *server, QIODevice *socket) : QObject(server), server(server), socket(socket), - request(socket->peerAddress(), socket->peerPort(), socket->localAddress(), - socket->localPort()) + tcpSocket(qobject_cast<QTcpSocket *>(socket)), +#if QT_CONFIG(localserver) + localSocket(qobject_cast<QLocalSocket*>(socket)), +#endif + request(initRequestFromSocket(tcpSocket)) { socket->setParent(this); - qCDebug(lcHttpServerStream) << "Connection from:" << socket->peerAddress(); - connect(socket, &QTcpSocket::readyRead, this, &QHttpServerStream::handleReadyRead); - connect(socket, &QTcpSocket::disconnected, this, &QHttpServerStream::socketDisconnected); + if (tcpSocket) { + qCDebug(lcHttpServerStream) << "Connection from:" << tcpSocket->peerAddress(); + connect(socket, &QTcpSocket::readyRead, this, &QHttpServerStream::handleReadyRead); + connect(tcpSocket, &QTcpSocket::disconnected, this, &QHttpServerStream::socketDisconnected); +#if QT_CONFIG(localserver) + } else if (localSocket) { + qCDebug(lcHttpServerStream) << "Connection from:" << localSocket->serverName(); + connect(socket, &QLocalSocket::readyRead, this, &QHttpServerStream::handleReadyRead); + connect(localSocket, &QLocalSocket::disconnected, this, &QHttpServerStream::socketDisconnected); +#endif + } } void QHttpServerStream::write(const QByteArray &ba) @@ -111,11 +148,23 @@ Q_ASSERT(handlingRequest); handlingRequest = false; - if (socket->state() != QAbstractSocket::ConnectedState) { - deleteLater(); - } else { - connect(socket, &QTcpSocket::readyRead, this, &QHttpServerStream::handleReadyRead); - QMetaObject::invokeMethod(socket, &QAbstractSocket::readyRead, Qt::QueuedConnection); + if (tcpSocket) { + if (tcpSocket->state() != QAbstractSocket::ConnectedState) { + deleteLater(); + } else { + connect(tcpSocket, &QTcpSocket::readyRead, this, &QHttpServerStream::handleReadyRead); + QMetaObject::invokeMethod(tcpSocket, &QTcpSocket::readyRead, Qt::QueuedConnection); + } +#if QT_CONFIG(localserver) + } else if (localSocket) { + if (localSocket->state() != QLocalSocket::ConnectedState) { + deleteLater(); + } else { + connect(localSocket, &QLocalSocket::readyRead, + this, &QHttpServerStream::handleReadyRead); + QMetaObject::invokeMethod(localSocket, &QLocalSocket::readyRead, Qt::QueuedConnection); + } +#endif } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverstream_p.h new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverstream_p.h --- old/qthttpserver-everywhere-src-6.6.3/src/httpserver/qhttpserverstream_p.h 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/src/httpserver/qhttpserverstream_p.h 2024-03-22 20:46:09.000000000 +0100 @@ -23,6 +23,9 @@ class QTcpSocket; class QAbstractHttpServer; +#if QT_CONFIG(localserver) +class QLocalSocket; +#endif class QHttpServerStream : public QObject { @@ -32,7 +35,7 @@ friend class QHttpServerResponder; private: - QHttpServerStream(QAbstractHttpServer *server, QTcpSocket *socket); + QHttpServerStream(QAbstractHttpServer *server, QIODevice *socket); void write(const QByteArray &data); void write(const char *body, qint64 size); @@ -43,7 +46,13 @@ void socketDisconnected(); QAbstractHttpServer *server; - QTcpSocket *socket; + QIODevice *socket; + QTcpSocket *tcpSocket; +#if QT_CONFIG(localserver) + QLocalSocket *localSocket; +#endif + + static QHttpServerRequest initRequestFromSocket(QTcpSocket *socket); QHttpServerRequest request; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/sync.profile new/qthttpserver-everywhere-src-6.7.0/sync.profile --- old/qthttpserver-everywhere-src-6.6.3/sync.profile 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/sync.profile 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -%modules = ( # path to module name map - "QtHttpServer" => "$basedir/src/httpserver", -); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qthttpserver-everywhere-src-6.6.3/tests/auto/qhttpserver/tst_qhttpserver.cpp new/qthttpserver-everywhere-src-6.7.0/tests/auto/qhttpserver/tst_qhttpserver.cpp --- old/qthttpserver-everywhere-src-6.6.3/tests/auto/qhttpserver/tst_qhttpserver.cpp 2024-03-19 03:30:54.000000000 +0100 +++ new/qthttpserver-everywhere-src-6.7.0/tests/auto/qhttpserver/tst_qhttpserver.cpp 2024-03-22 20:46:09.000000000 +0100 @@ -28,6 +28,12 @@ #include <QtNetwork/qsslconfiguration.h> #include <QtNetwork/qsslkey.h> +#if QT_CONFIG(localserver) +#include <qrandom.h> +#include <QtNetwork/qlocalserver.h> +#include <QtNetwork/qlocalsocket.h> +#endif + #include <array> #if QT_CONFIG(ssl) @@ -173,6 +179,10 @@ void pipelinedFutureRequests(); void multipleResponses(); +#if QT_CONFIG(localserver) + void localSocket(); +#endif + private: void checkReply(QNetworkReply *reply, const QString &response); @@ -378,6 +388,17 @@ }); #endif +#if QT_CONFIG(localserver) + const auto serverName = + QStringLiteral("testserver") + QString::number(qApp->applicationPid()); + + std::unique_ptr<QLocalServer> localServer = std::make_unique<QLocalServer>(); + if (localServer->listen(serverName)) + httpserver.bind(localServer.release()); + else + qCritical("Local Socket server listen failed"); +#endif + quint16 port = httpserver.listen(); if (!port) qCritical("Http server listen failed"); @@ -403,8 +424,7 @@ }; connect(&networkAccessManager, &QNetworkAccessManager::sslErrors, - [expectedSslErrors](QNetworkReply *reply, - const QList<QSslError> &errors) { + this, [expectedSslErrors](QNetworkReply *reply, const QList<QSslError> &errors) { for (const auto &error: errors) { if (!expectedSslErrors.contains(error)) qCritical() << "Got unexpected ssl error:" << error << error.certificate(); @@ -1097,6 +1117,33 @@ QCOMPARE(reply->readAll(), "done"); } +#if QT_CONFIG(localserver) +void tst_QHttpServer::localSocket() +{ + QVERIFY(!httpserver.localServers().isEmpty()); + + for (const auto &localServer : httpserver.localServers()) { + QLocalSocket socket; + socket.connectToServer(localServer->fullServerName()); + QVERIFY(socket.waitForConnected(1)); + + qApp->processEvents(); + + socket.write("GET /test HTTP/1.1\r\n" + "Host: local\r\n" + "User-Agent: curl/7.88.1\r\n" + "Accept: */*\r\n\r\n"); + + const QByteArray expectedResult = + "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 8\r\n\r\ntest msg"; + + // We need to call process events a couple of times for the write/read to go through + QTRY_COMPARE_GE(socket.bytesAvailable(), expectedResult.size()); + QCOMPARE(socket.readAll(), expectedResult); + } +} +#endif + QT_END_NAMESPACE Q_DECLARE_METATYPE(CustomArg);