зеркало из https://github.com/mozilla/gecko-dev.git
Add some docs for Resource module
This commit is contained in:
Родитель
d7369a90e1
Коммит
b8e79586eb
|
@ -52,6 +52,10 @@ Cu.import("resource://weave/auth.js");
|
||||||
|
|
||||||
Function.prototype.async = Async.sugar;
|
Function.prototype.async = Async.sugar;
|
||||||
|
|
||||||
|
// = RequestException =
|
||||||
|
//
|
||||||
|
// This function raises an exception through the call
|
||||||
|
// stack for a failed network request.
|
||||||
function RequestException(resource, action, request) {
|
function RequestException(resource, action, request) {
|
||||||
this._resource = resource;
|
this._resource = resource;
|
||||||
this._action = action;
|
this._action = action;
|
||||||
|
@ -69,12 +73,21 @@ RequestException.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// = Resource =
|
||||||
|
//
|
||||||
|
// Represents a remote network resource, identified by a URI.
|
||||||
function Resource(uri) {
|
function Resource(uri) {
|
||||||
this._init(uri);
|
this._init(uri);
|
||||||
}
|
}
|
||||||
Resource.prototype = {
|
Resource.prototype = {
|
||||||
_logName: "Net.Resource",
|
_logName: "Net.Resource",
|
||||||
|
|
||||||
|
// ** {{{ Resource.authenticator }}} **
|
||||||
|
//
|
||||||
|
// Getter and setter for the authenticator module
|
||||||
|
// responsible for this particular resource. The authenticator
|
||||||
|
// module may modify the headers to perform authentication
|
||||||
|
// while performing a request for the resource, for example.
|
||||||
get authenticator() {
|
get authenticator() {
|
||||||
if (this._authenticator)
|
if (this._authenticator)
|
||||||
return this._authenticator;
|
return this._authenticator;
|
||||||
|
@ -85,6 +98,11 @@ Resource.prototype = {
|
||||||
this._authenticator = value;
|
this._authenticator = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.headers }}} **
|
||||||
|
//
|
||||||
|
// Getter for access to received headers after the request
|
||||||
|
// for the resource has been made, setter for headers to be included
|
||||||
|
// while making a request for the resource.
|
||||||
get headers() {
|
get headers() {
|
||||||
return this.authenticator.onRequest(this._headers);
|
return this.authenticator.onRequest(this._headers);
|
||||||
},
|
},
|
||||||
|
@ -99,6 +117,9 @@ Resource.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.uri }}} **
|
||||||
|
//
|
||||||
|
// URI representing this resource.
|
||||||
get uri() {
|
get uri() {
|
||||||
return this._uri;
|
return this._uri;
|
||||||
},
|
},
|
||||||
|
@ -111,12 +132,18 @@ Resource.prototype = {
|
||||||
this._uri = value;
|
this._uri = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.spec }}} **
|
||||||
|
//
|
||||||
|
// Get the string representation of the URI.
|
||||||
get spec() {
|
get spec() {
|
||||||
if (this._uri)
|
if (this._uri)
|
||||||
return this._uri.spec;
|
return this._uri.spec;
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.data }}} **
|
||||||
|
//
|
||||||
|
// Get and set the data encapulated in the resource.
|
||||||
_data: null,
|
_data: null,
|
||||||
get data() this._data,
|
get data() this._data,
|
||||||
set data(value) {
|
set data(value) {
|
||||||
|
@ -131,6 +158,11 @@ Resource.prototype = {
|
||||||
get downloaded() this._downloaded,
|
get downloaded() this._downloaded,
|
||||||
get dirty() this._dirty,
|
get dirty() this._dirty,
|
||||||
|
|
||||||
|
// ** {{{ Resource.filters }}} **
|
||||||
|
//
|
||||||
|
// Filters are used to perform pre and post processing on
|
||||||
|
// requests made for resources. Use these methods to add,
|
||||||
|
// remove and clear filters applied to the resource.
|
||||||
_filters: null,
|
_filters: null,
|
||||||
pushFilter: function Res_pushFilter(filter) {
|
pushFilter: function Res_pushFilter(filter) {
|
||||||
this._filters.push(filter);
|
this._filters.push(filter);
|
||||||
|
@ -151,19 +183,28 @@ Resource.prototype = {
|
||||||
this._filters = [];
|
this._filters = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource._createRequest }}} **
|
||||||
|
//
|
||||||
|
// This method returns a new IO Channel for requests to be made
|
||||||
|
// through. It is never called directly, only {{{_request}}} uses it
|
||||||
|
// to obtain a request channel.
|
||||||
|
//
|
||||||
_createRequest: function Res__createRequest() {
|
_createRequest: function Res__createRequest() {
|
||||||
this._lastChannel = Svc.IO.newChannel(this.spec, null, null).
|
this._lastChannel = Svc.IO.newChannel(this.spec, null, null).
|
||||||
QueryInterface(Ci.nsIRequest);
|
QueryInterface(Ci.nsIRequest);
|
||||||
|
|
||||||
// Always validate the cache:
|
// Always validate the cache:
|
||||||
let loadFlags = this._lastChannel.loadFlags;
|
let loadFlags = this._lastChannel.loadFlags;
|
||||||
loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||||
loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
||||||
this._lastChannel.loadFlags = loadFlags;
|
this._lastChannel.loadFlags = loadFlags;
|
||||||
this._lastChannel = this._lastChannel.QueryInterface(Ci.nsIHttpChannel);
|
this._lastChannel = this._lastChannel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
|
||||||
|
// Setup a callback to handle bad HTTPS certificates.
|
||||||
this._lastChannel.notificationCallbacks = new badCertListener();
|
this._lastChannel.notificationCallbacks = new badCertListener();
|
||||||
|
|
||||||
let headers = this.headers; // avoid calling the authorizer more than once
|
// Avoid calling the authorizer more than once
|
||||||
|
let headers = this.headers;
|
||||||
for (let key in headers) {
|
for (let key in headers) {
|
||||||
if (key == 'Authorization')
|
if (key == 'Authorization')
|
||||||
this._log.trace("HTTP Header " + key + ": ***** (suppressed)");
|
this._log.trace("HTTP Header " + key + ": ***** (suppressed)");
|
||||||
|
@ -178,6 +219,10 @@ Resource.prototype = {
|
||||||
this._lastProgress = Date.now();
|
this._lastProgress = Date.now();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.filterUpload }}} **
|
||||||
|
//
|
||||||
|
// Apply pre-request filters. Currently, this is done before
|
||||||
|
// any PUT request.
|
||||||
filterUpload: function Res_filterUpload(onComplete) {
|
filterUpload: function Res_filterUpload(onComplete) {
|
||||||
let fn = function() {
|
let fn = function() {
|
||||||
let self = yield;
|
let self = yield;
|
||||||
|
@ -188,6 +233,10 @@ Resource.prototype = {
|
||||||
fn.async(this, onComplete);
|
fn.async(this, onComplete);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.filterDownload }}} **
|
||||||
|
//
|
||||||
|
// Apply post-request filters. Currently, this done after
|
||||||
|
// any GET request.
|
||||||
filterDownload: function Res_filterUpload(onComplete) {
|
filterDownload: function Res_filterUpload(onComplete) {
|
||||||
let fn = function() {
|
let fn = function() {
|
||||||
let self = yield;
|
let self = yield;
|
||||||
|
@ -199,6 +248,11 @@ Resource.prototype = {
|
||||||
fn.async(this, onComplete);
|
fn.async(this, onComplete);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource._request }}} **
|
||||||
|
//
|
||||||
|
// Perform a particular HTTP request on the resource. This method
|
||||||
|
// is never called directly, but is used by the high-level
|
||||||
|
// {{{get}}}, {{{put}}}, {{{post}}} and {{delete}} methods.
|
||||||
_request: function Res__request(action, data) {
|
_request: function Res__request(action, data) {
|
||||||
let self = yield;
|
let self = yield;
|
||||||
let iter = 0;
|
let iter = 0;
|
||||||
|
@ -207,6 +261,8 @@ Resource.prototype = {
|
||||||
if ("undefined" != typeof(data))
|
if ("undefined" != typeof(data))
|
||||||
this._data = data;
|
this._data = data;
|
||||||
|
|
||||||
|
// PUT and POST are trreated differently because
|
||||||
|
// they have payload data.
|
||||||
if ("PUT" == action || "POST" == action) {
|
if ("PUT" == action || "POST" == action) {
|
||||||
yield this.filterUpload(self.cb);
|
yield this.filterUpload(self.cb);
|
||||||
this._log.trace(action + " Body:\n" + this._data);
|
this._log.trace(action + " Body:\n" + this._data);
|
||||||
|
@ -222,6 +278,8 @@ Resource.prototype = {
|
||||||
channel.setUploadStream(stream, type, this._data.length);
|
channel.setUploadStream(stream, type, this._data.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup a channel listener so that the actual network operation
|
||||||
|
// is performed asynchronously.
|
||||||
let listener = new ChannelListener(self.cb, this._onProgress, this._log);
|
let listener = new ChannelListener(self.cb, this._onProgress, this._log);
|
||||||
channel.requestMethod = action;
|
channel.requestMethod = action;
|
||||||
this._data = yield channel.asyncOpen(listener, null);
|
this._data = yield channel.asyncOpen(listener, null);
|
||||||
|
@ -253,23 +311,40 @@ Resource.prototype = {
|
||||||
self.done(this._data);
|
self.done(this._data);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.get }}} **
|
||||||
|
//
|
||||||
|
// Perform an asynchronous HTTP GET for this resource.
|
||||||
|
// onComplete will be called on completion of the request.
|
||||||
get: function Res_get(onComplete) {
|
get: function Res_get(onComplete) {
|
||||||
this._request.async(this, onComplete, "GET");
|
this._request.async(this, onComplete, "GET");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.get }}} **
|
||||||
|
//
|
||||||
|
// Perform a HTTP PUT for this resource.
|
||||||
put: function Res_put(onComplete, data) {
|
put: function Res_put(onComplete, data) {
|
||||||
this._request.async(this, onComplete, "PUT", data);
|
this._request.async(this, onComplete, "PUT", data);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.post }}} **
|
||||||
|
//
|
||||||
|
// Perform a HTTP POST for this resource.
|
||||||
post: function Res_post(onComplete, data) {
|
post: function Res_post(onComplete, data) {
|
||||||
this._request.async(this, onComplete, "POST", data);
|
this._request.async(this, onComplete, "POST", data);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ Resource.delete }}} **
|
||||||
|
//
|
||||||
|
// Perform a HTTP DELETE for this resource.
|
||||||
delete: function Res_delete(onComplete) {
|
delete: function Res_delete(onComplete) {
|
||||||
this._request.async(this, onComplete, "DELETE");
|
this._request.async(this, onComplete, "DELETE");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// = ChannelListener =
|
||||||
|
//
|
||||||
|
// This object implements the {{{nsIStreamListener}}} interface
|
||||||
|
// and is called as the network operation proceeds.
|
||||||
function ChannelListener(onComplete, onProgress, logger) {
|
function ChannelListener(onComplete, onProgress, logger) {
|
||||||
this._onComplete = onComplete;
|
this._onComplete = onComplete;
|
||||||
this._onProgress = onProgress;
|
this._onProgress = onProgress;
|
||||||
|
@ -302,11 +377,24 @@ ChannelListener.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Parses out single WBOs from a full dump */
|
// = RecordParser =
|
||||||
|
//
|
||||||
|
// This object retrives single WBOs from a stream of incoming
|
||||||
|
// JSON. This should be useful for performance optimizations
|
||||||
|
// in cases where memory is low (on Fennec, for example).
|
||||||
|
//
|
||||||
|
// XXX: Note that this parser is currently not used because we
|
||||||
|
// are yet to figure out the best way to integrate it with the
|
||||||
|
// asynchronous nature of {{{ChannelListener}}}. Ed's work in the
|
||||||
|
// Sync module will make this easier in the future.
|
||||||
function RecordParser(data) {
|
function RecordParser(data) {
|
||||||
this._data = data;
|
this._data = data;
|
||||||
}
|
}
|
||||||
RecordParser.prototype = {
|
RecordParser.prototype = {
|
||||||
|
// ** {{{ RecordParser.getNextRecord }}} **
|
||||||
|
//
|
||||||
|
// Returns a single WBO from the stream of JSON received
|
||||||
|
// so far.
|
||||||
getNextRecord: function RecordParser_getNextRecord() {
|
getNextRecord: function RecordParser_getNextRecord() {
|
||||||
let start;
|
let start;
|
||||||
let bCount = 0;
|
let bCount = 0;
|
||||||
|
@ -333,11 +421,23 @@ RecordParser.prototype = {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ** {{{ RecordParser.append }}} **
|
||||||
|
//
|
||||||
|
// Appends data to the current internal buffer
|
||||||
|
// of received data by the parser. The buffer
|
||||||
|
// is continously processed as {{{getNextRecord}}}
|
||||||
|
// is called, so the caller need not keep a copy
|
||||||
|
// of the data passed to this function.
|
||||||
append: function RecordParser_append(data) {
|
append: function RecordParser_append(data) {
|
||||||
this._data += data;
|
this._data += data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// = JsonFilter =
|
||||||
|
//
|
||||||
|
// Currently, the only filter used in conjunction with
|
||||||
|
// {{{Resource.filters}}}. It simply encodes outgoing records
|
||||||
|
// as JSON, and decodes incoming JSON into JS objects.
|
||||||
function JsonFilter() {
|
function JsonFilter() {
|
||||||
let level = "Debug";
|
let level = "Debug";
|
||||||
try { level = Utils.prefs.getCharPref("log.logger.network.jsonFilter"); }
|
try { level = Utils.prefs.getCharPref("log.logger.network.jsonFilter"); }
|
||||||
|
@ -359,6 +459,13 @@ JsonFilter.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// = badCertListener =
|
||||||
|
//
|
||||||
|
// We use this listener to ignore bad HTTPS
|
||||||
|
// certificates and continue a request on a network
|
||||||
|
// channel. Probably not a very smart thing to do,
|
||||||
|
// but greatly simplifies debugging and is just very
|
||||||
|
// convenient.
|
||||||
function badCertListener() {
|
function badCertListener() {
|
||||||
}
|
}
|
||||||
badCertListener.prototype = {
|
badCertListener.prototype = {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче