| author | Dragana Damjanovic <dd.mozilla@gmail.com> |
| Mon, 02 Mar 2015 14:31:53 -0800 | |
| changeset 231507 | 4829b02a11af16bd8850fb3b377cfa59abd46fef |
| parent 231506 | cf124d6f66022d54ef6e3a61c3e173f3eb3df341 |
| child 231508 | fa16d24d530f347e9f4ae6de986e68d99c28e3cf |
| push id | 28353 |
| push user | cbook@mozilla.com |
| push date | Tue, 03 Mar 2015 12:54:59 +0000 |
| treeherder | mozilla-central@985070813323 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | michal |
| bugs | 918827 |
| milestone | 39.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp @@ -17,35 +17,32 @@ #include "nsFtpProtocolHandler.h" #include "netCore.h" #include "nsCRT.h" #include "nsEscape.h" #include "nsMimeTypes.h" #include "nsNetUtil.h" #include "nsThreadUtils.h" #include "nsStreamUtils.h" -#include "nsICacheService.h" #include "nsIURL.h" #include "nsISocketTransport.h" #include "nsIStreamListenerTee.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsIStringBundle.h" #include "nsAuthInformationHolder.h" #include "nsIProtocolProxyService.h" #include "nsICancelable.h" -#include "nsICacheEntryDescriptor.h" #include "nsIOutputStream.h" #include "nsIPrompt.h" #include "nsIProtocolHandler.h" #include "nsIProxyInfo.h" #include "nsIRunnable.h" #include "nsISocketTransportService.h" #include "nsIURI.h" -#include "nsICacheSession.h" #include "nsILoadInfo.h" #include "nsNullPrincipal.h" #ifdef MOZ_WIDGET_GONK #include "NetStatistics.h" #endif #if defined(PR_LOGGING) @@ -65,17 +62,16 @@ removeParamsFromPath(nsCString& path) path.SetLength(index); } } NS_IMPL_ISUPPORTS_INHERITED(nsFtpState, nsBaseContentStream, nsIInputStreamCallback, nsITransportEventSink, - nsICacheListener, nsIRequestObserver, nsIProtocolProxyCallback) nsFtpState::nsFtpState() : nsBaseContentStream(true) , mState(FTP_INIT) , mNextState(FTP_S_USER) , mKeepRunning(true) @@ -91,17 +87,16 @@ nsFtpState::nsFtpState() , mInternalError(NS_OK) , mReconnectAndLoginAgain(false) , mCacheConnection(true) , mPort(21) , mAddressChecked(false) , mServerIsIPv6(false) , mUseUTF8(false) , mControlStatus(NS_OK) - , mDoomCache(false) , mDeferredCallbackPending(false) { LOG_ALWAYS(("FTP:(%x) nsFtpState created", this)); // make sure handler stays around NS_ADDREF(gFtpHandler); } @@ -1137,18 +1132,17 @@ nsFtpState::R_mdtm() { } nsresult 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())); nsAutoCString filePath; if(NS_SUCCEEDED(url->GetFilePath(filePath))) { filePath.Append('/'); url->SetFilePath(filePath); } @@ -1168,33 +1162,16 @@ nsFtpState::S_list() { rv = mChannel->PushStreamConverter("text/ftp-dir", APPLICATION_HTTP_INDEX_FORMAT); if (NS_FAILED(rv)) { // clear mResponseMsg which is displayed to the user. // TODO: we should probably set this to something meaningful. 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); mChannel->SetEntityID(EmptyCString()); const char *listString; if (mServerType == FTP_VMS_TYPE) { @@ -1213,17 +1190,16 @@ nsFtpState::R_list() { if (mDataStream && HasPendingCallback()) mDataStream->AsyncWait(this, 0, 0, CallbackTarget()); return FTP_READ_BUF; } if (mResponseCode/100 == 2) { //(DONE) mNextState = FTP_COMPLETE; - mDoomCache = false; return FTP_COMPLETE; } return FTP_ERROR; } nsresult nsFtpState::S_retr() { nsAutoCString retrStr(mPath); @@ -1240,23 +1216,16 @@ FTP_STATE nsFtpState::R_retr() { if (mResponseCode/100 == 2) { //(DONE) mNextState = FTP_COMPLETE; return FTP_COMPLETE; } 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; } // These error codes are related to problems with the connection. // If we encounter any at this point, do not try CWD and abort. if (mResponseCode == 421 || mResponseCode == 425 || mResponseCode == 426) @@ -1639,133 +1608,16 @@ nsFtpState::R_opts() { static inline uint32_t GetFtpTime() { return uint32_t(PR_Now() / PR_USEC_PER_SEC); } 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) { // parameter validation NS_ASSERTION(channel, "FTP: needs a channel"); mChannel = channel; // a straight ref ptr to the channel @@ -1854,18 +1706,16 @@ nsFtpState::Init(nsFtpChannel *channel) return rv; CopyUTF8toUTF16(NS_UnescapeURL(password), mPassword); // return an error if we find a CR or LF in the password 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)) return rv; if (port > 0) mPort = port; @@ -2193,49 +2043,16 @@ nsFtpState::OnTransportStatus(nsITranspo // report the max progress based on where we started/resumed. mChannel->OnTransportStatus(nullptr, status, progress, mFileSize - mChannel->StartPos()); return NS_OK; } //----------------------------------------------------------------------------- - -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) { mStorReplyReceived = false; return NS_OK; } NS_IMETHODIMP @@ -2351,19 +2168,16 @@ nsFtpState::CloseWithStatus(nsresult sta SaveNetworkStats(true); // Shutdown the data transport. mDataTransport->Close(NS_ERROR_ABORT); mDataTransport = nullptr; } mDataStream = nullptr; - if (mDoomCache && mCacheEntry) - mCacheEntry->AsyncDoom(nullptr); - mCacheEntry = nullptr; return nsBaseContentStream::CloseWithStatus(status); } static nsresult CreateHTTPProxiedChannel(nsIChannel *channel, nsIProxyInfo *pi, nsIChannel **newChannel) { nsresult rv; @@ -2428,129 +2242,19 @@ nsFtpState::OnProxyAvailable(nsICancelab OnCallbackPending(); } return NS_OK; } 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); - -}
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.h +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.h @@ -3,17 +3,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef __nsFtpState__h_ #define __nsFtpState__h_ #include "nsBaseContentStream.h" -#include "nsICacheListener.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsIAsyncInputStream.h" #include "nsAutoPtr.h" #include "nsITransport.h" #include "mozilla/net/DNS.h" #include "nsFtpControlConnection.h" #include "nsIProtocolProxyCallback.h" @@ -30,18 +29,16 @@ #define FTP_NT_TYPE 9 #define FTP_OS2_TYPE 11 // ftp states typedef enum _FTP_STATE { /////////////////////// //// Internal states FTP_INIT, - FTP_WAIT_CACHE, - FTP_READ_CACHE, FTP_COMMAND_CONNECT, FTP_READ_BUF, FTP_ERROR, FTP_COMPLETE, /////////////////////// //// Command channel connection setup states FTP_S_USER, FTP_R_USER, @@ -62,38 +59,35 @@ typedef enum _FTP_STATE { FTP_S_OPTS, FTP_R_OPTS } FTP_STATE; // higher level ftp actions typedef enum _FTP_ACTION {GET, PUT} FTP_ACTION; class nsFtpChannel; class nsICancelable; -class nsICacheEntryDescriptor; class nsIProxyInfo; class nsIStreamListener; // The nsFtpState object is the content stream for the channel. It implements // nsIInputStreamCallback, so it can read data from the control connection. It // implements nsITransportEventSink so it can mix status events from both the // control connection and the data connection. class nsFtpState MOZ_FINAL : public nsBaseContentStream, public nsIInputStreamCallback, public nsITransportEventSink, - public nsICacheListener, public nsIRequestObserver, public nsFtpControlConnectionListener, public nsIProtocolProxyCallback { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSITRANSPORTEVENTSINK - NS_DECL_NSICACHELISTENER NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIPROTOCOLPROXYCALLBACK // Override input stream methods: NS_IMETHOD CloseWithStatus(nsresult status) MOZ_OVERRIDE; NS_IMETHOD Available(uint64_t *result) MOZ_OVERRIDE; NS_IMETHOD ReadSegments(nsWriteSegmentFun fun, void *closure, uint32_t count, uint32_t *result) MOZ_OVERRIDE; @@ -153,56 +147,16 @@ private: /** * This method is called to kick-off the FTP state machine. mState is * reset to FTP_COMMAND_CONNECT, and the FTP state machine progresses from * there. This method is initially called (indirectly) from the channel's * AsyncOpen implementation. */ 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 // ****** state machine vars FTP_STATE mState; // the current state FTP_STATE mNextState; // the next state bool mKeepRunning; // thread event loop boolean int32_t mResponseCode; // the last command response code @@ -252,19 +206,16 @@ private: static uint32_t mSessionStartTime; mozilla::net::NetAddr mServerAddress; // ***** control read gvars nsresult mControlStatus; nsCString mControlReadCarryOverBuf; - nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry; - bool mDoomCache; - nsCString mSuppliedEntityID; nsCOMPtr<nsICancelable> mProxyRequest; bool mDeferredCallbackPending; // These members are used for network per-app metering (bug 855948) // Currently, they are only available on gonk. uint64_t mCountRecv;
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp +++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp @@ -26,17 +26,16 @@ using namespace mozilla::net; #include "nsFTPChannel.h" #include "nsIStandardURL.h" #include "prlog.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsIObserverService.h" #include "nsEscape.h" #include "nsAlgorithm.h" -#include "nsICacheSession.h" //----------------------------------------------------------------------------- #if defined(PR_LOGGING) // // Log module for FTP Protocol logging... // // To enable logging (see prlog.h for full details):
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.h +++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.h @@ -8,18 +8,16 @@ #include "nsFtpControlConnection.h" #include "nsIProxiedProtocolHandler.h" #include "nsTArray.h" #include "nsITimer.h" #include "nsIObserver.h" #include "nsWeakReference.h" -class nsICacheSession; - //----------------------------------------------------------------------------- class nsFtpProtocolHandler MOZ_FINAL : public nsIProxiedProtocolHandler , public nsIObserver , public nsSupportsWeakReference { public: NS_DECL_THREADSAFE_ISUPPORTS @@ -62,17 +60,16 @@ private: } }; static void Timeout(nsITimer *aTimer, void *aClosure); void ClearAllConnections(); nsTArray<timerStruct*> mRootConnectionList; - nsCOMPtr<nsICacheSession> mCacheSession; int32_t mIdleTimeout; // When "clear active logins" is performed, all idle connection are dropped // and mSessionId is incremented. When nsFtpState wants to insert idle // connection we refuse to cache if its mSessionId is different (i.e. // control connection had been created before last "clear active logins" was // performed. uint32_t mSessionId;