91019 "BSD Type: L8" alert msg when clicking download link
59039 FTP should proxy back nsIPrompt like HTTP
84525 Not handling 421 error on connect
86369 ftp hangs in CWD
84854 ftp pages are not cached so going backforth is slow
77032 Logging should not log users password!
88482 nsFTPChannel::IsPending() needs to be implemented

Biggest change adds ftp cacheing. r=bbaetz@netscape.com, sr=darin@netscape.com
This commit is contained in:
dougt%netscape.com 2001-07-24 22:51:06 +00:00
Родитель 336ee9504c
Коммит 0714ae9359
6 изменённых файлов: 373 добавлений и 99 удалений

Просмотреть файл

@ -28,6 +28,7 @@
#include "nsIMIMEService.h"
#include "nsNetUtil.h"
#include "nsMimeTypes.h"
#include "nsIProxyObjectManager.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
@ -35,6 +36,22 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
extern PRLogModuleInfo* gFTPLog;
#endif /* PR_LOGGING */
////////////// this needs to move to nspr
static inline PRUint32
PRTimeToSeconds(PRTime t_usec)
{
PRTime usec_per_sec;
PRUint32 t_sec;
LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
LL_DIV(t_usec, t_usec, usec_per_sec);
LL_L2I(t_sec, t_usec);
return t_sec;
}
#define NowInSeconds() PRTimeToSeconds(PR_Now())
////////////// end
// There are two transport connections established for an
// ftp connection. One is used for the command channel , and
// the other for the data channel. The command channel is the first
@ -44,7 +61,8 @@ extern PRLogModuleInfo* gFTPLog;
// Client initiation is the most common case and is attempted first.
nsFTPChannel::nsFTPChannel()
: mLoadFlags(LOAD_NORMAL),
: mIsPending(0),
mLoadFlags(LOAD_NORMAL),
mSourceOffset(0),
mAmount(0),
mContentLength(-1),
@ -67,17 +85,18 @@ nsFTPChannel::~nsFTPChannel()
if (mLock) PR_DestroyLock(mLock);
}
NS_IMPL_THREADSAFE_ISUPPORTS7(nsFTPChannel,
NS_IMPL_THREADSAFE_ISUPPORTS8(nsFTPChannel,
nsIChannel,
nsIFTPChannel,
nsIRequest,
nsIInterfaceRequestor,
nsIProgressEventSink,
nsIStreamListener,
nsIRequestObserver);
nsIRequestObserver,
nsICacheListener);
nsresult
nsFTPChannel::Init(nsIURI* uri)
nsFTPChannel::Init(nsIURI* uri, nsICacheSession* session)
{
nsresult rv = NS_OK;
@ -94,6 +113,8 @@ nsFTPChannel::Init(nsIURI* uri)
mIOService = do_GetIOService(&rv);
if (NS_FAILED(rv)) return rv;
mCacheSession = session;
return NS_OK;
}
@ -135,9 +156,8 @@ nsFTPChannel::GetName(PRUnichar* *result)
NS_IMETHODIMP
nsFTPChannel::IsPending(PRBool *result) {
nsAutoLock lock(mLock);
NS_NOTREACHED("nsFTPChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
*result = mIsPending;
return NS_OK;
}
NS_IMETHODIMP
@ -166,7 +186,7 @@ nsFTPChannel::Cancel(nsresult status) {
mStatus = status;
if (mFTPState)
return mFTPState->Cancel(status);
(void)mFTPState->Cancel(status);
return NS_OK;
}
@ -230,6 +250,23 @@ nsFTPChannel::Open(nsIInputStream **result)
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsFTPChannel::GenerateCacheKey(nsACString &cacheKey)
{
cacheKey.SetLength(0);
nsXPIDLCString spec;
mURL->GetSpec(getter_Copies(spec));
// Strip any trailing #ref from the URL before using it as the key
const char *p = PL_strchr(spec, '#');
if (p)
cacheKey.Append(spec, p - spec);
else
cacheKey.Append(spec);
return NS_OK;
}
NS_IMETHODIMP
nsFTPChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
@ -252,20 +289,51 @@ nsFTPChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
rv = mLoadGroup->AddRequest(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
PRBool offline;
////////////////////////////////
//// setup the channel thread
if (mCacheSession) {
mIOService->GetOffline(&offline);
// Set the desired cache access mode accordingly...
nsCacheAccessMode accessRequested;
if (offline) {
// Since we are offline, we can only read from the cache.
accessRequested = nsICache::ACCESS_READ;
}
else if (mLoadFlags & LOAD_BYPASS_CACHE)
accessRequested = nsICache::ACCESS_WRITE; // replace cache entry
else
accessRequested = nsICache::ACCESS_READ_WRITE; // normal browsing
nsCAutoString cacheKey;
GenerateCacheKey(cacheKey);
return mCacheSession->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
}
return SetupState();
}
nsresult
nsFTPChannel::SetupState()
{
if (!mFTPState) {
NS_NEWXPCOM(mFTPState, nsFtpState);
if (!mFTPState) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mFTPState);
}
rv = mFTPState->Init(this, mPrompter, mAuthPrompter, mFTPEventSink);
nsresult rv = mFTPState->Init(this,
mPrompter,
mAuthPrompter,
mFTPEventSink,
mCacheEntry);
if (NS_FAILED(rv)) return rv;
rv = mFTPState->Connect();
return rv;
if (NS_FAILED(rv)) return rv;
mIsPending = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
@ -381,21 +449,59 @@ nsFTPChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallb
{
mCallbacks = aNotificationCallbacks;
// FIX these should be proxies!
if (mCallbacks) {
// nsIProgressEventSink
nsCOMPtr<nsIProgressEventSink> sink;
(void)mCallbacks->GetInterface(NS_GET_IID(nsIProgressEventSink),
getter_AddRefs(mEventSink));
getter_AddRefs(sink));
(void)mCallbacks->GetInterface(NS_GET_IID(nsIPrompt),
getter_AddRefs(mPrompter));
NS_ASSERTION ( mPrompter, "Channel doesn't have a prompt!!!" );
if (sink)
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIProgressEventSink),
sink,
PROXY_ASYNC | PROXY_ALWAYS,
getter_AddRefs(mEventSink));
(void)mCallbacks->GetInterface(NS_GET_IID(nsIFTPEventSink),
getter_AddRefs(mFTPEventSink));
// nsIFTPEventSink
nsCOMPtr<nsIFTPEventSink> ftpSink;
(void)mCallbacks->GetInterface(NS_GET_IID(nsIFTPEventSink),
getter_AddRefs(ftpSink));
if (ftpSink)
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIFTPEventSink),
sink,
PROXY_ASYNC | PROXY_ALWAYS,
getter_AddRefs(mFTPEventSink));
// nsIPrompt
nsCOMPtr<nsIPrompt> prompt;
(void)mCallbacks->GetInterface(NS_GET_IID(nsIPrompt),
getter_AddRefs(prompt));
NS_ASSERTION ( prompt, "Channel doesn't have a prompt!!!" );
if (prompt)
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIPrompt),
prompt,
PROXY_SYNC,
getter_AddRefs(mPrompter));
// nsIAuthPrompt
nsCOMPtr<nsIAuthPrompt> aPrompt;
(void)mCallbacks->GetInterface(NS_GET_IID(nsIAuthPrompt),
getter_AddRefs(mAuthPrompter));
NS_ASSERTION ( mAuthPrompter, "Channel doesn't have an auth prompt!!!" );
getter_AddRefs(aPrompt));
if (aPrompt)
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIAuthPrompt),
aPrompt,
PROXY_SYNC,
getter_AddRefs(mAuthPrompter));
}
return NS_OK;
}
@ -467,18 +573,29 @@ nsFTPChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
mStatus = aStatus;
if (mObserver) {
rv = mObserver->OnStopRequest(this, mUserContext, aStatus);
if (NS_FAILED(rv)) return rv;
(void) mObserver->OnStopRequest(this, mUserContext, aStatus);
}
if (mListener) {
rv = mListener->OnStopRequest(this, mUserContext, aStatus);
if (NS_FAILED(rv)) return rv;
(void) mListener->OnStopRequest(this, mUserContext, aStatus);
}
if (mLoadGroup) {
rv = mLoadGroup->RemoveRequest(this, nsnull, aStatus);
if (NS_FAILED(rv)) return rv;
(void) mLoadGroup->RemoveRequest(this, nsnull, aStatus);
}
if (mCacheEntry) {
if (NS_SUCCEEDED(aStatus)) {
(void) mCacheEntry->SetExpirationTime( NowInSeconds() + 900 ); // valid for 15 minutes.
(void) mCacheEntry->MarkValid();
}
else {
(void) mCacheEntry->Doom();
}
mCacheEntry->Close();
mCacheEntry = 0;
}
mIsPending = PR_FALSE;
return rv;
}
@ -511,3 +628,26 @@ nsFTPChannel::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
PRUint32 aLength) {
return mListener->OnDataAvailable(this, mUserContext, aInputStream, aSourceOffset, aLength);
}
//-----------------------------------------------------------------------------
// nsFTPChannel::nsICacheListener
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsFTPChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
nsCacheAccessMode access,
nsresult status)
{
nsresult rv;
if (NS_SUCCEEDED(status)) {
mCacheEntry = entry;
}
rv = SetupState();
if (NS_FAILED(rv)) {
Cancel(rv);
}
return NS_OK;
}

Просмотреть файл

@ -43,6 +43,11 @@
#include "nsIAuthPrompt.h"
#include "nsIFTPChannel.h"
#include "nsICacheService.h"
#include "nsICacheEntryDescriptor.h"
#include "nsICacheListener.h"
#include "nsICacheSession.h"
#define FTP_COMMAND_CHANNEL_SEG_SIZE 64
#define FTP_COMMAND_CHANNEL_MAX_SIZE 512
@ -54,7 +59,9 @@
class nsFTPChannel : public nsIFTPChannel,
public nsIInterfaceRequestor,
public nsIProgressEventSink,
public nsIStreamListener {
public nsIStreamListener,
public nsICacheListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
@ -64,6 +71,7 @@ public:
NS_DECL_NSIPROGRESSEVENTSINK
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSICACHELISTENER
// nsFTPChannel methods:
nsFTPChannel();
@ -74,7 +82,10 @@ public:
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
// initializes the channel.
nsresult Init(nsIURI* uri);
nsresult Init(nsIURI* uri, nsICacheSession* session);
nsresult SetupState();
nsresult GenerateCacheKey(nsACString &cacheKey);
protected:
@ -88,7 +99,7 @@ protected:
nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
PRBool mConnected;
PRBool mIsPending;
PRUint32 mLoadFlags;
PRUint32 mSourceOffset;
@ -110,6 +121,10 @@ protected:
PRPackedBool mCanceled;
nsCOMPtr<nsIIOService> mIOService;
nsCOMPtr<nsICacheSession> mCacheSession;
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
};
#endif /* nsFTPChannel_h___ */

Просмотреть файл

@ -47,17 +47,21 @@
#include "nsMimeTypes.h"
#include "nsIStringBundle.h"
#include "nsICacheEntryDescriptor.h"
#include "nsICacheListener.h"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kWalletServiceCID, NS_WALLETSERVICE_CID);
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
#if defined(PR_LOGGING)
extern PRLogModuleInfo* gFTPLog;
#endif /* PR_LOGGING */
class DataRequestForwarder : public nsIFTPChannel,
public nsIStreamListener,
public nsIInterfaceRequestor,
@ -69,7 +73,8 @@ public:
nsresult Init(nsIRequest *request);
nsresult SetStreamListener(nsIStreamListener *listener);
nsresult SetCacheEntry(nsICacheEntryDescriptor *entry);
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
@ -84,10 +89,11 @@ public:
protected:
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIFTPChannel> mFTPChannel;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsIProgressEventSink> mEventSink;
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIFTPChannel> mFTPChannel;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsIProgressEventSink> mEventSink;
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
nsresult DelayedOnStartRequest(nsIRequest *request, nsISupports *ctxt);
PRBool mDelayedOnStartFired;
@ -155,6 +161,35 @@ DataRequestForwarder::Init(nsIRequest *request)
return NS_OK;
}
nsresult
DataRequestForwarder::SetCacheEntry(nsICacheEntryDescriptor *cacheEntry)
{
// if there is a cache entry descriptor, send data to it.
if (!cacheEntry)
return NS_ERROR_FAILURE;
mCacheEntry = cacheEntry;
nsCOMPtr<nsITransport> cacheTransport;
nsresult rv = cacheEntry->GetTransport(getter_AddRefs(cacheTransport));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIOutputStream> out;
rv = cacheTransport->OpenOutputStream(0, PRUint32(-1), 0, getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamListenerTee> tee =
do_CreateInstance(kStreamListenerTeeCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = tee->Init(mListener, out);
if (NS_FAILED(rv)) return rv;
mListener = do_QueryInterface(tee, &rv);
return NS_OK;
}
nsresult
DataRequestForwarder::SetStreamListener(nsIStreamListener *listener)
{
@ -195,7 +230,6 @@ DataRequestForwarder::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsre
if (sTrans)
sTrans->SetReuseConnection(PR_FALSE);
}
if (mListener)
return mListener->OnStopRequest(this, ctxt, statusCode);
@ -828,6 +862,10 @@ return rv;
///////////////////////////////////
nsresult
nsFtpState::S_user() {
// some servers on connect send us a 421. (84525)
if (mResponseCode == 421)
return NS_ERROR_FAILURE;
nsresult rv;
nsCAutoString usernameStr("USER ");
@ -1013,7 +1051,9 @@ nsFtpState::S_syst() {
FTP_STATE
nsFtpState::R_syst() {
if (mResponseCode/100 == 2) {
if (mResponseMsg.Find("UNIX") > -1) {
if (( mResponseMsg.Find("UNIX") > -1) ||
( mResponseMsg.Find("BSD") > -1) ) // non standard response (91019)
{
mServerType = FTP_UNIX_TYPE;
}
else if ( ( mResponseMsg.Find("WIN32", PR_TRUE) > -1) ||
@ -1111,7 +1151,7 @@ nsFtpState::R_size() {
}
if (mResponseCode == 550) // File unavailable (e.g., file not found, no access).
return FTP_S_RETR;
return FTP_S_RETR; // Even if the file reports zero size, lets try retr (91292)
// if we tried downloading this, lets try restarting it...
if (mDRequestForwarder && mDRequestForwarder->GetBytesTransfered() > 0)
@ -1120,28 +1160,42 @@ nsFtpState::R_size() {
return FTP_S_RETR;
}
nsresult
nsFtpState::SetContentType()
{
if (mGenerateRawContent) {
nsAutoString fromStr(NS_LITERAL_STRING("text/ftp-dir-"));
SetDirMIMEType(fromStr);
nsCAutoString contentType;contentType.AssignWithConversion(fromStr);
return mChannel->SetContentType(contentType);
}
if (mGenerateHTMLContent)
return mChannel->SetContentType("text/html");
return mChannel->SetContentType("application/http-index-format");
}
nsresult
nsFtpState::S_list() {
nsresult rv;
if (!mDRequestForwarder)
return NS_ERROR_FAILURE;
if (mGenerateRawContent) {
nsAutoString fromStr(NS_LITERAL_STRING("text/ftp-dir-"));
SetDirMIMEType(fromStr);
nsCAutoString contentType;contentType.AssignWithConversion(fromStr);
rv = mChannel->SetContentType(contentType);
}
else if (mGenerateHTMLContent)
rv = mChannel->SetContentType("text/html");
else
rv = mChannel->SetContentType("application/http-index-format");
rv = SetContentType();
if (NS_FAILED(rv))
return FTP_ERROR;
// save off the server type if we are caching.
if(mCacheEntry) {
nsCAutoString serverType;
serverType.AppendInt(mServerType);
(void) mCacheEntry->SetMetaDataElement("servertype", serverType);
}
nsCOMPtr<nsIStreamListener> converter;
rv = BuildStreamConverter(getter_AddRefs(converter));
@ -1157,7 +1211,8 @@ nsFtpState::S_list() {
// to the channel. Lets hijack and send the notifications
// to the stream converter.
mDRequestForwarder->SetStreamListener(converter);
mDRequestForwarder->SetCacheEntry(mCacheEntry);
nsCAutoString listString("LIST" CRLF);
return SendFTPCommand(listString);
@ -1579,7 +1634,8 @@ nsresult
nsFtpState::Init(nsIFTPChannel* aChannel,
nsIPrompt* aPrompter,
nsIAuthPrompt* aAuthPrompter,
nsIFTPEventSink* sink)
nsIFTPEventSink* sink,
nsICacheEntryDescriptor* cacheEntry)
{
nsresult rv = NS_OK;
@ -1587,7 +1643,8 @@ nsFtpState::Init(nsIFTPChannel* aChannel,
mPrompter = aPrompter;
mFTPEventSink = sink;
mAuthPrompter = aAuthPrompter;
mCacheEntry = cacheEntry;
// parameter validation
NS_ASSERTION(aChannel, "FTP: needs a channel");
@ -1595,7 +1652,47 @@ nsFtpState::Init(nsIFTPChannel* aChannel,
rv = aChannel->GetURI(getter_AddRefs(mURL));
if (NS_FAILED(rv)) return rv;
if (mCacheEntry) {
nsCacheAccessMode access;
mCacheEntry->GetAccessGranted(&access);
if (access & nsICache::ACCESS_READ) {
// make sure the channel knows wassup
SetContentType();
NS_ASSERTION(!mDRequestForwarder, "there should not be a data forwarder");
mDRequestForwarder = new DataRequestForwarder;
if (!mDRequestForwarder) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mDRequestForwarder);
rv = mDRequestForwarder->Init(mChannel);
nsXPIDLCString serverType;
(void) mCacheEntry->GetMetaDataElement("servertype", getter_Copies(serverType));
nsCAutoString serverNum(serverType.get());
PRInt32 err;
mServerType = serverNum.ToInteger(&err);
nsCOMPtr<nsIStreamListener> converter;
rv = BuildStreamConverter(getter_AddRefs(converter));
if (NS_FAILED(rv)) return rv;
mDRequestForwarder->SetStreamListener(converter);
mDRequestForwarder->SetCacheEntry(mCacheEntry);
// Get a transport to the cached data...
nsCOMPtr<nsITransport> transport;
rv = mCacheEntry->GetTransport(getter_AddRefs(transport));
if (NS_FAILED(rv)) return rv;
// Pump the cache data downstream
return transport->AsyncRead(mDRequestForwarder,
nsnull,
0, PRUint32(-1), 0,
getter_AddRefs(mDPipeRequest));
}
}
char *path = nsnull;
nsCOMPtr<nsIURL> aURL(do_QueryInterface(mURL));
@ -1644,6 +1741,9 @@ nsFtpState::Init(nsIFTPChannel* aChannel,
nsresult
nsFtpState::Connect()
{
if (mDRequestForwarder)
return NS_OK; // we are already connected.
nsresult rv;
mState = FTP_COMMAND_CONNECT;
@ -1729,11 +1829,7 @@ nsFtpState::StopProcessing() {
#ifdef DEBUG_dougt
printf("FTP Stopped: [response code %d] [response msg follows:]\n%s\n", mResponseCode, mResponseMsg.get());
#endif
// Lets mask the FTP error code so that a client does not have to parse it
nsresult broadcastErrorCode = NS_BINDING_ABORTED;
// did the protocol fail?
if ( NS_FAILED(mInternalError) && mResponseMsg.Length())
{
// check to see if the control status is bad.
@ -1744,29 +1840,27 @@ nsFtpState::StopProcessing() {
NS_ASSERTION(mPrompter, "no prompter!");
if (mPrompter)
(void) mPrompter->Alert(nsnull, text.get());
#if DEBUG
else
printf("NO ALERT! FTP error: %s", text.get());
#endif
}
if ( NS_FAILED(mControlStatus) ) {
broadcastErrorCode = mControlStatus;
nsresult broadcastErrorCode = NS_OK;
if ( NS_FAILED(mControlStatus) || NS_FAILED(mInternalError)) {
// Lets mask the FTP error code so that a client does not have to parse it
broadcastErrorCode = NS_BINDING_ABORTED;
}
if (mFireCallbacks && mChannel) {
nsCOMPtr<nsIStreamListener> channelListener = do_QueryInterface(mChannel);
nsCOMPtr<nsIRequest> channelRequest = do_QueryInterface(mChannel);
NS_ASSERTION(channelListener && channelRequest, "ftp channel better have these interfaces");
nsCOMPtr<nsIStreamListener> asyncListener;
rv = NS_NewAsyncStreamListener(getter_AddRefs(asyncListener), channelListener, NS_UI_THREAD_EVENTQ);
if(NS_FAILED(rv)) return rv;
//(void) asyncListener->OnStartRequest(channelRequest, nsnull);
(void) asyncListener->OnStopRequest(channelRequest, nsnull, broadcastErrorCode);
if(asyncListener) {
(void) asyncListener->OnStartRequest(channelRequest, nsnull);
(void) asyncListener->OnStopRequest(channelRequest, nsnull, broadcastErrorCode);
}
}
// Clean up the event loop
mKeepRunning = PR_FALSE;
@ -1774,9 +1868,7 @@ nsFtpState::StopProcessing() {
nsCOMPtr<nsIProgressEventSink> sink(do_QueryInterface(mChannel));
if (sink)
// parameter can be null cause the channel fills them in.
sink->OnStatus(nsnull, nsnull,
NS_NET_STATUS_END_FTP_TRANSACTION, nsnull);
sink->OnStatus(nsnull, nsnull, NS_NET_STATUS_END_FTP_TRANSACTION, nsnull);
// Release the Observers
mWriteStream = 0;
@ -1887,18 +1979,15 @@ nsresult
nsFtpState::SendFTPCommand(nsCString& command)
{
NS_ASSERTION(mControlConnection, "null control connection");
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x) Writing \"%s\"\n", this, command.get()));
if (mFTPEventSink) {
if (command.CompareWithConversion("PASS ", PR_FALSE, 5) == 0)
{
mFTPEventSink->OnFTPControlLog(PR_FALSE, "PASS ");
}
else
{
mFTPEventSink->OnFTPControlLog(PR_FALSE, command.get());
}
}
// we don't want to log the password:
nsCAutoString logcmd(command);
if (command.CompareWithConversion("PASS ", PR_FALSE, 5) == 0)
logcmd = "PASS xxxxx";
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x)(dwait=%d) Writing \"%s\"\n", this, mWaitingForDConn, logcmd.get()));
if (mFTPEventSink)
mFTPEventSink->OnFTPControlLog(PR_FALSE, logcmd.get());
if (mControlConnection) {
return mControlConnection->Write(command, mWaitingForDConn);

Просмотреть файл

@ -46,11 +46,7 @@
#include "nsFtpControlConnection.h"
#ifdef DOUGT_NEW_CACHE
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsICacheEntryDescriptor.h"
#endif
// ftp server types
#define FTP_GENERIC_TYPE 0
@ -98,7 +94,11 @@ public:
nsFtpState();
virtual ~nsFtpState();
nsresult Init(nsIFTPChannel *aChannel, nsIPrompt *aPrompter, nsIAuthPrompt *aAuthPrompter, nsIFTPEventSink *sink);
nsresult Init(nsIFTPChannel *aChannel,
nsIPrompt *aPrompter,
nsIAuthPrompt *aAuthPrompter,
nsIFTPEventSink *sink,
nsICacheEntryDescriptor* cacheEntry);
// use this to provide a stream to be written to the server.
nsresult SetWriteStream(nsIInputStream* aInStream, PRUint32 aWriteCount);
@ -143,6 +143,7 @@ private:
nsresult EstablishControlConnection();
nsresult SendFTPCommand(nsCString& command);
nsresult BuildStreamConverter(nsIStreamListener** convertStreamListener);
nsresult SetContentType();
///////////////////////////////////
// Private members
@ -207,12 +208,8 @@ private:
PRPackedBool mControlReadContinue;
PRPackedBool mControlReadBrokenLine;
nsCAutoString mControlReadCarryOverBuf;
#ifdef DOUGT_NEW_CACHE
nsCOMPtr<nsICacheSession> mCacheSession;
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
PRPackedBool mReadingFromCache;
#endif
};

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
#include "prlog.h"
#include "nsIPref.h"
#include "nsNetUtil.h"
// For proxification of FTP URLs
@ -68,6 +69,8 @@ static NS_DEFINE_IID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kHttpHandlerCID, NS_HTTPPROTOCOLHANDLER_CID);
static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
nsSupportsHashtable* nsFtpProtocolHandler::mRootConnectionList = nsnull;
////////////////////////////////////////////////////////////////////////////////
@ -158,7 +161,34 @@ nsFtpProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result)
rv = nsFTPChannel::Create(nsnull, NS_GET_IID(nsIChannel), (void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(url);
static PRBool checkedPref = PR_FALSE;
static PRBool useCache = PR_TRUE;
if (!checkedPref) {
// XXX should register a prefs changed callback for this
nsCOMPtr<nsIPref> prefs = do_GetService(kPrefServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
prefs->GetBoolPref("browser.cache.enable", &useCache);
checkedPref = PR_TRUE;
}
if (useCache && !mCacheSession) {
nsCOMPtr<nsICacheService> serv = do_GetService(kCacheServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = serv->CreateSession("FTP",
nsICache::STORE_ANYWHERE,
nsICache::STREAM_BASED,
getter_AddRefs(mCacheSession));
if (NS_FAILED(rv)) return rv;
rv = mCacheSession->SetDoomEntriesIfExpired(PR_TRUE);
if (NS_FAILED(rv)) return rv;
}
rv = channel->Init(url, mCacheSession);
if (NS_FAILED(rv)) {
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFtpProtocolHandler::NewChannel() FAILED\n"));
return rv;

Просмотреть файл

@ -30,6 +30,7 @@
#include "nsIThreadPool.h"
#include "nsIObserverService.h"
#include "nsAutoLock.h"
#include "nsICacheSession.h"
// {25029490-F132-11d2-9588-00805F369F95}
#define NS_FTPPROTOCOLHANDLER_CID \
@ -49,11 +50,13 @@ public:
// FTP Connection list access
static nsresult InsertConnection(nsIURI *aKey, nsISupports *aConn);
static nsresult RemoveConnection(nsIURI *aKey, nsISupports **_retval);
static nsresult BuildStreamConverter(nsIStreamListener* in, nsIStreamListener** out);
protected:
static nsSupportsHashtable* mRootConnectionList;
nsCOMPtr<nsIIOService> mIOSvc;
nsCOMPtr<nsICacheSession> mCacheSession;
};
#endif /* nsFtpProtocolHandler_h___ */