Bug 802895 - add srcdoc support to (InputStream|ViewSource)Channels r=bz sr=bsmedberg

This commit is contained in:
James Kitchener 2013-06-28 23:04:42 -04:00
parent 100e9fea68
commit 9017174a43
8 changed files with 177 additions and 2 deletions

View File

@ -12,7 +12,7 @@ interface nsIInputStream;
* This interface provides methods to initialize an input stream channel.
* The input stream channel serves as a data pump for an input stream.
*/
[scriptable, uuid(274c4d7a-2447-4ceb-a6de-80db1b83f5d2)]
[scriptable, uuid(A30E916F-B1DE-452A-BDD0-C59BB516D427)]
interface nsIInputStreamChannel : nsISupports
{
/**
@ -36,4 +36,23 @@ interface nsIInputStreamChannel : nsISupports
* has been opened.
*/
attribute nsIInputStream contentStream;
/**
* Get/set the srcdoc data string. When the input stream channel is
* created to load a srcdoc iframe, this is set to hold the value of the
* srcdoc attribute.
*
* This should be the same value used to create contentStream, but this is
* not checked.
*
* Changing the value of this attribute will not otherwise affect the
* functionality of the channel or input stream.
*/
attribute AString srcdocData;
/**
* Returns true if srcdocData has been set within the channel.
*/
readonly attribute boolean isSrcdocChannel;
};

View File

@ -81,11 +81,14 @@
#include "nsIOfflineCacheUpdate.h"
#include "nsIContentSniffer.h"
#include "nsCategoryCache.h"
#include "nsStringStream.h"
#include <limits>
#ifdef MOZILLA_INTERNAL_API
#include "nsReadableUtils.h"
inline already_AddRefed<nsIIOService>
do_GetIOService(nsresult* error = 0)
{
@ -462,6 +465,47 @@ NS_NewInputStreamChannel(nsIChannel **result,
&contentCharset);
}
inline nsresult
NS_NewInputStreamChannel(nsIChannel **result,
nsIURI *uri,
const nsAString &data,
const nsACString &contentType,
bool isSrcdocChannel = false)
{
nsresult rv;
nsCOMPtr<nsIStringInputStream> stream;
stream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef MOZILLA_INTERNAL_API
uint32_t len;
char* utf8Bytes = ToNewUTF8String(data, &len);
rv = stream->AdoptData(utf8Bytes, len);
#else
char* utf8Bytes = ToNewUTF8String(data);
rv = stream->AdoptData(utf8Bytes, strlen(utf8Bytes));
#endif
nsCOMPtr<nsIChannel> chan;
rv = NS_NewInputStreamChannel(getter_AddRefs(chan), uri, stream,
contentType, NS_LITERAL_CSTRING("UTF-8"));
NS_ENSURE_SUCCESS(rv, rv);
if (isSrcdocChannel) {
nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(chan);
NS_ENSURE_TRUE(inStrmChan, NS_ERROR_FAILURE);
inStrmChan->SetSrcdocData(data);
}
*result = nullptr;
chan.swap(*result);
return NS_OK;
}
inline nsresult
NS_NewInputStreamPump(nsIInputStreamPump **result,
nsIInputStream *stream,

View File

@ -67,3 +67,26 @@ nsInputStreamChannel::SetContentStream(nsIInputStream *stream)
mContentStream = stream;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetSrcdocData(nsAString& aSrcdocData)
{
aSrcdocData = mSrcdocData;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::SetSrcdocData(const nsAString& aSrcdocData)
{
mSrcdocData = aSrcdocData;
mIsSrcdocChannel = true;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamChannel::GetIsSrcdocChannel(bool *aIsSrcdocChannel)
{
*aIsSrcdocChannel = mIsSrcdocChannel;
return NS_OK;
}

View File

@ -18,7 +18,8 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINPUTSTREAMCHANNEL
nsInputStreamChannel() {}
nsInputStreamChannel() :
mIsSrcdocChannel(false) {}
protected:
virtual ~nsInputStreamChannel() {}
@ -28,6 +29,8 @@ protected:
private:
nsCOMPtr<nsIInputStream> mContentStream;
nsString mSrcdocData;
bool mIsSrcdocChannel;
};
#endif // !nsInputStreamChannel_h__

View File

@ -14,6 +14,7 @@
#include "nsMimeTypes.h"
#include "nsNetUtil.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsStringStream.h"
NS_IMPL_ADDREF(nsViewSourceChannel)
NS_IMPL_RELEASE(nsViewSourceChannel)
@ -73,6 +74,36 @@ nsViewSourceChannel::Init(nsIURI* uri)
return NS_OK;
}
nsresult
nsViewSourceChannel::InitSrcdoc(nsIURI* aURI, const nsAString &aSrcdoc)
{
nsresult rv;
nsCOMPtr<nsIURI> inStreamURI;
// Need to strip view-source: from the URI. Hardcoded to
// about:srcdoc as this is the only permissible URI for srcdoc
// loads
rv = NS_NewURI(getter_AddRefs(inStreamURI),
NS_LITERAL_STRING("about:srcdoc"));
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewInputStreamChannel(getter_AddRefs(mChannel), inStreamURI,
aSrcdoc, NS_LITERAL_CSTRING("text/html"),
true);
NS_ENSURE_SUCCESS(rv, rv);
mOriginalURI = aURI;
mChannel->SetOriginalURI(mOriginalURI);
mHttpChannel = do_QueryInterface(mChannel);
mHttpChannelInternal = do_QueryInterface(mChannel);
mCachingChannel = do_QueryInterface(mChannel);
mApplicationCacheChannel = do_QueryInterface(mChannel);
mUploadChannel = do_QueryInterface(mChannel);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:

View File

@ -52,6 +52,8 @@ public:
NS_HIDDEN_(nsresult) Init(nsIURI* uri);
NS_HIDDEN_(nsresult) InitSrcdoc(nsIURI* aURI, const nsAString &aSrcdoc);
protected:
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIHttpChannel> mHttpChannel;

View File

@ -108,6 +108,26 @@ nsViewSourceHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
return NS_OK;
}
nsresult
nsViewSourceHandler::NewSrcdocChannel(nsIURI* uri, const nsAString &srcdoc,
nsIChannel* *result)
{
NS_ENSURE_ARG_POINTER(uri);
nsViewSourceChannel *channel = new nsViewSourceChannel();
if (!channel)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(channel);
nsresult rv = channel->InitSrcdoc(uri, srcdoc);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;
}
*result = static_cast<nsIViewSourceChannel*>(channel);
return NS_OK;
}
NS_IMETHODIMP
nsViewSourceHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
{
@ -115,3 +135,21 @@ nsViewSourceHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
*_retval = false;
return NS_OK;
}
nsViewSourceHandler::nsViewSourceHandler()
{
gInstance = this;
}
nsViewSourceHandler::~nsViewSourceHandler()
{
gInstance = nullptr;
}
nsViewSourceHandler* nsViewSourceHandler::gInstance = nullptr;
nsViewSourceHandler*
nsViewSourceHandler::GetInstance()
{
return gInstance;
}

View File

@ -14,6 +14,21 @@ class nsViewSourceHandler MOZ_FINAL : public nsIProtocolHandler
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
nsViewSourceHandler();
~nsViewSourceHandler();
// Creates a new nsViewSourceChannel to view the source of an about:srcdoc
// URI with contents specified by srcdoc.
nsresult NewSrcdocChannel(nsIURI* uri, const nsAString &srcdoc,
nsIChannel** result);
static nsViewSourceHandler* GetInstance();
private:
static nsViewSourceHandler* gInstance;
};
#endif /* !defined( nsViewSourceHandler_h___ ) */