Bug 1322013 - Use system principal to fetch moz-extension stylesheets;r=gl draft
authorJulian Descottes <jdescottes@mozilla.com>
Mon, 26 Dec 2016 11:16:24 +0100
changeset 454070 61fc7bbcabd7607e07b17f5614d5f0f039f9ca84
parent 453842 5ea0c495d3b2318287bffe1121e0e33d74427143
child 540613 1e6b96759767dd43c5f5f00f9fe7e92fccfcf35d
push id39827
push userjdescottes@mozilla.com
push dateTue, 27 Dec 2016 18:56:05 +0000
reviewersgl
bugs1322013
milestone53.0a1
Bug 1322013 - Use system principal to fetch moz-extension stylesheets;r=gl MozReview-Commit-ID: 8n15QUzbEUJ
devtools/server/actors/stylesheets.js
--- a/devtools/server/actors/stylesheets.js
+++ b/devtools/server/actors/stylesheets.js
@@ -436,39 +436,69 @@ var StyleSheetActor = protocol.ActorClas
 
     if (!this.href) {
       // this is an inline <style> sheet
       let content = this.ownerNode.textContent;
       this.text = content;
       return promise.resolve(content);
     }
 
+    return this.fetchStylesheet(this.href).then(({ content }) => {
+      this.text = content;
+      return content;
+    });
+  },
+
+  /**
+   * Fetch a stylesheet at the provided URL. Returns a promise that will resolve the
+   * result of the fetch command.
+   *
+   * @param  {String} href
+   *         The href of the stylesheet to retrieve.
+   * @return {Promise} a promise that resolves with an object with the following members
+   *         on success:
+   *           - content: the document at that URL, as a string,
+   *           - contentType: the content type of the document
+   *         If an error occurs, the promise is rejected with that error.
+   */
+  fetchStylesheet: Task.async(function* (href) {
     let options = {
       loadFromCache: true,
       policy: Ci.nsIContentPolicy.TYPE_INTERNAL_STYLESHEET,
       charset: this._getCSSCharset()
     };
 
     // Bug 1282660 - We use the system principal to load the default internal
     // stylesheets instead of the content principal since such stylesheets
     // require system principal to load. At meanwhile, we strip the loadGroup
     // for preventing the assertion of the userContextId mismatching.
-    // The default internal stylesheets load from the 'resource:' URL.
-    // Bug 1287607, 1291321 - 'chrome' and 'file' protocols should also be handled in the
-    // same way.
-    if (!/^(chrome|file|resource):\/\//.test(this.href)) {
+
+    // chrome|file|resource|moz-extension protocols rely on the system principal.
+    let excludedProtocolsRe = /^(chrome|file|resource|moz-extension):\/\//;
+    if (!excludedProtocolsRe.test(this.href)) {
+      // Stylesheets using other protocols should use the content principal.
       options.window = this.window;
       options.principal = this.document.nodePrincipal;
     }
 
-    return fetch(this.href, options).then(({ content }) => {
-      this.text = content;
-      return content;
-    });
-  },
+    let result;
+    try {
+      result = yield fetch(this.href, options);
+    } catch (e) {
+      // The list of excluded protocols can be missing some protocols, try to use the
+      // system principal if the first fetch failed.
+      console.error(`stylesheets actor: fetch failed for ${this.href},` +
+        ` using system principal instead.`);
+      options.window = undefined;
+      options.principal = undefined;
+      result = yield fetch(this.href, options);
+    }
+
+    return result;
+  }),
 
   /**
    * Protocol method to get the original source (actors) for this
    * stylesheet if it has uses source maps.
    */
   getOriginalSources: function () {
     if (this._originalSources) {
       return promise.resolve(this._originalSources);