summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Hartmann <phartmann@blackberry.com>2013-08-13 16:48:09 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-22 12:37:30 +0200
commit4f7e0fc632f36fc676303423af5d62adfb8d088f (patch)
treea201c142424a4c83e506b62182b12e3a27dc7b9b /src
parent676a10b3dc8fad7a3cf6b77d5e8ecf6df2e039bb (diff)
HTTP socket engine: support newer HTTP proxies
After sending authentication, we need to revert all states to be able to read the HTTP header again. Before, we would not try to read an HTTP header after sending authentication. Change-Id: Id4b95eda9881a37bcfbae0570756bb3e4918a568 Reviewed-by: Richard J. Moore <rich@kde.org> Reviewed-by: Shane Kearns <shane.kearns.qt@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/network/socket/qhttpsocketengine.cpp92
-rw-r--r--src/network/socket/qhttpsocketengine_p.h5
2 files changed, 60 insertions, 37 deletions
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index f2a1633bd3..2e920ad69f 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -545,7 +545,25 @@ void QHttpSocketEngine::slotSocketReadNotification()
return;
}
- readResponseContent:
+ if (d->state == ConnectSent) {
+ d->reply->d_func()->state = QHttpNetworkReplyPrivate::NothingDoneState;
+ d->state = ReadResponseHeader;
+ }
+
+ if (d->state == ReadResponseHeader) {
+ bool ok = readHttpHeader();
+ if (!ok) {
+ // protocol error, this isn't HTTP
+ d->socket->close();
+ setState(QAbstractSocket::UnconnectedState);
+ setError(QAbstractSocket::ProxyProtocolError, tr("Did not receive HTTP response from proxy"));
+ emitConnectionNotification();
+ return;
+ }
+ if (d->state == ReadResponseHeader)
+ return; // readHttpHeader() was not done yet, need to wait for more header data
+ }
+
if (d->state == ReadResponseContent) {
char dummybuffer[4096];
while (d->pendingResponseData) {
@@ -564,31 +582,8 @@ void QHttpSocketEngine::slotSocketReadNotification()
}
if (d->pendingResponseData > 0)
return;
- d->state = SendAuthentication;
- slotSocketConnected();
- return;
- }
-
- bool ok = true;
- if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::NothingDoneState)
- d->reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
- if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState) {
- ok = d->reply->d_func()->readStatus(d->socket) != -1;
- if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState)
- return; //Not done parsing headers yet, wait for more data
- }
- if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState) {
- ok = d->reply->d_func()->readHeader(d->socket) != -1;
- if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState)
- return; //Not done parsing headers yet, wait for more data
- }
- if (!ok) {
- // protocol error, this isn't HTTP
- d->socket->close();
- setState(QAbstractSocket::UnconnectedState);
- setError(QAbstractSocket::ProxyProtocolError, tr("Did not receive HTTP response from proxy"));
- emitConnectionNotification();
- return;
+ if (d->reply->d_func()->statusCode == 407)
+ d->state = SendAuthentication;
}
int statusCode = d->reply->statusCode();
@@ -664,16 +659,8 @@ void QHttpSocketEngine::slotSocketReadNotification()
if (willClose) {
d->socket->connectToHost(d->proxy.hostName(), d->proxy.port());
} else {
- bool ok;
- int contentLength = d->reply->headerField("Content-Length").toInt(&ok);
- if (ok && contentLength > 0) {
- d->state = ReadResponseContent;
- d->pendingResponseData = contentLength;
- goto readResponseContent;
- } else {
- d->state = SendAuthentication;
- slotSocketConnected();
- }
+ // send the HTTP CONNECT again
+ slotSocketConnected();
}
return;
}
@@ -701,6 +688,39 @@ void QHttpSocketEngine::slotSocketReadNotification()
emitConnectionNotification();
}
+bool QHttpSocketEngine::readHttpHeader()
+{
+ Q_D(QHttpSocketEngine);
+
+ if (d->state != ReadResponseHeader)
+ return false;
+
+ bool ok = true;
+ if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::NothingDoneState) {
+ // do not keep old content sizes, status etc. around
+ d->reply->d_func()->clearHttpLayerInformation();
+ d->reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
+ }
+ if (d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState) {
+ ok = d->reply->d_func()->readStatus(d->socket) != -1;
+ if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingStatusState)
+ return true; //Not done parsing headers yet, wait for more data
+ }
+ if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState) {
+ ok = d->reply->d_func()->readHeader(d->socket) != -1;
+ if (ok && d->reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingHeaderState)
+ return true; //Not done parsing headers yet, wait for more data
+ }
+ if (ok) {
+ bool contentLengthOk;
+ int contentLength = d->reply->headerField("Content-Length").toInt(&contentLengthOk);
+ if (contentLengthOk && contentLength > 0)
+ d->pendingResponseData = contentLength;
+ d->state = ReadResponseContent; // we are done reading the header
+ }
+ return ok;
+}
+
void QHttpSocketEngine::slotSocketBytesWritten()
{
Q_D(QHttpSocketEngine);
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index bac6d9edf7..7567772517 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -75,7 +75,8 @@ public:
ConnectSent,
Connected,
SendAuthentication,
- ReadResponseContent
+ ReadResponseContent,
+ ReadResponseHeader
};
QHttpSocketEngine(QObject *parent = 0);
~QHttpSocketEngine();
@@ -156,6 +157,8 @@ private:
void emitWriteNotification();
void emitConnectionNotification();
+ bool readHttpHeader();
+
Q_DECLARE_PRIVATE(QHttpSocketEngine)
Q_DISABLE_COPY(QHttpSocketEngine)