зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1352567 - Remove NPAPI seekable and file streams from the dom/plugins/base code, r=jimm
MozReview-Commit-ID: 4qxEFjTKMVZ
This commit is contained in:
Родитель
ce00e2cd37
Коммит
28588c1731
|
@ -1727,46 +1727,7 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
|||
NPError
|
||||
_requestread(NPStream *pstream, NPByteRange *rangeList)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_requestread called from the wrong thread\n"));
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_RequestRead: stream=%p\n",
|
||||
(void*)pstream));
|
||||
|
||||
#ifdef PLUGIN_LOGGING
|
||||
for(NPByteRange * range = rangeList; range != nullptr; range = range->next)
|
||||
MOZ_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
|
||||
("%i-%i", range->offset, range->offset + range->length - 1));
|
||||
|
||||
MOZ_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
|
||||
PR_LogFlush();
|
||||
#endif
|
||||
|
||||
if (!pstream || !rangeList || !pstream->ndata)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
|
||||
nsNPAPIPluginStreamListener* streamlistener = streamWrapper->GetStreamListener();
|
||||
if (!streamlistener) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
int32_t streamtype = NP_NORMAL;
|
||||
|
||||
streamlistener->GetStreamType(&streamtype);
|
||||
|
||||
if (streamtype != NP_SEEK)
|
||||
return NPERR_STREAM_NOT_SEEKABLE;
|
||||
|
||||
if (!streamlistener->mStreamListenerPeer)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsresult rv = streamlistener->mStreamListenerPeer->RequestRead((NPByteRange *)rangeList);
|
||||
if (NS_FAILED(rv))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return NPERR_STREAM_NOT_SEEKABLE;
|
||||
}
|
||||
|
||||
// Deprecated, only stubbed out
|
||||
|
|
|
@ -46,7 +46,6 @@ nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(nsNPAPIPluginInstance*
|
|||
, mInst(inst)
|
||||
, mStreamBufferSize(0)
|
||||
, mStreamBufferByteCount(0)
|
||||
, mStreamType(NP_NORMAL)
|
||||
, mStreamState(eStreamStopped)
|
||||
, mStreamCleanedUp(false)
|
||||
, mCallNotify(notifyData ? true : false)
|
||||
|
@ -115,11 +114,6 @@ nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason)
|
|||
mHTTPRedirectCallback = nullptr;
|
||||
}
|
||||
|
||||
// Seekable streams have an extra addref when they are created which must
|
||||
// be matched here.
|
||||
if (NP_SEEK == mStreamType && mStreamState == eStreamTypeSet)
|
||||
NS_RELEASE_THIS();
|
||||
|
||||
if (mStreamListenerPeer) {
|
||||
mStreamListenerPeer->CancelRequests(NS_BINDING_ABORTED);
|
||||
mStreamListenerPeer = nullptr;
|
||||
|
@ -212,7 +206,6 @@ nsNPAPIPluginStreamListener::OnStartBinding(nsPluginStreamListenerPeer* streamPe
|
|||
NPP npp;
|
||||
mInst->GetNPP(&npp);
|
||||
|
||||
bool seekable;
|
||||
char* contentType;
|
||||
uint16_t streamType = NP_NORMAL;
|
||||
NPError error;
|
||||
|
@ -220,7 +213,6 @@ nsNPAPIPluginStreamListener::OnStartBinding(nsPluginStreamListenerPeer* streamPe
|
|||
streamPeer->GetURL(&mNPStreamWrapper->mNPStream.url);
|
||||
streamPeer->GetLength((uint32_t*)&(mNPStreamWrapper->mNPStream.end));
|
||||
streamPeer->GetLastModified((uint32_t*)&(mNPStreamWrapper->mNPStream.lastmodified));
|
||||
streamPeer->IsSeekable(&seekable);
|
||||
streamPeer->GetContentType(&contentType);
|
||||
|
||||
if (!mResponseHeaders.IsEmpty()) {
|
||||
|
@ -232,68 +224,25 @@ nsNPAPIPluginStreamListener::OnStartBinding(nsPluginStreamListenerPeer* streamPe
|
|||
|
||||
NPPAutoPusher nppPusher(npp);
|
||||
|
||||
NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->newstream)(npp, (char*)contentType, &mNPStreamWrapper->mNPStream, seekable, &streamType), mInst,
|
||||
NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->newstream)(npp, (char*)contentType, &mNPStreamWrapper->mNPStream, false, &streamType), mInst,
|
||||
NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
|
||||
|
||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("NPP NewStream called: this=%p, npp=%p, mime=%s, seek=%d, type=%d, return=%d, url=%s\n",
|
||||
this, npp, (char *)contentType, seekable, streamType, error, mNPStreamWrapper->mNPStream.url));
|
||||
this, npp, (char *)contentType, false, streamType, error, mNPStreamWrapper->mNPStream.url));
|
||||
|
||||
if (error != NPERR_NO_ERROR)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mStreamState = eNewStreamCalled;
|
||||
|
||||
if (!SetStreamType(streamType, false)) {
|
||||
if (streamType != NP_NORMAL) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsNPAPIPluginStreamListener::SetStreamType(uint16_t aType, bool aNeedsResume)
|
||||
{
|
||||
switch(aType)
|
||||
{
|
||||
case NP_NORMAL:
|
||||
mStreamType = NP_NORMAL;
|
||||
break;
|
||||
case NP_ASFILEONLY:
|
||||
mStreamType = NP_ASFILEONLY;
|
||||
break;
|
||||
case NP_ASFILE:
|
||||
mStreamType = NP_ASFILE;
|
||||
break;
|
||||
case NP_SEEK:
|
||||
mStreamType = NP_SEEK;
|
||||
// Seekable streams should continue to exist even after OnStopRequest
|
||||
// is fired, so we AddRef ourself an extra time and Release when the
|
||||
// plugin calls NPN_DestroyStream (CleanUpStream). If the plugin never
|
||||
// calls NPN_DestroyStream the stream will be destroyed before the plugin
|
||||
// instance is destroyed.
|
||||
NS_ADDREF_THIS();
|
||||
break;
|
||||
case nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN:
|
||||
MOZ_ASSERT(!aNeedsResume);
|
||||
mStreamType = nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN;
|
||||
SuspendRequest();
|
||||
mStreamStopMode = eDoDeferredStop;
|
||||
// In this case we do not want to execute anything else in this function.
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
mStreamState = eStreamTypeSet;
|
||||
if (aNeedsResume) {
|
||||
if (mStreamListenerPeer) {
|
||||
mStreamListenerPeer->OnStreamTypeSet(mStreamType);
|
||||
}
|
||||
ResumeRequest();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsNPAPIPluginStreamListener::SuspendRequest()
|
||||
{
|
||||
|
@ -709,25 +658,7 @@ nsNPAPIPluginStreamListener::OnStopBinding(nsPluginStreamListenerPeer* streamPee
|
|||
|
||||
// The following code can result in the deletion of 'this'. Don't
|
||||
// assume we are alive after this!
|
||||
//
|
||||
// Delay cleanup if the stream is of type NP_SEEK and status isn't
|
||||
// NS_BINDING_ABORTED (meaning the plugin hasn't called NPN_DestroyStream).
|
||||
// This is because even though we're done delivering data the plugin may
|
||||
// want to seek. Eventually either the plugin will call NPN_DestroyStream
|
||||
// or we'll perform cleanup when the instance goes away. See bug 91140.
|
||||
if (mStreamType != NP_SEEK ||
|
||||
(NP_SEEK == mStreamType && NS_BINDING_ABORTED == status)) {
|
||||
return CleanUpStream(reason);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPluginStreamListener::GetStreamType(int32_t *result)
|
||||
{
|
||||
*result = mStreamType;
|
||||
return NS_OK;
|
||||
return CleanUpStream(reason);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -65,8 +65,6 @@ public:
|
|||
const char* fileName);
|
||||
nsresult OnStopBinding(nsPluginStreamListenerPeer* streamPeer,
|
||||
nsresult status);
|
||||
nsresult GetStreamType(int32_t *result);
|
||||
bool SetStreamType(uint16_t aType, bool aNeedsResume = true);
|
||||
|
||||
bool IsStarted();
|
||||
nsresult CleanUpStream(NPReason reason);
|
||||
|
@ -112,7 +110,6 @@ protected:
|
|||
nsNPAPIStreamWrapper *mNPStreamWrapper;
|
||||
uint32_t mStreamBufferSize;
|
||||
int32_t mStreamBufferByteCount;
|
||||
int32_t mStreamType;
|
||||
StreamState mStreamState;
|
||||
bool mStreamCleanedUp;
|
||||
bool mCallNotify;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsPluginHost.h"
|
||||
#include "nsIByteRangeRequest.h"
|
||||
#include "nsIMultiPartChannel.h"
|
||||
#include "nsIInputStreamTee.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
@ -35,224 +34,6 @@
|
|||
#include "nsDataHashtable.h"
|
||||
#include "NullPrincipal.h"
|
||||
|
||||
#define BYTERANGE_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
// nsPluginByteRangeStreamListener
|
||||
|
||||
class nsPluginByteRangeStreamListener
|
||||
: public nsIStreamListener
|
||||
, public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
explicit nsPluginByteRangeStreamListener(nsIWeakReference* aWeakPtr);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
private:
|
||||
virtual ~nsPluginByteRangeStreamListener();
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mStreamConverter;
|
||||
nsWeakPtr mWeakPtrPluginStreamListenerPeer;
|
||||
bool mRemoveByteRangeRequest;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPluginByteRangeStreamListener,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener,
|
||||
nsIInterfaceRequestor)
|
||||
|
||||
nsPluginByteRangeStreamListener::nsPluginByteRangeStreamListener(nsIWeakReference* aWeakPtr)
|
||||
{
|
||||
mWeakPtrPluginStreamListenerPeer = aWeakPtr;
|
||||
mRemoveByteRangeRequest = false;
|
||||
}
|
||||
|
||||
nsPluginByteRangeStreamListener::~nsPluginByteRangeStreamListener()
|
||||
{
|
||||
mStreamConverter = nullptr;
|
||||
mWeakPtrPluginStreamListenerPeer = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap any byte-range requests so that we can check whether the base channel
|
||||
* is being tracked properly.
|
||||
*/
|
||||
static nsCOMPtr<nsIRequest>
|
||||
GetBaseRequest(nsIRequest* r)
|
||||
{
|
||||
nsCOMPtr<nsIMultiPartChannel> mp = do_QueryInterface(r);
|
||||
if (!mp)
|
||||
return r;
|
||||
|
||||
nsCOMPtr<nsIChannel> base;
|
||||
mp->GetBaseChannel(getter_AddRefs(base));
|
||||
return already_AddRefed<nsIRequest>(base.forget());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginByteRangeStreamListener::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
||||
if (!finalStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsPluginStreamListenerPeer *pslp =
|
||||
static_cast<nsPluginStreamListenerPeer*>(finalStreamListener.get());
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIRequest> baseRequest = GetBaseRequest(request);
|
||||
#endif
|
||||
NS_ASSERTION(pslp->mRequests.IndexOfObject(baseRequest) != -1,
|
||||
"Untracked byte-range request?");
|
||||
|
||||
nsCOMPtr<nsIStreamConverterService> serv = do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = serv->AsyncConvertData(MULTIPART_BYTERANGES,
|
||||
"*/*",
|
||||
finalStreamListener,
|
||||
nullptr,
|
||||
getter_AddRefs(mStreamConverter));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mStreamConverter->OnStartRequest(request, ctxt);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
mStreamConverter = nullptr;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
|
||||
if (!httpChannel) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint32_t responseCode = 0;
|
||||
rv = httpChannel->GetResponseStatus(&responseCode);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (responseCode != 200) {
|
||||
uint32_t wantsAllNetworkStreams = 0;
|
||||
rv = pslp->GetPluginInstance()->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams,
|
||||
&wantsAllNetworkStreams);
|
||||
// If the call returned an error code make sure we still use our default value.
|
||||
if (NS_FAILED(rv)) {
|
||||
wantsAllNetworkStreams = 0;
|
||||
}
|
||||
|
||||
if (!wantsAllNetworkStreams){
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// if server cannot continue with byte range (206 status) and sending us whole object (200 status)
|
||||
// reset this seekable stream & try serve it to plugin instance as a file
|
||||
mStreamConverter = finalStreamListener;
|
||||
mRemoveByteRangeRequest = true;
|
||||
|
||||
rv = pslp->ServeStreamAsFile(request, ctxt);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginByteRangeStreamListener::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
nsresult status)
|
||||
{
|
||||
if (!mStreamConverter)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
||||
if (!finalStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsPluginStreamListenerPeer *pslp =
|
||||
static_cast<nsPluginStreamListenerPeer*>(finalStreamListener.get());
|
||||
bool found = pslp->mRequests.RemoveObject(request);
|
||||
if (!found) {
|
||||
NS_ERROR("OnStopRequest received for untracked byte-range request!");
|
||||
}
|
||||
|
||||
if (mRemoveByteRangeRequest) {
|
||||
// remove byte range request from container
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(ctxt);
|
||||
if (container) {
|
||||
uint32_t byteRangeRequest = 0;
|
||||
container->GetData(&byteRangeRequest);
|
||||
if (byteRangeRequest == BYTERANGE_REQUEST_CONTEXT) {
|
||||
// to allow properly finish nsPluginStreamListenerPeer->OnStopRequest()
|
||||
// set it to something that is not the byte range request.
|
||||
container->SetData(0);
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("Bad state of nsPluginByteRangeStreamListener");
|
||||
}
|
||||
}
|
||||
|
||||
return mStreamConverter->OnStopRequest(request, ctxt, status);
|
||||
}
|
||||
|
||||
// CachedFileHolder
|
||||
|
||||
CachedFileHolder::CachedFileHolder(nsIFile* cacheFile)
|
||||
: mFile(cacheFile)
|
||||
{
|
||||
NS_ASSERTION(mFile, "Empty CachedFileHolder");
|
||||
}
|
||||
|
||||
CachedFileHolder::~CachedFileHolder()
|
||||
{
|
||||
mFile->Remove(false);
|
||||
}
|
||||
|
||||
void
|
||||
CachedFileHolder::AddRef()
|
||||
{
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "CachedFileHolder", sizeof(*this));
|
||||
}
|
||||
|
||||
void
|
||||
CachedFileHolder::Release()
|
||||
{
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "CachedFileHolder");
|
||||
if (0 == mRefCnt)
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginByteRangeStreamListener::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
|
||||
nsIInputStream *inStr,
|
||||
uint64_t sourceOffset,
|
||||
uint32_t count)
|
||||
{
|
||||
if (!mStreamConverter)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
||||
if (!finalStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mStreamConverter->OnDataAvailable(request, ctxt, inStr, sourceOffset, count);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginByteRangeStreamListener::GetInterface(const nsIID& aIID, void** result)
|
||||
{
|
||||
// Forward interface requests to our parent
|
||||
nsCOMPtr<nsIInterfaceRequestor> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
||||
if (!finalStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return finalStreamListener->GetInterface(aIID, result);
|
||||
}
|
||||
|
||||
// nsPluginStreamListenerPeer
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPluginStreamListenerPeer,
|
||||
|
@ -267,15 +48,12 @@ nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
|
|||
{
|
||||
mStreamType = NP_NORMAL;
|
||||
mStartBinding = false;
|
||||
mAbort = false;
|
||||
mRequestFailed = false;
|
||||
|
||||
mPendingRequests = 0;
|
||||
mHaveFiredOnStartRequest = false;
|
||||
mDataForwardToRequest = nullptr;
|
||||
|
||||
mUseLocalCache = false;
|
||||
mSeekable = false;
|
||||
mModified = 0;
|
||||
mStreamOffset = 0;
|
||||
mStreamComplete = 0;
|
||||
|
@ -291,16 +69,6 @@ nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
|||
if (mPStreamListener) {
|
||||
mPStreamListener->SetStreamListenerPeer(nullptr);
|
||||
}
|
||||
|
||||
// close FD of mFileCacheOutputStream if it's still open
|
||||
// or we won't be able to remove the cache file
|
||||
if (mFileCacheOutputStream)
|
||||
mFileCacheOutputStream = nullptr;
|
||||
|
||||
delete mDataForwardToRequest;
|
||||
|
||||
if (mPluginInstance)
|
||||
mPluginInstance->FileCachedStreamListeners()->RemoveElement(this);
|
||||
}
|
||||
|
||||
// Called as a result of GetURL and PostURL, or by the host in the case of the
|
||||
|
@ -338,91 +106,9 @@ nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
|||
|
||||
mPendingRequests = 1;
|
||||
|
||||
mDataForwardToRequest = new nsDataHashtable<nsUint32HashKey, uint32_t>();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// SetupPluginCacheFile is called if we have to save the stream to disk.
|
||||
//
|
||||
// These files will be deleted when the host is destroyed.
|
||||
//
|
||||
// TODO? What if we fill up the the dest dir?
|
||||
nsresult
|
||||
nsPluginStreamListenerPeer::SetupPluginCacheFile(nsIChannel* channel)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
bool useExistingCacheFile = false;
|
||||
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
||||
|
||||
// Look for an existing cache file for the URI.
|
||||
nsTArray< RefPtr<nsNPAPIPluginInstance> > *instances = pluginHost->InstanceArray();
|
||||
for (uint32_t i = 0; i < instances->Length(); i++) {
|
||||
// most recent streams are at the end of list
|
||||
nsTArray<nsPluginStreamListenerPeer*> *streamListeners = instances->ElementAt(i)->FileCachedStreamListeners();
|
||||
for (int32_t i = streamListeners->Length() - 1; i >= 0; --i) {
|
||||
nsPluginStreamListenerPeer *lp = streamListeners->ElementAt(i);
|
||||
if (lp && lp->mLocalCachedFileHolder) {
|
||||
useExistingCacheFile = lp->UseExistingPluginCacheFile(this);
|
||||
if (useExistingCacheFile) {
|
||||
mLocalCachedFileHolder = lp->mLocalCachedFileHolder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (useExistingCacheFile)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new cache file if one could not be found.
|
||||
if (!useExistingCacheFile) {
|
||||
nsCOMPtr<nsIFile> pluginTmp;
|
||||
rv = nsPluginHost::GetPluginTempDir(getter_AddRefs(pluginTmp));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the filename from the channel
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = channel->GetURI(getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
|
||||
if (!url)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoCString filename;
|
||||
url->GetFileName(filename);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Create a file to save our stream into. Should we scramble the name?
|
||||
filename.InsertLiteral("plugin-", 0);
|
||||
rv = pluginTmp->AppendNative(filename);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Yes, make it unique.
|
||||
rv = pluginTmp->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// create a file output stream to write to...
|
||||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(mFileCacheOutputStream), pluginTmp, -1, 00600);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// save the file.
|
||||
mLocalCachedFileHolder = new CachedFileHolder(pluginTmp);
|
||||
}
|
||||
|
||||
// add this listenerPeer to list of stream peers for this instance
|
||||
mPluginInstance->FileCachedStreamListeners()->AppendElement(this);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
||||
nsISupports* aContext)
|
||||
|
@ -430,8 +116,7 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
|||
nsresult rv = NS_OK;
|
||||
AUTO_PROFILER_LABEL("nsPluginStreamListenerPeer::OnStartRequest", OTHER);
|
||||
|
||||
nsCOMPtr<nsIRequest> baseRequest = GetBaseRequest(request);
|
||||
if (mRequests.IndexOfObject(baseRequest) == -1) {
|
||||
if (mRequests.IndexOfObject(request) == -1) {
|
||||
NS_ASSERTION(mRequests.Count() == 0,
|
||||
"Only our initial stream should be unknown!");
|
||||
TrackRequest(request);
|
||||
|
@ -597,13 +282,6 @@ nsPluginStreamListenerPeer::GetContentType(char** result)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsPluginStreamListenerPeer::IsSeekable(bool* result)
|
||||
{
|
||||
*result = mSeekable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginStreamListenerPeer::GetLength(uint32_t* result)
|
||||
{
|
||||
|
@ -625,41 +303,6 @@ nsPluginStreamListenerPeer::GetURL(const char** result)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginStreamListenerPeer::MakeByteRangeString(NPByteRange* aRangeList, nsACString &rangeRequest,
|
||||
int32_t *numRequests)
|
||||
{
|
||||
rangeRequest.Truncate();
|
||||
*numRequests = 0;
|
||||
//the string should look like this: bytes=500-700,601-999
|
||||
if (!aRangeList)
|
||||
return;
|
||||
|
||||
int32_t requestCnt = 0;
|
||||
nsAutoCString string("bytes=");
|
||||
|
||||
for (NPByteRange * range = aRangeList; range != nullptr; range = range->next) {
|
||||
// XXX zero length?
|
||||
if (!range->length)
|
||||
continue;
|
||||
|
||||
// XXX needs to be fixed for negative offsets
|
||||
string.AppendInt(range->offset);
|
||||
string.Append('-');
|
||||
string.AppendInt(range->offset + range->length - 1);
|
||||
if (range->next)
|
||||
string.Append(',');
|
||||
|
||||
requestCnt++;
|
||||
}
|
||||
|
||||
// get rid of possible trailing comma
|
||||
string.Trim(",", false);
|
||||
|
||||
rangeRequest = string;
|
||||
*numRequests = requestCnt;
|
||||
}
|
||||
|
||||
// XXX: Converting the channel within nsPluginStreamListenerPeer
|
||||
// to use asyncOpen2() and do not want to touch the fragile logic
|
||||
// of byte range requests. Hence we just introduce this lightweight
|
||||
|
@ -717,99 +360,6 @@ private:
|
|||
|
||||
NS_IMPL_ISUPPORTS(PluginContextProxy, nsIStreamListener)
|
||||
|
||||
nsresult
|
||||
nsPluginStreamListenerPeer::RequestRead(NPByteRange* rangeList)
|
||||
{
|
||||
nsAutoCString rangeString;
|
||||
int32_t numRequests;
|
||||
|
||||
MakeByteRangeString(rangeList, rangeString, &numRequests);
|
||||
|
||||
if (numRequests == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
RefPtr<nsPluginInstanceOwner> owner = mPluginInstance->GetOwner();
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (owner) {
|
||||
rv = owner->GetDOMElement(getter_AddRefs(element));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = owner->GetDocument(getter_AddRefs(doc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks = do_QueryReferent(mWeakPtrChannelCallbacks);
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mWeakPtrChannelLoadGroup);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsCOMPtr<nsINode> requestingNode(do_QueryInterface(element));
|
||||
if (requestingNode) {
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
mURL,
|
||||
requestingNode,
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER,
|
||||
loadGroup,
|
||||
callbacks,
|
||||
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
|
||||
}
|
||||
else {
|
||||
// In this else branch we really don't know where the load is coming
|
||||
// from. Let's fall back to using the SystemPrincipal for such Plugins.
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
mURL,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER,
|
||||
loadGroup,
|
||||
callbacks,
|
||||
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (!httpChannel)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
mAbort = true; // instruct old stream listener to cancel
|
||||
// the request on the next ODA.
|
||||
|
||||
nsCOMPtr<nsIStreamListener> converter;
|
||||
|
||||
if (numRequests == 1) {
|
||||
converter = this;
|
||||
// set current stream offset equal to the first offset in the range list
|
||||
// it will work for single byte range request
|
||||
// for multy range we'll reset it in ODA
|
||||
SetStreamOffset(rangeList->offset);
|
||||
} else {
|
||||
nsWeakPtr weakpeer =
|
||||
do_GetWeakReference(static_cast<nsISupportsWeakReference*>(this));
|
||||
converter = new nsPluginByteRangeStreamListener(weakpeer);
|
||||
}
|
||||
|
||||
mPendingRequests += numRequests;
|
||||
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = container->SetData(BYTERANGE_REQUEST_CONTEXT);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<PluginContextProxy> pluginContextProxy =
|
||||
new PluginContextProxy(converter, container);
|
||||
rv = channel->AsyncOpen2(pluginContextProxy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TrackRequest(channel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginStreamListenerPeer::GetStreamOffset(int32_t* result)
|
||||
{
|
||||
|
@ -824,72 +374,13 @@ nsPluginStreamListenerPeer::SetStreamOffset(int32_t value)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
if (!mPluginInstance)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// mPluginInstance->Stop calls mPStreamListener->CleanUpStream(), so stream will be properly clean up
|
||||
mPluginInstance->Stop();
|
||||
mPluginInstance->Start();
|
||||
RefPtr<nsPluginInstanceOwner> owner = mPluginInstance->GetOwner();
|
||||
if (owner) {
|
||||
NPWindow* window = nullptr;
|
||||
owner->GetWindow(window);
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
// Should call GetPluginPort() here.
|
||||
// This part is copied from nsPluginInstanceOwner::GetPluginPort().
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
((nsPluginNativeWindow*)window)->GetPluginWidget(getter_AddRefs(widget));
|
||||
if (widget) {
|
||||
window->window = widget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
||||
}
|
||||
#endif
|
||||
owner->CallSetWindow();
|
||||
}
|
||||
|
||||
mSeekable = false;
|
||||
mPStreamListener->OnStartBinding(this);
|
||||
mStreamOffset = 0;
|
||||
|
||||
// force the plugin to use stream as file
|
||||
mStreamType = NP_ASFILE;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
if (channel) {
|
||||
SetupPluginCacheFile(channel);
|
||||
}
|
||||
|
||||
// unset mPendingRequests
|
||||
mPendingRequests = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPluginStreamListenerPeer::UseExistingPluginCacheFile(nsPluginStreamListenerPeer* psi)
|
||||
{
|
||||
NS_ENSURE_TRUE(psi, false);
|
||||
|
||||
if (psi->mLength == mLength &&
|
||||
psi->mModified == mModified &&
|
||||
mStreamComplete &&
|
||||
mURLSpec.Equals(psi->mURLSpec))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
||||
nsISupports* aContext,
|
||||
nsIInputStream *aIStream,
|
||||
uint64_t sourceOffset,
|
||||
uint32_t aLength)
|
||||
{
|
||||
nsCOMPtr<nsIRequest> baseRequest = GetBaseRequest(request);
|
||||
if (mRequests.IndexOfObject(baseRequest) == -1) {
|
||||
if (mRequests.IndexOfObject(request) == -1) {
|
||||
MOZ_ASSERT(false, "Received OnDataAvailable for untracked request.");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
@ -897,19 +388,6 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
|||
if (mRequestFailed)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mAbort) {
|
||||
uint32_t byteRangeRequest = 0; // set it to something that is not the byte range request.
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
||||
if (container)
|
||||
container->GetData(&byteRangeRequest);
|
||||
|
||||
if (byteRangeRequest != BYTERANGE_REQUEST_CONTEXT) {
|
||||
// this is not one of our range requests
|
||||
mAbort = false;
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mPStreamListener)
|
||||
|
@ -922,70 +400,17 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
|||
("nsPluginStreamListenerPeer::OnDataAvailable this=%p request=%p, offset=%" PRIu64 ", length=%u, url=%s\n",
|
||||
this, request, sourceOffset, aLength, url ? url : "no url set"));
|
||||
|
||||
// if the plugin has requested an AsFileOnly stream, then don't
|
||||
// call OnDataAvailable
|
||||
if (mStreamType != NP_ASFILEONLY) {
|
||||
// get the absolute offset of the request, if one exists.
|
||||
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
||||
if (brr) {
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIInputStream> stream = aIStream;
|
||||
rv = mPStreamListener->OnDataAvailable(this,
|
||||
stream,
|
||||
aLength);
|
||||
|
||||
int64_t absoluteOffset64 = 0;
|
||||
brr->GetStartRange(&absoluteOffset64);
|
||||
|
||||
// XXX handle 64-bit for real
|
||||
int32_t absoluteOffset = (int32_t)int64_t(absoluteOffset64);
|
||||
|
||||
// we need to track how much data we have forwarded to the
|
||||
// plugin.
|
||||
|
||||
// FIXME: http://bugzilla.mozilla.org/show_bug.cgi?id=240130
|
||||
//
|
||||
// Why couldn't this be tracked on the plugin info, and not in a
|
||||
// *hash table*?
|
||||
int32_t amtForwardToPlugin = mDataForwardToRequest->Get(absoluteOffset);
|
||||
mDataForwardToRequest->Put(absoluteOffset, (amtForwardToPlugin + aLength));
|
||||
|
||||
SetStreamOffset(absoluteOffset + amtForwardToPlugin);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream = aIStream;
|
||||
|
||||
// if we are caching the file ourselves to disk, we want to 'tee' off
|
||||
// the data as the plugin read from the stream. We do this by the magic
|
||||
// of an input stream tee.
|
||||
|
||||
if (mFileCacheOutputStream) {
|
||||
rv = NS_NewInputStreamTee(getter_AddRefs(stream), aIStream, mFileCacheOutputStream);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = mPStreamListener->OnDataAvailable(this,
|
||||
stream,
|
||||
aLength);
|
||||
|
||||
// if a plugin returns an error, the peer must kill the stream
|
||||
// else the stream and PluginStreamListener leak
|
||||
if (NS_FAILED(rv))
|
||||
request->Cancel(rv);
|
||||
// if a plugin returns an error, the peer must kill the stream
|
||||
// else the stream and PluginStreamListener leak
|
||||
if (NS_FAILED(rv)) {
|
||||
request->Cancel(rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we don't read from the stream, OnStopRequest will never be called
|
||||
char* buffer = new char[aLength];
|
||||
uint32_t amountRead, amountWrote = 0;
|
||||
rv = aIStream->Read(buffer, aLength, &amountRead);
|
||||
|
||||
// if we are caching this to disk ourselves, lets write the bytes out.
|
||||
if (mFileCacheOutputStream) {
|
||||
while (amountWrote < amountRead && NS_SUCCEEDED(rv)) {
|
||||
rv = mFileCacheOutputStream->Write(buffer, amountRead, &amountWrote);
|
||||
}
|
||||
}
|
||||
delete [] buffer;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1007,43 +432,10 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
|||
("nsPluginStreamListenerPeer::OnStopRequest this=%p aStatus=%" PRIu32 " request=%p\n",
|
||||
this, static_cast<uint32_t>(aStatus), request));
|
||||
|
||||
// for ByteRangeRequest we're just updating the mDataForwardToRequest hash and return.
|
||||
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
||||
if (brr) {
|
||||
int64_t absoluteOffset64 = 0;
|
||||
brr->GetStartRange(&absoluteOffset64);
|
||||
// XXX support 64-bit offsets
|
||||
int32_t absoluteOffset = (int32_t)int64_t(absoluteOffset64);
|
||||
|
||||
// remove the request from our data forwarding count hash.
|
||||
mDataForwardToRequest->Remove(absoluteOffset);
|
||||
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
(" ::OnStopRequest for ByteRangeRequest Started=%d\n",
|
||||
absoluteOffset));
|
||||
} else {
|
||||
// if this is not byte range request and
|
||||
// if we are writting the stream to disk ourselves,
|
||||
// close & tear it down here
|
||||
mFileCacheOutputStream = nullptr;
|
||||
}
|
||||
|
||||
// if we still have pending stuff to do, lets not close the plugin socket.
|
||||
if (--mPendingRequests > 0)
|
||||
return NS_OK;
|
||||
|
||||
// we keep our connections around...
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
||||
if (container) {
|
||||
uint32_t byteRangeRequest = 0; // something other than the byte range request.
|
||||
container->GetData(&byteRangeRequest);
|
||||
if (byteRangeRequest == BYTERANGE_REQUEST_CONTEXT) {
|
||||
// this is one of our range requests
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mPStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1070,24 +462,6 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// call OnFileAvailable if plugin requests stream type StreamType_AsFile or StreamType_AsFileOnly
|
||||
if (mStreamType >= NP_ASFILE) {
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
if (mLocalCachedFileHolder)
|
||||
localFile = mLocalCachedFileHolder->file();
|
||||
else {
|
||||
// see if it is a file channel.
|
||||
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
|
||||
if (fileChannel) {
|
||||
fileChannel->GetFile(getter_AddRefs(localFile));
|
||||
}
|
||||
}
|
||||
|
||||
if (localFile) {
|
||||
OnFileAvailable(localFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (mStartBinding) {
|
||||
// On start binding has been called
|
||||
mPStreamListener->OnStopBinding(this, aStatus);
|
||||
|
@ -1176,32 +550,6 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
|
|||
rv = httpChannel->VisitResponseHeaders(this);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
mSeekable = false;
|
||||
// first we look for a content-encoding header. If we find one, we tell the
|
||||
// plugin that stream is not seekable, because the plugin always sees
|
||||
// uncompressed data, so it can't make meaningful range requests on a
|
||||
// compressed entity. Also, we force the plugin to use
|
||||
// nsPluginStreamType_AsFile stream type and we have to save decompressed
|
||||
// file into local plugin cache, because necko cache contains original
|
||||
// compressed file.
|
||||
nsAutoCString contentEncoding;
|
||||
if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
|
||||
contentEncoding))) {
|
||||
mUseLocalCache = true;
|
||||
} else {
|
||||
// set seekability (seekable if the stream has a known length and if the
|
||||
// http server accepts byte ranges).
|
||||
uint32_t length;
|
||||
GetLength(&length);
|
||||
if (length) {
|
||||
nsAutoCString range;
|
||||
if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("accept-ranges"), range)) &&
|
||||
range.Equals(NS_LITERAL_CSTRING("bytes"), nsCaseInsensitiveCStringComparator())) {
|
||||
mSeekable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we require a content len
|
||||
// get Last-Modified header for plugin info
|
||||
nsAutoCString lastModified;
|
||||
|
@ -1226,56 +574,9 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
int32_t streamType = NP_NORMAL;
|
||||
mPStreamListener->GetStreamType(&streamType);
|
||||
|
||||
if (streamType != STREAM_TYPE_UNKNOWN) {
|
||||
OnStreamTypeSet(streamType);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginStreamListenerPeer::OnStreamTypeSet(const int32_t aStreamType)
|
||||
{
|
||||
MOZ_ASSERT(aStreamType != STREAM_TYPE_UNKNOWN);
|
||||
MOZ_ASSERT(mRequest);
|
||||
mStreamType = aStreamType;
|
||||
if (!mUseLocalCache && mStreamType >= NP_ASFILE) {
|
||||
// check it out if this is not a file channel.
|
||||
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(mRequest);
|
||||
if (!fileChannel) {
|
||||
mUseLocalCache = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mUseLocalCache) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(mRequest);
|
||||
SetupPluginCacheFile(channel);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginStreamListenerPeer::OnFileAvailable(nsIFile* aFile)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!mPStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoCString path;
|
||||
rv = aFile->GetNativePath(path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (path.IsEmpty()) {
|
||||
NS_WARNING("empty path");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = mPStreamListener->OnFileAvailable(this, path.get());
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginStreamListenerPeer::VisitHeader(const nsACString &header, const nsACString &value)
|
||||
{
|
||||
|
|
|
@ -63,29 +63,17 @@ public:
|
|||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
|
||||
// Called by RequestRead
|
||||
void
|
||||
MakeByteRangeString(NPByteRange* aRangeList, nsACString &string, int32_t *numRequests);
|
||||
|
||||
bool UseExistingPluginCacheFile(nsPluginStreamListenerPeer* psi);
|
||||
|
||||
// Called by GetURL and PostURL (via NewStream) or by the host in the case of
|
||||
// the initial plugin stream.
|
||||
nsresult Initialize(nsIURI *aURL,
|
||||
nsNPAPIPluginInstance *aInstance,
|
||||
nsNPAPIPluginStreamListener *aListener);
|
||||
|
||||
nsresult OnFileAvailable(nsIFile* aFile);
|
||||
|
||||
nsresult ServeStreamAsFile(nsIRequest *request, nsISupports *ctxt);
|
||||
|
||||
nsNPAPIPluginInstance *GetPluginInstance() { return mPluginInstance; }
|
||||
|
||||
nsresult RequestRead(NPByteRange* rangeList);
|
||||
nsresult GetLength(uint32_t* result);
|
||||
nsresult GetURL(const char** result);
|
||||
nsresult GetLastModified(uint32_t* result);
|
||||
nsresult IsSeekable(bool* result);
|
||||
nsresult GetContentType(char** result);
|
||||
nsresult GetStreamOffset(int32_t* result);
|
||||
nsresult SetStreamOffset(int32_t value);
|
||||
|
@ -128,16 +116,8 @@ public:
|
|||
requestsCopy[i]->Resume();
|
||||
}
|
||||
|
||||
// Called by nsNPAPIPluginStreamListener
|
||||
void OnStreamTypeSet(const int32_t aStreamType);
|
||||
|
||||
enum {
|
||||
STREAM_TYPE_UNKNOWN = UINT16_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
|
||||
nsresult SetupPluginCacheFile(nsIChannel* channel);
|
||||
nsresult GetInterfaceGlobal(const nsIID& aIID, void** result);
|
||||
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
|
@ -159,23 +139,15 @@ private:
|
|||
uint32_t mLength;
|
||||
int32_t mStreamType;
|
||||
|
||||
// local cached file, we save the content into local cache if browser cache is not available,
|
||||
// or plugin asks stream as file and it expects file extension until bug 90558 got fixed
|
||||
RefPtr<CachedFileHolder> mLocalCachedFileHolder;
|
||||
nsCOMPtr<nsIOutputStream> mFileCacheOutputStream;
|
||||
nsDataHashtable<nsUint32HashKey, uint32_t>* mDataForwardToRequest;
|
||||
|
||||
nsCString mContentType;
|
||||
bool mUseLocalCache;
|
||||
nsCOMPtr<nsIRequest> mRequest;
|
||||
bool mSeekable;
|
||||
uint32_t mModified;
|
||||
RefPtr<nsNPAPIPluginInstance> mPluginInstance;
|
||||
int32_t mStreamOffset;
|
||||
bool mStreamComplete;
|
||||
|
||||
public:
|
||||
bool mAbort;
|
||||
int32_t mPendingRequests;
|
||||
nsWeakPtr mWeakPtrChannelCallbacks;
|
||||
nsWeakPtr mWeakPtrChannelLoadGroup;
|
||||
|
|
Загрузка…
Ссылка в новой задаче