bug 700693 - OCSP stapling PSM changes r=bsmith
[gecko.git] / dom / workers / URL.cpp
blobc1220fbab2c44fa5b146e646b99394027ba0f11e
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
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 "URL.h"
7 #include "File.h"
9 #include "nsTraceRefcnt.h"
11 #include "WorkerPrivate.h"
12 #include "nsThreadUtils.h"
14 #include "nsPIDOMWindow.h"
15 #include "nsGlobalWindow.h"
16 #include "nsHostObjectProtocolHandler.h"
18 #include "nsIDocument.h"
19 #include "nsIDOMFile.h"
21 USING_WORKERS_NAMESPACE
22 using mozilla::dom::WorkerGlobalObject;
24 // Base class for the Revoke and Create runnable objects.
25 class URLRunnable : public nsRunnable
27 protected:
28 WorkerPrivate* mWorkerPrivate;
29 uint32_t mSyncQueueKey;
31 private:
32 class ResponseRunnable : public WorkerSyncRunnable
34 uint32_t mSyncQueueKey;
36 public:
37 ResponseRunnable(WorkerPrivate* aWorkerPrivate,
38 uint32_t aSyncQueueKey)
39 : WorkerSyncRunnable(aWorkerPrivate, aSyncQueueKey, false),
40 mSyncQueueKey(aSyncQueueKey)
42 NS_ASSERTION(aWorkerPrivate, "Don't hand me a null WorkerPrivate!");
45 bool
46 WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
48 aWorkerPrivate->StopSyncLoop(mSyncQueueKey, true);
49 return true;
52 bool
53 PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
55 AssertIsOnMainThread();
56 return true;
59 void
60 PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
61 bool aDispatchResult)
63 AssertIsOnMainThread();
67 protected:
68 URLRunnable(WorkerPrivate* aWorkerPrivate)
69 : mWorkerPrivate(aWorkerPrivate)
71 mWorkerPrivate->AssertIsOnWorkerThread();
74 public:
75 bool
76 Dispatch(JSContext* aCx)
78 mWorkerPrivate->AssertIsOnWorkerThread();
79 mSyncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
81 if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
82 JS_ReportError(aCx, "Failed to dispatch to main thread!");
83 mWorkerPrivate->StopSyncLoop(mSyncQueueKey, false);
84 return false;
87 return mWorkerPrivate->RunSyncLoop(aCx, mSyncQueueKey);
90 private:
91 NS_IMETHOD Run()
93 AssertIsOnMainThread();
95 MainThreadRun();
97 nsRefPtr<ResponseRunnable> response =
98 new ResponseRunnable(mWorkerPrivate, mSyncQueueKey);
99 if (!response->Dispatch(nullptr)) {
100 NS_WARNING("Failed to dispatch response!");
103 return NS_OK;
106 protected:
107 virtual void
108 MainThreadRun() = 0;
111 // This class creates an URL from a DOM Blob on the main thread.
112 class CreateURLRunnable : public URLRunnable
114 private:
115 nsIDOMBlob* mBlob;
116 nsString& mURL;
118 public:
119 CreateURLRunnable(WorkerPrivate* aWorkerPrivate, nsIDOMBlob* aBlob,
120 const mozilla::dom::objectURLOptionsWorkers& aOptions,
121 nsString& aURL)
122 : URLRunnable(aWorkerPrivate),
123 mBlob(aBlob),
124 mURL(aURL)
126 MOZ_ASSERT(aBlob);
129 void
130 MainThreadRun()
132 AssertIsOnMainThread();
134 nsCOMPtr<nsIPrincipal> principal;
135 nsIDocument* doc = nullptr;
137 nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
138 if (window) {
139 doc = window->GetExtantDoc();
140 if (!doc) {
141 SetDOMStringToNull(mURL);
142 return;
145 principal = doc->NodePrincipal();
146 } else {
147 MOZ_ASSERT(mWorkerPrivate->IsChromeWorker());
148 principal = mWorkerPrivate->GetPrincipal();
151 nsCString url;
152 nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
153 NS_LITERAL_CSTRING(BLOBURI_SCHEME),
154 mBlob, principal, url);
156 if (NS_FAILED(rv)) {
157 NS_WARNING("Failed to add data entry for the blob!");
158 SetDOMStringToNull(mURL);
159 return;
162 if (doc) {
163 doc->RegisterHostObjectUri(url);
164 } else {
165 mWorkerPrivate->RegisterHostObjectURI(url);
168 mURL = NS_ConvertUTF8toUTF16(url);
172 // This class revokes an URL on the main thread.
173 class RevokeURLRunnable : public URLRunnable
175 private:
176 const nsString mURL;
178 public:
179 RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
180 const nsAString& aURL)
181 : URLRunnable(aWorkerPrivate),
182 mURL(aURL)
185 void
186 MainThreadRun()
188 AssertIsOnMainThread();
190 nsCOMPtr<nsIPrincipal> principal;
191 nsIDocument* doc = nullptr;
193 nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
194 if (window) {
195 doc = window->GetExtantDoc();
196 if (!doc) {
197 return;
200 principal = doc->NodePrincipal();
201 } else {
202 MOZ_ASSERT(mWorkerPrivate->IsChromeWorker());
203 principal = mWorkerPrivate->GetPrincipal();
206 NS_ConvertUTF16toUTF8 url(mURL);
208 nsIPrincipal* urlPrincipal =
209 nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
211 bool subsumes;
212 if (urlPrincipal &&
213 NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
214 subsumes) {
215 if (doc) {
216 doc->UnregisterHostObjectUri(url);
219 nsHostObjectProtocolHandler::RemoveDataEntry(url);
222 if (!window) {
223 mWorkerPrivate->UnregisterHostObjectURI(url);
228 // static
229 void
230 URL::CreateObjectURL(const WorkerGlobalObject& aGlobal, JSObject* aBlob,
231 const mozilla::dom::objectURLOptionsWorkers& aOptions,
232 nsString& aResult, mozilla::ErrorResult& aRv)
234 JSContext* cx = aGlobal.GetContext();
235 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
237 nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob);
238 if (!blob) {
239 SetDOMStringToNull(aResult);
241 NS_NAMED_LITERAL_STRING(argStr, "Argument 1 of URL.createObjectURL");
242 NS_NAMED_LITERAL_STRING(blobStr, "Blob");
243 aRv.ThrowTypeError(MSG_DOES_NOT_IMPLEMENT_INTERFACE, &argStr, &blobStr);
244 return;
247 nsRefPtr<CreateURLRunnable> runnable =
248 new CreateURLRunnable(workerPrivate, blob, aOptions, aResult);
250 if (!runnable->Dispatch(cx)) {
251 JS_ReportPendingException(cx);
255 // static
256 void
257 URL::CreateObjectURL(const WorkerGlobalObject& aGlobal, JSObject& aBlob,
258 const mozilla::dom::objectURLOptionsWorkers& aOptions,
259 nsString& aResult, mozilla::ErrorResult& aRv)
261 return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv);
264 // static
265 void
266 URL::RevokeObjectURL(const WorkerGlobalObject& aGlobal, const nsAString& aUrl)
268 JSContext* cx = aGlobal.GetContext();
269 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
271 nsRefPtr<RevokeURLRunnable> runnable =
272 new RevokeURLRunnable(workerPrivate, aUrl);
274 if (!runnable->Dispatch(cx)) {
275 JS_ReportPendingException(cx);