Accept LFCRLF to mark end of HTTP Headers
Some embedded servers use LF to mark the end of an individual header, but use CRLF to mark the end of all the headers. The GoPro WiFi interface does this, as an example. Change-Id: I227ab73622c84f439a6cf8703d020393c4d8bf69 Reviewed-by: Marc Mutz <marc.mutz@kdab.com> Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>bb10
parent
d7db6c6c19
commit
f8f1bac3f0
|
|
@ -554,9 +554,8 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
|
|||
if (c == '\n') {
|
||||
// check for possible header endings. As per HTTP rfc,
|
||||
// the header endings will be marked by CRLFCRLF. But
|
||||
// we will allow CRLFCRLF, CRLFLF, LFLF
|
||||
if (fragment.endsWith("\r\n\r\n")
|
||||
|| fragment.endsWith("\r\n\n")
|
||||
// we will allow CRLFCRLF, CRLFLF, LFCRLF, LFLF
|
||||
if (fragment.endsWith("\n\r\n")
|
||||
|| fragment.endsWith("\n\n"))
|
||||
allHeaders = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate
|
||||
class Q_AUTOTEST_EXPORT QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate
|
||||
{
|
||||
public:
|
||||
QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl());
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QByteArray>
|
||||
|
||||
#include "private/qhttpnetworkconnection_p.h"
|
||||
|
||||
class tst_QHttpNetworkReply: public QObject
|
||||
|
|
@ -46,6 +49,9 @@ private Q_SLOTS:
|
|||
|
||||
void parseHeader_data();
|
||||
void parseHeader();
|
||||
|
||||
void parseEndOfHeader_data();
|
||||
void parseEndOfHeader();
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -122,5 +128,66 @@ void tst_QHttpNetworkReply::parseHeader()
|
|||
}
|
||||
}
|
||||
|
||||
class TestHeaderSocket : public QAbstractSocket
|
||||
{
|
||||
public:
|
||||
explicit TestHeaderSocket(const QByteArray &input) : QAbstractSocket(QAbstractSocket::TcpSocket, Q_NULLPTR)
|
||||
{
|
||||
inputBuffer.setData(input);
|
||||
inputBuffer.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||
open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||
}
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen) { return inputBuffer.read(data, maxlen); }
|
||||
|
||||
QBuffer inputBuffer;
|
||||
};
|
||||
|
||||
class TestHeaderReply : public QHttpNetworkReply
|
||||
{
|
||||
public:
|
||||
QHttpNetworkReplyPrivate *replyPrivate() { return static_cast<QHttpNetworkReplyPrivate *>(d_ptr.data()); }
|
||||
};
|
||||
|
||||
void tst_QHttpNetworkReply::parseEndOfHeader_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("headers");
|
||||
QTest::addColumn<qint64>("lengths");
|
||||
|
||||
QTest::newRow("CRLFCRLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Content-Length:\r\n 1024\r\n"
|
||||
"Content-Encoding: gzip\r\n\r\nHTTPBODY")
|
||||
<< qint64(90);
|
||||
|
||||
QTest::newRow("CRLFLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Content-Length:\r\n 1024\r\n"
|
||||
"Content-Encoding: gzip\r\n\nHTTPBODY")
|
||||
<< qint64(89);
|
||||
|
||||
QTest::newRow("LFCRLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Content-Length:\r\n 1024\r\n"
|
||||
"Content-Encoding: gzip\n\r\nHTTPBODY")
|
||||
<< qint64(89);
|
||||
|
||||
QTest::newRow("LFLF") << QByteArray("Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Content-Length:\r\n 1024\r\n"
|
||||
"Content-Encoding: gzip\n\nHTTPBODY")
|
||||
<< qint64(88);
|
||||
}
|
||||
|
||||
void tst_QHttpNetworkReply::parseEndOfHeader()
|
||||
{
|
||||
QFETCH(QByteArray, headers);
|
||||
QFETCH(qint64, lengths);
|
||||
|
||||
TestHeaderSocket socket(headers);
|
||||
|
||||
TestHeaderReply reply;
|
||||
|
||||
QHttpNetworkReplyPrivate *replyPrivate = reply.replyPrivate();
|
||||
qint64 headerBytes = replyPrivate->readHeader(&socket);
|
||||
QCOMPARE(headerBytes, lengths);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHttpNetworkReply)
|
||||
#include "tst_qhttpnetworkreply.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue