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 2026-02-03 21:27:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qt6-httpserver (Old)
 and      /work/SRC/openSUSE:Factory/.qt6-httpserver.new.1995 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "qt6-httpserver"

Tue Feb  3 21:27:00 2026 rev:26 rq:1330581 version:6.10.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/qt6-httpserver/qt6-httpserver.changes    
2025-11-25 15:48:37.683802357 +0100
+++ /work/SRC/openSUSE:Factory/.qt6-httpserver.new.1995/qt6-httpserver.changes  
2026-02-03 21:27:24.546329418 +0100
@@ -1,0 +2,6 @@
+Sat Jan 31 08:10:35 UTC 2026 - Christophe Marin <[email protected]>
+
+- Update to 6.10.2:
+  * https://www.qt.io/blog/qt-6.10.2-released
+
+-------------------------------------------------------------------

Old:
----
  qthttpserver-everywhere-src-6.10.1.tar.xz

New:
----
  qthttpserver-everywhere-src-6.10.2.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ qt6-httpserver.spec ++++++
--- /var/tmp/diff_new_pack.zr2Ait/_old  2026-02-03 21:27:25.582373016 +0100
+++ /var/tmp/diff_new_pack.zr2Ait/_new  2026-02-03 21:27:25.586373185 +0100
@@ -16,7 +16,7 @@
 #
 
 
-%define real_version 6.10.1
+%define real_version 6.10.2
 %define short_version 6.10
 %define tar_name qthttpserver-everywhere-src
 %define tar_suffix %{nil}
@@ -27,7 +27,7 @@
 %endif
 #
 Name:           qt6-httpserver%{?pkg_suffix}
-Version:        6.10.1
+Version:        6.10.2
 Release:        0
 Summary:        Qt HTTP Server
 License:        GPL-3.0-only

++++++ qthttpserver-everywhere-src-6.10.1.tar.xz -> 
qthttpserver-everywhere-src-6.10.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qthttpserver-everywhere-src-6.10.1/.cmake.conf 
new/qthttpserver-everywhere-src-6.10.2/.cmake.conf
--- old/qthttpserver-everywhere-src-6.10.1/.cmake.conf  2025-11-13 
22:11:08.000000000 +0100
+++ new/qthttpserver-everywhere-src-6.10.2/.cmake.conf  2026-01-22 
21:38:02.000000000 +0100
@@ -1,4 +1,6 @@
-set(QT_REPO_MODULE_VERSION "6.10.1")
+set(QT_REPO_MODULE_VERSION "6.10.2")
 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")
+set(QT_EXTRA_INTERNAL_TARGET_DEFINES
+    "QT_NO_CONTEXTLESS_CONNECT=1"
+    "QT_NO_FOREACH=1"
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qthttpserver-everywhere-src-6.10.1/.tag 
new/qthttpserver-everywhere-src-6.10.2/.tag
--- old/qthttpserver-everywhere-src-6.10.1/.tag 2025-11-13 22:11:08.000000000 
+0100
+++ new/qthttpserver-everywhere-src-6.10.2/.tag 2026-01-22 21:38:02.000000000 
+0100
@@ -1 +1 @@
-8dc17fd1270d367a10e1d69e561fba8797b896a9
+86b01c42b871a0240862ccbeb6ddc9f43ef483a4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qthttpserver-everywhere-src-6.10.1/dependencies.yaml 
new/qthttpserver-everywhere-src-6.10.2/dependencies.yaml
--- old/qthttpserver-everywhere-src-6.10.1/dependencies.yaml    2025-11-13 
22:11:08.000000000 +0100
+++ new/qthttpserver-everywhere-src-6.10.2/dependencies.yaml    2026-01-22 
21:38:02.000000000 +0100
@@ -1,7 +1,7 @@
 dependencies:
   ../qtbase:
-    ref: 90b845d15ffb97693dba527385db83510ebd121a
+    ref: 000d6c62f7880bb8d3054724e8da0b8ae244130e
     required: true
   ../qtwebsockets:
-    ref: ba2ada87ef9027650efb6251e7fc05519f484e95
+    ref: 2b969cb983d1e22df0e6fc6ece54043942090bd8
     required: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qthttpserver-everywhere-src-6.10.1/tests/auto/qhttpservermultithreaded/tst_qhttpservermultithreaded.cpp
 
new/qthttpserver-everywhere-src-6.10.2/tests/auto/qhttpservermultithreaded/tst_qhttpservermultithreaded.cpp
--- 
old/qthttpserver-everywhere-src-6.10.1/tests/auto/qhttpservermultithreaded/tst_qhttpservermultithreaded.cpp
 2025-11-13 22:11:08.000000000 +0100
+++ 
new/qthttpserver-everywhere-src-6.10.2/tests/auto/qhttpservermultithreaded/tst_qhttpservermultithreaded.cpp
 2026-01-22 21:38:02.000000000 +0100
@@ -124,10 +124,12 @@
 QT_BEGIN_NAMESPACE
 
 using namespace Qt::StringLiterals;
+using namespace std::chrono_literals;
 
 enum ServerType
 {
-    TCP,
+    HTTP1_0,
+    HTTP1_1,
 #if QT_CONFIG(ssl)
     SSL,
 #endif
@@ -147,21 +149,27 @@
 public:
     LocalHttpClient(ServerType type);
     ~LocalHttpClient();
-    QString get(const QString &url);
-    QString getSlowRead(const QString &url, qsizetype chunkSize, qsizetype 
mSleep);
+    QString get(const QString &url, const QHttpHeaders &headers = {});
+    QString getSlowRead(const QString &url, qsizetype chunkSize, qsizetype 
mSleep,
+                        const QHttpHeaders &headers);
     void pipelinedSendGet(const QString &url);
     QString piplinedFetchResults();
     QString postSlow(const QString &url, const QHttpHeaders &headers, 
qsizetype mSleep);
 
 private:
-    void sendGet(const QString &url);
+    void sendGet(const QString &url, const QHttpHeaders &headers = {});
     QString fetchResults();
+    void fetchStatusLine();
+    void fetchCrLf();
     QIODevice *socket = nullptr;
+    QByteArray version;
+    ServerType serverType;
 };
 
 LocalHttpClient::LocalHttpClient(ServerType type)
+    : version(type == HTTP1_0 ? "HTTP/1.0" : "HTTP/1.1"), serverType(type)
 {
-    if (type == TCP) {
+    if (type == HTTP1_0 || type == HTTP1_1) {
         QTcpSocket *tcpSocket = new QTcpSocket();
         tcpSocket->connectToHost("localhost", port);
         tcpSocket->waitForConnected();
@@ -214,15 +222,16 @@
     return fetchResults();
 }
 
-QString LocalHttpClient::get(const QString &url)
+QString LocalHttpClient::get(const QString &url, const QHttpHeaders &headers)
 {
-    sendGet(url);
+    sendGet(url, headers);
     return fetchResults();
 }
 
-QString LocalHttpClient::getSlowRead(const QString &url, qsizetype chunkSize, 
qsizetype mSleep)
+QString LocalHttpClient::getSlowRead(const QString &url, qsizetype chunkSize, 
qsizetype mSleep,
+                                     const QHttpHeaders &headers)
 {
-    sendGet(url);
+    sendGet(url, headers);
 
     qint64 contentLength = -1;
     constexpr qint64 headerBufferSize = 4 * 1024;
@@ -268,8 +277,8 @@
 QString LocalHttpClient::postSlow(const QString &url, const QHttpHeaders 
&headers, qsizetype mSleep)
 {
     Q_ASSERT(socket);
-    qint64 result = socket->write(u"POST %1 HTTP/1.1\r\n"_s.arg(url).toUtf8());
-    QVERIFY2(result >= 0, "Error writing POST method");
+    qint64 result = socket->write(u"POST %1 %2\r\n"_s.arg(url, 
version).toUtf8());
+    QVERIFY2(result != -1, "Error writing POST method");
 
     for (qsizetype i = 0; i < headers.size(); ++i) {
         QByteArray output;
@@ -294,16 +303,46 @@
     return fetchResults();
 }
 
-void LocalHttpClient::sendGet(const QString &url)
+void LocalHttpClient::sendGet(const QString &url, const QHttpHeaders &headers)
+{
+    Q_ASSERT(socket);
+    socket->write(u"GET %1 %2\r\n"_s.arg(url, version).toUtf8());
+    for (qsizetype i = 0; i < headers.size(); ++i) {
+        QByteArray output;
+        output.append(headers.nameAt(i));
+        output.append(": ");
+        output.append(headers.valueAt(i));
+        output.append("\r\n");
+        socket->write(output);
+    }
+    socket->write("\r\n");
+}
+
+void LocalHttpClient::fetchStatusLine()
 {
     Q_ASSERT(socket);
-    socket->write(u"GET %1 HTTP/1.1\r\n\r\n"_s.arg(url).toUtf8());
+    constexpr qint64 bufferSize = 4 * 1024;
+    char buffer[bufferSize];
+    qint64 read = 0;
+    while (!socket->canReadLine())
+        socket->waitForReadyRead(10);
+    read = socket->readLine(buffer, bufferSize);
+    QVERIFY2(read > 2, "Status line too short");
+
+    QByteArrayView line(buffer, read);
+    auto space = line.indexOf(' ');
+    QVERIFY2(space != -1, "Error parsing status line");
+
+    auto httpVersion = line.first(space);
+    QCOMPARE(httpVersion, version);
 }
 
 QString LocalHttpClient::fetchResults()
 {
     Q_ASSERT(socket);
+    fetchStatusLine();
     qint64 contentLength = -1;
+    QByteArray transferEncoding;
     constexpr qint64 bufferSize = 4 * 1024;
     char buffer[bufferSize];
     qint64 read = 0;
@@ -321,27 +360,146 @@
             auto headerTitle = line.first(colon);
             if (headerTitle.compare("Content-Length", Qt::CaseInsensitive) == 
0)
                 contentLength = line.sliced(colon + 1).trimmed().toLongLong();
+            else if (headerTitle.compare("Transfer-Encoding", 
Qt::CaseInsensitive) == 0)
+                transferEncoding = line.sliced(colon + 
1).trimmed().toByteArray();
         }
     };
 
-    QVERIFY2(contentLength != -1, "Content length missing");
     QVERIFY2(contentLength < bufferSize, "Buffer too small");
     if (contentLength == 0)
         return u""_s; // No content
 
-    read = 0;
-    forever {
-        qint64 result = socket->read(&buffer[read], contentLength - read);
-        QVERIFY2(result >= 0, "IO error reading content");
-        read += result;
-        if (read == contentLength)
-            break;
-        socket->waitForReadyRead(10);
-    };
-
+    if (contentLength > 0) {
+        read = 0;
+        while (read < contentLength) {
+            socket->waitForReadyRead(10);
+            qint64 result = socket->read(&buffer[read], contentLength - read);
+            QVERIFY2(result >= 0, "IO Error reading content");
+            read += result;
+        };
+    } else if (transferEncoding.compare("chunked", Qt::CaseInsensitive) == 0) {
+        if (serverType == HTTP1_0)
+            QEXPECT_FAIL("", "QTBUG-138410: The HTTP/1.0 support is 
incomplete", Abort);
+        QVERIFY2(serverType != HTTP1_0, "Chunked encoding not supported for 
HTTP/1.0");
+        read = 0;
+        forever {
+            while (!socket->canReadLine())
+                socket->waitForReadyRead(10);
+            QByteArray line = socket->readLine();
+            qint64 result = line.trimmed().toInt(nullptr, 16);
+            if (result == 0) {
+                fetchCrLf();
+                contentLength = read;
+                break;
+            }
+            qint64 toRead = qMin(result, bufferSize - read);
+            while (toRead > 0) {
+                result = socket->read(&buffer[read], toRead);
+                QVERIFY2(result >= 0, "Read error decoding chunked encoding");
+                read += result;
+                toRead -= result;
+                if (toRead)
+                    socket->waitForReadyRead(10);
+            }
+            fetchCrLf();
+        };
+    } else {
+        // Read until closed
+        read = 0;
+        while (read < bufferSize) {
+            socket->waitForReadyRead(10);
+            qint64 result = socket->read(&buffer[read], bufferSize - read);
+            if (result == -1) {
+                contentLength = read;
+                break;
+            }
+            read += result;
+        };
+    }
     return QString::fromUtf8(buffer, contentLength);
 }
 
+void LocalHttpClient::fetchCrLf()
+{
+    qint64 read = 0;
+    char buffer[2];
+    while (read < 2) {
+        qint64 toRead = 2 - read;
+        qint64 result = socket->read(&buffer[read], toRead);
+        QVERIFY2(result >= 0, "Read error decoding chunked encoding");
+        read += result;
+        if (read < 2)
+            socket->waitForReadyRead(10);
+    }
+    QVERIFY2(buffer[0] == '\r' && buffer[1] == '\n', "Read error decoding 
chunked encoding");
+}
+
+class SequentialIODevice : public QIODevice
+{
+    Q_OBJECT
+
+public:
+    SequentialIODevice(const QByteArray &data, int times, 
std::chrono::milliseconds readInterval)
+        : message(data), times(times)
+    {
+        setOpenMode(QIODeviceBase::ReadOnly);
+        timer = new QTimer(this);
+        timer->callOnTimeout(this, &SequentialIODevice::onTimeout);
+        timer->setSingleShot(false);
+        timer->setInterval(readInterval);
+        timer->start();
+    }
+
+    bool isSequential() const override { return true; }
+    qint64 bytesAvailable() const override { return buffer.size() - readPos; }
+    qint64 bytesToWrite() const override { return 0; }
+
+    bool seek(qint64) override
+    {
+        return false; // No random accesss on sequential devices
+    }
+
+    qint64 readData(char *data, qint64 maxSize) override
+    {
+        qint64 length = qMin(maxSize, buffer.size() - readPos);
+        if (length == 0)
+            return finishedReading ? -1 : 0;
+        QVERIFY(length + readPos <= buffer.size());
+        memcpy(data, buffer.constData() + readPos, length);
+        readPos += length;
+
+        if (readPos == buffer.size()) {
+            readPos = 0;
+            buffer.clear();
+        }
+        return length;
+    }
+
+    qint64 writeData(const char *, qint64) override { return -1; }
+
+    void onTimeout()
+    {
+        if (times > 0) {
+            buffer.append(message);
+            emit readyRead();
+        }
+
+        if (--times <= 0) {
+            timer->stop();
+            finishedReading = true;
+            emit readChannelFinished();
+        }
+    }
+
+private:
+    QTimer *timer;
+    const QByteArray message;
+    QByteArray buffer;
+    qsizetype readPos = 0;
+    int times;
+    bool finishedReading = false;
+};
+
 class tst_QHttpServerMultithreaded final : public QObject
 {
     Q_OBJECT
@@ -369,6 +527,8 @@
     void waitPipelinedQnam();
     void manyWaitingToRespond();
     void oneSlowManyFast();
+    void multipartBack();
+    void sequentialDevice();
 
 private:
     static constexpr qsizetype NumberOfThreads = 6;
@@ -415,7 +575,8 @@
 void tst_QHttpServerMultithreaded::initTestCase_data()
 {
     QTest::addColumn<ServerType>("serverType");
-    QTest::addRow("TCP") << ServerType::TCP;
+    QTest::addRow("HTTP/1.0") << ServerType::HTTP1_0;
+    QTest::addRow("HTTP/1.1") << ServerType::HTTP1_1;
 #if QT_CONFIG(ssl)
     if (QSslSocket::supportsSsl() && 
!QTestPrivate::isSecureTransportBlockingTest())
         QTest::addRow("SSL") << ServerType::SSL;
@@ -468,6 +629,27 @@
                          });
                      });
 
+    httpserver.route("/multipart/<arg>/<arg>",
+                     [this](QString message, int times, QHttpServerResponder 
&responder) {
+                         ++callCounter;
+                         if (times > 0) {
+                             QByteArray ba = message.toUtf8();
+                             responder.writeBeginChunked("text/plain"_ba);
+                             for (int i = 1; i < times; ++i)
+                                 responder.writeChunk(ba);
+                             responder.writeEndChunked(ba);
+                         } else {
+                             responder.write();
+                         }
+                     });
+
+    httpserver.route("/sequential/<arg>/<arg>",
+                     [this](QString message, int times, QHttpServerResponder 
&responder) {
+                         ++callCounter;
+                         auto device = new 
SequentialIODevice(message.toUtf8(), times, 50ms);
+                         responder.write(device, QHttpHeaders());
+                     });
+
     auto tcpserver = std::make_unique<QTcpServer>();
     QVERIFY2(tcpserver->listen(), "HTTP server listen failed");
     port = tcpserver->serverPort();
@@ -563,17 +745,21 @@
 
     QFuture<QList<QString>> futureLower = QtConcurrent::run(&clientThreadPool, 
[&]() {
         LocalHttpClient client(serverType);
+        QHttpHeaders headers;
+        headers.append(QHttpHeaders::WellKnownHeader::Connection, 
"keep-alive");
         QList<QString> results;
         for (auto &input : inputs)
-            
results.push_back(client.get(u"/convert-lowercase/%1"_s.arg(input)));
+            
results.push_back(client.get(u"/convert-lowercase/%1"_s.arg(input), headers));
         return results;
     });
 
     QFuture<QList<QString>> futureUpper = QtConcurrent::run(&clientThreadPool, 
[&]() {
         LocalHttpClient client(serverType);
+        QHttpHeaders headers;
+        headers.append(QHttpHeaders::WellKnownHeader::Connection, 
"keep-alive");
         QList<QString> results;
         for (auto &input : inputs)
-            
results.push_back(client.get(u"/convert-uppercase/%1"_s.arg(input)));
+            
results.push_back(client.get(u"/convert-uppercase/%1"_s.arg(input), headers));
         return results;
     });
 
@@ -605,17 +791,20 @@
         futures[i] = QtConcurrent::run(&clientThreadPool, [&]() {
             LocalHttpClient client(serverType);
             QList<std::pair<QString, QString>> results;
+            QHttpHeaders headers;
+            headers.append(QHttpHeaders::WellKnownHeader::Connection, 
"keep-alive");
             for (auto &input : inputs) {
-                QString lower = 
client.get(u"/convert-lowercase/%1"_s.arg(input));
-                QString upper = 
client.get(u"/convert-uppercase/%1"_s.arg(input));
+                QString lower = 
client.get(u"/convert-lowercase/%1"_s.arg(input), headers);
+                QString upper = 
client.get(u"/convert-uppercase/%1"_s.arg(input), headers);
                 results.push_back(std::make_pair(lower, upper));
             }
             return results;
         });
     };
 
-    QTRY_VERIFY(std::all_of(futures.begin(), futures.end(),
-                            [](auto &future) { return future.isFinished(); }));
+    QTRY_VERIFY_WITH_TIMEOUT(std::all_of(futures.begin(), futures.end(),
+                                         [](auto &future) { return 
future.isFinished(); }),
+                             10s);
 
     QCOMPARE(getCallCount(), inputs.size() * NumberOfTasks * 2);
     for (qsizetype i = 0; i < NumberOfTasks; ++i) {
@@ -637,8 +826,12 @@
     for (qsizetype i = 0; i < NumberOfTasks; ++i) {
         futures[i] = QtConcurrent::run([&](QPromise<QString> &promise) {
             LocalHttpClient client(serverType);
-            
promise.addResult(client.getSlowRead(u"/convert-lowercase/%1"_s.arg(input), 10, 
3000));
-            
promise.addResult(client.getSlowRead(u"/convert-uppercase/%1"_s.arg(input), 10, 
1000));
+            QHttpHeaders headers;
+            headers.append(QHttpHeaders::WellKnownHeader::Connection, 
"keep-alive");
+            promise.addResult(
+                    client.getSlowRead(u"/convert-lowercase/%1"_s.arg(input), 
10, 3000, headers));
+            promise.addResult(
+                    client.getSlowRead(u"/convert-uppercase/%1"_s.arg(input), 
10, 1000, headers));
         });
     }
 
@@ -731,15 +924,19 @@
 
     QFuture<QString> future1 = QtConcurrent::run(&clientThreadPool, [&]() {
         LocalHttpClient client(serverType);
-        QString result = client.get(u"/wait/2001"_s);
-        result += client.get(u"/wait/9"_s);
+        QHttpHeaders headers;
+        headers.append(QHttpHeaders::WellKnownHeader::Connection, 
"keep-alive");
+        QString result = client.get(u"/wait/2001"_s, headers);
+        result += client.get(u"/wait/9"_s, headers);
         return result;
     });
 
     QFuture<QString> future2 = QtConcurrent::run(&clientThreadPool, [&]() {
         LocalHttpClient client(serverType);
-        QString result = client.get(u"/wait/2000"_s);
-        result += client.get(u"/wait/10"_s);
+        QHttpHeaders headers;
+        headers.append(QHttpHeaders::WellKnownHeader::Connection, 
"keep-alive");
+        QString result = client.get(u"/wait/2000"_s, headers);
+        result += client.get(u"/wait/10"_s, headers);
         return result;
     });
 
@@ -751,6 +948,8 @@
 void tst_QHttpServerMultithreaded::waitPipelined()
 {
     QFETCH_GLOBAL(ServerType, serverType);
+    if (serverType == HTTP1_0)
+        QSKIP("Pipelining is not supported for HTTP/1.0");
     QList<qsizetype> waitTimes = { 3000, 1000, 1 };
     constexpr qsizetype NumberOfTasks = NumberOfThreads;
 
@@ -782,8 +981,8 @@
 void tst_QHttpServerMultithreaded::waitPipelinedQnam()
 {
     QFETCH_GLOBAL(ServerType, serverType);
-    if (serverType != TCP)
-        QSKIP("This test only supports TCP");
+    if (serverType != HTTP1_1)
+        QSKIP("This test only supports HTTP/1.1 over TCP");
 
     QList<qsizetype> waitTimes = { 3000, 1000, 1 };
     constexpr qsizetype NumberOfTasks = NumberOfThreads;
@@ -877,6 +1076,40 @@
     QCOMPARE(getCallCount(), NumberOfFastTasks + 1);
 }
 
+void tst_QHttpServerMultithreaded::multipartBack()
+{
+    QFETCH_GLOBAL(ServerType, serverType);
+
+    QFuture<QString> future = QtConcurrent::run([&]() {
+        LocalHttpClient client(serverType);
+        return client.get("/multipart/Hey/3");
+    });
+
+    QTRY_VERIFY(future.isFinished());
+
+    QString returned = future.result();
+    QCOMPARE(returned, u"HeyHeyHey"_s);
+    QCOMPARE(getCallCount(), 1);
+}
+
+void tst_QHttpServerMultithreaded::sequentialDevice()
+{
+    QFETCH_GLOBAL(ServerType, serverType);
+
+    QFuture<QString> future = QtConcurrent::run([&]() {
+        LocalHttpClient client(serverType);
+        return client.get("/sequential/Hey/3");
+    });
+
+    QTRY_VERIFY(future.isFinished());
+
+    QString returned = future.result();
+    if (serverType == HTTP1_0)
+        QSKIP("QTBUG-138410: The HTTP/1.0 support is incomplete: Flaky, mostly 
fails on HTTP/1.0");
+    QCOMPARE(returned, u"HeyHeyHey"_s);
+    QCOMPARE(getCallCount(), 1);
+}
+
 QT_END_NAMESPACE
 
 QTEST_MAIN(tst_QHttpServerMultithreaded)

Reply via email to