QNAM should prepend Host header to the header list instead of appending

When original QNetworkRequest is missing "Host" header (which is the most
common case), it is provided automatically from request URL. However,
resulting header is appended to the list, i.e. after all headers specified
by user, which may include a big bunch of cookies.

To the contrary, RFC 7230 suggests: "However, it is good practice to send
header fields that contain control data first, such as Host on requests
and Date on responses, so that implementations can decide when not to
handle a message as early as possible". Many other user agents are
following this suggestion.

Task-number: QTBUG-51557
Change-Id: I1448ed3ae124f5ce86a8ca8ff35f5d05476a005d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
bb10
Konstantin Tokarev 2018-01-17 15:22:56 +03:00
parent b40e0e7233
commit d2b2511f88
5 changed files with 13 additions and 1 deletions

View File

@ -355,7 +355,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
host += QByteArray::number(port);
}
request.setHeaderField("Host", host);
request.prependHeaderField("Host", host);
}
reply->d_func()->requestIsPrepared = true;

View File

@ -114,6 +114,11 @@ void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QBy
fields.append(qMakePair(name, data));
}
void QHttpNetworkHeaderPrivate::prependHeaderField(const QByteArray &name, const QByteArray &data)
{
fields.prepend(qMakePair(name, data));
}
bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const
{
return (url == other.url);

View File

@ -92,6 +92,7 @@ public:
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
QList<QByteArray> headerFieldValues(const QByteArray &name) const;
void setHeaderField(const QByteArray &name, const QByteArray &data);
void prependHeaderField(const QByteArray &name, const QByteArray &data);
bool operator==(const QHttpNetworkHeaderPrivate &other) const;
};

View File

@ -279,6 +279,11 @@ void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArra
d->setHeaderField(name, data);
}
void QHttpNetworkRequest::prependHeaderField(const QByteArray &name, const QByteArray &data)
{
d->prependHeaderField(name, data);
}
QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)
{
d = other.d;

View File

@ -102,6 +102,7 @@ public:
QList<QPair<QByteArray, QByteArray> > header() const Q_DECL_OVERRIDE;
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const Q_DECL_OVERRIDE;
void setHeaderField(const QByteArray &name, const QByteArray &data) Q_DECL_OVERRIDE;
void prependHeaderField(const QByteArray &name, const QByteArray &data);
Operation operation() const;
void setOperation(Operation operation);