diff --git a/htmlparser/src/nsViewSourceHTML.cpp b/htmlparser/src/nsViewSourceHTML.cpp
index 9212e8d1040..936cdb4532d 100644
--- a/htmlparser/src/nsViewSourceHTML.cpp
+++ b/htmlparser/src/nsViewSourceHTML.cpp
@@ -467,7 +467,11 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
if((!aParserContext.mPrevContext) && (mSink)) {
- mFilename=aParserContext.mScanner->GetFilename();
+ nsAString & contextFilename = aParserContext.mScanner->GetFilename();
+ mFilename = Substring(contextFilename,
+ 12, // The length of "view-source:"
+ contextFilename.Length() - 12);
+
mTags.Truncate();
mErrors.Assign(NS_LITERAL_STRING(" HTML 4.0 Strict-DTD validation (enabled); [Should use Transitional?].\n"));
diff --git a/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp
index 1492e8a4d09..94d72002f5b 100644
--- a/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp
@@ -32,7 +32,7 @@
#include "nsNetUtil.h"
// nsViewSourceChannel methods
-nsViewSourceChannel::nsViewSourceChannel()
+nsViewSourceChannel::nsViewSourceChannel() : mIsDocument(PR_FALSE)
{
NS_INIT_REFCNT();
}
@@ -173,7 +173,17 @@ nsViewSourceChannel::GetURI(nsIURI* *aURI)
{
NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
- return mChannel->GetURI(aURI);
+ nsCOMPtr uri;
+ nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCAutoString spec;
+ uri->GetSpec(spec);
+
+ /* XXX Gross hack -- NS_NewURI goes into an infinite loop on
+ non-flat specs. See bug 136980 */
+ return NS_NewURI(aURI, nsCAutoString(NS_LITERAL_CSTRING("view-source:")+spec), nsnull);
}
NS_IMETHODIMP
@@ -191,15 +201,57 @@ nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
mListener = aListener;
- return mChannel->AsyncOpen(this, ctxt);
+ /*
+ * We want to add ourselves to the loadgroup before opening
+ * mChannel, since we want to make sure we're in the loadgroup
+ * when mChannel finishes and fires OnStopRequest()
+ */
+
+ nsCOMPtr loadGroup;
+ mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
+ if (loadGroup)
+ loadGroup->AddRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
+ this), nsnull);
+
+ nsresult rv = mChannel->AsyncOpen(this, ctxt);
+
+ if (NS_FAILED(rv) && loadGroup)
+ loadGroup->RemoveRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
+ this),
+ nsnull, rv);
+
+ return rv;
}
+/*
+ * Both the view source channel and mChannel are added to the
+ * loadgroup. There should never be more than one request in the
+ * loadgroup that has LOAD_DOCUMENT_URI set. The one that has this
+ * flag set is the request whose URI is used to refetch the document,
+ * so it better be the viewsource channel.
+ *
+ * Therefore, we need to make sure that
+ * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI
+ * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was
+ * set via SetLoadFlags (mIsDocument keeps track of this flag).
+ */
+
NS_IMETHODIMP
nsViewSourceChannel::GetLoadFlags(PRUint32 *aLoadFlags)
{
NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
- return mChannel->GetLoadFlags(aLoadFlags);
+ nsresult rv = mChannel->GetLoadFlags(aLoadFlags);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler
+ // fails to deal due to amiguous inheritance. nsIChannel::LOAD_DOCUMENT_URI
+ // also fails; the Win32 compiler thinks that's supposed to be a method.
+ if (mIsDocument)
+ *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI;
+
+ return rv;
}
NS_IMETHODIMP
@@ -207,11 +259,19 @@ nsViewSourceChannel::SetLoadFlags(PRUint32 aLoadFlags)
{
NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
- // "View source" always wants the currently cached content.
+ // "View source" always wants the currently cached content.
+ // We also want to have _this_ channel, not mChannel to be the
+ // 'document' channel in the loadgroup.
- // This should actually be just nsIRequest::LOAD_FROM_CACHE but
- // the win32 compiler fails to deal... tries to do a method lookup
- return mChannel->SetLoadFlags(aLoadFlags | ::nsIRequest::LOAD_FROM_CACHE);
+ // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but
+ // the win32 compiler fails to deal due to amiguous inheritance.
+ // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the
+ // Win32 compiler thinks that's supposed to be a method.
+ mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) ? PR_TRUE : PR_FALSE;
+
+ return mChannel->SetLoadFlags((aLoadFlags |
+ ::nsIRequest::LOAD_FROM_CACHE) &
+ ~::nsIChannel::LOAD_DOCUMENT_URI);
}
#define X_VIEW_SOURCE_PARAM "; x-view-type=view-source"
@@ -393,6 +453,17 @@ nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
nsresult aStatus)
{
NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
+ if (mChannel)
+ {
+ nsCOMPtr loadGroup;
+ mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
+ if (loadGroup)
+ {
+ loadGroup->RemoveRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
+ this),
+ nsnull, aStatus);
+ }
+ }
return mListener->OnStopRequest(NS_STATIC_CAST(nsIViewSourceChannel*,
this),
aContext, aStatus);
diff --git a/netwerk/protocol/viewsource/src/nsViewSourceChannel.h b/netwerk/protocol/viewsource/src/nsViewSourceChannel.h
index a8164b569c9..1d6d250b534 100644
--- a/netwerk/protocol/viewsource/src/nsViewSourceChannel.h
+++ b/netwerk/protocol/viewsource/src/nsViewSourceChannel.h
@@ -86,6 +86,7 @@ protected:
nsCOMPtr mUploadChannel;
nsCOMPtr mListener;
nsCString mContentType;
+ PRBool mIsDocument; // keeps track of the LOAD_DOCUMENT_URI flag
};
#endif /* nsViewSourceChannel_h___ */
diff --git a/parser/htmlparser/src/nsViewSourceHTML.cpp b/parser/htmlparser/src/nsViewSourceHTML.cpp
index 9212e8d1040..936cdb4532d 100644
--- a/parser/htmlparser/src/nsViewSourceHTML.cpp
+++ b/parser/htmlparser/src/nsViewSourceHTML.cpp
@@ -467,7 +467,11 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
if((!aParserContext.mPrevContext) && (mSink)) {
- mFilename=aParserContext.mScanner->GetFilename();
+ nsAString & contextFilename = aParserContext.mScanner->GetFilename();
+ mFilename = Substring(contextFilename,
+ 12, // The length of "view-source:"
+ contextFilename.Length() - 12);
+
mTags.Truncate();
mErrors.Assign(NS_LITERAL_STRING(" HTML 4.0 Strict-DTD validation (enabled); [Should use Transitional?].\n"));