mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Backed out 2 changesets (bug 1558923) for mochitest crashes on AssertIsOnMainThread(). CLOSED TREE
Backed out changeset 643de99320a8 (bug 1558923) Backed out changeset f758b5ccd0c0 (bug 1558923)
This commit is contained in:
parent
9b7249b587
commit
8e2da98d46
@ -5745,6 +5745,7 @@ nsresult nsContentUtils::GetASCIIOrigin(nsIPrincipal* aPrincipal,
|
||||
/* static */
|
||||
nsresult nsContentUtils::GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin) {
|
||||
MOZ_ASSERT(aURI, "missing uri");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool isBlobURL = false;
|
||||
nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL);
|
||||
@ -5795,6 +5796,69 @@ nsresult nsContentUtils::GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult nsContentUtils::GetThreadSafeASCIIOrigin(nsIURI* aURI,
|
||||
nsACString& aOrigin) {
|
||||
MOZ_ASSERT(aURI, "missing uri");
|
||||
|
||||
bool isBlobURL = false;
|
||||
nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// For Blob URI, the path is the URL of the owning page.
|
||||
if (isBlobURL) {
|
||||
nsAutoCString path;
|
||||
rv = aURI->GetPathQueryRef(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), path);
|
||||
if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
aOrigin.AssignLiteral("null");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return GetThreadSafeASCIIOrigin(uri, aOrigin);
|
||||
}
|
||||
|
||||
aOrigin.Truncate();
|
||||
|
||||
// This is not supported yet.
|
||||
nsCOMPtr<nsINestedURI> nestedURI(do_QueryInterface(aURI));
|
||||
if (nestedURI) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
nsAutoCString host;
|
||||
rv = aURI->GetAsciiHost(host);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !host.IsEmpty()) {
|
||||
nsAutoCString userPass;
|
||||
aURI->GetUserPass(userPass);
|
||||
|
||||
nsCOMPtr<nsIURI> uri = aURI;
|
||||
|
||||
nsAutoCString prePath;
|
||||
if (!userPass.IsEmpty()) {
|
||||
rv = NS_MutateURI(uri).SetUserPass(EmptyCString()).Finalize(uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = uri->GetPrePath(prePath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aOrigin = prePath;
|
||||
} else {
|
||||
aOrigin.AssignLiteral("null");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal,
|
||||
nsAString& aOrigin) {
|
||||
@ -5813,6 +5877,7 @@ nsresult nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal,
|
||||
/* static */
|
||||
nsresult nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) {
|
||||
MOZ_ASSERT(aURI, "missing uri");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsresult rv;
|
||||
|
||||
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
|
||||
@ -5836,6 +5901,24 @@ nsresult nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult nsContentUtils::GetThreadSafeUTFOrigin(nsIURI* aURI,
|
||||
nsAString& aOrigin) {
|
||||
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(aURI, "missing uri");
|
||||
nsresult rv;
|
||||
|
||||
nsAutoCString asciiOrigin;
|
||||
rv = GetThreadSafeASCIIOrigin(aURI, asciiOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aOrigin = NS_ConvertUTF8toUTF16(asciiOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool nsContentUtils::CheckMayLoad(nsIPrincipal* aPrincipal,
|
||||
nsIChannel* aChannel,
|
||||
|
@ -2141,8 +2141,10 @@ class nsContentUtils {
|
||||
*/
|
||||
static nsresult GetASCIIOrigin(nsIPrincipal* aPrincipal, nsACString& aOrigin);
|
||||
static nsresult GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin);
|
||||
static nsresult GetThreadSafeASCIIOrigin(nsIURI* aURI, nsACString& aOrigin);
|
||||
static nsresult GetUTFOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin);
|
||||
static nsresult GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin);
|
||||
static nsresult GetThreadSafeUTFOrigin(nsIURI* aURI, nsAString& aOrigin);
|
||||
|
||||
/**
|
||||
* This method creates and dispatches "command" event, which implements
|
||||
|
@ -178,8 +178,7 @@ already_AddRefed<URL> ParseURLFromWorker(const GlobalObject& aGlobal,
|
||||
worker->AssertIsOnWorkerThread();
|
||||
|
||||
NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref);
|
||||
RefPtr<URL> url =
|
||||
URL::Constructor(aGlobal.GetAsSupports(), aInput, baseURL, aRv);
|
||||
RefPtr<URL> url = URL::WorkerConstructor(aGlobal, aInput, baseURL, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aInput);
|
||||
}
|
||||
|
@ -126,8 +126,7 @@ already_AddRefed<Response> Response::Redirect(const GlobalObject& aGlobal,
|
||||
worker->AssertIsOnWorkerThread();
|
||||
|
||||
NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref);
|
||||
RefPtr<URL> url =
|
||||
URL::Constructor(aGlobal.GetAsSupports(), aUrl, baseURL, aRv);
|
||||
RefPtr<URL> url = URL::WorkerConstructor(aGlobal, aUrl, baseURL, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
102
dom/url/URL.cpp
102
dom/url/URL.cpp
@ -14,7 +14,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIURIMutator.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -38,46 +37,19 @@ already_AddRefed<URL> URL::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL,
|
||||
const Optional<nsAString>& aBase,
|
||||
ErrorResult& aRv) {
|
||||
if (aBase.WasPassed()) {
|
||||
return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
|
||||
if (NS_IsMainThread()) {
|
||||
return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
|
||||
}
|
||||
|
||||
return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
|
||||
return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URL> URL::Constructor(nsISupports* aParent,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aBase,
|
||||
ErrorResult& aRv) {
|
||||
nsCOMPtr<nsIURI> baseUri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Constructor(aParent, aURL, baseUri, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URL> URL::Constructor(nsISupports* aParent,
|
||||
const nsAString& aURL, nsIURI* aBase,
|
||||
ErrorResult& aRv) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_FAILED(rv)) {
|
||||
// No need to warn in this case. It's common to use the URL constructor
|
||||
// to determine if a URL is valid and an exception will be propagated.
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<URL> url = new URL(aParent);
|
||||
url->SetURI(uri.forget());
|
||||
return url.forget();
|
||||
already_AddRefed<URL> URL::WorkerConstructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aBase,
|
||||
ErrorResult& aRv) {
|
||||
return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
|
||||
}
|
||||
|
||||
void URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
|
||||
@ -156,69 +128,11 @@ void URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams) {
|
||||
|
||||
void URL::GetHref(nsAString& aHref) const { URL_GETTER(aHref, GetSpec); }
|
||||
|
||||
void URL::SetHref(const nsAString& aHref, ErrorResult& aRv) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aHref, nullptr, nullptr,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
|
||||
return;
|
||||
}
|
||||
|
||||
mURI = std::move(uri);
|
||||
UpdateURLSearchParams();
|
||||
}
|
||||
|
||||
void URL::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const {
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(GetURI(), aOrigin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aOrigin.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
void URL::GetProtocol(nsAString& aProtocol) const {
|
||||
URL_GETTER(aProtocol, GetScheme);
|
||||
aProtocol.Append(char16_t(':'));
|
||||
}
|
||||
|
||||
void URL::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) {
|
||||
nsAString::const_iterator start;
|
||||
aProtocol.BeginReading(start);
|
||||
|
||||
nsAString::const_iterator end;
|
||||
aProtocol.EndReading(end);
|
||||
|
||||
nsAString::const_iterator iter(start);
|
||||
FindCharInReadable(':', iter, end);
|
||||
|
||||
// Changing the protocol of a URL, changes the "nature" of the URI
|
||||
// implementation. In order to do this properly, we have to serialize the
|
||||
// existing URL and reparse it in a new object.
|
||||
nsCOMPtr<nsIURI> clone;
|
||||
nsresult rv = NS_MutateURI(GetURI())
|
||||
.SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)))
|
||||
.Finalize(clone);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString href;
|
||||
rv = clone->GetSpec(href);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), href);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
mURI = std::move(uri);
|
||||
}
|
||||
|
||||
void URL::GetUsername(nsAString& aUsername) const {
|
||||
URL_GETTER(aUsername, GetUsername);
|
||||
}
|
||||
|
@ -26,32 +26,29 @@ class Blob;
|
||||
class MediaSource;
|
||||
class GlobalObject;
|
||||
|
||||
class URL final : public URLSearchParamsObserver, public nsWrapperCache {
|
||||
class URL : public URLSearchParamsObserver, public nsWrapperCache {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(URL)
|
||||
|
||||
explicit URL(nsISupports* aParent) : mParent(aParent) {}
|
||||
URL(nsISupports* aParent) : mParent(aParent) {}
|
||||
|
||||
// WebIDL methods
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static already_AddRefed<URL> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL,
|
||||
const Optional<nsAString>& aBase,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<URL> Constructor(nsISupports* aParent,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aBase,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<URL> Constructor(nsISupports* aParent,
|
||||
const nsAString& aURL, nsIURI* aBase,
|
||||
ErrorResult& aRv);
|
||||
// Helper for Fetch API
|
||||
static already_AddRefed<URL> WorkerConstructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aBase,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static void CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
|
||||
nsAString& aResult, ErrorResult& aRv);
|
||||
@ -67,13 +64,13 @@ class URL final : public URLSearchParamsObserver, public nsWrapperCache {
|
||||
|
||||
void GetHref(nsAString& aHref) const;
|
||||
|
||||
void SetHref(const nsAString& aHref, ErrorResult& aRv);
|
||||
virtual void SetHref(const nsAString& aHref, ErrorResult& aRv) = 0;
|
||||
|
||||
void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const;
|
||||
virtual void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const = 0;
|
||||
|
||||
void GetProtocol(nsAString& aProtocol) const;
|
||||
|
||||
void SetProtocol(const nsAString& aProtocol, ErrorResult& aRv);
|
||||
virtual void SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) = 0;
|
||||
|
||||
void GetUsername(nsAString& aUsername) const;
|
||||
|
||||
@ -101,7 +98,7 @@ class URL final : public URLSearchParamsObserver, public nsWrapperCache {
|
||||
|
||||
void GetSearch(nsAString& aSearch) const;
|
||||
|
||||
void SetSearch(const nsAString& aSearch);
|
||||
virtual void SetSearch(const nsAString& aSearch);
|
||||
|
||||
URLSearchParams* SearchParams();
|
||||
|
||||
@ -116,8 +113,8 @@ class URL final : public URLSearchParamsObserver, public nsWrapperCache {
|
||||
// URLSearchParamsObserver
|
||||
void URLSearchParamsUpdated(URLSearchParams* aSearchParams) override;
|
||||
|
||||
private:
|
||||
~URL() = default;
|
||||
protected:
|
||||
virtual ~URL() = default;
|
||||
|
||||
void SetURI(already_AddRefed<nsIURI> aURI);
|
||||
|
||||
|
@ -18,6 +18,55 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URLMainThread> URLMainThread::Constructor(
|
||||
const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
const Optional<nsAString>& aBase, ErrorResult& aRv) {
|
||||
if (aBase.WasPassed()) {
|
||||
return Constructor(aGlobal.GetAsSupports(), aURL, aBase.Value(), aRv);
|
||||
}
|
||||
|
||||
return Constructor(aGlobal.GetAsSupports(), aURL, nullptr, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URLMainThread> URLMainThread::Constructor(
|
||||
nsISupports* aParent, const nsAString& aURL, const nsAString& aBase,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIURI> baseUri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(baseUri), aBase, nullptr, nullptr,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aBase);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Constructor(aParent, aURL, baseUri, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URLMainThread> URLMainThread::Constructor(
|
||||
nsISupports* aParent, const nsAString& aURL, nsIURI* aBase,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_FAILED(rv)) {
|
||||
// No need to warn in this case. It's common to use the URL constructor
|
||||
// to determine if a URL is valid and an exception will be propagated.
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<URLMainThread> url = new URLMainThread(aParent);
|
||||
url->SetURI(uri.forget());
|
||||
return url.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void URLMainThread::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
|
||||
nsAString& aResult, ErrorResult& aRv) {
|
||||
@ -89,6 +138,12 @@ void URLMainThread::RevokeObjectURL(const GlobalObject& aGlobal,
|
||||
}
|
||||
}
|
||||
|
||||
URLMainThread::URLMainThread(nsISupports* aParent) : URL(aParent) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
URLMainThread::~URLMainThread() { MOZ_ASSERT(NS_IsMainThread()); }
|
||||
|
||||
/* static */
|
||||
bool URLMainThread::IsValidURL(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL, ErrorResult& aRv) {
|
||||
@ -97,5 +152,64 @@ bool URLMainThread::IsValidURL(const GlobalObject& aGlobal,
|
||||
return BlobURLProtocolHandler::HasDataEntry(asciiurl);
|
||||
}
|
||||
|
||||
void URLMainThread::SetHref(const nsAString& aHref, ErrorResult& aRv) {
|
||||
NS_ConvertUTF16toUTF8 href(aHref);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = ioService->NewURI(href, nullptr, nullptr, getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
|
||||
return;
|
||||
}
|
||||
|
||||
SetURI(uri.forget());
|
||||
UpdateURLSearchParams();
|
||||
}
|
||||
|
||||
void URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const {
|
||||
nsContentUtils::GetUTFOrigin(GetURI(), aOrigin);
|
||||
}
|
||||
|
||||
void URLMainThread::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) {
|
||||
nsAString::const_iterator start, end;
|
||||
aProtocol.BeginReading(start);
|
||||
aProtocol.EndReading(end);
|
||||
nsAString::const_iterator iter(start);
|
||||
|
||||
FindCharInReadable(':', iter, end);
|
||||
|
||||
// Changing the protocol of a URL, changes the "nature" of the URI
|
||||
// implementation. In order to do this properly, we have to serialize the
|
||||
// existing URL and reparse it in a new object.
|
||||
nsCOMPtr<nsIURI> clone;
|
||||
nsresult rv = NS_MutateURI(GetURI())
|
||||
.SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)))
|
||||
.Finalize(clone);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString href;
|
||||
rv = clone->GetSpec(href);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), href);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetURI(uri.forget());
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -12,8 +12,23 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class URLMainThread final {
|
||||
// The URL implementation for the main-thread
|
||||
class URLMainThread final : public URL {
|
||||
public:
|
||||
static already_AddRefed<URLMainThread> Constructor(
|
||||
const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
const Optional<nsAString>& aBase, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<URLMainThread> Constructor(nsISupports* aParent,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aBase,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<URLMainThread> Constructor(nsISupports* aParent,
|
||||
const nsAString& aURL,
|
||||
nsIURI* aBase,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static void CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
|
||||
nsAString& aResult, ErrorResult& aRv);
|
||||
|
||||
@ -25,6 +40,18 @@ class URLMainThread final {
|
||||
|
||||
static bool IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
explicit URLMainThread(nsISupports* aParent);
|
||||
|
||||
virtual void SetHref(const nsAString& aHref, ErrorResult& aRv) override;
|
||||
|
||||
virtual void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
|
||||
|
||||
virtual void SetProtocol(const nsAString& aProtocol,
|
||||
ErrorResult& aRv) override;
|
||||
|
||||
private:
|
||||
~URLMainThread();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -11,8 +11,15 @@
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsStandardURL.h"
|
||||
#include "nsURLHelper.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using net::nsStandardURL;
|
||||
|
||||
namespace dom {
|
||||
|
||||
// This class creates an URL from a DOM Blob on the main thread.
|
||||
@ -154,6 +161,163 @@ class IsValidURLRunnable : public WorkerMainThreadRunnable {
|
||||
bool IsValidURL() const { return mValid; }
|
||||
};
|
||||
|
||||
// This class creates a URL object on the main thread.
|
||||
class ConstructorRunnable : public WorkerMainThreadRunnable {
|
||||
private:
|
||||
const nsString mURL;
|
||||
|
||||
nsString mBase; // IsVoid() if we have no base URI string.
|
||||
|
||||
nsCOMPtr<nsIURI> mRetval;
|
||||
|
||||
public:
|
||||
ConstructorRunnable(WorkerPrivate* aWorkerPrivate, const nsAString& aURL,
|
||||
const Optional<nsAString>& aBase)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate,
|
||||
NS_LITERAL_CSTRING("URL :: Constructor")),
|
||||
mURL(aURL) {
|
||||
if (aBase.WasPassed()) {
|
||||
mBase = aBase.Value();
|
||||
} else {
|
||||
mBase.SetIsVoid(true);
|
||||
}
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool MainThreadRun() override {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> baseUri;
|
||||
if (!mBase.IsVoid()) {
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(baseUri), mBase, nullptr, nullptr,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), mURL, nullptr, baseUri,
|
||||
nsContentUtils::GetIOService());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mRetval = std::move(uri);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsIURI* GetURI(ErrorResult& aRv) const {
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (!mRetval) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(mURL);
|
||||
}
|
||||
|
||||
return mRetval;
|
||||
}
|
||||
};
|
||||
|
||||
class OriginGetterRunnable : public WorkerMainThreadRunnable {
|
||||
public:
|
||||
OriginGetterRunnable(WorkerPrivate* aWorkerPrivate, nsAString& aValue,
|
||||
nsIURI* aURI)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate,
|
||||
NS_LITERAL_CSTRING("URL :: origin getter")),
|
||||
mValue(aValue),
|
||||
mURI(aURI) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool MainThreadRun() override {
|
||||
AssertIsOnMainThread();
|
||||
ErrorResult rv;
|
||||
nsContentUtils::GetUTFOrigin(mURI, mValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dispatch(ErrorResult& aRv) {
|
||||
WorkerMainThreadRunnable::Dispatch(Canceling, aRv);
|
||||
}
|
||||
|
||||
private:
|
||||
nsAString& mValue;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
};
|
||||
|
||||
class ProtocolSetterRunnable : public WorkerMainThreadRunnable {
|
||||
public:
|
||||
ProtocolSetterRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
const nsACString& aValue, nsIURI* aURI)
|
||||
: WorkerMainThreadRunnable(aWorkerPrivate,
|
||||
NS_LITERAL_CSTRING("ProtocolSetterRunnable")),
|
||||
mValue(aValue),
|
||||
mURI(aURI) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool MainThreadRun() override {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> clone;
|
||||
nsresult rv = NS_MutateURI(mURI).SetScheme(mValue).Finalize(clone);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoCString href;
|
||||
rv = clone->GetSpec(href);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), href);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mRetval = std::move(uri);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dispatch(ErrorResult& aRv) {
|
||||
WorkerMainThreadRunnable::Dispatch(Canceling, aRv);
|
||||
}
|
||||
|
||||
nsIURI* GetRetval() const { return mRetval; }
|
||||
|
||||
private:
|
||||
const nsCString mValue;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mRetval;
|
||||
};
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URLWorker> URLWorker::Constructor(
|
||||
const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
const Optional<nsAString>& aBase, ErrorResult& aRv) {
|
||||
JSContext* cx = aGlobal.Context();
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
||||
|
||||
RefPtr<URLWorker> url = new URLWorker(workerPrivate);
|
||||
url->Init(aURL, aBase, aRv);
|
||||
|
||||
return aRv.Failed() ? nullptr : url.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<URLWorker> URLWorker::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aBase,
|
||||
ErrorResult& aRv) {
|
||||
Optional<nsAString> base;
|
||||
base = &aBase;
|
||||
|
||||
return Constructor(aGlobal, aURL, base, aRv);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void URLWorker::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
|
||||
nsAString& aResult, mozilla::ErrorResult& aRv) {
|
||||
@ -223,5 +387,138 @@ bool URLWorker::IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
return runnable->IsValidURL();
|
||||
}
|
||||
|
||||
URLWorker::URLWorker(WorkerPrivate* aWorkerPrivate)
|
||||
: URL(nullptr), mWorkerPrivate(aWorkerPrivate) {}
|
||||
|
||||
void URLWorker::Init(const nsAString& aURL, const Optional<nsAString>& aBase,
|
||||
ErrorResult& aRv) {
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = net_ExtractURLScheme(NS_ConvertUTF16toUTF8(aURL), scheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
// this may be a relative URL, check baseURL
|
||||
if (!aBase.WasPassed()) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
|
||||
return;
|
||||
}
|
||||
rv = net_ExtractURLScheme(NS_ConvertUTF16toUTF8(aBase.Value()), scheme);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's check if the baseURI was passed and if it can be parsed on the worker
|
||||
// thread.
|
||||
bool useProxy = false;
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
if (aBase.WasPassed()) {
|
||||
rv = NS_NewURI(getter_AddRefs(baseURI),
|
||||
NS_ConvertUTF16toUTF8(aBase.Value()));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv != NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aBase.Value());
|
||||
return;
|
||||
}
|
||||
useProxy = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's see if we can parse aURI on this thread.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
if (!useProxy) {
|
||||
rv = NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(aURL), nullptr,
|
||||
baseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv != NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
|
||||
return;
|
||||
}
|
||||
useProxy = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback by proxy.
|
||||
if (useProxy) {
|
||||
RefPtr<ConstructorRunnable> runnable =
|
||||
new ConstructorRunnable(mWorkerPrivate, aURL, aBase);
|
||||
runnable->Dispatch(Canceling, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
uri = runnable->GetURI(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetURI(uri.forget());
|
||||
}
|
||||
|
||||
URLWorker::~URLWorker() = default;
|
||||
|
||||
void URLWorker::SetHref(const nsAString& aHref, ErrorResult& aRv) {
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = net_ExtractURLScheme(NS_ConvertUTF16toUTF8(aHref), scheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.ThrowTypeError<MSG_INVALID_URL>(aHref);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ConstructorRunnable> runnable =
|
||||
new ConstructorRunnable(mWorkerPrivate, aHref, Optional<nsAString>());
|
||||
runnable->Dispatch(Canceling, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = runnable->GetURI(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetURI(uri.forget());
|
||||
UpdateURLSearchParams();
|
||||
}
|
||||
|
||||
void URLWorker::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const {
|
||||
nsresult rv = nsContentUtils::GetThreadSafeUTFOrigin(GetURI(), aOrigin);
|
||||
if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
|
||||
RefPtr<OriginGetterRunnable> runnable =
|
||||
new OriginGetterRunnable(mWorkerPrivate, aOrigin, GetURI());
|
||||
|
||||
runnable->Dispatch(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aOrigin.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
void URLWorker::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) {
|
||||
nsAString::const_iterator start, end;
|
||||
aProtocol.BeginReading(start);
|
||||
aProtocol.EndReading(end);
|
||||
nsAString::const_iterator iter(start);
|
||||
|
||||
FindCharInReadable(':', iter, end);
|
||||
NS_ConvertUTF16toUTF8 scheme(Substring(start, iter));
|
||||
|
||||
RefPtr<ProtocolSetterRunnable> runnable =
|
||||
new ProtocolSetterRunnable(mWorkerPrivate, scheme, GetURI());
|
||||
runnable->Dispatch(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = runnable->GetRetval();
|
||||
if (NS_WARN_IF(!uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetURI(uri.forget());
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -18,7 +18,10 @@ class nsStandardURL;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class URLWorker final {
|
||||
class WorkerPrivate;
|
||||
|
||||
// URLWorker implements the URL object in workers.
|
||||
class URLWorker final : public URL {
|
||||
public:
|
||||
static already_AddRefed<URLWorker> Constructor(
|
||||
const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
@ -37,6 +40,23 @@ class URLWorker final {
|
||||
|
||||
static bool IsValidURL(const GlobalObject& aGlobal, const nsAString& aUrl,
|
||||
ErrorResult& aRv);
|
||||
|
||||
explicit URLWorker(WorkerPrivate* aWorkerPrivate);
|
||||
|
||||
void Init(const nsAString& aURL, const Optional<nsAString>& aBase,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual void SetHref(const nsAString& aHref, ErrorResult& aRv) override;
|
||||
|
||||
virtual void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override;
|
||||
|
||||
virtual void SetProtocol(const nsAString& aProtocol,
|
||||
ErrorResult& aRv) override;
|
||||
|
||||
private:
|
||||
~URLWorker();
|
||||
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
Loading…
Reference in New Issue
Block a user