diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-05-13 10:25:36 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-05-13 11:55:57 (GMT) |
commit | 87022c9a4ab00a9faaf6bcdaa8d5884962ccf305 (patch) | |
tree | 7229c0fffcc830e2c08ac92774cdf736a25b29ba /src/network | |
parent | 4910404284b1bb4fdde89d4fd8a420767ee52069 (diff) | |
download | Qt-87022c9a4ab00a9faaf6bcdaa8d5884962ccf305.zip Qt-87022c9a4ab00a9faaf6bcdaa8d5884962ccf305.tar.gz Qt-87022c9a4ab00a9faaf6bcdaa8d5884962ccf305.tar.bz2 |
Fix handling of garbage data sent by the HTTP server instead of a
proper HTTP reply.
If the server's reply doesn't start with "HTTP/", then the reply is
not valid. This could happen if we connected via HTTP to an HTTPS
server. It could also happen with an Icecast server (reply ICY/x.y).
Task-number: 248838
Reviewed-by: Markus Goetz
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 14 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkreply.cpp | 11 |
2 files changed, 22 insertions, 3 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 5940fba..f558f2b 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -529,10 +529,20 @@ void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpN QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState; switch (state) { case QHttpNetworkReplyPrivate::NothingDoneState: - case QHttpNetworkReplyPrivate::ReadingStatusState: - bytes += reply->d_func()->readStatus(socket); + case QHttpNetworkReplyPrivate::ReadingStatusState: { + qint64 statusBytes = reply->d_func()->readStatus(socket); + if (statusBytes == -1) { + // error reading the status, close the socket and emit error + socket->close(); + reply->d_func()->errorString = errorDetail(QNetworkReply::ProtocolFailure, socket); + emit reply->finishedWithError(QNetworkReply::ProtocolFailure, reply->d_func()->errorString); + QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); + break; + } + bytes += statusBytes; channels[i].lastStatus = reply->d_func()->statusCode; break; + } case QHttpNetworkReplyPrivate::ReadingHeaderState: bytes += reply->d_func()->readHeader(socket); if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index fe3f6af..1b41e1e 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -409,6 +409,9 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) if (fragment.endsWith('\r')) { fragment.truncate(fragment.length()-1); } + if (!fragment.startsWith("HTTP/")) + return -1; + parseStatus(fragment); state = ReadingHeaderState; fragment.clear(); // next fragment @@ -418,7 +421,13 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) bytes += socket->read(&c, 1); fragment.append(c); } + + // is this a valid reply? + if (fragment.length() >= 5 && !fragment.startsWith("HTTP/")) + return -1; + } + return bytes; } @@ -660,4 +669,4 @@ void QHttpNetworkReply::ignoreSslErrors() QT_END_NAMESPACE -#endif // QT_NO_HTTP
\ No newline at end of file +#endif // QT_NO_HTTP |