зеркало из https://github.com/mozilla/gecko-dev.git
Bug 851454 - Define the format of "downloads.json" and of the parameters of createDownload. r=enn
This commit is contained in:
Родитель
ef758e8b77
Коммит
38e7ec52c3
|
@ -56,6 +56,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
|
@ -69,6 +71,15 @@ const BackgroundFileSaverStreamListener = Components.Constructor(
|
|||
"@mozilla.org/network/background-file-saver;1?mode=streamlistener",
|
||||
"nsIBackgroundFileSaver");
|
||||
|
||||
/**
|
||||
* Returns true if the given value is a primitive string or a String object.
|
||||
*/
|
||||
function isString(aValue) {
|
||||
// We cannot use the "instanceof" operator reliably across module boundaries.
|
||||
return (typeof aValue == "string") ||
|
||||
(typeof aValue == "object" && "charAt" in aValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Download
|
||||
|
||||
|
@ -422,6 +433,71 @@ Download.prototype = {
|
|||
}
|
||||
this._notifyChange();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a static representation of the current object state.
|
||||
*
|
||||
* @return A JavaScript object that can be serialized to JSON.
|
||||
*/
|
||||
toSerializable: function ()
|
||||
{
|
||||
let serializable = {
|
||||
source: this.source.toSerializable(),
|
||||
target: this.target.toSerializable(),
|
||||
};
|
||||
|
||||
// Simplify the representation for the most common saver type. If the saver
|
||||
// is an object instead of a simple string, we can't simplify it because we
|
||||
// need to persist all its properties, not only "type". This may happen for
|
||||
// savers of type "copy" as well as other types.
|
||||
let saver = this.saver.toSerializable();
|
||||
if (saver !== "copy") {
|
||||
serializable.saver = saver;
|
||||
}
|
||||
|
||||
return serializable;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new Download object from a serializable representation. This
|
||||
* function is used by the createDownload method of Downloads.jsm when a new
|
||||
* Download object is requested, thus some properties may refer to live objects
|
||||
* in place of their serializable representations.
|
||||
*
|
||||
* @param aSerializable
|
||||
* An object with the following fields:
|
||||
* {
|
||||
* source: DownloadSource object, or its serializable representation.
|
||||
* See DownloadSource.fromSerializable for details.
|
||||
* target: DownloadTarget object, or its serializable representation.
|
||||
* See DownloadTarget.fromSerializable for details.
|
||||
* saver: Serializable representation of a DownloadSaver object. See
|
||||
* DownloadSaver.fromSerializable for details. If omitted,
|
||||
* defaults to "copy".
|
||||
* }
|
||||
*
|
||||
* @return The newly created Download object.
|
||||
*/
|
||||
Download.fromSerializable = function (aSerializable) {
|
||||
let download = new Download();
|
||||
if (aSerializable.source instanceof DownloadSource) {
|
||||
download.source = aSerializable.source;
|
||||
} else {
|
||||
download.source = DownloadSource.fromSerializable(aSerializable.source);
|
||||
}
|
||||
if (aSerializable.target instanceof DownloadTarget) {
|
||||
download.target = aSerializable.target;
|
||||
} else {
|
||||
download.target = DownloadTarget.fromSerializable(aSerializable.target);
|
||||
}
|
||||
if ("saver" in aSerializable) {
|
||||
download.saver = DownloadSaver.fromSerializable(aSerializable.saver);
|
||||
} else {
|
||||
download.saver = DownloadSaver.fromSerializable("copy");
|
||||
}
|
||||
download.saver.download = download;
|
||||
return download;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -434,20 +510,20 @@ function DownloadSource() { }
|
|||
|
||||
DownloadSource.prototype = {
|
||||
/**
|
||||
* The nsIURI for the download source.
|
||||
* String containing the URI for the download source.
|
||||
*/
|
||||
uri: null,
|
||||
url: null,
|
||||
|
||||
/**
|
||||
* Indicates whether the download originated from a private window. This
|
||||
* determines the context of the network request that is made to retrieve the
|
||||
* determines the context of the network request that is made to retrieve the
|
||||
* resource.
|
||||
*/
|
||||
isPrivate: false,
|
||||
|
||||
/**
|
||||
* The nsIURI for the referrer of the download source, or null if no referrer
|
||||
* should be sent or the download source is not HTTP.
|
||||
* String containing the referrer URI of the download source, or null if no
|
||||
* referrer should be sent or the download source is not HTTP.
|
||||
*/
|
||||
referrer: null,
|
||||
|
||||
|
@ -456,19 +532,60 @@ DownloadSource.prototype = {
|
|||
*
|
||||
* @return A JavaScript object that can be serialized to JSON.
|
||||
*/
|
||||
serialize: function DS_serialize()
|
||||
toSerializable: function ()
|
||||
{
|
||||
let serialized = { uri: this.uri.spec };
|
||||
// Simplify the representation if we don't have other details.
|
||||
if (!this.isPrivate && !this.referrer) {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
let serializable = { url: this.url };
|
||||
if (this.isPrivate) {
|
||||
serialized.isPrivate = true;
|
||||
serializable.isPrivate = true;
|
||||
}
|
||||
if (this.referrer) {
|
||||
serialized.referrer = this.referrer.spec;
|
||||
serializable.referrer = this.referrer;
|
||||
}
|
||||
return serialized;
|
||||
return serializable;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new DownloadSource object from its serializable representation.
|
||||
*
|
||||
* @param aSerializable
|
||||
* Serializable representation of a DownloadSource object. This may be a
|
||||
* string containing the URI for the download source, an nsIURI, or an
|
||||
* object with the following properties:
|
||||
* {
|
||||
* url: String containing the URI for the download source.
|
||||
* isPrivate: Indicates whether the download originated from a private
|
||||
* window. If omitted, the download is public.
|
||||
* referrer: String containing the referrer URI of the download source.
|
||||
* Can be omitted or null if no referrer should be sent or
|
||||
* the download source is not HTTP.
|
||||
* }
|
||||
*
|
||||
* @return The newly created DownloadSource object.
|
||||
*/
|
||||
DownloadSource.fromSerializable = function (aSerializable) {
|
||||
let source = new DownloadSource();
|
||||
if (isString(aSerializable)) {
|
||||
source.url = aSerializable;
|
||||
} else if (aSerializable instanceof Ci.nsIURI) {
|
||||
source.url = aSerializable.spec;
|
||||
} else {
|
||||
source.url = aSerializable.url;
|
||||
if ("isPrivate" in aSerializable) {
|
||||
source.isPrivate = aSerializable.isPrivate;
|
||||
}
|
||||
if ("referrer" in aSerializable) {
|
||||
source.referrer = aSerializable.referrer;
|
||||
}
|
||||
}
|
||||
return source;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadTarget
|
||||
|
||||
|
@ -480,21 +597,50 @@ function DownloadTarget() { }
|
|||
|
||||
DownloadTarget.prototype = {
|
||||
/**
|
||||
* The nsIFile for the download target.
|
||||
* String containing the path of the target file.
|
||||
*/
|
||||
file: null,
|
||||
path: null,
|
||||
|
||||
/**
|
||||
* Returns a static representation of the current object state.
|
||||
*
|
||||
* @return A JavaScript object that can be serialized to JSON.
|
||||
*/
|
||||
serialize: function DT_serialize()
|
||||
toSerializable: function ()
|
||||
{
|
||||
return { file: this.file.path };
|
||||
// Simplify the representation since we don't have other details for now.
|
||||
return this.path;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new DownloadTarget object from its serializable representation.
|
||||
*
|
||||
* @param aSerializable
|
||||
* Serializable representation of a DownloadTarget object. This may be a
|
||||
* string containing the path of the target file, an nsIFile, or an
|
||||
* object with the following properties:
|
||||
* {
|
||||
* path: String containing the path of the target file.
|
||||
* }
|
||||
*
|
||||
* @return The newly created DownloadTarget object.
|
||||
*/
|
||||
DownloadTarget.fromSerializable = function (aSerializable) {
|
||||
let target = new DownloadTarget();
|
||||
if (isString(aSerializable)) {
|
||||
target.path = aSerializable;
|
||||
} else if (aSerializable instanceof Ci.nsIFile) {
|
||||
// Read the "path" property of nsIFile after checking the object type.
|
||||
target.path = aSerializable.path;
|
||||
} else {
|
||||
// Read the "path" property of the serializable DownloadTarget
|
||||
// representation.
|
||||
target.path = aSerializable.path;
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadError
|
||||
|
||||
|
@ -610,12 +756,39 @@ DownloadSaver.prototype = {
|
|||
*
|
||||
* @return A JavaScript object that can be serialized to JSON.
|
||||
*/
|
||||
serialize: function DS_serialize()
|
||||
toSerializable: function ()
|
||||
{
|
||||
throw new Error("Not implemented.");
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new DownloadSaver object from its serializable representation.
|
||||
*
|
||||
* @param aSerializable
|
||||
* Serializable representation of a DownloadSaver object. If no initial
|
||||
* state information for the saver object is needed, can be a string
|
||||
* representing the class of the download operation, for example "copy".
|
||||
*
|
||||
* @return The newly created DownloadSaver object.
|
||||
*/
|
||||
DownloadSaver.fromSerializable = function (aSerializable) {
|
||||
let serializable = isString(aSerializable) ? { type: aSerializable }
|
||||
: aSerializable;
|
||||
let saver;
|
||||
switch (serializable.type) {
|
||||
case "copy":
|
||||
saver = DownloadCopySaver.fromSerializable(serializable);
|
||||
break;
|
||||
case "legacy":
|
||||
saver = DownloadLegacySaver.fromSerializable(serializable);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unrecoginzed download saver type.");
|
||||
}
|
||||
return saver;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadCopySaver
|
||||
|
||||
|
@ -665,15 +838,16 @@ DownloadCopySaver.prototype = {
|
|||
};
|
||||
|
||||
// Set the target file, that will be deleted if the download fails.
|
||||
backgroundFileSaver.setTarget(download.target.file, false);
|
||||
backgroundFileSaver.setTarget(new FileUtils.File(download.target.path),
|
||||
false);
|
||||
|
||||
// Create a channel from the source, and listen to progress notifications.
|
||||
let channel = NetUtil.newChannel(download.source.uri);
|
||||
let channel = NetUtil.newChannel(NetUtil.newURI(download.source.url));
|
||||
if (channel instanceof Ci.nsIPrivateBrowsingChannel) {
|
||||
channel.setPrivate(download.source.isPrivate);
|
||||
}
|
||||
if (channel instanceof Ci.nsIHttpChannel) {
|
||||
channel.referrer = download.source.referrer;
|
||||
if (channel instanceof Ci.nsIHttpChannel && download.source.referrer) {
|
||||
channel.referrer = NetUtil.newURI(download.source.referrer);
|
||||
}
|
||||
|
||||
channel.notificationCallbacks = {
|
||||
|
@ -747,14 +921,29 @@ DownloadCopySaver.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Implements "DownloadSaver.serialize".
|
||||
* Implements "DownloadSaver.toSerializable".
|
||||
*/
|
||||
serialize: function DCS_serialize()
|
||||
toSerializable: function ()
|
||||
{
|
||||
return { type: "copy" };
|
||||
// Simplify the representation since we don't have other details for now.
|
||||
return "copy";
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new DownloadCopySaver object, with its initial state derived from
|
||||
* its serializable representation.
|
||||
*
|
||||
* @param aSerializable
|
||||
* Serializable representation of a DownloadCopySaver object.
|
||||
*
|
||||
* @return The newly created DownloadCopySaver object.
|
||||
*/
|
||||
DownloadCopySaver.fromSerializable = function (aSerializable) {
|
||||
// We don't have other state details for now.
|
||||
return new DownloadCopySaver();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadLegacySaver
|
||||
|
||||
|
@ -872,7 +1061,7 @@ DownloadLegacySaver.prototype = {
|
|||
// empty file is created as expected.
|
||||
try {
|
||||
// This atomic operation is more efficient than an existence check.
|
||||
let file = yield OS.File.open(this.download.target.file.path,
|
||||
let file = yield OS.File.open(this.download.target.path,
|
||||
{ create: true });
|
||||
yield file.close();
|
||||
} catch (ex if ex instanceof OS.File.Error && ex.becauseExists) { }
|
||||
|
@ -898,3 +1087,12 @@ DownloadLegacySaver.prototype = {
|
|||
"Download canceled."));
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a new DownloadLegacySaver object. This saver type has a
|
||||
* deserializable form only when creating a new object in memory, because it
|
||||
* cannot be serialized to disk.
|
||||
*/
|
||||
DownloadLegacySaver.fromSerializable = function () {
|
||||
return new DownloadLegacySaver();
|
||||
};
|
||||
|
|
|
@ -29,6 +29,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadStore",
|
|||
"resource://gre/modules/DownloadStore.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
|
@ -254,7 +256,8 @@ this.DownloadIntegration = {
|
|||
// Log the event if required by parental controls settings.
|
||||
if (isEnabled && gParentalControlsService.loggingEnabled) {
|
||||
gParentalControlsService.log(gParentalControlsService.ePCLog_FileDownload,
|
||||
shouldBlock, aDownload.source.uri, null);
|
||||
shouldBlock,
|
||||
NetUtil.newURI(aDownload.source.url), null);
|
||||
}
|
||||
|
||||
return Promise.resolve(shouldBlock);
|
||||
|
|
|
@ -161,9 +161,9 @@ DownloadLegacyTransfer.prototype = {
|
|||
// wait for it to be available. This operation may cause the entire
|
||||
// download system to initialize before the object is created.
|
||||
Downloads.createDownload({
|
||||
source: { uri: aSource, isPrivate: aIsPrivate },
|
||||
target: { file: aTarget.QueryInterface(Ci.nsIFileURL).file },
|
||||
saver: { type: "legacy" },
|
||||
source: { url: aSource.spec, isPrivate: aIsPrivate },
|
||||
target: aTarget.QueryInterface(Ci.nsIFileURL).file,
|
||||
saver: "legacy",
|
||||
}).then(function DLT_I_onDownload(aDownload) {
|
||||
// Now that the saver is available, hook up the cancellation handler.
|
||||
aDownload.saver.deferCanceled.promise.then(() => {
|
||||
|
|
|
@ -25,6 +25,8 @@ const Cr = Components.results;
|
|||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
|
@ -234,7 +236,8 @@ DownloadList.prototype = {
|
|||
//// nsINavHistoryObserver
|
||||
|
||||
onDeleteURI: function DL_onDeleteURI(aURI, aGUID) {
|
||||
this._removeWhere(download => aURI.equals(download.source.uri));
|
||||
this._removeWhere(download => aURI.equals(NetUtil.newURI(
|
||||
download.source.url)));
|
||||
},
|
||||
|
||||
onClearHistory: function DL_onClearHistory() {
|
||||
|
|
|
@ -7,6 +7,25 @@
|
|||
/**
|
||||
* Handles serialization of Download objects and persistence into a file, so
|
||||
* that the state of downloads can be restored across sessions.
|
||||
*
|
||||
* The file is stored in JSON format, without indentation. With indentation
|
||||
* applied, the file would look like this:
|
||||
*
|
||||
* {
|
||||
* "list": [
|
||||
* {
|
||||
* "source": "http://www.example.com/download.txt",
|
||||
* "target": "/home/user/Downloads/download.txt"
|
||||
* },
|
||||
* {
|
||||
* "source": {
|
||||
* "url": "http://www.example.com/download.txt",
|
||||
* "referrer": "http://www.example.com/referrer.html"
|
||||
* },
|
||||
* "target": "/home/user/Downloads/download-2.txt"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -27,16 +46,11 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm")
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
const LocalFile = Components.Constructor("@mozilla.org/file/local;1",
|
||||
"nsIFile", "initWithPath");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gTextDecoder", function () {
|
||||
return new TextDecoder();
|
||||
});
|
||||
|
@ -95,19 +109,9 @@ DownloadStore.prototype = {
|
|||
let storeData = JSON.parse(gTextDecoder.decode(bytes));
|
||||
|
||||
// Create live downloads based on the static snapshot.
|
||||
for (let downloadData of storeData) {
|
||||
for (let downloadData of storeData.list) {
|
||||
try {
|
||||
let source = { uri: NetUtil.newURI(downloadData.source.uri) };
|
||||
if ("referrer" in downloadData.source) {
|
||||
source.referrer = NetUtil.newURI(downloadData.source.referrer);
|
||||
}
|
||||
let download = yield Downloads.createDownload({
|
||||
source: source,
|
||||
target: { file: new LocalFile(downloadData.target.file) },
|
||||
saver: downloadData.saver,
|
||||
});
|
||||
|
||||
this.list.add(download);
|
||||
this.list.add(yield Downloads.createDownload(downloadData));
|
||||
} catch (ex) {
|
||||
// If an item is unrecognized, don't prevent others from being loaded.
|
||||
Cu.reportError(ex);
|
||||
|
@ -131,19 +135,15 @@ DownloadStore.prototype = {
|
|||
let downloads = yield this.list.getAll();
|
||||
|
||||
// Take a static snapshot of the current state of all the downloads.
|
||||
let storeData = [];
|
||||
let storeData = { list: [] };
|
||||
let atLeastOneDownload = false;
|
||||
for (let download of downloads) {
|
||||
try {
|
||||
storeData.push({
|
||||
source: download.source.serialize(),
|
||||
target: download.target.serialize(),
|
||||
saver: download.saver.serialize(),
|
||||
});
|
||||
storeData.list.push(download.toSerializable());
|
||||
atLeastOneDownload = true;
|
||||
} catch (ex) {
|
||||
// If an item cannot be serialized, don't prevent others from being
|
||||
// saved.
|
||||
// If an item cannot be converted to a serializable form, don't
|
||||
// prevent others from being saved.
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,14 +31,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadList",
|
|||
"resource://gre/modules/DownloadList.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUIHelper",
|
||||
"resource://gre/modules/DownloadUIHelper.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
|
@ -55,19 +49,29 @@ this.Downloads = {
|
|||
*
|
||||
* @param aProperties
|
||||
* Provides the initial properties for the newly created download.
|
||||
* This matches the serializable representation of a Download object.
|
||||
* Some of the most common properties in this object include:
|
||||
* {
|
||||
* source: {
|
||||
* uri: The nsIURI for the download source.
|
||||
* source: String containing the URI for the download source.
|
||||
* Alternatively, may be an nsIURI, a DownloadSource object,
|
||||
* or an object with the following properties:
|
||||
* {
|
||||
* url: String containing the URI for the download source.
|
||||
* isPrivate: Indicates whether the download originated from a
|
||||
* private window.
|
||||
* private window. If omitted, the download is public.
|
||||
* referrer: String containing the referrer URI of the download
|
||||
* source. Can be omitted or null if no referrer should
|
||||
* be sent or the download source is not HTTP.
|
||||
* },
|
||||
* target: {
|
||||
* file: The nsIFile for the download target.
|
||||
* },
|
||||
* saver: {
|
||||
* type: String representing the class of download operation
|
||||
* handled by this saver object, for example "copy".
|
||||
* target: String containing the path of the target file.
|
||||
* Alternatively, may be an nsIFile, a DownloadTarget object,
|
||||
* or an object with the following properties:
|
||||
* {
|
||||
* path: String containing the path of the target file.
|
||||
* },
|
||||
* saver: String representing the class of the download operation.
|
||||
* If omitted, defaults to "copy". Alternatively, may be the
|
||||
* serializable representation of a DownloadSaver object.
|
||||
* }
|
||||
*
|
||||
* @return {Promise}
|
||||
|
@ -76,31 +80,11 @@ this.Downloads = {
|
|||
*/
|
||||
createDownload: function D_createDownload(aProperties)
|
||||
{
|
||||
return Task.spawn(function task_D_createDownload() {
|
||||
let download = new Download();
|
||||
|
||||
download.source = new DownloadSource();
|
||||
download.source.uri = aProperties.source.uri;
|
||||
if ("isPrivate" in aProperties.source) {
|
||||
download.source.isPrivate = aProperties.source.isPrivate;
|
||||
}
|
||||
if ("referrer" in aProperties.source) {
|
||||
download.source.referrer = aProperties.source.referrer;
|
||||
}
|
||||
download.target = new DownloadTarget();
|
||||
download.target.file = aProperties.target.file;
|
||||
|
||||
// Support for different aProperties.saver values isn't implemented yet.
|
||||
download.saver = aProperties.saver.type == "legacy"
|
||||
? new DownloadLegacySaver()
|
||||
: new DownloadCopySaver();
|
||||
download.saver.download = download;
|
||||
|
||||
// This explicitly makes this function a generator for Task.jsm, so that
|
||||
// exceptions in the above calls can be reported asynchronously.
|
||||
yield;
|
||||
throw new Task.Result(download);
|
||||
});
|
||||
try {
|
||||
return Promise.resolve(Download.fromSerializable(aProperties));
|
||||
} catch (ex) {
|
||||
return Promise.reject(ex);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -111,15 +95,17 @@ this.Downloads = {
|
|||
* reference to a Download object using the createDownload function.
|
||||
*
|
||||
* @param aSource
|
||||
* The nsIURI or string containing the URI spec for the download
|
||||
* source, or alternative DownloadSource.
|
||||
* String containing the URI for the download source. Alternatively,
|
||||
* may be an nsIURI or a DownloadSource object.
|
||||
* @param aTarget
|
||||
* The nsIFile or string containing the file path, or alternative
|
||||
* DownloadTarget.
|
||||
* String containing the path of the target file. Alternatively, may
|
||||
* be an nsIFile or a DownloadTarget object.
|
||||
* @param aOptions
|
||||
* The object contains different additional options or null.
|
||||
* { isPrivate: Indicates whether the download originated from a
|
||||
* private window.
|
||||
* An optional object used to control the behavior of this function.
|
||||
* You may pass an object with a subset of the following fields:
|
||||
* {
|
||||
* isPrivate: Indicates whether the download originated from a
|
||||
* private window.
|
||||
* }
|
||||
*
|
||||
* @return {Promise}
|
||||
|
@ -127,31 +113,13 @@ this.Downloads = {
|
|||
* @rejects JavaScript exception if the download failed.
|
||||
*/
|
||||
simpleDownload: function D_simpleDownload(aSource, aTarget, aOptions) {
|
||||
// Wrap the arguments into simple objects resembling DownloadSource and
|
||||
// DownloadTarget, if they are not objects of that type already.
|
||||
if (aSource instanceof Ci.nsIURI) {
|
||||
aSource = { uri: aSource };
|
||||
} else if (typeof aSource == "string" ||
|
||||
(typeof aSource == "object" && "charAt" in aSource)) {
|
||||
aSource = { uri: NetUtil.newURI(aSource) };
|
||||
}
|
||||
|
||||
if (aSource && aOptions && ("isPrivate" in aOptions)) {
|
||||
aSource.isPrivate = aOptions.isPrivate;
|
||||
}
|
||||
if (aTarget instanceof Ci.nsIFile) {
|
||||
aTarget = { file: aTarget };
|
||||
} else if (typeof aTarget == "string" ||
|
||||
(typeof aTarget == "object" && "charAt" in aTarget)) {
|
||||
aTarget = { file: new FileUtils.File(aTarget) };
|
||||
}
|
||||
|
||||
// Create and start the actual download.
|
||||
return this.createDownload({
|
||||
source: aSource,
|
||||
target: aTarget,
|
||||
saver: { type: "copy" },
|
||||
}).then(function D_SD_onSuccess(aDownload) {
|
||||
if (aOptions && ("isPrivate" in aOptions)) {
|
||||
aDownload.source.isPrivate = aOptions.isPrivate;
|
||||
}
|
||||
return aDownload.start();
|
||||
});
|
||||
},
|
||||
|
|
|
@ -51,51 +51,11 @@ const BinaryOutputStream = Components.Constructor(
|
|||
"nsIBinaryOutputStream",
|
||||
"setOutputStream")
|
||||
|
||||
Object.defineProperty(this, "HTTP_BASE", {get: function() {
|
||||
return "http://localhost:" + gHttpServer.identity.primaryPort;
|
||||
}});
|
||||
|
||||
Object.defineProperty(this, "FAKE_BASE", {get: function() {
|
||||
return "http://localhost:" + gFakeServerPort;
|
||||
}});
|
||||
|
||||
Object.defineProperty(this, "TEST_REFERRER_URI", {get: function() {
|
||||
return NetUtil.newURI(HTTP_BASE + "/referrer.html");
|
||||
}});
|
||||
|
||||
Object.defineProperty(this, "TEST_SOURCE_URI", {get: function() {
|
||||
return NetUtil.newURI(HTTP_BASE + "/source.txt");
|
||||
}});
|
||||
|
||||
Object.defineProperty(this, "TEST_EMPTY_URI", {get: function() {
|
||||
return NetUtil.newURI(HTTP_BASE + "/empty.txt");
|
||||
}});
|
||||
|
||||
Object.defineProperty(this, "TEST_FAKE_SOURCE_URI", {get: function() {
|
||||
return NetUtil.newURI(FAKE_BASE + "/source.txt");
|
||||
}});
|
||||
|
||||
const TEST_EMPTY_NOPROGRESS_PATH = "/empty-noprogress.txt";
|
||||
|
||||
Object.defineProperty(this, "TEST_EMPTY_NOPROGRESS_URI", {get: function() {
|
||||
return NetUtil.newURI(HTTP_BASE + TEST_EMPTY_NOPROGRESS_PATH);
|
||||
}});
|
||||
|
||||
const TEST_INTERRUPTIBLE_PATH = "/interruptible.txt";
|
||||
|
||||
Object.defineProperty(this, "TEST_INTERRUPTIBLE_URI", {get: function() {
|
||||
return NetUtil.newURI(HTTP_BASE + TEST_INTERRUPTIBLE_PATH);
|
||||
}});
|
||||
|
||||
const TEST_INTERRUPTIBLE_GZIP_PATH = "/interruptible_gzip.txt";
|
||||
|
||||
Object.defineProperty(this, "TEST_INTERRUPTIBLE_GZIP_URI", {get: function() {
|
||||
return NetUtil.newURI(HTTP_BASE + TEST_INTERRUPTIBLE_GZIP_PATH);
|
||||
}});
|
||||
|
||||
const TEST_TARGET_FILE_NAME = "test-download.txt";
|
||||
const TEST_STORE_FILE_NAME = "test-downloads.json";
|
||||
|
||||
const TEST_REFERRER_URL = "http://www.example.com/referrer.html";
|
||||
|
||||
const TEST_DATA_SHORT = "This test string is downloaded.";
|
||||
// Generate using gzipCompressString in TelemetryPing.js.
|
||||
const TEST_DATA_SHORT_GZIP_ENCODED_FIRST = [
|
||||
|
@ -119,6 +79,20 @@ function run_test()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Support functions
|
||||
|
||||
/**
|
||||
* HttpServer object initialized before tests start.
|
||||
*/
|
||||
let gHttpServer;
|
||||
|
||||
/**
|
||||
* Given a file name, returns a string containing an URI that points to the file
|
||||
* on the currently running instance of the test HTTP server.
|
||||
*/
|
||||
function httpUrl(aFileName) {
|
||||
return "http://localhost:" + gHttpServer.identity.primaryPort + "/" +
|
||||
aFileName;
|
||||
}
|
||||
|
||||
// While the previous test file should have deleted all the temporary files it
|
||||
// used, on Windows these might still be pending deletion on the physical file
|
||||
// system. Thus, start from a new base number every time, to make a collision
|
||||
|
@ -190,18 +164,18 @@ function promiseTimeout(aTime)
|
|||
/**
|
||||
* Creates a new Download object, setting a temporary file as the target.
|
||||
*
|
||||
* @param aSourceURI
|
||||
* The nsIURI for the download source, or null to use TEST_SOURCE_URI.
|
||||
* @param aSourceUrl
|
||||
* String containing the URI for the download source, or null to use
|
||||
* httpUrl("source.txt").
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves The newly created Download object.
|
||||
* @rejects JavaScript exception.
|
||||
*/
|
||||
function promiseSimpleDownload(aSourceURI) {
|
||||
function promiseSimpleDownload(aSourceUrl) {
|
||||
return Downloads.createDownload({
|
||||
source: { uri: aSourceURI || TEST_SOURCE_URI },
|
||||
target: { file: getTempFile(TEST_TARGET_FILE_NAME) },
|
||||
saver: { type: "copy" },
|
||||
source: aSourceUrl || httpUrl("source.txt"),
|
||||
target: getTempFile(TEST_TARGET_FILE_NAME),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -234,8 +208,9 @@ function promiseNewPrivateDownloadList() {
|
|||
/**
|
||||
* Ensures that the given file contents are equal to the given string.
|
||||
*
|
||||
* @param aFile
|
||||
* nsIFile whose contents should be verified.
|
||||
* @param aPath
|
||||
* String containing the path of the file whose contents should be
|
||||
* verified.
|
||||
* @param aExpectedContents
|
||||
* String containing the octets that are expected in the file.
|
||||
*
|
||||
|
@ -243,10 +218,11 @@ function promiseNewPrivateDownloadList() {
|
|||
* @resolves When the operation completes.
|
||||
* @rejects Never.
|
||||
*/
|
||||
function promiseVerifyContents(aFile, aExpectedContents)
|
||||
function promiseVerifyContents(aPath, aExpectedContents)
|
||||
{
|
||||
let deferred = Promise.defer();
|
||||
NetUtil.asyncFetch(aFile, function(aInputStream, aStatus) {
|
||||
let file = new FileUtils.File(aPath);
|
||||
NetUtil.asyncFetch(file, function(aInputStream, aStatus) {
|
||||
do_check_true(Components.isSuccessCode(aStatus));
|
||||
let contents = NetUtil.readInputStreamToString(aInputStream,
|
||||
aInputStream.available());
|
||||
|
@ -265,17 +241,18 @@ function promiseVerifyContents(aFile, aExpectedContents)
|
|||
/**
|
||||
* Adds entry for download.
|
||||
*
|
||||
* @param aSourceURI
|
||||
* The nsIURI for the download source, or null to use TEST_SOURCE_URI.
|
||||
* @param aSourceUrl
|
||||
* String containing the URI for the download source, or null to use
|
||||
* httpUrl("source.txt").
|
||||
*
|
||||
* @return {Promise}
|
||||
* @rejects JavaScript exception.
|
||||
*/
|
||||
function promiseAddDownloadToHistory(aSourceURI) {
|
||||
function promiseAddDownloadToHistory(aSourceUrl) {
|
||||
let deferred = Promise.defer();
|
||||
PlacesUtils.asyncHistory.updatePlaces(
|
||||
{
|
||||
uri: aSourceURI || TEST_SOURCE_URI,
|
||||
uri: NetUtil.newURI(aSourceUrl || httpUrl("source.txt")),
|
||||
visits: [{
|
||||
transitionType: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,
|
||||
visitDate: Date.now()
|
||||
|
@ -304,7 +281,6 @@ function promiseAddDownloadToHistory(aSourceURI) {
|
|||
function startFakeServer()
|
||||
{
|
||||
let serverSocket = new ServerSocket(-1, true, -1);
|
||||
gFakeServerPort = serverSocket.port;
|
||||
serverSocket.asyncListen({
|
||||
onSocketAccepted: function (aServ, aTransport) {
|
||||
aTransport.close(Cr.NS_BINDING_ABORTED);
|
||||
|
@ -326,10 +302,10 @@ function startFakeServer()
|
|||
* handlers, you may call "deferNextResponse" to get a reference to an object
|
||||
* that allows you to control the next request.
|
||||
*
|
||||
* For example, the handler accessible at the TEST_INTERRUPTIBLE_URI address
|
||||
* returns the TEST_DATA_SHORT text, then waits until the "resolve" method is
|
||||
* called on the object returned by the function. At this point, the handler
|
||||
* sends the TEST_DATA_SHORT text again to complete the response.
|
||||
* For example, the handler accessible at the httpUri("interruptible.txt")
|
||||
* address returns the TEST_DATA_SHORT text, then waits until the "resolve"
|
||||
* method is called on the object returned by the function. At this point, the
|
||||
* handler sends the TEST_DATA_SHORT text again to complete the response.
|
||||
*
|
||||
* You can also call the "reject" method on the returned object to interrupt the
|
||||
* response midway. Because of how the network layer is implemented, this does
|
||||
|
@ -429,9 +405,6 @@ function isValidDate(aDate) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Initialization functions common to all tests
|
||||
|
||||
let gHttpServer;
|
||||
let gFakeServerPort;
|
||||
|
||||
add_task(function test_common_initialize()
|
||||
{
|
||||
// Start the HTTP server.
|
||||
|
@ -439,7 +412,7 @@ add_task(function test_common_initialize()
|
|||
gHttpServer.registerDirectory("/", do_get_file("../data"));
|
||||
gHttpServer.start(-1);
|
||||
|
||||
registerInterruptibleHandler(TEST_INTERRUPTIBLE_PATH,
|
||||
registerInterruptibleHandler("/interruptible.txt",
|
||||
function firstPart(aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
aResponse.setHeader("Content-Length", "" + (TEST_DATA_SHORT.length * 2),
|
||||
|
@ -449,13 +422,13 @@ add_task(function test_common_initialize()
|
|||
aResponse.write(TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
registerInterruptibleHandler(TEST_EMPTY_NOPROGRESS_PATH,
|
||||
registerInterruptibleHandler("/empty-noprogress.txt",
|
||||
function firstPart(aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
}, function secondPart(aRequest, aResponse) { });
|
||||
|
||||
|
||||
registerInterruptibleHandler(TEST_INTERRUPTIBLE_GZIP_PATH,
|
||||
registerInterruptibleHandler("/interruptible_gzip.txt",
|
||||
function firstPart(aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
aResponse.setHeader("Content-Encoding", "gzip", false);
|
||||
|
|
|
@ -17,23 +17,23 @@
|
|||
*/
|
||||
add_task(function test_download_construction()
|
||||
{
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
|
||||
let download = yield Downloads.createDownload({
|
||||
source: { uri: TEST_SOURCE_URI },
|
||||
target: { file: targetFile },
|
||||
source: { url: httpUrl("source.txt") },
|
||||
target: { path: targetPath },
|
||||
saver: { type: "copy" },
|
||||
});
|
||||
|
||||
// Checks the generated DownloadSource and DownloadTarget properties.
|
||||
do_check_true(download.source.uri.equals(TEST_SOURCE_URI));
|
||||
do_check_eq(download.target.file, targetFile);
|
||||
do_check_eq(download.source.url, httpUrl("source.txt"));
|
||||
do_check_eq(download.target.path, targetPath);
|
||||
do_check_true(download.source.referrer === null);
|
||||
|
||||
// Starts the download and waits for completion.
|
||||
yield download.start();
|
||||
|
||||
yield promiseVerifyContents(targetFile, TEST_DATA_SHORT);
|
||||
yield promiseVerifyContents(targetPath, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -41,46 +41,44 @@ add_task(function test_download_construction()
|
|||
*/
|
||||
add_task(function test_download_referrer()
|
||||
{
|
||||
let source_path = "/test_download_referrer.txt";
|
||||
let source_uri = NetUtil.newURI(HTTP_BASE + source_path);
|
||||
let target_uri = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
let sourcePath = "/test_download_referrer.txt";
|
||||
let sourceUrl = httpUrl("test_download_referrer.txt");
|
||||
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
|
||||
function cleanup() {
|
||||
gHttpServer.registerPathHandler(source_path, null);
|
||||
gHttpServer.registerPathHandler(sourcePath, null);
|
||||
}
|
||||
|
||||
do_register_cleanup(cleanup);
|
||||
|
||||
gHttpServer.registerPathHandler(source_path, function (aRequest, aResponse) {
|
||||
gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
do_check_true(aRequest.hasHeader("Referer"));
|
||||
do_check_eq(aRequest.getHeader("Referer"), TEST_REFERRER_URI.spec);
|
||||
do_check_eq(aRequest.getHeader("Referer"), TEST_REFERRER_URL);
|
||||
});
|
||||
let download = yield Downloads.createDownload({
|
||||
source: { uri: source_uri, referrer: TEST_REFERRER_URI },
|
||||
target: { file: target_uri },
|
||||
saver: { type: "copy" },
|
||||
source: { url: sourceUrl, referrer: TEST_REFERRER_URL },
|
||||
target: targetPath,
|
||||
});
|
||||
do_check_true(download.source.referrer.equals(TEST_REFERRER_URI));
|
||||
do_check_eq(download.source.referrer, TEST_REFERRER_URL);
|
||||
yield download.start();
|
||||
|
||||
download = yield Downloads.createDownload({
|
||||
source: { uri: source_uri, referrer: TEST_REFERRER_URI, isPrivate: true },
|
||||
target: { file: target_uri },
|
||||
saver: { type: "copy" },
|
||||
source: { url: sourceUrl, referrer: TEST_REFERRER_URL,
|
||||
isPrivate: true },
|
||||
target: targetPath,
|
||||
});
|
||||
do_check_true(download.source.referrer.equals(TEST_REFERRER_URI));
|
||||
do_check_eq(download.source.referrer, TEST_REFERRER_URL);
|
||||
yield download.start();
|
||||
|
||||
// Test the download still works for non-HTTP channel with referrer.
|
||||
source_uri = NetUtil.newURI("data:text/html,<html><body></body></html>");
|
||||
sourceUrl = "data:text/html,<html><body></body></html>";
|
||||
download = yield Downloads.createDownload({
|
||||
source: { uri: source_uri, referrer: TEST_REFERRER_URI },
|
||||
target: { file: target_uri },
|
||||
saver: { type: "copy" },
|
||||
source: { url: sourceUrl, referrer: TEST_REFERRER_URL },
|
||||
target: targetPath,
|
||||
});
|
||||
do_check_true(download.source.referrer.equals(TEST_REFERRER_URI));
|
||||
do_check_eq(download.source.referrer, TEST_REFERRER_URL);
|
||||
yield download.start();
|
||||
|
||||
cleanup();
|
||||
|
@ -143,7 +141,7 @@ add_task(function test_download_intermediate_progress()
|
|||
{
|
||||
let deferResponse = deferNextResponse();
|
||||
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
download.onchange = function () {
|
||||
if (download.progress == 50) {
|
||||
|
@ -162,7 +160,7 @@ add_task(function test_download_intermediate_progress()
|
|||
do_check_true(download.stopped);
|
||||
do_check_eq(download.progress, 100);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -171,7 +169,7 @@ add_task(function test_download_intermediate_progress()
|
|||
*/
|
||||
add_task(function test_download_empty_progress()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_EMPTY_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("empty.txt"));
|
||||
|
||||
yield download.start();
|
||||
|
||||
|
@ -181,7 +179,7 @@ add_task(function test_download_empty_progress()
|
|||
do_check_eq(download.currentBytes, 0);
|
||||
do_check_eq(download.totalBytes, 0);
|
||||
|
||||
do_check_eq(download.target.file.fileSize, 0);
|
||||
do_check_eq((yield OS.File.stat(download.target.path)).size, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -192,7 +190,7 @@ add_task(function test_download_empty_noprogress()
|
|||
let deferResponse = deferNextResponse();
|
||||
let promiseEmptyRequestReceived = promiseNextRequestReceived();
|
||||
|
||||
let download = yield promiseSimpleDownload(TEST_EMPTY_NOPROGRESS_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("empty-noprogress.txt"));
|
||||
|
||||
download.onchange = function () {
|
||||
if (!download.stopped) {
|
||||
|
@ -228,7 +226,7 @@ add_task(function test_download_empty_noprogress()
|
|||
do_check_eq(download.currentBytes, 0);
|
||||
do_check_eq(download.totalBytes, 0);
|
||||
|
||||
do_check_eq(download.target.file.fileSize, 0);
|
||||
do_check_eq((yield OS.File.stat(download.target.path)).size, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -236,7 +234,7 @@ add_task(function test_download_empty_noprogress()
|
|||
*/
|
||||
add_task(function test_download_start_twice()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
// Ensure that the download cannot complete before start is called twice.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -257,7 +255,7 @@ add_task(function test_download_start_twice()
|
|||
do_check_false(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -266,7 +264,7 @@ add_task(function test_download_start_twice()
|
|||
*/
|
||||
add_task(function test_download_cancel_midway()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
let deferResponse = deferNextResponse();
|
||||
try {
|
||||
|
@ -292,7 +290,7 @@ add_task(function test_download_cancel_midway()
|
|||
do_check_true(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
do_check_false(download.target.file.exists());
|
||||
do_check_false(yield OS.File.exists(download.target.path));
|
||||
|
||||
// Progress properties are not reset by canceling.
|
||||
do_check_eq(download.progress, 50);
|
||||
|
@ -320,7 +318,7 @@ add_task(function test_download_cancel_immediately()
|
|||
// Ensure that the download cannot complete before cancel is called.
|
||||
let deferResponse = deferNextResponse();
|
||||
try {
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
let promiseAttempt = download.start();
|
||||
do_check_false(download.stopped);
|
||||
|
@ -343,7 +341,7 @@ add_task(function test_download_cancel_immediately()
|
|||
do_check_true(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
do_check_false(download.target.file.exists());
|
||||
do_check_false(yield OS.File.exists(download.target.path));
|
||||
|
||||
// Check that the promise returned by the "cancel" method has been resolved.
|
||||
yield promiseCancel;
|
||||
|
@ -365,7 +363,7 @@ add_task(function test_download_cancel_immediately()
|
|||
*/
|
||||
add_task(function test_download_cancel_midway_restart()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
// The first time, cancel the download midway.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -407,7 +405,7 @@ add_task(function test_download_cancel_midway_restart()
|
|||
do_check_false(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -416,7 +414,7 @@ add_task(function test_download_cancel_midway_restart()
|
|||
*/
|
||||
add_task(function test_download_cancel_immediately_restart_immediately()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
// Ensure that the download cannot complete before cancel is called.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -467,7 +465,7 @@ add_task(function test_download_cancel_immediately_restart_immediately()
|
|||
do_check_false(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -476,7 +474,7 @@ add_task(function test_download_cancel_immediately_restart_immediately()
|
|||
*/
|
||||
add_task(function test_download_cancel_midway_restart_immediately()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
// The first time, cancel the download midway.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -525,7 +523,7 @@ add_task(function test_download_cancel_midway_restart_immediately()
|
|||
do_check_false(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -547,7 +545,7 @@ add_task(function test_download_cancel_successful()
|
|||
do_check_false(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
yield promiseVerifyContents(download.target.file, TEST_DATA_SHORT);
|
||||
yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -555,7 +553,7 @@ add_task(function test_download_cancel_successful()
|
|||
*/
|
||||
add_task(function test_download_cancel_twice()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
// Ensure that the download cannot complete before cancel is called.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -584,7 +582,7 @@ add_task(function test_download_cancel_twice()
|
|||
do_check_true(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
do_check_false(download.target.file.exists());
|
||||
do_check_false(yield OS.File.exists(download.target.path));
|
||||
} finally {
|
||||
deferResponse.resolve();
|
||||
}
|
||||
|
@ -595,7 +593,7 @@ add_task(function test_download_cancel_twice()
|
|||
*/
|
||||
add_task(function test_download_whenSucceeded()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
// Ensure that the download cannot complete before cancel is called.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -620,7 +618,7 @@ add_task(function test_download_whenSucceeded()
|
|||
do_check_false(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -631,7 +629,9 @@ add_task(function test_download_error_source()
|
|||
{
|
||||
let serverSocket = startFakeServer();
|
||||
try {
|
||||
let download = yield promiseSimpleDownload(TEST_FAKE_SOURCE_URI);
|
||||
let sourceUrl = "http://localhost:" + serverSocket.port + "/source.txt";
|
||||
|
||||
let download = yield promiseSimpleDownload(sourceUrl);
|
||||
|
||||
do_check_true(download.error === null);
|
||||
|
||||
|
@ -662,7 +662,8 @@ add_task(function test_download_error_target()
|
|||
do_check_true(download.error === null);
|
||||
|
||||
// Create a file without write access permissions before downloading.
|
||||
download.target.file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0);
|
||||
let targetFile = new FileUtils.File(download.target.path);
|
||||
targetFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0);
|
||||
try {
|
||||
try {
|
||||
yield download.start();
|
||||
|
@ -678,9 +679,9 @@ add_task(function test_download_error_target()
|
|||
do_check_false(download.error.becauseSourceFailed);
|
||||
} finally {
|
||||
// Restore the default permissions to allow deleting the file on Windows.
|
||||
if (download.target.file.exists()) {
|
||||
download.target.file.permissions = FileUtils.PERMS_FILE;
|
||||
download.target.file.remove(false);
|
||||
if (targetFile.exists()) {
|
||||
targetFile.permissions = FileUtils.PERMS_FILE;
|
||||
targetFile.remove(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -695,7 +696,8 @@ add_task(function test_download_error_restart()
|
|||
do_check_true(download.error === null);
|
||||
|
||||
// Create a file without write access permissions before downloading.
|
||||
download.target.file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0);
|
||||
let targetFile = new FileUtils.File(download.target.path);
|
||||
targetFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0);
|
||||
|
||||
try {
|
||||
yield download.start();
|
||||
|
@ -704,15 +706,14 @@ add_task(function test_download_error_restart()
|
|||
// A specific error object is thrown when writing to the target fails.
|
||||
} finally {
|
||||
// Restore the default permissions to allow deleting the file on Windows.
|
||||
if (download.target.file.exists()) {
|
||||
download.target.file.permissions = FileUtils.PERMS_FILE;
|
||||
if (targetFile.exists()) {
|
||||
targetFile.permissions = FileUtils.PERMS_FILE;
|
||||
|
||||
// Also for Windows, rename the file before deleting. This makes the
|
||||
// current file name available immediately for a new file, while deleting
|
||||
// in place prevents creation of a file with the same name for some time.
|
||||
let fileToRemove = download.target.file.clone();
|
||||
fileToRemove.moveTo(null, fileToRemove.leafName + ".delete.tmp");
|
||||
fileToRemove.remove(false);
|
||||
targetFile.moveTo(null, targetFile.leafName + ".delete.tmp");
|
||||
targetFile.remove(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,7 +726,7 @@ add_task(function test_download_error_restart()
|
|||
do_check_true(download.error === null);
|
||||
do_check_eq(download.progress, 100);
|
||||
|
||||
yield promiseVerifyContents(download.target.file, TEST_DATA_SHORT);
|
||||
yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -733,8 +734,8 @@ add_task(function test_download_error_restart()
|
|||
*/
|
||||
add_task(function test_download_public_and_private()
|
||||
{
|
||||
let source_path = "/test_download_public_and_private.txt";
|
||||
let source_uri = NetUtil.newURI(HTTP_BASE + source_path);
|
||||
let sourcePath = "/test_download_public_and_private.txt";
|
||||
let sourceUrl = httpUrl("test_download_public_and_private.txt");
|
||||
let testCount = 0;
|
||||
|
||||
// Apply pref to allow all cookies.
|
||||
|
@ -743,11 +744,11 @@ add_task(function test_download_public_and_private()
|
|||
function cleanup() {
|
||||
Services.prefs.clearUserPref("network.cookie.cookieBehavior");
|
||||
Services.cookies.removeAll();
|
||||
gHttpServer.registerPathHandler(source_path, null);
|
||||
gHttpServer.registerPathHandler(sourcePath, null);
|
||||
}
|
||||
do_register_cleanup(cleanup);
|
||||
|
||||
gHttpServer.registerPathHandler(source_path, function (aRequest, aResponse) {
|
||||
gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
if (testCount == 0) {
|
||||
|
@ -767,12 +768,11 @@ add_task(function test_download_public_and_private()
|
|||
});
|
||||
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
yield Downloads.simpleDownload(source_uri, targetFile);
|
||||
yield Downloads.simpleDownload(source_uri, targetFile);
|
||||
yield Downloads.simpleDownload(sourceUrl, targetFile);
|
||||
yield Downloads.simpleDownload(sourceUrl, targetFile);
|
||||
let download = yield Downloads.createDownload({
|
||||
source: { uri: source_uri, isPrivate: true },
|
||||
target: { file: targetFile },
|
||||
saver: { type: "copy" },
|
||||
source: { url: sourceUrl, isPrivate: true },
|
||||
target: targetFile,
|
||||
});
|
||||
yield download.start();
|
||||
|
||||
|
@ -805,15 +805,15 @@ add_task(function test_download_cancel_immediately_restart_and_check_startTime()
|
|||
*/
|
||||
add_task(function test_download_with_content_encoding()
|
||||
{
|
||||
let source_path = "/test_download_with_content_encoding.txt";
|
||||
let source_uri = NetUtil.newURI(HTTP_BASE + source_path);
|
||||
let sourcePath = "/test_download_with_content_encoding.txt";
|
||||
let sourceUrl = httpUrl("test_download_with_content_encoding.txt");
|
||||
|
||||
function cleanup() {
|
||||
gHttpServer.registerPathHandler(source_path, null);
|
||||
gHttpServer.registerPathHandler(sourcePath, null);
|
||||
}
|
||||
do_register_cleanup(cleanup);
|
||||
|
||||
gHttpServer.registerPathHandler(source_path, function (aRequest, aResponse) {
|
||||
gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
aResponse.setHeader("Content-Encoding", "gzip", false);
|
||||
aResponse.setHeader("Content-Length",
|
||||
|
@ -825,9 +825,8 @@ add_task(function test_download_with_content_encoding()
|
|||
});
|
||||
|
||||
let download = yield Downloads.createDownload({
|
||||
source: { uri: source_uri },
|
||||
target: { file: getTempFile(TEST_TARGET_FILE_NAME) },
|
||||
saver: { type: "copy" },
|
||||
source: sourceUrl,
|
||||
target: getTempFile(TEST_TARGET_FILE_NAME),
|
||||
});
|
||||
yield download.start();
|
||||
|
||||
|
@ -835,7 +834,7 @@ add_task(function test_download_with_content_encoding()
|
|||
do_check_eq(download.totalBytes, TEST_DATA_SHORT_GZIP_ENCODED.length);
|
||||
|
||||
// Ensure the content matches the decoded test data.
|
||||
yield promiseVerifyContents(download.target.file, TEST_DATA_SHORT);
|
||||
yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -843,7 +842,7 @@ add_task(function test_download_with_content_encoding()
|
|||
*/
|
||||
add_task(function test_download_cancel_midway_restart_with_content_encoding()
|
||||
{
|
||||
let download = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_GZIP_URI);
|
||||
let download = yield promiseSimpleDownload(httpUrl("interruptible_gzip.txt"));
|
||||
|
||||
// The first time, cancel the download midway.
|
||||
let deferResponse = deferNextResponse();
|
||||
|
@ -870,7 +869,7 @@ add_task(function test_download_cancel_midway_restart_with_content_encoding()
|
|||
do_check_eq(download.progress, 100);
|
||||
do_check_eq(download.totalBytes, TEST_DATA_SHORT_GZIP_ENCODED.length);
|
||||
|
||||
yield promiseVerifyContents(download.target.file, TEST_DATA_SHORT);
|
||||
yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
* Starts a new download using the nsIWebBrowserPersist interface, and controls
|
||||
* it using the legacy nsITransfer interface.
|
||||
*
|
||||
* @param aSourceURI
|
||||
* The nsIURI for the download source, or null to use TEST_SOURCE_URI.
|
||||
* @param aSourceUrl
|
||||
* String containing the URI for the download source, or null to use
|
||||
* httpUrl("source.txt").
|
||||
* @param isPrivate
|
||||
* Optional boolean indicates whether the download originated from a
|
||||
* private window.
|
||||
|
@ -30,8 +31,8 @@
|
|||
* download through the legacy nsITransfer interface.
|
||||
* @rejects Never. The current test fails in case of exceptions.
|
||||
*/
|
||||
function promiseStartLegacyDownload(aSourceURI, aIsPrivate, aOutPersist) {
|
||||
let sourceURI = aSourceURI || TEST_SOURCE_URI;
|
||||
function promiseStartLegacyDownload(aSourceUrl, aIsPrivate, aOutPersist) {
|
||||
let sourceURI = NetUtil.newURI(aSourceUrl || httpUrl("source.txt"));
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
|
||||
let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
||||
|
@ -94,15 +95,16 @@ add_task(function test_basic()
|
|||
let download = yield promiseStartLegacyDownload();
|
||||
|
||||
// Checks the generated DownloadSource and DownloadTarget properties.
|
||||
do_check_true(download.source.uri.equals(TEST_SOURCE_URI));
|
||||
do_check_true(download.target.file.parent.equals(tempDirectory));
|
||||
do_check_eq(download.source.url, httpUrl("source.txt"));
|
||||
do_check_true(new FileUtils.File(download.target.path).parent
|
||||
.equals(tempDirectory));
|
||||
|
||||
// The download is already started, wait for completion and report any errors.
|
||||
if (!download.stopped) {
|
||||
yield download.start();
|
||||
}
|
||||
|
||||
yield promiseVerifyContents(download.target.file, TEST_DATA_SHORT);
|
||||
yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -131,7 +133,7 @@ add_task(function test_intermediate_progress()
|
|||
{
|
||||
let deferResponse = deferNextResponse();
|
||||
|
||||
let download = yield promiseStartLegacyDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let download = yield promiseStartLegacyDownload(httpUrl("interruptible.txt"));
|
||||
|
||||
let onchange = function () {
|
||||
if (download.progress == 50) {
|
||||
|
@ -157,7 +159,7 @@ add_task(function test_intermediate_progress()
|
|||
do_check_true(download.stopped);
|
||||
do_check_eq(download.progress, 100);
|
||||
|
||||
yield promiseVerifyContents(download.target.file,
|
||||
yield promiseVerifyContents(download.target.path,
|
||||
TEST_DATA_SHORT + TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
|
@ -166,7 +168,7 @@ add_task(function test_intermediate_progress()
|
|||
*/
|
||||
add_task(function test_empty_progress()
|
||||
{
|
||||
let download = yield promiseStartLegacyDownload(TEST_EMPTY_URI);
|
||||
let download = yield promiseStartLegacyDownload(httpUrl("empty.txt"));
|
||||
|
||||
// The download is already started, wait for completion and report any errors.
|
||||
if (!download.stopped) {
|
||||
|
@ -179,7 +181,7 @@ add_task(function test_empty_progress()
|
|||
do_check_eq(download.currentBytes, 0);
|
||||
do_check_eq(download.totalBytes, 0);
|
||||
|
||||
do_check_eq(download.target.file.fileSize, 0);
|
||||
do_check_eq((yield OS.File.stat(download.target.path)).size, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -190,7 +192,8 @@ add_task(function test_empty_noprogress()
|
|||
let deferResponse = deferNextResponse();
|
||||
let promiseEmptyRequestReceived = promiseNextRequestReceived();
|
||||
|
||||
let download = yield promiseStartLegacyDownload(TEST_EMPTY_NOPROGRESS_URI);
|
||||
let download = yield promiseStartLegacyDownload(
|
||||
httpUrl("empty-noprogress.txt"));
|
||||
|
||||
// Wait for the request to be received by the HTTP server, but don't allow the
|
||||
// request to finish yet. Before checking the download state, wait for the
|
||||
|
@ -218,7 +221,7 @@ add_task(function test_empty_noprogress()
|
|||
do_check_eq(download.currentBytes, 0);
|
||||
do_check_eq(download.totalBytes, 0);
|
||||
|
||||
do_check_eq(download.target.file.fileSize, 0);
|
||||
do_check_eq((yield OS.File.stat(download.target.path)).size, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -228,8 +231,8 @@ add_task(function test_cancel_midway()
|
|||
{
|
||||
let deferResponse = deferNextResponse();
|
||||
let outPersist = {};
|
||||
let download = yield promiseStartLegacyDownload(TEST_INTERRUPTIBLE_URI, false,
|
||||
outPersist);
|
||||
let download = yield promiseStartLegacyDownload(httpUrl("interruptible.txt"),
|
||||
false, outPersist);
|
||||
|
||||
try {
|
||||
// Cancel the download after receiving the first part of the response.
|
||||
|
@ -260,7 +263,7 @@ add_task(function test_cancel_midway()
|
|||
do_check_true(download.canceled);
|
||||
do_check_true(download.error === null);
|
||||
|
||||
do_check_false(download.target.file.exists());
|
||||
do_check_false(yield OS.File.exists(download.target.path));
|
||||
|
||||
// Progress properties are not reset by canceling.
|
||||
do_check_eq(download.progress, 50);
|
||||
|
@ -278,7 +281,9 @@ add_task(function test_error()
|
|||
{
|
||||
let serverSocket = startFakeServer();
|
||||
try {
|
||||
let download = yield promiseStartLegacyDownload(TEST_FAKE_SOURCE_URI);
|
||||
let sourceUrl = "http://localhost:" + serverSocket.port + "/source.txt";
|
||||
|
||||
let download = yield promiseStartLegacyDownload(sourceUrl);
|
||||
|
||||
// We must check the download properties instead of calling the "start"
|
||||
// method because the download has been started and may already be stopped.
|
||||
|
@ -307,8 +312,8 @@ add_task(function test_error()
|
|||
*/
|
||||
add_task(function test_download_public_and_private()
|
||||
{
|
||||
let source_path = "/test_download_public_and_private.txt";
|
||||
let source_uri = NetUtil.newURI(HTTP_BASE + source_path);
|
||||
let sourcePath = "/test_download_public_and_private.txt";
|
||||
let sourceUrl = httpUrl("test_download_public_and_private.txt");
|
||||
let testCount = 0;
|
||||
|
||||
// Apply pref to allow all cookies.
|
||||
|
@ -317,12 +322,12 @@ add_task(function test_download_public_and_private()
|
|||
function cleanup() {
|
||||
Services.prefs.clearUserPref("network.cookie.cookieBehavior");
|
||||
Services.cookies.removeAll();
|
||||
gHttpServer.registerPathHandler(source_path, null);
|
||||
gHttpServer.registerPathHandler(sourcePath, null);
|
||||
}
|
||||
|
||||
do_register_cleanup(cleanup);
|
||||
|
||||
gHttpServer.registerPathHandler(source_path, function (aRequest, aResponse) {
|
||||
gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
if (testCount == 0) {
|
||||
|
@ -342,9 +347,9 @@ add_task(function test_download_public_and_private()
|
|||
});
|
||||
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
yield Downloads.simpleDownload(source_uri, targetFile);
|
||||
yield Downloads.simpleDownload(source_uri, targetFile);
|
||||
let download = yield promiseStartLegacyDownload(source_uri, true);
|
||||
yield Downloads.simpleDownload(sourceUrl, targetFile);
|
||||
yield Downloads.simpleDownload(sourceUrl, targetFile);
|
||||
let download = yield promiseStartLegacyDownload(sourceUrl, true);
|
||||
// The download is already started, wait for completion and report any errors.
|
||||
if (!download.stopped) {
|
||||
yield download.start();
|
||||
|
@ -373,7 +378,7 @@ add_task(function test_download_blocked_parental_controls()
|
|||
do_check_true(ex.becauseBlockedByParentalControls);
|
||||
}
|
||||
|
||||
do_check_false(download.target.file.exists());
|
||||
do_check_false(yield OS.File.exists(download.target.path));
|
||||
|
||||
cleanup();
|
||||
});
|
||||
|
|
|
@ -174,11 +174,11 @@ add_task(function test_history_expiration()
|
|||
|
||||
// Add expirable visit for downloads.
|
||||
yield promiseAddDownloadToHistory();
|
||||
yield promiseAddDownloadToHistory(TEST_INTERRUPTIBLE_URI);
|
||||
yield promiseAddDownloadToHistory(httpUrl("interruptible.txt"));
|
||||
|
||||
let list = yield promiseNewDownloadList();
|
||||
let downloadOne = yield promiseSimpleDownload();
|
||||
let downloadTwo = yield promiseSimpleDownload(TEST_INTERRUPTIBLE_URI);
|
||||
let downloadTwo = yield promiseSimpleDownload(httpUrl("interruptible.txt"));
|
||||
list.add(downloadOne);
|
||||
list.add(downloadTwo);
|
||||
|
||||
|
|
|
@ -49,12 +49,11 @@ add_task(function test_save_reload()
|
|||
let [listForLoad, storeForLoad] = yield promiseNewListAndStore(
|
||||
storeForSave.path);
|
||||
|
||||
listForSave.add(yield promiseSimpleDownload(TEST_SOURCE_URI));
|
||||
listForSave.add(yield promiseSimpleDownload(httpUrl("source.txt")));
|
||||
listForSave.add(yield Downloads.createDownload({
|
||||
source: { uri: TEST_EMPTY_URI,
|
||||
referrer: TEST_REFERRER_URI },
|
||||
target: { file: getTempFile(TEST_TARGET_FILE_NAME) },
|
||||
saver: { type: "copy" },
|
||||
source: { url: httpUrl("empty.txt"),
|
||||
referrer: TEST_REFERRER_URL },
|
||||
target: getTempFile(TEST_TARGET_FILE_NAME),
|
||||
}));
|
||||
|
||||
yield storeForSave.save();
|
||||
|
@ -71,16 +70,12 @@ add_task(function test_save_reload()
|
|||
do_check_neq(itemsForSave[i], itemsForLoad[i]);
|
||||
|
||||
// The reloaded downloads have the same properties.
|
||||
do_check_true(itemsForSave[i].source.uri.equals(
|
||||
itemsForLoad[i].source.uri));
|
||||
if (itemsForSave[i].source.referrer) {
|
||||
do_check_true(itemsForSave[i].source.referrer.equals(
|
||||
itemsForLoad[i].source.referrer));
|
||||
} else {
|
||||
do_check_true(itemsForLoad[i].source.referrer === null);
|
||||
}
|
||||
do_check_true(itemsForSave[i].target.file.equals(
|
||||
itemsForLoad[i].target.file));
|
||||
do_check_eq(itemsForSave[i].source.url,
|
||||
itemsForLoad[i].source.url);
|
||||
do_check_eq(itemsForSave[i].source.referrer,
|
||||
itemsForLoad[i].source.referrer);
|
||||
do_check_eq(itemsForSave[i].target.path,
|
||||
itemsForLoad[i].target.path);
|
||||
do_check_eq(itemsForSave[i].saver.type,
|
||||
itemsForLoad[i].saver.type);
|
||||
}
|
||||
|
@ -129,19 +124,17 @@ add_task(function test_load_string_predefined()
|
|||
let [list, store] = yield promiseNewListAndStore();
|
||||
|
||||
// The platform-dependent file name should be generated dynamically.
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
let filePathLiteral = JSON.stringify(targetFile.path);
|
||||
let sourceUriLiteral = JSON.stringify(TEST_SOURCE_URI.spec);
|
||||
let emptyUriLiteral = JSON.stringify(TEST_EMPTY_URI.spec);
|
||||
let referrerUriLiteral = JSON.stringify(TEST_REFERRER_URI.spec);
|
||||
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
let filePathLiteral = JSON.stringify(targetPath);
|
||||
let sourceUriLiteral = JSON.stringify(httpUrl("source.txt"));
|
||||
let emptyUriLiteral = JSON.stringify(httpUrl("empty.txt"));
|
||||
let referrerUriLiteral = JSON.stringify(TEST_REFERRER_URL);
|
||||
|
||||
let string = "[{\"source\":{\"uri\":" + sourceUriLiteral + "}," +
|
||||
"\"target\":{\"file\":" + filePathLiteral + "}," +
|
||||
"\"saver\":{\"type\":\"copy\"}}," +
|
||||
"{\"source\":{\"uri\":" + emptyUriLiteral + "," +
|
||||
let string = "{\"list\":[{\"source\":" + sourceUriLiteral + "," +
|
||||
"\"target\":" + filePathLiteral + "}," +
|
||||
"{\"source\":{\"url\":" + emptyUriLiteral + "," +
|
||||
"\"referrer\":" + referrerUriLiteral + "}," +
|
||||
"\"target\":{\"file\":" + filePathLiteral + "}," +
|
||||
"\"saver\":{\"type\":\"copy\"}}]";
|
||||
"\"target\":" + filePathLiteral + "}]}";
|
||||
|
||||
yield OS.File.writeAtomic(store.path,
|
||||
new TextEncoder().encode(string),
|
||||
|
@ -153,12 +146,12 @@ add_task(function test_load_string_predefined()
|
|||
|
||||
do_check_eq(items.length, 2);
|
||||
|
||||
do_check_true(items[0].source.uri.equals(TEST_SOURCE_URI));
|
||||
do_check_true(items[0].target.file.equals(targetFile));
|
||||
do_check_eq(items[0].source.url, httpUrl("source.txt"));
|
||||
do_check_eq(items[0].target.path, targetPath);
|
||||
|
||||
do_check_true(items[1].source.uri.equals(TEST_EMPTY_URI));
|
||||
do_check_true(items[1].source.referrer.equals(TEST_REFERRER_URI));
|
||||
do_check_true(items[1].target.file.equals(targetFile));
|
||||
do_check_eq(items[1].source.url, httpUrl("empty.txt"));
|
||||
do_check_eq(items[1].source.referrer, TEST_REFERRER_URL);
|
||||
do_check_eq(items[1].target.path, targetPath);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -169,15 +162,15 @@ add_task(function test_load_string_unrecognized()
|
|||
let [list, store] = yield promiseNewListAndStore();
|
||||
|
||||
// The platform-dependent file name should be generated dynamically.
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
let filePathLiteral = JSON.stringify(targetFile.path);
|
||||
let sourceUriLiteral = JSON.stringify(TEST_SOURCE_URI.spec);
|
||||
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
let filePathLiteral = JSON.stringify(targetPath);
|
||||
let sourceUriLiteral = JSON.stringify(httpUrl("source.txt"));
|
||||
|
||||
let string = "[{\"source\":null," +
|
||||
let string = "{\"list\":[{\"source\":null," +
|
||||
"\"target\":null}," +
|
||||
"{\"source\":{\"uri\":" + sourceUriLiteral + "}," +
|
||||
"\"target\":{\"file\":" + filePathLiteral + "}," +
|
||||
"\"saver\":{\"type\":\"copy\"}}]";
|
||||
"{\"source\":{\"url\":" + sourceUriLiteral + "}," +
|
||||
"\"target\":{\"path\":" + filePathLiteral + "}," +
|
||||
"\"saver\":{\"type\":\"copy\"}}]}";
|
||||
|
||||
yield OS.File.writeAtomic(store.path,
|
||||
new TextEncoder().encode(string),
|
||||
|
@ -189,8 +182,8 @@ add_task(function test_load_string_unrecognized()
|
|||
|
||||
do_check_eq(items.length, 1);
|
||||
|
||||
do_check_true(items[0].source.uri.equals(TEST_SOURCE_URI));
|
||||
do_check_true(items[0].target.file.equals(targetFile));
|
||||
do_check_eq(items[0].source.url, httpUrl("source.txt"));
|
||||
do_check_eq(items[0].target.path, targetPath);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -200,8 +193,8 @@ add_task(function test_load_string_malformed()
|
|||
{
|
||||
let [list, store] = yield promiseNewListAndStore();
|
||||
|
||||
let string = "[{\"source\":null,\"target\":null}," +
|
||||
"{\"source\":{\"uri\":\"about:blank\"}}";
|
||||
let string = "{\"list\":[{\"source\":null,\"target\":null}," +
|
||||
"{\"source\":{\"url\":\"about:blank\"}}}";
|
||||
|
||||
yield OS.File.writeAtomic(store.path, new TextEncoder().encode(string),
|
||||
{ tmpPath: store.path + ".tmp" });
|
||||
|
|
|
@ -20,21 +20,20 @@ add_task(function test_createDownload()
|
|||
{
|
||||
// Creates a simple Download object without starting the download.
|
||||
yield Downloads.createDownload({
|
||||
source: { uri: NetUtil.newURI("about:blank") },
|
||||
target: { file: getTempFile(TEST_TARGET_FILE_NAME) },
|
||||
source: { url: "about:blank" },
|
||||
target: { path: getTempFile(TEST_TARGET_FILE_NAME).path },
|
||||
saver: { type: "copy" },
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests createDownload for private download.
|
||||
* Tests createDownload for private download.
|
||||
*/
|
||||
add_task(function test_createDownload_private()
|
||||
{
|
||||
let download = yield Downloads.createDownload({
|
||||
source: { uri: NetUtil.newURI("about:blank"),
|
||||
isPrivate: true },
|
||||
target: { file: getTempFile(TEST_TARGET_FILE_NAME) },
|
||||
source: { url: "about:blank", isPrivate: true },
|
||||
target: { path: getTempFile(TEST_TARGET_FILE_NAME).path },
|
||||
saver: { type: "copy" }
|
||||
});
|
||||
do_check_true(download.source.isPrivate);
|
||||
|
@ -45,21 +44,20 @@ add_task(function test_createDownload_private()
|
|||
*/
|
||||
add_task(function test_createDownload_public()
|
||||
{
|
||||
let uri = NetUtil.newURI("about:blank");
|
||||
let tempFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
let tempPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
let download = yield Downloads.createDownload({
|
||||
source: { uri: uri, isPrivate: false },
|
||||
target: { file: tempFile },
|
||||
source: { url: "about:blank", isPrivate: false },
|
||||
target: { path: tempPath },
|
||||
saver: { type: "copy" }
|
||||
});
|
||||
do_check_false(download.source.isPrivate);
|
||||
|
||||
download = yield Downloads.createDownload({
|
||||
source: { uri: uri },
|
||||
target: { file: tempFile },
|
||||
source: { url: "about:blank" },
|
||||
target: { path: tempPath },
|
||||
saver: { type: "copy" }
|
||||
});
|
||||
do_check_true(!download.source.isPrivate);
|
||||
do_check_false(download.source.isPrivate);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -68,8 +66,9 @@ add_task(function test_createDownload_public()
|
|||
add_task(function test_simpleDownload_uri_file_arguments()
|
||||
{
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
yield Downloads.simpleDownload(TEST_SOURCE_URI, targetFile);
|
||||
yield promiseVerifyContents(targetFile, TEST_DATA_SHORT);
|
||||
yield Downloads.simpleDownload(NetUtil.newURI(httpUrl("source.txt")),
|
||||
targetFile);
|
||||
yield promiseVerifyContents(targetFile.path, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -77,10 +76,10 @@ add_task(function test_simpleDownload_uri_file_arguments()
|
|||
*/
|
||||
add_task(function test_simpleDownload_object_arguments()
|
||||
{
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
yield Downloads.simpleDownload({ uri: TEST_SOURCE_URI },
|
||||
{ file: targetFile });
|
||||
yield promiseVerifyContents(targetFile, TEST_DATA_SHORT);
|
||||
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
yield Downloads.simpleDownload({ url: httpUrl("source.txt") },
|
||||
{ path: targetPath });
|
||||
yield promiseVerifyContents(targetPath, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -88,15 +87,15 @@ add_task(function test_simpleDownload_object_arguments()
|
|||
*/
|
||||
add_task(function test_simpleDownload_string_arguments()
|
||||
{
|
||||
let targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
yield Downloads.simpleDownload(TEST_SOURCE_URI.spec,
|
||||
targetFile.path);
|
||||
yield promiseVerifyContents(targetFile, TEST_DATA_SHORT);
|
||||
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
yield Downloads.simpleDownload(httpUrl("source.txt"),
|
||||
targetPath);
|
||||
yield promiseVerifyContents(targetPath, TEST_DATA_SHORT);
|
||||
|
||||
targetFile = getTempFile(TEST_TARGET_FILE_NAME);
|
||||
yield Downloads.simpleDownload(new String(TEST_SOURCE_URI.spec),
|
||||
new String(targetFile.path));
|
||||
yield promiseVerifyContents(targetFile, TEST_DATA_SHORT);
|
||||
targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
|
||||
yield Downloads.simpleDownload(new String(httpUrl("source.txt")),
|
||||
new String(targetPath));
|
||||
yield promiseVerifyContents(targetPath, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче