Bug 1322013 - Use system principal to fetch moz-extension stylesheets;r=gl
MozReview-Commit-ID: 8n15QUzbEUJ
--- 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);