diff --git a/mozilla/netwerk/protocol/http/src/nsHTTPChannel.cpp b/mozilla/netwerk/protocol/http/src/nsHTTPChannel.cpp index 9dcc3cc9207..a1022c17170 100644 --- a/mozilla/netwerk/protocol/http/src/nsHTTPChannel.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHTTPChannel.cpp @@ -835,20 +835,22 @@ private: NS_IMETHOD OnDataAvailable(nsIChannel *aChannel, nsISupports *aContext, - nsIInputStream *aStream, PRUint32 aSourceOffset, PRUint32 aCount) { - return mListener->OnDataAvailable(aChannel, aContext, aStream, aSourceOffset, aCount); + nsIInputStream *aStream, PRUint32 aSourceOffset, + PRUint32 aCount) + { + return mListener->OnDataAvailable(mChannel, aContext, + aStream, aSourceOffset, aCount); } NS_IMETHOD OnStartRequest(nsIChannel *aChannel, nsISupports *aContext) { - return mListener->OnStartRequest(aChannel, aContext); + return mListener->OnStartRequest(mChannel, aContext); } NS_IMETHOD OnStopRequest(nsIChannel *aChannel, nsISupports *aContext, nsresult aStatus, const PRUnichar *aErrorMsg) { - mChannel->ResponseCompleted(0, aStatus, aErrorMsg); - return mListener->OnStopRequest(aChannel, aContext, aStatus, aErrorMsg); + return mChannel->ResponseCompleted(nsnull, mListener, aStatus, aErrorMsg); } protected: @@ -918,7 +920,7 @@ nsHTTPChannel::ReadFromCache(PRUint32 aStartPosition, PRInt32 aReadCount) mResponseContext, listener); NS_RELEASE(listener); if (NS_FAILED(rv)) { - ResponseCompleted(0, rv, 0); + ResponseCompleted(0, nsnull, rv, 0); } return rv; } @@ -1097,7 +1099,7 @@ nsHTTPChannel::Open(void) } if (NS_FAILED(rv)) { // Unable to create a transport... End the request... - (void) ResponseCompleted(nsnull, rv, nsnull); + (void) ResponseCompleted(nsnull, mResponseDataListener, rv, nsnull); return rv; } @@ -1105,7 +1107,7 @@ nsHTTPChannel::Open(void) rv = transport->SetNotificationCallbacks(this); if (NS_FAILED(rv)) { // Unable to create a transport... End the request... - (void) ResponseCompleted(nsnull, rv, nsnull); + (void) ResponseCompleted(nsnull, mResponseDataListener, rv, nsnull); return rv; } @@ -1242,11 +1244,47 @@ nsresult nsHTTPChannel::Redirect(const char *aNewLocation, nsresult nsHTTPChannel::ResponseCompleted(nsIChannel* aTransport, + nsIStreamListener *aListener, nsresult aStatus, const PRUnichar* aMsg) { nsresult rv = NS_OK; + // + // First: + // + // Call the consumer OnStopRequest(...) to end the request... + if (aListener) { + rv = aListener->OnStopRequest(this, mResponseContext, aStatus, aMsg); + + if (NS_FAILED(rv)) { + PR_LOG(gHTTPLog, PR_LOG_ERROR, + ("nsHTTPChannel::OnStopRequest(...) [this=%x]." + "\tOnStopRequest to consumer failed! Status:%x\n", + this, rv)); + } + } + + // Release the transport... + if (aTransport) { + (void)mHandler->ReleaseTransport(aTransport); + } + + // + // After the consumer has been notified, remove the channel from its + // load group... This will trigger an OnStopRequest from the load group. + // + if (mLoadGroup) { + (void)mLoadGroup->RemoveChannel(this, nsnull, aStatus, nsnull); + } + + // + // Finally, notify the OpenObserver that the request has completed. + // + if (mOpenObserver) { + (void) mOpenObserver->OnStopRequest(this, mOpenContext, aStatus, aMsg); + } + // Null out pointers that are no longer needed... // rjc says: don't null out mResponseContext; @@ -1256,21 +1294,6 @@ nsresult nsHTTPChannel::ResponseCompleted(nsIChannel* aTransport, mResponseDataListener = 0; NS_IF_RELEASE(mCachedResponse); - // Release the transport... - if (aTransport) { - (void)mHandler->ReleaseTransport(aTransport); - } - - // Remove the channel from its load group... - if (mLoadGroup) { - (void)mLoadGroup->RemoveChannel(this, nsnull, aStatus, nsnull); - } - - if (mOpenObserver) { - rv = mOpenObserver->OnStopRequest(this, mOpenContext, aStatus, aMsg); - if (NS_FAILED(rv)) return rv; - } - return rv; } @@ -1294,6 +1317,28 @@ nsresult nsHTTPChannel::GetResponseContext(nsISupports** aContext) return NS_ERROR_NULL_POINTER; } + +nsresult nsHTTPChannel::Abort() +{ + // Disconnect the consumer from this response listener... + // This allows the entity that follows to be discarded + // without notifying the consumer... + if (mRawResponseListener) { + mRawResponseListener->Abort(); + } + + // Null out pointers that are no longer needed... + // + // This will prevent the OnStopRequest(...) notification from being fired + // for the original URL... + // + mResponseDataListener = 0; + mOpenObserver = 0; + + return NS_OK; +} + + nsresult nsHTTPChannel::OnHeadersAvailable() { nsresult rv = NS_OK; @@ -1582,8 +1627,9 @@ nsHTTPChannel::ProcessStatusCode(void) if ((statusCode == 200) || (statusCode == 203)) { nsCOMPtr listener2; CacheReceivedResponse(listener, getter_AddRefs(listener2)); - if (listener2) + if (listener2) { listener = listener2; + } } break; @@ -1607,8 +1653,9 @@ nsHTTPChannel::ProcessStatusCode(void) else if ((statusCode == 300) || (statusCode == 301)) { nsCOMPtr listener2; CacheReceivedResponse(listener, getter_AddRefs(listener2)); - if (listener2) + if (listener2) { listener = listener2; + } } rv = ProcessRedirection(statusCode); @@ -1645,9 +1692,12 @@ nsHTTPChannel::ProcessStatusCode(void) break; } - if (mRawResponseListener) + // If mResponseDataListener is null this means that the response has been + // aborted... So, do not update the response listener because this + // is being discarded... + if (mResponseDataListener && mRawResponseListener) { mRawResponseListener->SetResponseDataListener(listener); - + } return rv; } @@ -1656,8 +1706,11 @@ nsHTTPChannel::ProcessNotModifiedResponse(nsIStreamListener *aListener) { nsresult rv; NS_ASSERTION(!mCachedContentIsValid, "We should never have cached a 304 response"); - - mRawResponseListener->Abort(); + + // Abort the current response... This will disconnect the consumer from + // the response listener... Thus allowing the entity that follows to + // be discarded without notifying the consumer... + Abort(); // Fake it so that HTTP headers come from cached versions SetResponse(mCachedResponse); @@ -1684,13 +1737,12 @@ nsHTTPChannel::ProcessRedirection(PRInt32 aStatusCode) nsCOMPtr channel; rv = Redirect(location, getter_AddRefs(channel)); + if (NS_FAILED(rv)) return rv; - // Disconnect the consumer from this response listener... - // This allows the entity that follows to be discarded - // without notifying the consumer... - if (NS_SUCCEEDED(rv) && mRawResponseListener) { - mRawResponseListener->Abort(); - } + // Abort the current response... This will disconnect the consumer from + // the response listener... Thus allowing the entity that follows to + // be discarded without notifying the consumer... + Abort(); } return rv; } @@ -1719,19 +1771,10 @@ nsHTTPChannel::ProcessAuthentication(PRInt32 aStatusCode) if (NS_FAILED(rv = Authenticate(challenge, getter_AddRefs(channel)))) return rv; - // Disconnect the consumer from this response listener... - // This allows the entity that follows to be discarded - // without notifying the consumer... - if (mRawResponseListener) - mRawResponseListener->Abort(); - - // Null out pointers that are no longer needed... - // - // This will prevent the OnStopRequest(...) notification from being fired - // for the original URL... - // - mResponseDataListener = 0; - mOpenObserver = 0; + // Abort the current response... This will disconnect the consumer from + // the response listener... Thus allowing the entity that follows to + // be discarded without notifying the consumer... + Abort(); return rv; } diff --git a/mozilla/netwerk/protocol/http/src/nsHTTPChannel.h b/mozilla/netwerk/protocol/http/src/nsHTTPChannel.h index 4b345b18326..a4f4fd1cd66 100644 --- a/mozilla/netwerk/protocol/http/src/nsHTTPChannel.h +++ b/mozilla/netwerk/protocol/http/src/nsHTTPChannel.h @@ -86,9 +86,12 @@ public: nsresult Open(); nsresult Redirect(const char *aURL, nsIChannel **aResult); + nsresult ResponseCompleted(nsIChannel* aTransport, + nsIStreamListener* aListener, nsresult aStatus, const PRUnichar* aMsg); + nsresult SetResponse(nsHTTPResponse* i_pResp); nsresult GetResponseContext(nsISupports** aContext); nsresult CacheReceivedResponse(nsIStreamListener *aListener, @@ -101,6 +104,8 @@ public: nsresult FinishedResponseHeaders(); + nsresult Abort(); + protected: nsresult CheckCache(); nsresult ReadFromCache(PRUint32 aStartPosition, PRInt32 aReadCount); diff --git a/mozilla/netwerk/protocol/http/src/nsHTTPRequest.cpp b/mozilla/netwerk/protocol/http/src/nsHTTPRequest.cpp index 0139e577c09..14b0ead57a9 100644 --- a/mozilla/netwerk/protocol/http/src/nsHTTPRequest.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHTTPRequest.cpp @@ -498,7 +498,11 @@ nsHTTPRequest::OnStopRequest(nsIChannel* channel, nsISupports* i_Context, this, iStatus)); // Notify the HTTPChannel that the request has finished - mConnection->ResponseCompleted(mTransport, iStatus, i_Msg); + nsCOMPtr consumer; + + mConnection->GetResponseDataListener(getter_AddRefs(consumer)); + + mConnection->ResponseCompleted(mTransport, consumer, iStatus, i_Msg); mTransport = null_nsCOMPtr(); rv = iStatus; diff --git a/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.cpp b/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.cpp index f2b48ed874e..302431d74ee 100644 --- a/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.cpp @@ -59,7 +59,6 @@ static const int kMAX_HEADER_SIZE = 60000; nsHTTPResponseListener::nsHTTPResponseListener(nsHTTPChannel* aConnection): mFirstLineParsed(PR_FALSE), mHeadersDone(PR_FALSE), - mAborted(PR_FALSE), mResponse(nsnull), mBytesReceived(0) { @@ -178,7 +177,7 @@ nsHTTPResponseListener::OnDataAvailable(nsIChannel* channel, // Abort the connection if the consumer has been released. This will // happen if a redirect has been processed... // - if (mAborted) { + if (!mResponseDataListener) { // XXX: What should the return code be? rv = NS_BINDING_ABORTED; } @@ -247,23 +246,13 @@ nsHTTPResponseListener::OnStopRequest(nsIChannel* channel, // Notify the HTTPChannel that the response has completed... NS_ASSERTION(mChannel, "HTTPChannel is null."); if (mChannel) { - mChannel->ResponseCompleted(channel, i_Status, i_pMsg); + mChannel->ResponseCompleted(channel, mResponseDataListener, + i_Status, i_pMsg); + + // The HTTPChannel is no longer needed... + mChannel->mRawResponseListener = 0; } - // Call the consumer OnStopRequest(...) to end the request... - if (mResponseDataListener && !mAborted) { - rv = mResponseDataListener->OnStopRequest(mChannel, mChannel->mResponseContext, i_Status, i_pMsg); - - if (NS_FAILED(rv)) { - PR_LOG(gHTTPLog, PR_LOG_ERROR, - ("nsHTTPChannel::OnStopRequest(...) [this=%x]." - "\tOnStopRequest to consumer failed! Status:%x\n", - this, rv)); - } - } - - // The HTTPChannel is no longer needed... - mChannel->mRawResponseListener = 0; NS_IF_RELEASE(mChannel); NS_IF_RELEASE(mResponse); @@ -273,6 +262,21 @@ nsHTTPResponseListener::OnStopRequest(nsIChannel* channel, //////////////////////////////////////////////////////////////////////////////// // nsHTTPResponseListener methods: +nsresult nsHTTPResponseListener::Abort() +{ + PR_LOG(gHTTPLog, PR_LOG_ALWAYS, + ("nsHTTPResponseListener::Abort [this=%x].", this)); + + // + // Clearing the data consumer will cause the response to abort. This + // also prevents any more notifications from being passed out to the consumer. + // + mResponseDataListener = 0; + + return NS_OK; +} + + nsresult nsHTTPResponseListener::FireSingleOnData(nsIStreamListener *aListener, nsISupports *aContext) { nsresult rv; @@ -281,7 +285,7 @@ nsresult nsHTTPResponseListener::FireSingleOnData(nsIStreamListener *aListener, rv = FinishedResponseHeaders(); if (NS_FAILED(rv)) return rv; - if (mBytesReceived) { + if (mBytesReceived && mResponseDataListener) { rv = mResponseDataListener->OnDataAvailable(mChannel, mChannel->mResponseContext, mDataStream, 0, mBytesReceived); } @@ -499,7 +503,7 @@ nsresult nsHTTPResponseListener::FinishedResponseHeaders(void) // // Fire the OnStartRequest notification - now that user data is available // - if (NS_SUCCEEDED(rv) && mResponseDataListener && !mAborted) { + if (NS_SUCCEEDED(rv) && mResponseDataListener) { rv = mResponseDataListener->OnStartRequest(mChannel, mChannel->mResponseContext); if (NS_FAILED(rv)) { PR_LOG(gHTTPLog, PR_LOG_ERROR, diff --git a/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.h b/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.h index 0657e4b86e7..18e11eb0d75 100644 --- a/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.h +++ b/mozilla/netwerk/protocol/http/src/nsHTTPResponseListener.h @@ -63,7 +63,7 @@ public: NS_DECL_NSISTREAMLISTENER nsresult FireSingleOnData(nsIStreamListener *aListener, nsISupports *aContext); - void Abort() { mAborted = PR_TRUE; } + nsresult Abort(); void SetResponseDataListener(nsIStreamListener *aListener) { mResponseDataListener = aListener; } @@ -86,7 +86,6 @@ protected: nsHTTPResponse* mResponse; PRBool mFirstLineParsed; PRBool mHeadersDone; - PRBool mAborted; nsCOMPtr mDataStream; PRUint32 mBytesReceived;