diff --git a/extensions/datetime/nsDateTimeChannel.cpp b/extensions/datetime/nsDateTimeChannel.cpp
index bc927138a43a..d6ab81ea0f26 100644
--- a/extensions/datetime/nsDateTimeChannel.cpp
+++ b/extensions/datetime/nsDateTimeChannel.cpp
@@ -403,7 +403,7 @@ nsDateTimeChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
// suppress status notification if channel is no longer pending!
- if (mProgressSink && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
+ if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUCS2 host(mHost);
mProgressSink->OnStatus(this, nsnull, status, host.get());
diff --git a/extensions/finger/nsFingerChannel.cpp b/extensions/finger/nsFingerChannel.cpp
index 40e3e1320585..42c852a4bd82 100644
--- a/extensions/finger/nsFingerChannel.cpp
+++ b/extensions/finger/nsFingerChannel.cpp
@@ -425,7 +425,7 @@ nsFingerChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
// suppress status notification if channel is no longer pending!
- if (mProgressSink && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
+ if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUCS2 host(mHost);
mProgressSink->OnStatus(this, nsnull, status, host.get());
diff --git a/mailnews/imap/src/nsImapProtocol.cpp b/mailnews/imap/src/nsImapProtocol.cpp
index ce0ee47f2cb1..c96877ae6d3f 100644
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -8266,7 +8266,7 @@ NS_IMETHODIMP
nsImapMockChannel::OnTransportStatus(nsITransport *transport, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
- if (mProgressEventSink && !(mLoadFlags & LOAD_BACKGROUND))
+ if (mProgressEventSink && NS_SUCCEEDED(m_cancelStatus) && !(mLoadFlags & LOAD_BACKGROUND))
{
// these transport events should not generate any status messages
if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
diff --git a/netwerk/base/public/nsIProgressEventSink.idl b/netwerk/base/public/nsIProgressEventSink.idl
index c372fa687c5f..8952866f32bc 100644
--- a/netwerk/base/public/nsIProgressEventSink.idl
+++ b/netwerk/base/public/nsIProgressEventSink.idl
@@ -41,35 +41,74 @@ interface nsIURI;
interface nsIRequest;
/**
- * An instance of nsIFfpEventSink should be passed as the eventSink
- * argument of nsINetService::NewConnection for ftp URLs. It defines
- * the callbacks to the application program (the html parser).
+ * nsIProgressEventSink
+ *
+ * This interface is used to asynchronously convey channel status and progress
+ * information that is generally not critical to the processing of the channel.
+ * The information is intended to be displayed to the user in some meaningful
+ * way.
+ *
+ * An implementation of this interface can be passed to a channel via the
+ * channel's notificationCallbacks attribute. See nsIChannel for more info.
+ *
+ * The channel will begin passing notifications to the progress event sink
+ * after its asyncOpen method has been called. Notifications will cease once
+ * the channel calls its listener's onStopRequest method or once the channel
+ * is canceled (via nsIRequest::cancel).
+ *
+ * NOTE: This interface is actually not specific to channels and may be used
+ * with other implementations of nsIRequest.
+ *
+ * @status UNDER_REVIEW
*/
[scriptable, uuid(dd47ee00-18c2-11d3-9337-00104ba0fd40)]
interface nsIProgressEventSink : nsISupports
{
/**
- * Notify the EventSink that progress has occurred for the URL load.
+ * Called to notify the event sink that progress has occurred for the
+ * given request.
+ *
+ * @param aRequest
+ * the request being observed (may QI to nsIChannel).
+ * @param aContext
+ * if aRequest is a channel, then this parameter is the listener
+ * context passed to nsIChannel::asyncOpen.
+ * @param aProgress
+ * numeric value in the range 0 to aProgressMax indicating the
+ * number of bytes transfered thus far.
+ * @param aProgressMax
+ * numeric value indicating maximum number of bytes that will be
+ * transfered (or 0xFFFFFFFF if total is unknown).
*/
- void onProgress(in nsIRequest request,
- in nsISupports ctxt,
+ void onProgress(in nsIRequest aRequest,
+ in nsISupports aContext,
in unsigned long aProgress,
in unsigned long aProgressMax);
/**
- * Notify the EventSink with a status message for the URL load.
- * @param status - A status code denoting the type of notification. This
- * can be a message to be displayed (e.g. for file I/O,
- * STATUS_READ_FROM, or STATUS_WROTE_TO), or can be an event
- * to be programmatically handled.
- * @param statusArg - An argument or arguments to the status notification.
- * These arguments will be formatted into any status or error
- * message. Multiple arguments can be passed by delimiting them
- * with newline ('\n') characters.
+ * Called to notify the event sink with a status message for the given
+ * request.
+ *
+ * @param aRequest
+ * the request being observed (may QI to nsIChannel).
+ * @param aContext
+ * if aRequest is a channel, then this parameter is the listener
+ * context passed to nsIChannel::asyncOpen.
+ * @param aStatus
+ * status code (not necessarily an error code) indicating the
+ * state of the channel (usually the state of the underlying
+ * transport). see nsISocketTransport for socket specific status
+ * codes.
+ * @param aStatusArg
+ * status code argument to be used with the string bundle service
+ * to convert the status message into localized, human readable
+ * text. the meaning of this parameter is specific to the value
+ * of the status code. for socket status codes, this parameter
+ * indicates the host:port associated with the status code.
*/
- void onStatus(in nsIRequest request,
- in nsISupports ctxt,
- in nsresult status,
- in wstring statusArg);
+ void onStatus(in nsIRequest aRequest,
+ in nsISupports aContext,
+ in nsresult aStatus,
+ in wstring aStatusArg);
};
diff --git a/netwerk/protocol/file/src/nsFileChannel.cpp b/netwerk/protocol/file/src/nsFileChannel.cpp
index a22b52acaf64..6c7b2523443c 100644
--- a/netwerk/protocol/file/src/nsFileChannel.cpp
+++ b/netwerk/protocol/file/src/nsFileChannel.cpp
@@ -165,6 +165,7 @@ NS_IMETHODIMP
nsFileChannel::Cancel(nsresult status)
{
NS_ENSURE_TRUE(mRequest, NS_ERROR_UNEXPECTED);
+ mStatus = status;
return mRequest->Cancel(status);
}
@@ -596,7 +597,7 @@ nsFileChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
// suppress status notification if channel is no longer pending!
- if (mProgressSink && mRequest && !(mLoadFlags & LOAD_BACKGROUND)) {
+ if (mProgressSink && NS_SUCCEEDED(mStatus) && mRequest && !(mLoadFlags & LOAD_BACKGROUND)) {
// file channel does not send OnStatus events!
if (status == nsITransport::STATUS_READING ||
status == nsITransport::STATUS_WRITING) {
diff --git a/netwerk/protocol/ftp/src/nsFTPChannel.cpp b/netwerk/protocol/ftp/src/nsFTPChannel.cpp
index 2eecb51a6dbe..201c2dcf328d 100644
--- a/netwerk/protocol/ftp/src/nsFTPChannel.cpp
+++ b/netwerk/protocol/ftp/src/nsFTPChannel.cpp
@@ -581,7 +581,7 @@ nsFTPChannel::OnStatus(nsIRequest *request, nsISupports *aContext,
NS_ERROR("ftp state is null.");
}
- if (!mEventSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending)
+ if (!mEventSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending || NS_FAILED(mStatus))
return NS_OK;
return mEventSink->OnStatus(this, mUserContext, aStatus,
diff --git a/netwerk/protocol/gopher/src/nsGopherChannel.cpp b/netwerk/protocol/gopher/src/nsGopherChannel.cpp
index c2829c4ee0c1..073767bf83fb 100644
--- a/netwerk/protocol/gopher/src/nsGopherChannel.cpp
+++ b/netwerk/protocol/gopher/src/nsGopherChannel.cpp
@@ -783,7 +783,7 @@ nsGopherChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
// suppress status notification if channel is no longer pending!
- if (mProgressSink && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
+ if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUCS2 host(mHost);
mProgressSink->OnStatus(this, nsnull, status, host.get());
diff --git a/netwerk/protocol/http/src/nsHttpChannel.cpp b/netwerk/protocol/http/src/nsHttpChannel.cpp
index e002e15a290b..906abbe3f8c0 100644
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -3188,8 +3188,8 @@ NS_IMETHODIMP
nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint32 progress, PRUint32 progressMax)
{
- // block socket status event after OnStopRequest has been fired.
- if (mProgressSink && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) {
+ // block socket status event after Cancel or OnStopRequest has been called.
+ if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) {
LOG(("sending status notification [this=%x status=%x progress=%u/%u]\n",
this, status, progress, progressMax));