Bug 918827 - Remove caching for ftp connections. r=michal

--HG--
extra : amend_source : 2e31431e4227fdf3f88d31a8efa14aab8e793cd2
This commit is contained in:
Dragana Damjanovic 2015-03-02 14:31:53 -08:00
parent 73f4a67965
commit 7af9c45717
4 changed files with 1 additions and 350 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -31,7 +31,6 @@ using namespace mozilla::net;
#include "nsIObserverService.h"
#include "nsEscape.h"
#include "nsAlgorithm.h"
#include "nsICacheSession.h"
//-----------------------------------------------------------------------------

View File

@ -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