dom/workers/URL.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
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 "URL.h"
michael@0 7
michael@0 8 #include "nsIDocument.h"
michael@0 9 #include "nsIDOMFile.h"
michael@0 10 #include "nsIIOService.h"
michael@0 11 #include "nsPIDOMWindow.h"
michael@0 12
michael@0 13 #include "mozilla/dom/URL.h"
michael@0 14 #include "mozilla/dom/URLBinding.h"
michael@0 15 #include "mozilla/dom/URLSearchParams.h"
michael@0 16 #include "nsGlobalWindow.h"
michael@0 17 #include "nsHostObjectProtocolHandler.h"
michael@0 18 #include "nsNetCID.h"
michael@0 19 #include "nsServiceManagerUtils.h"
michael@0 20 #include "nsThreadUtils.h"
michael@0 21
michael@0 22 #include "File.h"
michael@0 23 #include "WorkerPrivate.h"
michael@0 24 #include "WorkerRunnable.h"
michael@0 25
michael@0 26 BEGIN_WORKERS_NAMESPACE
michael@0 27 using mozilla::dom::GlobalObject;
michael@0 28
michael@0 29 class URLProxy MOZ_FINAL
michael@0 30 {
michael@0 31 public:
michael@0 32 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
michael@0 33
michael@0 34 URLProxy(mozilla::dom::URL* aURL)
michael@0 35 : mURL(aURL)
michael@0 36 {
michael@0 37 AssertIsOnMainThread();
michael@0 38 }
michael@0 39
michael@0 40 mozilla::dom::URL* URL()
michael@0 41 {
michael@0 42 return mURL;
michael@0 43 }
michael@0 44
michael@0 45 nsIURI* URI()
michael@0 46 {
michael@0 47 return mURL->GetURI();
michael@0 48 }
michael@0 49
michael@0 50 void ReleaseURI()
michael@0 51 {
michael@0 52 AssertIsOnMainThread();
michael@0 53 mURL = nullptr;
michael@0 54 }
michael@0 55
michael@0 56 private:
michael@0 57 // Private destructor, to discourage deletion outside of Release():
michael@0 58 ~URLProxy()
michael@0 59 {
michael@0 60 MOZ_ASSERT(!mURL);
michael@0 61 }
michael@0 62
michael@0 63 nsRefPtr<mozilla::dom::URL> mURL;
michael@0 64 };
michael@0 65
michael@0 66 // Base class for the URL runnable objects.
michael@0 67 class URLRunnable : public nsRunnable
michael@0 68 {
michael@0 69 protected:
michael@0 70 WorkerPrivate* mWorkerPrivate;
michael@0 71 nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
michael@0 72
michael@0 73 protected:
michael@0 74 URLRunnable(WorkerPrivate* aWorkerPrivate)
michael@0 75 : mWorkerPrivate(aWorkerPrivate)
michael@0 76 {
michael@0 77 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 78 }
michael@0 79
michael@0 80 public:
michael@0 81 bool
michael@0 82 Dispatch(JSContext* aCx)
michael@0 83 {
michael@0 84 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 85
michael@0 86 AutoSyncLoopHolder syncLoop(mWorkerPrivate);
michael@0 87
michael@0 88 mSyncLoopTarget = syncLoop.EventTarget();
michael@0 89
michael@0 90 if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
michael@0 91 JS_ReportError(aCx, "Failed to dispatch to main thread!");
michael@0 92 return false;
michael@0 93 }
michael@0 94
michael@0 95 return syncLoop.Run();
michael@0 96 }
michael@0 97
michael@0 98 private:
michael@0 99 NS_IMETHOD Run()
michael@0 100 {
michael@0 101 AssertIsOnMainThread();
michael@0 102
michael@0 103 MainThreadRun();
michael@0 104
michael@0 105 nsRefPtr<MainThreadStopSyncLoopRunnable> response =
michael@0 106 new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
michael@0 107 mSyncLoopTarget.forget(),
michael@0 108 true);
michael@0 109 if (!response->Dispatch(nullptr)) {
michael@0 110 NS_WARNING("Failed to dispatch response!");
michael@0 111 }
michael@0 112
michael@0 113 return NS_OK;
michael@0 114 }
michael@0 115
michael@0 116 protected:
michael@0 117 virtual void
michael@0 118 MainThreadRun() = 0;
michael@0 119 };
michael@0 120
michael@0 121 // This class creates an URL from a DOM Blob on the main thread.
michael@0 122 class CreateURLRunnable : public URLRunnable
michael@0 123 {
michael@0 124 private:
michael@0 125 nsIDOMBlob* mBlob;
michael@0 126 nsString& mURL;
michael@0 127
michael@0 128 public:
michael@0 129 CreateURLRunnable(WorkerPrivate* aWorkerPrivate, nsIDOMBlob* aBlob,
michael@0 130 const mozilla::dom::objectURLOptions& aOptions,
michael@0 131 nsString& aURL)
michael@0 132 : URLRunnable(aWorkerPrivate),
michael@0 133 mBlob(aBlob),
michael@0 134 mURL(aURL)
michael@0 135 {
michael@0 136 MOZ_ASSERT(aBlob);
michael@0 137 }
michael@0 138
michael@0 139 void
michael@0 140 MainThreadRun()
michael@0 141 {
michael@0 142 AssertIsOnMainThread();
michael@0 143
michael@0 144 nsCOMPtr<nsIPrincipal> principal;
michael@0 145 nsIDocument* doc = nullptr;
michael@0 146
michael@0 147 nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
michael@0 148 if (window) {
michael@0 149 doc = window->GetExtantDoc();
michael@0 150 if (!doc) {
michael@0 151 SetDOMStringToNull(mURL);
michael@0 152 return;
michael@0 153 }
michael@0 154
michael@0 155 principal = doc->NodePrincipal();
michael@0 156 } else {
michael@0 157 MOZ_ASSERT_IF(!mWorkerPrivate->GetParent(), mWorkerPrivate->IsChromeWorker());
michael@0 158 principal = mWorkerPrivate->GetPrincipal();
michael@0 159 }
michael@0 160
michael@0 161 nsCString url;
michael@0 162 nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
michael@0 163 NS_LITERAL_CSTRING(BLOBURI_SCHEME),
michael@0 164 mBlob, principal, url);
michael@0 165
michael@0 166 if (NS_FAILED(rv)) {
michael@0 167 NS_WARNING("Failed to add data entry for the blob!");
michael@0 168 SetDOMStringToNull(mURL);
michael@0 169 return;
michael@0 170 }
michael@0 171
michael@0 172 if (doc) {
michael@0 173 doc->RegisterHostObjectUri(url);
michael@0 174 } else {
michael@0 175 mWorkerPrivate->RegisterHostObjectURI(url);
michael@0 176 }
michael@0 177
michael@0 178 mURL = NS_ConvertUTF8toUTF16(url);
michael@0 179 }
michael@0 180 };
michael@0 181
michael@0 182 // This class revokes an URL on the main thread.
michael@0 183 class RevokeURLRunnable : public URLRunnable
michael@0 184 {
michael@0 185 private:
michael@0 186 const nsString mURL;
michael@0 187
michael@0 188 public:
michael@0 189 RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
michael@0 190 const nsAString& aURL)
michael@0 191 : URLRunnable(aWorkerPrivate),
michael@0 192 mURL(aURL)
michael@0 193 {}
michael@0 194
michael@0 195 void
michael@0 196 MainThreadRun()
michael@0 197 {
michael@0 198 AssertIsOnMainThread();
michael@0 199
michael@0 200 nsCOMPtr<nsIPrincipal> principal;
michael@0 201 nsIDocument* doc = nullptr;
michael@0 202
michael@0 203 nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
michael@0 204 if (window) {
michael@0 205 doc = window->GetExtantDoc();
michael@0 206 if (!doc) {
michael@0 207 return;
michael@0 208 }
michael@0 209
michael@0 210 principal = doc->NodePrincipal();
michael@0 211 } else {
michael@0 212 MOZ_ASSERT_IF(!mWorkerPrivate->GetParent(), mWorkerPrivate->IsChromeWorker());
michael@0 213 principal = mWorkerPrivate->GetPrincipal();
michael@0 214 }
michael@0 215
michael@0 216 NS_ConvertUTF16toUTF8 url(mURL);
michael@0 217
michael@0 218 nsIPrincipal* urlPrincipal =
michael@0 219 nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
michael@0 220
michael@0 221 bool subsumes;
michael@0 222 if (urlPrincipal &&
michael@0 223 NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
michael@0 224 subsumes) {
michael@0 225 if (doc) {
michael@0 226 doc->UnregisterHostObjectUri(url);
michael@0 227 }
michael@0 228
michael@0 229 nsHostObjectProtocolHandler::RemoveDataEntry(url);
michael@0 230 }
michael@0 231
michael@0 232 if (!window) {
michael@0 233 mWorkerPrivate->UnregisterHostObjectURI(url);
michael@0 234 }
michael@0 235 }
michael@0 236 };
michael@0 237
michael@0 238 // This class creates a URL object on the main thread.
michael@0 239 class ConstructorRunnable : public URLRunnable
michael@0 240 {
michael@0 241 private:
michael@0 242 const nsString mURL;
michael@0 243
michael@0 244 const nsString mBase;
michael@0 245 nsRefPtr<URLProxy> mBaseProxy;
michael@0 246 mozilla::ErrorResult& mRv;
michael@0 247
michael@0 248 nsRefPtr<URLProxy> mRetval;
michael@0 249
michael@0 250 public:
michael@0 251 ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
michael@0 252 const nsAString& aURL, const nsAString& aBase,
michael@0 253 mozilla::ErrorResult& aRv)
michael@0 254 : URLRunnable(aWorkerPrivate)
michael@0 255 , mURL(aURL)
michael@0 256 , mBase(aBase)
michael@0 257 , mRv(aRv)
michael@0 258 {
michael@0 259 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 260 }
michael@0 261
michael@0 262 ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
michael@0 263 const nsAString& aURL, URLProxy* aBaseProxy,
michael@0 264 mozilla::ErrorResult& aRv)
michael@0 265 : URLRunnable(aWorkerPrivate)
michael@0 266 , mURL(aURL)
michael@0 267 , mBaseProxy(aBaseProxy)
michael@0 268 , mRv(aRv)
michael@0 269 {
michael@0 270 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 271 }
michael@0 272
michael@0 273 void
michael@0 274 MainThreadRun()
michael@0 275 {
michael@0 276 AssertIsOnMainThread();
michael@0 277
michael@0 278 nsresult rv;
michael@0 279 nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
michael@0 280 if (NS_FAILED(rv)) {
michael@0 281 mRv.Throw(rv);
michael@0 282 return;
michael@0 283 }
michael@0 284
michael@0 285 nsCOMPtr<nsIURI> baseURL;
michael@0 286
michael@0 287 if (!mBaseProxy) {
michael@0 288 rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mBase), nullptr, nullptr,
michael@0 289 getter_AddRefs(baseURL));
michael@0 290 if (NS_FAILED(rv)) {
michael@0 291 mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
michael@0 292 return;
michael@0 293 }
michael@0 294 } else {
michael@0 295 baseURL = mBaseProxy->URI();
michael@0 296 }
michael@0 297
michael@0 298 nsCOMPtr<nsIURI> url;
michael@0 299 rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mURL), nullptr, baseURL,
michael@0 300 getter_AddRefs(url));
michael@0 301 if (NS_FAILED(rv)) {
michael@0 302 mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
michael@0 303 return;
michael@0 304 }
michael@0 305
michael@0 306 mRetval = new URLProxy(new mozilla::dom::URL(url));
michael@0 307 }
michael@0 308
michael@0 309 URLProxy*
michael@0 310 GetURLProxy()
michael@0 311 {
michael@0 312 return mRetval;
michael@0 313 }
michael@0 314 };
michael@0 315
michael@0 316 class TeardownURLRunnable : public nsRunnable
michael@0 317 {
michael@0 318 public:
michael@0 319 TeardownURLRunnable(URLProxy* aURLProxy)
michael@0 320 : mURLProxy(aURLProxy)
michael@0 321 {
michael@0 322 }
michael@0 323
michael@0 324 NS_IMETHOD Run()
michael@0 325 {
michael@0 326 AssertIsOnMainThread();
michael@0 327
michael@0 328 mURLProxy->ReleaseURI();
michael@0 329 mURLProxy = nullptr;
michael@0 330
michael@0 331 return NS_OK;
michael@0 332 }
michael@0 333
michael@0 334 private:
michael@0 335 nsRefPtr<URLProxy> mURLProxy;
michael@0 336 };
michael@0 337
michael@0 338 // This class is the generic getter for any URL property.
michael@0 339 class GetterRunnable : public URLRunnable
michael@0 340 {
michael@0 341 public:
michael@0 342 enum GetterType {
michael@0 343 GetterHref,
michael@0 344 GetterOrigin,
michael@0 345 GetterProtocol,
michael@0 346 GetterUsername,
michael@0 347 GetterPassword,
michael@0 348 GetterHost,
michael@0 349 GetterHostname,
michael@0 350 GetterPort,
michael@0 351 GetterPathname,
michael@0 352 GetterSearch,
michael@0 353 GetterHash,
michael@0 354 };
michael@0 355
michael@0 356 GetterRunnable(WorkerPrivate* aWorkerPrivate,
michael@0 357 GetterType aType, nsString& aValue,
michael@0 358 URLProxy* aURLProxy)
michael@0 359 : URLRunnable(aWorkerPrivate)
michael@0 360 , mValue(aValue)
michael@0 361 , mType(aType)
michael@0 362 , mURLProxy(aURLProxy)
michael@0 363 {
michael@0 364 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 365 }
michael@0 366
michael@0 367 void
michael@0 368 MainThreadRun()
michael@0 369 {
michael@0 370 AssertIsOnMainThread();
michael@0 371
michael@0 372 switch (mType) {
michael@0 373 case GetterHref:
michael@0 374 mURLProxy->URL()->GetHref(mValue);
michael@0 375 break;
michael@0 376
michael@0 377 case GetterOrigin:
michael@0 378 mURLProxy->URL()->GetOrigin(mValue);
michael@0 379 break;
michael@0 380
michael@0 381 case GetterProtocol:
michael@0 382 mURLProxy->URL()->GetProtocol(mValue);
michael@0 383 break;
michael@0 384
michael@0 385 case GetterUsername:
michael@0 386 mURLProxy->URL()->GetUsername(mValue);
michael@0 387 break;
michael@0 388
michael@0 389 case GetterPassword:
michael@0 390 mURLProxy->URL()->GetPassword(mValue);
michael@0 391 break;
michael@0 392
michael@0 393 case GetterHost:
michael@0 394 mURLProxy->URL()->GetHost(mValue);
michael@0 395 break;
michael@0 396
michael@0 397 case GetterHostname:
michael@0 398 mURLProxy->URL()->GetHostname(mValue);
michael@0 399 break;
michael@0 400
michael@0 401 case GetterPort:
michael@0 402 mURLProxy->URL()->GetPort(mValue);
michael@0 403 break;
michael@0 404
michael@0 405 case GetterPathname:
michael@0 406 mURLProxy->URL()->GetPathname(mValue);
michael@0 407 break;
michael@0 408
michael@0 409 case GetterSearch:
michael@0 410 mURLProxy->URL()->GetSearch(mValue);
michael@0 411 break;
michael@0 412
michael@0 413 case GetterHash:
michael@0 414 mURLProxy->URL()->GetHash(mValue);
michael@0 415 break;
michael@0 416 }
michael@0 417 }
michael@0 418
michael@0 419 private:
michael@0 420 nsString& mValue;
michael@0 421 GetterType mType;
michael@0 422 nsRefPtr<URLProxy> mURLProxy;
michael@0 423 };
michael@0 424
michael@0 425 // This class is the generic setter for any URL property.
michael@0 426 class SetterRunnable : public URLRunnable
michael@0 427 {
michael@0 428 public:
michael@0 429 enum SetterType {
michael@0 430 SetterHref,
michael@0 431 SetterProtocol,
michael@0 432 SetterUsername,
michael@0 433 SetterPassword,
michael@0 434 SetterHost,
michael@0 435 SetterHostname,
michael@0 436 SetterPort,
michael@0 437 SetterPathname,
michael@0 438 SetterSearch,
michael@0 439 SetterHash,
michael@0 440 };
michael@0 441
michael@0 442 SetterRunnable(WorkerPrivate* aWorkerPrivate,
michael@0 443 SetterType aType, const nsAString& aValue,
michael@0 444 URLProxy* aURLProxy, mozilla::ErrorResult& aRv)
michael@0 445 : URLRunnable(aWorkerPrivate)
michael@0 446 , mValue(aValue)
michael@0 447 , mType(aType)
michael@0 448 , mURLProxy(aURLProxy)
michael@0 449 , mRv(aRv)
michael@0 450 {
michael@0 451 mWorkerPrivate->AssertIsOnWorkerThread();
michael@0 452 }
michael@0 453
michael@0 454 void
michael@0 455 MainThreadRun()
michael@0 456 {
michael@0 457 AssertIsOnMainThread();
michael@0 458
michael@0 459 switch (mType) {
michael@0 460 case SetterHref:
michael@0 461 mURLProxy->URL()->SetHref(mValue, mRv);
michael@0 462 break;
michael@0 463
michael@0 464 case SetterProtocol:
michael@0 465 mURLProxy->URL()->SetProtocol(mValue);
michael@0 466 break;
michael@0 467
michael@0 468 case SetterUsername:
michael@0 469 mURLProxy->URL()->SetUsername(mValue);
michael@0 470 break;
michael@0 471
michael@0 472 case SetterPassword:
michael@0 473 mURLProxy->URL()->SetPassword(mValue);
michael@0 474 break;
michael@0 475
michael@0 476 case SetterHost:
michael@0 477 mURLProxy->URL()->SetHost(mValue);
michael@0 478 break;
michael@0 479
michael@0 480 case SetterHostname:
michael@0 481 mURLProxy->URL()->SetHostname(mValue);
michael@0 482 break;
michael@0 483
michael@0 484 case SetterPort:
michael@0 485 mURLProxy->URL()->SetPort(mValue);
michael@0 486 break;
michael@0 487
michael@0 488 case SetterPathname:
michael@0 489 mURLProxy->URL()->SetPathname(mValue);
michael@0 490 break;
michael@0 491
michael@0 492 case SetterSearch:
michael@0 493 mURLProxy->URL()->SetSearch(mValue);
michael@0 494 break;
michael@0 495
michael@0 496 case SetterHash:
michael@0 497 mURLProxy->URL()->SetHash(mValue);
michael@0 498 break;
michael@0 499 }
michael@0 500 }
michael@0 501
michael@0 502 private:
michael@0 503 const nsString mValue;
michael@0 504 SetterType mType;
michael@0 505 nsRefPtr<URLProxy> mURLProxy;
michael@0 506 mozilla::ErrorResult& mRv;
michael@0 507 };
michael@0 508
michael@0 509 NS_IMPL_CYCLE_COLLECTION(URL, mSearchParams)
michael@0 510
michael@0 511 // The reason for using worker::URL is to have different refcnt logging than
michael@0 512 // for main thread URL.
michael@0 513 NS_IMPL_CYCLE_COLLECTING_ADDREF(workers::URL)
michael@0 514 NS_IMPL_CYCLE_COLLECTING_RELEASE(workers::URL)
michael@0 515
michael@0 516 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
michael@0 517 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 518 NS_INTERFACE_MAP_END
michael@0 519
michael@0 520 // static
michael@0 521 URL*
michael@0 522 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
michael@0 523 URL& aBase, ErrorResult& aRv)
michael@0 524 {
michael@0 525 JSContext* cx = aGlobal.GetContext();
michael@0 526 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
michael@0 527
michael@0 528 nsRefPtr<ConstructorRunnable> runnable =
michael@0 529 new ConstructorRunnable(workerPrivate, aUrl, aBase.GetURLProxy(), aRv);
michael@0 530
michael@0 531 if (!runnable->Dispatch(cx)) {
michael@0 532 JS_ReportPendingException(cx);
michael@0 533 }
michael@0 534
michael@0 535 nsRefPtr<URLProxy> proxy = runnable->GetURLProxy();
michael@0 536 if (!proxy) {
michael@0 537 aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
michael@0 538 return nullptr;
michael@0 539 }
michael@0 540
michael@0 541 return new URL(workerPrivate, proxy);
michael@0 542 }
michael@0 543
michael@0 544 // static
michael@0 545 URL*
michael@0 546 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
michael@0 547 const nsAString& aBase, ErrorResult& aRv)
michael@0 548 {
michael@0 549 JSContext* cx = aGlobal.GetContext();
michael@0 550 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
michael@0 551
michael@0 552 nsRefPtr<ConstructorRunnable> runnable =
michael@0 553 new ConstructorRunnable(workerPrivate, aUrl, aBase, aRv);
michael@0 554
michael@0 555 if (!runnable->Dispatch(cx)) {
michael@0 556 JS_ReportPendingException(cx);
michael@0 557 }
michael@0 558
michael@0 559 nsRefPtr<URLProxy> proxy = runnable->GetURLProxy();
michael@0 560 if (!proxy) {
michael@0 561 aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
michael@0 562 return nullptr;
michael@0 563 }
michael@0 564
michael@0 565 return new URL(workerPrivate, proxy);
michael@0 566 }
michael@0 567
michael@0 568 URL::URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy)
michael@0 569 : mWorkerPrivate(aWorkerPrivate)
michael@0 570 , mURLProxy(aURLProxy)
michael@0 571 {
michael@0 572 MOZ_COUNT_CTOR(workers::URL);
michael@0 573 }
michael@0 574
michael@0 575 URL::~URL()
michael@0 576 {
michael@0 577 MOZ_COUNT_DTOR(workers::URL);
michael@0 578
michael@0 579 if (mURLProxy) {
michael@0 580 nsRefPtr<TeardownURLRunnable> runnable =
michael@0 581 new TeardownURLRunnable(mURLProxy);
michael@0 582 mURLProxy = nullptr;
michael@0 583
michael@0 584 if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
michael@0 585 NS_ERROR("Failed to dispatch teardown runnable!");
michael@0 586 }
michael@0 587 }
michael@0 588 }
michael@0 589
michael@0 590 JSObject*
michael@0 591 URL::WrapObject(JSContext* aCx)
michael@0 592 {
michael@0 593 return URLBinding_workers::Wrap(aCx, this);
michael@0 594 }
michael@0 595
michael@0 596 void
michael@0 597 URL::GetHref(nsString& aHref) const
michael@0 598 {
michael@0 599 nsRefPtr<GetterRunnable> runnable =
michael@0 600 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
michael@0 601 mURLProxy);
michael@0 602
michael@0 603 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 604 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 605 }
michael@0 606 }
michael@0 607
michael@0 608 void
michael@0 609 URL::SetHref(const nsAString& aHref, ErrorResult& aRv)
michael@0 610 {
michael@0 611 nsRefPtr<SetterRunnable> runnable =
michael@0 612 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref,
michael@0 613 mURLProxy, aRv);
michael@0 614
michael@0 615 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 616 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 617 }
michael@0 618
michael@0 619 UpdateURLSearchParams();
michael@0 620 }
michael@0 621
michael@0 622 void
michael@0 623 URL::GetOrigin(nsString& aOrigin) const
michael@0 624 {
michael@0 625 nsRefPtr<GetterRunnable> runnable =
michael@0 626 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin,
michael@0 627 mURLProxy);
michael@0 628
michael@0 629 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 630 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 631 }
michael@0 632 }
michael@0 633
michael@0 634 void
michael@0 635 URL::GetProtocol(nsString& aProtocol) const
michael@0 636 {
michael@0 637 nsRefPtr<GetterRunnable> runnable =
michael@0 638 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol,
michael@0 639 mURLProxy);
michael@0 640
michael@0 641 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 642 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 643 }
michael@0 644 }
michael@0 645
michael@0 646 void
michael@0 647 URL::SetProtocol(const nsAString& aProtocol)
michael@0 648 {
michael@0 649 ErrorResult rv;
michael@0 650 nsRefPtr<SetterRunnable> runnable =
michael@0 651 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol,
michael@0 652 aProtocol, mURLProxy, rv);
michael@0 653
michael@0 654 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 655 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 656 }
michael@0 657 }
michael@0 658
michael@0 659 void
michael@0 660 URL::GetUsername(nsString& aUsername) const
michael@0 661 {
michael@0 662 nsRefPtr<GetterRunnable> runnable =
michael@0 663 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername,
michael@0 664 mURLProxy);
michael@0 665
michael@0 666 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 667 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 668 }
michael@0 669 }
michael@0 670
michael@0 671 void
michael@0 672 URL::SetUsername(const nsAString& aUsername)
michael@0 673 {
michael@0 674 ErrorResult rv;
michael@0 675 nsRefPtr<SetterRunnable> runnable =
michael@0 676 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername,
michael@0 677 aUsername, mURLProxy, rv);
michael@0 678
michael@0 679 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 680 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 681 }
michael@0 682 }
michael@0 683
michael@0 684 void
michael@0 685 URL::GetPassword(nsString& aPassword) const
michael@0 686 {
michael@0 687 nsRefPtr<GetterRunnable> runnable =
michael@0 688 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword,
michael@0 689 mURLProxy);
michael@0 690
michael@0 691 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 692 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 693 }
michael@0 694 }
michael@0 695
michael@0 696 void
michael@0 697 URL::SetPassword(const nsAString& aPassword)
michael@0 698 {
michael@0 699 ErrorResult rv;
michael@0 700 nsRefPtr<SetterRunnable> runnable =
michael@0 701 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword,
michael@0 702 aPassword, mURLProxy, rv);
michael@0 703
michael@0 704 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 705 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 706 }
michael@0 707 }
michael@0 708
michael@0 709 void
michael@0 710 URL::GetHost(nsString& aHost) const
michael@0 711 {
michael@0 712 nsRefPtr<GetterRunnable> runnable =
michael@0 713 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost,
michael@0 714 mURLProxy);
michael@0 715
michael@0 716 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 717 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 718 }
michael@0 719 }
michael@0 720
michael@0 721 void
michael@0 722 URL::SetHost(const nsAString& aHost)
michael@0 723 {
michael@0 724 ErrorResult rv;
michael@0 725 nsRefPtr<SetterRunnable> runnable =
michael@0 726 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost,
michael@0 727 aHost, mURLProxy, rv);
michael@0 728
michael@0 729 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 730 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 731 }
michael@0 732 }
michael@0 733
michael@0 734 void
michael@0 735 URL::GetHostname(nsString& aHostname) const
michael@0 736 {
michael@0 737 nsRefPtr<GetterRunnable> runnable =
michael@0 738 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname,
michael@0 739 mURLProxy);
michael@0 740
michael@0 741 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 742 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 743 }
michael@0 744 }
michael@0 745
michael@0 746 void
michael@0 747 URL::SetHostname(const nsAString& aHostname)
michael@0 748 {
michael@0 749 ErrorResult rv;
michael@0 750 nsRefPtr<SetterRunnable> runnable =
michael@0 751 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname,
michael@0 752 aHostname, mURLProxy, rv);
michael@0 753
michael@0 754 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 755 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 756 }
michael@0 757 }
michael@0 758
michael@0 759 void
michael@0 760 URL::GetPort(nsString& aPort) const
michael@0 761 {
michael@0 762 nsRefPtr<GetterRunnable> runnable =
michael@0 763 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort,
michael@0 764 mURLProxy);
michael@0 765
michael@0 766 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 767 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 768 }
michael@0 769 }
michael@0 770
michael@0 771 void
michael@0 772 URL::SetPort(const nsAString& aPort)
michael@0 773 {
michael@0 774 ErrorResult rv;
michael@0 775 nsRefPtr<SetterRunnable> runnable =
michael@0 776 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort,
michael@0 777 aPort, mURLProxy, rv);
michael@0 778
michael@0 779 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 780 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 781 }
michael@0 782 }
michael@0 783
michael@0 784 void
michael@0 785 URL::GetPathname(nsString& aPathname) const
michael@0 786 {
michael@0 787 nsRefPtr<GetterRunnable> runnable =
michael@0 788 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, aPathname,
michael@0 789 mURLProxy);
michael@0 790
michael@0 791 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 792 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 793 }
michael@0 794 }
michael@0 795
michael@0 796 void
michael@0 797 URL::SetPathname(const nsAString& aPathname)
michael@0 798 {
michael@0 799 ErrorResult rv;
michael@0 800 nsRefPtr<SetterRunnable> runnable =
michael@0 801 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname,
michael@0 802 aPathname, mURLProxy, rv);
michael@0 803
michael@0 804 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 805 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 806 }
michael@0 807 }
michael@0 808
michael@0 809 void
michael@0 810 URL::GetSearch(nsString& aSearch) const
michael@0 811 {
michael@0 812 nsRefPtr<GetterRunnable> runnable =
michael@0 813 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch,
michael@0 814 mURLProxy);
michael@0 815
michael@0 816 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 817 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 818 }
michael@0 819 }
michael@0 820
michael@0 821 void
michael@0 822 URL::SetSearch(const nsAString& aSearch)
michael@0 823 {
michael@0 824 SetSearchInternal(aSearch);
michael@0 825 UpdateURLSearchParams();
michael@0 826 }
michael@0 827
michael@0 828 void
michael@0 829 URL::SetSearchInternal(const nsAString& aSearch)
michael@0 830 {
michael@0 831 ErrorResult rv;
michael@0 832 nsRefPtr<SetterRunnable> runnable =
michael@0 833 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch,
michael@0 834 aSearch, mURLProxy, rv);
michael@0 835
michael@0 836 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 837 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 838 }
michael@0 839 }
michael@0 840
michael@0 841 mozilla::dom::URLSearchParams*
michael@0 842 URL::SearchParams()
michael@0 843 {
michael@0 844 CreateSearchParamsIfNeeded();
michael@0 845 return mSearchParams;
michael@0 846 }
michael@0 847
michael@0 848 void
michael@0 849 URL::SetSearchParams(URLSearchParams& aSearchParams)
michael@0 850 {
michael@0 851 if (mSearchParams) {
michael@0 852 mSearchParams->RemoveObserver(this);
michael@0 853 }
michael@0 854
michael@0 855 mSearchParams = &aSearchParams;
michael@0 856 mSearchParams->AddObserver(this);
michael@0 857
michael@0 858 nsString search;
michael@0 859 mSearchParams->Serialize(search);
michael@0 860 SetSearchInternal(search);
michael@0 861 }
michael@0 862
michael@0 863 void
michael@0 864 URL::GetHash(nsString& aHash) const
michael@0 865 {
michael@0 866 nsRefPtr<GetterRunnable> runnable =
michael@0 867 new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash,
michael@0 868 mURLProxy);
michael@0 869
michael@0 870 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 871 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 872 }
michael@0 873 }
michael@0 874
michael@0 875 void
michael@0 876 URL::SetHash(const nsAString& aHash)
michael@0 877 {
michael@0 878 ErrorResult rv;
michael@0 879 nsRefPtr<SetterRunnable> runnable =
michael@0 880 new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash,
michael@0 881 aHash, mURLProxy, rv);
michael@0 882
michael@0 883 if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
michael@0 884 JS_ReportPendingException(mWorkerPrivate->GetJSContext());
michael@0 885 }
michael@0 886 }
michael@0 887
michael@0 888 // static
michael@0 889 void
michael@0 890 URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob,
michael@0 891 const mozilla::dom::objectURLOptions& aOptions,
michael@0 892 nsString& aResult, mozilla::ErrorResult& aRv)
michael@0 893 {
michael@0 894 JSContext* cx = aGlobal.GetContext();
michael@0 895 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
michael@0 896
michael@0 897 nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob);
michael@0 898 if (!blob) {
michael@0 899 SetDOMStringToNull(aResult);
michael@0 900
michael@0 901 NS_NAMED_LITERAL_STRING(argStr, "Argument 1 of URL.createObjectURL");
michael@0 902 NS_NAMED_LITERAL_STRING(blobStr, "Blob");
michael@0 903 aRv.ThrowTypeError(MSG_DOES_NOT_IMPLEMENT_INTERFACE, &argStr, &blobStr);
michael@0 904 return;
michael@0 905 }
michael@0 906
michael@0 907 nsRefPtr<CreateURLRunnable> runnable =
michael@0 908 new CreateURLRunnable(workerPrivate, blob, aOptions, aResult);
michael@0 909
michael@0 910 if (!runnable->Dispatch(cx)) {
michael@0 911 JS_ReportPendingException(cx);
michael@0 912 }
michael@0 913 }
michael@0 914
michael@0 915 // static
michael@0 916 void
michael@0 917 URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject& aBlob,
michael@0 918 const mozilla::dom::objectURLOptions& aOptions,
michael@0 919 nsString& aResult, mozilla::ErrorResult& aRv)
michael@0 920 {
michael@0 921 return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv);
michael@0 922 }
michael@0 923
michael@0 924 // static
michael@0 925 void
michael@0 926 URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl)
michael@0 927 {
michael@0 928 JSContext* cx = aGlobal.GetContext();
michael@0 929 WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
michael@0 930
michael@0 931 nsRefPtr<RevokeURLRunnable> runnable =
michael@0 932 new RevokeURLRunnable(workerPrivate, aUrl);
michael@0 933
michael@0 934 if (!runnable->Dispatch(cx)) {
michael@0 935 JS_ReportPendingException(cx);
michael@0 936 }
michael@0 937 }
michael@0 938
michael@0 939 void
michael@0 940 URL::URLSearchParamsUpdated()
michael@0 941 {
michael@0 942 MOZ_ASSERT(mSearchParams);
michael@0 943
michael@0 944 nsString search;
michael@0 945 mSearchParams->Serialize(search);
michael@0 946 SetSearchInternal(search);
michael@0 947 }
michael@0 948
michael@0 949 void
michael@0 950 URL::UpdateURLSearchParams()
michael@0 951 {
michael@0 952 if (mSearchParams) {
michael@0 953 nsString search;
michael@0 954 GetSearch(search);
michael@0 955 mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1)), this);
michael@0 956 }
michael@0 957 }
michael@0 958
michael@0 959 void
michael@0 960 URL::CreateSearchParamsIfNeeded()
michael@0 961 {
michael@0 962 if (!mSearchParams) {
michael@0 963 mSearchParams = new URLSearchParams();
michael@0 964 mSearchParams->AddObserver(this);
michael@0 965 UpdateURLSearchParams();
michael@0 966 }
michael@0 967 }
michael@0 968
michael@0 969 END_WORKERS_NAMESPACE

mercurial