summaryrefslogtreecommitdiffstats
path: root/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp
blob: 729605d9c8631e49fccfd3d80cd303d8e43d9c15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include <QtNetwork/qtnetworkglobal.h>

#include <QtTest/qtest.h>

#include <QtNetwork/qnetworkreply.h>
#include <QtNetwork/qnetworkaccessmanager.h>

#include "minihttpserver.h"

using namespace Qt::StringLiterals;

/*
    The tests here are meant to be self-contained, using servers in the same
    process if needed. This enables externals to more easily run the tests too.
*/
class tst_QNetworkReply_local : public QObject
{
    Q_OBJECT
private slots:
    void initTestCase_data();

    void get();
    void post();
};

void tst_QNetworkReply_local::initTestCase_data()
{
    QTest::addColumn<QString>("scheme");

    QTest::newRow("http") << "http";
#if QT_CONFIG(localserver)
    QTest::newRow("unix") << "unix+http";
    QTest::newRow("local") << "local+http"; // equivalent to unix, but test that it works
#endif
}

static std::unique_ptr<MiniHttpServerV2> getServerForCurrentScheme()
{
    auto server = std::make_unique<MiniHttpServerV2>();
    QFETCH_GLOBAL(QString, scheme);
    if (scheme.startsWith("unix"_L1) || scheme.startsWith("local"_L1)) {
#if QT_CONFIG(localserver)
        QLocalServer *localServer = new QLocalServer(server.get());
        localServer->listen(u"qt_networkreply_test_"_s
                            % QLatin1StringView(QTest::currentTestFunction())
                            % QString::number(QCoreApplication::applicationPid()));
        server->bind(localServer);
#endif
    } else if (scheme == "http") {
        QTcpServer *tcpServer = new QTcpServer(server.get());
        tcpServer->listen(QHostAddress::LocalHost, 0);
        server->bind(tcpServer);
    }
    return server;
}

static QUrl getUrlForCurrentScheme(MiniHttpServerV2 *server)
{
    QFETCH_GLOBAL(QString, scheme);
    const QString address = server->addressForScheme(scheme);
    const QString urlString = QLatin1StringView("%1://%2").arg(scheme, address);
    return { urlString };
}

void tst_QNetworkReply_local::get()
{
    std::unique_ptr<MiniHttpServerV2> server = getServerForCurrentScheme();
    const QUrl url = getUrlForCurrentScheme(server.get());

    QNetworkAccessManager manager;
    std::unique_ptr<QNetworkReply> reply(manager.get(QNetworkRequest(url)));

    const bool res = QTest::qWaitFor([reply = reply.get()] { return reply->isFinished(); });
    QVERIFY(res);

    QCOMPARE(reply->readAll(), QByteArray("Hello World!"));
    QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200);
}

void tst_QNetworkReply_local::post()
{
    std::unique_ptr<MiniHttpServerV2> server = getServerForCurrentScheme();
    const QUrl url = getUrlForCurrentScheme(server.get());

    QNetworkAccessManager manager;
    const QByteArray payload = "Hello from the other side!"_ba;
    QNetworkRequest req(url);
    req.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
    std::unique_ptr<QNetworkReply> reply(manager.post(req, payload));

    const bool res = QTest::qWaitFor([reply = reply.get()] { return reply->isFinished(); });
    QVERIFY(res);

    QCOMPARE(reply->readAll(), QByteArray("Hello World!"));
    QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200);

    auto states = server->peerStates();
    QCOMPARE(states.size(), 1);

    const auto &firstRequest = states.at(0);

    QVERIFY(firstRequest.checkedContentLength);
    QCOMPARE(firstRequest.contentLength, payload.size());
    QCOMPARE_GT(firstRequest.receivedData.size(), payload.size() + 4);
    QCOMPARE(firstRequest.receivedData.last(payload.size() + 4), "\r\n\r\n" + payload);
}

QTEST_MAIN(tst_QNetworkReply_local)

#include "tst_qnetworkreply_local.moc"
#include "moc_minihttpserver.cpp"