mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge services-central into mozilla-central
This commit is contained in:
commit
9d66d1498f
@ -57,7 +57,7 @@
|
|||||||
<implementation>
|
<implementation>
|
||||||
<constructor><![CDATA[
|
<constructor><![CDATA[
|
||||||
let temp = {};
|
let temp = {};
|
||||||
Cu.import("resource://services-sync/ext/Observers.js", temp);
|
Cu.import("resource://services-common/observers.js", temp);
|
||||||
temp.Observers.add("weave:notification:added", this.onNotificationAdded, this);
|
temp.Observers.add("weave:notification:added", this.onNotificationAdded, this);
|
||||||
temp.Observers.add("weave:notification:removed", this.onNotificationRemoved, this);
|
temp.Observers.add("weave:notification:removed", this.onNotificationRemoved, this);
|
||||||
|
|
||||||
@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
<destructor><![CDATA[
|
<destructor><![CDATA[
|
||||||
let temp = {};
|
let temp = {};
|
||||||
Cu.import("resource://services-sync/ext/Observers.js", temp);
|
Cu.import("resource://services-common/observers.js", temp);
|
||||||
temp.Observers.remove("weave:notification:added", this.onNotificationAdded, this);
|
temp.Observers.remove("weave:notification:added", this.onNotificationAdded, this);
|
||||||
temp.Observers.remove("weave:notification:removed", this.onNotificationRemoved, this);
|
temp.Observers.remove("weave:notification:removed", this.onNotificationRemoved, this);
|
||||||
]]></destructor>
|
]]></destructor>
|
||||||
|
@ -1031,6 +1031,13 @@ xpicleanup@BIN_SUFFIX@
|
|||||||
modules/PropertyPanel.jsm
|
modules/PropertyPanel.jsm
|
||||||
modules/reflect.jsm
|
modules/reflect.jsm
|
||||||
modules/Services.jsm
|
modules/Services.jsm
|
||||||
|
modules/services-common/async.js
|
||||||
|
modules/services-common/log4moz.js
|
||||||
|
modules/services-common/observers.js
|
||||||
|
modules/services-common/preferences.js
|
||||||
|
modules/services-common/rest.js
|
||||||
|
modules/services-common/stringbundle.js
|
||||||
|
modules/services-common/utils.js
|
||||||
modules/services-sync/auth.js
|
modules/services-sync/auth.js
|
||||||
modules/services-sync/base_records/collection.js
|
modules/services-sync/base_records/collection.js
|
||||||
modules/services-sync/base_records/crypto.js
|
modules/services-sync/base_records/crypto.js
|
||||||
|
@ -43,7 +43,7 @@ VPATH = @srcdir@
|
|||||||
include $(DEPTH)/config/autoconf.mk
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
ifdef MOZ_SERVICES_SYNC
|
ifdef MOZ_SERVICES_SYNC
|
||||||
PARALLEL_DIRS += crypto sync
|
PARALLEL_DIRS += common crypto sync
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
34
services/common/Makefile.in
Normal file
34
services/common/Makefile.in
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
DEPTH = ../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
PREF_JS_EXPORTS = $(srcdir)/services-common.js
|
||||||
|
|
||||||
|
modules := \
|
||||||
|
async.js \
|
||||||
|
log4moz.js \
|
||||||
|
observers.js \
|
||||||
|
preferences.js \
|
||||||
|
rest.js \
|
||||||
|
stringbundle.js \
|
||||||
|
tokenserverclient.js \
|
||||||
|
utils.js \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
source_modules = $(foreach module,$(modules),$(srcdir)/$(module))
|
||||||
|
module_dir = $(FINAL_TARGET)/modules/services-common
|
||||||
|
|
||||||
|
libs::
|
||||||
|
$(NSINSTALL) -D $(module_dir)
|
||||||
|
$(NSINSTALL) -l $(source_modules) $(module_dir)
|
||||||
|
|
||||||
|
TEST_DIRS += tests
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
@ -1,46 +1,10 @@
|
|||||||
/* ***** BEGIN LICENSE BLOCK *****
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
*
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is Firefox Sync.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* the Mozilla Foundation.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Richard Newman <rnewman@mozilla.com>
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
const EXPORTED_SYMBOLS = ['Async'];
|
const EXPORTED_SYMBOLS = ["Async"];
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||||
const Ci = Components.interfaces;
|
|
||||||
const Cr = Components.results;
|
|
||||||
const Cu = Components.utils;
|
|
||||||
|
|
||||||
// Constants for makeSyncCallback, waitForSyncCallback.
|
// Constants for makeSyncCallback, waitForSyncCallback.
|
||||||
const CB_READY = {};
|
const CB_READY = {};
|
||||||
@ -61,10 +25,10 @@ let Async = {
|
|||||||
* other, passing the callback arguments on to the next one. All functions
|
* other, passing the callback arguments on to the next one. All functions
|
||||||
* must take a callback function as their last argument. The 'this' object
|
* must take a callback function as their last argument. The 'this' object
|
||||||
* will be whatever chain()'s is.
|
* will be whatever chain()'s is.
|
||||||
*
|
*
|
||||||
* @usage this._chain = Async.chain;
|
* @usage this._chain = Async.chain;
|
||||||
* this._chain(this.foo, this.bar, this.baz)(args, for, foo)
|
* this._chain(this.foo, this.bar, this.baz)(args, for, foo)
|
||||||
*
|
*
|
||||||
* This is equivalent to:
|
* This is equivalent to:
|
||||||
*
|
*
|
||||||
* let self = this;
|
* let self = this;
|
@ -39,10 +39,7 @@
|
|||||||
|
|
||||||
const EXPORTED_SYMBOLS = ['Log4Moz'];
|
const EXPORTED_SYMBOLS = ['Log4Moz'];
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||||
const Ci = Components.interfaces;
|
|
||||||
const Cr = Components.results;
|
|
||||||
const Cu = Components.utils;
|
|
||||||
|
|
||||||
const ONE_BYTE = 1;
|
const ONE_BYTE = 1;
|
||||||
const ONE_KILOBYTE = 1024 * ONE_BYTE;
|
const ONE_KILOBYTE = 1024 * ONE_BYTE;
|
||||||
@ -373,7 +370,7 @@ BasicFormatter.prototype = {
|
|||||||
__proto__: Formatter.prototype,
|
__proto__: Formatter.prototype,
|
||||||
|
|
||||||
format: function BF_format(message) {
|
format: function BF_format(message) {
|
||||||
return message.time + "\t" + message.loggerName + "\t" + message.levelDesc
|
return message.time + "\t" + message.loggerName + "\t" + message.levelDesc
|
||||||
+ "\t" + message.message + "\n";
|
+ "\t" + message.message + "\n";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -442,7 +439,7 @@ ConsoleAppender.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Base implementation for stream based appenders.
|
* Base implementation for stream based appenders.
|
||||||
*
|
*
|
||||||
* Caution: This writes to the output stream synchronously, thus logging calls
|
* Caution: This writes to the output stream synchronously, thus logging calls
|
||||||
* block as the data is written to the stream. This can have negligible impact
|
* block as the data is written to the stream. This can have negligible impact
|
||||||
* for in-memory streams, but should be taken into account for I/O streams
|
* for in-memory streams, but should be taken into account for I/O streams
|
||||||
@ -460,7 +457,7 @@ BlockingStreamAppender.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Output stream to write to.
|
* Output stream to write to.
|
||||||
*
|
*
|
||||||
* This will automatically open the stream if it doesn't exist yet by
|
* This will automatically open the stream if it doesn't exist yet by
|
||||||
* calling newOutputStream. The resulting raw stream is wrapped in a
|
* calling newOutputStream. The resulting raw stream is wrapped in a
|
||||||
* nsIConverterOutputStream to ensure text is written as UTF-8.
|
* nsIConverterOutputStream to ensure text is written as UTF-8.
|
||||||
@ -481,7 +478,7 @@ BlockingStreamAppender.prototype = {
|
|||||||
}
|
}
|
||||||
this._converterStream.init(
|
this._converterStream.init(
|
||||||
this._outputStream, "UTF-8", STREAM_SEGMENT_SIZE,
|
this._outputStream, "UTF-8", STREAM_SEGMENT_SIZE,
|
||||||
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
|
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
|
||||||
}
|
}
|
||||||
return this._converterStream;
|
return this._converterStream;
|
||||||
},
|
},
|
||||||
@ -521,7 +518,7 @@ BlockingStreamAppender.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Append to an nsIStorageStream
|
* Append to an nsIStorageStream
|
||||||
*
|
*
|
||||||
* This writes logging output to an in-memory stream which can later be read
|
* This writes logging output to an in-memory stream which can later be read
|
||||||
* back as an nsIInputStream. It can be used to avoid expensive I/O operations
|
* back as an nsIInputStream. It can be used to avoid expensive I/O operations
|
||||||
* during logging. Instead, one can periodically consume the input stream and
|
* during logging. Instead, one can periodically consume the input stream and
|
||||||
@ -531,7 +528,7 @@ function StorageStreamAppender(formatter) {
|
|||||||
this._name = "StorageStreamAppender";
|
this._name = "StorageStreamAppender";
|
||||||
BlockingStreamAppender.call(this, formatter);
|
BlockingStreamAppender.call(this, formatter);
|
||||||
}
|
}
|
||||||
StorageStreamAppender.prototype = {
|
StorageStreamAppender.prototype = {
|
||||||
__proto__: BlockingStreamAppender.prototype,
|
__proto__: BlockingStreamAppender.prototype,
|
||||||
|
|
||||||
_ss: null,
|
_ss: null,
|
||||||
@ -590,7 +587,7 @@ FileAppender.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotating file appender (discouraged)
|
* Rotating file appender (discouraged)
|
||||||
*
|
*
|
||||||
* Similar to FileAppender, but rotates logs when they become too large.
|
* Similar to FileAppender, but rotates logs when they become too large.
|
||||||
*/
|
*/
|
||||||
function RotatingFileAppender(file, formatter, maxSize, maxBackups) {
|
function RotatingFileAppender(file, formatter, maxSize, maxBackups) {
|
578
services/common/rest.js
Normal file
578
services/common/rest.js
Normal file
@ -0,0 +1,578 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
|
const EXPORTED_SYMBOLS = ["RESTRequest", "RESTResponse"];
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
|
const Prefs = new Preferences("services.common.rest.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single use HTTP requests to RESTish resources.
|
||||||
|
*
|
||||||
|
* @param uri
|
||||||
|
* URI for the request. This can be an nsIURI object or a string
|
||||||
|
* that can be used to create one. An exception will be thrown if
|
||||||
|
* the string is not a valid URI.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* (1) Quick GET request:
|
||||||
|
*
|
||||||
|
* new RESTRequest("http://server/rest/resource").get(function (error) {
|
||||||
|
* if (error) {
|
||||||
|
* // Deal with a network error.
|
||||||
|
* processNetworkErrorCode(error.result);
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* if (!this.response.success) {
|
||||||
|
* // Bail out if we're not getting an HTTP 2xx code.
|
||||||
|
* processHTTPError(this.response.status);
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* processData(this.response.body);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* (2) Quick PUT request (non-string data is automatically JSONified)
|
||||||
|
*
|
||||||
|
* new RESTRequest("http://server/rest/resource").put(data, function (error) {
|
||||||
|
* ...
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* (3) Streaming GET
|
||||||
|
*
|
||||||
|
* let request = new RESTRequest("http://server/rest/resource");
|
||||||
|
* request.setHeader("Accept", "application/newlines");
|
||||||
|
* request.onComplete = function (error) {
|
||||||
|
* if (error) {
|
||||||
|
* // Deal with a network error.
|
||||||
|
* processNetworkErrorCode(error.result);
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* callbackAfterRequestHasCompleted()
|
||||||
|
* });
|
||||||
|
* request.onProgress = function () {
|
||||||
|
* if (!this.response.success) {
|
||||||
|
* // Bail out if we're not getting an HTTP 2xx code.
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* // Process body data and reset it so we don't process the same data twice.
|
||||||
|
* processIncrementalData(this.response.body);
|
||||||
|
* this.response.body = "";
|
||||||
|
* });
|
||||||
|
* request.get();
|
||||||
|
*/
|
||||||
|
function RESTRequest(uri) {
|
||||||
|
this.status = this.NOT_SENT;
|
||||||
|
|
||||||
|
// If we don't have an nsIURI object yet, make one. This will throw if
|
||||||
|
// 'uri' isn't a valid URI string.
|
||||||
|
if (!(uri instanceof Ci.nsIURI)) {
|
||||||
|
uri = Services.io.newURI(uri, null, null);
|
||||||
|
}
|
||||||
|
this.uri = uri;
|
||||||
|
|
||||||
|
this._headers = {};
|
||||||
|
this._log = Log4Moz.repository.getLogger(this._logName);
|
||||||
|
this._log.level =
|
||||||
|
Log4Moz.Level[Prefs.get("log.logger.rest.request")];
|
||||||
|
}
|
||||||
|
RESTRequest.prototype = {
|
||||||
|
|
||||||
|
_logName: "Services.Common.RESTRequest",
|
||||||
|
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([
|
||||||
|
Ci.nsIBadCertListener2,
|
||||||
|
Ci.nsIInterfaceRequestor,
|
||||||
|
Ci.nsIChannelEventSink
|
||||||
|
]),
|
||||||
|
|
||||||
|
/*** Public API: ***/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URI for the request (an nsIURI object).
|
||||||
|
*/
|
||||||
|
uri: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP method (e.g. "GET")
|
||||||
|
*/
|
||||||
|
method: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RESTResponse object
|
||||||
|
*/
|
||||||
|
response: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsIRequest load flags. Don't do any caching by default.
|
||||||
|
*/
|
||||||
|
loadFlags: Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsIHttpChannel
|
||||||
|
*/
|
||||||
|
channel: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to indicate the status of the request.
|
||||||
|
*
|
||||||
|
* One of NOT_SENT, SENT, IN_PROGRESS, COMPLETED, ABORTED.
|
||||||
|
*/
|
||||||
|
status: null,
|
||||||
|
|
||||||
|
NOT_SENT: 0,
|
||||||
|
SENT: 1,
|
||||||
|
IN_PROGRESS: 2,
|
||||||
|
COMPLETED: 4,
|
||||||
|
ABORTED: 8,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request timeout (in seconds, though decimal values can be used for
|
||||||
|
* up to millisecond granularity.)
|
||||||
|
*
|
||||||
|
* 0 for no timeout.
|
||||||
|
*/
|
||||||
|
timeout: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the request has been completed, including failures and
|
||||||
|
* timeouts.
|
||||||
|
*
|
||||||
|
* @param error
|
||||||
|
* Error that occurred while making the request, null if there
|
||||||
|
* was no error.
|
||||||
|
*/
|
||||||
|
onComplete: function onComplete(error) {
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever data is being received on the channel. If this throws an
|
||||||
|
* exception, the request is aborted and the exception is passed as the
|
||||||
|
* error to onComplete().
|
||||||
|
*/
|
||||||
|
onProgress: function onProgress() {
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a request header.
|
||||||
|
*/
|
||||||
|
setHeader: function setHeader(name, value) {
|
||||||
|
this._headers[name.toLowerCase()] = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an HTTP GET.
|
||||||
|
*
|
||||||
|
* @param onComplete
|
||||||
|
* Short-circuit way to set the 'onComplete' method. Optional.
|
||||||
|
* @param onProgress
|
||||||
|
* Short-circuit way to set the 'onProgress' method. Optional.
|
||||||
|
*
|
||||||
|
* @return the request object.
|
||||||
|
*/
|
||||||
|
get: function get(onComplete, onProgress) {
|
||||||
|
return this.dispatch("GET", null, onComplete, onProgress);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an HTTP PUT.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* Data to be used as the request body. If this isn't a string
|
||||||
|
* it will be JSONified automatically.
|
||||||
|
* @param onComplete
|
||||||
|
* Short-circuit way to set the 'onComplete' method. Optional.
|
||||||
|
* @param onProgress
|
||||||
|
* Short-circuit way to set the 'onProgress' method. Optional.
|
||||||
|
*
|
||||||
|
* @return the request object.
|
||||||
|
*/
|
||||||
|
put: function put(data, onComplete, onProgress) {
|
||||||
|
return this.dispatch("PUT", data, onComplete, onProgress);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an HTTP POST.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* Data to be used as the request body. If this isn't a string
|
||||||
|
* it will be JSONified automatically.
|
||||||
|
* @param onComplete
|
||||||
|
* Short-circuit way to set the 'onComplete' method. Optional.
|
||||||
|
* @param onProgress
|
||||||
|
* Short-circuit way to set the 'onProgress' method. Optional.
|
||||||
|
*
|
||||||
|
* @return the request object.
|
||||||
|
*/
|
||||||
|
post: function post(data, onComplete, onProgress) {
|
||||||
|
return this.dispatch("POST", data, onComplete, onProgress);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an HTTP DELETE.
|
||||||
|
*
|
||||||
|
* @param onComplete
|
||||||
|
* Short-circuit way to set the 'onComplete' method. Optional.
|
||||||
|
* @param onProgress
|
||||||
|
* Short-circuit way to set the 'onProgress' method. Optional.
|
||||||
|
*
|
||||||
|
* @return the request object.
|
||||||
|
*/
|
||||||
|
delete: function delete_(onComplete, onProgress) {
|
||||||
|
return this.dispatch("DELETE", null, onComplete, onProgress);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort an active request.
|
||||||
|
*/
|
||||||
|
abort: function abort() {
|
||||||
|
if (this.status != this.SENT && this.status != this.IN_PROGRESS) {
|
||||||
|
throw "Can only abort a request that has been sent.";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.status = this.ABORTED;
|
||||||
|
this.channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
|
|
||||||
|
if (this.timeoutTimer) {
|
||||||
|
// Clear the abort timer now that the channel is done.
|
||||||
|
this.timeoutTimer.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*** Implementation stuff ***/
|
||||||
|
|
||||||
|
dispatch: function dispatch(method, data, onComplete, onProgress) {
|
||||||
|
if (this.status != this.NOT_SENT) {
|
||||||
|
throw "Request has already been sent!";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.method = method;
|
||||||
|
if (onComplete) {
|
||||||
|
this.onComplete = onComplete;
|
||||||
|
}
|
||||||
|
if (onProgress) {
|
||||||
|
this.onProgress = onProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and initialize HTTP channel.
|
||||||
|
let channel = Services.io.newChannelFromURI(this.uri, null, null)
|
||||||
|
.QueryInterface(Ci.nsIRequest)
|
||||||
|
.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
this.channel = channel;
|
||||||
|
channel.loadFlags |= this.loadFlags;
|
||||||
|
channel.notificationCallbacks = this;
|
||||||
|
|
||||||
|
// Set request headers.
|
||||||
|
let headers = this._headers;
|
||||||
|
for (let key in headers) {
|
||||||
|
if (key == 'authorization') {
|
||||||
|
this._log.trace("HTTP Header " + key + ": ***** (suppressed)");
|
||||||
|
} else {
|
||||||
|
this._log.trace("HTTP Header " + key + ": " + headers[key]);
|
||||||
|
}
|
||||||
|
channel.setRequestHeader(key, headers[key], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set HTTP request body.
|
||||||
|
if (method == "PUT" || method == "POST") {
|
||||||
|
// Convert non-string bodies into JSON.
|
||||||
|
if (typeof data != "string") {
|
||||||
|
data = JSON.stringify(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._log.debug(method + " Length: " + data.length);
|
||||||
|
if (this._log.level <= Log4Moz.Level.Trace) {
|
||||||
|
this._log.trace(method + " Body: " + data);
|
||||||
|
}
|
||||||
|
|
||||||
|
let stream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||||
|
.createInstance(Ci.nsIStringInputStream);
|
||||||
|
stream.setData(data, data.length);
|
||||||
|
|
||||||
|
let type = headers["content-type"] || "text/plain";
|
||||||
|
channel.QueryInterface(Ci.nsIUploadChannel);
|
||||||
|
channel.setUploadStream(stream, type, data.length);
|
||||||
|
}
|
||||||
|
// We must set this after setting the upload stream, otherwise it
|
||||||
|
// will always be 'PUT'. Yeah, I know.
|
||||||
|
channel.requestMethod = method;
|
||||||
|
|
||||||
|
// Blast off!
|
||||||
|
channel.asyncOpen(this, null);
|
||||||
|
this.status = this.SENT;
|
||||||
|
this.delayTimeout();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or push back the abort timer that kills this request.
|
||||||
|
*/
|
||||||
|
delayTimeout: function delayTimeout() {
|
||||||
|
if (this.timeout) {
|
||||||
|
CommonUtils.namedTimer(this.abortTimeout, this.timeout * 1000, this,
|
||||||
|
"timeoutTimer");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort the request based on a timeout.
|
||||||
|
*/
|
||||||
|
abortTimeout: function abortTimeout() {
|
||||||
|
this.abort();
|
||||||
|
let error = Components.Exception("Aborting due to channel inactivity.",
|
||||||
|
Cr.NS_ERROR_NET_TIMEOUT);
|
||||||
|
if (!this.onComplete) {
|
||||||
|
this._log.error("Unexpected error: onComplete not defined in " +
|
||||||
|
"abortTimeout.")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.onComplete(error);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*** nsIStreamListener ***/
|
||||||
|
|
||||||
|
onStartRequest: function onStartRequest(channel) {
|
||||||
|
if (this.status == this.ABORTED) {
|
||||||
|
this._log.trace("Not proceeding with onStartRequest, request was aborted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.error("Unexpected error: channel is not a nsIHttpChannel!");
|
||||||
|
this.status = this.ABORTED;
|
||||||
|
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.status = this.IN_PROGRESS;
|
||||||
|
|
||||||
|
this._log.trace("onStartRequest: " + channel.requestMethod + " " +
|
||||||
|
channel.URI.spec);
|
||||||
|
|
||||||
|
// Create a response object and fill it with some data.
|
||||||
|
let response = this.response = new RESTResponse();
|
||||||
|
response.request = this;
|
||||||
|
response.body = "";
|
||||||
|
|
||||||
|
// Define this here so that we don't have make a new one each time
|
||||||
|
// onDataAvailable() gets called.
|
||||||
|
this._inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
|
||||||
|
.createInstance(Ci.nsIScriptableInputStream);
|
||||||
|
|
||||||
|
this.delayTimeout();
|
||||||
|
},
|
||||||
|
|
||||||
|
onStopRequest: function onStopRequest(channel, context, statusCode) {
|
||||||
|
if (this.timeoutTimer) {
|
||||||
|
// Clear the abort timer now that the channel is done.
|
||||||
|
this.timeoutTimer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to do anything for a request that's already been aborted.
|
||||||
|
if (this.status == this.ABORTED) {
|
||||||
|
this._log.trace("Not proceeding with onStopRequest, request was aborted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.error("Unexpected error: channel not nsIHttpChannel!");
|
||||||
|
this.status = this.ABORTED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.status = this.COMPLETED;
|
||||||
|
|
||||||
|
let statusSuccess = Components.isSuccessCode(statusCode);
|
||||||
|
let uri = channel && channel.URI && channel.URI.spec || "<unknown>";
|
||||||
|
this._log.trace("Channel for " + channel.requestMethod + " " + uri +
|
||||||
|
" returned status code " + statusCode);
|
||||||
|
|
||||||
|
if (!this.onComplete) {
|
||||||
|
this._log.error("Unexpected error: onComplete not defined in " +
|
||||||
|
"abortRequest.");
|
||||||
|
this.onProgress = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw the failure code and stop execution. Use Components.Exception()
|
||||||
|
// instead of Error() so the exception is QI-able and can be passed across
|
||||||
|
// XPCOM borders while preserving the status code.
|
||||||
|
if (!statusSuccess) {
|
||||||
|
let message = Components.Exception("", statusCode).name;
|
||||||
|
let error = Components.Exception(message, statusCode);
|
||||||
|
this.onComplete(error);
|
||||||
|
this.onComplete = this.onProgress = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._log.debug(this.method + " " + uri + " " + this.response.status);
|
||||||
|
|
||||||
|
// Additionally give the full response body when Trace logging.
|
||||||
|
if (this._log.level <= Log4Moz.Level.Trace) {
|
||||||
|
this._log.trace(this.method + " body: " + this.response.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this._inputStream;
|
||||||
|
|
||||||
|
this.onComplete(null);
|
||||||
|
this.onComplete = this.onProgress = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDataAvailable: function onDataAvailable(req, cb, stream, off, count) {
|
||||||
|
this._inputStream.init(stream);
|
||||||
|
try {
|
||||||
|
this.response.body += this._inputStream.read(count);
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.warn("Exception thrown reading " + count +
|
||||||
|
" bytes from the channel.");
|
||||||
|
this._log.debug(CommonUtils.exceptionStr(ex));
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.onProgress();
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.warn("Got exception calling onProgress handler, aborting " +
|
||||||
|
this.method + " " + req.URI.spec);
|
||||||
|
this._log.debug("Exception: " + CommonUtils.exceptionStr(ex));
|
||||||
|
this.abort();
|
||||||
|
|
||||||
|
if (!this.onComplete) {
|
||||||
|
this._log.error("Unexpected error: onComplete not defined in " +
|
||||||
|
"onDataAvailable.");
|
||||||
|
this.onProgress = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onComplete(ex);
|
||||||
|
this.onComplete = this.onProgress = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.delayTimeout();
|
||||||
|
},
|
||||||
|
|
||||||
|
/*** nsIInterfaceRequestor ***/
|
||||||
|
|
||||||
|
getInterface: function(aIID) {
|
||||||
|
return this.QueryInterface(aIID);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*** nsIBadCertListener2 ***/
|
||||||
|
|
||||||
|
notifyCertProblem: function notifyCertProblem(socketInfo, sslStatus, targetHost) {
|
||||||
|
this._log.warn("Invalid HTTPS certificate encountered!");
|
||||||
|
// Suppress invalid HTTPS certificate warnings in the UI.
|
||||||
|
// (The request will still fail.)
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*** nsIChannelEventSink ***/
|
||||||
|
asyncOnChannelRedirect:
|
||||||
|
function asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
newChannel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.error("Unexpected error: channel not nsIHttpChannel!");
|
||||||
|
callback.onRedirectVerifyCallback(Cr.NS_ERROR_NO_INTERFACE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.channel = newChannel;
|
||||||
|
|
||||||
|
// We let all redirects proceed.
|
||||||
|
callback.onRedirectVerifyCallback(Cr.NS_OK);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response object for a RESTRequest. This will be created automatically by
|
||||||
|
* the RESTRequest.
|
||||||
|
*/
|
||||||
|
function RESTResponse() {
|
||||||
|
this._log = Log4Moz.repository.getLogger(this._logName);
|
||||||
|
this._log.level =
|
||||||
|
Log4Moz.Level[Prefs.get("log.logger.rest.response")];
|
||||||
|
}
|
||||||
|
RESTResponse.prototype = {
|
||||||
|
|
||||||
|
_logName: "Sync.RESTResponse",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corresponding REST request
|
||||||
|
*/
|
||||||
|
request: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP status code
|
||||||
|
*/
|
||||||
|
get status() {
|
||||||
|
let status;
|
||||||
|
try {
|
||||||
|
let channel = this.request.channel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
status = channel.responseStatus;
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.debug("Caught exception fetching HTTP status code:" +
|
||||||
|
CommonUtils.exceptionStr(ex));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
delete this.status;
|
||||||
|
return this.status = status;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean flag that indicates whether the HTTP status code is 2xx or not.
|
||||||
|
*/
|
||||||
|
get success() {
|
||||||
|
let success;
|
||||||
|
try {
|
||||||
|
let channel = this.request.channel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
success = channel.requestSucceeded;
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.debug("Caught exception fetching HTTP success flag:" +
|
||||||
|
CommonUtils.exceptionStr(ex));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
delete this.success;
|
||||||
|
return this.success = success;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object containing HTTP headers (keyed as lower case)
|
||||||
|
*/
|
||||||
|
get headers() {
|
||||||
|
let headers = {};
|
||||||
|
try {
|
||||||
|
this._log.trace("Processing response headers.");
|
||||||
|
let channel = this.request.channel.QueryInterface(Ci.nsIHttpChannel);
|
||||||
|
channel.visitResponseHeaders(function (header, value) {
|
||||||
|
headers[header.toLowerCase()] = value;
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.debug("Caught exception processing response headers:" +
|
||||||
|
CommonUtils.exceptionStr(ex));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.headers;
|
||||||
|
return this.headers = headers;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP body (string)
|
||||||
|
*/
|
||||||
|
body: null
|
||||||
|
|
||||||
|
};
|
7
services/common/services-common.js
Normal file
7
services/common/services-common.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// This file contains default preference values for components in
|
||||||
|
// services-common.
|
||||||
|
|
||||||
|
pref("services.common.log.logger.rest.request", "Debug");
|
||||||
|
pref("services.common.log.logger.rest.response", "Debug");
|
||||||
|
|
||||||
|
pref("services.common.tokenserverclient.logger.level", "Info");
|
@ -34,12 +34,9 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
let EXPORTED_SYMBOLS = ["StringBundle"];
|
const EXPORTED_SYMBOLS = ["StringBundle"];
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||||
const Ci = Components.interfaces;
|
|
||||||
const Cr = Components.results;
|
|
||||||
const Cu = Components.utils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A string bundle.
|
* A string bundle.
|
16
services/common/tests/Makefile.in
Normal file
16
services/common/tests/Makefile.in
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
DEPTH = ../../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
relativesrcdir = services/common/tests
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = test_services_common
|
||||||
|
XPCSHELL_TESTS = unit
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
54
services/common/tests/unit/head_global.js
Normal file
54
services/common/tests/unit/head_global.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Where to bind test HTTP servers to.
|
||||||
|
const TEST_SERVER_URL = "http://localhost:8080/";
|
||||||
|
|
||||||
|
// This has the side-effect of populating Cc, Ci, Cu, Cr. It's best not to
|
||||||
|
// ask questions and just accept it.
|
||||||
|
do_load_httpd_js();
|
||||||
|
const Cm = Components.manager;
|
||||||
|
|
||||||
|
let gSyncProfile = do_get_profile();
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
|
let XULAppInfo = {
|
||||||
|
vendor: "Mozilla",
|
||||||
|
name: "XPCShell",
|
||||||
|
ID: "xpcshell@tests.mozilla.org",
|
||||||
|
version: "1",
|
||||||
|
appBuildID: "20100621",
|
||||||
|
platformVersion: "",
|
||||||
|
platformBuildID: "20100621",
|
||||||
|
inSafeMode: false,
|
||||||
|
logConsoleErrors: true,
|
||||||
|
OS: "XPCShell",
|
||||||
|
XPCOMABI: "noarch-spidermonkey",
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, Ci.nsIXULRuntime]),
|
||||||
|
invalidateCachesOnRestart: function invalidateCachesOnRestart() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
let XULAppInfoFactory = {
|
||||||
|
createInstance: function (outer, iid) {
|
||||||
|
if (outer != null)
|
||||||
|
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||||
|
return XULAppInfo.QueryInterface(iid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
|
registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}"),
|
||||||
|
"XULAppInfo", "@mozilla.org/xre/app-info;1",
|
||||||
|
XULAppInfoFactory);
|
||||||
|
|
||||||
|
function addResourceAlias() {
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
const handler = Services.io.getProtocolHandler("resource")
|
||||||
|
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||||
|
|
||||||
|
let uri = Services.io.newURI("resource:///modules/services-common/", null,
|
||||||
|
null);
|
||||||
|
handler.setSubstitution("services-common", uri);
|
||||||
|
}
|
||||||
|
addResourceAlias();
|
173
services/common/tests/unit/head_helpers.js
Normal file
173
services/common/tests/unit/head_helpers.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
|
function do_check_empty(obj) {
|
||||||
|
do_check_attribute_count(obj, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_check_attribute_count(obj, c) {
|
||||||
|
do_check_eq(c, Object.keys(obj).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_check_throws(aFunc, aResult, aStack) {
|
||||||
|
if (!aStack) {
|
||||||
|
try {
|
||||||
|
// We might not have a 'Components' object.
|
||||||
|
aStack = Components.stack.caller;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
aFunc();
|
||||||
|
} catch (e) {
|
||||||
|
do_check_eq(e.result, aResult, aStack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_throw("Expected result " + aResult + ", none thrown.", aStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print some debug message to the console. All arguments will be printed,
|
||||||
|
* separated by spaces.
|
||||||
|
*
|
||||||
|
* @param [arg0, arg1, arg2, ...]
|
||||||
|
* Any number of arguments to print out
|
||||||
|
* @usage _("Hello World") -> prints "Hello World"
|
||||||
|
* @usage _(1, 2, 3) -> prints "1 2 3"
|
||||||
|
*/
|
||||||
|
let _ = function(some, debug, text, to) print(Array.slice(arguments).join(" "));
|
||||||
|
|
||||||
|
function initTestLogging(level) {
|
||||||
|
function LogStats() {
|
||||||
|
this.errorsLogged = 0;
|
||||||
|
}
|
||||||
|
LogStats.prototype = {
|
||||||
|
format: function BF_format(message) {
|
||||||
|
if (message.level == Log4Moz.Level.Error)
|
||||||
|
this.errorsLogged += 1;
|
||||||
|
return message.loggerName + "\t" + message.levelDesc + "\t" +
|
||||||
|
message.message + "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
LogStats.prototype.__proto__ = new Log4Moz.Formatter();
|
||||||
|
|
||||||
|
var log = Log4Moz.repository.rootLogger;
|
||||||
|
var logStats = new LogStats();
|
||||||
|
var appender = new Log4Moz.DumpAppender(logStats);
|
||||||
|
|
||||||
|
if (typeof(level) == "undefined")
|
||||||
|
level = "Debug";
|
||||||
|
getTestLogger().level = Log4Moz.Level[level];
|
||||||
|
|
||||||
|
log.level = Log4Moz.Level.Trace;
|
||||||
|
appender.level = Log4Moz.Level.Trace;
|
||||||
|
// Overwrite any other appenders (e.g. from previous incarnations)
|
||||||
|
log.ownAppenders = [appender];
|
||||||
|
log.updateAppenders();
|
||||||
|
|
||||||
|
return logStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTestLogger(component) {
|
||||||
|
return Log4Moz.repository.getLogger("Testing");
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpd_setup (handlers, port) {
|
||||||
|
let port = port || 8080;
|
||||||
|
let server = new nsHttpServer();
|
||||||
|
for (let path in handlers) {
|
||||||
|
server.registerPathHandler(path, handlers[path]);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
server.start(port);
|
||||||
|
} catch (ex) {
|
||||||
|
_("==========================================");
|
||||||
|
_("Got exception starting HTTP server on port " + port);
|
||||||
|
_("Error: " + Utils.exceptionStr(ex));
|
||||||
|
_("Is there a process already listening on port " + port + "?");
|
||||||
|
_("==========================================");
|
||||||
|
do_throw(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpd_handler(statusCode, status, body) {
|
||||||
|
return function handler(request, response) {
|
||||||
|
_("Processing request");
|
||||||
|
// Allow test functions to inspect the request.
|
||||||
|
request.body = readBytesFromInputStream(request.bodyInputStream);
|
||||||
|
handler.request = request;
|
||||||
|
|
||||||
|
response.setStatusLine(request.httpVersion, statusCode, status);
|
||||||
|
if (body) {
|
||||||
|
response.bodyOutputStream.write(body, body.length);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read bytes string from an nsIInputStream. If 'count' is omitted,
|
||||||
|
* all available input is read.
|
||||||
|
*/
|
||||||
|
function readBytesFromInputStream(inputStream, count) {
|
||||||
|
var BinaryInputStream = Components.Constructor(
|
||||||
|
"@mozilla.org/binaryinputstream;1",
|
||||||
|
"nsIBinaryInputStream",
|
||||||
|
"setInputStream");
|
||||||
|
if (!count) {
|
||||||
|
count = inputStream.available();
|
||||||
|
}
|
||||||
|
return new BinaryInputStream(inputStream).readBytes(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy auth helpers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fake a PAC to prompt a channel replacement.
|
||||||
|
*/
|
||||||
|
let PACSystemSettings = {
|
||||||
|
CID: Components.ID("{5645d2c1-d6d8-4091-b117-fe7ee4027db7}"),
|
||||||
|
contractID: "@mozilla.org/system-proxy-settings;1",
|
||||||
|
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory,
|
||||||
|
Ci.nsISystemProxySettings]),
|
||||||
|
|
||||||
|
createInstance: function createInstance(outer, iid) {
|
||||||
|
if (outer) {
|
||||||
|
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||||
|
}
|
||||||
|
return this.QueryInterface(iid);
|
||||||
|
},
|
||||||
|
|
||||||
|
lockFactory: function lockFactory(lock) {
|
||||||
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Replace this URI for each test to avoid caching. We want to ensure that
|
||||||
|
// each test gets a completely fresh setup.
|
||||||
|
PACURI: null,
|
||||||
|
getProxyForURI: function getProxyForURI(aURI) {
|
||||||
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function installFakePAC() {
|
||||||
|
_("Installing fake PAC.");
|
||||||
|
Cm.nsIComponentRegistrar
|
||||||
|
.registerFactory(PACSystemSettings.CID,
|
||||||
|
"Fake system proxy-settings",
|
||||||
|
PACSystemSettings.contractID,
|
||||||
|
PACSystemSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstallFakePAC() {
|
||||||
|
_("Uninstalling fake PAC.");
|
||||||
|
let CID = PACSystemSettings.CID;
|
||||||
|
Cm.nsIComponentRegistrar.unregisterFactory(CID, PACSystemSettings);
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
Cu.import("resource://services-sync/async.js");
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/async.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
_("Chain a few async methods, making sure the 'this' object is correct.");
|
_("Chain a few async methods, making sure the 'this' object is correct.");
|
@ -1,12 +1,23 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://services-common/async.js");
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
_("Make sure querySpinningly will synchronously fetch rows for a query asyncly");
|
_("Make sure querySpinningly will synchronously fetch rows for a query asyncly");
|
||||||
Cu.import("resource://services-sync/async.js");
|
|
||||||
|
|
||||||
const SQLITE_CONSTRAINT_VIOLATION = 19; // http://www.sqlite.org/c3ref/c_abort.html
|
const SQLITE_CONSTRAINT_VIOLATION = 19; // http://www.sqlite.org/c3ref/c_abort.html
|
||||||
|
|
||||||
|
let Svc = {};
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(Svc, "Form",
|
||||||
|
"@mozilla.org/satchel/form-history;1",
|
||||||
|
"nsIFormHistory2");
|
||||||
|
|
||||||
function querySpinningly(query, names) {
|
function querySpinningly(query, names) {
|
||||||
let q = Svc.Form.DBConnection.createStatement(query);
|
let q = Svc.Form.DBConnection.createStatement(query);
|
||||||
let r = Async.querySpinningly(q, names);
|
let r = Async.querySpinningly(q, names);
|
||||||
q.finalize();
|
q.finalize();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,7 +26,7 @@ function run_test() {
|
|||||||
|
|
||||||
_("Make sure the call is async and allows other events to process");
|
_("Make sure the call is async and allows other events to process");
|
||||||
let isAsync = false;
|
let isAsync = false;
|
||||||
Utils.nextTick(function() { isAsync = true; });
|
CommonUtils.nextTick(function() { isAsync = true; });
|
||||||
do_check_false(isAsync);
|
do_check_false(isAsync);
|
||||||
|
|
||||||
_("Empty out the formhistory table");
|
_("Empty out the formhistory table");
|
19
services/common/tests/unit/test_load_modules.js
Normal file
19
services/common/tests/unit/test_load_modules.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
const modules = [
|
||||||
|
"async.js",
|
||||||
|
"log4moz.js",
|
||||||
|
"preferences.js",
|
||||||
|
"rest.js",
|
||||||
|
"stringbundle.js",
|
||||||
|
"tokenserverclient.js",
|
||||||
|
"utils.js",
|
||||||
|
];
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
for each (let m in modules) {
|
||||||
|
let resource = "resource://services-common/" + m;
|
||||||
|
Components.utils.import(resource, {});
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Components.utils.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
let testFormatter = {
|
let testFormatter = {
|
||||||
format: function format(message) {
|
format: function format(message) {
|
@ -1,8 +1,15 @@
|
|||||||
Components.utils.import("resource://services-sync/ext/Observers.js");
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Components.utils.import("resource://services-common/observers.js");
|
||||||
|
|
||||||
let gSubject = {};
|
let gSubject = {};
|
||||||
|
|
||||||
function test_function_observer() {
|
function run_test() {
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_test(function test_function_observer() {
|
||||||
let foo = false;
|
let foo = false;
|
||||||
|
|
||||||
let onFoo = function(subject, data) {
|
let onFoo = function(subject, data) {
|
||||||
@ -22,9 +29,11 @@ function test_function_observer() {
|
|||||||
|
|
||||||
// The observer was not notified after being removed.
|
// The observer was not notified after being removed.
|
||||||
do_check_true(foo);
|
do_check_true(foo);
|
||||||
}
|
|
||||||
|
|
||||||
function test_method_observer() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_method_observer() {
|
||||||
let obj = {
|
let obj = {
|
||||||
foo: false,
|
foo: false,
|
||||||
onFoo: function(subject, data) {
|
onFoo: function(subject, data) {
|
||||||
@ -43,9 +52,11 @@ function test_method_observer() {
|
|||||||
Observers.remove("foo", obj.onFoo, obj);
|
Observers.remove("foo", obj.onFoo, obj);
|
||||||
Observers.notify("foo");
|
Observers.notify("foo");
|
||||||
do_check_true(obj.foo);
|
do_check_true(obj.foo);
|
||||||
}
|
|
||||||
|
|
||||||
function test_object_observer() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_object_observer() {
|
||||||
let obj = {
|
let obj = {
|
||||||
foo: false,
|
foo: false,
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
@ -68,10 +79,6 @@ function test_object_observer() {
|
|||||||
|
|
||||||
// The observer is not notified after being removed.
|
// The observer is not notified after being removed.
|
||||||
do_check_true(obj.foo);
|
do_check_true(obj.foo);
|
||||||
}
|
|
||||||
|
|
||||||
function run_test() {
|
run_next_test();
|
||||||
test_function_observer();
|
});
|
||||||
test_method_observer();
|
|
||||||
test_object_observer();
|
|
||||||
}
|
|
@ -1,6 +1,13 @@
|
|||||||
Components.utils.import("resource://services-sync/ext/Preferences.js");
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
function test_set_get_pref() {
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_test(function test_set_get_pref() {
|
||||||
Preferences.set("test_set_get_pref.integer", 1);
|
Preferences.set("test_set_get_pref.integer", 1);
|
||||||
do_check_eq(Preferences.get("test_set_get_pref.integer"), 1);
|
do_check_eq(Preferences.get("test_set_get_pref.integer"), 1);
|
||||||
|
|
||||||
@ -12,9 +19,11 @@ function test_set_get_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.resetBranch("test_set_get_pref.");
|
Preferences.resetBranch("test_set_get_pref.");
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_get_branch_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_get_branch_pref() {
|
||||||
let prefs = new Preferences("test_set_get_branch_pref.");
|
let prefs = new Preferences("test_set_get_branch_pref.");
|
||||||
|
|
||||||
prefs.set("something", 1);
|
prefs.set("something", 1);
|
||||||
@ -23,9 +32,11 @@ function test_set_get_branch_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
prefs.reset("something");
|
prefs.reset("something");
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_get_multiple_prefs() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_get_multiple_prefs() {
|
||||||
Preferences.set({ "test_set_get_multiple_prefs.integer": 1,
|
Preferences.set({ "test_set_get_multiple_prefs.integer": 1,
|
||||||
"test_set_get_multiple_prefs.string": "foo",
|
"test_set_get_multiple_prefs.string": "foo",
|
||||||
"test_set_get_multiple_prefs.boolean": true });
|
"test_set_get_multiple_prefs.boolean": true });
|
||||||
@ -40,9 +51,11 @@ function test_set_get_multiple_prefs() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.resetBranch("test_set_get_multiple_prefs.");
|
Preferences.resetBranch("test_set_get_multiple_prefs.");
|
||||||
}
|
|
||||||
|
|
||||||
function test_get_multiple_prefs_with_default_value() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_get_multiple_prefs_with_default_value() {
|
||||||
Preferences.set({ "test_get_multiple_prefs_with_default_value.a": 1,
|
Preferences.set({ "test_get_multiple_prefs_with_default_value.a": 1,
|
||||||
"test_get_multiple_prefs_with_default_value.b": 2 });
|
"test_get_multiple_prefs_with_default_value.b": 2 });
|
||||||
|
|
||||||
@ -57,47 +70,57 @@ function test_get_multiple_prefs_with_default_value() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.resetBranch("test_get_multiple_prefs_with_default_value.");
|
Preferences.resetBranch("test_get_multiple_prefs_with_default_value.");
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_get_unicode_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_get_unicode_pref() {
|
||||||
Preferences.set("test_set_get_unicode_pref", String.fromCharCode(960));
|
Preferences.set("test_set_get_unicode_pref", String.fromCharCode(960));
|
||||||
do_check_eq(Preferences.get("test_set_get_unicode_pref"), String.fromCharCode(960));
|
do_check_eq(Preferences.get("test_set_get_unicode_pref"), String.fromCharCode(960));
|
||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("test_set_get_unicode_pref");
|
Preferences.reset("test_set_get_unicode_pref");
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_null_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_null_pref() {
|
||||||
try {
|
try {
|
||||||
Preferences.set("test_set_null_pref", null);
|
Preferences.set("test_set_null_pref", null);
|
||||||
// We expect this to throw, so the test is designed to fail if it doesn't.
|
// We expect this to throw, so the test is designed to fail if it doesn't.
|
||||||
do_check_true(false);
|
do_check_true(false);
|
||||||
}
|
}
|
||||||
catch(ex) {}
|
catch(ex) {}
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_undefined_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_undefined_pref() {
|
||||||
try {
|
try {
|
||||||
Preferences.set("test_set_undefined_pref");
|
Preferences.set("test_set_undefined_pref");
|
||||||
// We expect this to throw, so the test is designed to fail if it doesn't.
|
// We expect this to throw, so the test is designed to fail if it doesn't.
|
||||||
do_check_true(false);
|
do_check_true(false);
|
||||||
}
|
}
|
||||||
catch(ex) {}
|
catch(ex) {}
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_unsupported_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_unsupported_pref() {
|
||||||
try {
|
try {
|
||||||
Preferences.set("test_set_unsupported_pref", new Array());
|
Preferences.set("test_set_unsupported_pref", new Array());
|
||||||
// We expect this to throw, so the test is designed to fail if it doesn't.
|
// We expect this to throw, so the test is designed to fail if it doesn't.
|
||||||
do_check_true(false);
|
do_check_true(false);
|
||||||
}
|
}
|
||||||
catch(ex) {}
|
catch(ex) {}
|
||||||
}
|
|
||||||
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
// Make sure that we can get a string pref that we didn't set ourselves
|
// Make sure that we can get a string pref that we didn't set ourselves
|
||||||
// (i.e. that the way we get a string pref using getComplexValue doesn't
|
// (i.e. that the way we get a string pref using getComplexValue doesn't
|
||||||
// hork us getting a string pref that wasn't set using setComplexValue).
|
// hork us getting a string pref that wasn't set using setComplexValue).
|
||||||
function test_get_string_pref() {
|
add_test(function test_get_string_pref() {
|
||||||
let svc = Cc["@mozilla.org/preferences-service;1"].
|
let svc = Cc["@mozilla.org/preferences-service;1"].
|
||||||
getService(Ci.nsIPrefService).
|
getService(Ci.nsIPrefService).
|
||||||
getBranch("");
|
getBranch("");
|
||||||
@ -106,9 +129,11 @@ function test_get_string_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("test_get_string_pref");
|
Preferences.reset("test_get_string_pref");
|
||||||
}
|
|
||||||
|
|
||||||
function test_set_get_number_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_get_number_pref() {
|
||||||
Preferences.set("test_set_get_number_pref", 5);
|
Preferences.set("test_set_get_number_pref", 5);
|
||||||
do_check_eq(Preferences.get("test_set_get_number_pref"), 5);
|
do_check_eq(Preferences.get("test_set_get_number_pref"), 5);
|
||||||
|
|
||||||
@ -126,35 +151,45 @@ function test_set_get_number_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("test_set_get_number_pref");
|
Preferences.reset("test_set_get_number_pref");
|
||||||
}
|
|
||||||
|
|
||||||
function test_reset_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_reset_pref() {
|
||||||
Preferences.set("test_reset_pref", 1);
|
Preferences.set("test_reset_pref", 1);
|
||||||
Preferences.reset("test_reset_pref");
|
Preferences.reset("test_reset_pref");
|
||||||
do_check_eq(Preferences.get("test_reset_pref"), undefined);
|
do_check_eq(Preferences.get("test_reset_pref"), undefined);
|
||||||
}
|
|
||||||
|
|
||||||
function test_reset_pref_branch() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_reset_pref_branch() {
|
||||||
Preferences.set("test_reset_pref_branch.foo", 1);
|
Preferences.set("test_reset_pref_branch.foo", 1);
|
||||||
Preferences.set("test_reset_pref_branch.bar", 2);
|
Preferences.set("test_reset_pref_branch.bar", 2);
|
||||||
Preferences.resetBranch("test_reset_pref_branch.");
|
Preferences.resetBranch("test_reset_pref_branch.");
|
||||||
do_check_eq(Preferences.get("test_reset_pref_branch.foo"), undefined);
|
do_check_eq(Preferences.get("test_reset_pref_branch.foo"), undefined);
|
||||||
do_check_eq(Preferences.get("test_reset_pref_branch.bar"), undefined);
|
do_check_eq(Preferences.get("test_reset_pref_branch.bar"), undefined);
|
||||||
}
|
|
||||||
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
// Make sure the module doesn't throw an exception when asked to reset
|
// Make sure the module doesn't throw an exception when asked to reset
|
||||||
// a nonexistent pref.
|
// a nonexistent pref.
|
||||||
function test_reset_nonexistent_pref() {
|
add_test(function test_reset_nonexistent_pref() {
|
||||||
Preferences.reset("test_reset_nonexistent_pref");
|
Preferences.reset("test_reset_nonexistent_pref");
|
||||||
}
|
|
||||||
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
// Make sure the module doesn't throw an exception when asked to reset
|
// Make sure the module doesn't throw an exception when asked to reset
|
||||||
// a nonexistent pref branch.
|
// a nonexistent pref branch.
|
||||||
function test_reset_nonexistent_pref_branch() {
|
add_test(function test_reset_nonexistent_pref_branch() {
|
||||||
Preferences.resetBranch("test_reset_nonexistent_pref_branch.");
|
Preferences.resetBranch("test_reset_nonexistent_pref_branch.");
|
||||||
}
|
|
||||||
|
|
||||||
function test_observe_prefs_function() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_observe_prefs_function() {
|
||||||
let observed = false;
|
let observed = false;
|
||||||
let observer = function() { observed = !observed };
|
let observer = function() { observed = !observed };
|
||||||
|
|
||||||
@ -168,9 +203,11 @@ function test_observe_prefs_function() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("test_observe_prefs_function");
|
Preferences.reset("test_observe_prefs_function");
|
||||||
}
|
|
||||||
|
|
||||||
function test_observe_prefs_object() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_observe_prefs_object() {
|
||||||
let observer = {
|
let observer = {
|
||||||
observed: false,
|
observed: false,
|
||||||
observe: function() {
|
observe: function() {
|
||||||
@ -188,9 +225,11 @@ function test_observe_prefs_object() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("test_observe_prefs_object");
|
Preferences.reset("test_observe_prefs_object");
|
||||||
}
|
|
||||||
|
|
||||||
function test_observe_prefs_nsIObserver() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_observe_prefs_nsIObserver() {
|
||||||
let observer = {
|
let observer = {
|
||||||
observed: false,
|
observed: false,
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
@ -211,9 +250,12 @@ function test_observe_prefs_nsIObserver() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("test_observe_prefs_nsIObserver");
|
Preferences.reset("test_observe_prefs_nsIObserver");
|
||||||
}
|
|
||||||
|
|
||||||
function test_observe_exact_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
add_test(function test_observe_exact_pref() {
|
||||||
let observed = false;
|
let observed = false;
|
||||||
let observer = function() { observed = !observed };
|
let observer = function() { observed = !observed };
|
||||||
|
|
||||||
@ -224,9 +266,12 @@ function test_observe_exact_pref() {
|
|||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.ignore("test_observe_exact_pref", observer);
|
Preferences.ignore("test_observe_exact_pref", observer);
|
||||||
Preferences.reset("test_observe_exact_pref.sub-pref");
|
Preferences.reset("test_observe_exact_pref.sub-pref");
|
||||||
}
|
|
||||||
|
|
||||||
function test_observe_value_of_set_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
add_test(function test_observe_value_of_set_pref() {
|
||||||
let observer = function(newVal) { do_check_eq(newVal, "something") };
|
let observer = function(newVal) { do_check_eq(newVal, "something") };
|
||||||
|
|
||||||
Preferences.observe("test_observe_value_of_set_pref", observer);
|
Preferences.observe("test_observe_value_of_set_pref", observer);
|
||||||
@ -235,9 +280,11 @@ function test_observe_value_of_set_pref() {
|
|||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.ignore("test_observe_value_of_set_pref", observer);
|
Preferences.ignore("test_observe_value_of_set_pref", observer);
|
||||||
Preferences.reset("test_observe_value_of_set_pref");
|
Preferences.reset("test_observe_value_of_set_pref");
|
||||||
}
|
|
||||||
|
|
||||||
function test_observe_value_of_reset_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_observe_value_of_reset_pref() {
|
||||||
let observer = function(newVal) { do_check_true(typeof newVal == "undefined") };
|
let observer = function(newVal) { do_check_true(typeof newVal == "undefined") };
|
||||||
|
|
||||||
Preferences.set("test_observe_value_of_reset_pref", "something");
|
Preferences.set("test_observe_value_of_reset_pref", "something");
|
||||||
@ -246,9 +293,11 @@ function test_observe_value_of_reset_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.ignore("test_observe_value_of_reset_pref", observer);
|
Preferences.ignore("test_observe_value_of_reset_pref", observer);
|
||||||
}
|
|
||||||
|
|
||||||
function test_has_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_has_pref() {
|
||||||
do_check_false(Preferences.has("test_has_pref"));
|
do_check_false(Preferences.has("test_has_pref"));
|
||||||
Preferences.set("test_has_pref", "foo");
|
Preferences.set("test_has_pref", "foo");
|
||||||
do_check_true(Preferences.has("test_has_pref"));
|
do_check_true(Preferences.has("test_has_pref"));
|
||||||
@ -264,9 +313,11 @@ function test_has_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.resetBranch("test_has_pref");
|
Preferences.resetBranch("test_has_pref");
|
||||||
}
|
|
||||||
|
|
||||||
function test_isSet_pref() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_isSet_pref() {
|
||||||
// Use a pref that we know has a default value but no user-set value.
|
// Use a pref that we know has a default value but no user-set value.
|
||||||
// This feels dangerous; perhaps we should create some other default prefs
|
// This feels dangerous; perhaps we should create some other default prefs
|
||||||
// that we can use for testing.
|
// that we can use for testing.
|
||||||
@ -276,9 +327,12 @@ function test_isSet_pref() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("toolkit.defaultChromeURI");
|
Preferences.reset("toolkit.defaultChromeURI");
|
||||||
}
|
|
||||||
|
|
||||||
function test_lock_prefs() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
add_test(function test_lock_prefs() {
|
||||||
// Use a pref that we know has a default value.
|
// Use a pref that we know has a default value.
|
||||||
// This feels dangerous; perhaps we should create some other default prefs
|
// This feels dangerous; perhaps we should create some other default prefs
|
||||||
// that we can use for testing.
|
// that we can use for testing.
|
||||||
@ -298,9 +352,12 @@ function test_lock_prefs() {
|
|||||||
|
|
||||||
// Clean up.
|
// Clean up.
|
||||||
Preferences.reset("toolkit.defaultChromeURI");
|
Preferences.reset("toolkit.defaultChromeURI");
|
||||||
}
|
|
||||||
|
|
||||||
function test_site_prefs() {
|
run_next_test();
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
add_test(function test_site_prefs() {
|
||||||
let prefs = Preferences.site("www.example.com");
|
let prefs = Preferences.site("www.example.com");
|
||||||
|
|
||||||
prefs.set("test_site_prefs.integer", 1);
|
prefs.set("test_site_prefs.integer", 1);
|
||||||
@ -323,32 +380,6 @@ function test_site_prefs() {
|
|||||||
do_check_false(Preferences.has("test_site_prefs.boolean"));
|
do_check_false(Preferences.has("test_site_prefs.boolean"));
|
||||||
prefs.reset("test_site_prefs.boolean");
|
prefs.reset("test_site_prefs.boolean");
|
||||||
do_check_false(prefs.has("test_site_prefs.boolean"));
|
do_check_false(prefs.has("test_site_prefs.boolean"));
|
||||||
}
|
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
function run_test() {
|
});
|
||||||
test_set_get_pref();
|
|
||||||
test_set_get_branch_pref();
|
|
||||||
test_set_get_multiple_prefs();
|
|
||||||
test_get_multiple_prefs_with_default_value();
|
|
||||||
test_set_get_unicode_pref();
|
|
||||||
test_set_null_pref();
|
|
||||||
test_set_undefined_pref();
|
|
||||||
test_set_unsupported_pref();
|
|
||||||
test_get_string_pref();
|
|
||||||
test_set_get_number_pref();
|
|
||||||
test_reset_pref();
|
|
||||||
test_reset_pref_branch();
|
|
||||||
test_reset_nonexistent_pref();
|
|
||||||
test_reset_nonexistent_pref_branch();
|
|
||||||
test_observe_prefs_function();
|
|
||||||
test_observe_prefs_object();
|
|
||||||
test_observe_prefs_nsIObserver();
|
|
||||||
//test_observe_exact_pref();
|
|
||||||
test_observe_value_of_set_pref();
|
|
||||||
test_observe_value_of_reset_pref();
|
|
||||||
test_has_pref();
|
|
||||||
test_isSet_pref();
|
|
||||||
//test_lock_prefs();
|
|
||||||
test_site_prefs();
|
|
||||||
}
|
|
@ -1,14 +1,18 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Cu.import("resource://services-sync/rest.js");
|
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
|
||||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
Cu.import("resource://services-common/rest.js");
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
const TEST_RESOURCE_URL = TEST_SERVER_URL + "resource";
|
const TEST_RESOURCE_URL = TEST_SERVER_URL + "resource";
|
||||||
|
|
||||||
|
//DEBUG = true;
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
Log4Moz.repository.getLogger("Sync.RESTRequest").level = Log4Moz.Level.Trace;
|
Log4Moz.repository.getLogger("Services.Common.RESTRequest").level =
|
||||||
|
Log4Moz.Level.Trace;
|
||||||
initTestLogging();
|
initTestLogging();
|
||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
@ -140,7 +144,7 @@ add_test(function test_get() {
|
|||||||
do_check_eq(handler.request.method, "GET");
|
do_check_eq(handler.request.method, "GET");
|
||||||
|
|
||||||
do_check_true(onProgress_called);
|
do_check_true(onProgress_called);
|
||||||
Utils.nextTick(function () {
|
CommonUtils.nextTick(function () {
|
||||||
do_check_eq(request.onComplete, null);
|
do_check_eq(request.onComplete, null);
|
||||||
do_check_eq(request.onProgress, null);
|
do_check_eq(request.onProgress, null);
|
||||||
server.stop(run_next_test);
|
server.stop(run_next_test);
|
||||||
@ -189,7 +193,7 @@ add_test(function test_put() {
|
|||||||
do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
|
do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
|
||||||
|
|
||||||
do_check_true(onProgress_called);
|
do_check_true(onProgress_called);
|
||||||
Utils.nextTick(function () {
|
CommonUtils.nextTick(function () {
|
||||||
do_check_eq(request.onComplete, null);
|
do_check_eq(request.onComplete, null);
|
||||||
do_check_eq(request.onProgress, null);
|
do_check_eq(request.onProgress, null);
|
||||||
server.stop(run_next_test);
|
server.stop(run_next_test);
|
||||||
@ -238,7 +242,7 @@ add_test(function test_post() {
|
|||||||
do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
|
do_check_eq(handler.request.getHeader("Content-Type"), "text/plain");
|
||||||
|
|
||||||
do_check_true(onProgress_called);
|
do_check_true(onProgress_called);
|
||||||
Utils.nextTick(function () {
|
CommonUtils.nextTick(function () {
|
||||||
do_check_eq(request.onComplete, null);
|
do_check_eq(request.onComplete, null);
|
||||||
do_check_eq(request.onProgress, null);
|
do_check_eq(request.onProgress, null);
|
||||||
server.stop(run_next_test);
|
server.stop(run_next_test);
|
||||||
@ -284,7 +288,7 @@ add_test(function test_delete() {
|
|||||||
do_check_eq(handler.request.method, "DELETE");
|
do_check_eq(handler.request.method, "DELETE");
|
||||||
|
|
||||||
do_check_true(onProgress_called);
|
do_check_true(onProgress_called);
|
||||||
Utils.nextTick(function () {
|
CommonUtils.nextTick(function () {
|
||||||
do_check_eq(request.onComplete, null);
|
do_check_eq(request.onComplete, null);
|
||||||
do_check_eq(request.onProgress, null);
|
do_check_eq(request.onProgress, null);
|
||||||
server.stop(run_next_test);
|
server.stop(run_next_test);
|
||||||
@ -467,7 +471,7 @@ add_test(function test_changing_uri() {
|
|||||||
let server = httpd_setup({"/resource": handler});
|
let server = httpd_setup({"/resource": handler});
|
||||||
|
|
||||||
let request = new RESTRequest("http://localhost:8080/the-wrong-resource");
|
let request = new RESTRequest("http://localhost:8080/the-wrong-resource");
|
||||||
request.uri = Utils.makeURI(TEST_RESOURCE_URL);
|
request.uri = CommonUtils.makeURI(TEST_RESOURCE_URL);
|
||||||
request.get(function (error) {
|
request.get(function (error) {
|
||||||
do_check_eq(error, null);
|
do_check_eq(error, null);
|
||||||
do_check_eq(this.response.status, 200);
|
do_check_eq(this.response.status, 200);
|
||||||
@ -572,7 +576,7 @@ add_test(function test_abort() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
do_check_eq(request.status, request.ABORTED);
|
do_check_eq(request.status, request.ABORTED);
|
||||||
Utils.nextTick(function () {
|
CommonUtils.nextTick(function () {
|
||||||
server.stop(run_next_test);
|
server.stop(run_next_test);
|
||||||
});
|
});
|
||||||
});
|
});
|
166
services/common/tests/unit/test_tokenserverclient.js
Normal file
166
services/common/tests/unit/test_tokenserverclient.js
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/async.js");
|
||||||
|
Cu.import("resource://services-common/tokenserverclient.js");
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
initTestLogging("Trace");
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_test(function test_working_bid_exchange() {
|
||||||
|
_("Ensure that working BrowserID token exchange works as expected.");
|
||||||
|
|
||||||
|
let service = "http://example.com/foo";
|
||||||
|
|
||||||
|
let server = httpd_setup({
|
||||||
|
"/1.0/foo/1.0": function(request, response) {
|
||||||
|
do_check_true(request.hasHeader("accept"));
|
||||||
|
do_check_eq("application/json", request.getHeader("accept"));
|
||||||
|
|
||||||
|
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
let body = JSON.stringify({
|
||||||
|
id: "id",
|
||||||
|
secret: "key",
|
||||||
|
api_endpoint: service,
|
||||||
|
uid: "uid",
|
||||||
|
});
|
||||||
|
response.bodyOutputStream.write(body, body.length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let client = new TokenServerClient();
|
||||||
|
let cb = Async.makeSpinningCallback();
|
||||||
|
let url = TEST_SERVER_URL + "1.0/foo/1.0";
|
||||||
|
client.getTokenFromBrowserIDAssertion(url, "assertion", cb);
|
||||||
|
let result = cb.wait();
|
||||||
|
do_check_eq("object", typeof(result));
|
||||||
|
do_check_attribute_count(result, 4);
|
||||||
|
do_check_eq(service, result.endpoint);
|
||||||
|
do_check_eq("id", result.id);
|
||||||
|
do_check_eq("key", result.key);
|
||||||
|
do_check_eq("uid", result.uid);
|
||||||
|
|
||||||
|
server.stop(run_next_test);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_invalid_arguments() {
|
||||||
|
_("Ensure invalid arguments to APIs are rejected.");
|
||||||
|
|
||||||
|
let args = [
|
||||||
|
[null, "assertion", function() {}],
|
||||||
|
["http://example.com/", null, function() {}],
|
||||||
|
["http://example.com/", "assertion", null]
|
||||||
|
];
|
||||||
|
|
||||||
|
for each (let arg in args) {
|
||||||
|
try {
|
||||||
|
let client = new TokenServerClient();
|
||||||
|
client.getTokenFromBrowserIDAssertion(arg[0], arg[1], arg[2]);
|
||||||
|
do_throw("Should never get here.");
|
||||||
|
} catch (ex) {
|
||||||
|
do_check_true(ex instanceof TokenServerClientError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_error_404() {
|
||||||
|
_("Ensure that 404 responses result in error.");
|
||||||
|
|
||||||
|
let server = httpd_setup();
|
||||||
|
|
||||||
|
let client = new TokenServerClient();
|
||||||
|
let url = TEST_SERVER_URL + "foo";
|
||||||
|
client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
|
||||||
|
do_check_neq(null, error);
|
||||||
|
do_check_eq("TokenServerClientServerError", error.name);
|
||||||
|
do_check_neq(null, error.response);
|
||||||
|
do_check_eq(null, r);
|
||||||
|
|
||||||
|
server.stop(run_next_test);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_bad_json() {
|
||||||
|
_("Ensure that malformed JSON is handled properly.");
|
||||||
|
|
||||||
|
let server = httpd_setup({
|
||||||
|
"/1.0/foo/1.0": function(request, response) {
|
||||||
|
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
let body = '{"id": "id", baz}'
|
||||||
|
response.bodyOutputStream.write(body, body.length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let client = new TokenServerClient();
|
||||||
|
let url = TEST_SERVER_URL + "1.0/foo/1.0";
|
||||||
|
client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
|
||||||
|
_(error);
|
||||||
|
do_check_neq(null, error);
|
||||||
|
do_check_eq("TokenServerClientServerError", error.name);
|
||||||
|
do_check_neq(null, error.response);
|
||||||
|
do_check_eq(null, r);
|
||||||
|
|
||||||
|
server.stop(run_next_test);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_unhandled_media_type() {
|
||||||
|
_("Ensure that unhandled media types throw an error.");
|
||||||
|
|
||||||
|
let server = httpd_setup({
|
||||||
|
"/1.0/foo/1.0": function(request, response) {
|
||||||
|
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||||
|
response.setHeader("Content-Type", "text/plain");
|
||||||
|
|
||||||
|
let body = "hello, world";
|
||||||
|
response.bodyOutputStream.write(body, body.length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let url = TEST_SERVER_URL + "1.0/foo/1.0";
|
||||||
|
let client = new TokenServerClient();
|
||||||
|
client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
|
||||||
|
do_check_neq(null, error);
|
||||||
|
do_check_eq("TokenServerClientError", error.name);
|
||||||
|
do_check_neq(null, error.response);
|
||||||
|
do_check_eq(null, r);
|
||||||
|
|
||||||
|
server.stop(run_next_test);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_rich_media_types() {
|
||||||
|
_("Ensure that extra tokens in the media type aren't rejected.");
|
||||||
|
|
||||||
|
let server = httpd_setup({
|
||||||
|
"/foo": function(request, response) {
|
||||||
|
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||||
|
response.setHeader("Content-Type", "application/json; foo=bar; bar=foo");
|
||||||
|
|
||||||
|
let body = JSON.stringify({
|
||||||
|
id: "id",
|
||||||
|
secret: "key",
|
||||||
|
api_endpoint: "foo",
|
||||||
|
uid: "uid",
|
||||||
|
});
|
||||||
|
response.bodyOutputStream.write(body, body.length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let url = TEST_SERVER_URL + "foo";
|
||||||
|
let client = new TokenServerClient();
|
||||||
|
client.getTokenFromBrowserIDAssertion(url, "assertion", function(error, r) {
|
||||||
|
do_check_eq(null, error);
|
||||||
|
|
||||||
|
server.stop(run_next_test);
|
||||||
|
});
|
||||||
|
});
|
11
services/common/tests/unit/test_utils_atob.js
Normal file
11
services/common/tests/unit/test_utils_atob.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
let data = ["Zm9vYmE=", "Zm9vYmE==", "Zm9vYmE==="];
|
||||||
|
for (let d in data) {
|
||||||
|
do_check_eq(CommonUtils.safeAtoB(data[d]), "fooba");
|
||||||
|
}
|
||||||
|
}
|
66
services/common/tests/unit/test_utils_makeURI.js
Normal file
66
services/common/tests/unit/test_utils_makeURI.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
_("Make sure uri strings are converted to nsIURIs");
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
_test_makeURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _test_makeURI() {
|
||||||
|
_("Check http uris");
|
||||||
|
let uri1 = "http://mozillalabs.com/";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uri1).spec, uri1);
|
||||||
|
let uri2 = "http://www.mozillalabs.com/";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uri2).spec, uri2);
|
||||||
|
let uri3 = "http://mozillalabs.com/path";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uri3).spec, uri3);
|
||||||
|
let uri4 = "http://mozillalabs.com/multi/path";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uri4).spec, uri4);
|
||||||
|
let uri5 = "http://mozillalabs.com/?query";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uri5).spec, uri5);
|
||||||
|
let uri6 = "http://mozillalabs.com/#hash";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uri6).spec, uri6);
|
||||||
|
|
||||||
|
_("Check https uris");
|
||||||
|
let uris1 = "https://mozillalabs.com/";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uris1).spec, uris1);
|
||||||
|
let uris2 = "https://www.mozillalabs.com/";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uris2).spec, uris2);
|
||||||
|
let uris3 = "https://mozillalabs.com/path";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uris3).spec, uris3);
|
||||||
|
let uris4 = "https://mozillalabs.com/multi/path";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uris4).spec, uris4);
|
||||||
|
let uris5 = "https://mozillalabs.com/?query";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uris5).spec, uris5);
|
||||||
|
let uris6 = "https://mozillalabs.com/#hash";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uris6).spec, uris6);
|
||||||
|
|
||||||
|
_("Check chrome uris");
|
||||||
|
let uric1 = "chrome://browser/content/browser.xul";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uric1).spec, uric1);
|
||||||
|
let uric2 = "chrome://browser/skin/browser.css";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uric2).spec, uric2);
|
||||||
|
let uric3 = "chrome://browser/locale/browser.dtd";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uric3).spec, uric3);
|
||||||
|
|
||||||
|
_("Check about uris");
|
||||||
|
let uria1 = "about:weave";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uria1).spec, uria1);
|
||||||
|
let uria2 = "about:weave/";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uria2).spec, uria2);
|
||||||
|
let uria3 = "about:weave/path";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uria3).spec, uria3);
|
||||||
|
let uria4 = "about:weave/multi/path";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uria4).spec, uria4);
|
||||||
|
let uria5 = "about:weave/?query";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uria5).spec, uria5);
|
||||||
|
let uria6 = "about:weave/#hash";
|
||||||
|
do_check_eq(CommonUtils.makeURI(uria6).spec, uria6);
|
||||||
|
|
||||||
|
_("Invalid uris are undefined");
|
||||||
|
do_check_eq(CommonUtils.makeURI("mozillalabs.com"), undefined);
|
||||||
|
do_check_eq(CommonUtils.makeURI("chrome://badstuff"), undefined);
|
||||||
|
do_check_eq(CommonUtils.makeURI("this is a test"), undefined);
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
run_next_test();
|
run_next_test();
|
||||||
@ -9,7 +9,7 @@ function run_test() {
|
|||||||
|
|
||||||
add_test(function test_required_args() {
|
add_test(function test_required_args() {
|
||||||
try {
|
try {
|
||||||
Utils.namedTimer(function callback() {
|
CommonUtils.namedTimer(function callback() {
|
||||||
do_throw("Shouldn't fire.");
|
do_throw("Shouldn't fire.");
|
||||||
}, 0);
|
}, 0);
|
||||||
do_throw("Should have thrown!");
|
do_throw("Should have thrown!");
|
||||||
@ -19,12 +19,12 @@ add_test(function test_required_args() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
add_test(function test_simple() {
|
add_test(function test_simple() {
|
||||||
_("Test basic properties of Utils.namedTimer.");
|
_("Test basic properties of CommonUtils.namedTimer.");
|
||||||
|
|
||||||
const delay = 200;
|
const delay = 200;
|
||||||
let that = {};
|
let that = {};
|
||||||
let t0 = Date.now();
|
let t0 = Date.now();
|
||||||
Utils.namedTimer(function callback(timer) {
|
CommonUtils.namedTimer(function callback(timer) {
|
||||||
do_check_eq(this, that);
|
do_check_eq(this, that);
|
||||||
do_check_eq(this._zetimer, null);
|
do_check_eq(this._zetimer, null);
|
||||||
do_check_true(timer instanceof Ci.nsITimer);
|
do_check_true(timer instanceof Ci.nsITimer);
|
||||||
@ -37,7 +37,7 @@ add_test(function test_simple() {
|
|||||||
|
|
||||||
add_test(function test_delay() {
|
add_test(function test_delay() {
|
||||||
_("Test delaying a timer that hasn't fired yet.");
|
_("Test delaying a timer that hasn't fired yet.");
|
||||||
|
|
||||||
const delay = 100;
|
const delay = 100;
|
||||||
let that = {};
|
let that = {};
|
||||||
let t0 = Date.now();
|
let t0 = Date.now();
|
||||||
@ -47,8 +47,8 @@ add_test(function test_delay() {
|
|||||||
do_check_true((Date.now() - t0) > delay);
|
do_check_true((Date.now() - t0) > delay);
|
||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
Utils.namedTimer(callback, delay, that, "_zetimer");
|
CommonUtils.namedTimer(callback, delay, that, "_zetimer");
|
||||||
Utils.namedTimer(callback, 2 * delay, that, "_zetimer");
|
CommonUtils.namedTimer(callback, 2 * delay, that, "_zetimer");
|
||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,13 +57,13 @@ add_test(function test_clear() {
|
|||||||
|
|
||||||
const delay = 0;
|
const delay = 0;
|
||||||
let that = {};
|
let that = {};
|
||||||
Utils.namedTimer(function callback(timer) {
|
CommonUtils.namedTimer(function callback(timer) {
|
||||||
do_throw("Shouldn't fire!");
|
do_throw("Shouldn't fire!");
|
||||||
}, delay, that, "_zetimer");
|
}, delay, that, "_zetimer");
|
||||||
|
|
||||||
that._zetimer.clear();
|
that._zetimer.clear();
|
||||||
do_check_eq(that._zetimer, null);
|
do_check_eq(that._zetimer, null);
|
||||||
Utils.nextTick(run_next_test);
|
CommonUtils.nextTick(run_next_test);
|
||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
@ -1,10 +1,13 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
_("Define some functions in well defined line positions for the test");
|
_("Define some functions in well defined line positions for the test");
|
||||||
function foo(v) bar(v + 1); // line 2
|
function foo(v) bar(v + 1); // line 2
|
||||||
function bar(v) baz(v + 1); // line 3
|
function bar(v) baz(v + 1); // line 3
|
||||||
function baz(v) { throw new Error(v + 1); } // line 4
|
function baz(v) { throw new Error(v + 1); } // line 4
|
||||||
|
|
||||||
_("Make sure lazy constructor calling/assignment works");
|
_("Make sure lazy constructor calling/assignment works");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
_("Make sure functions, arguments, files are pretty printed in the trace");
|
_("Make sure functions, arguments, files are pretty printed in the trace");
|
||||||
@ -13,14 +16,14 @@ function run_test() {
|
|||||||
foo(0);
|
foo(0);
|
||||||
}
|
}
|
||||||
catch(ex) {
|
catch(ex) {
|
||||||
trace = Utils.stackTrace(ex);
|
trace = CommonUtils.stackTrace(ex);
|
||||||
}
|
}
|
||||||
_("Got trace:", trace);
|
_("Got trace:", trace);
|
||||||
do_check_neq(trace, "");
|
do_check_neq(trace, "");
|
||||||
|
|
||||||
let bazPos = trace.indexOf("baz(2)@test_utils_stackTrace.js:4");
|
let bazPos = trace.indexOf("baz(2)@test_utils_stackTrace.js:7");
|
||||||
let barPos = trace.indexOf("bar(1)@test_utils_stackTrace.js:3");
|
let barPos = trace.indexOf("bar(1)@test_utils_stackTrace.js:6");
|
||||||
let fooPos = trace.indexOf("foo(0)@test_utils_stackTrace.js:2");
|
let fooPos = trace.indexOf("foo(0)@test_utils_stackTrace.js:5");
|
||||||
_("String positions:", bazPos, barPos, fooPos);
|
_("String positions:", bazPos, barPos, fooPos);
|
||||||
|
|
||||||
_("Make sure the desired messages show up");
|
_("Make sure the desired messages show up");
|
11
services/common/tests/unit/test_utils_utf8.js
Normal file
11
services/common/tests/unit/test_utils_utf8.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
let str = "Umlaute: \u00FC \u00E4\n"; // Umlaute: ü ä
|
||||||
|
let encoded = CommonUtils.encodeUTF8(str);
|
||||||
|
let decoded = CommonUtils.decodeUTF8(encoded);
|
||||||
|
do_check_eq(decoded, str);
|
||||||
|
}
|
20
services/common/tests/unit/xpcshell.ini
Normal file
20
services/common/tests/unit/xpcshell.ini
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
head = head_global.js head_helpers.js
|
||||||
|
tail =
|
||||||
|
|
||||||
|
# Test load modules first so syntax failures are caught early.
|
||||||
|
[test_load_modules.js]
|
||||||
|
|
||||||
|
[test_utils_atob.js]
|
||||||
|
[test_utils_makeURI.js]
|
||||||
|
[test_utils_namedTimer.js]
|
||||||
|
[test_utils_stackTrace.js]
|
||||||
|
[test_utils_utf8.js]
|
||||||
|
|
||||||
|
[test_async_chain.js]
|
||||||
|
[test_async_querySpinningly.js]
|
||||||
|
[test_log4moz.js]
|
||||||
|
[test_observers.js]
|
||||||
|
[test_preferences.js]
|
||||||
|
[test_restrequest.js]
|
||||||
|
[test_tokenserverclient.js]
|
238
services/common/tokenserverclient.js
Normal file
238
services/common/tokenserverclient.js
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const EXPORTED_SYMBOLS = [
|
||||||
|
"TokenServerClient",
|
||||||
|
"TokenServerClientError",
|
||||||
|
"TokenServerClientNetworkError",
|
||||||
|
"TokenServerClientServerError"
|
||||||
|
];
|
||||||
|
|
||||||
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
Cu.import("resource://services-common/rest.js");
|
||||||
|
|
||||||
|
const Prefs = new Preferences("services.common.tokenserverclient.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a TokenServerClient error that occurred on the client.
|
||||||
|
*
|
||||||
|
* This is the base type for all errors raised by client operations.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* (string) Error message.
|
||||||
|
*/
|
||||||
|
function TokenServerClientError(message) {
|
||||||
|
this.name = "TokenServerClientError";
|
||||||
|
this.message = message || "Client error.";
|
||||||
|
}
|
||||||
|
TokenServerClientError.prototype = new Error();
|
||||||
|
TokenServerClientError.prototype.constructor = TokenServerClientError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a TokenServerClient error that occurred in the network layer.
|
||||||
|
*
|
||||||
|
* @param error
|
||||||
|
* The underlying error thrown by the network layer.
|
||||||
|
*/
|
||||||
|
function TokenServerClientNetworkError(error) {
|
||||||
|
this.name = "TokenServerClientNetworkError";
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
TokenServerClientNetworkError.prototype = new TokenServerClientError();
|
||||||
|
TokenServerClientNetworkError.prototype.constructor =
|
||||||
|
TokenServerClientNetworkError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a TokenServerClient error that occurred on the server.
|
||||||
|
*
|
||||||
|
* This type will be encountered for all non-200 response codes from the
|
||||||
|
* server.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* (string) Error message.
|
||||||
|
*/
|
||||||
|
function TokenServerClientServerError(message) {
|
||||||
|
this.name = "TokenServerClientServerError";
|
||||||
|
this.message = message || "Server error.";
|
||||||
|
}
|
||||||
|
TokenServerClientServerError.prototype = new TokenServerClientError();
|
||||||
|
TokenServerClientServerError.prototype.constructor =
|
||||||
|
TokenServerClientServerError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a client to the Token Server.
|
||||||
|
*
|
||||||
|
* http://docs.services.mozilla.com/token/index.html
|
||||||
|
*
|
||||||
|
* The Token Server supports obtaining tokens for arbitrary apps by
|
||||||
|
* constructing URI paths of the form <app>/<app_version>. However, the service
|
||||||
|
* discovery mechanism emphasizes the use of full URIs and tries to not force
|
||||||
|
* the client to manipulate URIs. This client currently enforces this practice
|
||||||
|
* by not implementing an API which would perform URI manipulation.
|
||||||
|
*
|
||||||
|
* If you are tempted to implement this API in the future, consider this your
|
||||||
|
* warning that you may be doing it wrong and that you should store full URIs
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* Areas to Improve:
|
||||||
|
*
|
||||||
|
* - The server sends a JSON response on error. The client does not currently
|
||||||
|
* parse this. It might be convenient if it did.
|
||||||
|
* - Currently all non-200 status codes are rolled into one error type. It
|
||||||
|
* might be helpful if callers had a richer API that communicated who was
|
||||||
|
* at fault (e.g. differentiating a 503 from a 401).
|
||||||
|
*/
|
||||||
|
function TokenServerClient() {
|
||||||
|
this._log = Log4Moz.repository.getLogger("Common.TokenServerClient");
|
||||||
|
this._log.level = Log4Moz.Level[Prefs.get("logger.level")];
|
||||||
|
}
|
||||||
|
TokenServerClient.prototype = {
|
||||||
|
/**
|
||||||
|
* Logger instance.
|
||||||
|
*/
|
||||||
|
_log: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a token from a BrowserID assertion against a specific URL.
|
||||||
|
*
|
||||||
|
* This asynchronously obtains the token. The callback receives 2 arguments.
|
||||||
|
* The first signifies an error and is a TokenServerClientError (or derived)
|
||||||
|
* type when an error occurs. If an HTTP response was seen, a RESTResponse
|
||||||
|
* instance will be stored in the "response" property of this object.
|
||||||
|
*
|
||||||
|
* The second argument to the callback is a map containing the results from
|
||||||
|
* the server. This map has the following keys:
|
||||||
|
*
|
||||||
|
* id (string) HTTP MAC public key identifier.
|
||||||
|
* key (string) HTTP MAC shared symmetric key.
|
||||||
|
* endpoint (string) URL where service can be connected to.
|
||||||
|
* uid (string) user ID for requested service.
|
||||||
|
*
|
||||||
|
* e.g.
|
||||||
|
*
|
||||||
|
* let client = new TokenServerClient();
|
||||||
|
* let assertion = getBrowserIDAssertionFromSomewhere();
|
||||||
|
* let url = "https://token.services.mozilla.com/1.0/sync/2.0";
|
||||||
|
*
|
||||||
|
* client.getTokenFromBrowserIDAssertion(url, assertion,
|
||||||
|
* function(error, result) {
|
||||||
|
* if (error) {
|
||||||
|
* // Do error handling.
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* let {id: id, key: key, uid: uid, endpoint: endpoint} = result;
|
||||||
|
* // Do stuff with data and carry on.
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* (string) URL to fetch token from.
|
||||||
|
* @param assertion
|
||||||
|
* (string) BrowserID assertion to exchange token for.
|
||||||
|
* @param cb
|
||||||
|
* (function) Callback to be invoked with result of operation.
|
||||||
|
*/
|
||||||
|
getTokenFromBrowserIDAssertion:
|
||||||
|
function getTokenFromBrowserIDAssertion(url, assertion, cb) {
|
||||||
|
if (!url) {
|
||||||
|
throw new TokenServerClientError("url argument is not valid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assertion) {
|
||||||
|
throw new TokenServerClientError("assertion argument is not valid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cb) {
|
||||||
|
throw new TokenServerClientError("cb argument is not valid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._log.debug("Beginning BID assertion exchange: " + url);
|
||||||
|
|
||||||
|
let req = new RESTRequest(url);
|
||||||
|
req.setHeader("accept", "application/json");
|
||||||
|
req.setHeader("authorization", "Browser-ID " + assertion);
|
||||||
|
let client = this;
|
||||||
|
req.get(function onResponse(error) {
|
||||||
|
if (error) {
|
||||||
|
cb(new TokenServerClientNetworkError(error), null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
client._processTokenResponse(this.response, cb);
|
||||||
|
} catch (ex) {
|
||||||
|
let error = new TokenServerClientError(ex);
|
||||||
|
error.response = this.response;
|
||||||
|
cb(error, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to process token request responses.
|
||||||
|
*
|
||||||
|
* @param response
|
||||||
|
* RESTResponse from token HTTP request.
|
||||||
|
* @param cb
|
||||||
|
* The original callback passed to the public API.
|
||||||
|
*/
|
||||||
|
_processTokenResponse: function processTokenResponse(response, cb) {
|
||||||
|
this._log.debug("Got token response.");
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
this._log.info("Non-200 response code to token request: " +
|
||||||
|
response.status);
|
||||||
|
this._log.debug("Response body: " + response.body);
|
||||||
|
let error = new TokenServerClientServerError("Non 200 response code: " +
|
||||||
|
response.status);
|
||||||
|
error.response = response;
|
||||||
|
cb(error, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ct = response.headers["content-type"];
|
||||||
|
if (ct != "application/json" && ct.indexOf("application/json;") != 0) {
|
||||||
|
let error = new TokenServerClientError("Unsupported media type: " + ct);
|
||||||
|
error.response = response;
|
||||||
|
cb(error, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = JSON.parse(response.body);
|
||||||
|
} catch (ex) {
|
||||||
|
let error = new TokenServerClientServerError("Invalid JSON returned " +
|
||||||
|
"from server.");
|
||||||
|
error.response = response;
|
||||||
|
cb(error, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for each (let k in ["id", "secret", "api_endpoint", "uid"]) {
|
||||||
|
if (!(k in result)) {
|
||||||
|
let error = new TokenServerClientServerError("Expected key not " +
|
||||||
|
" present in result: " +
|
||||||
|
k);
|
||||||
|
error.response = response;
|
||||||
|
cb(error, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._log.debug("Successful token response: " + result.id);
|
||||||
|
cb(null, {
|
||||||
|
id: result.id,
|
||||||
|
key: result.secret,
|
||||||
|
endpoint: result.api_endpoint,
|
||||||
|
uid: result.uid,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
161
services/common/utils.js
Normal file
161
services/common/utils.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
|
const EXPORTED_SYMBOLS = ["CommonUtils"];
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
|
let CommonUtils = {
|
||||||
|
exceptionStr: function exceptionStr(e) {
|
||||||
|
let message = e.message ? e.message : e;
|
||||||
|
return message + " " + CommonUtils.stackTrace(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
stackTrace: function stackTrace(e) {
|
||||||
|
// Wrapped nsIException
|
||||||
|
if (e.location) {
|
||||||
|
let frame = e.location;
|
||||||
|
let output = [];
|
||||||
|
while (frame) {
|
||||||
|
// Works on frames or exceptions, munges file:// URIs to shorten the paths
|
||||||
|
// FIXME: filename munging is sort of hackish, might be confusing if
|
||||||
|
// there are multiple extensions with similar filenames
|
||||||
|
let str = "<file:unknown>";
|
||||||
|
|
||||||
|
let file = frame.filename || frame.fileName;
|
||||||
|
if (file){
|
||||||
|
str = file.replace(/^(?:chrome|file):.*?([^\/\.]+\.\w+)$/, "$1");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.lineNumber){
|
||||||
|
str += ":" + frame.lineNumber;
|
||||||
|
}
|
||||||
|
if (frame.name){
|
||||||
|
str = frame.name + "()@" + str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str){
|
||||||
|
output.push(str);
|
||||||
|
}
|
||||||
|
frame = frame.caller;
|
||||||
|
}
|
||||||
|
return "Stack trace: " + output.join(" < ");
|
||||||
|
}
|
||||||
|
// Standard JS exception
|
||||||
|
if (e.stack){
|
||||||
|
return "JS Stack trace: " + e.stack.trim().replace(/\n/g, " < ").
|
||||||
|
replace(/@[^@]*?([^\/\.]+\.\w+:)/g, "@$1");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "No traceback available";
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a nsIURI instance from a string.
|
||||||
|
*/
|
||||||
|
makeURI: function makeURI(URIString) {
|
||||||
|
if (!URIString)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
return Services.io.newURI(URIString, null, null);
|
||||||
|
} catch (e) {
|
||||||
|
let log = Log4Moz.repository.getLogger("Common.Utils");
|
||||||
|
log.debug("Could not create URI: " + CommonUtils.exceptionStr(e));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a function on the next event loop tick.
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* Function to invoke.
|
||||||
|
* @param thisObj [optional]
|
||||||
|
* Object to bind the callback to.
|
||||||
|
*/
|
||||||
|
nextTick: function nextTick(callback, thisObj) {
|
||||||
|
if (thisObj) {
|
||||||
|
callback = callback.bind(thisObj);
|
||||||
|
}
|
||||||
|
Services.tm.currentThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a timer that is scheduled to call the callback after waiting the
|
||||||
|
* provided time or as soon as possible. The timer will be set as a property
|
||||||
|
* of the provided object with the given timer name.
|
||||||
|
*/
|
||||||
|
namedTimer: function namedTimer(callback, wait, thisObj, name) {
|
||||||
|
if (!thisObj || !name) {
|
||||||
|
throw "You must provide both an object and a property name for the timer!";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay an existing timer if it exists
|
||||||
|
if (name in thisObj && thisObj[name] instanceof Ci.nsITimer) {
|
||||||
|
thisObj[name].delay = wait;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a special timer that we can add extra properties
|
||||||
|
let timer = {};
|
||||||
|
timer.__proto__ = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||||
|
|
||||||
|
// Provide an easy way to clear out the timer
|
||||||
|
timer.clear = function() {
|
||||||
|
thisObj[name] = null;
|
||||||
|
timer.cancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize the timer with a smart callback
|
||||||
|
timer.initWithCallback({
|
||||||
|
notify: function notify() {
|
||||||
|
// Clear out the timer once it's been triggered
|
||||||
|
timer.clear();
|
||||||
|
callback.call(thisObj, timer);
|
||||||
|
}
|
||||||
|
}, wait, timer.TYPE_ONE_SHOT);
|
||||||
|
|
||||||
|
return thisObj[name] = timer;
|
||||||
|
},
|
||||||
|
|
||||||
|
encodeUTF8: function encodeUTF8(str) {
|
||||||
|
try {
|
||||||
|
str = this._utf8Converter.ConvertFromUnicode(str);
|
||||||
|
return str + this._utf8Converter.Finish();
|
||||||
|
} catch (ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
decodeUTF8: function decodeUTF8(str) {
|
||||||
|
try {
|
||||||
|
str = this._utf8Converter.ConvertToUnicode(str);
|
||||||
|
return str + this._utf8Converter.Finish();
|
||||||
|
} catch (ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trim excess padding from a Base64 string and atob().
|
||||||
|
*
|
||||||
|
* See bug 562431 comment 4.
|
||||||
|
*/
|
||||||
|
safeAtoB: function safeAtoB(b64) {
|
||||||
|
let len = b64.length;
|
||||||
|
let over = len % 4;
|
||||||
|
return over ? atob(b64.substr(0, len - over)) : atob(b64);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(CommonUtils, "_utf8Converter", function() {
|
||||||
|
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||||
|
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||||
|
converter.charset = "UTF-8";
|
||||||
|
return converter;
|
||||||
|
});
|
@ -35,24 +35,18 @@
|
|||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
MAKEFILES_crypto="
|
add_makefiles "
|
||||||
|
services/Makefile
|
||||||
|
services/common/Makefile
|
||||||
services/crypto/Makefile
|
services/crypto/Makefile
|
||||||
services/crypto/component/Makefile
|
services/crypto/component/Makefile
|
||||||
"
|
|
||||||
|
|
||||||
MAKEFILES_sync="
|
|
||||||
services/sync/Makefile
|
services/sync/Makefile
|
||||||
services/sync/locales/Makefile
|
services/sync/locales/Makefile
|
||||||
"
|
"
|
||||||
|
|
||||||
add_makefiles "
|
|
||||||
services/Makefile
|
|
||||||
$MAKEFILES_crypto
|
|
||||||
$MAKEFILES_sync
|
|
||||||
"
|
|
||||||
|
|
||||||
if [ "$ENABLE_TESTS" ]; then
|
if [ "$ENABLE_TESTS" ]; then
|
||||||
add_makefiles "
|
add_makefiles "
|
||||||
|
services/common/tests/Makefile
|
||||||
services/crypto/tests/Makefile
|
services/crypto/tests/Makefile
|
||||||
services/sync/tests/Makefile
|
services/sync/tests/Makefile
|
||||||
"
|
"
|
||||||
|
@ -6,4 +6,5 @@ component {d28f8a0b-95da-48f4-b712-caf37097be41} Weave.js
|
|||||||
contract @mozilla.org/network/protocol/about;1?what=sync-log {d28f8a0b-95da-48f4-b712-caf37097be41}
|
contract @mozilla.org/network/protocol/about;1?what=sync-log {d28f8a0b-95da-48f4-b712-caf37097be41}
|
||||||
# Register resource aliases
|
# Register resource aliases
|
||||||
resource services-sync resource:///modules/services-sync/
|
resource services-sync resource:///modules/services-sync/
|
||||||
|
resource services-common resource:///modules/services-common/
|
||||||
resource services-crypto resource:///modules/services-crypto/
|
resource services-crypto resource:///modules/services-crypto/
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||||
|
@ -46,12 +46,12 @@ const Ci = Components.interfaces;
|
|||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
@ -72,8 +72,8 @@ Cu.import("resource://services-sync/engines.js");
|
|||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||||
Cu.import("resource://gre/modules/AddonRepository.jsm");
|
Cu.import("resource://gre/modules/AddonRepository.jsm");
|
||||||
|
@ -51,7 +51,7 @@ Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
|||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
|
|
||||||
|
@ -42,9 +42,9 @@ const Cc = Components.classes;
|
|||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/stringbundle.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/ext/StringBundle.js");
|
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
@ -43,10 +43,10 @@ const Cu = Components.utils;
|
|||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
const FORMS_TTL = 5184000; // 60 days
|
const FORMS_TTL = 5184000; // 60 days
|
||||||
|
|
||||||
|
@ -51,9 +51,9 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
function HistoryRec(collection, id) {
|
function HistoryRec(collection, id) {
|
||||||
CryptoWrapper.call(this, collection, id);
|
CryptoWrapper.call(this, collection, id);
|
||||||
|
@ -47,7 +47,7 @@ Cu.import("resource://services-sync/engines.js");
|
|||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
|
Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
|
||||||
|
|
||||||
const PREFS_GUID = Utils.encodeBase64url(Services.appinfo.ID);
|
const PREFS_GUID = Utils.encodeBase64url(Services.appinfo.ID);
|
||||||
|
@ -51,7 +51,7 @@ Cu.import("resource://services-sync/record.js");
|
|||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
|
||||||
// It is safer to inspect the private browsing preferences rather than
|
// It is safer to inspect the private browsing preferences rather than
|
||||||
// the flags of nsIPrivateBrowsingService. The user may have turned on
|
// the flags of nsIPrivateBrowsingService. The user may have turned on
|
||||||
|
@ -10,7 +10,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|||||||
|
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/keys.js");
|
Cu.import("resource://services-sync/keys.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "Identity", function() {
|
XPCOMUtils.defineLazyGetter(this, "Identity", function() {
|
||||||
|
@ -40,8 +40,8 @@ const Ci = Components.interfaces;
|
|||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/rest.js");
|
Cu.import("resource://services-common/rest.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ const EXPORTED_SYMBOLS = [
|
|||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,8 +41,8 @@ const Ci = Components.interfaces;
|
|||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
let Notifications = {
|
let Notifications = {
|
||||||
|
@ -45,7 +45,7 @@ const EXPORTED_SYMBOLS = ["SyncScheduler",
|
|||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/clients.js");
|
Cu.import("resource://services-sync/engines/clients.js");
|
||||||
|
@ -51,7 +51,7 @@ const KEYS_WBO = "keys";
|
|||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/keys.js");
|
Cu.import("resource://services-sync/keys.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
@ -47,12 +47,12 @@ const Ci = Components.interfaces;
|
|||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -40,581 +40,16 @@
|
|||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
Cu.import("resource://services-common/rest.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
|
|
||||||
const EXPORTED_SYMBOLS = ["RESTRequest", "SyncStorageRequest"];
|
const EXPORTED_SYMBOLS = ["SyncStorageRequest"];
|
||||||
|
|
||||||
const STORAGE_REQUEST_TIMEOUT = 5 * 60; // 5 minutes
|
const STORAGE_REQUEST_TIMEOUT = 5 * 60; // 5 minutes
|
||||||
|
|
||||||
/**
|
|
||||||
* Single use HTTP requests to RESTish resources.
|
|
||||||
*
|
|
||||||
* @param uri
|
|
||||||
* URI for the request. This can be an nsIURI object or a string
|
|
||||||
* that can be used to create one. An exception will be thrown if
|
|
||||||
* the string is not a valid URI.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* (1) Quick GET request:
|
|
||||||
*
|
|
||||||
* new RESTRequest("http://server/rest/resource").get(function (error) {
|
|
||||||
* if (error) {
|
|
||||||
* // Deal with a network error.
|
|
||||||
* processNetworkErrorCode(error.result);
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
* if (!this.response.success) {
|
|
||||||
|
|
||||||
* * // Bail out if we're not getting an HTTP 2xx code.
|
|
||||||
* processHTTPError(this.response.status);
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
* processData(this.response.body);
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* (2) Quick PUT request (non-string data is automatically JSONified)
|
|
||||||
*
|
|
||||||
* new RESTRequest("http://server/rest/resource").put(data, function (error) {
|
|
||||||
* ...
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* (3) Streaming GET
|
|
||||||
*
|
|
||||||
* let request = new RESTRequest("http://server/rest/resource");
|
|
||||||
* request.setHeader("Accept", "application/newlines");
|
|
||||||
* request.onComplete = function (error) {
|
|
||||||
* if (error) {
|
|
||||||
* // Deal with a network error.
|
|
||||||
* processNetworkErrorCode(error.result);
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
* callbackAfterRequestHasCompleted()
|
|
||||||
* });
|
|
||||||
* request.onProgress = function () {
|
|
||||||
* if (!this.response.success) {
|
|
||||||
* // Bail out if we're not getting an HTTP 2xx code.
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
* // Process body data and reset it so we don't process the same data twice.
|
|
||||||
* processIncrementalData(this.response.body);
|
|
||||||
* this.response.body = "";
|
|
||||||
* });
|
|
||||||
* request.get();
|
|
||||||
*/
|
|
||||||
function RESTRequest(uri) {
|
|
||||||
this.status = this.NOT_SENT;
|
|
||||||
|
|
||||||
// If we don't have an nsIURI object yet, make one. This will throw if
|
|
||||||
// 'uri' isn't a valid URI string.
|
|
||||||
if (!(uri instanceof Ci.nsIURI)) {
|
|
||||||
uri = Services.io.newURI(uri, null, null);
|
|
||||||
}
|
|
||||||
this.uri = uri;
|
|
||||||
|
|
||||||
this._headers = {};
|
|
||||||
this._log = Log4Moz.repository.getLogger(this._logName);
|
|
||||||
this._log.level =
|
|
||||||
Log4Moz.Level[Svc.Prefs.get("log.logger.network.resources")];
|
|
||||||
}
|
|
||||||
RESTRequest.prototype = {
|
|
||||||
|
|
||||||
_logName: "Sync.RESTRequest",
|
|
||||||
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([
|
|
||||||
Ci.nsIBadCertListener2,
|
|
||||||
Ci.nsIInterfaceRequestor,
|
|
||||||
Ci.nsIChannelEventSink
|
|
||||||
]),
|
|
||||||
|
|
||||||
/*** Public API: ***/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URI for the request (an nsIURI object).
|
|
||||||
*/
|
|
||||||
uri: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP method (e.g. "GET")
|
|
||||||
*/
|
|
||||||
method: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RESTResponse object
|
|
||||||
*/
|
|
||||||
response: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIRequest load flags. Don't do any caching by default.
|
|
||||||
*/
|
|
||||||
loadFlags: Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIHttpChannel
|
|
||||||
*/
|
|
||||||
channel: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag to indicate the status of the request.
|
|
||||||
*
|
|
||||||
* One of NOT_SENT, SENT, IN_PROGRESS, COMPLETED, ABORTED.
|
|
||||||
*/
|
|
||||||
status: null,
|
|
||||||
|
|
||||||
NOT_SENT: 0,
|
|
||||||
SENT: 1,
|
|
||||||
IN_PROGRESS: 2,
|
|
||||||
COMPLETED: 4,
|
|
||||||
ABORTED: 8,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request timeout (in seconds, though decimal values can be used for
|
|
||||||
* up to millisecond granularity.)
|
|
||||||
*
|
|
||||||
* 0 for no timeout.
|
|
||||||
*/
|
|
||||||
timeout: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the request has been completed, including failures and
|
|
||||||
* timeouts.
|
|
||||||
*
|
|
||||||
* @param error
|
|
||||||
* Error that occurred while making the request, null if there
|
|
||||||
* was no error.
|
|
||||||
*/
|
|
||||||
onComplete: function onComplete(error) {
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called whenever data is being received on the channel. If this throws an
|
|
||||||
* exception, the request is aborted and the exception is passed as the
|
|
||||||
* error to onComplete().
|
|
||||||
*/
|
|
||||||
onProgress: function onProgress() {
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a request header.
|
|
||||||
*/
|
|
||||||
setHeader: function setHeader(name, value) {
|
|
||||||
this._headers[name.toLowerCase()] = value;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an HTTP GET.
|
|
||||||
*
|
|
||||||
* @param onComplete
|
|
||||||
* Short-circuit way to set the 'onComplete' method. Optional.
|
|
||||||
* @param onProgress
|
|
||||||
* Short-circuit way to set the 'onProgress' method. Optional.
|
|
||||||
*
|
|
||||||
* @return the request object.
|
|
||||||
*/
|
|
||||||
get: function get(onComplete, onProgress) {
|
|
||||||
return this.dispatch("GET", null, onComplete, onProgress);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an HTTP PUT.
|
|
||||||
*
|
|
||||||
* @param data
|
|
||||||
* Data to be used as the request body. If this isn't a string
|
|
||||||
* it will be JSONified automatically.
|
|
||||||
* @param onComplete
|
|
||||||
* Short-circuit way to set the 'onComplete' method. Optional.
|
|
||||||
* @param onProgress
|
|
||||||
* Short-circuit way to set the 'onProgress' method. Optional.
|
|
||||||
*
|
|
||||||
* @return the request object.
|
|
||||||
*/
|
|
||||||
put: function put(data, onComplete, onProgress) {
|
|
||||||
return this.dispatch("PUT", data, onComplete, onProgress);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an HTTP POST.
|
|
||||||
*
|
|
||||||
* @param data
|
|
||||||
* Data to be used as the request body. If this isn't a string
|
|
||||||
* it will be JSONified automatically.
|
|
||||||
* @param onComplete
|
|
||||||
* Short-circuit way to set the 'onComplete' method. Optional.
|
|
||||||
* @param onProgress
|
|
||||||
* Short-circuit way to set the 'onProgress' method. Optional.
|
|
||||||
*
|
|
||||||
* @return the request object.
|
|
||||||
*/
|
|
||||||
post: function post(data, onComplete, onProgress) {
|
|
||||||
return this.dispatch("POST", data, onComplete, onProgress);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an HTTP DELETE.
|
|
||||||
*
|
|
||||||
* @param onComplete
|
|
||||||
* Short-circuit way to set the 'onComplete' method. Optional.
|
|
||||||
* @param onProgress
|
|
||||||
* Short-circuit way to set the 'onProgress' method. Optional.
|
|
||||||
*
|
|
||||||
* @return the request object.
|
|
||||||
*/
|
|
||||||
delete: function delete_(onComplete, onProgress) {
|
|
||||||
return this.dispatch("DELETE", null, onComplete, onProgress);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abort an active request.
|
|
||||||
*/
|
|
||||||
abort: function abort() {
|
|
||||||
if (this.status != this.SENT && this.status != this.IN_PROGRESS) {
|
|
||||||
throw "Can only abort a request that has been sent.";
|
|
||||||
}
|
|
||||||
|
|
||||||
this.status = this.ABORTED;
|
|
||||||
this.channel.cancel(Cr.NS_BINDING_ABORTED);
|
|
||||||
|
|
||||||
if (this.timeoutTimer) {
|
|
||||||
// Clear the abort timer now that the channel is done.
|
|
||||||
this.timeoutTimer.clear();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*** Implementation stuff ***/
|
|
||||||
|
|
||||||
dispatch: function dispatch(method, data, onComplete, onProgress) {
|
|
||||||
if (this.status != this.NOT_SENT) {
|
|
||||||
throw "Request has already been sent!";
|
|
||||||
}
|
|
||||||
|
|
||||||
this.method = method;
|
|
||||||
if (onComplete) {
|
|
||||||
this.onComplete = onComplete;
|
|
||||||
}
|
|
||||||
if (onProgress) {
|
|
||||||
this.onProgress = onProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and initialize HTTP channel.
|
|
||||||
let channel = Services.io.newChannelFromURI(this.uri, null, null)
|
|
||||||
.QueryInterface(Ci.nsIRequest)
|
|
||||||
.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
this.channel = channel;
|
|
||||||
channel.loadFlags |= this.loadFlags;
|
|
||||||
channel.notificationCallbacks = this;
|
|
||||||
|
|
||||||
// Set request headers.
|
|
||||||
let headers = this._headers;
|
|
||||||
for (let key in headers) {
|
|
||||||
if (key == 'authorization') {
|
|
||||||
this._log.trace("HTTP Header " + key + ": ***** (suppressed)");
|
|
||||||
} else {
|
|
||||||
this._log.trace("HTTP Header " + key + ": " + headers[key]);
|
|
||||||
}
|
|
||||||
channel.setRequestHeader(key, headers[key], false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set HTTP request body.
|
|
||||||
if (method == "PUT" || method == "POST") {
|
|
||||||
// Convert non-string bodies into JSON.
|
|
||||||
if (typeof data != "string") {
|
|
||||||
data = JSON.stringify(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._log.debug(method + " Length: " + data.length);
|
|
||||||
if (this._log.level <= Log4Moz.Level.Trace) {
|
|
||||||
this._log.trace(method + " Body: " + data);
|
|
||||||
}
|
|
||||||
|
|
||||||
let stream = Cc["@mozilla.org/io/string-input-stream;1"]
|
|
||||||
.createInstance(Ci.nsIStringInputStream);
|
|
||||||
stream.setData(data, data.length);
|
|
||||||
|
|
||||||
let type = headers["content-type"] || "text/plain";
|
|
||||||
channel.QueryInterface(Ci.nsIUploadChannel);
|
|
||||||
channel.setUploadStream(stream, type, data.length);
|
|
||||||
}
|
|
||||||
// We must set this after setting the upload stream, otherwise it
|
|
||||||
// will always be 'PUT'. Yeah, I know.
|
|
||||||
channel.requestMethod = method;
|
|
||||||
|
|
||||||
// Blast off!
|
|
||||||
channel.asyncOpen(this, null);
|
|
||||||
this.status = this.SENT;
|
|
||||||
this.delayTimeout();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create or push back the abort timer that kills this request.
|
|
||||||
*/
|
|
||||||
delayTimeout: function delayTimeout() {
|
|
||||||
if (this.timeout) {
|
|
||||||
Utils.namedTimer(this.abortTimeout, this.timeout * 1000, this,
|
|
||||||
"timeoutTimer");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abort the request based on a timeout.
|
|
||||||
*/
|
|
||||||
abortTimeout: function abortTimeout() {
|
|
||||||
this.abort();
|
|
||||||
let error = Components.Exception("Aborting due to channel inactivity.",
|
|
||||||
Cr.NS_ERROR_NET_TIMEOUT);
|
|
||||||
if (!this.onComplete) {
|
|
||||||
this._log.error("Unexpected error: onComplete not defined in " +
|
|
||||||
"abortTimeout.")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.onComplete(error);
|
|
||||||
},
|
|
||||||
|
|
||||||
/*** nsIStreamListener ***/
|
|
||||||
|
|
||||||
onStartRequest: function onStartRequest(channel) {
|
|
||||||
if (this.status == this.ABORTED) {
|
|
||||||
this._log.trace("Not proceeding with onStartRequest, request was aborted.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.error("Unexpected error: channel is not a nsIHttpChannel!");
|
|
||||||
this.status = this.ABORTED;
|
|
||||||
channel.cancel(Cr.NS_BINDING_ABORTED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.status = this.IN_PROGRESS;
|
|
||||||
|
|
||||||
this._log.trace("onStartRequest: " + channel.requestMethod + " " +
|
|
||||||
channel.URI.spec);
|
|
||||||
|
|
||||||
// Create a response object and fill it with some data.
|
|
||||||
let response = this.response = new RESTResponse();
|
|
||||||
response.request = this;
|
|
||||||
response.body = "";
|
|
||||||
|
|
||||||
// Define this here so that we don't have make a new one each time
|
|
||||||
// onDataAvailable() gets called.
|
|
||||||
this._inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
|
|
||||||
.createInstance(Ci.nsIScriptableInputStream);
|
|
||||||
|
|
||||||
this.delayTimeout();
|
|
||||||
},
|
|
||||||
|
|
||||||
onStopRequest: function onStopRequest(channel, context, statusCode) {
|
|
||||||
if (this.timeoutTimer) {
|
|
||||||
// Clear the abort timer now that the channel is done.
|
|
||||||
this.timeoutTimer.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't want to do anything for a request that's already been aborted.
|
|
||||||
if (this.status == this.ABORTED) {
|
|
||||||
this._log.trace("Not proceeding with onStopRequest, request was aborted.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.error("Unexpected error: channel not nsIHttpChannel!");
|
|
||||||
this.status = this.ABORTED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.status = this.COMPLETED;
|
|
||||||
|
|
||||||
let statusSuccess = Components.isSuccessCode(statusCode);
|
|
||||||
let uri = channel && channel.URI && channel.URI.spec || "<unknown>";
|
|
||||||
this._log.trace("Channel for " + channel.requestMethod + " " + uri +
|
|
||||||
" returned status code " + statusCode);
|
|
||||||
|
|
||||||
if (!this.onComplete) {
|
|
||||||
this._log.error("Unexpected error: onComplete not defined in " +
|
|
||||||
"abortRequest.");
|
|
||||||
this.onProgress = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throw the failure code and stop execution. Use Components.Exception()
|
|
||||||
// instead of Error() so the exception is QI-able and can be passed across
|
|
||||||
// XPCOM borders while preserving the status code.
|
|
||||||
if (!statusSuccess) {
|
|
||||||
let message = Components.Exception("", statusCode).name;
|
|
||||||
let error = Components.Exception(message, statusCode);
|
|
||||||
this.onComplete(error);
|
|
||||||
this.onComplete = this.onProgress = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._log.debug(this.method + " " + uri + " " + this.response.status);
|
|
||||||
|
|
||||||
// Additionally give the full response body when Trace logging.
|
|
||||||
if (this._log.level <= Log4Moz.Level.Trace) {
|
|
||||||
this._log.trace(this.method + " body: " + this.response.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this._inputStream;
|
|
||||||
|
|
||||||
this.onComplete(null);
|
|
||||||
this.onComplete = this.onProgress = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
onDataAvailable: function onDataAvailable(req, cb, stream, off, count) {
|
|
||||||
this._inputStream.init(stream);
|
|
||||||
try {
|
|
||||||
this.response.body += this._inputStream.read(count);
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.warn("Exception thrown reading " + count +
|
|
||||||
" bytes from the channel.");
|
|
||||||
this._log.debug(Utils.exceptionStr(ex));
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.onProgress();
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.warn("Got exception calling onProgress handler, aborting " +
|
|
||||||
this.method + " " + req.URI.spec);
|
|
||||||
this._log.debug("Exception: " + Utils.exceptionStr(ex));
|
|
||||||
this.abort();
|
|
||||||
|
|
||||||
if (!this.onComplete) {
|
|
||||||
this._log.error("Unexpected error: onComplete not defined in " +
|
|
||||||
"onDataAvailable.");
|
|
||||||
this.onProgress = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onComplete(ex);
|
|
||||||
this.onComplete = this.onProgress = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.delayTimeout();
|
|
||||||
},
|
|
||||||
|
|
||||||
/*** nsIInterfaceRequestor ***/
|
|
||||||
|
|
||||||
getInterface: function(aIID) {
|
|
||||||
return this.QueryInterface(aIID);
|
|
||||||
},
|
|
||||||
|
|
||||||
/*** nsIBadCertListener2 ***/
|
|
||||||
|
|
||||||
notifyCertProblem: function notifyCertProblem(socketInfo, sslStatus, targetHost) {
|
|
||||||
this._log.warn("Invalid HTTPS certificate encountered!");
|
|
||||||
// Suppress invalid HTTPS certificate warnings in the UI.
|
|
||||||
// (The request will still fail.)
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*** nsIChannelEventSink ***/
|
|
||||||
asyncOnChannelRedirect:
|
|
||||||
function asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
newChannel.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.error("Unexpected error: channel not nsIHttpChannel!");
|
|
||||||
callback.onRedirectVerifyCallback(Cr.NS_ERROR_NO_INTERFACE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.channel = newChannel;
|
|
||||||
|
|
||||||
// We let all redirects proceed.
|
|
||||||
callback.onRedirectVerifyCallback(Cr.NS_OK);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Response object for a RESTRequest. This will be created automatically by
|
|
||||||
* the RESTRequest.
|
|
||||||
*/
|
|
||||||
function RESTResponse() {
|
|
||||||
this._log = Log4Moz.repository.getLogger(this._logName);
|
|
||||||
this._log.level =
|
|
||||||
Log4Moz.Level[Svc.Prefs.get("log.logger.network.resources")];
|
|
||||||
}
|
|
||||||
RESTResponse.prototype = {
|
|
||||||
|
|
||||||
_logName: "Sync.RESTResponse",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Corresponding REST request
|
|
||||||
*/
|
|
||||||
request: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP status code
|
|
||||||
*/
|
|
||||||
get status() {
|
|
||||||
let status;
|
|
||||||
try {
|
|
||||||
let channel = this.request.channel.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
status = channel.responseStatus;
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.debug("Caught exception fetching HTTP status code:" +
|
|
||||||
Utils.exceptionStr(ex));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
delete this.status;
|
|
||||||
return this.status = status;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Boolean flag that indicates whether the HTTP status code is 2xx or not.
|
|
||||||
*/
|
|
||||||
get success() {
|
|
||||||
let success;
|
|
||||||
try {
|
|
||||||
let channel = this.request.channel.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
success = channel.requestSucceeded;
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.debug("Caught exception fetching HTTP success flag:" +
|
|
||||||
Utils.exceptionStr(ex));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
delete this.success;
|
|
||||||
return this.success = success;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Object containing HTTP headers (keyed as lower case)
|
|
||||||
*/
|
|
||||||
get headers() {
|
|
||||||
let headers = {};
|
|
||||||
try {
|
|
||||||
this._log.trace("Processing response headers.");
|
|
||||||
let channel = this.request.channel.QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
channel.visitResponseHeaders(function (header, value) {
|
|
||||||
headers[header.toLowerCase()] = value;
|
|
||||||
});
|
|
||||||
} catch (ex) {
|
|
||||||
this._log.debug("Caught exception processing response headers:" +
|
|
||||||
Utils.exceptionStr(ex));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this.headers;
|
|
||||||
return this.headers = headers;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP body (string)
|
|
||||||
*/
|
|
||||||
body: null
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RESTRequest variant for use against a Sync storage server.
|
* RESTRequest variant for use against a Sync storage server.
|
||||||
*/
|
*/
|
||||||
|
@ -63,9 +63,9 @@ Cu.import("resource://services-sync/record.js");
|
|||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/clients.js");
|
Cu.import("resource://services-sync/engines/clients.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/rest.js");
|
Cu.import("resource://services-sync/rest.js");
|
||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
|
@ -41,7 +41,7 @@ const Cr = Components.results;
|
|||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
@ -38,17 +38,15 @@
|
|||||||
const EXPORTED_SYMBOLS = ["XPCOMUtils", "Services", "NetUtil", "PlacesUtils",
|
const EXPORTED_SYMBOLS = ["XPCOMUtils", "Services", "NetUtil", "PlacesUtils",
|
||||||
"FileUtils", "Utils", "Async", "Svc", "Str"];
|
"FileUtils", "Utils", "Async", "Svc", "Str"];
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||||
const Ci = Components.interfaces;
|
|
||||||
const Cr = Components.results;
|
|
||||||
const Cu = Components.utils;
|
|
||||||
|
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
Cu.import("resource://services-common/stringbundle.js");
|
||||||
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
|
||||||
Cu.import("resource://services-sync/ext/StringBundle.js");
|
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||||
@ -60,6 +58,17 @@ Cu.import("resource://gre/modules/FileUtils.jsm");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let Utils = {
|
let Utils = {
|
||||||
|
// Alias in functions from CommonUtils. These previously were defined here.
|
||||||
|
// In the ideal world, references to these would be removed.
|
||||||
|
nextTick: CommonUtils.nextTick,
|
||||||
|
namedTimer: CommonUtils.namedTimer,
|
||||||
|
exceptionStr: CommonUtils.exceptionStr,
|
||||||
|
stackTrace: CommonUtils.stackTrace,
|
||||||
|
makeURI: CommonUtils.makeURI,
|
||||||
|
encodeUTF8: CommonUtils.encodeUTF8,
|
||||||
|
decodeUTF8: CommonUtils.decodeUTF8,
|
||||||
|
safeAtoB: CommonUtils.safeAtoB,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap a function to catch all exceptions and log them
|
* Wrap a function to catch all exceptions and log them
|
||||||
*
|
*
|
||||||
@ -269,62 +278,18 @@ let Utils = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
exceptionStr: function Weave_exceptionStr(e) {
|
|
||||||
let message = e.message ? e.message : e;
|
|
||||||
return message + " " + Utils.stackTrace(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
stackTrace: function Weave_stackTrace(e) {
|
|
||||||
// Wrapped nsIException
|
|
||||||
if (e.location){
|
|
||||||
let frame = e.location;
|
|
||||||
let output = [];
|
|
||||||
while (frame) {
|
|
||||||
// Works on frames or exceptions, munges file:// URIs to shorten the paths
|
|
||||||
// FIXME: filename munging is sort of hackish, might be confusing if
|
|
||||||
// there are multiple extensions with similar filenames
|
|
||||||
let str = "<file:unknown>";
|
|
||||||
|
|
||||||
let file = frame.filename || frame.fileName;
|
|
||||||
if (file){
|
|
||||||
str = file.replace(/^(?:chrome|file):.*?([^\/\.]+\.\w+)$/, "$1");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame.lineNumber){
|
|
||||||
str += ":" + frame.lineNumber;
|
|
||||||
}
|
|
||||||
if (frame.name){
|
|
||||||
str = frame.name + "()@" + str;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str){
|
|
||||||
output.push(str);
|
|
||||||
}
|
|
||||||
frame = frame.caller;
|
|
||||||
}
|
|
||||||
return "Stack trace: " + output.join(" < ");
|
|
||||||
}
|
|
||||||
// Standard JS exception
|
|
||||||
if (e.stack){
|
|
||||||
return "JS Stack trace: " + e.stack.trim().replace(/\n/g, " < ").
|
|
||||||
replace(/@[^@]*?([^\/\.]+\.\w+:)/g, "@$1");
|
|
||||||
}
|
|
||||||
|
|
||||||
return "No traceback available";
|
|
||||||
},
|
|
||||||
|
|
||||||
// Generator and discriminator for HMAC exceptions.
|
// Generator and discriminator for HMAC exceptions.
|
||||||
// Split these out in case we want to make them richer in future, and to
|
// Split these out in case we want to make them richer in future, and to
|
||||||
// avoid inevitable confusion if the message changes.
|
// avoid inevitable confusion if the message changes.
|
||||||
throwHMACMismatch: function throwHMACMismatch(shouldBe, is) {
|
throwHMACMismatch: function throwHMACMismatch(shouldBe, is) {
|
||||||
throw "Record SHA256 HMAC mismatch: should be " + shouldBe + ", is " + is;
|
throw "Record SHA256 HMAC mismatch: should be " + shouldBe + ", is " + is;
|
||||||
},
|
},
|
||||||
|
|
||||||
isHMACMismatch: function isHMACMismatch(ex) {
|
isHMACMismatch: function isHMACMismatch(ex) {
|
||||||
const hmacFail = "Record SHA256 HMAC mismatch: ";
|
const hmacFail = "Record SHA256 HMAC mismatch: ";
|
||||||
return ex && ex.indexOf && (ex.indexOf(hmacFail) == 0);
|
return ex && ex.indexOf && (ex.indexOf(hmacFail) == 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UTF8-encode a message and hash it with the given hasher. Returns a
|
* UTF8-encode a message and hash it with the given hasher. Returns a
|
||||||
* string containing bytes. The hasher is reset if it's an HMAC hasher.
|
* string containing bytes. The hasher is reset if it's an HMAC hasher.
|
||||||
@ -832,18 +797,6 @@ let Utils = {
|
|||||||
return header += ', ext="' + ext +'"';
|
return header += ', ext="' + ext +'"';
|
||||||
},
|
},
|
||||||
|
|
||||||
makeURI: function Weave_makeURI(URIString) {
|
|
||||||
if (!URIString)
|
|
||||||
return null;
|
|
||||||
try {
|
|
||||||
return Services.io.newURI(URIString, null, null);
|
|
||||||
} catch (e) {
|
|
||||||
let log = Log4Moz.repository.getLogger("Sync.Utils");
|
|
||||||
log.debug("Could not create URI: " + Utils.exceptionStr(e));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a json object from disk
|
* Load a json object from disk
|
||||||
*
|
*
|
||||||
@ -917,59 +870,6 @@ let Utils = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a function on the next event loop tick.
|
|
||||||
*
|
|
||||||
* @param callback
|
|
||||||
* Function to invoke.
|
|
||||||
* @param thisObj [optional]
|
|
||||||
* Object to bind the callback to.
|
|
||||||
*/
|
|
||||||
nextTick: function nextTick(callback, thisObj) {
|
|
||||||
if (thisObj) {
|
|
||||||
callback = callback.bind(thisObj);
|
|
||||||
}
|
|
||||||
Services.tm.currentThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a timer that is scheduled to call the callback after waiting the
|
|
||||||
* provided time or as soon as possible. The timer will be set as a property
|
|
||||||
* of the provided object with the given timer name.
|
|
||||||
*/
|
|
||||||
namedTimer: function delay(callback, wait, thisObj, name) {
|
|
||||||
if (!thisObj || !name) {
|
|
||||||
throw "You must provide both an object and a property name for the timer!";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay an existing timer if it exists
|
|
||||||
if (name in thisObj && thisObj[name] instanceof Ci.nsITimer) {
|
|
||||||
thisObj[name].delay = wait;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a special timer that we can add extra properties
|
|
||||||
let timer = {};
|
|
||||||
timer.__proto__ = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
||||||
|
|
||||||
// Provide an easy way to clear out the timer
|
|
||||||
timer.clear = function() {
|
|
||||||
thisObj[name] = null;
|
|
||||||
timer.cancel();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize the timer with a smart callback
|
|
||||||
timer.initWithCallback({
|
|
||||||
notify: function notify() {
|
|
||||||
// Clear out the timer once it's been triggered
|
|
||||||
timer.clear();
|
|
||||||
callback.call(thisObj, timer);
|
|
||||||
}
|
|
||||||
}, wait, timer.TYPE_ONE_SHOT);
|
|
||||||
|
|
||||||
return thisObj[name] = timer;
|
|
||||||
},
|
|
||||||
|
|
||||||
getIcon: function(iconUri, defaultIcon) {
|
getIcon: function(iconUri, defaultIcon) {
|
||||||
try {
|
try {
|
||||||
let iconURI = Utils.makeURI(iconUri);
|
let iconURI = Utils.makeURI(iconUri);
|
||||||
@ -990,24 +890,6 @@ let Utils = {
|
|||||||
return Str.errors.get("error.reason.unknown");
|
return Str.errors.get("error.reason.unknown");
|
||||||
},
|
},
|
||||||
|
|
||||||
encodeUTF8: function(str) {
|
|
||||||
try {
|
|
||||||
str = this._utf8Converter.ConvertFromUnicode(str);
|
|
||||||
return str + this._utf8Converter.Finish();
|
|
||||||
} catch(ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
decodeUTF8: function(str) {
|
|
||||||
try {
|
|
||||||
str = this._utf8Converter.ConvertToUnicode(str);
|
|
||||||
return str + this._utf8Converter.Finish();
|
|
||||||
} catch(ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate 26 characters.
|
* Generate 26 characters.
|
||||||
*/
|
*/
|
||||||
@ -1108,15 +990,6 @@ let Utils = {
|
|||||||
return acc.trim();
|
return acc.trim();
|
||||||
},
|
},
|
||||||
|
|
||||||
// WeaveCrypto returns bad base64 strings. Truncate excess padding
|
|
||||||
// and decode.
|
|
||||||
// See Bug 562431, comment 4.
|
|
||||||
safeAtoB: function safeAtoB(b64) {
|
|
||||||
let len = b64.length;
|
|
||||||
let over = len % 4;
|
|
||||||
return over ? atob(b64.substr(0, len - over)) : atob(b64);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an array like the first but without elements of the second. Reuse
|
* Create an array like the first but without elements of the second. Reuse
|
||||||
* arrays if possible.
|
* arrays if possible.
|
||||||
|
@ -49,10 +49,10 @@ function addResourceAlias() {
|
|||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
const resProt = Services.io.getProtocolHandler("resource")
|
const resProt = Services.io.getProtocolHandler("resource")
|
||||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||||
let uri;
|
for each (let s in ["common", "sync", "crypto"]) {
|
||||||
uri = Services.io.newURI("resource:///modules/services-sync/", null, null);
|
let uri = Services.io.newURI("resource:///modules/services-" + s + "/", null,
|
||||||
resProt.setSubstitution("services-sync", uri);
|
null);
|
||||||
uri = Services.io.newURI("resource:///modules/services-crypto/", null, null);
|
resProt.setSubstitution("services-" + s, uri);
|
||||||
resProt.setSubstitution("services-crypto", uri);
|
}
|
||||||
}
|
}
|
||||||
addResourceAlias();
|
addResourceAlias();
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
@ -40,42 +41,8 @@ function waitForZeroTimer(callback) {
|
|||||||
timer = Utils.namedTimer(wait, 150, {}, "timer");
|
timer = Utils.namedTimer(wait, 150, {}, "timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
btoa = Cu.import("resource://services-sync/log4moz.js").btoa;
|
btoa = Cu.import("resource://services-common/log4moz.js").btoa;
|
||||||
atob = Cu.import("resource://services-sync/log4moz.js").atob;
|
atob = Cu.import("resource://services-common/log4moz.js").atob;
|
||||||
function getTestLogger(component) {
|
|
||||||
return Log4Moz.repository.getLogger("Testing");
|
|
||||||
}
|
|
||||||
|
|
||||||
function initTestLogging(level) {
|
|
||||||
function LogStats() {
|
|
||||||
this.errorsLogged = 0;
|
|
||||||
}
|
|
||||||
LogStats.prototype = {
|
|
||||||
format: function BF_format(message) {
|
|
||||||
if (message.level == Log4Moz.Level.Error)
|
|
||||||
this.errorsLogged += 1;
|
|
||||||
return message.loggerName + "\t" + message.levelDesc + "\t" +
|
|
||||||
message.message + "\n";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
LogStats.prototype.__proto__ = new Log4Moz.Formatter();
|
|
||||||
|
|
||||||
var log = Log4Moz.repository.rootLogger;
|
|
||||||
var logStats = new LogStats();
|
|
||||||
var appender = new Log4Moz.DumpAppender(logStats);
|
|
||||||
|
|
||||||
if (typeof(level) == "undefined")
|
|
||||||
level = "Debug";
|
|
||||||
getTestLogger().level = Log4Moz.Level[level];
|
|
||||||
|
|
||||||
log.level = Log4Moz.Level.Trace;
|
|
||||||
appender.level = Log4Moz.Level.Trace;
|
|
||||||
// Overwrite any other appenders (e.g. from previous incarnations)
|
|
||||||
log.ownAppenders = [appender];
|
|
||||||
log.updateAppenders();
|
|
||||||
|
|
||||||
return logStats;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is needed for loadAddonTestFunctions().
|
// This is needed for loadAddonTestFunctions().
|
||||||
let gGlobalScope = this;
|
let gGlobalScope = this;
|
||||||
@ -298,21 +265,9 @@ function ensureThrows(func) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print some debug message to the console. All arguments will be printed,
|
|
||||||
* separated by spaces.
|
|
||||||
*
|
|
||||||
* @param [arg0, arg1, arg2, ...]
|
|
||||||
* Any number of arguments to print out
|
|
||||||
* @usage _("Hello World") -> prints "Hello World"
|
|
||||||
* @usage _(1, 2, 3) -> prints "1 2 3"
|
|
||||||
*/
|
|
||||||
let _ = function(some, debug, text, to) print(Array.slice(arguments).join(" "));
|
|
||||||
|
|
||||||
_("Setting the identity for passphrase");
|
_("Setting the identity for passphrase");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test setup helpers.
|
* Test setup helpers.
|
||||||
*/
|
*/
|
||||||
@ -334,32 +289,6 @@ function generateNewKeys(collections) {
|
|||||||
CollectionKeys.setContents(wbo.cleartext, modified);
|
CollectionKeys.setContents(wbo.cleartext, modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
function do_check_empty(obj) {
|
|
||||||
do_check_attribute_count(obj, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function do_check_attribute_count(obj, c) {
|
|
||||||
do_check_eq(c, Object.keys(obj).length);
|
|
||||||
}
|
|
||||||
|
|
||||||
function do_check_throws(aFunc, aResult, aStack)
|
|
||||||
{
|
|
||||||
if (!aStack) {
|
|
||||||
try {
|
|
||||||
// We might not have a 'Components' object.
|
|
||||||
aStack = Components.stack.caller;
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
aFunc();
|
|
||||||
} catch (e) {
|
|
||||||
do_check_eq(e.result, aResult, aStack);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
do_throw("Expected result " + aResult + ", none thrown.", aStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A fake engine implementation.
|
* A fake engine implementation.
|
||||||
* This is used all over the place.
|
* This is used all over the place.
|
||||||
@ -487,4 +416,4 @@ deepCopy: function deepCopy(thing, noSort) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ const TEST_CLUSTER_URL = "http://localhost:8080/";
|
|||||||
const TEST_SERVER_URL = "http://localhost:8080/";
|
const TEST_SERVER_URL = "http://localhost:8080/";
|
||||||
|
|
||||||
// Shared logging for all HTTP server functions.
|
// Shared logging for all HTTP server functions.
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
const SYNC_HTTP_LOGGER = "Sync.Test.Server";
|
const SYNC_HTTP_LOGGER = "Sync.Test.Server";
|
||||||
const SYNC_API_VERSION = "1.1";
|
const SYNC_API_VERSION = "1.1";
|
||||||
|
|
||||||
@ -26,39 +26,6 @@ function return_timestamp(request, response, timestamp) {
|
|||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
function httpd_setup (handlers, port) {
|
|
||||||
let port = port || 8080;
|
|
||||||
let server = new nsHttpServer();
|
|
||||||
for (let path in handlers) {
|
|
||||||
server.registerPathHandler(path, handlers[path]);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
server.start(port);
|
|
||||||
} catch (ex) {
|
|
||||||
_("==========================================");
|
|
||||||
_("Got exception starting HTTP server on port " + port);
|
|
||||||
_("Error: " + Utils.exceptionStr(ex));
|
|
||||||
_("Is there a process already listening on port " + port + "?");
|
|
||||||
_("==========================================");
|
|
||||||
do_throw(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
function httpd_handler(statusCode, status, body) {
|
|
||||||
return function handler(request, response) {
|
|
||||||
// Allow test functions to inspect the request.
|
|
||||||
request.body = readBytesFromInputStream(request.bodyInputStream);
|
|
||||||
handler.request = request;
|
|
||||||
|
|
||||||
response.setStatusLine(request.httpVersion, statusCode, status);
|
|
||||||
if (body) {
|
|
||||||
response.bodyOutputStream.write(body, body.length);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function basic_auth_header(user, password) {
|
function basic_auth_header(user, password) {
|
||||||
return "Basic " + btoa(user + ":" + Utils.encodeUTF8(password));
|
return "Basic " + btoa(user + ":" + Utils.encodeUTF8(password));
|
||||||
}
|
}
|
||||||
@ -84,21 +51,6 @@ function httpd_basic_auth_handler(body, metadata, response) {
|
|||||||
response.bodyOutputStream.write(body, body.length);
|
response.bodyOutputStream.write(body, body.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Read bytes string from an nsIInputStream. If 'count' is omitted,
|
|
||||||
* all available input is read.
|
|
||||||
*/
|
|
||||||
function readBytesFromInputStream(inputStream, count) {
|
|
||||||
var BinaryInputStream = Components.Constructor(
|
|
||||||
"@mozilla.org/binaryinputstream;1",
|
|
||||||
"nsIBinaryInputStream",
|
|
||||||
"setInputStream");
|
|
||||||
if (!count) {
|
|
||||||
count = inputStream.available();
|
|
||||||
}
|
|
||||||
return new BinaryInputStream(inputStream).readBytes(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Represent a WBO on the server
|
* Represent a WBO on the server
|
||||||
*/
|
*/
|
||||||
@ -1044,51 +996,3 @@ function serverForUsers(users, contents, callback) {
|
|||||||
server.start();
|
server.start();
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy auth helpers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fake a PAC to prompt a channel replacement.
|
|
||||||
*/
|
|
||||||
let PACSystemSettings = {
|
|
||||||
CID: Components.ID("{5645d2c1-d6d8-4091-b117-fe7ee4027db7}"),
|
|
||||||
contractID: "@mozilla.org/system-proxy-settings;1",
|
|
||||||
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory,
|
|
||||||
Ci.nsISystemProxySettings]),
|
|
||||||
|
|
||||||
createInstance: function createInstance(outer, iid) {
|
|
||||||
if (outer) {
|
|
||||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
|
||||||
}
|
|
||||||
return this.QueryInterface(iid);
|
|
||||||
},
|
|
||||||
|
|
||||||
lockFactory: function lockFactory(lock) {
|
|
||||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Replace this URI for each test to avoid caching. We want to ensure that
|
|
||||||
// each test gets a completely fresh setup.
|
|
||||||
PACURI: null,
|
|
||||||
getProxyForURI: function getProxyForURI(aURI) {
|
|
||||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function installFakePAC() {
|
|
||||||
_("Installing fake PAC.");
|
|
||||||
Cm.nsIComponentRegistrar
|
|
||||||
.registerFactory(PACSystemSettings.CID,
|
|
||||||
"Fake system proxy-settings",
|
|
||||||
PACSystemSettings.contractID,
|
|
||||||
PACSystemSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallFakePAC() {
|
|
||||||
_("Uninstalling fake PAC.");
|
|
||||||
let CID = PACSystemSettings.CID;
|
|
||||||
Cm.nsIComponentRegistrar.unregisterFactory(CID, PACSystemSettings);
|
|
||||||
}
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://services-sync/addonsreconciler.js");
|
Cu.import("resource://services-sync/addonsreconciler.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/engines/addons.js");
|
Cu.import("resource://services-sync/engines/addons.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
|
|
||||||
let prefs = new Preferences();
|
let prefs = new Preferences();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Cu.import("resource://services-sync/engines/addons.js");
|
Cu.import("resource://services-sync/engines/addons.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
|
||||||
const HTTP_PORT = 8888;
|
const HTTP_PORT = 8888;
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/bookmarks.js");
|
Cu.import("resource://services-sync/engines/bookmarks.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/bookmarks.js");
|
Cu.import("resource://services-sync/engines/bookmarks.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/bookmarks.js");
|
Cu.import("resource://services-sync/engines/bookmarks.js");
|
||||||
|
@ -5,7 +5,7 @@ Cu.import("resource://services-sync/identity.js");
|
|||||||
Cu.import("resource://services-sync/keys.js");
|
Cu.import("resource://services-sync/keys.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/engines/bookmarks.js");
|
Cu.import("resource://services-sync/engines/bookmarks.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
function prepareBookmarkItem(collection, id) {
|
function prepareBookmarkItem(collection, id) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/bookmarks.js");
|
Cu.import("resource://services-sync/engines/bookmarks.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
|
@ -7,7 +7,7 @@ Cu.import("resource://services-sync/constants.js");
|
|||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/engines/tabs.js");
|
Cu.import("resource://services-sync/engines/tabs.js");
|
||||||
Cu.import("resource://services-sync/engines/history.js");
|
Cu.import("resource://services-sync/engines/history.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
add_test(function test_locally_changed_keys() {
|
add_test(function test_locally_changed_keys() {
|
||||||
let passphrase = "abcdeabcdeabcdeabcdeabcdea";
|
let passphrase = "abcdeabcdeabcdeabcdeabcdea";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
Cu.import("resource://services-sync/policies.js");
|
Cu.import("resource://services-sync/policies.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
|
const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
|
||||||
const LOG_PREFIX_SUCCESS = "success-";
|
const LOG_PREFIX_SUCCESS = "success-";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Cu.import("resource://services-sync/engines/forms.js");
|
Cu.import("resource://services-sync/engines/forms.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
_("Verify we've got an empty tracker to work with.");
|
_("Verify we've got an empty tracker to work with.");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://services-sync/engines/history.js");
|
Cu.import("resource://services-sync/engines/history.js");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
const TIMESTAMP1 = (Date.now() - 103406528) * 1000;
|
const TIMESTAMP1 = (Date.now() - 103406528) * 1000;
|
||||||
|
@ -59,7 +59,7 @@ add_test(function test_url_parsing() {
|
|||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
||||||
|
|
||||||
Cu.import("resource://services-sync/rest.js");
|
Cu.import("resource://services-common/rest.js");
|
||||||
function localRequest(path) {
|
function localRequest(path) {
|
||||||
_("localRequest: " + path);
|
_("localRequest: " + path);
|
||||||
let url = "http://127.0.0.1:8080" + path;
|
let url = "http://127.0.0.1:8080" + path;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/jpakeclient.js");
|
Cu.import("resource://services-sync/jpakeclient.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
@ -190,7 +190,8 @@ function run_test() {
|
|||||||
|
|
||||||
initTestLogging("Trace");
|
initTestLogging("Trace");
|
||||||
Log4Moz.repository.getLogger("Sync.JPAKEClient").level = Log4Moz.Level.Trace;
|
Log4Moz.repository.getLogger("Sync.JPAKEClient").level = Log4Moz.Level.Trace;
|
||||||
Log4Moz.repository.getLogger("Sync.RESTRequest").level = Log4Moz.Level.Trace;
|
Log4Moz.repository.getLogger("Common.RESTRequest").level =
|
||||||
|
Log4Moz.Level.Trace;
|
||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const modules = [
|
const modules = [
|
||||||
"addonsreconciler.js",
|
"addonsreconciler.js",
|
||||||
"async.js",
|
|
||||||
"constants.js",
|
"constants.js",
|
||||||
"engines/addons.js",
|
"engines/addons.js",
|
||||||
"engines/bookmarks.js",
|
"engines/bookmarks.js",
|
||||||
@ -11,12 +10,9 @@ const modules = [
|
|||||||
"engines/prefs.js",
|
"engines/prefs.js",
|
||||||
"engines/tabs.js",
|
"engines/tabs.js",
|
||||||
"engines.js",
|
"engines.js",
|
||||||
"ext/Observers.js",
|
|
||||||
"ext/Preferences.js",
|
|
||||||
"identity.js",
|
"identity.js",
|
||||||
"jpakeclient.js",
|
"jpakeclient.js",
|
||||||
"keys.js",
|
"keys.js",
|
||||||
"log4moz.js",
|
|
||||||
"main.js",
|
"main.js",
|
||||||
"notifications.js",
|
"notifications.js",
|
||||||
"policies.js",
|
"policies.js",
|
||||||
|
@ -7,12 +7,12 @@ _("Test that node reassignment responses are respected on all kinds of " +
|
|||||||
// Don't sync any engines by default.
|
// Don't sync any engines by default.
|
||||||
Svc.DefaultPrefs.set("registerEngines", "")
|
Svc.DefaultPrefs.set("registerEngines", "")
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/rest.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/policies.js");
|
Cu.import("resource://services-sync/policies.js");
|
||||||
Cu.import("resource://services-sync/rest.js");
|
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
Log4Moz.repository.getLogger("Sync.AsyncResource").level = Log4Moz.Level.Trace;
|
Log4Moz.repository.getLogger("Sync.AsyncResource").level = Log4Moz.Level.Trace;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/engines/history.js");
|
Cu.import("resource://services-sync/engines/history.js");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Cu.import("resource://services-sync/engines/prefs.js");
|
Cu.import("resource://services-sync/engines/prefs.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
|
Cu.import("resource://gre/modules/LightweightThemeManager.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Cu.import("resource://services-sync/engines/prefs.js");
|
Cu.import("resource://services-sync/engines/prefs.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
let engine = new PrefsEngine();
|
let engine = new PrefsEngine();
|
||||||
|
@ -6,7 +6,7 @@ Cu.import("resource://services-sync/identity.js");
|
|||||||
Cu.import("resource://services-sync/keys.js");
|
Cu.import("resource://services-sync/keys.js");
|
||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
let cryptoWrap;
|
let cryptoWrap;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/resource.js");
|
Cu.import("resource://services-sync/resource.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ Cu.import("resource://services-sync/main.js");
|
|||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
|
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
initTestLogging("Trace");
|
initTestLogging("Trace");
|
||||||
|
@ -10,7 +10,7 @@ Cu.import("resource://services-sync/constants.js");
|
|||||||
Cu.import("resource://services-sync/record.js");
|
Cu.import("resource://services-sync/record.js");
|
||||||
Cu.import("resource://services-sync/keys.js");
|
Cu.import("resource://services-sync/keys.js");
|
||||||
Cu.import("resource://services-sync/engines/tabs.js");
|
Cu.import("resource://services-sync/engines/tabs.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
Engines.register(TabEngine);
|
Engines.register(TabEngine);
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/rest.js");
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
Cu.import("resource://services-sync/rest.js");
|
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Cu.import("resource://services-sync/ext/Preferences.js");
|
Cu.import("resource://services-common/preferences.js");
|
||||||
|
|
||||||
function test_migrate_logging() {
|
function test_migrate_logging() {
|
||||||
_("Testing log pref migration.");
|
_("Testing log pref migration.");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
Cu.import("resource://services-sync/ext/Observers.js");
|
Cu.import("resource://services-common/observers.js");
|
||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
@ -6,7 +6,7 @@ Cu.import("resource://services-sync/util.js");
|
|||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/keys.js");
|
Cu.import("resource://services-sync/keys.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
let logger = Log4Moz.repository.rootLogger;
|
let logger = Log4Moz.repository.rootLogger;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
Cu.import("resource://services-sync/service.js");
|
Cu.import("resource://services-sync/service.js");
|
||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
|
@ -5,7 +5,7 @@ Cu.import("resource://services-sync/rest.js");
|
|||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/identity.js");
|
Cu.import("resource://services-sync/identity.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
Cu.import("resource://services-sync/log4moz.js");
|
Cu.import("resource://services-common/log4moz.js");
|
||||||
|
|
||||||
const STORAGE_REQUEST_RESOURCE_URL = TEST_SERVER_URL + "resource";
|
const STORAGE_REQUEST_RESOURCE_URL = TEST_SERVER_URL + "resource";
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
Cu.import("resource://services-sync/util.js");
|
|
||||||
|
|
||||||
function run_test() {
|
|
||||||
let data = ["Zm9vYmE=", "Zm9vYmE==", "Zm9vYmE==="];
|
|
||||||
for (let d in data) {
|
|
||||||
do_check_eq(Utils.safeAtoB(data[d]), "fooba");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,8 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
Cu.import("resource://services-common/stringbundle.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://services-sync/ext/StringBundle.js");
|
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
let fn = Utils.lazyStrings("sync");
|
let fn = Utils.lazyStrings("sync");
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
_("Make sure uri strings are converted to nsIURIs");
|
|
||||||
Cu.import("resource://services-sync/util.js");
|
|
||||||
|
|
||||||
function run_test() {
|
|
||||||
_test_makeURI();
|
|
||||||
}
|
|
||||||
|
|
||||||
function _test_makeURI() {
|
|
||||||
_("Check http uris");
|
|
||||||
let uri1 = "http://mozillalabs.com/";
|
|
||||||
do_check_eq(Utils.makeURI(uri1).spec, uri1);
|
|
||||||
let uri2 = "http://www.mozillalabs.com/";
|
|
||||||
do_check_eq(Utils.makeURI(uri2).spec, uri2);
|
|
||||||
let uri3 = "http://mozillalabs.com/path";
|
|
||||||
do_check_eq(Utils.makeURI(uri3).spec, uri3);
|
|
||||||
let uri4 = "http://mozillalabs.com/multi/path";
|
|
||||||
do_check_eq(Utils.makeURI(uri4).spec, uri4);
|
|
||||||
let uri5 = "http://mozillalabs.com/?query";
|
|
||||||
do_check_eq(Utils.makeURI(uri5).spec, uri5);
|
|
||||||
let uri6 = "http://mozillalabs.com/#hash";
|
|
||||||
do_check_eq(Utils.makeURI(uri6).spec, uri6);
|
|
||||||
|
|
||||||
_("Check https uris");
|
|
||||||
let uris1 = "https://mozillalabs.com/";
|
|
||||||
do_check_eq(Utils.makeURI(uris1).spec, uris1);
|
|
||||||
let uris2 = "https://www.mozillalabs.com/";
|
|
||||||
do_check_eq(Utils.makeURI(uris2).spec, uris2);
|
|
||||||
let uris3 = "https://mozillalabs.com/path";
|
|
||||||
do_check_eq(Utils.makeURI(uris3).spec, uris3);
|
|
||||||
let uris4 = "https://mozillalabs.com/multi/path";
|
|
||||||
do_check_eq(Utils.makeURI(uris4).spec, uris4);
|
|
||||||
let uris5 = "https://mozillalabs.com/?query";
|
|
||||||
do_check_eq(Utils.makeURI(uris5).spec, uris5);
|
|
||||||
let uris6 = "https://mozillalabs.com/#hash";
|
|
||||||
do_check_eq(Utils.makeURI(uris6).spec, uris6);
|
|
||||||
|
|
||||||
_("Check chrome uris");
|
|
||||||
let uric1 = "chrome://browser/content/browser.xul";
|
|
||||||
do_check_eq(Utils.makeURI(uric1).spec, uric1);
|
|
||||||
let uric2 = "chrome://browser/skin/browser.css";
|
|
||||||
do_check_eq(Utils.makeURI(uric2).spec, uric2);
|
|
||||||
let uric3 = "chrome://browser/locale/browser.dtd";
|
|
||||||
do_check_eq(Utils.makeURI(uric3).spec, uric3);
|
|
||||||
|
|
||||||
_("Check about uris");
|
|
||||||
let uria1 = "about:weave";
|
|
||||||
do_check_eq(Utils.makeURI(uria1).spec, uria1);
|
|
||||||
let uria2 = "about:weave/";
|
|
||||||
do_check_eq(Utils.makeURI(uria2).spec, uria2);
|
|
||||||
let uria3 = "about:weave/path";
|
|
||||||
do_check_eq(Utils.makeURI(uria3).spec, uria3);
|
|
||||||
let uria4 = "about:weave/multi/path";
|
|
||||||
do_check_eq(Utils.makeURI(uria4).spec, uria4);
|
|
||||||
let uria5 = "about:weave/?query";
|
|
||||||
do_check_eq(Utils.makeURI(uria5).spec, uria5);
|
|
||||||
let uria6 = "about:weave/#hash";
|
|
||||||
do_check_eq(Utils.makeURI(uria6).spec, uria6);
|
|
||||||
|
|
||||||
_("Invalid uris are undefined");
|
|
||||||
do_check_eq(Utils.makeURI("mozillalabs.com"), undefined);
|
|
||||||
do_check_eq(Utils.makeURI("chrome://badstuff"), undefined);
|
|
||||||
do_check_eq(Utils.makeURI("this is a test"), undefined);
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
Cu.import("resource://services-sync/util.js");
|
|
||||||
|
|
||||||
function run_test() {
|
|
||||||
let str = "Umlaute: \u00FC \u00E4\n"; // Umlaute: ü ä
|
|
||||||
let encoded = Utils.encodeUTF8(str);
|
|
||||||
let decoded = Utils.decodeUTF8(encoded);
|
|
||||||
do_check_eq(decoded, str);
|
|
||||||
}
|
|
@ -1,9 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
head = head_appinfo.js head_helpers.js head_http_server.js
|
head = head_appinfo.js ../../../common/tests/unit/head_helpers.js head_helpers.js head_http_server.js
|
||||||
tail =
|
tail =
|
||||||
|
|
||||||
[test_load_modules.js]
|
|
||||||
|
|
||||||
# The manifest is roughly ordered from low-level to high-level. When making
|
# The manifest is roughly ordered from low-level to high-level. When making
|
||||||
# systemic sweeping changes, this makes it easier to identify errors closer to
|
# systemic sweeping changes, this makes it easier to identify errors closer to
|
||||||
# the source.
|
# the source.
|
||||||
@ -12,7 +10,6 @@ tail =
|
|||||||
[test_load_modules.js]
|
[test_load_modules.js]
|
||||||
|
|
||||||
# util contains a bunch of functionality used throughout.
|
# util contains a bunch of functionality used throughout.
|
||||||
[test_utils_atob.js]
|
|
||||||
[test_utils_catch.js]
|
[test_utils_catch.js]
|
||||||
[test_utils_deepCopy.js]
|
[test_utils_deepCopy.js]
|
||||||
[test_utils_deepEquals.js]
|
[test_utils_deepEquals.js]
|
||||||
@ -27,23 +24,13 @@ tail =
|
|||||||
[test_utils_lazyStrings.js]
|
[test_utils_lazyStrings.js]
|
||||||
[test_utils_lock.js]
|
[test_utils_lock.js]
|
||||||
[test_utils_makeGUID.js]
|
[test_utils_makeGUID.js]
|
||||||
[test_utils_makeURI.js]
|
|
||||||
[test_utils_namedTimer.js]
|
|
||||||
[test_utils_notify.js]
|
[test_utils_notify.js]
|
||||||
[test_utils_passphrase.js]
|
[test_utils_passphrase.js]
|
||||||
[test_utils_pbkdf2.js]
|
[test_utils_pbkdf2.js]
|
||||||
[test_utils_sha1.js]
|
[test_utils_sha1.js]
|
||||||
[test_utils_stackTrace.js]
|
|
||||||
[test_utils_utf8.js]
|
|
||||||
|
|
||||||
# We have a number of other libraries that are pretty much standalone.
|
# We have a number of other libraries that are pretty much standalone.
|
||||||
[test_Observers.js]
|
|
||||||
[test_Preferences.js]
|
|
||||||
[test_async_chain.js]
|
|
||||||
[test_async_querySpinningly.js]
|
|
||||||
[test_httpd_sync_server.js]
|
[test_httpd_sync_server.js]
|
||||||
[test_log4moz.js]
|
|
||||||
[test_restrequest.js]
|
|
||||||
[test_jpakeclient.js]
|
[test_jpakeclient.js]
|
||||||
# Bug 618233: this test produces random failures on Windows 7.
|
# Bug 618233: this test produces random failures on Windows 7.
|
||||||
# Bug 676978: test hangs on Android (see also testing/xpcshell/xpcshell.ini)
|
# Bug 676978: test hangs on Android (see also testing/xpcshell/xpcshell.ini)
|
||||||
|
@ -42,7 +42,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|||||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||||
Cu.import("resource://gre/modules/AddonRepository.jsm");
|
Cu.import("resource://gre/modules/AddonRepository.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://services-sync/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
Cu.import("resource://services-sync/util.js");
|
Cu.import("resource://services-sync/util.js");
|
||||||
Cu.import("resource://tps/logger.jsm");
|
Cu.import("resource://tps/logger.jsm");
|
||||||
|
@ -50,7 +50,7 @@ const CU = Components.utils;
|
|||||||
CU.import("resource://tps/logger.jsm");
|
CU.import("resource://tps/logger.jsm");
|
||||||
CU.import("resource://gre/modules/Services.jsm");
|
CU.import("resource://gre/modules/Services.jsm");
|
||||||
CU.import("resource://gre/modules/PlacesUtils.jsm");
|
CU.import("resource://gre/modules/PlacesUtils.jsm");
|
||||||
CU.import("resource://services-sync/async.js");
|
CU.import("resource://services-common/async.js");
|
||||||
|
|
||||||
var DumpBookmarks = function TPS_Bookmarks__DumpBookmarks() {
|
var DumpBookmarks = function TPS_Bookmarks__DumpBookmarks() {
|
||||||
let writer = {
|
let writer = {
|
||||||
|
@ -49,7 +49,7 @@ const CU = Components.utils;
|
|||||||
CU.import("resource://gre/modules/Services.jsm");
|
CU.import("resource://gre/modules/Services.jsm");
|
||||||
CU.import("resource://gre/modules/PlacesUtils.jsm");
|
CU.import("resource://gre/modules/PlacesUtils.jsm");
|
||||||
CU.import("resource://tps/logger.jsm");
|
CU.import("resource://tps/logger.jsm");
|
||||||
CU.import("resource://services-sync/async.js");
|
CU.import("resource://services-common/async.js");
|
||||||
|
|
||||||
var DumpHistory = function TPS_History__DumpHistory() {
|
var DumpHistory = function TPS_History__DumpHistory() {
|
||||||
let writer = {
|
let writer = {
|
||||||
|
@ -47,7 +47,7 @@ const {classes: CC, interfaces: CI, utils: CU} = Components;
|
|||||||
CU.import("resource://services-sync/service.js");
|
CU.import("resource://services-sync/service.js");
|
||||||
CU.import("resource://services-sync/constants.js");
|
CU.import("resource://services-sync/constants.js");
|
||||||
CU.import("resource://services-sync/engines.js");
|
CU.import("resource://services-sync/engines.js");
|
||||||
CU.import("resource://services-sync/async.js");
|
CU.import("resource://services-common/async.js");
|
||||||
CU.import("resource://services-sync/util.js");
|
CU.import("resource://services-sync/util.js");
|
||||||
CU.import("resource://gre/modules/XPCOMUtils.jsm");
|
CU.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
CU.import("resource://gre/modules/Services.jsm");
|
CU.import("resource://gre/modules/Services.jsm");
|
||||||
|
@ -40,7 +40,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
version = '0.2.40'
|
version = '0.2.40'
|
||||||
|
|
||||||
deps = ['pulsebuildmonitor >= 0.2', 'MozillaPulse == .4',
|
deps = ['pulsebuildmonitor >= 0.62', 'MozillaPulse == 0.61',
|
||||||
'mozinfo == 0.3.1', 'mozprofile == 0.1t',
|
'mozinfo == 0.3.1', 'mozprofile == 0.1t',
|
||||||
'mozprocess == 0.1a', 'mozrunner == 3.0a', 'mozregression == 0.3',
|
'mozprocess == 0.1a', 'mozrunner == 3.0a', 'mozregression == 0.3',
|
||||||
'mozautolog >= 0.2.1']
|
'mozautolog >= 0.2.1']
|
||||||
|
@ -51,7 +51,7 @@ class TPSPulseMonitor(PulseBuildMonitor):
|
|||||||
def __init__(self, extensionDir, platform='linux', config=None,
|
def __init__(self, extensionDir, platform='linux', config=None,
|
||||||
autolog=False, emailresults=False, testfile=None,
|
autolog=False, emailresults=False, testfile=None,
|
||||||
logfile=None, rlock=None, **kwargs):
|
logfile=None, rlock=None, **kwargs):
|
||||||
self.buildtype = 'opt'
|
self.buildtype = ['opt']
|
||||||
self.autolog = autolog
|
self.autolog = autolog
|
||||||
self.emailresults = emailresults
|
self.emailresults = emailresults
|
||||||
self.testfile = testfile
|
self.testfile = testfile
|
||||||
@ -59,8 +59,8 @@ class TPSPulseMonitor(PulseBuildMonitor):
|
|||||||
self.rlock = rlock
|
self.rlock = rlock
|
||||||
self.extensionDir = extensionDir
|
self.extensionDir = extensionDir
|
||||||
self.config = config
|
self.config = config
|
||||||
self.tree = self.config.get('tree', ['services-central', 'places'])
|
self.tree = self.config.get('tree', ['services-central'])
|
||||||
self.platform = self.config.get('platform', 'linux')
|
self.platform = [self.config.get('platform', 'linux')]
|
||||||
self.label=('crossweave@mozilla.com|tps_build_monitor_' +
|
self.label=('crossweave@mozilla.com|tps_build_monitor_' +
|
||||||
socket.gethostname())
|
socket.gethostname())
|
||||||
|
|
||||||
@ -70,10 +70,12 @@ class TPSPulseMonitor(PulseBuildMonitor):
|
|||||||
self.logger.addHandler(handler)
|
self.logger.addHandler(handler)
|
||||||
|
|
||||||
PulseBuildMonitor.__init__(self,
|
PulseBuildMonitor.__init__(self,
|
||||||
tree=self.tree,
|
trees=self.tree,
|
||||||
label=self.label,
|
label=self.label,
|
||||||
mobile=False,
|
|
||||||
logger=self.logger,
|
logger=self.logger,
|
||||||
|
platforms=self.platform,
|
||||||
|
buildtypes=self.buildtype,
|
||||||
|
builds=True,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
def onPulseMessage(self, data):
|
def onPulseMessage(self, data):
|
||||||
@ -84,12 +86,7 @@ class TPSPulseMonitor(PulseBuildMonitor):
|
|||||||
print "================================================================="
|
print "================================================================="
|
||||||
print json.dumps(builddata)
|
print json.dumps(builddata)
|
||||||
print "================================================================="
|
print "================================================================="
|
||||||
try:
|
|
||||||
if not (builddata['platform'] == self.platform and
|
|
||||||
builddata['buildtype'] == self.buildtype):
|
|
||||||
return
|
|
||||||
except KeyError:
|
|
||||||
return
|
|
||||||
thread = TPSTestThread(self.extensionDir,
|
thread = TPSTestThread(self.extensionDir,
|
||||||
builddata=builddata,
|
builddata=builddata,
|
||||||
emailresults=self.emailresults,
|
emailresults=self.emailresults,
|
||||||
|
@ -67,6 +67,7 @@ skip-if = os == "android"
|
|||||||
[include:content/base/test/unit/xpcshell.ini]
|
[include:content/base/test/unit/xpcshell.ini]
|
||||||
[include:content/test/unit/xpcshell.ini]
|
[include:content/test/unit/xpcshell.ini]
|
||||||
[include:toolkit/components/url-classifier/tests/unit/xpcshell.ini]
|
[include:toolkit/components/url-classifier/tests/unit/xpcshell.ini]
|
||||||
|
[include:services/common/tests/unit/xpcshell.ini]
|
||||||
[include:services/crypto/tests/unit/xpcshell.ini]
|
[include:services/crypto/tests/unit/xpcshell.ini]
|
||||||
[include:services/crypto/components/tests/unit/xpcshell.ini]
|
[include:services/crypto/components/tests/unit/xpcshell.ini]
|
||||||
[include:services/sync/tests/unit/xpcshell.ini]
|
[include:services/sync/tests/unit/xpcshell.ini]
|
||||||
|
Loading…
Reference in New Issue
Block a user