mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-11 14:28:42 +00:00
Bug 767633 - Part 2 - nsObjectLoadingContent should handle all initial streams for plugins. r=josh
This commit is contained in:
parent
0c05d17225
commit
84f92e6c9e
@ -532,6 +532,35 @@ IsPluginEnabledForType(const nsCString& aMIMEType)
|
||||
/// Member Functions
|
||||
///
|
||||
|
||||
// Tedious syntax to create a plugin stream listener with checks and put it in
|
||||
// mFinalListener
|
||||
bool
|
||||
nsObjectLoadingContent::MakePluginListener()
|
||||
{
|
||||
if (!mInstanceOwner) {
|
||||
NS_NOTREACHED("expecting a spawned plugin");
|
||||
return false;
|
||||
}
|
||||
nsRefPtr<nsPluginHost> pluginHost =
|
||||
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
|
||||
if (!pluginHost) {
|
||||
NS_NOTREACHED("No pluginHost");
|
||||
return false;
|
||||
}
|
||||
NS_ASSERTION(!mFinalListener, "overwriting a final listener");
|
||||
nsresult rv;
|
||||
nsRefPtr<nsNPAPIPluginInstance> inst;
|
||||
nsCOMPtr<nsIStreamListener> finalListener;
|
||||
rv = mInstanceOwner->GetInstance(getter_AddRefs(inst));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
rv = pluginHost->NewEmbeddedPluginStreamListener(mURI, inst,
|
||||
getter_AddRefs(finalListener));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
mFinalListener = finalListener;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::IsSupportedDocument(const nsCString& aMimeType)
|
||||
{
|
||||
@ -656,12 +685,18 @@ nsObjectLoadingContent::~nsObjectLoadingContent()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsObjectLoadingContent::InstantiatePluginInstance()
|
||||
nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
|
||||
{
|
||||
if (mInstanceOwner || mType != eType_Plugin || mIsLoading || mInstantiating) {
|
||||
if (mInstanceOwner || mType != eType_Plugin || (mIsLoading != aIsLoading) ||
|
||||
mInstantiating) {
|
||||
// If we hit this assertion it's probably because LoadObject re-entered :(
|
||||
//
|
||||
// XXX(johns): This hackiness will go away in bug 767635
|
||||
NS_ASSERTION(mIsLoading || !aIsLoading,
|
||||
"aIsLoading should only be true inside LoadObject");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
mInstantiating = true;
|
||||
AutoSetInstantiatingToFalse autoInstantiating(this);
|
||||
|
||||
@ -763,6 +798,19 @@ nsObjectLoadingContent::InstantiatePluginInstance()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a URI but didn't open a channel yet (eAllowPluginSkipChannel)
|
||||
// or we did load with a channel but are re-instantiating, re-open the
|
||||
// channel. OpenChannel() performs security checks, and this plugin has
|
||||
// already passed content policy in LoadObject.
|
||||
if ((mURI && !mChannelLoaded) || (mChannelLoaded && !aIsLoading)) {
|
||||
NS_ASSERTION(!mChannel, "should not have an existing channel here");
|
||||
if (MakePluginListener()) {
|
||||
// We intentionally ignore errors here, leaving it up to the plugin to
|
||||
// deal with not having an initial stream.
|
||||
OpenChannel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -788,9 +836,6 @@ NS_IMETHODIMP
|
||||
nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
/// This must call LoadObject, even upon failure, to allow it to either
|
||||
/// proceed with the load, or trigger fallback content.
|
||||
|
||||
SAMPLE_LABEL("nsObjectLoadingContent", "OnStartRequest");
|
||||
|
||||
LOG(("OBJLC [%p]: Channel OnStartRequest", this));
|
||||
@ -801,6 +846,22 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mChannelLoaded, "mChannelLoaded set already?");
|
||||
// If we already switched to type plugin, this channel can just be passed to
|
||||
// the final listener.
|
||||
if (mType == eType_Plugin) {
|
||||
if (!mInstanceOwner || !mFinalListener) {
|
||||
// We drop mChannel when stopping plugins, so something is wrong
|
||||
NS_NOTREACHED("Opened a channel in plugin mode, but don't have a plugin");
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
return mFinalListener->OnStartRequest(aRequest, nullptr);
|
||||
}
|
||||
|
||||
// Otherwise we should be state loading, and call LoadObject with the channel
|
||||
if (mType != eType_Loading) {
|
||||
NS_NOTREACHED("Should be type loading at this point");
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
NS_ASSERTION(!mFinalListener, "mFinalListener exists already?");
|
||||
|
||||
mChannelLoaded = true;
|
||||
@ -1626,20 +1687,15 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
|
||||
if (mType != eType_Null) {
|
||||
int16_t contentPolicy = nsIContentPolicy::ACCEPT;
|
||||
bool allowLoad = false;
|
||||
// We check load policy before opening a channel, and process policy before
|
||||
// going ahead with any final-type load
|
||||
if (mType == eType_Loading) {
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
if (!secMan) {
|
||||
NS_NOTREACHED("No security manager?");
|
||||
} else {
|
||||
rv = secMan->CheckLoadURIWithPrincipal(thisContent->NodePrincipal(),
|
||||
mURI, 0);
|
||||
allowLoad = NS_SUCCEEDED(rv) && CheckLoadPolicy(&contentPolicy);
|
||||
}
|
||||
} else {
|
||||
bool allowLoad = true;
|
||||
// If mChannelLoaded is set we presumably already passed load policy
|
||||
if (mURI && !mChannelLoaded) {
|
||||
allowLoad = CheckLoadPolicy(&contentPolicy);
|
||||
}
|
||||
// If we're loading a type now, check ProcessPolicy. Note that we may check
|
||||
// both now in the case of plugins whose type is determined before opening a
|
||||
// channel.
|
||||
if (allowLoad && mType != eType_Loading) {
|
||||
allowLoad = CheckProcessPolicy(&contentPolicy);
|
||||
}
|
||||
|
||||
@ -1715,6 +1771,9 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
// We don't set mFinalListener until OnStartRequest has been called, to
|
||||
// prevent re-entry ugliness with CloseChannel()
|
||||
nsCOMPtr<nsIStreamListener> finalListener;
|
||||
// If we decide to synchronously spawn a plugin, we do it after firing
|
||||
// notifications to avoid re-entry causing notifications to fire out of order.
|
||||
bool doSpawnPlugin = false;
|
||||
switch (mType) {
|
||||
case eType_Image:
|
||||
if (!mChannel) {
|
||||
@ -1730,14 +1789,6 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
case eType_Plugin:
|
||||
{
|
||||
if (mChannel) {
|
||||
nsRefPtr<nsPluginHost> pluginHost =
|
||||
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
|
||||
if (!pluginHost) {
|
||||
NS_NOTREACHED("No pluginHost");
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
// Force a sync state change now, we need the frame created
|
||||
NotifyStateChanged(oldType, oldState, true, aNotify);
|
||||
oldType = mType;
|
||||
@ -1751,9 +1802,8 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
break;
|
||||
}
|
||||
|
||||
rv = pluginHost->NewEmbeddedPluginStreamListener(mURI, this, nullptr,
|
||||
getter_AddRefs(finalListener));
|
||||
// finalListener will receive OnStartRequest below
|
||||
// We'll handle this below
|
||||
doSpawnPlugin = true;
|
||||
} else {
|
||||
rv = AsyncStartPluginInstance();
|
||||
}
|
||||
@ -1848,7 +1898,8 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
CloseChannel();
|
||||
}
|
||||
|
||||
// Don't try to initialize final listener below
|
||||
// Don't try to initialize plugins or final listener below
|
||||
doSpawnPlugin = false;
|
||||
finalListener = nullptr;
|
||||
|
||||
// Don't notify, as LoadFallback doesn't know of our previous state
|
||||
@ -1858,41 +1909,48 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
|
||||
// Notify of our final state
|
||||
NotifyStateChanged(oldType, oldState, false, aNotify);
|
||||
NS_ENSURE_TRUE(mIsLoading, NS_OK);
|
||||
|
||||
|
||||
//
|
||||
// Pass load on to finalListener if loading with a channel.
|
||||
// Spawning plugins and dispatching to the final listener may re-enter, so are
|
||||
// delayed until after we fire a notification, to prevent missing
|
||||
// notifications or firing them out of order.
|
||||
//
|
||||
// We do this after finishing our notification such that re-entrance doesn't
|
||||
// skip notifications or fire them out of order.
|
||||
// Note that we ensured that we entered into LoadObject() from
|
||||
// ::OnStartRequest above when loading with a channel.
|
||||
//
|
||||
|
||||
if (!mIsLoading) {
|
||||
LOG(("OBJLC [%p]: Re-entered before dispatching to final listener", this));
|
||||
rv = NS_OK;
|
||||
if (doSpawnPlugin) {
|
||||
rv = InstantiatePluginInstance(true);
|
||||
NS_ENSURE_TRUE(mIsLoading, NS_OK);
|
||||
// Create the final listener if we're loading with a channel. We can't do
|
||||
// this in the loading block above as it requires an instance.
|
||||
if (aLoadingChannel && NS_SUCCEEDED(rv)) {
|
||||
// Plugins can continue to run even if their initial stream dies. Some
|
||||
// plugins will even return failure codes to reject the stream, but expect
|
||||
// to continue running, so ignore the error code. rv is thus the result of
|
||||
// spawning the plugin above
|
||||
if (NS_SUCCEEDED(rv) && MakePluginListener()) {
|
||||
mFinalListener->OnStartRequest(mChannel, nullptr);
|
||||
}
|
||||
}
|
||||
} else if (finalListener) {
|
||||
NS_ASSERTION(mType != eType_Null && mType != eType_Loading,
|
||||
"We should not have a final listener with a non-loaded type");
|
||||
// Note that we always enter into LoadObject() from ::OnStartRequest when
|
||||
// loading with a channel.
|
||||
mSrcStreamLoading = true;
|
||||
// Remove blocker on entering into instantiate
|
||||
// (this is otherwise unset by the stack class)
|
||||
mIsLoading = false;
|
||||
mFinalListener = finalListener;
|
||||
rv = finalListener->OnStartRequest(mChannel, nullptr);
|
||||
mSrcStreamLoading = false;
|
||||
if (NS_FAILED(rv)) {
|
||||
// Failed to load new content, but since we've already notified of our
|
||||
// transition, we can just Unload and call LoadFallback (which will notify
|
||||
// again)
|
||||
mType = eType_Null;
|
||||
// This could *also* technically re-enter if OnStartRequest fails after
|
||||
// spawning a plugin.
|
||||
mIsLoading = true;
|
||||
UnloadObject(false);
|
||||
NS_ENSURE_TRUE(mIsLoading, NS_OK);
|
||||
CloseChannel();
|
||||
LoadFallback(fallbackType, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) && mIsLoading) {
|
||||
// Since we've already notified of our transition, we can just Unload and
|
||||
// call LoadFallback (which will notify again)
|
||||
mType = eType_Null;
|
||||
UnloadObject(false);
|
||||
NS_ENSURE_TRUE(mIsLoading, NS_OK);
|
||||
CloseChannel();
|
||||
LoadFallback(fallbackType, true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1922,13 +1980,13 @@ nsObjectLoadingContent::CloseChannel()
|
||||
nsresult
|
||||
nsObjectLoadingContent::OpenChannel()
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
NS_ASSERTION(thisContent, "must be a content");
|
||||
nsIDocument* doc = thisContent->OwnerDoc();
|
||||
NS_ASSERTION(doc, "No owner document?");
|
||||
NS_ASSERTION(!mInstanceOwner && !mInstantiating,
|
||||
"opening a new channel with already loaded content");
|
||||
|
||||
nsresult rv;
|
||||
mChannel = nullptr;
|
||||
@ -1938,6 +1996,9 @@ nsObjectLoadingContent::OpenChannel()
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
rv = secMan->CheckLoadURIWithPrincipal(thisContent->NodePrincipal(), mURI, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILoadGroup> group = doc->GetDocumentLoadGroup();
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
nsCOMPtr<nsIChannelPolicy> channelPolicy;
|
||||
|
@ -116,10 +116,13 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately instantiate a plugin instance. This is a no-op if
|
||||
* mType != eType_Plugin or a plugin is already running.
|
||||
* Immediately instantiate a plugin instance. This is a no-op if mType !=
|
||||
* eType_Plugin or a plugin is already running.
|
||||
*
|
||||
* aIsLoading indicates that we are in the loading code, and we can bypass
|
||||
* the mIsLoading check.
|
||||
*/
|
||||
nsresult InstantiatePluginInstance();
|
||||
nsresult InstantiatePluginInstance(bool aIsLoading = false);
|
||||
|
||||
/**
|
||||
* Notify this class the document state has changed
|
||||
@ -180,12 +183,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
eSupportSVG = 1u << 3, // SVG is supported (image/svg+xml)
|
||||
eSupportClassID = 1u << 4, // The classid attribute is supported
|
||||
|
||||
// Allows us to load a plugin if it matches a MIME type or file extension
|
||||
// registered to a plugin without opening its specified URI first. Can
|
||||
// result in launching plugins for URIs that return differing content
|
||||
// types. Plugins without URIs may instantiate regardless.
|
||||
// XXX(johns) this is our legacy behavior on <embed> tags, whereas object
|
||||
// will always open a channel and check its MIME if a URI is present.
|
||||
// If possible to get a *plugin* type from the type attribute *or* file
|
||||
// extension, we can use that type and begin loading the plugin before
|
||||
// opening a channel.
|
||||
// A side effect of this is if the channel fails, the plugin is still
|
||||
// running.
|
||||
eAllowPluginSkipChannel = 1u << 5
|
||||
};
|
||||
|
||||
@ -329,6 +331,12 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
*/
|
||||
bool IsSupportedDocument(const nsCString& aType);
|
||||
|
||||
/**
|
||||
* Gets the plugin instance and creates a plugin stream listener, assigning
|
||||
* it to mFinalListener
|
||||
*/
|
||||
bool MakePluginListener();
|
||||
|
||||
/**
|
||||
* Unloads all content and resets the object to a completely unloaded state
|
||||
*
|
||||
@ -412,8 +420,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// The type of fallback content we're showing (see ObjectState())
|
||||
FallbackType mFallbackType : 8;
|
||||
|
||||
// If true, the current load has finished opening a channel. Does not imply
|
||||
// mChannel -- mChannelLoaded && !mChannel may occur for a load that failed
|
||||
// If true, we have opened a channel as the listener and it has reached
|
||||
// OnStartRequest. Does not get set for channels that are passed directly to
|
||||
// the plugin listener.
|
||||
bool mChannelLoaded : 1;
|
||||
|
||||
// Whether we are about to call instantiate on our frame. If we aren't,
|
||||
|
@ -3347,7 +3347,6 @@ nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
|
||||
}
|
||||
|
||||
nsresult nsPluginHost::NewEmbeddedPluginStreamListener(nsIURI* aURI,
|
||||
nsObjectLoadingContent *aContent,
|
||||
nsNPAPIPluginInstance* aInstance,
|
||||
nsIStreamListener **aStreamListener)
|
||||
{
|
||||
@ -3355,7 +3354,7 @@ nsresult nsPluginHost::NewEmbeddedPluginStreamListener(nsIURI* aURI,
|
||||
NS_ENSURE_ARG_POINTER(aStreamListener);
|
||||
|
||||
nsRefPtr<nsPluginStreamListenerPeer> listener = new nsPluginStreamListenerPeer();
|
||||
nsresult rv = listener->InitializeEmbedded(aURI, aInstance, aContent);
|
||||
nsresult rv = listener->InitializeEmbedded(aURI, aInstance);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ public:
|
||||
|
||||
nsresult GetPlugin(const char *aMimeType, nsNPAPIPlugin** aPlugin);
|
||||
|
||||
nsresult NewEmbeddedPluginStreamListener(nsIURI* aURL, nsObjectLoadingContent *aContent,
|
||||
nsresult NewEmbeddedPluginStreamListener(nsIURI* aURL,
|
||||
nsNPAPIPluginInstance* aInstance,
|
||||
nsIStreamListener **aStreamListener);
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPluginNativeWindow.h"
|
||||
#include "sampler.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsPluginInstanceOwner.h"
|
||||
|
||||
#define MAGIC_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
@ -346,39 +346,34 @@ nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
||||
}
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::InitializeEmbedded(nsIURI *aURL,
|
||||
nsNPAPIPluginInstance* aInstance,
|
||||
nsObjectLoadingContent *aContent)
|
||||
nsNPAPIPluginInstance* aInstance)
|
||||
{
|
||||
#ifdef PLUGIN_LOGGING
|
||||
nsAutoCString urlSpec;
|
||||
aURL->GetSpec(urlSpec);
|
||||
|
||||
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
||||
("nsPluginStreamListenerPeer::InitializeEmbedded url=%s\n", urlSpec.get()));
|
||||
|
||||
|
||||
PR_LogFlush();
|
||||
#endif
|
||||
|
||||
// We have to have one or the other.
|
||||
if (!aInstance && !aContent) {
|
||||
// Not gonna work out
|
||||
if (!aInstance) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mURL = aURL;
|
||||
|
||||
if (aInstance) {
|
||||
NS_ASSERTION(mPluginInstance == nullptr, "nsPluginStreamListenerPeer::InitializeEmbedded mPluginInstance != nullptr");
|
||||
mPluginInstance = aInstance;
|
||||
} else {
|
||||
mContent = aContent;
|
||||
}
|
||||
|
||||
|
||||
NS_ASSERTION(mPluginInstance == nullptr, "nsPluginStreamListenerPeer::InitializeEmbedded mPluginInstance != nullptr");
|
||||
mPluginInstance = aInstance;
|
||||
|
||||
mPendingRequests = 1;
|
||||
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, false);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -497,16 +492,16 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
"Only our initial stream should be unknown!");
|
||||
TrackRequest(request);
|
||||
}
|
||||
|
||||
|
||||
if (mHaveFiredOnStartRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
mHaveFiredOnStartRequest = true;
|
||||
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
|
||||
|
||||
|
||||
// deal with 404 (Not Found) HTTP response,
|
||||
// just return, this causes the request to be ignored.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
@ -521,7 +516,7 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
mRequestFailed = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if (responseCode > 206) { // not normal
|
||||
bool bWantsAllNetworkStreams = false;
|
||||
|
||||
@ -542,7 +537,7 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the notification callbacks from the channel and save it as
|
||||
// week ref we'll use it in nsPluginStreamInfo::RequestRead() when
|
||||
// we'll create channel for byte range request.
|
||||
@ -550,15 +545,15 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
channel->GetNotificationCallbacks(getter_AddRefs(callbacks));
|
||||
if (callbacks)
|
||||
mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks);
|
||||
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
channel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
if (loadGroup)
|
||||
mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup);
|
||||
|
||||
|
||||
int64_t length;
|
||||
rv = channel->GetContentLength(&length);
|
||||
|
||||
|
||||
// it's possible for the server to not send a Content-Length.
|
||||
// we should still work in this case.
|
||||
if (NS_FAILED(rv) || length == -1) {
|
||||
@ -574,48 +569,34 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
else {
|
||||
mLength = length;
|
||||
}
|
||||
|
||||
|
||||
nsAutoCString aContentType; // XXX but we already got the type above!
|
||||
rv = channel->GetContentType(aContentType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
||||
nsCOMPtr<nsIURI> aURL;
|
||||
rv = channel->GetURI(getter_AddRefs(aURL));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
||||
aURL->GetSpec(mURLSpec);
|
||||
|
||||
|
||||
if (!aContentType.IsEmpty())
|
||||
mContentType = aContentType;
|
||||
|
||||
|
||||
#ifdef PLUGIN_LOGGING
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
|
||||
("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n",
|
||||
this, request, aContentType.get(), mURLSpec.get()));
|
||||
|
||||
|
||||
PR_LogFlush();
|
||||
#endif
|
||||
|
||||
// If we don't have an instance yet it means we weren't able to load
|
||||
// a plugin previously because we didn't have the mimetype. Try again
|
||||
// if we have a mime type now.
|
||||
if (!mPluginInstance && mContent && !aContentType.IsEmpty()) {
|
||||
nsObjectLoadingContent *olc = static_cast<nsObjectLoadingContent*>(mContent.get());
|
||||
rv = olc->InstantiatePluginInstance();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = olc->GetPluginInstance(getter_AddRefs(mPluginInstance));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the stream listener...
|
||||
rv = SetUpStreamListener(request, aURL);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,8 @@
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIObjectLoadingContent.h"
|
||||
|
||||
class nsIChannel;
|
||||
class nsObjectLoadingContent;
|
||||
|
||||
/**
|
||||
* When a plugin requests opens multiple requests to the same URL and
|
||||
@ -75,8 +73,7 @@ public:
|
||||
nsNPAPIPluginStreamListener *aListener);
|
||||
|
||||
nsresult InitializeEmbedded(nsIURI *aURL,
|
||||
nsNPAPIPluginInstance* aInstance,
|
||||
nsObjectLoadingContent *aContent);
|
||||
nsNPAPIPluginInstance* aInstance);
|
||||
|
||||
nsresult InitializeFullPage(nsIURI* aURL, nsNPAPIPluginInstance *aInstance);
|
||||
|
||||
@ -140,7 +137,6 @@ private:
|
||||
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCString mURLSpec; // Have to keep this member because GetURL hands out char*
|
||||
nsCOMPtr<nsIObjectLoadingContent> mContent;
|
||||
nsRefPtr<nsNPAPIPluginStreamListener> mPStreamListener;
|
||||
|
||||
// Set to true if we request failed (like with a HTTP response of 404)
|
||||
|
Loading…
x
Reference in New Issue
Block a user