зеркало из https://github.com/mozilla/gecko-dev.git
16910, r=mcafee. FTP now uses thread pools. it also provides some status to the webshell. and it no longer uses the server's defualt path.
This commit is contained in:
Родитель
eab20fe1b3
Коммит
b7021722f9
|
@ -18,21 +18,12 @@
|
||||||
|
|
||||||
#include "nsIChannel.idl"
|
#include "nsIChannel.idl"
|
||||||
|
|
||||||
interface nsIStreamListener;
|
interface nsIEventQueue;
|
||||||
|
|
||||||
[scriptable, uuid(64718e40-18c2-11d3-9337-00104ba0fd40)]
|
[scriptable, uuid(64718e40-18c2-11d3-9337-00104ba0fd40)]
|
||||||
interface nsIFTPChannel : nsIChannel
|
interface nsIFTPChannel : nsIChannel
|
||||||
{
|
{
|
||||||
// PRE connect
|
void SetConnectionQueue(in nsIEventQueue aEventQ);
|
||||||
|
|
||||||
// POST connect
|
|
||||||
|
|
||||||
// Initiate connect
|
|
||||||
void Get();
|
|
||||||
|
|
||||||
void Put();
|
|
||||||
|
|
||||||
void SetStreamListener(in nsIStreamListener aListener);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ public:
|
||||||
|
|
||||||
mServerType = 0;
|
mServerType = 0;
|
||||||
mList = PR_FALSE;
|
mList = PR_FALSE;
|
||||||
mUseDefaultPath = PR_TRUE;
|
|
||||||
};
|
};
|
||||||
~nsConnectionCacheObj()
|
~nsConnectionCacheObj()
|
||||||
{
|
{
|
||||||
|
@ -61,7 +60,6 @@ public:
|
||||||
PRUint32 mServerType; // what kind of server is it.
|
PRUint32 mServerType; // what kind of server is it.
|
||||||
nsCAutoString mCwd; // what dir are we in
|
nsCAutoString mCwd; // what dir are we in
|
||||||
PRBool mList; // are we sending LIST or NLST
|
PRBool mList; // are we sending LIST or NLST
|
||||||
PRBool mUseDefaultPath; // do we need to use the default path.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __nsconnectioncacheobj__h____
|
#endif // __nsconnectioncacheobj__h____
|
||||||
|
|
|
@ -61,12 +61,34 @@ nsFTPChannel::nsFTPChannel() {
|
||||||
nsFTPChannel::~nsFTPChannel() {
|
nsFTPChannel::~nsFTPChannel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS4(nsFTPChannel, nsIChannel, nsIFTPChannel, nsIStreamListener, nsIStreamObserver);
|
NS_IMETHODIMP_(nsrefcnt) nsFTPChannel::AddRef(void)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
|
||||||
|
++mRefCnt;
|
||||||
|
NS_LOG_ADDREF(this, mRefCnt, "nsFTPChannel", sizeof(*this));
|
||||||
|
return mRefCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP_(nsrefcnt) nsFTPChannel::Release(void)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||||
|
--mRefCnt;
|
||||||
|
NS_LOG_RELEASE(this, mRefCnt, "nsFTPChannel");
|
||||||
|
if (mRefCnt == 0) {
|
||||||
|
mRefCnt = 1; /* stabilize */
|
||||||
|
NS_DELETEXPCOM(this);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mRefCnt;
|
||||||
|
}
|
||||||
|
NS_IMPL_QUERY_INTERFACE4(nsFTPChannel, nsIChannel, nsIFTPChannel, nsIStreamListener, nsIStreamObserver);
|
||||||
|
|
||||||
|
//NS_IMPL_ISUPPORTS4(nsFTPChannel, nsIChannel, nsIFTPChannel, nsIStreamListener, nsIStreamObserver);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFTPChannel::Init(const char* verb, nsIURI* uri, nsILoadGroup *aGroup,
|
nsFTPChannel::Init(const char* verb, nsIURI* uri, nsILoadGroup *aGroup,
|
||||||
nsIEventSinkGetter* getter, nsIURI* originalURI,
|
nsIEventSinkGetter* getter, nsIURI* originalURI,
|
||||||
nsIProtocolHandler* aHandler)
|
nsIProtocolHandler* aHandler, nsIThreadPool* aPool)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
@ -75,13 +97,19 @@ nsFTPChannel::Init(const char* verb, nsIURI* uri, nsILoadGroup *aGroup,
|
||||||
|
|
||||||
mHandler = aHandler;
|
mHandler = aHandler;
|
||||||
|
|
||||||
|
NS_ASSERTION(aPool, "FTP channel needs a thread pool to play in");
|
||||||
|
if (!aPool) return NS_ERROR_NULL_POINTER;
|
||||||
|
mPool = aPool;
|
||||||
|
|
||||||
mOriginalURI = originalURI ? originalURI : uri;
|
mOriginalURI = originalURI ? originalURI : uri;
|
||||||
mURL = uri;
|
mURL = uri;
|
||||||
|
|
||||||
mLoadGroup = aGroup;
|
mLoadGroup = aGroup;
|
||||||
|
|
||||||
if (getter) {
|
mEventSinkGetter = getter;
|
||||||
rv = getter->GetEventSink(verb, NS_GET_IID(nsIProgressEventSink),
|
|
||||||
|
if (mEventSinkGetter) {
|
||||||
|
rv = mEventSinkGetter->GetEventSink(verb, NS_GET_IID(nsIProgressEventSink),
|
||||||
(nsISupports**)(nsIProgressEventSink**)getter_AddRefs(mEventSink));
|
(nsISupports**)(nsIProgressEventSink**)getter_AddRefs(mEventSink));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::Init() (couldn't find event sink)\n"));
|
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::Init() (couldn't find event sink)\n"));
|
||||||
|
@ -96,28 +124,6 @@ nsFTPChannel::Init(const char* verb, nsIURI* uri, nsILoadGroup *aGroup,
|
||||||
rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), getter_AddRefs(mEventQueue));
|
rv = eventQService->GetThreadEventQueue(PR_CurrentThread(), getter_AddRefs(mEventQueue));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// go ahead and create the thread for the connection.
|
|
||||||
// we'll init it and kick it off later
|
|
||||||
rv = NS_NewThread(getter_AddRefs(mConnectionThread));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// we'll create the FTP connection's event queue here, on this thread.
|
|
||||||
// it will be passed to the FTP connection upon FTP connection
|
|
||||||
// initialization. at that point it's up to the FTP conn thread to
|
|
||||||
// turn the crank on it.
|
|
||||||
#if 1
|
|
||||||
PRThread *thread; // does not need deleting
|
|
||||||
rv = mConnectionThread->GetPRThread(&thread);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
PLEventQueue* PLEventQ = PL_CreateEventQueue("FTP thread", thread);
|
|
||||||
if (!PLEventQ) return rv;
|
|
||||||
|
|
||||||
rv = eventQService->CreateFromPLEventQueue(PLEventQ, getter_AddRefs(mConnectionEventQueue));
|
|
||||||
#else
|
|
||||||
rv = eventQService->CreateFromIThread(mConnectionThread, getter_AddRefs(mConnectionEventQueue));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +158,8 @@ NS_IMETHODIMP
|
||||||
nsFTPChannel::Cancel(void)
|
nsFTPChannel::Cancel(void)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mThreadRequest)
|
if (mProxiedThreadRequest)
|
||||||
rv = mThreadRequest->Cancel();
|
rv = mProxiedThreadRequest->Cancel();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +167,8 @@ NS_IMETHODIMP
|
||||||
nsFTPChannel::Suspend(void)
|
nsFTPChannel::Suspend(void)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mThreadRequest)
|
if (mProxiedThreadRequest)
|
||||||
rv = mThreadRequest->Suspend();
|
rv = mProxiedThreadRequest->Suspend();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +176,8 @@ NS_IMETHODIMP
|
||||||
nsFTPChannel::Resume(void)
|
nsFTPChannel::Resume(void)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mThreadRequest)
|
if (mProxiedThreadRequest)
|
||||||
rv = mThreadRequest->Resume();
|
rv = mProxiedThreadRequest->Resume();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,40 +206,6 @@ NS_IMETHODIMP
|
||||||
nsFTPChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
nsFTPChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
||||||
nsIInputStream **_retval)
|
nsIInputStream **_retval)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
// The ftp channel will act as the listener which will receive
|
|
||||||
// events from the ftp connection thread. It then uses a syncstreamlistener
|
|
||||||
// as it's mListener which receives the listener notifications and writes
|
|
||||||
// data down the output stream end of a pipe.
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::OpenInputStream() called\n"));
|
|
||||||
|
|
||||||
rv = serv->NewSyncStreamListener(_retval /* nsIInputStream **inStream */,
|
|
||||||
&mBufferOutputStream /* nsIBufferOutputStream **outStream */,
|
|
||||||
&mListener/* nsIStreamListener **listener */);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
mSourceOffset = startPosition;
|
|
||||||
mAmount = readCount;
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//// setup the channel thread
|
|
||||||
|
|
||||||
nsIThread* workerThread = nsnull;
|
|
||||||
nsFtpConnectionThread* protocolInterpreter =
|
|
||||||
new nsFtpConnectionThread(mEventQueue, this, this, nsnull);
|
|
||||||
if (!protocolInterpreter)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
protocolInterpreter->Init(mURL);
|
|
||||||
protocolInterpreter->SetUsePasv(PR_TRUE);
|
|
||||||
|
|
||||||
rv = NS_NewThread(&workerThread, protocolInterpreter);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
#endif // 0
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,17 +230,24 @@ nsFTPChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
|
||||||
|
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::AsyncRead() called\n"));
|
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::AsyncRead() called\n"));
|
||||||
|
|
||||||
|
if (mEventSink) {
|
||||||
|
nsAutoString statusMsg("Beginning FTP transaction.");
|
||||||
|
#ifndef BUG_16273_FIXED //TODO
|
||||||
|
rv = mEventSink->OnStatus(this, ctxt, statusMsg.ToNewUnicode());
|
||||||
|
#else
|
||||||
|
rv = mEventSink->OnStatus(this, ctxt, statusMsg.GetUnicode());
|
||||||
|
#endif
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
//// setup channel state
|
//// setup channel state
|
||||||
|
|
||||||
// XXX we should be using these. esp. for FTP restart.
|
// XXX we should be using these. esp. for FTP restart.
|
||||||
mSourceOffset = startPosition;
|
mSourceOffset = startPosition;
|
||||||
mAmount = readCount;
|
mAmount = readCount;
|
||||||
|
|
||||||
mContext = ctxt;
|
mContext = ctxt;
|
||||||
|
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
|
|
||||||
mSourceOffset = startPosition;
|
mSourceOffset = startPosition;
|
||||||
mAmount = readCount;
|
mAmount = readCount;
|
||||||
|
|
||||||
|
@ -279,39 +258,19 @@ nsFTPChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
|
||||||
if (!protocolInterpreter) return NS_ERROR_OUT_OF_MEMORY;
|
if (!protocolInterpreter) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
NS_ADDREF(protocolInterpreter);
|
NS_ADDREF(protocolInterpreter);
|
||||||
|
|
||||||
rv = protocolInterpreter->Init(mConnectionEventQueue, /* FTP thread queue */
|
mThreadRequest = do_QueryInterface((nsISupports*)(nsIRequest*)protocolInterpreter, &rv);
|
||||||
mURL, /* url to load */
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = protocolInterpreter->Init(mURL, /* url to load */
|
||||||
mEventQueue, /* event queue for this thread */
|
mEventQueue, /* event queue for this thread */
|
||||||
mHandler,
|
mHandler,
|
||||||
this, ctxt);
|
this, ctxt, mEventSinkGetter);
|
||||||
|
mHandler = 0; // XXX this can go away when the channel is no longer being leaked.
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// create the proxy object so we can call into the FTP thread.
|
rv = mPool->DispatchRequest((nsIRunnable*)protocolInterpreter);
|
||||||
NS_WITH_SERVICE(nsIProxyObjectManager, proxyManager, kProxyObjectManagerCID, &rv);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = proxyManager->GetProxyObject(mConnectionEventQueue,
|
|
||||||
NS_GET_IID(nsIRequest),
|
|
||||||
(nsISupports*)(nsIRequest*)protocolInterpreter,
|
|
||||||
PROXY_SYNC | PROXY_ALWAYS,
|
|
||||||
getter_AddRefs(mThreadRequest));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = mConnectionThread->Init((nsIRunnable*)protocolInterpreter,
|
|
||||||
0, /* stack size */
|
|
||||||
PR_PRIORITY_NORMAL,
|
|
||||||
PR_GLOBAL_THREAD,
|
|
||||||
PR_UNJOINABLE_THREAD);
|
|
||||||
|
|
||||||
// this extra release is a result of a discussion with
|
|
||||||
// dougt. GetProxyObject is doing an extra addref. dougt
|
|
||||||
// can best explain why. If this is suddenly an *extra*
|
|
||||||
// release, yank it.
|
|
||||||
NS_RELEASE2(protocolInterpreter, rv);
|
|
||||||
NS_RELEASE(protocolInterpreter);
|
NS_RELEASE(protocolInterpreter);
|
||||||
mConnectionThread = 0; // this is necessary because there is a circular dependency
|
|
||||||
// between the FTPChannel and the connection thread.
|
|
||||||
// we need to ditch our ref to the connection thread asap.
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
mConnected = PR_TRUE;
|
mConnected = PR_TRUE;
|
||||||
|
@ -424,20 +383,22 @@ nsFTPChannel::SetOwner(nsISupports * aOwner)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsIFTPChannel methods:
|
// nsIFTPChannel methods:
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFTPChannel::Get(void) {
|
nsFTPChannel::SetConnectionQueue(nsIEventQueue *aEventQ) {
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
nsresult rv;
|
||||||
}
|
// create the proxy object so we can call into the FTP thread.
|
||||||
|
NS_WITH_SERVICE(nsIProxyObjectManager, proxyManager, kProxyObjectManagerCID, &rv);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
// change the thread request over to a proxy thread request.
|
||||||
nsFTPChannel::Put(void) {
|
rv = proxyManager->GetProxyObject(aEventQ,
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
NS_GET_IID(nsIRequest),
|
||||||
}
|
mThreadRequest,
|
||||||
|
PROXY_SYNC | PROXY_ALWAYS,
|
||||||
|
getter_AddRefs(mProxiedThreadRequest));
|
||||||
|
mThreadRequest = 0;
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsFTPChannel::SetStreamListener(nsIStreamListener *aListener) {
|
|
||||||
mListener = aListener;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +407,7 @@ nsFTPChannel::SetStreamListener(nsIStreamListener *aListener) {
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFTPChannel::OnStartRequest(nsIChannel* channel, nsISupports* context) {
|
nsFTPChannel::OnStartRequest(nsIChannel* channel, nsISupports* context) {
|
||||||
|
//MOZ_TIMER_START(channelTime, "nsFTPChannel::OnStart(): hit.");
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::OnStartRequest(channel = %x, context = %x)\n", channel, context));
|
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::OnStartRequest(channel = %x, context = %x)\n", channel, context));
|
||||||
if (mListener) {
|
if (mListener) {
|
||||||
|
@ -459,6 +421,15 @@ nsFTPChannel::OnStopRequest(nsIChannel* channel, nsISupports* context,
|
||||||
nsresult aStatus,
|
nsresult aStatus,
|
||||||
const PRUnichar* aMsg) {
|
const PRUnichar* aMsg) {
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
if (mEventSink) {
|
||||||
|
nsAutoString statusMsg("FTP transaction complete.");
|
||||||
|
#ifndef BUG_16273_FIXED //TODO
|
||||||
|
rv = mEventSink->OnStatus(this, context, statusMsg.ToNewUnicode());
|
||||||
|
#else
|
||||||
|
rv = mEventSink->OnStatus(this, context, statusMsg.GetUnicode());
|
||||||
|
#endif
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
}
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::OnStopRequest(channel = %x, context = %x, status = %d, msg = N/A)\n",channel, context, aStatus));
|
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::OnStopRequest(channel = %x, context = %x, status = %d, msg = N/A)\n",channel, context, aStatus));
|
||||||
if (mListener) {
|
if (mListener) {
|
||||||
rv = mListener->OnStopRequest(channel, mContext, aStatus, aMsg);
|
rv = mListener->OnStopRequest(channel, mContext, aStatus, aMsg);
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
#include "nsIFTPChannel.h"
|
#include "nsIFTPChannel.h"
|
||||||
#include "nsIStreamListener.h"
|
#include "nsIStreamListener.h"
|
||||||
#include "nsIThread.h"
|
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsString2.h"
|
#include "nsString2.h"
|
||||||
#include "nsIEventQueue.h"
|
#include "nsIEventQueue.h"
|
||||||
|
@ -32,6 +31,8 @@
|
||||||
#include "nsHashtable.h"
|
#include "nsHashtable.h"
|
||||||
#include "nsIProtocolHandler.h"
|
#include "nsIProtocolHandler.h"
|
||||||
#include "nsIProgressEventSink.h"
|
#include "nsIProgressEventSink.h"
|
||||||
|
#include "nsIEventSinkGetter.h"
|
||||||
|
#include "nsIThreadPool.h"
|
||||||
|
|
||||||
class nsIEventSinkGetter;
|
class nsIEventSinkGetter;
|
||||||
class nsIProgressEventSink;
|
class nsIProgressEventSink;
|
||||||
|
@ -59,13 +60,14 @@ public:
|
||||||
// join() it on shutdown.
|
// join() it on shutdown.
|
||||||
nsresult Init(const char* verb, nsIURI* uri, nsILoadGroup *aGroup,
|
nsresult Init(const char* verb, nsIURI* uri, nsILoadGroup *aGroup,
|
||||||
nsIEventSinkGetter* getter, nsIURI* originalURI,
|
nsIEventSinkGetter* getter, nsIURI* originalURI,
|
||||||
nsIProtocolHandler* aHandler);
|
nsIProtocolHandler* aHandler, nsIThreadPool* aPool);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIURI> mOriginalURI;
|
nsCOMPtr<nsIURI> mOriginalURI;
|
||||||
nsCOMPtr<nsIURI> mURL;
|
nsCOMPtr<nsIURI> mURL;
|
||||||
nsCOMPtr<nsIEventQueue> mEventQueue;
|
nsCOMPtr<nsIEventQueue> mEventQueue;
|
||||||
nsCOMPtr<nsIProgressEventSink> mEventSink;
|
nsCOMPtr<nsIProgressEventSink> mEventSink;
|
||||||
|
nsCOMPtr<nsIEventSinkGetter> mEventSinkGetter;
|
||||||
|
|
||||||
PRBool mConnected;
|
PRBool mConnected;
|
||||||
nsCOMPtr<nsIStreamListener> mListener;
|
nsCOMPtr<nsIStreamListener> mListener;
|
||||||
|
@ -78,11 +80,11 @@ protected:
|
||||||
nsAutoString mContentType;
|
nsAutoString mContentType;
|
||||||
PRInt32 mContentLength;
|
PRInt32 mContentLength;
|
||||||
nsCOMPtr<nsISupports> mOwner;
|
nsCOMPtr<nsISupports> mOwner;
|
||||||
nsCOMPtr<nsIThread> mConnectionThread; // the thread for this connection.
|
|
||||||
|
|
||||||
nsCOMPtr<nsIEventQueue> mConnectionEventQueue;
|
nsCOMPtr<nsIRequest> mThreadRequest;
|
||||||
nsCOMPtr<nsIRequest> mThreadRequest; // the nsIRequest proxy object.
|
nsCOMPtr<nsIRequest> mProxiedThreadRequest;
|
||||||
nsCOMPtr<nsIProtocolHandler> mHandler;
|
nsCOMPtr<nsIProtocolHandler> mHandler;
|
||||||
|
nsCOMPtr<nsIThreadPool> mPool; // the thread pool we want to use to fire off connections.
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NS_FTP_SEGMENT_SIZE (4*1024)
|
#define NS_FTP_SEGMENT_SIZE (4*1024)
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "nsProxiedService.h"
|
#include "nsProxiedService.h"
|
||||||
#include "nsINetSupportDialogService.h"
|
#include "nsINetSupportDialogService.h"
|
||||||
#include "nsFtpProtocolHandler.h"
|
#include "nsFtpProtocolHandler.h"
|
||||||
|
#include "nsIFTPChannel.h"
|
||||||
|
|
||||||
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||||
|
@ -104,8 +105,28 @@ NS_IMPL_ISUPPORTS(nsFTPContext, kIFTPContextIID);
|
||||||
|
|
||||||
|
|
||||||
// BEGIN: nsFtpConnectionThread implementation
|
// BEGIN: nsFtpConnectionThread implementation
|
||||||
|
NS_IMETHODIMP_(nsrefcnt) nsFtpConnectionThread::AddRef(void)
|
||||||
NS_IMPL_ISUPPORTS2(nsFtpConnectionThread, nsIRunnable, nsIRequest);
|
{
|
||||||
|
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
|
||||||
|
++mRefCnt;
|
||||||
|
NS_LOG_ADDREF(this, mRefCnt, "nsFtpConnectionThread", sizeof(*this));
|
||||||
|
return mRefCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP_(nsrefcnt) nsFtpConnectionThread::Release(void)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||||
|
--mRefCnt;
|
||||||
|
NS_LOG_RELEASE(this, mRefCnt, "nsFtpConnectionThread");
|
||||||
|
if (mRefCnt == 0) {
|
||||||
|
mRefCnt = 1; /* stabilize */
|
||||||
|
NS_DELETEXPCOM(this);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mRefCnt;
|
||||||
|
}
|
||||||
|
NS_IMPL_QUERY_INTERFACE2(nsFtpConnectionThread, nsIRunnable, nsIRequest);
|
||||||
|
//NS_IMPL_ISUPPORTS2(nsFtpConnectionThread, nsIRunnable, nsIRequest);
|
||||||
|
|
||||||
nsFtpConnectionThread::nsFtpConnectionThread() {
|
nsFtpConnectionThread::nsFtpConnectionThread() {
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
@ -119,7 +140,6 @@ nsFtpConnectionThread::nsFtpConnectionThread() {
|
||||||
mResetMode = PR_FALSE;
|
mResetMode = PR_FALSE;
|
||||||
mList = PR_FALSE;
|
mList = PR_FALSE;
|
||||||
mKeepRunning = PR_TRUE;
|
mKeepRunning = PR_TRUE;
|
||||||
mUseDefaultPath = PR_FALSE;
|
|
||||||
mContinueRead = PR_FALSE;
|
mContinueRead = PR_FALSE;
|
||||||
mAnonymous = PR_TRUE;
|
mAnonymous = PR_TRUE;
|
||||||
mRetryPass = PR_FALSE;
|
mRetryPass = PR_FALSE;
|
||||||
|
@ -253,7 +273,6 @@ nsFtpConnectionThread::Process() {
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("%x Process() - COMPLETE\n", mURL.get()));
|
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("%x Process() - COMPLETE\n", mURL.get()));
|
||||||
// push through all of the pertinent state into the cache entry;
|
// push through all of the pertinent state into the cache entry;
|
||||||
mConn->mCwd = mCwd;
|
mConn->mCwd = mCwd;
|
||||||
mConn->mUseDefaultPath = mUseDefaultPath;
|
|
||||||
rv = mConnCache->InsertConn(mCacheKey.GetBuffer(), mConn);
|
rv = mConnCache->InsertConn(mCacheKey.GetBuffer(), mConn);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
@ -866,12 +885,11 @@ nsFtpConnectionThread::R_syst() {
|
||||||
|
|
||||||
SetSystInternals(); // must be called first to setup member vars.
|
SetSystInternals(); // must be called first to setup member vars.
|
||||||
|
|
||||||
if (!mUseDefaultPath)
|
|
||||||
state = FindActionState();
|
|
||||||
|
|
||||||
// setup next state based on server type.
|
// setup next state based on server type.
|
||||||
if (mServerType == FTP_PETER_LEWIS_TYPE || mServerType == FTP_WEBSTAR_TYPE)
|
if (mServerType == FTP_PETER_LEWIS_TYPE || mServerType == FTP_WEBSTAR_TYPE)
|
||||||
state = FTP_S_MACB;
|
state = FTP_S_MACB;
|
||||||
|
else
|
||||||
|
state = FindActionState();
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -932,7 +950,6 @@ nsFtpConnectionThread::S_pwd() {
|
||||||
|
|
||||||
FTP_STATE
|
FTP_STATE
|
||||||
nsFtpConnectionThread::R_pwd() {
|
nsFtpConnectionThread::R_pwd() {
|
||||||
nsresult rv;
|
|
||||||
FTP_STATE state = FTP_ERROR;
|
FTP_STATE state = FTP_ERROR;
|
||||||
nsCAutoString lNewMsg(mResponseMsg);
|
nsCAutoString lNewMsg(mResponseMsg);
|
||||||
// fun response interpretation begins :)
|
// fun response interpretation begins :)
|
||||||
|
@ -971,53 +988,6 @@ nsFtpConnectionThread::R_pwd() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we only want to use the parent working directory (pwd) when
|
|
||||||
// the url supplied provides ambiguous path info (such as /./, or
|
|
||||||
// no slash at all.
|
|
||||||
|
|
||||||
if (mUseDefaultPath && mServerType != FTP_VMS_TYPE) {
|
|
||||||
mUseDefaultPath = PR_FALSE;
|
|
||||||
// we want to use the default path specified by the PWD command.
|
|
||||||
nsCAutoString ptr;
|
|
||||||
|
|
||||||
if (lNewMsg.First() != '/') {
|
|
||||||
PRInt32 start = lNewMsg.FindChar('/');
|
|
||||||
if (start > -1) {
|
|
||||||
lNewMsg.Right(ptr, start); // use everything after the first slash (inclusive)
|
|
||||||
} else {
|
|
||||||
// if we couldn't find a slash, check for back slashes and switch them out.
|
|
||||||
start = lNewMsg.FindChar('\\');
|
|
||||||
if (start > -1) {
|
|
||||||
lNewMsg.ReplaceChar("\\", '/');
|
|
||||||
}
|
|
||||||
ptr = lNewMsg;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ptr = lNewMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct the new url by appending
|
|
||||||
// the initial path to the new path.
|
|
||||||
if (ptr.Length()) {
|
|
||||||
|
|
||||||
nsXPIDLCString initialPath;
|
|
||||||
rv = mURL->GetPath(getter_Copies(initialPath));
|
|
||||||
if (NS_FAILED(rv)) return FTP_ERROR;
|
|
||||||
|
|
||||||
if (ptr.Last() == '/') {
|
|
||||||
PRUint32 insertionOffset = ptr.Length() - 1;
|
|
||||||
ptr.Cut(insertionOffset, 1);
|
|
||||||
ptr.Insert(initialPath, insertionOffset);
|
|
||||||
} else {
|
|
||||||
ptr.Append(initialPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *p = ptr.GetBuffer();
|
|
||||||
rv = mURL->SetPath(p);
|
|
||||||
if (NS_FAILED(rv)) return FTP_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// change state for these servers.
|
// change state for these servers.
|
||||||
if (mServerType == FTP_GENERIC_TYPE
|
if (mServerType == FTP_GENERIC_TYPE
|
||||||
|| mServerType == FTP_NCSA_TYPE
|
|| mServerType == FTP_NCSA_TYPE
|
||||||
|
@ -1280,7 +1250,8 @@ nsFtpConnectionThread::R_list() {
|
||||||
|
|
||||||
rv = StreamConvService->AsyncConvertData(fromStr.GetUnicode(),
|
rv = StreamConvService->AsyncConvertData(fromStr.GetUnicode(),
|
||||||
toStr.GetUnicode(),
|
toStr.GetUnicode(),
|
||||||
mSyncListener, mURL, getter_AddRefs(converterListener));
|
mSyncListener,
|
||||||
|
mURL, getter_AddRefs(converterListener));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return FTP_ERROR;
|
return FTP_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1511,7 +1482,9 @@ nsFtpConnectionThread::R_pasv() {
|
||||||
nsAllocator::Free(response);
|
nsAllocator::Free(response);
|
||||||
|
|
||||||
// now we know where to connect our data channel
|
// now we know where to connect our data channel
|
||||||
rv = mSTS->CreateTransport(host.GetBuffer(), port, nsnull, getter_AddRefs(mDPipe)); // the data channel
|
rv = mSTS->CreateTransport(host.GetBuffer(), port,
|
||||||
|
nsnull, /* don't push the event sink getter through for the data channel */
|
||||||
|
getter_AddRefs(mDPipe)); // the data channel
|
||||||
if (NS_FAILED(rv)) return FTP_ERROR;
|
if (NS_FAILED(rv)) return FTP_ERROR;
|
||||||
|
|
||||||
if (mAction == GET) {
|
if (mAction == GET) {
|
||||||
|
@ -1635,7 +1608,33 @@ nsFtpConnectionThread::R_mkdir() {
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFtpConnectionThread::Run() {
|
nsFtpConnectionThread::Run() {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = eventQService->CreateThreadEventQueue();
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = eventQService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(mFTPEventQueue));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// we've got to send the event queue for this sucker over to the
|
||||||
|
// channel's thread so he can post event back to us.
|
||||||
|
NS_WITH_SERVICE(nsIProxyObjectManager, pIProxyObjectManager, kProxyObjectManagerCID, &rv);
|
||||||
|
if(NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFTPChannel> ftpChannel;
|
||||||
|
rv = pIProxyObjectManager->GetProxyObject(mOutsideEventQueue,
|
||||||
|
NS_GET_IID(nsIFTPChannel),
|
||||||
|
mChannel,
|
||||||
|
PROXY_SYNC | PROXY_ALWAYS,
|
||||||
|
getter_AddRefs(ftpChannel));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = ftpChannel->SetConnectionQueue(mFTPEventQueue);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
|
||||||
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
|
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
|
||||||
NS_GET_IID(nsISocketTransportService),
|
NS_GET_IID(nsISocketTransportService),
|
||||||
(nsISupports **)&mSTS);
|
(nsISupports **)&mSTS);
|
||||||
|
@ -1666,10 +1665,9 @@ nsFtpConnectionThread::Run() {
|
||||||
mServerType = mConn->mServerType;
|
mServerType = mConn->mServerType;
|
||||||
mCwd = mConn->mCwd;
|
mCwd = mConn->mCwd;
|
||||||
mList = mConn->mList;
|
mList = mConn->mList;
|
||||||
mUseDefaultPath = mConn->mUseDefaultPath;
|
|
||||||
} else {
|
} else {
|
||||||
// build our own
|
// build our own
|
||||||
rv = mSTS->CreateTransport(host, port, nsnull, getter_AddRefs(mCPipe)); // the command channel
|
rv = mSTS->CreateTransport(host, port, mEventSinkGetter, getter_AddRefs(mCPipe)); // the command channel
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// get the output stream so we can write to the server
|
// get the output stream so we can write to the server
|
||||||
|
@ -1753,6 +1751,10 @@ nsFtpConnectionThread::Run() {
|
||||||
mConnected = PR_TRUE;
|
mConnected = PR_TRUE;
|
||||||
|
|
||||||
rv = Process();
|
rv = Process();
|
||||||
|
mListener = 0;
|
||||||
|
mSyncListener = 0;
|
||||||
|
mChannel = 0;
|
||||||
|
mConnCache = 0;
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -1822,43 +1824,52 @@ nsFtpConnectionThread::Resume(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFtpConnectionThread::Init(nsIEventQueue* aFTPEventQ,
|
nsFtpConnectionThread::Init(nsIURI* aUrl,
|
||||||
nsIURI* aUrl,
|
|
||||||
nsIEventQueue* aEventQ,
|
nsIEventQueue* aEventQ,
|
||||||
nsIProtocolHandler* aHandler,
|
nsIProtocolHandler* aHandler,
|
||||||
nsIChannel* aChannel,
|
nsIChannel* aChannel,
|
||||||
nsISupports* aContext) {
|
nsISupports* aContext,
|
||||||
|
nsIEventSinkGetter* aEventSinkGetter) {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
NS_ASSERTION(aFTPEventQ, "FTP: thread needs an event queue to process");
|
|
||||||
mFTPEventQueue = aFTPEventQ;
|
|
||||||
|
|
||||||
NS_ASSERTION(aChannel, "FTP: thread needs a channel");
|
NS_ASSERTION(aChannel, "FTP: thread needs a channel");
|
||||||
|
|
||||||
|
mOutsideEventQueue = aEventQ;
|
||||||
|
mEventSinkGetter = aEventSinkGetter;
|
||||||
|
|
||||||
NS_WITH_SERVICE(nsIProxyObjectManager, pIProxyObjectManager, kProxyObjectManagerCID, &rv);
|
NS_WITH_SERVICE(nsIProxyObjectManager, pIProxyObjectManager, kProxyObjectManagerCID, &rv);
|
||||||
if(NS_FAILED(rv)) return rv;
|
if(NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = pIProxyObjectManager->GetProxyObject(aEventQ,
|
rv = pIProxyObjectManager->GetProxyObject(mOutsideEventQueue,
|
||||||
NS_GET_IID(nsIStreamListener),
|
NS_GET_IID(nsIStreamListener),
|
||||||
aChannel,
|
aChannel,
|
||||||
PROXY_ASYNC | PROXY_ALWAYS,
|
PROXY_ASYNC | PROXY_ALWAYS,
|
||||||
getter_AddRefs(mListener));
|
getter_AddRefs(mListener));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = pIProxyObjectManager->GetProxyObject(aEventQ,
|
rv = pIProxyObjectManager->GetProxyObject(mOutsideEventQueue,
|
||||||
NS_GET_IID(nsIStreamListener),
|
NS_GET_IID(nsIStreamListener),
|
||||||
aChannel,
|
aChannel,
|
||||||
PROXY_SYNC | PROXY_ALWAYS,
|
PROXY_SYNC | PROXY_ALWAYS,
|
||||||
getter_AddRefs(mSyncListener));
|
getter_AddRefs(mSyncListener));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = pIProxyObjectManager->GetProxyObject(aEventQ,
|
rv = pIProxyObjectManager->GetProxyObject(mOutsideEventQueue,
|
||||||
NS_GET_IID(nsIChannel),
|
NS_GET_IID(nsIChannel),
|
||||||
aChannel,
|
aChannel,
|
||||||
PROXY_SYNC | PROXY_ALWAYS,
|
PROXY_SYNC | PROXY_ALWAYS,
|
||||||
getter_AddRefs(mChannel));
|
getter_AddRefs(mChannel));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// get a proxied ptr to the FTP protocol handler service so we can control
|
||||||
|
// the connection cache from here.
|
||||||
|
rv = pIProxyObjectManager->GetProxyObject(nsnull,
|
||||||
|
NS_GET_IID(nsIConnectionCache),
|
||||||
|
aHandler,
|
||||||
|
PROXY_SYNC | PROXY_ALWAYS,
|
||||||
|
getter_AddRefs(mConnCache));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
mContext = aContext;
|
mContext = aContext;
|
||||||
mURL = aUrl;
|
mURL = aUrl;
|
||||||
|
|
||||||
|
@ -1904,24 +1915,6 @@ nsFtpConnectionThread::Init(nsIEventQueue* aFTPEventQ,
|
||||||
getter_AddRefs(mConnCache));
|
getter_AddRefs(mConnCache));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// XXX this entire check can probably go away.
|
|
||||||
// figure out whether or not we want to use the default path supplied by the server.
|
|
||||||
// we want to do this when there's some ambiguity in our path.
|
|
||||||
nsXPIDLCString path;
|
|
||||||
rv = mURL->GetPath(getter_Copies(path));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
if (!path || !*path || !PL_strncmp(path, "/.", 2) ) {
|
|
||||||
// scoot past the '/.'
|
|
||||||
char *newPath = nsCRT::strdup((const char*)path+2);
|
|
||||||
if (!newPath) return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
rv = mURL->SetPath(newPath);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
mUseDefaultPath = PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "nsIRunnable.h"
|
#include "nsIRunnable.h"
|
||||||
#include "nsIRequest.h"
|
#include "nsIRequest.h"
|
||||||
#include "nsISocketTransportService.h"
|
#include "nsISocketTransportService.h"
|
||||||
|
#include "nsIEventSinkGetter.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsIStreamListener.h"
|
#include "nsIStreamListener.h"
|
||||||
#include "nsIOutputStream.h"
|
#include "nsIOutputStream.h"
|
||||||
|
@ -124,17 +125,16 @@ public:
|
||||||
nsFtpConnectionThread();
|
nsFtpConnectionThread();
|
||||||
virtual ~nsFtpConnectionThread();
|
virtual ~nsFtpConnectionThread();
|
||||||
|
|
||||||
nsresult Init(nsIEventQueue* aFTPEventQ,
|
nsresult Init(nsIURI* aUrl,
|
||||||
nsIURI* aUrl,
|
|
||||||
nsIEventQueue* aEventQ,
|
nsIEventQueue* aEventQ,
|
||||||
nsIProtocolHandler* aHandler,
|
nsIProtocolHandler* aHandler,
|
||||||
nsIChannel* channel,
|
nsIChannel* channel,
|
||||||
nsISupports* ctxt);
|
nsISupports* ctxt,
|
||||||
|
nsIEventSinkGetter* aEventSink);
|
||||||
nsresult Process();
|
nsresult Process();
|
||||||
|
|
||||||
// user level setup
|
// user level setup
|
||||||
nsresult SetAction(FTP_ACTION aAction);
|
nsresult SetAction(FTP_ACTION aAction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
@ -187,6 +187,7 @@ private:
|
||||||
// Private members
|
// Private members
|
||||||
|
|
||||||
nsCOMPtr<nsIEventQueue> mFTPEventQueue; // the eventq for this thread.
|
nsCOMPtr<nsIEventQueue> mFTPEventQueue; // the eventq for this thread.
|
||||||
|
nsCOMPtr<nsIEventQueue> mOutsideEventQueue; // the eventq for the using thread.
|
||||||
nsCOMPtr<nsIURI> mURL;
|
nsCOMPtr<nsIURI> mURL;
|
||||||
|
|
||||||
FTP_STATE mState; // the current state
|
FTP_STATE mState; // the current state
|
||||||
|
@ -223,7 +224,6 @@ private:
|
||||||
nsCAutoString mCacheKey; // the key into the cache hash.
|
nsCAutoString mCacheKey; // the key into the cache hash.
|
||||||
|
|
||||||
PRBool mConnected;
|
PRBool mConnected;
|
||||||
PRBool mUseDefaultPath; // use PWD to figure out path
|
|
||||||
PRBool mUsePasv; // use a passive data connection.
|
PRBool mUsePasv; // use a passive data connection.
|
||||||
PRBool mDirectory; // this url is a directory
|
PRBool mDirectory; // this url is a directory
|
||||||
PRBool mBin; // transfer mode (ascii or binary)
|
PRBool mBin; // transfer mode (ascii or binary)
|
||||||
|
@ -248,6 +248,7 @@ private:
|
||||||
|
|
||||||
nsString2 mContentType; // the content type of the data we're dealing w/.
|
nsString2 mContentType; // the content type of the data we're dealing w/.
|
||||||
nsXPIDLCString mURLSpec;
|
nsXPIDLCString mURLSpec;
|
||||||
|
nsCOMPtr<nsIEventSinkGetter> mEventSinkGetter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NS_FTP_BUFFER_READ_SIZE (8*1024)
|
#define NS_FTP_BUFFER_READ_SIZE (8*1024)
|
||||||
|
|
|
@ -50,6 +50,9 @@ static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
|
||||||
nsFtpProtocolHandler::nsFtpProtocolHandler() {
|
nsFtpProtocolHandler::nsFtpProtocolHandler() {
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
NS_NEWXPCOM(mRootConnectionList, nsHashtable);
|
NS_NEWXPCOM(mRootConnectionList, nsHashtable);
|
||||||
|
NS_NewThreadPool(getter_AddRefs(mPool), NS_FTP_CONNECTION_COUNT,
|
||||||
|
NS_FTP_CONNECTION_COUNT,
|
||||||
|
NS_FTP_CONNECTION_STACK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleans up a connection list entry
|
// cleans up a connection list entry
|
||||||
|
@ -64,7 +67,30 @@ nsFtpProtocolHandler::~nsFtpProtocolHandler() {
|
||||||
NS_DELETEXPCOM(mRootConnectionList);
|
NS_DELETEXPCOM(mRootConnectionList);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsFtpProtocolHandler, nsIProtocolHandler, nsIConnectionCache);
|
|
||||||
|
NS_IMETHODIMP_(nsrefcnt) nsFtpProtocolHandler::AddRef(void)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
|
||||||
|
++mRefCnt;
|
||||||
|
NS_LOG_ADDREF(this, mRefCnt, "nsFtpProtocolHandler", sizeof(*this));
|
||||||
|
return mRefCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP_(nsrefcnt) nsFtpProtocolHandler::Release(void)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||||
|
--mRefCnt;
|
||||||
|
NS_LOG_RELEASE(this, mRefCnt, "nsFtpProtocolHandler");
|
||||||
|
if (mRefCnt == 0) {
|
||||||
|
mRefCnt = 1; /* stabilize */
|
||||||
|
NS_DELETEXPCOM(this);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mRefCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_QUERY_INTERFACE2(nsFtpProtocolHandler, nsIProtocolHandler, nsIConnectionCache);
|
||||||
|
//NS_IMPL_ISUPPORTS2(nsFtpProtocolHandler, nsIProtocolHandler, nsIConnectionCache);
|
||||||
|
|
||||||
NS_METHOD
|
NS_METHOD
|
||||||
nsFtpProtocolHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
nsFtpProtocolHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||||
|
@ -181,7 +207,7 @@ nsFtpProtocolHandler::NewChannel(const char* verb, nsIURI* url,
|
||||||
rv = nsFTPChannel::Create(nsnull, NS_GET_IID(nsIFTPChannel), (void**)&channel);
|
rv = nsFTPChannel::Create(nsnull, NS_GET_IID(nsIFTPChannel), (void**)&channel);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = channel->Init(verb, url, aGroup, eventSinkGetter, originalURI, this);
|
rv = channel->Init(verb, url, aGroup, eventSinkGetter, originalURI, this, mPool);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_RELEASE(channel);
|
NS_RELEASE(channel);
|
||||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFtpProtocolHandler::NewChannel() FAILED\n"));
|
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFtpProtocolHandler::NewChannel() FAILED\n"));
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "nsVoidArray.h"
|
#include "nsVoidArray.h"
|
||||||
#include "nsIConnectionCache.h"
|
#include "nsIConnectionCache.h"
|
||||||
#include "nsConnectionCacheObj.h"
|
#include "nsConnectionCacheObj.h"
|
||||||
|
#include "nsIThreadPool.h"
|
||||||
|
|
||||||
// {25029490-F132-11d2-9588-00805F369F95}
|
// {25029490-F132-11d2-9588-00805F369F95}
|
||||||
#define NS_FTPPROTOCOLHANDLER_CID \
|
#define NS_FTPPROTOCOLHANDLER_CID \
|
||||||
|
@ -52,6 +53,10 @@ public:
|
||||||
protected:
|
protected:
|
||||||
nsISupports* mEventSinkGetter;
|
nsISupports* mEventSinkGetter;
|
||||||
nsHashtable* mRootConnectionList; // hash of FTP connections
|
nsHashtable* mRootConnectionList; // hash of FTP connections
|
||||||
|
nsCOMPtr<nsIThreadPool> mPool; // thread pool for FTP connections
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NS_FTP_CONNECTION_COUNT 6
|
||||||
|
#define NS_FTP_CONNECTION_STACK_SIZE (64 * 1024)
|
||||||
|
|
||||||
#endif /* nsFtpProtocolHandler_h___ */
|
#endif /* nsFtpProtocolHandler_h___ */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче