Bug 1163024 - Part 1: Stylesheet actors should use the common DevToolsUtils.fetch(). r=bgrins

This commit is contained in:
Panos Astithas 2015-05-14 13:38:18 +03:00
parent 222808ee0d
commit d2e61ab500
3 changed files with 35 additions and 312 deletions

View File

@ -434,6 +434,9 @@ exports.defineLazyGetter(this, "NetUtil", () => {
* An object with the following optional properties:
* - loadFromCache: if false, will bypass the cache and
* always load fresh from the network (default: true)
* - policy: the nsIContentPolicy type to apply when fetching the URL
* - window: the window to get the loadGroup from
* - charset: the charset to use if the channel doesn't provide one
* @returns Promise
* A promise of the document at that URL, as a string.
*
@ -441,7 +444,10 @@ exports.defineLazyGetter(this, "NetUtil", () => {
* without relying on caching when we can (not for eval, etc.):
* http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
*/
exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true }) {
exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true,
policy: Ci.nsIContentPolicy.TYPE_OTHER,
window: null,
charset: null }) {
let deferred = promise.defer();
let scheme;
let url = aURL.split(" -> ").pop();
@ -483,14 +489,14 @@ exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true }) {
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
aOptions.policy);
} catch (ex) {
deferred.reject(ex);
}
break;
default:
let channel;
let channel;
try {
channel = Services.io.newChannel2(url,
null,
@ -499,7 +505,7 @@ exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true }) {
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
aOptions.policy);
} catch (e if e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
// On Windows xpcshell tests, c:/foo/bar can pass as a valid URL, but
// newChannel won't be able to handle it.
@ -511,7 +517,7 @@ exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true }) {
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
aOptions.policy);
}
let chunks = [];
let streamListener = {
@ -535,12 +541,19 @@ exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true }) {
return;
}
charset = channel.contentCharset;
charset = channel.contentCharset || aOptions.charset;
contentType = channel.contentType;
deferred.resolve(chunks.join(""));
}
};
if (aOptions.window) {
// Respect private browsing.
channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocumentLoader)
.loadGroup;
}
channel.loadFlags = aOptions.loadFromCache
? channel.LOAD_FROM_CACHE
: channel.LOAD_BYPASS_CACHE;

View File

@ -17,6 +17,7 @@ const events = require("sdk/event/core");
const protocol = require("devtools/server/protocol");
const {Arg, Option, method, RetVal, types} = protocol;
const {LongStringActor, ShortLongString} = require("devtools/server/actors/string");
const {fetch} = require("devtools/toolkit/DevToolsUtils");
loader.lazyGetter(this, "CssLogic", () => require("devtools/styleinspector/css-logic").CssLogic);
@ -445,6 +446,7 @@ let OldStyleSheetActor = protocol.ActorClass({
}
let options = {
policy: Ci.nsIContentPolicy.TYPE_STYLESHEET,
window: this.window,
charset: this._getCSSCharset()
};
@ -636,157 +638,6 @@ exports.OldStyleSheetActor = OldStyleSheetActor;
exports.OldStyleSheetFront = OldStyleSheetFront;
/**
* Performs a request to load the desired URL and returns a promise.
*
* @param aURL String
* The URL we will request.
* @returns Promise
* A promise of the document at that URL, as a string.
*/
function fetch(aURL, aOptions={ loadFromCache: true, window: null,
charset: null}) {
let deferred = promise.defer();
let scheme;
let url = aURL.split(" -> ").pop();
let charset;
let contentType;
try {
scheme = Services.io.extractScheme(url);
} catch (e) {
// In the xpcshell tests, the script url is the absolute path of the test
// file, which will make a malformed URI error be thrown. Add the file
// scheme prefix ourselves.
url = "file://" + url;
scheme = Services.io.extractScheme(url);
}
switch (scheme) {
case "file":
case "chrome":
case "resource":
try {
NetUtil.asyncFetch2(
url,
function onFetch(aStream, aStatus, aRequest) {
if (!components.isSuccessCode(aStatus)) {
deferred.reject(new Error("Request failed with status code = "
+ aStatus
+ " after NetUtil.asyncFetch2 for url = "
+ url));
return;
}
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
contentType = aRequest.contentType;
deferred.resolve(source);
aStream.close();
},
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_STYLESHEET);
} catch (ex) {
deferred.reject(ex);
}
break;
default:
let channel;
try {
channel = Services.io.newChannel2(url,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_STYLESHEET);
} catch (e if e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
// On Windows xpcshell tests, c:/foo/bar can pass as a valid URL, but
// newChannel won't be able to handle it.
url = "file:///" + url;
channel = Services.io.newChannel2(url,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_STYLESHEET);
}
let chunks = [];
let streamListener = {
onStartRequest: function(aRequest, aContext, aStatusCode) {
if (!components.isSuccessCode(aStatusCode)) {
deferred.reject(new Error("Request failed with status code = "
+ aStatusCode
+ " in onStartRequest handler for url = "
+ url));
}
},
onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
},
onStopRequest: function(aRequest, aContext, aStatusCode) {
if (!components.isSuccessCode(aStatusCode)) {
deferred.reject(new Error("Request failed with status code = "
+ aStatusCode
+ " in onStopRequest handler for url = "
+ url));
return;
}
charset = channel.contentCharset || charset;
contentType = channel.contentType;
deferred.resolve(chunks.join(""));
}
};
if (aOptions.window) {
// respect private browsing
channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocumentLoader)
.loadGroup;
}
channel.loadFlags = aOptions.loadFromCache
? channel.LOAD_FROM_CACHE
: channel.LOAD_BYPASS_CACHE;
channel.asyncOpen(streamListener, null);
break;
}
return deferred.promise.then(source => {
return {
content: convertToUnicode(source, charset),
contentType: contentType
};
});
}
/**
* Convert a given string, encoded in a given character set, to unicode.
*
* @param string aString
* A string.
* @param string aCharset
* A character set.
*/
function convertToUnicode(aString, aCharset=null) {
// Decoding primitives.
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
try {
converter.charset = aCharset || "UTF-8";
return converter.ConvertToUnicode(aString);
} catch(e) {
return aString;
}
}
/**
* Normalize multiple relative paths towards the base paths on the right.
*/

View File

@ -18,6 +18,7 @@ const events = require("sdk/event/core");
const protocol = require("devtools/server/protocol");
const {Arg, Option, method, RetVal, types} = protocol;
const {LongStringActor, ShortLongString} = require("devtools/server/actors/string");
const {fetch} = require("devtools/toolkit/DevToolsUtils");
loader.lazyGetter(this, "CssLogic", () => require("devtools/styleinspector/css-logic").CssLogic);
@ -589,8 +590,9 @@ let StyleSheetActor = protocol.ActorClass({
}
let options = {
window: this.window,
loadFromCache: true,
policy: Ci.nsIContentPolicy.TYPE_STYLESHEET,
window: this.window,
charset: this._getCSSCharset()
};
@ -673,8 +675,12 @@ let StyleSheetActor = protocol.ActorClass({
};
url = normalize(url, this.href);
let map = fetch(url, { loadFromCache: false, window: this.window })
let options = {
loadFromCache: false,
policy: Ci.nsIContentPolicy.TYPE_STYLESHEET,
window: this.window
};
let map = fetch(url, options)
.then(({content}) => {
let map = new SourceMapConsumer(content);
this._setSourceMapRoot(map, url, this.href);
@ -1031,7 +1037,11 @@ let OriginalSourceActor = protocol.ActorClass({
this.text = content;
return promise.resolve(content);
}
return fetch(this.url, { window: this.window }).then(({content}) => {
let options = {
policy: Ci.nsIContentPolicy.TYPE_STYLESHEET,
window: this.window
};
return fetch(this.url, options).then(({content}) => {
this.text = content;
return content;
});
@ -1086,157 +1096,6 @@ exports.StyleSheetActor = StyleSheetActor;
exports.StyleSheetFront = StyleSheetFront;
/**
* Performs a request to load the desired URL and returns a promise.
*
* @param aURL String
* The URL we will request.
* @returns Promise
* A promise of the document at that URL, as a string.
*/
function fetch(aURL, aOptions={ loadFromCache: true, window: null,
charset: null}) {
let deferred = promise.defer();
let scheme;
let url = aURL.split(" -> ").pop();
let charset;
let contentType;
try {
scheme = Services.io.extractScheme(url);
} catch (e) {
// In the xpcshell tests, the script url is the absolute path of the test
// file, which will make a malformed URI error be thrown. Add the file
// scheme prefix ourselves.
url = "file://" + url;
scheme = Services.io.extractScheme(url);
}
switch (scheme) {
case "file":
case "chrome":
case "resource":
try {
NetUtil.asyncFetch2(
url,
function onFetch(aStream, aStatus, aRequest) {
if (!components.isSuccessCode(aStatus)) {
deferred.reject(new Error("Request failed with status code = "
+ aStatus
+ " after NetUtil.asyncFetch2 for url = "
+ url));
return;
}
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
contentType = aRequest.contentType;
deferred.resolve(source);
aStream.close();
},
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_STYLESHEET);
} catch (ex) {
deferred.reject(ex);
}
break;
default:
let channel;
try {
channel = Services.io.newChannel2(url,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_STYLESHEET);
} catch (e if e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
// On Windows xpcshell tests, c:/foo/bar can pass as a valid URL, but
// newChannel won't be able to handle it.
url = "file:///" + url;
channel = Services.io.newChannel2(url,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_STYLESHEET);
}
let chunks = [];
let streamListener = {
onStartRequest: function(aRequest, aContext, aStatusCode) {
if (!components.isSuccessCode(aStatusCode)) {
deferred.reject(new Error("Request failed with status code = "
+ aStatusCode
+ " in onStartRequest handler for url = "
+ url));
}
},
onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
},
onStopRequest: function(aRequest, aContext, aStatusCode) {
if (!components.isSuccessCode(aStatusCode)) {
deferred.reject(new Error("Request failed with status code = "
+ aStatusCode
+ " in onStopRequest handler for url = "
+ url));
return;
}
charset = channel.contentCharset || charset;
contentType = channel.contentType;
deferred.resolve(chunks.join(""));
}
};
if (aOptions.window) {
// respect private browsing
channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocumentLoader)
.loadGroup;
}
channel.loadFlags = aOptions.loadFromCache
? channel.LOAD_FROM_CACHE
: channel.LOAD_BYPASS_CACHE;
channel.asyncOpen(streamListener, null);
break;
}
return deferred.promise.then(source => {
return {
content: convertToUnicode(source, charset),
contentType: contentType
};
});
}
/**
* Convert a given string, encoded in a given character set, to unicode.
*
* @param string aString
* A string.
* @param string aCharset
* A character set.
*/
function convertToUnicode(aString, aCharset=null) {
// Decoding primitives.
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
try {
converter.charset = aCharset || "UTF-8";
return converter.ConvertToUnicode(aString);
} catch(e) {
return aString;
}
}
/**
* Normalize multiple relative paths towards the base paths on the right.
*/