From 90c3e1d2110c47ad36e05c04c874d6d932dd772f Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 18 Feb 2010 14:41:20 +0100 Subject: QNAM HTTP: Clean code a bit .. and some changes that will help us track down bugs Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 10 ++-- .../access/qhttpnetworkconnectionchannel.cpp | 64 ++++++++++++++-------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 327d2db..62aa2d7 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -689,14 +689,12 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() if (channels[i].resendCurrent) { channels[i].resendCurrent = false; channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) { - // if this is not possible, error will be emitted and connection terminated - if (!channels[i].resetUploadData()) - continue; + // if this is not possible, error will be emitted and connection terminated + if (!channels[i].resetUploadData()) + continue; - channels[i].sendRequest(); - } + channels[i].sendRequest(); } } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 89fd032..dbee72a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -124,6 +124,13 @@ void QHttpNetworkConnectionChannel::close() bool QHttpNetworkConnectionChannel::sendRequest() { + if (!reply) { + // heh, how should that happen! + qWarning() << "QHttpNetworkConnectionChannel::sendRequest() called without QHttpNetworkReply"; + state = QHttpNetworkConnectionChannel::IdleState; + return false; + } + switch (state) { case QHttpNetworkConnectionChannel::IdleState: { // write the header if (!ensureConnection()) { @@ -134,14 +141,13 @@ bool QHttpNetworkConnectionChannel::sendRequest() } written = 0; // excluding the header bytesTotal = 0; - if (reply) { - reply->d_func()->clear(); - reply->d_func()->connection = connection; - reply->d_func()->connectionChannel = this; - reply->d_func()->autoDecompress = request.d->autoDecompress; - reply->d_func()->pipeliningUsed = false; - } - state = QHttpNetworkConnectionChannel::WritingState; + + reply->d_func()->clear(); + reply->d_func()->connection = connection; + reply->d_func()->connectionChannel = this; + reply->d_func()->autoDecompress = request.d->autoDecompress; + reply->d_func()->pipeliningUsed = false; + pendingEncrypt = false; // if the url contains authentication parameters, use the new ones // both channels will use the new authentication parameters @@ -175,13 +181,15 @@ bool QHttpNetworkConnectionChannel::sendRequest() QObject::connect(uploadByteDevice, SIGNAL(readyRead()),this, SLOT(_q_uploadDataReadyRead())); bytesTotal = request.contentLength(); + + state = QHttpNetworkConnectionChannel::WritingState; // start writing data + sendRequest(); //recurse } else { - state = QHttpNetworkConnectionChannel::WaitingState; - sendRequest(); - break; + state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response + sendRequest(); //recurse } - // write the initial chunk together with the headers - // fall through + + break; } case QHttpNetworkConnectionChannel::WritingState: { @@ -191,7 +199,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() if (uploadByteDevice) emit reply->dataSendProgress(written, bytesTotal); state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response - sendRequest(); + sendRequest(); // recurse break; } @@ -279,16 +287,25 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(socket); + if (!reply) { + // heh, how should that happen! + qWarning() << "QHttpNetworkConnectionChannel::_q_receiveReply() called without QHttpNetworkReply," + << socket->bytesAvailable() << "bytes on socket."; + close(); + return; + } + qint64 bytes = 0; QAbstractSocket::SocketState socketState = socket->state(); // connection might be closed to signal the end of data if (socketState == QAbstractSocket::UnconnectedState) { if (socket->bytesAvailable() <= 0) { - if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { + if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { // finish this reply. this case happens when the server did not send a content length reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; allDone(); + return; } else { handleUnexpectedEOF(); return; @@ -300,12 +317,13 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() // read loop for the response while (socket->bytesAvailable()) { - QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState; + QHttpNetworkReplyPrivate::ReplyState state = reply->d_func()->state; switch (state) { case QHttpNetworkReplyPrivate::NothingDoneState: { // only eat whitespace on the first call eatWhitespace(); state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState; + // fallthrough } case QHttpNetworkReplyPrivate::ReadingStatusState: { qint64 statusBytes = reply->d_func()->readStatus(socket); @@ -413,8 +431,10 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() #endif } } + // still in ReadingDataState? This function will be called again by the socket's readyRead if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) break; + // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: @@ -752,13 +772,11 @@ void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) QHttpNetworkRequest &request = pair.first; QHttpNetworkReply *reply = pair.second; - if (reply) { - reply->d_func()->clear(); - reply->d_func()->connection = connection; - reply->d_func()->connectionChannel = this; - reply->d_func()->autoDecompress = request.d->autoDecompress; - reply->d_func()->pipeliningUsed = true; - } + reply->d_func()->clear(); + reply->d_func()->connection = connection; + reply->d_func()->connectionChannel = this; + reply->d_func()->autoDecompress = request.d->autoDecompress; + reply->d_func()->pipeliningUsed = true; #ifndef QT_NO_NETWORKPROXY QByteArray header = QHttpNetworkRequestPrivate::header(request, -- cgit v0.12