Tue, 06 Jan 2015 21:39:09 +0100
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.
1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "OfflineCacheUpdateParent.h"
8 #include "mozilla/dom/TabParent.h"
9 #include "mozilla/ipc/URIUtils.h"
10 #include "mozilla/unused.h"
11 #include "nsOfflineCacheUpdate.h"
12 #include "nsIApplicationCache.h"
13 #include "nsIScriptSecurityManager.h"
14 #include "nsNetUtil.h"
15 #include "nsContentUtils.h"
17 using namespace mozilla::ipc;
18 using mozilla::dom::TabParent;
20 #if defined(PR_LOGGING)
21 //
22 // To enable logging (see prlog.h for full details):
23 //
24 // set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
25 // set NSPR_LOG_FILE=offlineupdate.log
26 //
27 // this enables PR_LOG_ALWAYS level information and places all output in
28 // the file offlineupdate.log
29 //
30 extern PRLogModuleInfo *gOfflineCacheUpdateLog;
31 #endif
33 #undef LOG
34 #define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
36 #undef LOG_ENABLED
37 #define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
39 namespace mozilla {
40 namespace docshell {
42 //-----------------------------------------------------------------------------
43 // OfflineCacheUpdateParent::nsISupports
44 //-----------------------------------------------------------------------------
46 NS_IMPL_ISUPPORTS(OfflineCacheUpdateParent,
47 nsIOfflineCacheUpdateObserver,
48 nsILoadContext)
50 //-----------------------------------------------------------------------------
51 // OfflineCacheUpdateParent <public>
52 //-----------------------------------------------------------------------------
54 OfflineCacheUpdateParent::OfflineCacheUpdateParent(uint32_t aAppId,
55 bool aIsInBrowser)
56 : mIPCClosed(false)
57 , mIsInBrowserElement(aIsInBrowser)
58 , mAppId(aAppId)
59 {
60 // Make sure the service has been initialized
61 nsOfflineCacheUpdateService::EnsureService();
63 LOG(("OfflineCacheUpdateParent::OfflineCacheUpdateParent [%p]", this));
64 }
66 OfflineCacheUpdateParent::~OfflineCacheUpdateParent()
67 {
68 LOG(("OfflineCacheUpdateParent::~OfflineCacheUpdateParent [%p]", this));
69 }
71 void
72 OfflineCacheUpdateParent::ActorDestroy(ActorDestroyReason why)
73 {
74 mIPCClosed = true;
75 }
77 nsresult
78 OfflineCacheUpdateParent::Schedule(const URIParams& aManifestURI,
79 const URIParams& aDocumentURI,
80 const bool& stickDocument)
81 {
82 LOG(("OfflineCacheUpdateParent::RecvSchedule [%p]", this));
84 nsRefPtr<nsOfflineCacheUpdate> update;
85 nsCOMPtr<nsIURI> manifestURI = DeserializeURI(aManifestURI);
86 if (!manifestURI)
87 return NS_ERROR_FAILURE;
89 nsOfflineCacheUpdateService* service =
90 nsOfflineCacheUpdateService::EnsureService();
91 if (!service)
92 return NS_ERROR_FAILURE;
94 bool offlinePermissionAllowed = false;
96 nsCOMPtr<nsIPrincipal> principal;
97 nsContentUtils::GetSecurityManager()->
98 GetAppCodebasePrincipal(manifestURI, mAppId, mIsInBrowserElement,
99 getter_AddRefs(principal));
101 nsresult rv = service->OfflineAppAllowed(
102 principal, nullptr, &offlinePermissionAllowed);
103 NS_ENSURE_SUCCESS(rv, rv);
105 if (!offlinePermissionAllowed)
106 return NS_ERROR_DOM_SECURITY_ERR;
108 nsCOMPtr<nsIURI> documentURI = DeserializeURI(aDocumentURI);
109 if (!documentURI)
110 return NS_ERROR_FAILURE;
112 if (!NS_SecurityCompareURIs(manifestURI, documentURI, false))
113 return NS_ERROR_DOM_SECURITY_ERR;
115 service->FindUpdate(manifestURI, mAppId, mIsInBrowserElement,
116 getter_AddRefs(update));
117 if (!update) {
118 update = new nsOfflineCacheUpdate();
120 // Leave aDocument argument null. Only glues and children keep
121 // document instances.
122 rv = update->Init(manifestURI, documentURI, nullptr, nullptr,
123 mAppId, mIsInBrowserElement);
124 NS_ENSURE_SUCCESS(rv, rv);
126 rv = update->Schedule();
127 NS_ENSURE_SUCCESS(rv, rv);
128 }
130 update->AddObserver(this, false);
132 if (stickDocument) {
133 nsCOMPtr<nsIURI> stickURI;
134 documentURI->Clone(getter_AddRefs(stickURI));
135 update->StickDocument(stickURI);
136 }
138 return NS_OK;
139 }
141 NS_IMETHODIMP
142 OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, uint32_t state)
143 {
144 if (mIPCClosed)
145 return NS_ERROR_UNEXPECTED;
147 LOG(("OfflineCacheUpdateParent::StateEvent [%p]", this));
149 uint64_t byteProgress;
150 aUpdate->GetByteProgress(&byteProgress);
151 unused << SendNotifyStateEvent(state, byteProgress);
153 if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
154 // Tell the child the particulars after the update has finished.
155 // Sending the Finish event will release the child side of the protocol
156 // and notify "offline-cache-update-completed" on the child process.
157 bool isUpgrade;
158 aUpdate->GetIsUpgrade(&isUpgrade);
159 bool succeeded;
160 aUpdate->GetSucceeded(&succeeded);
162 unused << SendFinish(succeeded, isUpgrade);
163 }
165 return NS_OK;
166 }
168 NS_IMETHODIMP
169 OfflineCacheUpdateParent::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
170 {
171 if (mIPCClosed)
172 return NS_ERROR_UNEXPECTED;
174 NS_ENSURE_ARG(aApplicationCache);
176 nsCString cacheClientId;
177 aApplicationCache->GetClientID(cacheClientId);
178 nsCString cacheGroupId;
179 aApplicationCache->GetGroupID(cacheGroupId);
181 unused << SendAssociateDocuments(cacheGroupId, cacheClientId);
182 return NS_OK;
183 }
185 //-----------------------------------------------------------------------------
186 // OfflineCacheUpdateParent::nsILoadContext
187 //-----------------------------------------------------------------------------
189 NS_IMETHODIMP
190 OfflineCacheUpdateParent::GetAssociatedWindow(nsIDOMWindow * *aAssociatedWindow)
191 {
192 return NS_ERROR_NOT_IMPLEMENTED;
193 }
195 NS_IMETHODIMP
196 OfflineCacheUpdateParent::GetTopWindow(nsIDOMWindow * *aTopWindow)
197 {
198 return NS_ERROR_NOT_IMPLEMENTED;
199 }
201 NS_IMETHODIMP
202 OfflineCacheUpdateParent::GetTopFrameElement(nsIDOMElement** aElement)
203 {
204 return NS_ERROR_NOT_IMPLEMENTED;
205 }
207 NS_IMETHODIMP
208 OfflineCacheUpdateParent::IsAppOfType(uint32_t appType, bool *_retval)
209 {
210 return NS_ERROR_NOT_IMPLEMENTED;
211 }
213 NS_IMETHODIMP
214 OfflineCacheUpdateParent::GetIsContent(bool *aIsContent)
215 {
216 return NS_ERROR_NOT_IMPLEMENTED;
217 }
219 NS_IMETHODIMP
220 OfflineCacheUpdateParent::GetUsePrivateBrowsing(bool *aUsePrivateBrowsing)
221 {
222 return NS_ERROR_NOT_IMPLEMENTED;
223 }
224 NS_IMETHODIMP
225 OfflineCacheUpdateParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
226 {
227 return NS_ERROR_NOT_IMPLEMENTED;
228 }
230 NS_IMETHODIMP
231 OfflineCacheUpdateParent::SetPrivateBrowsing(bool aUsePrivateBrowsing)
232 {
233 return NS_ERROR_NOT_IMPLEMENTED;
234 }
236 NS_IMETHODIMP
237 OfflineCacheUpdateParent::GetUseRemoteTabs(bool *aUseRemoteTabs)
238 {
239 return NS_ERROR_NOT_IMPLEMENTED;
240 }
242 NS_IMETHODIMP
243 OfflineCacheUpdateParent::SetRemoteTabs(bool aUseRemoteTabs)
244 {
245 return NS_ERROR_NOT_IMPLEMENTED;
246 }
248 NS_IMETHODIMP
249 OfflineCacheUpdateParent::GetIsInBrowserElement(bool *aIsInBrowserElement)
250 {
251 *aIsInBrowserElement = mIsInBrowserElement;
252 return NS_OK;
253 }
255 NS_IMETHODIMP
256 OfflineCacheUpdateParent::GetAppId(uint32_t *aAppId)
257 {
258 *aAppId = mAppId;
259 return NS_OK;
260 }
262 } // docshell
263 } // mozilla