diff --git a/dom/fetch/ChannelInfo.cpp b/dom/fetch/ChannelInfo.cpp index bf49e530ceb..4f8d3ccf07f 100644 --- a/dom/fetch/ChannelInfo.cpp +++ b/dom/fetch/ChannelInfo.cpp @@ -7,6 +7,7 @@ #include "mozilla/dom/ChannelInfo.h" #include "nsCOMPtr.h" #include "nsIChannel.h" +#include "nsIDocument.h" #include "nsIHttpChannel.h" #include "nsSerializationHelper.h" #include "mozilla/net/HttpBaseChannel.h" @@ -18,6 +19,26 @@ using namespace mozilla; using namespace mozilla::dom; +void +ChannelInfo::InitFromDocument(nsIDocument* aDoc) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mInited, "Cannot initialize the object twice"); + + nsCOMPtr securityInfo = aDoc->GetSecurityInfo(); + if (securityInfo) { + SetSecurityInfo(securityInfo); + } + + // mRedirected flag and mRedirectedURISpec are only important for maintaining + // the channel's redirected status. If the ChannelInfo is initialized from + // a document, that document has already asked the channel from which it was + // loaded about the current channel URI, so it won't matter if a future + // ResurrectInfoOnChannel() call misses whether the channel was redirected. + mRedirected = false; + mInited = true; +} + void ChannelInfo::InitFromChannel(nsIChannel* aChannel) { diff --git a/dom/fetch/ChannelInfo.h b/dom/fetch/ChannelInfo.h index ebedbcf0ae6..8bc17c6a13b 100644 --- a/dom/fetch/ChannelInfo.h +++ b/dom/fetch/ChannelInfo.h @@ -11,6 +11,7 @@ #include "nsCOMPtr.h" class nsIChannel; +class nsIDocument; class nsIURI; namespace mozilla { @@ -66,6 +67,7 @@ public: return *this; } + void InitFromDocument(nsIDocument* aDoc); void InitFromChannel(nsIChannel* aChannel); void InitFromIPCChannelInfo(const IPCChannelInfo& aChannelInfo); diff --git a/dom/fetch/Response.cpp b/dom/fetch/Response.cpp index 2f9f90b8806..e99f8a18bc8 100644 --- a/dom/fetch/Response.cpp +++ b/dom/fetch/Response.cpp @@ -159,6 +159,22 @@ Response::Constructor(const GlobalObject& aGlobal, nsRefPtr internalResponse = new InternalResponse(aInit.mStatus, statusText); + // Grab a valid channel info from the global so this response is 'valid' for + // interception. + if (NS_IsMainThread()) { + nsCOMPtr window = do_QueryInterface(global); + MOZ_ASSERT(window); + nsIDocument* doc = window->GetExtantDoc(); + MOZ_ASSERT(doc); + ChannelInfo info; + info.InitFromDocument(doc); + internalResponse->InitChannelInfo(info); + } else { + workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(worker); + internalResponse->InitChannelInfo(worker->GetChannelInfo()); + } + nsRefPtr r = new Response(global, internalResponse); if (aInit.mHeaders.WasPassed()) { diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index f8513f42ffc..d35b0c5e747 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -1033,9 +1033,7 @@ private: mWorkerPrivate->SetBaseURI(finalURI); // Store the channel info if needed. - if (mWorkerPrivate->IsServiceWorker()) { - mWorkerPrivate->InitChannelInfo(channel); - } + mWorkerPrivate->InitChannelInfo(channel); // Now to figure out which principal to give this worker. WorkerPrivate* parent = mWorkerPrivate->GetParent(); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 0b2dfc966d6..48a9f06ca91 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -503,14 +503,12 @@ public: const ChannelInfo& GetChannelInfo() const { - MOZ_ASSERT(IsServiceWorker()); return mLoadInfo.mChannelInfo; } void SetChannelInfo(const ChannelInfo& aChannelInfo) { - MOZ_ASSERT(IsServiceWorker()); AssertIsOnMainThread(); MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized()); MOZ_ASSERT(aChannelInfo.IsInitialized()); diff --git a/dom/workers/test/serviceworkers/fetch/https/https_test.js b/dom/workers/test/serviceworkers/fetch/https/https_test.js index bb0aee13e5e..6f87bb5ee1c 100644 --- a/dom/workers/test/serviceworkers/fetch/https/https_test.js +++ b/dom/workers/test/serviceworkers/fetch/https/https_test.js @@ -1,12 +1,21 @@ self.addEventListener("install", function(event) { event.waitUntil(caches.open("cache").then(function(cache) { - return cache.add("index.html"); + var synth = new Response('', + {headers:{"Content-Type": "text/html"}}); + return Promise.all([ + cache.add("index.html"), + cache.put("synth-sw.html", synth), + ]); })); }); self.addEventListener("fetch", function(event) { if (event.request.url.indexOf("index.html") >= 0) { event.respondWith(caches.match(event.request)); + } else if (event.request.url.indexOf("synth-sw.html") >= 0) { + event.respondWith(caches.match(event.request)); + } else if (event.request.url.indexOf("synth-window.html") >= 0) { + event.respondWith(caches.match(event.request)); } else if (event.request.url.indexOf("synth.html") >= 0) { event.respondWith(new Response('', {headers:{"Content-Type": "text/html"}})); diff --git a/dom/workers/test/serviceworkers/fetch/https/register.html b/dom/workers/test/serviceworkers/fetch/https/register.html index 41774f70d18..fa666fe9573 100644 --- a/dom/workers/test/serviceworkers/fetch/https/register.html +++ b/dom/workers/test/serviceworkers/fetch/https/register.html @@ -9,6 +9,12 @@ window.parent.postMessage({status: "registrationdone"}, "*"); } - navigator.serviceWorker.ready.then(done); + navigator.serviceWorker.ready.then(reg => { + return window.caches.open("cache").then(function(cache) { + var synth = new Response(' diff --git a/dom/workers/test/serviceworkers/test_https_fetch.html b/dom/workers/test/serviceworkers/test_https_fetch.html index 5b0dc31b1b4..01e18b03d25 100644 --- a/dom/workers/test/serviceworkers/test_https_fetch.html +++ b/dom/workers/test/serviceworkers/test_https_fetch.html @@ -31,6 +31,10 @@ ios.offline = true; iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/index.html"; } else if (e.data.status == "done") { + iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/synth-sw.html"; + } else if (e.data.status == "done-synth-sw") { + iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/synth-window.html"; + } else if (e.data.status == "done-synth-window") { iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/https/synth.html"; } else if (e.data.status == "done-synth") { ios.offline = false;