uriloader/prefetch/OfflineCacheUpdateGlue.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "OfflineCacheUpdateGlue.h"
michael@0 7 #include "nsOfflineCacheUpdate.h"
michael@0 8 #include "mozilla/Services.h"
michael@0 9
michael@0 10 #include "nsIApplicationCache.h"
michael@0 11 #include "nsIApplicationCacheChannel.h"
michael@0 12 #include "nsIApplicationCacheContainer.h"
michael@0 13 #include "nsIChannel.h"
michael@0 14 #include "nsIDocument.h"
michael@0 15 #include "prlog.h"
michael@0 16
michael@0 17 #if defined(PR_LOGGING)
michael@0 18 //
michael@0 19 // To enable logging (see prlog.h for full details):
michael@0 20 //
michael@0 21 // set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
michael@0 22 // set NSPR_LOG_FILE=offlineupdate.log
michael@0 23 //
michael@0 24 // this enables PR_LOG_ALWAYS level information and places all output in
michael@0 25 // the file offlineupdate.log
michael@0 26 //
michael@0 27 extern PRLogModuleInfo *gOfflineCacheUpdateLog;
michael@0 28 #endif
michael@0 29
michael@0 30 #undef LOG
michael@0 31 #define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
michael@0 32
michael@0 33 #undef LOG_ENABLED
michael@0 34 #define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
michael@0 35
michael@0 36 namespace mozilla {
michael@0 37 namespace docshell {
michael@0 38
michael@0 39 //-----------------------------------------------------------------------------
michael@0 40 // OfflineCacheUpdateGlue::nsISupports
michael@0 41 //-----------------------------------------------------------------------------
michael@0 42
michael@0 43 NS_IMPL_ISUPPORTS(OfflineCacheUpdateGlue,
michael@0 44 nsIOfflineCacheUpdate,
michael@0 45 nsIOfflineCacheUpdateObserver,
michael@0 46 nsISupportsWeakReference)
michael@0 47
michael@0 48 //-----------------------------------------------------------------------------
michael@0 49 // OfflineCacheUpdateGlue <public>
michael@0 50 //-----------------------------------------------------------------------------
michael@0 51
michael@0 52 OfflineCacheUpdateGlue::OfflineCacheUpdateGlue()
michael@0 53 {
michael@0 54 LOG(("OfflineCacheUpdateGlue::OfflineCacheUpdateGlue [%p]", this));
michael@0 55 }
michael@0 56
michael@0 57 OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue()
michael@0 58 {
michael@0 59 LOG(("OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue [%p]", this));
michael@0 60 }
michael@0 61
michael@0 62 nsIOfflineCacheUpdate*
michael@0 63 OfflineCacheUpdateGlue::EnsureUpdate()
michael@0 64 {
michael@0 65 if (!mUpdate) {
michael@0 66 mUpdate = new nsOfflineCacheUpdate();
michael@0 67 LOG(("OfflineCacheUpdateGlue [%p] is using update [%p]", this, mUpdate.get()));
michael@0 68 }
michael@0 69
michael@0 70 return mUpdate;
michael@0 71 }
michael@0 72
michael@0 73 NS_IMETHODIMP
michael@0 74 OfflineCacheUpdateGlue::Schedule()
michael@0 75 {
michael@0 76 nsCOMPtr<nsIObserverService> observerService =
michael@0 77 mozilla::services::GetObserverService();
michael@0 78 if (observerService) {
michael@0 79 LOG(("Calling offline-cache-update-added"));
michael@0 80 observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
michael@0 81 "offline-cache-update-added",
michael@0 82 nullptr);
michael@0 83 LOG(("Done offline-cache-update-added"));
michael@0 84 }
michael@0 85
michael@0 86 if (!EnsureUpdate())
michael@0 87 return NS_ERROR_NULL_POINTER;
michael@0 88
michael@0 89 // Do not use weak reference, we must survive!
michael@0 90 mUpdate->AddObserver(this, false);
michael@0 91
michael@0 92 return mUpdate->Schedule();
michael@0 93 }
michael@0 94
michael@0 95 NS_IMETHODIMP
michael@0 96 OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI,
michael@0 97 nsIURI *aDocumentURI,
michael@0 98 nsIDOMDocument *aDocument,
michael@0 99 nsIFile *aCustomProfileDir,
michael@0 100 uint32_t aAppID,
michael@0 101 bool aInBrowser)
michael@0 102 {
michael@0 103 if (!EnsureUpdate())
michael@0 104 return NS_ERROR_NULL_POINTER;
michael@0 105
michael@0 106 mDocumentURI = aDocumentURI;
michael@0 107
michael@0 108 if (aDocument)
michael@0 109 SetDocument(aDocument);
michael@0 110
michael@0 111 return mUpdate->Init(aManifestURI, aDocumentURI, nullptr, aCustomProfileDir, aAppID, aInBrowser);
michael@0 112 }
michael@0 113
michael@0 114 void
michael@0 115 OfflineCacheUpdateGlue::SetDocument(nsIDOMDocument *aDocument)
michael@0 116 {
michael@0 117 // The design is one document for one cache update on the content process.
michael@0 118 NS_ASSERTION(!mDocument,
michael@0 119 "Setting more then a single document on an instance of OfflineCacheUpdateGlue");
michael@0 120
michael@0 121 LOG(("Document %p added to update glue %p", aDocument, this));
michael@0 122
michael@0 123 // Add document only if it was not loaded from an offline cache.
michael@0 124 // If it were loaded from an offline cache then it has already
michael@0 125 // been associated with it and must not be again cached as
michael@0 126 // implicit (which are the reasons we collect documents here).
michael@0 127 nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
michael@0 128 if (!document)
michael@0 129 return;
michael@0 130
michael@0 131 nsIChannel* channel = document->GetChannel();
michael@0 132 nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
michael@0 133 do_QueryInterface(channel);
michael@0 134 if (!appCacheChannel)
michael@0 135 return;
michael@0 136
michael@0 137 bool loadedFromAppCache;
michael@0 138 appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache);
michael@0 139 if (loadedFromAppCache)
michael@0 140 return;
michael@0 141
michael@0 142 if (EnsureUpdate()) {
michael@0 143 mUpdate->StickDocument(mDocumentURI);
michael@0 144 }
michael@0 145
michael@0 146 mDocument = aDocument;
michael@0 147 }
michael@0 148
michael@0 149 NS_IMETHODIMP
michael@0 150 OfflineCacheUpdateGlue::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, uint32_t state)
michael@0 151 {
michael@0 152 if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
michael@0 153 LOG(("OfflineCacheUpdateGlue got STATE_FINISHED [%p]", this));
michael@0 154
michael@0 155 nsCOMPtr<nsIObserverService> observerService =
michael@0 156 mozilla::services::GetObserverService();
michael@0 157 if (observerService) {
michael@0 158 LOG(("Calling offline-cache-update-completed"));
michael@0 159 observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
michael@0 160 "offline-cache-update-completed",
michael@0 161 nullptr);
michael@0 162 LOG(("Done offline-cache-update-completed"));
michael@0 163 }
michael@0 164
michael@0 165 aUpdate->RemoveObserver(this);
michael@0 166 }
michael@0 167
michael@0 168 return NS_OK;
michael@0 169 }
michael@0 170
michael@0 171 NS_IMETHODIMP
michael@0 172 OfflineCacheUpdateGlue::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
michael@0 173 {
michael@0 174 NS_ENSURE_ARG(aApplicationCache);
michael@0 175
michael@0 176 // Check that the document that requested this update was
michael@0 177 // previously associated with an application cache. If not, it
michael@0 178 // should be associated with the new one.
michael@0 179 nsCOMPtr<nsIApplicationCacheContainer> container =
michael@0 180 do_QueryInterface(mDocument);
michael@0 181 if (!container)
michael@0 182 return NS_OK;
michael@0 183
michael@0 184 nsCOMPtr<nsIApplicationCache> existingCache;
michael@0 185 nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
michael@0 186 NS_ENSURE_SUCCESS(rv, rv);
michael@0 187
michael@0 188 if (!existingCache) {
michael@0 189 #if defined(PR_LOGGING)
michael@0 190 if (LOG_ENABLED()) {
michael@0 191 nsAutoCString clientID;
michael@0 192 if (aApplicationCache) {
michael@0 193 aApplicationCache->GetClientID(clientID);
michael@0 194 }
michael@0 195 LOG(("Update %p: associating app cache %s to document %p",
michael@0 196 this, clientID.get(), mDocument.get()));
michael@0 197 }
michael@0 198 #endif
michael@0 199
michael@0 200 rv = container->SetApplicationCache(aApplicationCache);
michael@0 201 NS_ENSURE_SUCCESS(rv, rv);
michael@0 202 }
michael@0 203
michael@0 204 return NS_OK;
michael@0 205 }
michael@0 206
michael@0 207 }
michael@0 208 }

mercurial