@@ -171,7 +172,7 @@
This way, if a proxy is destroyed without calling cancel on it, it won't leak
and won't leave a bad pointer in mObservers.
*/
- if (mRequest && mLoading && NS_FAILED(aStatus)) {
+ if (mChannel && mRequest && mLoading && NS_FAILED(aStatus)) { LOG_MSG(gImgLog, "imgRequest::RemoveProxy", "load in progress. canceling");
NS_ASSERTION(!mDecoder, "imgRequest::OnStartRequest -- we already have a decoder");
+ /* if mChannel isn't set here, use aRequest.
+ *
+ * Having mChannel set is important for Canceling the load, and
+ * since we set mChannel to null in OnStopRequest. Since with
+ * multipart/x-mixed-replace, you can get multiple OnStartRequests,
+ * we need to reinstance mChannel so that when/if Cancel() gets
+ * called, we have a channel to cancel and we don't leave the
+ * channel open forever.
+ */
nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));
+
+ if (!mChannel) {
+ if (mpchan)
+ mpchan->GetBaseChannel(getter_AddRefs(mChannel));
+ else
+ mChannel = do_QueryInterface(aRequest);
+ }
+
if (mpchan) mIsMultiPartChannel = PR_TRUE;
@@ -674,6 +694,8 @@
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
if (mObservers.IsEmpty()) {
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
+ // Shut down the channel explictly.
+ mChannel->Cancel(NS_IMAGELIB_ERROR_FAILURE);
}
return NS_OK;
@@ -711,6 +733,10 @@
mRequest = nsnull; // we no longer need the request
}
+ if (mChannel) {
+ mChannel = nsnull; // we no longer need the channel
+ }
+
// If mImage is still null, we didn't properly load the image.
if (NS_FAILED(status) || !mImage) {
this->Cancel(status); // sets status, stops animations, removes from cache
(In reply to comment #54)
> Post a diff?
Oh. Sorry. Sure. To apply, cut and paste this text to a file called, say, "mjpeg.patch" and cd to mozilla/ modules/ libpr0n/ src, then
% patch < mjpeg.patch
--- imgRequest.h-orig 2008-09-15 14:25:41.000000000 +0200 escriptor. h" fer.h" ner.h" NSIREQUESTOBSER VER
+++ imgRequest.h 2008-09-15 14:26:13.000000000 +0200
@@ -49,6 +49,7 @@
#include "nsICacheEntryD
#include "nsIContentSnif
#include "nsIRequest.h"
+#include "nsIChannel.h"
#include "nsIProperties.h"
#include "nsIStreamListe
#include "nsIURI.h"
@@ -151,6 +152,7 @@
NS_DECL_
private: nsIChannel> mChannel; nsIRequest> mRequest; nsIPrincipal> mPrincipal; OUT_OF_ MEMORY;
+ nsCOMPtr<
nsCOMPtr<
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<
--- imgRequest.cpp-orig 2008-09-15 14:25:49.000000000 +0200
+++ imgRequest.cpp 2008-09-15 14:26:16.000000000 +0200
@@ -106,6 +106,7 @@
if (!mProperties)
return NS_ERROR_
+ mChannel = do_QueryInterfa ce(aRequest) ;
mURI = aURI;
mRequest = aRequest;
@@ -171,7 +172,7 @@
LOG_MSG( gImgLog, "imgRequest: :RemoveProxy" , "load in progress. canceling");
This way, if a proxy is destroyed without calling cancel on it, it won't leak
and won't leave a bad pointer in mObservers.
*/
- if (mRequest && mLoading && NS_FAILED(aStatus)) {
+ if (mChannel && mRequest && mLoading && NS_FAILED(aStatus)) {
mImageStatus |= imgIRequest: :STATUS_ LOAD_PARTIAL; Cache() ;
@@ -292,14 +293,16 @@
RemoveFrom
}
- if (mRequest && mLoading) >Cancel( aStatus) ; >Cancel( aStatus) ;
+ if (mChannel && mRequest && mLoading) {
+ /* Cancel both channel and request. */
mRequest-
+ mChannel-
+ }
}
nsresult imgRequest: :GetURI( nsIURI **aURI) FUNC(gImgLog, "imgRequest: :GetURI" ); ADDREF( *aURI);
{
LOG_
-
if (mURI) {
*aURI = mURI;
NS_
@@ -587,7 +590,24 @@
NS_ASSERTION (!mDecoder, "imgRequest: :OnStartRequest -- we already have a decoder");
+ /* if mChannel isn't set here, use aRequest. x-mixed- replace, you can get multiple OnStartRequests, nsIMultiPartCha nnel> mpchan( do_QueryInterfa ce(aRequest) ); >GetBaseChannel (getter_ AddRefs( mChannel) ); ce(aRequest) ;
mIsMultiPartCha nnel = PR_TRUE;
+ *
+ * Having mChannel set is important for Canceling the load, and
+ * since we set mChannel to null in OnStopRequest. Since with
+ * multipart/
+ * we need to reinstance mChannel so that when/if Cancel() gets
+ * called, we have a channel to cancel and we don't leave the
+ * channel open forever.
+ */
nsCOMPtr<
+
+ if (!mChannel) {
+ if (mpchan)
+ mpchan-
+ else
+ mChannel = do_QueryInterfa
+ }
+
if (mpchan)
@@ -674,6 +694,8 @@ x-mixed- replace. .. IsEmpty( )) { >Cancel( NS_IMAGELIB_ ERROR_FAILURE) ; >Cancel( NS_IMAGELIB_ ERROR_FAILURE) ;
// Shouldn't we be dead already if this gets hit? Probably multipart/
if (mObservers.
this-
+ // Shut down the channel explictly.
+ mChannel-
}
return NS_OK;
@@ -711,6 +733,10 @@
mRequest = nsnull; // we no longer need the request
}
+ if (mChannel) { >Cancel( status) ; // sets status, stops animations, removes from cache
+ mChannel = nsnull; // we no longer need the channel
+ }
+
// If mImage is still null, we didn't properly load the image.
if (NS_FAILED(status) || !mImage) {
this-