1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31#include <QtCore/QBuffer>
32#include <QtCore/QByteArray>
33
34#include "private/qhttpnetworkconnection_p.h"
35
36class tst_QHttpNetworkReply: public QObject
37{
38 Q_OBJECT
39private Q_SLOTS:
40 void parseHeader_data();
41 void parseHeader();
42
43 void parseEndOfHeader_data();
44 void parseEndOfHeader();
45};
46
47void tst_QHttpNetworkReply::parseHeader_data()
48{
49 QTest::addColumn<QByteArray>(name: "headers");
50 QTest::addColumn<QStringList>(name: "fields");
51 QTest::addColumn<QStringList>(name: "values");
52
53 QTest::newRow(dataTag: "empty-field") << QByteArray("Set-Cookie: \r\n")
54 << (QStringList() << "Set-Cookie")
55 << (QStringList() << "");
56 QTest::newRow(dataTag: "single-field") << QByteArray("Content-Type: text/html; charset=utf-8\r\n")
57 << (QStringList() << "Content-Type")
58 << (QStringList() << "text/html; charset=utf-8");
59 QTest::newRow(dataTag: "single-field-continued") << QByteArray("Content-Type: text/html;\r\n"
60 " charset=utf-8\r\n")
61 << (QStringList() << "Content-Type")
62 << (QStringList() << "text/html; charset=utf-8");
63
64 QTest::newRow(dataTag: "multi-field") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
65 "Content-Length: 1024\r\n"
66 "Content-Encoding: gzip\r\n")
67 << (QStringList() << "Content-Type" << "Content-Length" << "Content-Encoding")
68 << (QStringList() << "text/html; charset=utf-8" << "1024" << "gzip");
69 QTest::newRow(dataTag: "multi-field-with-emtpy") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
70 "Content-Length: 1024\r\n"
71 "Set-Cookie: \r\n"
72 "Content-Encoding: gzip\r\n")
73 << (QStringList() << "Content-Type" << "Content-Length" << "Set-Cookie" << "Content-Encoding")
74 << (QStringList() << "text/html; charset=utf-8" << "1024" << "" << "gzip");
75
76 QTest::newRow(dataTag: "lws-field") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
77 "Content-Length:\r\n 1024\r\n"
78 "Content-Encoding: gzip\r\n")
79 << (QStringList() << "Content-Type" << "Content-Length" << "Content-Encoding")
80 << (QStringList() << "text/html; charset=utf-8" << "1024" << "gzip");
81
82 QTest::newRow(dataTag: "duplicated-field") << QByteArray("Vary: Accept-Language\r\n"
83 "Vary: Cookie\r\n"
84 "Vary: User-Agent\r\n")
85 << (QStringList() << "Vary")
86 << (QStringList() << "Accept-Language, Cookie, User-Agent");
87}
88
89void tst_QHttpNetworkReply::parseHeader()
90{
91 QFETCH(QByteArray, headers);
92 QFETCH(QStringList, fields);
93 QFETCH(QStringList, values);
94
95 QHttpNetworkReply reply;
96 reply.parseHeader(header: headers);
97 for (int i = 0; i < fields.count(); ++i) {
98 //qDebug() << "field" << fields.at(i) << "value" << reply.headerField(fields.at(i)) << "expected" << values.at(i);
99 QString field = reply.headerField(name: fields.at(i).toLatin1());
100 QCOMPARE(field, values.at(i));
101 }
102}
103
104class TestHeaderSocket : public QAbstractSocket
105{
106public:
107 explicit TestHeaderSocket(const QByteArray &input) : QAbstractSocket(QAbstractSocket::TcpSocket, nullptr)
108 {
109 inputBuffer.setData(input);
110 inputBuffer.open(openMode: QIODevice::ReadOnly | QIODevice::Unbuffered);
111 open(mode: QIODevice::ReadOnly | QIODevice::Unbuffered);
112 }
113
114 qint64 readData(char *data, qint64 maxlen) { return inputBuffer.read(data, maxlen); }
115
116 QBuffer inputBuffer;
117};
118
119class TestHeaderReply : public QHttpNetworkReply
120{
121public:
122 QHttpNetworkReplyPrivate *replyPrivate() { return static_cast<QHttpNetworkReplyPrivate *>(d_ptr.data()); }
123};
124
125void tst_QHttpNetworkReply::parseEndOfHeader_data()
126{
127 QTest::addColumn<QByteArray>(name: "headers");
128 QTest::addColumn<qint64>(name: "lengths");
129
130 QTest::newRow(dataTag: "CRLFCRLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
131 "Content-Length:\r\n 1024\r\n"
132 "Content-Encoding: gzip\r\n\r\nHTTPBODY")
133 << qint64(90);
134
135 QTest::newRow(dataTag: "CRLFLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
136 "Content-Length:\r\n 1024\r\n"
137 "Content-Encoding: gzip\r\n\nHTTPBODY")
138 << qint64(89);
139
140 QTest::newRow(dataTag: "LFCRLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
141 "Content-Length:\r\n 1024\r\n"
142 "Content-Encoding: gzip\n\r\nHTTPBODY")
143 << qint64(89);
144
145 QTest::newRow(dataTag: "LFLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
146 "Content-Length:\r\n 1024\r\n"
147 "Content-Encoding: gzip\n\nHTTPBODY")
148 << qint64(88);
149}
150
151void tst_QHttpNetworkReply::parseEndOfHeader()
152{
153 QFETCH(QByteArray, headers);
154 QFETCH(qint64, lengths);
155
156 TestHeaderSocket socket(headers);
157
158 TestHeaderReply reply;
159
160 QHttpNetworkReplyPrivate *replyPrivate = reply.replyPrivate();
161 qint64 headerBytes = replyPrivate->readHeader(socket: &socket);
162 QCOMPARE(headerBytes, lengths);
163}
164
165QTEST_MAIN(tst_QHttpNetworkReply)
166#include "tst_qhttpnetworkreply.moc"
167

source code of qtbase/tests/auto/network/access/qhttpnetworkreply/tst_qhttpnetworkreply.cpp