mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-01 11:27:55 +00:00
Implements NPN_RequestRead(). Bug number 53363. r=peterl@netscape.com, sr=attinasi@netscape.com.
This commit is contained in:
parent
d9e67ab2aa
commit
59eb2b1392
@ -82,7 +82,7 @@ public:
|
||||
* @return The return value is currently ignored.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length) = 0;
|
||||
OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 sourceOffset, PRUint32 length) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) = 0;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsplugin.h"
|
||||
#include "ns4xPlugin.h"
|
||||
#include "ns4xPluginInstance.h"
|
||||
#include "ns4xPluginStreamListener.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIMemory.h"
|
||||
#include "nsIPluginStreamListener.h"
|
||||
@ -676,6 +677,11 @@ ns4xStreamWrapper::GetStream(nsIOutputStream* &result)
|
||||
NPError NP_EXPORT
|
||||
_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
|
||||
{
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nNewStream called \n\n");
|
||||
#endif
|
||||
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
@ -719,6 +725,10 @@ _newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
|
||||
int32 NP_EXPORT
|
||||
_write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nWrite called by plugin: \n%s\n", buffer);
|
||||
#endif
|
||||
|
||||
// negative return indicates failure to the plugin
|
||||
if(!npp)
|
||||
return -1;
|
||||
@ -745,6 +755,11 @@ _write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
NPError NP_EXPORT
|
||||
_destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
{
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nDestroy Stream called \n\n");
|
||||
#endif
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
@ -770,7 +785,7 @@ _destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
delete wrapper;
|
||||
|
||||
pstream->ndata = nsnull;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -1035,7 +1050,38 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||
NPError NP_EXPORT
|
||||
_requestread(NPStream *pstream, NPByteRange *rangeList)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nRequestRead called by plugin: ");
|
||||
for(NPByteRange * range = rangeList; range != nsnull; range = range->next)
|
||||
{
|
||||
printf("%i-%i", range->offset, range->offset + range->length - 1);
|
||||
if(range->next)
|
||||
printf(",");
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
if(!pstream || !rangeList || !pstream->ndata)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsresult res = NS_OK;
|
||||
|
||||
ns4xPluginStreamListener * streamlistener = (ns4xPluginStreamListener *)pstream->ndata;
|
||||
|
||||
if(NS_FAILED(res))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsPluginStreamType streamtype = nsPluginStreamType_Normal;
|
||||
|
||||
streamlistener->GetStreamType(&streamtype);
|
||||
|
||||
if(streamtype != nsPluginStreamType_Seek)
|
||||
return NPERR_STREAM_NOT_SEEKABLE;
|
||||
|
||||
if(streamlistener->mStreamInfo)
|
||||
streamlistener->mStreamInfo->RequestRead((nsByteRange *)rangeList);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "ns4xPluginInstance.h"
|
||||
#include "nsIPluginStreamListener.h"
|
||||
#include "ns4xPluginStreamListener.h"
|
||||
#include "nsPluginHostImpl.h"
|
||||
|
||||
#include "prlog.h"
|
||||
@ -40,46 +40,6 @@
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); // needed for NS_TRY_SAFE_CALL_*
|
||||
static NS_DEFINE_IID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
|
||||
#define MAX_PLUGIN_NECKO_BUFFER 16384
|
||||
|
||||
class ns4xPluginStreamListener : public nsIPluginStreamListener {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// from nsIPluginStreamListener:
|
||||
|
||||
NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
|
||||
|
||||
NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input,
|
||||
PRUint32 length);
|
||||
|
||||
NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName);
|
||||
|
||||
NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
|
||||
|
||||
NS_IMETHOD GetStreamType(nsPluginStreamType *result);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ns4xPluginStreamListener specific methods:
|
||||
|
||||
ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData);
|
||||
virtual ~ns4xPluginStreamListener(void);
|
||||
PRBool IsStarted(void);
|
||||
|
||||
protected:
|
||||
|
||||
void* mNotifyData;
|
||||
char* mStreamBuffer;
|
||||
ns4xPluginInstance* mInst;
|
||||
NPStream mNPStream;
|
||||
PRUint32 mPosition;
|
||||
nsPluginStreamType mStreamType;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ns4xPluginStreamListener Methods
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -88,13 +48,13 @@ static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
|
||||
|
||||
ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst,
|
||||
void* notifyData)
|
||||
: mNotifyData(notifyData)
|
||||
: mNotifyData(notifyData),
|
||||
mStreamInfo(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInst = (ns4xPluginInstance*) inst;
|
||||
mPosition = 0;
|
||||
mStreamBuffer=nsnull;
|
||||
|
||||
mStreamBuffer=nsnull;
|
||||
mPosition = 0;
|
||||
// Initialize the 4.x interface structure
|
||||
memset(&mNPStream, 0, sizeof(mNPStream));
|
||||
|
||||
@ -137,6 +97,8 @@ ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
|
||||
pluginInfo->IsSeekable(&seekable);
|
||||
pluginInfo->GetContentType(&contentType);
|
||||
|
||||
mStreamInfo = pluginInfo;
|
||||
|
||||
PRLibrary* lib = mInst->fLibrary;
|
||||
|
||||
// if we don't know the end of the stream, use 0 instead of -1. bug 59571
|
||||
@ -185,6 +147,7 @@ ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
|
||||
NS_IMETHODIMP
|
||||
ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
nsIInputStream* input,
|
||||
PRUint32 sourceOffset,
|
||||
PRUint32 length)
|
||||
{
|
||||
if (!mInst || !mInst->IsStarted())
|
||||
@ -205,6 +168,11 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
PRUint32 leftToRead = 0; // just in case OnDataaAvail tries to overflow our buffer
|
||||
PRBool createdHere = PR_FALSE; // we did malloc in locally, so we must free locally
|
||||
|
||||
// we are getting a range request, reset mPosition since postion passed to plugin will
|
||||
// be relative to the absolute position of the file.
|
||||
if (sourceOffset != 0)
|
||||
mPosition = 0;
|
||||
|
||||
pluginInfo->GetURL(&mNPStream.url);
|
||||
pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
|
||||
|
||||
@ -267,10 +235,24 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
{
|
||||
PRLibrary* lib = mInst->fLibrary;
|
||||
|
||||
#ifdef DEBUG_dougt
|
||||
printf("> %d - %d \n", sourceOffset + writeCount + mPosition, numtowrite);
|
||||
#if 0
|
||||
nsCString x;
|
||||
x.Append("d:\\parts\\");
|
||||
x.AppendInt(sourceOffset);
|
||||
|
||||
PRFileDesc* fd;
|
||||
fd = PR_Open(x, PR_CREATE_FILE |PR_SYNC| PR_APPEND | PR_RDWR, 777);
|
||||
PR_Write(fd, mStreamBuffer, numtowrite);
|
||||
PR_Close(fd);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
NS_TRY_SAFE_CALL_RETURN(writeCount, CallNPP_WriteProc(callbacks->write,
|
||||
npp,
|
||||
&mNPStream,
|
||||
mPosition,
|
||||
sourceOffset + writeCount + mPosition,
|
||||
numtowrite,
|
||||
(void *)mStreamBuffer), lib);
|
||||
if (writeCount < 0) {
|
||||
@ -278,8 +260,10 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sourceOffset == 0)
|
||||
mPosition += numtowrite;
|
||||
|
||||
amountRead -= numtowrite;
|
||||
mPosition += numtowrite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +278,7 @@ error:
|
||||
|
||||
if (leftToRead > 0) // if we have more to read in this pass, do it recursivly
|
||||
{
|
||||
OnDataAvailable(pluginInfo, input, leftToRead);
|
||||
OnDataAvailable(pluginInfo, input, sourceOffset, leftToRead);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
|
||||
// returns the state of mStarted
|
||||
PRBool IsStarted(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
nsresult InitializePlugin(nsIPluginInstancePeer* peer);
|
||||
|
60
modules/plugin/base/src/ns4xPluginStreamListener.h
Normal file
60
modules/plugin/base/src/ns4xPluginStreamListener.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef ns4xPluginStreamListener_h__
|
||||
#define ns4xPluginStreamListener_h__
|
||||
|
||||
#include "nsIPluginStreamListener.h"
|
||||
#include "nsIPluginStreamInfo.h"
|
||||
|
||||
#define MAX_PLUGIN_NECKO_BUFFER 16384
|
||||
|
||||
class ns4xPluginStreamListener : public nsIPluginStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// from nsIPluginStreamListener:
|
||||
NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
|
||||
NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length, PRUint32 offset);
|
||||
NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName);
|
||||
NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
|
||||
NS_IMETHOD GetStreamType(nsPluginStreamType *result);
|
||||
|
||||
// ns4xPluginStreamListener specific methods:
|
||||
ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData);
|
||||
virtual ~ns4xPluginStreamListener();
|
||||
PRBool IsStarted();
|
||||
|
||||
protected:
|
||||
void* mNotifyData;
|
||||
char* mStreamBuffer;
|
||||
ns4xPluginInstance* mInst;
|
||||
NPStream mNPStream;
|
||||
PRUint32 mPosition;
|
||||
nsPluginStreamType mStreamType;
|
||||
|
||||
public:
|
||||
nsIPluginStreamInfo * mStreamInfo;
|
||||
};
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIHttpProtocolHandler.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIByteRangeRequest.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
@ -44,6 +45,7 @@
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIProtocolProxyService.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIOService.h"
|
||||
@ -55,6 +57,8 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScriptablePlugin.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
|
||||
// Friggin' X11 has to "#define None". Lame!
|
||||
#ifdef None
|
||||
@ -63,12 +67,11 @@
|
||||
|
||||
#include "nsIRegistry.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
|
||||
#include "nsISupportsPrimitives.h"
|
||||
// for the dialog
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptGlobalObjectOwner.h"
|
||||
@ -144,6 +147,7 @@ static NS_DEFINE_IID(kIRequestObserverIID, NS_IREQUESTOBSERVER_IID);
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
static NS_DEFINE_CID(kHttpHandlerCID, NS_HTTPPROTOCOLHANDLER_CID);
|
||||
static NS_DEFINE_CID(kIHttpHeaderVisitorIID, NS_IHTTPHEADERVISITOR_IID);
|
||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
|
||||
static NS_DEFINE_IID(kIFileUtilitiesIID, NS_IFILEUTILITIES_IID);
|
||||
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
|
||||
@ -167,6 +171,8 @@ static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
#define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins"
|
||||
#define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
|
||||
|
||||
#define MAGIC_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
void DisplayNoDefaultPluginDialog(const char *mimeType);
|
||||
|
||||
/**
|
||||
@ -828,10 +834,11 @@ void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown)
|
||||
mLibrary = nsnull;
|
||||
}
|
||||
|
||||
class nsPluginStreamListenerPeer;
|
||||
|
||||
class nsPluginStreamInfo : public nsIPluginStreamInfo
|
||||
{
|
||||
public:
|
||||
|
||||
nsPluginStreamInfo();
|
||||
virtual ~nsPluginStreamInfo();
|
||||
|
||||
@ -874,22 +881,116 @@ public:
|
||||
void
|
||||
SetURL(const char* url);
|
||||
|
||||
void
|
||||
SetPluginInstance(nsIPluginInstance * aPluginInstance);
|
||||
|
||||
void
|
||||
SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamListenerPeer);
|
||||
|
||||
void
|
||||
MakeByteRangeString(nsByteRange* aRangeList, char** string, PRInt32 *numRequests);
|
||||
|
||||
void
|
||||
SetLocalCachedFile(const char* path);
|
||||
|
||||
void
|
||||
GetLocalCachedFile(char** path);
|
||||
|
||||
private:
|
||||
|
||||
char* mContentType;
|
||||
char* mURL;
|
||||
PRBool mSeekable;
|
||||
char* mFilePath;
|
||||
PRBool mSeekable;
|
||||
PRUint32 mLength;
|
||||
PRUint32 mModified;
|
||||
nsIPluginInstance * mPluginInstance;
|
||||
nsPluginStreamListenerPeer * mPluginStreamListenerPeer;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsPluginStreamListenerPeer : public nsIStreamListener,
|
||||
public nsIProgressEventSink,
|
||||
public nsIHttpHeaderVisitor
|
||||
{
|
||||
public:
|
||||
nsPluginStreamListenerPeer();
|
||||
virtual ~nsPluginStreamListenerPeer();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIHTTPHEADERVISITOR
|
||||
|
||||
// Called by GetURL and PostURL (via NewStream)
|
||||
nsresult Initialize(nsIURI *aURL,
|
||||
nsIPluginInstance *aInstance,
|
||||
nsIPluginStreamListener *aListener,
|
||||
PRInt32 requestCount = 1);
|
||||
|
||||
nsresult InitializeEmbeded(nsIURI *aURL,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIPluginInstanceOwner *aOwner = nsnull,
|
||||
nsIPluginHost *aHost = nsnull);
|
||||
|
||||
nsresult InitializeFullPage(nsIPluginInstance *aInstance);
|
||||
|
||||
nsresult OnFileAvailable(const char* aFilename);
|
||||
|
||||
nsILoadGroup* GetLoadGroup();
|
||||
|
||||
nsresult SetLocalFile(const char* aFilename);
|
||||
|
||||
private:
|
||||
nsresult SetUpCache(nsIURI* aURL);
|
||||
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
|
||||
|
||||
nsIURI *mURL;
|
||||
|
||||
|
||||
nsIPluginInstanceOwner *mOwner;
|
||||
nsIPluginInstance *mInstance;
|
||||
nsIPluginStreamListener *mPStreamListener;
|
||||
nsPluginStreamInfo *mPluginStreamInfo;
|
||||
PRBool mSetUpListener;
|
||||
|
||||
/*
|
||||
* Set to PR_TRUE after nsIPluginInstancePeer::OnStartBinding() has
|
||||
* been called. Checked in ::OnStopRequest so we can call the
|
||||
* plugin's OnStartBinding if, for some reason, it has not already
|
||||
* been called.
|
||||
*/
|
||||
PRPackedBool mStartBinding;
|
||||
PRPackedBool mHaveFiredOnStartRequest;
|
||||
// these get passed to the plugin stream listener
|
||||
char *mMIMEType;
|
||||
PRUint32 mLength;
|
||||
nsPluginStreamType mStreamType;
|
||||
nsIPluginHost *mHost;
|
||||
|
||||
// local file which was used to post data and which should be deleted after that
|
||||
char *mLocalFile;
|
||||
nsHashtable *mDataForwardToRequest;
|
||||
|
||||
public:
|
||||
PRBool mAbort;
|
||||
PRInt32 mPendingRequests;
|
||||
|
||||
};
|
||||
|
||||
nsPluginStreamInfo::nsPluginStreamInfo()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mPluginInstance = nsnull;
|
||||
mPluginStreamListenerPeer = nsnull;
|
||||
|
||||
mContentType = nsnull;
|
||||
mURL = nsnull;
|
||||
mSeekable = PR_FALSE;
|
||||
mFilePath = nsnull;
|
||||
mSeekable = PR_FALSE;
|
||||
mLength = 0;
|
||||
mModified = 0;
|
||||
}
|
||||
@ -900,6 +1001,11 @@ nsPluginStreamInfo::~nsPluginStreamInfo()
|
||||
PL_strfree(mContentType);
|
||||
if(mURL != nsnull)
|
||||
PL_strfree(mURL);
|
||||
if(mFilePath != nsnull)
|
||||
PL_strfree(mFilePath);
|
||||
|
||||
NS_IF_RELEASE(mPluginInstance);
|
||||
NS_IF_RELEASE(mPluginStreamListenerPeer);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsPluginStreamInfo)
|
||||
@ -965,10 +1071,111 @@ nsPluginStreamInfo::GetURL(const char** result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsPluginStreamInfo::MakeByteRangeString(nsByteRange* aRangeList, char** rangeRequest, PRInt32 *numRequests)
|
||||
{
|
||||
*rangeRequest = nsnull;
|
||||
*numRequests = 0;
|
||||
//the string should look like this: bytes=500-700,601-999
|
||||
if(!aRangeList)
|
||||
return;
|
||||
|
||||
PRInt32 requestCnt = 0;
|
||||
// XXX needs to be smarter than that
|
||||
char * string = new char[1024];
|
||||
|
||||
string[0] = '\0';
|
||||
PL_strcat(string, "bytes=");
|
||||
|
||||
for(nsByteRange * range = aRangeList; range != nsnull; range = range->next)
|
||||
{
|
||||
// XXX zero length?
|
||||
if(!range->length)
|
||||
continue;
|
||||
|
||||
// XXX needs to be fixed for negative offsets
|
||||
nsCString firstbyte; firstbyte.AppendInt(range->offset);
|
||||
nsCString lastbyte; firstbyte.AppendInt(range->offset + range->length - 1);
|
||||
|
||||
PL_strcat(string, firstbyte.get());
|
||||
PL_strcat(string, "-");
|
||||
PL_strcat(string, lastbyte.get());
|
||||
if(range->next)
|
||||
PL_strcat(string, ",");
|
||||
|
||||
requestCnt++;
|
||||
}
|
||||
|
||||
// get rid of possible tailing comma
|
||||
PRInt32 len = PL_strlen(string);
|
||||
if(string[len - 1] == ',')
|
||||
string[len - 1] = '\0';
|
||||
|
||||
*rangeRequest = string;
|
||||
*numRequests = requestCnt;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginStreamInfo::RequestRead(nsByteRange* rangeList)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mPluginStreamListenerPeer->mAbort = PR_TRUE;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIURI> url;
|
||||
|
||||
rv = NS_NewURI(getter_AddRefs(url), mURL);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if(!httpChannel)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char *rangeString;
|
||||
PRInt32 numRequests;
|
||||
|
||||
MakeByteRangeString(rangeList, &rangeString, &numRequests);
|
||||
|
||||
if(!rangeString)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
httpChannel->SetRequestHeader("Range", rangeString);
|
||||
|
||||
delete [] rangeString;
|
||||
|
||||
// instruct old stream listener to cancel the request on the next
|
||||
// attempt to write.
|
||||
|
||||
nsCOMPtr<nsIStreamListener> converter = mPluginStreamListenerPeer;
|
||||
|
||||
if (numRequests > 1) {
|
||||
nsCOMPtr<nsIStreamConverterService> serv = do_GetService(kStreamConverterServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = serv->AsyncConvertData(NS_LITERAL_STRING("multipart/byteranges").get(),
|
||||
NS_LITERAL_STRING("*/*").get(),
|
||||
mPluginStreamListenerPeer,
|
||||
nsnull,
|
||||
getter_AddRefs(converter));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
mPluginStreamListenerPeer->mPendingRequests += numRequests;
|
||||
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = container->SetData(MAGIC_REQUEST_CONTEXT);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return channel->AsyncOpen(converter, container);
|
||||
}
|
||||
|
||||
// local methods
|
||||
@ -1009,68 +1216,33 @@ nsPluginStreamInfo::SetURL(const char* url)
|
||||
mURL = PL_strdup(url);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsPluginStreamListenerPeer : public nsIStreamListener,
|
||||
public nsIProgressEventSink,
|
||||
public nsIHttpHeaderVisitor
|
||||
void
|
||||
nsPluginStreamInfo::SetLocalCachedFile(const char* path)
|
||||
{
|
||||
if(mFilePath != nsnull)
|
||||
PL_strfree(mFilePath);
|
||||
|
||||
mFilePath = PL_strdup(path);
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginStreamInfo::GetLocalCachedFile(char** path)
|
||||
{
|
||||
*path = PL_strdup(mFilePath);
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginStreamInfo::SetPluginInstance(nsIPluginInstance * aPluginInstance)
|
||||
{
|
||||
public:
|
||||
nsPluginStreamListenerPeer();
|
||||
virtual ~nsPluginStreamListenerPeer();
|
||||
NS_IF_ADDREF(mPluginInstance = aPluginInstance);
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIHTTPHEADERVISITOR
|
||||
|
||||
// Called by GetURL and PostURL (via NewStream)
|
||||
nsresult Initialize(nsIURI *aURL,
|
||||
nsIPluginInstance *aInstance,
|
||||
nsIPluginStreamListener *aListener);
|
||||
|
||||
nsresult InitializeEmbeded(nsIURI *aURL,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIPluginInstanceOwner *aOwner = nsnull,
|
||||
nsIPluginHost *aHost = nsnull);
|
||||
|
||||
nsresult InitializeFullPage(nsIPluginInstance *aInstance);
|
||||
|
||||
nsresult OnFileAvailable(const char* aFilename);
|
||||
|
||||
nsILoadGroup* GetLoadGroup();
|
||||
|
||||
nsresult SetLocalFile(const char* aFilename);
|
||||
|
||||
private:
|
||||
nsresult SetUpCache(nsIURI* aURL);
|
||||
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
|
||||
|
||||
nsIURI *mURL;
|
||||
nsIPluginInstanceOwner *mOwner;
|
||||
nsIPluginInstance *mInstance;
|
||||
nsIPluginStreamListener *mPStreamListener;
|
||||
nsPluginStreamInfo *mPluginStreamInfo;
|
||||
PRBool mSetUpListener;
|
||||
|
||||
/*
|
||||
* Set to PR_TRUE after nsIPluginInstancePeer::OnStartBinding() has
|
||||
* been called. Checked in ::OnStopRequest so we can call the
|
||||
* plugin's OnStartBinding if, for some reason, it has not already
|
||||
* been called.
|
||||
*/
|
||||
PRBool mStartBinding;
|
||||
|
||||
// these get passed to the plugin stream listener
|
||||
char *mMIMEType;
|
||||
PRUint32 mLength;
|
||||
nsPluginStreamType mStreamType;
|
||||
nsIPluginHost *mHost;
|
||||
|
||||
// local file which was used to post data and which should be deleted after that
|
||||
char *mLocalFile;
|
||||
};
|
||||
void
|
||||
nsPluginStreamInfo::SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamListenerPeer)
|
||||
{
|
||||
NS_IF_ADDREF(mPluginStreamListenerPeer = aPluginStreamListenerPeer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1157,6 +1329,11 @@ nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
|
||||
mStreamType = nsPluginStreamType_Normal;
|
||||
mStartBinding = PR_FALSE;
|
||||
mLocalFile = nsnull;
|
||||
mAbort = PR_FALSE;
|
||||
|
||||
mPendingRequests = 0;
|
||||
mHaveFiredOnStartRequest = PR_FALSE;
|
||||
mDataForwardToRequest = nsnull;
|
||||
}
|
||||
|
||||
nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
||||
@ -1187,55 +1364,21 @@ nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
||||
localFile->Delete(PR_FALSE);
|
||||
delete [] mLocalFile;
|
||||
}
|
||||
delete mDataForwardToRequest;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsPluginStreamListenerPeer);
|
||||
NS_IMPL_RELEASE(nsPluginStreamListenerPeer);
|
||||
NS_IMPL_ISUPPORTS3(nsPluginStreamListenerPeer,
|
||||
nsIStreamListener,
|
||||
nsIRequestObserver,
|
||||
nsIHttpHeaderVisitor)
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::QueryInterface(const nsIID& aIID,
|
||||
void** aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
|
||||
|
||||
if (nsnull == aInstancePtrResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aIID.Equals(kIStreamListenerIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsIStreamListener *)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(kIRequestObserverIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsIRequestObserver *)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(kIHttpHeaderVisitorIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsIHttpHeaderVisitor *)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(kISupportsIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsISupports *)((nsIStreamListener *)this));
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
/* Called as a result of GetURL and PostURL */
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
||||
nsIPluginInstance *aInstance,
|
||||
nsIPluginStreamListener* aListener)
|
||||
nsIPluginStreamListener* aListener,
|
||||
PRInt32 requestCount)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
char* spec;
|
||||
@ -1255,6 +1398,15 @@ nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
|
||||
mPluginStreamInfo->SetPluginInstance(aInstance);
|
||||
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
||||
|
||||
mPendingRequests = requestCount;
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1297,6 +1449,13 @@ nsresult nsPluginStreamListenerPeer::InitializeEmbeded(nsIURI *aURL,
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
|
||||
mPluginStreamInfo->SetPluginInstance(aInstance);
|
||||
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1315,6 +1474,13 @@ nsresult nsPluginStreamListenerPeer::InitializeFullPage(nsIPluginInstance *aInst
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
|
||||
mPluginStreamInfo->SetPluginInstance(aInstance);
|
||||
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1324,6 +1490,12 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, nsISupports* aCo
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mHaveFiredOnStartRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mHaveFiredOnStartRequest = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
|
||||
if (!channel)
|
||||
@ -1435,12 +1607,52 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStatus(nsIRequest *request,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class nsPRUintKey : public nsHashKey {
|
||||
protected:
|
||||
PRUint32 mKey;
|
||||
public:
|
||||
nsPRUintKey(PRUint32 key) : mKey(key) {}
|
||||
|
||||
PRUint32 HashCode(void) const {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
PRBool Equals(const nsHashKey *aKey) const {
|
||||
return mKey == ((const nsPRUintKey *) aKey)->mKey;
|
||||
}
|
||||
nsHashKey *Clone() const {
|
||||
return new nsPRUintKey(mKey);
|
||||
}
|
||||
PRUint32 GetValue() { return mKey; }
|
||||
};
|
||||
|
||||
|
||||
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
||||
nsISupports* aContext,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 sourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
|
||||
|
||||
if(mAbort)
|
||||
{
|
||||
PRUint32 magicNumber = 0; // set it to something that is not the magic number.
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
||||
if (container)
|
||||
container->GetData(&magicNumber);
|
||||
|
||||
if (magicNumber != MAGIC_REQUEST_CONTEXT)
|
||||
{
|
||||
// this is not one of our range requests
|
||||
mAbort = PR_FALSE;
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIURI> aURL;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
@ -1463,9 +1675,30 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
||||
// call OnDataAvailable
|
||||
if(mStreamType != nsPluginStreamType_AsFileOnly)
|
||||
{
|
||||
// It's up to the plugin to read from the stream
|
||||
// If it doesn't, OnStopRequest will never be called
|
||||
rv = mPStreamListener->OnDataAvailable((nsIPluginStreamInfo*)mPluginStreamInfo, aIStream, aLength);
|
||||
// get the absolute offset of the request, if one exists.
|
||||
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
||||
PRInt32 absoluteOffset = 0;
|
||||
PRInt32 amtForwardToPlugin = 0;
|
||||
if (brr) {
|
||||
brr->GetStartRange(&absoluteOffset);
|
||||
|
||||
// we need to track how much data we have forward on to the plugin.
|
||||
nsPRUintKey key(absoluteOffset);
|
||||
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mDataForwardToRequest->Exists(&key))
|
||||
amtForwardToPlugin = (PRInt32) mDataForwardToRequest->Remove(&key);
|
||||
|
||||
mDataForwardToRequest->Put(&key, (void*) (amtForwardToPlugin+aLength));
|
||||
}
|
||||
|
||||
rv = mPStreamListener->OnDataAvailable((nsIPluginStreamInfo*)mPluginStreamInfo,
|
||||
aIStream,
|
||||
absoluteOffset+amtForwardToPlugin,
|
||||
aLength);
|
||||
|
||||
// if a plugin returns an error, the peer must kill the stream
|
||||
// else the stream and PluginStreamListener leak
|
||||
if (NS_FAILED(rv))
|
||||
@ -1486,7 +1719,74 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
nsXPIDLCString pathAndFilename;
|
||||
|
||||
// doing multiple requests, the main url load (the cacheable entry) could come
|
||||
// out of order. Here we will check to see if the request is main url load.
|
||||
|
||||
if (cacheChannel) {
|
||||
rv = cacheChannel->GetCacheFile(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
localFile->GetPath(getter_Copies(pathAndFilename));
|
||||
mPluginStreamInfo->SetLocalCachedFile(pathAndFilename);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the request from our data forwarding count hash.
|
||||
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
||||
if (brr) {
|
||||
PRInt32 absoluteOffset = 0;
|
||||
brr->GetStartRange(&absoluteOffset);
|
||||
|
||||
nsPRUintKey key(absoluteOffset);
|
||||
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
(void) mDataForwardToRequest->Remove(&key);
|
||||
}
|
||||
|
||||
|
||||
// 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...
|
||||
PRUint32 magicNumber = 0; // set it to something that is not the magic number.
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
||||
if (container)
|
||||
container->GetData(&magicNumber);
|
||||
|
||||
if (magicNumber == MAGIC_REQUEST_CONTEXT)
|
||||
{
|
||||
// this is one of our range requests
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if(!mPStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!pathAndFilename)
|
||||
mPluginStreamInfo->GetLocalCachedFile(getter_Copies(pathAndFilename));
|
||||
|
||||
if (!pathAndFilename) {
|
||||
// see if it is a file channel.
|
||||
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
|
||||
if (fileChannel)
|
||||
fileChannel->GetFile(getter_AddRefs(localFile));
|
||||
if (localFile)
|
||||
localFile->GetPath(getter_Copies(pathAndFilename));
|
||||
|
||||
mPluginStreamInfo->SetLocalCachedFile(pathAndFilename);
|
||||
}
|
||||
|
||||
if (pathAndFilename)
|
||||
OnFileAvailable(pathAndFilename);
|
||||
|
||||
nsCOMPtr<nsIURI> aURL;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
if (!channel)
|
||||
@ -1495,59 +1795,34 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
||||
rv = channel->GetURI(getter_AddRefs(aURL));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsXPIDLCString urlString;
|
||||
rv = aURL->GetSpec(getter_Copies(urlString));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mPluginStreamInfo->SetURL(urlString);
|
||||
|
||||
// Set the content type to ensure we don't pass null to the plugin
|
||||
nsXPIDLCString aContentType;
|
||||
rv = channel->GetContentType(getter_Copies(aContentType));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if(nsnull != mPStreamListener)
|
||||
if (aContentType)
|
||||
mPluginStreamInfo->SetContentType(aContentType);
|
||||
|
||||
if (mStartBinding)
|
||||
{
|
||||
char* urlString;
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(channel);
|
||||
if (cacheChannel)
|
||||
rv = cacheChannel->GetCacheFile(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv) && localFile)
|
||||
{
|
||||
char* pathAndFilename;
|
||||
rv = localFile->GetPath(&pathAndFilename);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
OnFileAvailable(pathAndFilename);
|
||||
nsMemory::Free(pathAndFilename);
|
||||
}
|
||||
}
|
||||
|
||||
rv = aURL->GetSpec(&urlString);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
mPluginStreamInfo->SetURL(urlString);
|
||||
nsCRT::free(urlString);
|
||||
}
|
||||
|
||||
// Set the content type to ensure we don't pass null to the plugin
|
||||
char* aContentType = nsnull;
|
||||
rv = channel->GetContentType(&aContentType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (nsnull != aContentType)
|
||||
mPluginStreamInfo->SetContentType(aContentType);
|
||||
|
||||
if (mStartBinding)
|
||||
{
|
||||
// On start binding has been called
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OnStartBinding hasn't been called, so complete the action.
|
||||
mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInfo);
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
|
||||
if (aContentType)
|
||||
nsCRT::free(aContentType);
|
||||
// On start binding has been called
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OnStartBinding hasn't been called, so complete the action.
|
||||
mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInfo);
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// private methods for nsPluginStreamListenerPeer
|
||||
@ -1604,6 +1879,7 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
|
||||
bSeekable = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
mPluginStreamInfo->SetSeekable(bSeekable);
|
||||
|
||||
// get Last-Modified header for plugin info
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsplugin.h"
|
||||
#include "ns4xPlugin.h"
|
||||
#include "ns4xPluginInstance.h"
|
||||
#include "ns4xPluginStreamListener.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIMemory.h"
|
||||
#include "nsIPluginStreamListener.h"
|
||||
@ -676,6 +677,11 @@ ns4xStreamWrapper::GetStream(nsIOutputStream* &result)
|
||||
NPError NP_EXPORT
|
||||
_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
|
||||
{
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nNewStream called \n\n");
|
||||
#endif
|
||||
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
@ -719,6 +725,10 @@ _newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
|
||||
int32 NP_EXPORT
|
||||
_write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nWrite called by plugin: \n%s\n", buffer);
|
||||
#endif
|
||||
|
||||
// negative return indicates failure to the plugin
|
||||
if(!npp)
|
||||
return -1;
|
||||
@ -745,6 +755,11 @@ _write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
NPError NP_EXPORT
|
||||
_destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
{
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nDestroy Stream called \n\n");
|
||||
#endif
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
@ -770,7 +785,7 @@ _destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
delete wrapper;
|
||||
|
||||
pstream->ndata = nsnull;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -1035,7 +1050,38 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||
NPError NP_EXPORT
|
||||
_requestread(NPStream *pstream, NPByteRange *rangeList)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
printf("\nRequestRead called by plugin: ");
|
||||
for(NPByteRange * range = rangeList; range != nsnull; range = range->next)
|
||||
{
|
||||
printf("%i-%i", range->offset, range->offset + range->length - 1);
|
||||
if(range->next)
|
||||
printf(",");
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
if(!pstream || !rangeList || !pstream->ndata)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsresult res = NS_OK;
|
||||
|
||||
ns4xPluginStreamListener * streamlistener = (ns4xPluginStreamListener *)pstream->ndata;
|
||||
|
||||
if(NS_FAILED(res))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
nsPluginStreamType streamtype = nsPluginStreamType_Normal;
|
||||
|
||||
streamlistener->GetStreamType(&streamtype);
|
||||
|
||||
if(streamtype != nsPluginStreamType_Seek)
|
||||
return NPERR_STREAM_NOT_SEEKABLE;
|
||||
|
||||
if(streamlistener->mStreamInfo)
|
||||
streamlistener->mStreamInfo->RequestRead((nsByteRange *)rangeList);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "ns4xPluginInstance.h"
|
||||
#include "nsIPluginStreamListener.h"
|
||||
#include "ns4xPluginStreamListener.h"
|
||||
#include "nsPluginHostImpl.h"
|
||||
|
||||
#include "prlog.h"
|
||||
@ -40,46 +40,6 @@
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); // needed for NS_TRY_SAFE_CALL_*
|
||||
static NS_DEFINE_IID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
|
||||
#define MAX_PLUGIN_NECKO_BUFFER 16384
|
||||
|
||||
class ns4xPluginStreamListener : public nsIPluginStreamListener {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// from nsIPluginStreamListener:
|
||||
|
||||
NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
|
||||
|
||||
NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input,
|
||||
PRUint32 length);
|
||||
|
||||
NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName);
|
||||
|
||||
NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
|
||||
|
||||
NS_IMETHOD GetStreamType(nsPluginStreamType *result);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ns4xPluginStreamListener specific methods:
|
||||
|
||||
ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData);
|
||||
virtual ~ns4xPluginStreamListener(void);
|
||||
PRBool IsStarted(void);
|
||||
|
||||
protected:
|
||||
|
||||
void* mNotifyData;
|
||||
char* mStreamBuffer;
|
||||
ns4xPluginInstance* mInst;
|
||||
NPStream mNPStream;
|
||||
PRUint32 mPosition;
|
||||
nsPluginStreamType mStreamType;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ns4xPluginStreamListener Methods
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -88,13 +48,13 @@ static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
|
||||
|
||||
ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst,
|
||||
void* notifyData)
|
||||
: mNotifyData(notifyData)
|
||||
: mNotifyData(notifyData),
|
||||
mStreamInfo(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInst = (ns4xPluginInstance*) inst;
|
||||
mPosition = 0;
|
||||
mStreamBuffer=nsnull;
|
||||
|
||||
mStreamBuffer=nsnull;
|
||||
mPosition = 0;
|
||||
// Initialize the 4.x interface structure
|
||||
memset(&mNPStream, 0, sizeof(mNPStream));
|
||||
|
||||
@ -137,6 +97,8 @@ ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
|
||||
pluginInfo->IsSeekable(&seekable);
|
||||
pluginInfo->GetContentType(&contentType);
|
||||
|
||||
mStreamInfo = pluginInfo;
|
||||
|
||||
PRLibrary* lib = mInst->fLibrary;
|
||||
|
||||
// if we don't know the end of the stream, use 0 instead of -1. bug 59571
|
||||
@ -185,6 +147,7 @@ ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
|
||||
NS_IMETHODIMP
|
||||
ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
nsIInputStream* input,
|
||||
PRUint32 sourceOffset,
|
||||
PRUint32 length)
|
||||
{
|
||||
if (!mInst || !mInst->IsStarted())
|
||||
@ -205,6 +168,11 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
PRUint32 leftToRead = 0; // just in case OnDataaAvail tries to overflow our buffer
|
||||
PRBool createdHere = PR_FALSE; // we did malloc in locally, so we must free locally
|
||||
|
||||
// we are getting a range request, reset mPosition since postion passed to plugin will
|
||||
// be relative to the absolute position of the file.
|
||||
if (sourceOffset != 0)
|
||||
mPosition = 0;
|
||||
|
||||
pluginInfo->GetURL(&mNPStream.url);
|
||||
pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified));
|
||||
|
||||
@ -267,10 +235,24 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
{
|
||||
PRLibrary* lib = mInst->fLibrary;
|
||||
|
||||
#ifdef DEBUG_dougt
|
||||
printf("> %d - %d \n", sourceOffset + writeCount + mPosition, numtowrite);
|
||||
#if 0
|
||||
nsCString x;
|
||||
x.Append("d:\\parts\\");
|
||||
x.AppendInt(sourceOffset);
|
||||
|
||||
PRFileDesc* fd;
|
||||
fd = PR_Open(x, PR_CREATE_FILE |PR_SYNC| PR_APPEND | PR_RDWR, 777);
|
||||
PR_Write(fd, mStreamBuffer, numtowrite);
|
||||
PR_Close(fd);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
NS_TRY_SAFE_CALL_RETURN(writeCount, CallNPP_WriteProc(callbacks->write,
|
||||
npp,
|
||||
&mNPStream,
|
||||
mPosition,
|
||||
sourceOffset + writeCount + mPosition,
|
||||
numtowrite,
|
||||
(void *)mStreamBuffer), lib);
|
||||
if (writeCount < 0) {
|
||||
@ -278,8 +260,10 @@ ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sourceOffset == 0)
|
||||
mPosition += numtowrite;
|
||||
|
||||
amountRead -= numtowrite;
|
||||
mPosition += numtowrite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +278,7 @@ error:
|
||||
|
||||
if (leftToRead > 0) // if we have more to read in this pass, do it recursivly
|
||||
{
|
||||
OnDataAvailable(pluginInfo, input, leftToRead);
|
||||
OnDataAvailable(pluginInfo, input, sourceOffset, leftToRead);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
|
||||
// returns the state of mStarted
|
||||
PRBool IsStarted(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
nsresult InitializePlugin(nsIPluginInstancePeer* peer);
|
||||
|
60
modules/plugin/nglsrc/ns4xPluginStreamListener.h
Normal file
60
modules/plugin/nglsrc/ns4xPluginStreamListener.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef ns4xPluginStreamListener_h__
|
||||
#define ns4xPluginStreamListener_h__
|
||||
|
||||
#include "nsIPluginStreamListener.h"
|
||||
#include "nsIPluginStreamInfo.h"
|
||||
|
||||
#define MAX_PLUGIN_NECKO_BUFFER 16384
|
||||
|
||||
class ns4xPluginStreamListener : public nsIPluginStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// from nsIPluginStreamListener:
|
||||
NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
|
||||
NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length, PRUint32 offset);
|
||||
NS_IMETHOD OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName);
|
||||
NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
|
||||
NS_IMETHOD GetStreamType(nsPluginStreamType *result);
|
||||
|
||||
// ns4xPluginStreamListener specific methods:
|
||||
ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData);
|
||||
virtual ~ns4xPluginStreamListener();
|
||||
PRBool IsStarted();
|
||||
|
||||
protected:
|
||||
void* mNotifyData;
|
||||
char* mStreamBuffer;
|
||||
ns4xPluginInstance* mInst;
|
||||
NPStream mNPStream;
|
||||
PRUint32 mPosition;
|
||||
nsPluginStreamType mStreamType;
|
||||
|
||||
public:
|
||||
nsIPluginStreamInfo * mStreamInfo;
|
||||
};
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIHttpProtocolHandler.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIByteRangeRequest.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
@ -44,6 +45,7 @@
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIProtocolProxyService.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIOService.h"
|
||||
@ -55,6 +57,8 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScriptablePlugin.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
|
||||
// Friggin' X11 has to "#define None". Lame!
|
||||
#ifdef None
|
||||
@ -63,12 +67,11 @@
|
||||
|
||||
#include "nsIRegistry.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
|
||||
#include "nsISupportsPrimitives.h"
|
||||
// for the dialog
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptGlobalObjectOwner.h"
|
||||
@ -144,6 +147,7 @@ static NS_DEFINE_IID(kIRequestObserverIID, NS_IREQUESTOBSERVER_IID);
|
||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||
static NS_DEFINE_CID(kHttpHandlerCID, NS_HTTPPROTOCOLHANDLER_CID);
|
||||
static NS_DEFINE_CID(kIHttpHeaderVisitorIID, NS_IHTTPHEADERVISITOR_IID);
|
||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
|
||||
static NS_DEFINE_IID(kIFileUtilitiesIID, NS_IFILEUTILITIES_IID);
|
||||
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
|
||||
@ -167,6 +171,8 @@ static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
#define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins"
|
||||
#define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
|
||||
|
||||
#define MAGIC_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
void DisplayNoDefaultPluginDialog(const char *mimeType);
|
||||
|
||||
/**
|
||||
@ -828,10 +834,11 @@ void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown)
|
||||
mLibrary = nsnull;
|
||||
}
|
||||
|
||||
class nsPluginStreamListenerPeer;
|
||||
|
||||
class nsPluginStreamInfo : public nsIPluginStreamInfo
|
||||
{
|
||||
public:
|
||||
|
||||
nsPluginStreamInfo();
|
||||
virtual ~nsPluginStreamInfo();
|
||||
|
||||
@ -874,22 +881,116 @@ public:
|
||||
void
|
||||
SetURL(const char* url);
|
||||
|
||||
void
|
||||
SetPluginInstance(nsIPluginInstance * aPluginInstance);
|
||||
|
||||
void
|
||||
SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamListenerPeer);
|
||||
|
||||
void
|
||||
MakeByteRangeString(nsByteRange* aRangeList, char** string, PRInt32 *numRequests);
|
||||
|
||||
void
|
||||
SetLocalCachedFile(const char* path);
|
||||
|
||||
void
|
||||
GetLocalCachedFile(char** path);
|
||||
|
||||
private:
|
||||
|
||||
char* mContentType;
|
||||
char* mURL;
|
||||
PRBool mSeekable;
|
||||
char* mFilePath;
|
||||
PRBool mSeekable;
|
||||
PRUint32 mLength;
|
||||
PRUint32 mModified;
|
||||
nsIPluginInstance * mPluginInstance;
|
||||
nsPluginStreamListenerPeer * mPluginStreamListenerPeer;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsPluginStreamListenerPeer : public nsIStreamListener,
|
||||
public nsIProgressEventSink,
|
||||
public nsIHttpHeaderVisitor
|
||||
{
|
||||
public:
|
||||
nsPluginStreamListenerPeer();
|
||||
virtual ~nsPluginStreamListenerPeer();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIHTTPHEADERVISITOR
|
||||
|
||||
// Called by GetURL and PostURL (via NewStream)
|
||||
nsresult Initialize(nsIURI *aURL,
|
||||
nsIPluginInstance *aInstance,
|
||||
nsIPluginStreamListener *aListener,
|
||||
PRInt32 requestCount = 1);
|
||||
|
||||
nsresult InitializeEmbeded(nsIURI *aURL,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIPluginInstanceOwner *aOwner = nsnull,
|
||||
nsIPluginHost *aHost = nsnull);
|
||||
|
||||
nsresult InitializeFullPage(nsIPluginInstance *aInstance);
|
||||
|
||||
nsresult OnFileAvailable(const char* aFilename);
|
||||
|
||||
nsILoadGroup* GetLoadGroup();
|
||||
|
||||
nsresult SetLocalFile(const char* aFilename);
|
||||
|
||||
private:
|
||||
nsresult SetUpCache(nsIURI* aURL);
|
||||
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
|
||||
|
||||
nsIURI *mURL;
|
||||
|
||||
|
||||
nsIPluginInstanceOwner *mOwner;
|
||||
nsIPluginInstance *mInstance;
|
||||
nsIPluginStreamListener *mPStreamListener;
|
||||
nsPluginStreamInfo *mPluginStreamInfo;
|
||||
PRBool mSetUpListener;
|
||||
|
||||
/*
|
||||
* Set to PR_TRUE after nsIPluginInstancePeer::OnStartBinding() has
|
||||
* been called. Checked in ::OnStopRequest so we can call the
|
||||
* plugin's OnStartBinding if, for some reason, it has not already
|
||||
* been called.
|
||||
*/
|
||||
PRPackedBool mStartBinding;
|
||||
PRPackedBool mHaveFiredOnStartRequest;
|
||||
// these get passed to the plugin stream listener
|
||||
char *mMIMEType;
|
||||
PRUint32 mLength;
|
||||
nsPluginStreamType mStreamType;
|
||||
nsIPluginHost *mHost;
|
||||
|
||||
// local file which was used to post data and which should be deleted after that
|
||||
char *mLocalFile;
|
||||
nsHashtable *mDataForwardToRequest;
|
||||
|
||||
public:
|
||||
PRBool mAbort;
|
||||
PRInt32 mPendingRequests;
|
||||
|
||||
};
|
||||
|
||||
nsPluginStreamInfo::nsPluginStreamInfo()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mPluginInstance = nsnull;
|
||||
mPluginStreamListenerPeer = nsnull;
|
||||
|
||||
mContentType = nsnull;
|
||||
mURL = nsnull;
|
||||
mSeekable = PR_FALSE;
|
||||
mFilePath = nsnull;
|
||||
mSeekable = PR_FALSE;
|
||||
mLength = 0;
|
||||
mModified = 0;
|
||||
}
|
||||
@ -900,6 +1001,11 @@ nsPluginStreamInfo::~nsPluginStreamInfo()
|
||||
PL_strfree(mContentType);
|
||||
if(mURL != nsnull)
|
||||
PL_strfree(mURL);
|
||||
if(mFilePath != nsnull)
|
||||
PL_strfree(mFilePath);
|
||||
|
||||
NS_IF_RELEASE(mPluginInstance);
|
||||
NS_IF_RELEASE(mPluginStreamListenerPeer);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsPluginStreamInfo)
|
||||
@ -965,10 +1071,111 @@ nsPluginStreamInfo::GetURL(const char** result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsPluginStreamInfo::MakeByteRangeString(nsByteRange* aRangeList, char** rangeRequest, PRInt32 *numRequests)
|
||||
{
|
||||
*rangeRequest = nsnull;
|
||||
*numRequests = 0;
|
||||
//the string should look like this: bytes=500-700,601-999
|
||||
if(!aRangeList)
|
||||
return;
|
||||
|
||||
PRInt32 requestCnt = 0;
|
||||
// XXX needs to be smarter than that
|
||||
char * string = new char[1024];
|
||||
|
||||
string[0] = '\0';
|
||||
PL_strcat(string, "bytes=");
|
||||
|
||||
for(nsByteRange * range = aRangeList; range != nsnull; range = range->next)
|
||||
{
|
||||
// XXX zero length?
|
||||
if(!range->length)
|
||||
continue;
|
||||
|
||||
// XXX needs to be fixed for negative offsets
|
||||
nsCString firstbyte; firstbyte.AppendInt(range->offset);
|
||||
nsCString lastbyte; firstbyte.AppendInt(range->offset + range->length - 1);
|
||||
|
||||
PL_strcat(string, firstbyte.get());
|
||||
PL_strcat(string, "-");
|
||||
PL_strcat(string, lastbyte.get());
|
||||
if(range->next)
|
||||
PL_strcat(string, ",");
|
||||
|
||||
requestCnt++;
|
||||
}
|
||||
|
||||
// get rid of possible tailing comma
|
||||
PRInt32 len = PL_strlen(string);
|
||||
if(string[len - 1] == ',')
|
||||
string[len - 1] = '\0';
|
||||
|
||||
*rangeRequest = string;
|
||||
*numRequests = requestCnt;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginStreamInfo::RequestRead(nsByteRange* rangeList)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mPluginStreamListenerPeer->mAbort = PR_TRUE;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIURI> url;
|
||||
|
||||
rv = NS_NewURI(getter_AddRefs(url), mURL);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if(!httpChannel)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char *rangeString;
|
||||
PRInt32 numRequests;
|
||||
|
||||
MakeByteRangeString(rangeList, &rangeString, &numRequests);
|
||||
|
||||
if(!rangeString)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
httpChannel->SetRequestHeader("Range", rangeString);
|
||||
|
||||
delete [] rangeString;
|
||||
|
||||
// instruct old stream listener to cancel the request on the next
|
||||
// attempt to write.
|
||||
|
||||
nsCOMPtr<nsIStreamListener> converter = mPluginStreamListenerPeer;
|
||||
|
||||
if (numRequests > 1) {
|
||||
nsCOMPtr<nsIStreamConverterService> serv = do_GetService(kStreamConverterServiceCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = serv->AsyncConvertData(NS_LITERAL_STRING("multipart/byteranges").get(),
|
||||
NS_LITERAL_STRING("*/*").get(),
|
||||
mPluginStreamListenerPeer,
|
||||
nsnull,
|
||||
getter_AddRefs(converter));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
mPluginStreamListenerPeer->mPendingRequests += numRequests;
|
||||
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = container->SetData(MAGIC_REQUEST_CONTEXT);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return channel->AsyncOpen(converter, container);
|
||||
}
|
||||
|
||||
// local methods
|
||||
@ -1009,68 +1216,33 @@ nsPluginStreamInfo::SetURL(const char* url)
|
||||
mURL = PL_strdup(url);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsPluginStreamListenerPeer : public nsIStreamListener,
|
||||
public nsIProgressEventSink,
|
||||
public nsIHttpHeaderVisitor
|
||||
void
|
||||
nsPluginStreamInfo::SetLocalCachedFile(const char* path)
|
||||
{
|
||||
if(mFilePath != nsnull)
|
||||
PL_strfree(mFilePath);
|
||||
|
||||
mFilePath = PL_strdup(path);
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginStreamInfo::GetLocalCachedFile(char** path)
|
||||
{
|
||||
*path = PL_strdup(mFilePath);
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginStreamInfo::SetPluginInstance(nsIPluginInstance * aPluginInstance)
|
||||
{
|
||||
public:
|
||||
nsPluginStreamListenerPeer();
|
||||
virtual ~nsPluginStreamListenerPeer();
|
||||
NS_IF_ADDREF(mPluginInstance = aPluginInstance);
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIHTTPHEADERVISITOR
|
||||
|
||||
// Called by GetURL and PostURL (via NewStream)
|
||||
nsresult Initialize(nsIURI *aURL,
|
||||
nsIPluginInstance *aInstance,
|
||||
nsIPluginStreamListener *aListener);
|
||||
|
||||
nsresult InitializeEmbeded(nsIURI *aURL,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIPluginInstanceOwner *aOwner = nsnull,
|
||||
nsIPluginHost *aHost = nsnull);
|
||||
|
||||
nsresult InitializeFullPage(nsIPluginInstance *aInstance);
|
||||
|
||||
nsresult OnFileAvailable(const char* aFilename);
|
||||
|
||||
nsILoadGroup* GetLoadGroup();
|
||||
|
||||
nsresult SetLocalFile(const char* aFilename);
|
||||
|
||||
private:
|
||||
nsresult SetUpCache(nsIURI* aURL);
|
||||
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
|
||||
|
||||
nsIURI *mURL;
|
||||
nsIPluginInstanceOwner *mOwner;
|
||||
nsIPluginInstance *mInstance;
|
||||
nsIPluginStreamListener *mPStreamListener;
|
||||
nsPluginStreamInfo *mPluginStreamInfo;
|
||||
PRBool mSetUpListener;
|
||||
|
||||
/*
|
||||
* Set to PR_TRUE after nsIPluginInstancePeer::OnStartBinding() has
|
||||
* been called. Checked in ::OnStopRequest so we can call the
|
||||
* plugin's OnStartBinding if, for some reason, it has not already
|
||||
* been called.
|
||||
*/
|
||||
PRBool mStartBinding;
|
||||
|
||||
// these get passed to the plugin stream listener
|
||||
char *mMIMEType;
|
||||
PRUint32 mLength;
|
||||
nsPluginStreamType mStreamType;
|
||||
nsIPluginHost *mHost;
|
||||
|
||||
// local file which was used to post data and which should be deleted after that
|
||||
char *mLocalFile;
|
||||
};
|
||||
void
|
||||
nsPluginStreamInfo::SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamListenerPeer)
|
||||
{
|
||||
NS_IF_ADDREF(mPluginStreamListenerPeer = aPluginStreamListenerPeer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1157,6 +1329,11 @@ nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
|
||||
mStreamType = nsPluginStreamType_Normal;
|
||||
mStartBinding = PR_FALSE;
|
||||
mLocalFile = nsnull;
|
||||
mAbort = PR_FALSE;
|
||||
|
||||
mPendingRequests = 0;
|
||||
mHaveFiredOnStartRequest = PR_FALSE;
|
||||
mDataForwardToRequest = nsnull;
|
||||
}
|
||||
|
||||
nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
||||
@ -1187,55 +1364,21 @@ nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
||||
localFile->Delete(PR_FALSE);
|
||||
delete [] mLocalFile;
|
||||
}
|
||||
delete mDataForwardToRequest;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsPluginStreamListenerPeer);
|
||||
NS_IMPL_RELEASE(nsPluginStreamListenerPeer);
|
||||
NS_IMPL_ISUPPORTS3(nsPluginStreamListenerPeer,
|
||||
nsIStreamListener,
|
||||
nsIRequestObserver,
|
||||
nsIHttpHeaderVisitor)
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::QueryInterface(const nsIID& aIID,
|
||||
void** aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
|
||||
|
||||
if (nsnull == aInstancePtrResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aIID.Equals(kIStreamListenerIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsIStreamListener *)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(kIRequestObserverIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsIRequestObserver *)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(kIHttpHeaderVisitorIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsIHttpHeaderVisitor *)this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(kISupportsIID))
|
||||
{
|
||||
*aInstancePtrResult = (void *)((nsISupports *)((nsIStreamListener *)this));
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
/* Called as a result of GetURL and PostURL */
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
||||
nsIPluginInstance *aInstance,
|
||||
nsIPluginStreamListener* aListener)
|
||||
nsIPluginStreamListener* aListener,
|
||||
PRInt32 requestCount)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
char* spec;
|
||||
@ -1255,6 +1398,15 @@ nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
|
||||
mPluginStreamInfo->SetPluginInstance(aInstance);
|
||||
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
||||
|
||||
mPendingRequests = requestCount;
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1297,6 +1449,13 @@ nsresult nsPluginStreamListenerPeer::InitializeEmbeded(nsIURI *aURL,
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
|
||||
mPluginStreamInfo->SetPluginInstance(aInstance);
|
||||
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1315,6 +1474,13 @@ nsresult nsPluginStreamListenerPeer::InitializeFullPage(nsIPluginInstance *aInst
|
||||
|
||||
mPluginStreamInfo = new nsPluginStreamInfo();
|
||||
|
||||
mPluginStreamInfo->SetPluginInstance(aInstance);
|
||||
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
||||
|
||||
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1324,6 +1490,12 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, nsISupports* aCo
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mHaveFiredOnStartRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mHaveFiredOnStartRequest = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
|
||||
if (!channel)
|
||||
@ -1435,12 +1607,52 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStatus(nsIRequest *request,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class nsPRUintKey : public nsHashKey {
|
||||
protected:
|
||||
PRUint32 mKey;
|
||||
public:
|
||||
nsPRUintKey(PRUint32 key) : mKey(key) {}
|
||||
|
||||
PRUint32 HashCode(void) const {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
PRBool Equals(const nsHashKey *aKey) const {
|
||||
return mKey == ((const nsPRUintKey *) aKey)->mKey;
|
||||
}
|
||||
nsHashKey *Clone() const {
|
||||
return new nsPRUintKey(mKey);
|
||||
}
|
||||
PRUint32 GetValue() { return mKey; }
|
||||
};
|
||||
|
||||
|
||||
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
||||
nsISupports* aContext,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 sourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
|
||||
|
||||
if(mAbort)
|
||||
{
|
||||
PRUint32 magicNumber = 0; // set it to something that is not the magic number.
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
||||
if (container)
|
||||
container->GetData(&magicNumber);
|
||||
|
||||
if (magicNumber != MAGIC_REQUEST_CONTEXT)
|
||||
{
|
||||
// this is not one of our range requests
|
||||
mAbort = PR_FALSE;
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIURI> aURL;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
@ -1463,9 +1675,30 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
||||
// call OnDataAvailable
|
||||
if(mStreamType != nsPluginStreamType_AsFileOnly)
|
||||
{
|
||||
// It's up to the plugin to read from the stream
|
||||
// If it doesn't, OnStopRequest will never be called
|
||||
rv = mPStreamListener->OnDataAvailable((nsIPluginStreamInfo*)mPluginStreamInfo, aIStream, aLength);
|
||||
// get the absolute offset of the request, if one exists.
|
||||
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
||||
PRInt32 absoluteOffset = 0;
|
||||
PRInt32 amtForwardToPlugin = 0;
|
||||
if (brr) {
|
||||
brr->GetStartRange(&absoluteOffset);
|
||||
|
||||
// we need to track how much data we have forward on to the plugin.
|
||||
nsPRUintKey key(absoluteOffset);
|
||||
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mDataForwardToRequest->Exists(&key))
|
||||
amtForwardToPlugin = (PRInt32) mDataForwardToRequest->Remove(&key);
|
||||
|
||||
mDataForwardToRequest->Put(&key, (void*) (amtForwardToPlugin+aLength));
|
||||
}
|
||||
|
||||
rv = mPStreamListener->OnDataAvailable((nsIPluginStreamInfo*)mPluginStreamInfo,
|
||||
aIStream,
|
||||
absoluteOffset+amtForwardToPlugin,
|
||||
aLength);
|
||||
|
||||
// if a plugin returns an error, the peer must kill the stream
|
||||
// else the stream and PluginStreamListener leak
|
||||
if (NS_FAILED(rv))
|
||||
@ -1486,7 +1719,74 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
nsXPIDLCString pathAndFilename;
|
||||
|
||||
// doing multiple requests, the main url load (the cacheable entry) could come
|
||||
// out of order. Here we will check to see if the request is main url load.
|
||||
|
||||
if (cacheChannel) {
|
||||
rv = cacheChannel->GetCacheFile(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
localFile->GetPath(getter_Copies(pathAndFilename));
|
||||
mPluginStreamInfo->SetLocalCachedFile(pathAndFilename);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the request from our data forwarding count hash.
|
||||
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
||||
if (brr) {
|
||||
PRInt32 absoluteOffset = 0;
|
||||
brr->GetStartRange(&absoluteOffset);
|
||||
|
||||
nsPRUintKey key(absoluteOffset);
|
||||
|
||||
if (!mDataForwardToRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
(void) mDataForwardToRequest->Remove(&key);
|
||||
}
|
||||
|
||||
|
||||
// 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...
|
||||
PRUint32 magicNumber = 0; // set it to something that is not the magic number.
|
||||
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
||||
if (container)
|
||||
container->GetData(&magicNumber);
|
||||
|
||||
if (magicNumber == MAGIC_REQUEST_CONTEXT)
|
||||
{
|
||||
// this is one of our range requests
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if(!mPStreamListener)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!pathAndFilename)
|
||||
mPluginStreamInfo->GetLocalCachedFile(getter_Copies(pathAndFilename));
|
||||
|
||||
if (!pathAndFilename) {
|
||||
// see if it is a file channel.
|
||||
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
|
||||
if (fileChannel)
|
||||
fileChannel->GetFile(getter_AddRefs(localFile));
|
||||
if (localFile)
|
||||
localFile->GetPath(getter_Copies(pathAndFilename));
|
||||
|
||||
mPluginStreamInfo->SetLocalCachedFile(pathAndFilename);
|
||||
}
|
||||
|
||||
if (pathAndFilename)
|
||||
OnFileAvailable(pathAndFilename);
|
||||
|
||||
nsCOMPtr<nsIURI> aURL;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
if (!channel)
|
||||
@ -1495,59 +1795,34 @@ NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
||||
rv = channel->GetURI(getter_AddRefs(aURL));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsXPIDLCString urlString;
|
||||
rv = aURL->GetSpec(getter_Copies(urlString));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mPluginStreamInfo->SetURL(urlString);
|
||||
|
||||
// Set the content type to ensure we don't pass null to the plugin
|
||||
nsXPIDLCString aContentType;
|
||||
rv = channel->GetContentType(getter_Copies(aContentType));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if(nsnull != mPStreamListener)
|
||||
if (aContentType)
|
||||
mPluginStreamInfo->SetContentType(aContentType);
|
||||
|
||||
if (mStartBinding)
|
||||
{
|
||||
char* urlString;
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(channel);
|
||||
if (cacheChannel)
|
||||
rv = cacheChannel->GetCacheFile(getter_AddRefs(localFile));
|
||||
if (NS_SUCCEEDED(rv) && localFile)
|
||||
{
|
||||
char* pathAndFilename;
|
||||
rv = localFile->GetPath(&pathAndFilename);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
OnFileAvailable(pathAndFilename);
|
||||
nsMemory::Free(pathAndFilename);
|
||||
}
|
||||
}
|
||||
|
||||
rv = aURL->GetSpec(&urlString);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
mPluginStreamInfo->SetURL(urlString);
|
||||
nsCRT::free(urlString);
|
||||
}
|
||||
|
||||
// Set the content type to ensure we don't pass null to the plugin
|
||||
char* aContentType = nsnull;
|
||||
rv = channel->GetContentType(&aContentType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (nsnull != aContentType)
|
||||
mPluginStreamInfo->SetContentType(aContentType);
|
||||
|
||||
if (mStartBinding)
|
||||
{
|
||||
// On start binding has been called
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OnStartBinding hasn't been called, so complete the action.
|
||||
mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInfo);
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
|
||||
if (aContentType)
|
||||
nsCRT::free(aContentType);
|
||||
// On start binding has been called
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
// OnStartBinding hasn't been called, so complete the action.
|
||||
mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInfo);
|
||||
mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, aStatus);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// private methods for nsPluginStreamListenerPeer
|
||||
@ -1604,6 +1879,7 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
|
||||
bSeekable = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
mPluginStreamInfo->SetSeekable(bSeekable);
|
||||
|
||||
// get Last-Modified header for plugin info
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
* @return The return value is currently ignored.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length) = 0;
|
||||
OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 sourceOffset, PRUint32 length) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user