Bug 1189673 - Set FetchEvent.request.headers' guard to immutable before dispatching the FetchEvent; r=bkelly
☠☠ backed out by a4334a6c5313 ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 19 Oct 2015 14:23:28 -0400
changeset 268421 4b38a09cca568ef84499ad5f8ed8f4ad1e2f414f
parent 268420 069effcd9de620b46cce83acbe03284e8a1da5a5
child 268422 d8e39b8847377d9030138b70952cc2421528a800
push id66822
push usereakhgari@mozilla.com
push dateTue, 20 Oct 2015 01:55:19 +0000
treeherdermozilla-inbound@d8e39b884737 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1189673
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1189673 - Set FetchEvent.request.headers' guard to immutable before dispatching the FetchEvent; r=bkelly
dom/fetch/InternalHeaders.h
dom/workers/ServiceWorkerPrivate.cpp
testing/web-platform/mozilla/meta/service-workers/service-worker/request-end-to-end.https.html.ini
testing/web-platform/mozilla/tests/service-workers/service-worker/request-end-to-end.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/request-end-to-end-worker.js
--- a/dom/fetch/InternalHeaders.h
+++ b/dom/fetch/InternalHeaders.h
@@ -46,21 +46,24 @@ private:
 
 public:
   explicit InternalHeaders(HeadersGuardEnum aGuard = HeadersGuardEnum::None)
     : mGuard(aGuard)
   {
   }
 
   explicit InternalHeaders(const InternalHeaders& aOther)
-    : mGuard(aOther.mGuard)
+    : mGuard(HeadersGuardEnum::None)
   {
     ErrorResult result;
     Fill(aOther, result);
     MOZ_ASSERT(!result.Failed());
+    // Note that it's important to set the guard after Fill(), to make sure
+    // that Fill() doesn't fail if aOther is immutable.
+    mGuard = aOther.mGuard;
   }
 
   explicit InternalHeaders(const nsTArray<Entry>&& aHeaders,
                            HeadersGuardEnum aGuard = HeadersGuardEnum::None);
 
   void Append(const nsACString& aName, const nsACString& aValue,
               ErrorResult& aRv);
   void Delete(const nsACString& aName, ErrorResult& aRv);
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -1032,16 +1032,22 @@ private:
     MOZ_ASSERT(internalReq);
     internalReq->SetCreatedByFetchEvent();
 
     internalReq->SetBody(mUploadStream);
     internalReq->SetReferrer(NS_ConvertUTF8toUTF16(mReferrer));
 
     request->SetContentPolicyType(mContentPolicyType);
 
+    request->GetInternalHeaders()->SetGuard(HeadersGuardEnum::Immutable, result);
+    if (NS_WARN_IF(result.Failed())) {
+      result.SuppressException();
+      return false;
+    }
+
     // TODO: remove conditional on http here once app protocol support is
     //       removed from service worker interception
     MOZ_ASSERT_IF(mIsHttpChannel && internalReq->IsNavigationRequest(),
                   request->Redirect() == RequestRedirect::Manual);
 
     RootedDictionary<FetchEventInit> init(aCx);
     init.mRequest.Construct();
     init.mRequest.Value() = request;
deleted file mode 100644
--- a/testing/web-platform/mozilla/meta/service-workers/service-worker/request-end-to-end.https.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[request-end-to-end.https.html]
-  type: testharness
-  expected: TIMEOUT
-  [Request: end-to-end]
-    expected: TIMEOUT
-
--- a/testing/web-platform/mozilla/tests/service-workers/service-worker/request-end-to-end.https.html
+++ b/testing/web-platform/mozilla/tests/service-workers/service-worker/request-end-to-end.https.html
@@ -41,17 +41,17 @@ t.step(function() {
             event.data.url,
             location.href.substring(0, location.href.lastIndexOf('/') + 1) +
             scope,
             'request.url should be passed to onfetch event.');
         assert_equals(event.data.method, 'GET',
                       'request.method should be passed to onfetch event.');
         assert_equals(event.data.referrer, location.href,
                       'request.referrer should be passed to onfetch event.');
-        assert_equals(event.data.headers['user-agent'], navigator.userAgent,
-                      'User-Agent header should be passed to onfetch event.')
+        assert_equals(event.data.headers['user-agent'], undefined,
+                      'Default User-Agent header should not be passed to onfetch event.')
         assert_equals(event.data.errorNameWhileAppendingHeader, 'TypeError',
                       'Appending a new header to the request must throw a ' +
                       'TypeError.')
         service_worker_unregister_and_done(t, scope);
     }
 });
 </script>
--- a/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/request-end-to-end-worker.js
+++ b/testing/web-platform/mozilla/tests/service-workers/service-worker/resources/request-end-to-end-worker.js
@@ -4,16 +4,17 @@ onmessage = function(e) {
   var message = e.data;
   if (typeof message === 'object' && 'port' in message) {
     port = message.port;
   }
 };
 
 onfetch = function(e) {
   var headers = {};
+  var errorNameWhileAppendingHeader;
   for (var header of e.request.headers) {
     var key = header[0], value = header[1];
     headers[key] = value;
   }
   var errorNameWhileAddingHeader = '';
   try {
     e.request.headers.append('Test-Header', 'TestValue');
   } catch (e) {