mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Bug 918827 - Remove caching for ftp connections. r=michal
--HG-- extra : amend_source : 2e31431e4227fdf3f88d31a8efa14aab8e793cd2
This commit is contained in:
parent
73f4a67965
commit
7af9c45717
@ -22,7 +22,6 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsIStreamListenerTee.h"
|
||||
@ -32,7 +31,6 @@
|
||||
#include "nsAuthInformationHolder.h"
|
||||
#include "nsIProtocolProxyService.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
@ -40,7 +38,6 @@
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsISocketTransportService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
|
||||
@ -70,7 +67,6 @@ NS_IMPL_ISUPPORTS_INHERITED(nsFtpState,
|
||||
nsBaseContentStream,
|
||||
nsIInputStreamCallback,
|
||||
nsITransportEventSink,
|
||||
nsICacheListener,
|
||||
nsIRequestObserver,
|
||||
nsIProtocolProxyCallback)
|
||||
|
||||
@ -96,7 +92,6 @@ nsFtpState::nsFtpState()
|
||||
, mServerIsIPv6(false)
|
||||
, mUseUTF8(false)
|
||||
, mControlStatus(NS_OK)
|
||||
, mDoomCache(false)
|
||||
, mDeferredCallbackPending(false)
|
||||
{
|
||||
LOG_ALWAYS(("FTP:(%x) nsFtpState created", this));
|
||||
@ -1142,8 +1137,7 @@ nsFtpState::SetContentType()
|
||||
// FTP directory URLs don't always end in a slash. Make sure they do.
|
||||
// This check needs to be here rather than a more obvious place
|
||||
// (e.g. LIST command processing) so that it ensures the terminating
|
||||
// slash is appended for the new request case, as well as the case
|
||||
// where the URL is being loaded from the cache.
|
||||
// slash is appended for the new request case.
|
||||
|
||||
if (!mPath.IsEmpty() && mPath.Last() != '/') {
|
||||
nsCOMPtr<nsIURL> url = (do_QueryInterface(mChannel->URI()));
|
||||
@ -1173,23 +1167,6 @@ nsFtpState::S_list() {
|
||||
mResponseMsg = "";
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mCacheEntry) {
|
||||
// save off the server type if we are caching.
|
||||
nsAutoCString serverType;
|
||||
serverType.AppendInt(mServerType);
|
||||
mCacheEntry->SetMetaDataElement("servertype", serverType.get());
|
||||
|
||||
nsAutoCString useUTF8;
|
||||
useUTF8.AppendInt(mUseUTF8);
|
||||
mCacheEntry->SetMetaDataElement("useUTF8", useUTF8.get());
|
||||
|
||||
// open cache entry for writing, and configure it to receive data.
|
||||
if (NS_FAILED(InstallCacheListener())) {
|
||||
mCacheEntry->AsyncDoom(nullptr);
|
||||
mCacheEntry = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// dir listings aren't resumable
|
||||
NS_ENSURE_TRUE(!mChannel->ResumeRequested(), NS_ERROR_NOT_RESUMABLE);
|
||||
@ -1218,7 +1195,6 @@ nsFtpState::R_list() {
|
||||
if (mResponseCode/100 == 2) {
|
||||
//(DONE)
|
||||
mNextState = FTP_COMPLETE;
|
||||
mDoomCache = false;
|
||||
return FTP_COMPLETE;
|
||||
}
|
||||
return FTP_ERROR;
|
||||
@ -1245,13 +1221,6 @@ nsFtpState::R_retr() {
|
||||
}
|
||||
|
||||
if (mResponseCode/100 == 1) {
|
||||
// We're going to grab a file, not a directory. So we need to clear
|
||||
// any cache entry, otherwise we'll have problems reading it later.
|
||||
// See bug 122548
|
||||
if (mCacheEntry) {
|
||||
(void)mCacheEntry->AsyncDoom(nullptr);
|
||||
mCacheEntry = nullptr;
|
||||
}
|
||||
if (mDataStream && HasPendingCallback())
|
||||
mDataStream->AsyncWait(this, 0, 0, CallbackTarget());
|
||||
return FTP_READ_BUF;
|
||||
@ -1644,123 +1613,6 @@ uint32_t GetFtpTime()
|
||||
|
||||
uint32_t nsFtpState::mSessionStartTime = GetFtpTime();
|
||||
|
||||
/* Is this cache entry valid to use for reading?
|
||||
* Since we make up an expiration time for ftp, use the following rules:
|
||||
* (see bug 103726)
|
||||
*
|
||||
* LOAD_FROM_CACHE : always use cache entry, even if expired
|
||||
* LOAD_BYPASS_CACHE : overwrite cache entry
|
||||
* LOAD_NORMAL|VALIDATE_ALWAYS : overwrite cache entry
|
||||
* LOAD_NORMAL : honor expiration time
|
||||
* LOAD_NORMAL|VALIDATE_ONCE_PER_SESSION : overwrite cache entry if first access
|
||||
* this session, otherwise use cache entry
|
||||
* even if expired.
|
||||
* LOAD_NORMAL|VALIDATE_NEVER : always use cache entry, even if expired
|
||||
*
|
||||
* Note that in theory we could use the mdtm time on the directory
|
||||
* In practice, the lack of a timezone plus the general lack of support for that
|
||||
* on directories means that its not worth it, I suspect. Revisit if we start
|
||||
* caching files - bbaetz
|
||||
*/
|
||||
bool
|
||||
nsFtpState::CanReadCacheEntry()
|
||||
{
|
||||
NS_ASSERTION(mCacheEntry, "must have a cache entry");
|
||||
|
||||
nsCacheAccessMode access;
|
||||
nsresult rv = mCacheEntry->GetAccessGranted(&access);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
// If I'm not granted read access, then I can't reuse it...
|
||||
if (!(access & nsICache::ACCESS_READ))
|
||||
return false;
|
||||
|
||||
if (mChannel->HasLoadFlag(nsIRequest::LOAD_FROM_CACHE))
|
||||
return true;
|
||||
|
||||
if (mChannel->HasLoadFlag(nsIRequest::LOAD_BYPASS_CACHE))
|
||||
return false;
|
||||
|
||||
if (mChannel->HasLoadFlag(nsIRequest::VALIDATE_ALWAYS))
|
||||
return false;
|
||||
|
||||
uint32_t time;
|
||||
if (mChannel->HasLoadFlag(nsIRequest::VALIDATE_ONCE_PER_SESSION)) {
|
||||
rv = mCacheEntry->GetLastModified(&time);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
return (mSessionStartTime > time);
|
||||
}
|
||||
|
||||
if (mChannel->HasLoadFlag(nsIRequest::VALIDATE_NEVER))
|
||||
return true;
|
||||
|
||||
// OK, now we just check the expiration time as usual
|
||||
rv = mCacheEntry->GetExpirationTime(&time);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
return (GetFtpTime() <= time);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::InstallCacheListener()
|
||||
{
|
||||
NS_ASSERTION(mCacheEntry, "must have a cache entry");
|
||||
|
||||
nsCOMPtr<nsIOutputStream> out;
|
||||
mCacheEntry->OpenOutputStream(0, getter_AddRefs(out));
|
||||
NS_ENSURE_STATE(out);
|
||||
|
||||
nsCOMPtr<nsIStreamListenerTee> tee =
|
||||
do_CreateInstance(NS_STREAMLISTENERTEE_CONTRACTID);
|
||||
NS_ENSURE_STATE(tee);
|
||||
|
||||
nsresult rv = tee->Init(mChannel->StreamListener(), out, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mChannel->SetStreamListener(tee);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::OpenCacheDataStream()
|
||||
{
|
||||
NS_ASSERTION(mCacheEntry, "must have a cache entry");
|
||||
|
||||
// Get a transport to the cached data...
|
||||
nsCOMPtr<nsIInputStream> input;
|
||||
mCacheEntry->OpenInputStream(0, getter_AddRefs(input));
|
||||
NS_ENSURE_STATE(input);
|
||||
|
||||
nsCOMPtr<nsIStreamTransportService> sts =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ENSURE_STATE(sts);
|
||||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
sts->CreateInputTransport(input, -1, -1, true,
|
||||
getter_AddRefs(transport));
|
||||
NS_ENSURE_STATE(transport);
|
||||
|
||||
nsresult rv = transport->SetEventSink(this, NS_GetCurrentThread());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Open a non-blocking, buffered input stream...
|
||||
nsCOMPtr<nsIInputStream> transportInput;
|
||||
transport->OpenInputStream(0,
|
||||
nsIOService::gDefaultSegmentSize,
|
||||
nsIOService::gDefaultSegmentCount,
|
||||
getter_AddRefs(transportInput));
|
||||
NS_ENSURE_STATE(transportInput);
|
||||
|
||||
mDataStream = do_QueryInterface(transportInput);
|
||||
NS_ENSURE_STATE(mDataStream);
|
||||
|
||||
mDataTransport = transport;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFtpState::Init(nsFtpChannel *channel)
|
||||
{
|
||||
@ -1859,8 +1711,6 @@ nsFtpState::Init(nsFtpChannel *channel)
|
||||
if (mPassword.FindCharInSet(CRLF) >= 0)
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
// setup the connection cache key
|
||||
|
||||
int32_t port;
|
||||
rv = mChannel->URI()->GetPort(&port);
|
||||
if (NS_FAILED(rv))
|
||||
@ -2198,39 +2048,6 @@ nsFtpState::OnTransportStatus(nsITransport *transport, nsresult status,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpState::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
|
||||
nsCacheAccessMode access,
|
||||
nsresult status)
|
||||
{
|
||||
// We may have been closed while we were waiting for this cache entry.
|
||||
if (IsClosed())
|
||||
return NS_OK;
|
||||
|
||||
if (NS_SUCCEEDED(status) && entry) {
|
||||
mDoomCache = true;
|
||||
mCacheEntry = entry;
|
||||
if (CanReadCacheEntry() && ReadCacheEntry()) {
|
||||
mState = FTP_READ_CACHE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
Connect();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpState::OnCacheEntryDoomed(nsresult status)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpState::OnStartRequest(nsIRequest *request, nsISupports *context)
|
||||
{
|
||||
@ -2356,9 +2173,6 @@ nsFtpState::CloseWithStatus(nsresult status)
|
||||
}
|
||||
|
||||
mDataStream = nullptr;
|
||||
if (mDoomCache && mCacheEntry)
|
||||
mCacheEntry->AsyncDoom(nullptr);
|
||||
mCacheEntry = nullptr;
|
||||
|
||||
return nsBaseContentStream::CloseWithStatus(status);
|
||||
}
|
||||
@ -2433,124 +2247,14 @@ nsFtpState::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
|
||||
void
|
||||
nsFtpState::OnCallbackPending()
|
||||
{
|
||||
// If this is the first call, then see if we could use the cache. If we
|
||||
// aren't going to read from (or write to) the cache, then just proceed to
|
||||
// connect to the server.
|
||||
|
||||
if (mState == FTP_INIT) {
|
||||
if (mProxyRequest) {
|
||||
mDeferredCallbackPending = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckCache()) {
|
||||
mState = FTP_WAIT_CACHE;
|
||||
return;
|
||||
}
|
||||
if (mCacheEntry && CanReadCacheEntry() && ReadCacheEntry()) {
|
||||
mState = FTP_READ_CACHE;
|
||||
return;
|
||||
}
|
||||
Connect();
|
||||
} else if (mDataStream) {
|
||||
mDataStream->AsyncWait(this, 0, 0, CallbackTarget());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsFtpState::ReadCacheEntry()
|
||||
{
|
||||
NS_ASSERTION(mCacheEntry, "should have a cache entry");
|
||||
|
||||
// make sure the channel knows wassup
|
||||
SetContentType();
|
||||
|
||||
nsXPIDLCString serverType;
|
||||
mCacheEntry->GetMetaDataElement("servertype", getter_Copies(serverType));
|
||||
nsAutoCString serverNum(serverType.get());
|
||||
nsresult err;
|
||||
mServerType = serverNum.ToInteger(&err);
|
||||
|
||||
nsXPIDLCString charset;
|
||||
mCacheEntry->GetMetaDataElement("useUTF8", getter_Copies(charset));
|
||||
const char *useUTF8 = charset.get();
|
||||
if (useUTF8 && atoi(useUTF8) == 1)
|
||||
mChannel->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
|
||||
|
||||
mChannel->PushStreamConverter("text/ftp-dir",
|
||||
APPLICATION_HTTP_INDEX_FORMAT);
|
||||
|
||||
mChannel->SetEntityID(EmptyCString());
|
||||
|
||||
if (NS_FAILED(OpenCacheDataStream()))
|
||||
return false;
|
||||
|
||||
if (mDataStream && HasPendingCallback())
|
||||
mDataStream->AsyncWait(this, 0, 0, CallbackTarget());
|
||||
|
||||
mDoomCache = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFtpState::CheckCache()
|
||||
{
|
||||
// This function is responsible for setting mCacheEntry if there is a cache
|
||||
// entry that we can use. It returns true if we end up waiting for access
|
||||
// to the cache.
|
||||
|
||||
// In some cases, we don't want to use the cache:
|
||||
if (mChannel->UploadStream() || mChannel->ResumeRequested())
|
||||
return false;
|
||||
|
||||
nsCOMPtr<nsICacheService> cache = do_GetService(NS_CACHESERVICE_CONTRACTID);
|
||||
if (!cache)
|
||||
return false;
|
||||
|
||||
bool isPrivate = NS_UsePrivateBrowsing(mChannel);
|
||||
const char* sessionName = isPrivate ? "FTP-private" : "FTP";
|
||||
nsCacheStoragePolicy policy =
|
||||
isPrivate ? nsICache::STORE_IN_MEMORY : nsICache::STORE_ANYWHERE;
|
||||
nsCOMPtr<nsICacheSession> session;
|
||||
cache->CreateSession(sessionName,
|
||||
policy,
|
||||
nsICache::STREAM_BASED,
|
||||
getter_AddRefs(session));
|
||||
if (!session)
|
||||
return false;
|
||||
session->SetDoomEntriesIfExpired(false);
|
||||
session->SetIsPrivate(isPrivate);
|
||||
|
||||
// Set cache access requested:
|
||||
nsCacheAccessMode accessReq;
|
||||
uint32_t appId;
|
||||
bool isInBrowser;
|
||||
NS_GetAppInfo(mChannel, &appId, &isInBrowser);
|
||||
|
||||
if (NS_IsOffline() || NS_IsAppOffline(appId)) {
|
||||
accessReq = nsICache::ACCESS_READ; // can only read
|
||||
} else if (mChannel->HasLoadFlag(nsIRequest::LOAD_BYPASS_CACHE)) {
|
||||
accessReq = nsICache::ACCESS_WRITE; // replace cache entry
|
||||
} else {
|
||||
accessReq = nsICache::ACCESS_READ_WRITE; // normal browsing
|
||||
}
|
||||
|
||||
// Check to see if we are not allowed to write to the cache:
|
||||
if (mChannel->HasLoadFlag(nsIRequest::INHIBIT_CACHING)) {
|
||||
accessReq &= ~nsICache::ACCESS_WRITE;
|
||||
if (accessReq == nsICache::ACCESS_NONE)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate cache key (remove trailing #ref if any):
|
||||
nsAutoCString key;
|
||||
mChannel->URI()->GetAsciiSpec(key);
|
||||
int32_t pos = key.RFindChar('#');
|
||||
if (pos != kNotFound)
|
||||
key.Truncate(pos);
|
||||
NS_ENSURE_FALSE(key.IsEmpty(), false);
|
||||
|
||||
nsresult rv = session->AsyncOpenCacheEntry(key, accessReq, this, false);
|
||||
return NS_SUCCEEDED(rv);
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "nsBaseContentStream.h"
|
||||
|
||||
#include "nsICacheListener.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
@ -35,8 +34,6 @@ typedef enum _FTP_STATE {
|
||||
///////////////////////
|
||||
//// Internal states
|
||||
FTP_INIT,
|
||||
FTP_WAIT_CACHE,
|
||||
FTP_READ_CACHE,
|
||||
FTP_COMMAND_CONNECT,
|
||||
FTP_READ_BUF,
|
||||
FTP_ERROR,
|
||||
@ -67,7 +64,6 @@ typedef enum _FTP_ACTION {GET, PUT} FTP_ACTION;
|
||||
|
||||
class nsFtpChannel;
|
||||
class nsICancelable;
|
||||
class nsICacheEntryDescriptor;
|
||||
class nsIProxyInfo;
|
||||
class nsIStreamListener;
|
||||
|
||||
@ -79,7 +75,6 @@ class nsIStreamListener;
|
||||
class nsFtpState MOZ_FINAL : public nsBaseContentStream,
|
||||
public nsIInputStreamCallback,
|
||||
public nsITransportEventSink,
|
||||
public nsICacheListener,
|
||||
public nsIRequestObserver,
|
||||
public nsFtpControlConnectionListener,
|
||||
public nsIProtocolProxyCallback
|
||||
@ -88,7 +83,6 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIINPUTSTREAMCALLBACK
|
||||
NS_DECL_NSITRANSPORTEVENTSINK
|
||||
NS_DECL_NSICACHELISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSIPROTOCOLPROXYCALLBACK
|
||||
|
||||
@ -158,46 +152,6 @@ private:
|
||||
*/
|
||||
void Connect();
|
||||
|
||||
/**
|
||||
* This method opens a cache entry for reading or writing depending on the
|
||||
* state of the channel and of the system (e.g., opened for reading if we
|
||||
* are offline). This method is responsible for setting mCacheEntry if
|
||||
* there is a cache entry that can be used. It returns true if it ends up
|
||||
* waiting (asynchronously) for access to the cache entry. In that case,
|
||||
* the nsFtpState's OnCacheEntryAvailable method will be called once the
|
||||
* cache entry is available or if an error occurs.
|
||||
*/
|
||||
bool CheckCache();
|
||||
|
||||
/**
|
||||
* This method returns true if the data for this URL can be read from the
|
||||
* cache. This method assumes that mCacheEntry is non-null.
|
||||
*/
|
||||
bool CanReadCacheEntry();
|
||||
|
||||
/**
|
||||
* This method causes the cache entry to be read. Data from the cache
|
||||
* entry will be fed to the channel's listener. This method returns true
|
||||
* if successfully reading from the cache. This method assumes that
|
||||
* mCacheEntry is non-null and opened with read access.
|
||||
*/
|
||||
bool ReadCacheEntry();
|
||||
|
||||
/**
|
||||
* This method configures mDataStream with an asynchronous input stream to
|
||||
* the cache entry. The cache entry is read on a background thread. This
|
||||
* method assumes that mCacheEntry is non-null and opened with read access.
|
||||
*/
|
||||
nsresult OpenCacheDataStream();
|
||||
|
||||
/**
|
||||
* This method inserts the cache entry's output stream into the stream
|
||||
* listener chain for the FTP channel. As a result, the cache entry
|
||||
* receives data as data is pushed to the channel's listener. This method
|
||||
* assumes that mCacheEntry is non-null and opened with write access.
|
||||
*/
|
||||
nsresult InstallCacheListener();
|
||||
|
||||
///////////////////////////////////
|
||||
// Private members
|
||||
|
||||
@ -257,9 +211,6 @@ private:
|
||||
nsresult mControlStatus;
|
||||
nsCString mControlReadCarryOverBuf;
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||
bool mDoomCache;
|
||||
|
||||
nsCString mSuppliedEntityID;
|
||||
|
||||
nsCOMPtr<nsICancelable> mProxyRequest;
|
||||
|
@ -31,7 +31,6 @@ using namespace mozilla::net;
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsICacheSession.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -13,8 +13,6 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsICacheSession;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsFtpProtocolHandler MOZ_FINAL : public nsIProxiedProtocolHandler
|
||||
@ -67,7 +65,6 @@ private:
|
||||
|
||||
nsTArray<timerStruct*> mRootConnectionList;
|
||||
|
||||
nsCOMPtr<nsICacheSession> mCacheSession;
|
||||
int32_t mIdleTimeout;
|
||||
|
||||
// When "clear active logins" is performed, all idle connection are dropped
|
||||
|
Loading…
Reference in New Issue
Block a user