forked from mirrors/gecko-dev
Bug 1561435 - Format netwerk/, a=automatic-formatting
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35919 --HG-- extra : source : afa5bd771feba466ba7670c58f3d93233a14e202
This commit is contained in:
parent
ea8b91c51d
commit
2c53a5dcd9
455 changed files with 25908 additions and 16247 deletions
|
|
@ -45,7 +45,6 @@ module.exports = {
|
|||
"overrides": [{
|
||||
"files": [
|
||||
"devtools/**",
|
||||
"netwerk/**",
|
||||
"nsprpub/**",
|
||||
"other-licenses/**",
|
||||
"parser/**",
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
|
|||
toolkit/components/telemetry/healthreport-prefs.js
|
||||
|
||||
# Ignore all top-level directories for now.
|
||||
netwerk/**
|
||||
nsprpub/**
|
||||
other-licenses/**
|
||||
parser/**
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@
|
|||
* 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/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"NetUtil",
|
||||
];
|
||||
var EXPORTED_SYMBOLS = ["NetUtil"];
|
||||
|
||||
/**
|
||||
* Necko utilities
|
||||
|
|
@ -17,413 +15,435 @@ var EXPORTED_SYMBOLS = [
|
|||
|
||||
const PR_UINT32_MAX = 0xffffffff;
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream", "setInputStream");
|
||||
const BinaryInputStream = Components.Constructor(
|
||||
"@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream"
|
||||
);
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// // NetUtil Object
|
||||
|
||||
var NetUtil = {
|
||||
/**
|
||||
* Function to perform simple async copying from aSource (an input stream)
|
||||
* to aSink (an output stream). The copy will happen on some background
|
||||
* thread. Both streams will be closed when the copy completes.
|
||||
*
|
||||
* @param aSource
|
||||
* The input stream to read from
|
||||
* @param aSink
|
||||
* The output stream to write to
|
||||
* @param aCallback [optional]
|
||||
* A function that will be called at copy completion with a single
|
||||
* argument: the nsresult status code for the copy operation.
|
||||
*
|
||||
* @return An nsIRequest representing the copy operation (for example, this
|
||||
* can be used to cancel the copying). The consumer can ignore the
|
||||
* return value if desired.
|
||||
*/
|
||||
asyncCopy: function NetUtil_asyncCopy(aSource, aSink,
|
||||
aCallback = null) {
|
||||
if (!aSource || !aSink) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a source and a sink",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
/**
|
||||
* Function to perform simple async copying from aSource (an input stream)
|
||||
* to aSink (an output stream). The copy will happen on some background
|
||||
* thread. Both streams will be closed when the copy completes.
|
||||
*
|
||||
* @param aSource
|
||||
* The input stream to read from
|
||||
* @param aSink
|
||||
* The output stream to write to
|
||||
* @param aCallback [optional]
|
||||
* A function that will be called at copy completion with a single
|
||||
* argument: the nsresult status code for the copy operation.
|
||||
*
|
||||
* @return An nsIRequest representing the copy operation (for example, this
|
||||
* can be used to cancel the copying). The consumer can ignore the
|
||||
* return value if desired.
|
||||
*/
|
||||
asyncCopy: function NetUtil_asyncCopy(aSource, aSink, aCallback = null) {
|
||||
if (!aSource || !aSink) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a source and a sink",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
// make a stream copier
|
||||
var copier = Cc[
|
||||
"@mozilla.org/network/async-stream-copier;1"
|
||||
].createInstance(Ci.nsIAsyncStreamCopier2);
|
||||
copier.init(
|
||||
aSource,
|
||||
aSink,
|
||||
null /* Default event target */,
|
||||
0 /* Default length */,
|
||||
true,
|
||||
true /* Auto-close */
|
||||
);
|
||||
|
||||
var observer;
|
||||
if (aCallback) {
|
||||
observer = {
|
||||
onStartRequest(aRequest) {},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
aCallback(aStatusCode);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
observer = null;
|
||||
}
|
||||
|
||||
// start the copying
|
||||
copier.QueryInterface(Ci.nsIAsyncStreamCopier).asyncCopy(observer, null);
|
||||
return copier;
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronously opens a source and fetches the response. While the fetch
|
||||
* is asynchronous, I/O may happen on the main thread. When reading from
|
||||
* a local file, prefer using "OS.File" methods instead.
|
||||
*
|
||||
* @param aSource
|
||||
* This argument can be one of the following:
|
||||
* - An options object that will be passed to NetUtil.newChannel.
|
||||
* - An existing nsIChannel.
|
||||
* - An existing nsIInputStream.
|
||||
* Using an nsIURI, nsIFile, or string spec directly is deprecated.
|
||||
* @param aCallback
|
||||
* The callback function that will be notified upon completion. It
|
||||
* will get these arguments:
|
||||
* 1) An nsIInputStream containing the data from aSource, if any.
|
||||
* 2) The status code from opening the source.
|
||||
* 3) Reference to the nsIRequest.
|
||||
*/
|
||||
asyncFetch: function NetUtil_asyncFetch(aSource, aCallback) {
|
||||
if (!aSource || !aCallback) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a source and a callback",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
// Create a pipe that will create our output stream that we can use once
|
||||
// we have gotten all the data.
|
||||
let pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, PR_UINT32_MAX, null);
|
||||
|
||||
// Create a listener that will give data to the pipe's output stream.
|
||||
let listener = Cc[
|
||||
"@mozilla.org/network/simple-stream-listener;1"
|
||||
].createInstance(Ci.nsISimpleStreamListener);
|
||||
listener.init(pipe.outputStream, {
|
||||
onStartRequest(aRequest) {},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
pipe.outputStream.close();
|
||||
aCallback(pipe.inputStream, aStatusCode, aRequest);
|
||||
},
|
||||
});
|
||||
|
||||
// Input streams are handled slightly differently from everything else.
|
||||
if (aSource instanceof Ci.nsIInputStream) {
|
||||
let pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(
|
||||
Ci.nsIInputStreamPump
|
||||
);
|
||||
pump.init(aSource, 0, 0, true);
|
||||
pump.asyncRead(listener, null);
|
||||
return;
|
||||
}
|
||||
|
||||
let channel = aSource;
|
||||
if (!(channel instanceof Ci.nsIChannel)) {
|
||||
channel = this.newChannel(aSource);
|
||||
}
|
||||
|
||||
try {
|
||||
channel.asyncOpen(listener);
|
||||
} catch (e) {
|
||||
let exception = new Components.Exception(
|
||||
"Failed to open input source '" + channel.originalURI.spec + "'",
|
||||
e.result,
|
||||
Components.stack.caller,
|
||||
aSource,
|
||||
e
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructs a new URI for the given spec, character set, and base URI, or
|
||||
* an nsIFile.
|
||||
*
|
||||
* @param aTarget
|
||||
* The string spec for the desired URI or an nsIFile.
|
||||
* @param aOriginCharset [optional]
|
||||
* The character set for the URI. Only used if aTarget is not an
|
||||
* nsIFile.
|
||||
* @param aBaseURI [optional]
|
||||
* The base URI for the spec. Only used if aTarget is not an
|
||||
* nsIFile.
|
||||
*
|
||||
* @return an nsIURI object.
|
||||
*/
|
||||
newURI: function NetUtil_newURI(aTarget, aOriginCharset, aBaseURI) {
|
||||
if (!aTarget) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a non-null string spec or nsIFile object",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (aTarget instanceof Ci.nsIFile) {
|
||||
return Services.io.newFileURI(aTarget);
|
||||
}
|
||||
|
||||
return Services.io.newURI(aTarget, aOriginCharset, aBaseURI);
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructs a new channel for the given source.
|
||||
*
|
||||
* Keep in mind that URIs coming from a webpage should *never* use the
|
||||
* systemPrincipal as the loadingPrincipal.
|
||||
*
|
||||
* @param aWhatToLoad
|
||||
* This argument used to be a string spec for the desired URI, an
|
||||
* nsIURI, or an nsIFile. Now it should be an options object with
|
||||
* the following properties:
|
||||
* {
|
||||
* uri:
|
||||
* The full URI spec string, nsIURI or nsIFile to create the
|
||||
* channel for.
|
||||
* Note that this cannot be an nsIFile if you have to specify a
|
||||
* non-default charset or base URI. Call NetUtil.newURI first if
|
||||
* you need to construct an URI using those options.
|
||||
* loadingNode:
|
||||
* loadingPrincipal:
|
||||
* triggeringPrincipal:
|
||||
* securityFlags:
|
||||
* contentPolicyType:
|
||||
* These will be used as values for the nsILoadInfo object on the
|
||||
* created channel. For details, see nsILoadInfo in nsILoadInfo.idl
|
||||
* loadUsingSystemPrincipal:
|
||||
* Set this to true to use the system principal as
|
||||
* loadingPrincipal. This must be omitted if loadingPrincipal or
|
||||
* loadingNode are present.
|
||||
* This should be used with care as it skips security checks.
|
||||
* }
|
||||
* @return an nsIChannel object.
|
||||
*/
|
||||
newChannel: function NetUtil_newChannel(aWhatToLoad) {
|
||||
// Make sure the API is called using only the options object.
|
||||
if (typeof aWhatToLoad != "object" || arguments.length != 1) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires a single object argument",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
let {
|
||||
uri,
|
||||
loadingNode,
|
||||
loadingPrincipal,
|
||||
loadUsingSystemPrincipal,
|
||||
triggeringPrincipal,
|
||||
securityFlags,
|
||||
contentPolicyType,
|
||||
} = aWhatToLoad;
|
||||
|
||||
if (!uri) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'uri' property on the options object.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof uri == "string" || uri instanceof Ci.nsIFile) {
|
||||
uri = this.newURI(uri);
|
||||
}
|
||||
|
||||
if (!loadingNode && !loadingPrincipal && !loadUsingSystemPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires at least one of the 'loadingNode'," +
|
||||
" 'loadingPrincipal', or 'loadUsingSystemPrincipal'" +
|
||||
" properties on the options object.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
if (loadUsingSystemPrincipal === true) {
|
||||
if (loadingNode || loadingPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel does not accept 'loadUsingSystemPrincipal'" +
|
||||
" if the 'loadingNode' or 'loadingPrincipal' properties" +
|
||||
" are present on the options object.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
loadingPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
} else if (loadUsingSystemPrincipal !== undefined) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'loadUsingSystemPrincipal'" +
|
||||
" property on the options object to be 'true' or 'undefined'.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
if (securityFlags === undefined) {
|
||||
if (!loadUsingSystemPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'securityFlags' property on" +
|
||||
" the options object unless loading from system principal.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
|
||||
}
|
||||
|
||||
if (contentPolicyType === undefined) {
|
||||
if (!loadUsingSystemPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'contentPolicyType' property on" +
|
||||
" the options object unless loading from system principal.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
|
||||
}
|
||||
|
||||
return Services.io.newChannelFromURI(
|
||||
uri,
|
||||
loadingNode || null,
|
||||
loadingPrincipal || null,
|
||||
triggeringPrincipal || null,
|
||||
securityFlags,
|
||||
contentPolicyType
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reads aCount bytes from aInputStream into a string.
|
||||
*
|
||||
* @param aInputStream
|
||||
* The input stream to read from.
|
||||
* @param aCount
|
||||
* The number of bytes to read from the stream.
|
||||
* @param aOptions [optional]
|
||||
* charset
|
||||
* The character encoding of stream data.
|
||||
* replacement
|
||||
* The character to replace unknown byte sequences.
|
||||
* If unset, it causes an exceptions to be thrown.
|
||||
*
|
||||
* @return the bytes from the input stream in string form.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG if aInputStream is not an nsIInputStream.
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if reading from aInputStream would
|
||||
* block the calling thread (non-blocking mode only).
|
||||
* @throws NS_ERROR_FAILURE if there are not enough bytes available to read
|
||||
* aCount amount of data.
|
||||
* @throws NS_ERROR_ILLEGAL_INPUT if aInputStream has invalid sequences
|
||||
*/
|
||||
readInputStreamToString: function NetUtil_readInputStreamToString(
|
||||
aInputStream,
|
||||
aCount,
|
||||
aOptions
|
||||
) {
|
||||
if (!(aInputStream instanceof Ci.nsIInputStream)) {
|
||||
let exception = new Components.Exception(
|
||||
"First argument should be an nsIInputStream",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (!aCount) {
|
||||
let exception = new Components.Exception(
|
||||
"Non-zero amount of bytes must be specified",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (aOptions && "charset" in aOptions) {
|
||||
let cis = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(
|
||||
Ci.nsIConverterInputStream
|
||||
);
|
||||
try {
|
||||
// When replacement is set, the character that is unknown sequence
|
||||
// replaces with aOptions.replacement character.
|
||||
if (!("replacement" in aOptions)) {
|
||||
// aOptions.replacement isn't set.
|
||||
// If input stream has unknown sequences for aOptions.charset,
|
||||
// throw NS_ERROR_ILLEGAL_INPUT.
|
||||
aOptions.replacement = 0;
|
||||
}
|
||||
|
||||
// make a stream copier
|
||||
var copier = Cc["@mozilla.org/network/async-stream-copier;1"].
|
||||
createInstance(Ci.nsIAsyncStreamCopier2);
|
||||
copier.init(aSource, aSink,
|
||||
null /* Default event target */,
|
||||
0 /* Default length */,
|
||||
true, true /* Auto-close */);
|
||||
cis.init(aInputStream, aOptions.charset, aCount, aOptions.replacement);
|
||||
let str = {};
|
||||
cis.readString(-1, str);
|
||||
cis.close();
|
||||
return str.value;
|
||||
} catch (e) {
|
||||
// Adjust the stack so it throws at the caller's location.
|
||||
throw new Components.Exception(
|
||||
e.message,
|
||||
e.result,
|
||||
Components.stack.caller,
|
||||
e.data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var observer;
|
||||
if (aCallback) {
|
||||
observer = {
|
||||
onStartRequest(aRequest) {},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
aCallback(aStatusCode);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
observer = null;
|
||||
}
|
||||
let sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
sis.init(aInputStream);
|
||||
try {
|
||||
return sis.readBytes(aCount);
|
||||
} catch (e) {
|
||||
// Adjust the stack so it throws at the caller's location.
|
||||
throw new Components.Exception(
|
||||
e.message,
|
||||
e.result,
|
||||
Components.stack.caller,
|
||||
e.data
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// start the copying
|
||||
copier.QueryInterface(Ci.nsIAsyncStreamCopier).asyncCopy(observer, null);
|
||||
return copier;
|
||||
},
|
||||
/**
|
||||
* Reads aCount bytes from aInputStream into a string.
|
||||
*
|
||||
* @param {nsIInputStream} aInputStream
|
||||
* The input stream to read from.
|
||||
* @param {integer} [aCount = aInputStream.available()]
|
||||
* The number of bytes to read from the stream.
|
||||
*
|
||||
* @return the bytes from the input stream in string form.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG if aInputStream is not an nsIInputStream.
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if reading from aInputStream would
|
||||
* block the calling thread (non-blocking mode only).
|
||||
* @throws NS_ERROR_FAILURE if there are not enough bytes available to read
|
||||
* aCount amount of data.
|
||||
*/
|
||||
readInputStream(aInputStream, aCount) {
|
||||
if (!(aInputStream instanceof Ci.nsIInputStream)) {
|
||||
let exception = new Components.Exception(
|
||||
"First argument should be an nsIInputStream",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously opens a source and fetches the response. While the fetch
|
||||
* is asynchronous, I/O may happen on the main thread. When reading from
|
||||
* a local file, prefer using "OS.File" methods instead.
|
||||
*
|
||||
* @param aSource
|
||||
* This argument can be one of the following:
|
||||
* - An options object that will be passed to NetUtil.newChannel.
|
||||
* - An existing nsIChannel.
|
||||
* - An existing nsIInputStream.
|
||||
* Using an nsIURI, nsIFile, or string spec directly is deprecated.
|
||||
* @param aCallback
|
||||
* The callback function that will be notified upon completion. It
|
||||
* will get these arguments:
|
||||
* 1) An nsIInputStream containing the data from aSource, if any.
|
||||
* 2) The status code from opening the source.
|
||||
* 3) Reference to the nsIRequest.
|
||||
*/
|
||||
asyncFetch: function NetUtil_asyncFetch(aSource, aCallback) {
|
||||
if (!aSource || !aCallback) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a source and a callback",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
if (!aCount) {
|
||||
aCount = aInputStream.available();
|
||||
}
|
||||
|
||||
// Create a pipe that will create our output stream that we can use once
|
||||
// we have gotten all the data.
|
||||
let pipe = Cc["@mozilla.org/pipe;1"].
|
||||
createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, PR_UINT32_MAX, null);
|
||||
|
||||
// Create a listener that will give data to the pipe's output stream.
|
||||
let listener = Cc["@mozilla.org/network/simple-stream-listener;1"].
|
||||
createInstance(Ci.nsISimpleStreamListener);
|
||||
listener.init(pipe.outputStream, {
|
||||
onStartRequest(aRequest) {},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
pipe.outputStream.close();
|
||||
aCallback(pipe.inputStream, aStatusCode, aRequest);
|
||||
},
|
||||
});
|
||||
|
||||
// Input streams are handled slightly differently from everything else.
|
||||
if (aSource instanceof Ci.nsIInputStream) {
|
||||
let pump = Cc["@mozilla.org/network/input-stream-pump;1"].
|
||||
createInstance(Ci.nsIInputStreamPump);
|
||||
pump.init(aSource, 0, 0, true);
|
||||
pump.asyncRead(listener, null);
|
||||
return;
|
||||
}
|
||||
|
||||
let channel = aSource;
|
||||
if (!(channel instanceof Ci.nsIChannel)) {
|
||||
channel = this.newChannel(aSource);
|
||||
}
|
||||
|
||||
try {
|
||||
channel.asyncOpen(listener);
|
||||
} catch (e) {
|
||||
let exception = new Components.Exception(
|
||||
"Failed to open input source '" + channel.originalURI.spec + "'",
|
||||
e.result,
|
||||
Components.stack.caller,
|
||||
aSource,
|
||||
e
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructs a new URI for the given spec, character set, and base URI, or
|
||||
* an nsIFile.
|
||||
*
|
||||
* @param aTarget
|
||||
* The string spec for the desired URI or an nsIFile.
|
||||
* @param aOriginCharset [optional]
|
||||
* The character set for the URI. Only used if aTarget is not an
|
||||
* nsIFile.
|
||||
* @param aBaseURI [optional]
|
||||
* The base URI for the spec. Only used if aTarget is not an
|
||||
* nsIFile.
|
||||
*
|
||||
* @return an nsIURI object.
|
||||
*/
|
||||
newURI: function NetUtil_newURI(aTarget, aOriginCharset, aBaseURI) {
|
||||
if (!aTarget) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a non-null string spec or nsIFile object",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (aTarget instanceof Ci.nsIFile) {
|
||||
return Services.io.newFileURI(aTarget);
|
||||
}
|
||||
|
||||
return Services.io.newURI(aTarget, aOriginCharset, aBaseURI);
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructs a new channel for the given source.
|
||||
*
|
||||
* Keep in mind that URIs coming from a webpage should *never* use the
|
||||
* systemPrincipal as the loadingPrincipal.
|
||||
*
|
||||
* @param aWhatToLoad
|
||||
* This argument used to be a string spec for the desired URI, an
|
||||
* nsIURI, or an nsIFile. Now it should be an options object with
|
||||
* the following properties:
|
||||
* {
|
||||
* uri:
|
||||
* The full URI spec string, nsIURI or nsIFile to create the
|
||||
* channel for.
|
||||
* Note that this cannot be an nsIFile if you have to specify a
|
||||
* non-default charset or base URI. Call NetUtil.newURI first if
|
||||
* you need to construct an URI using those options.
|
||||
* loadingNode:
|
||||
* loadingPrincipal:
|
||||
* triggeringPrincipal:
|
||||
* securityFlags:
|
||||
* contentPolicyType:
|
||||
* These will be used as values for the nsILoadInfo object on the
|
||||
* created channel. For details, see nsILoadInfo in nsILoadInfo.idl
|
||||
* loadUsingSystemPrincipal:
|
||||
* Set this to true to use the system principal as
|
||||
* loadingPrincipal. This must be omitted if loadingPrincipal or
|
||||
* loadingNode are present.
|
||||
* This should be used with care as it skips security checks.
|
||||
* }
|
||||
* @return an nsIChannel object.
|
||||
*/
|
||||
newChannel: function NetUtil_newChannel(aWhatToLoad) {
|
||||
// Make sure the API is called using only the options object.
|
||||
if (typeof aWhatToLoad != "object" || arguments.length != 1) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires a single object argument",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
let { uri,
|
||||
loadingNode,
|
||||
loadingPrincipal,
|
||||
loadUsingSystemPrincipal,
|
||||
triggeringPrincipal,
|
||||
securityFlags,
|
||||
contentPolicyType } = aWhatToLoad;
|
||||
|
||||
if (!uri) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'uri' property on the options object.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof uri == "string" || uri instanceof Ci.nsIFile) {
|
||||
uri = this.newURI(uri);
|
||||
}
|
||||
|
||||
if (!loadingNode && !loadingPrincipal && !loadUsingSystemPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires at least one of the 'loadingNode'," +
|
||||
" 'loadingPrincipal', or 'loadUsingSystemPrincipal'" +
|
||||
" properties on the options object.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
if (loadUsingSystemPrincipal === true) {
|
||||
if (loadingNode || loadingPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel does not accept 'loadUsingSystemPrincipal'" +
|
||||
" if the 'loadingNode' or 'loadingPrincipal' properties" +
|
||||
" are present on the options object.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
loadingPrincipal = Services.scriptSecurityManager
|
||||
.getSystemPrincipal();
|
||||
} else if (loadUsingSystemPrincipal !== undefined) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'loadUsingSystemPrincipal'" +
|
||||
" property on the options object to be 'true' or 'undefined'.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
|
||||
if (securityFlags === undefined) {
|
||||
if (!loadUsingSystemPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'securityFlags' property on" +
|
||||
" the options object unless loading from system principal.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
|
||||
}
|
||||
|
||||
if (contentPolicyType === undefined) {
|
||||
if (!loadUsingSystemPrincipal) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'contentPolicyType' property on" +
|
||||
" the options object unless loading from system principal.",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
|
||||
}
|
||||
|
||||
return Services.io.newChannelFromURI(uri,
|
||||
loadingNode || null,
|
||||
loadingPrincipal || null,
|
||||
triggeringPrincipal || null,
|
||||
securityFlags,
|
||||
contentPolicyType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reads aCount bytes from aInputStream into a string.
|
||||
*
|
||||
* @param aInputStream
|
||||
* The input stream to read from.
|
||||
* @param aCount
|
||||
* The number of bytes to read from the stream.
|
||||
* @param aOptions [optional]
|
||||
* charset
|
||||
* The character encoding of stream data.
|
||||
* replacement
|
||||
* The character to replace unknown byte sequences.
|
||||
* If unset, it causes an exceptions to be thrown.
|
||||
*
|
||||
* @return the bytes from the input stream in string form.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG if aInputStream is not an nsIInputStream.
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if reading from aInputStream would
|
||||
* block the calling thread (non-blocking mode only).
|
||||
* @throws NS_ERROR_FAILURE if there are not enough bytes available to read
|
||||
* aCount amount of data.
|
||||
* @throws NS_ERROR_ILLEGAL_INPUT if aInputStream has invalid sequences
|
||||
*/
|
||||
readInputStreamToString: function NetUtil_readInputStreamToString(aInputStream,
|
||||
aCount,
|
||||
aOptions) {
|
||||
if (!(aInputStream instanceof Ci.nsIInputStream)) {
|
||||
let exception = new Components.Exception(
|
||||
"First argument should be an nsIInputStream",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (!aCount) {
|
||||
let exception = new Components.Exception(
|
||||
"Non-zero amount of bytes must be specified",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (aOptions && "charset" in aOptions) {
|
||||
let cis = Cc["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Ci.nsIConverterInputStream);
|
||||
try {
|
||||
// When replacement is set, the character that is unknown sequence
|
||||
// replaces with aOptions.replacement character.
|
||||
if (!("replacement" in aOptions)) {
|
||||
// aOptions.replacement isn't set.
|
||||
// If input stream has unknown sequences for aOptions.charset,
|
||||
// throw NS_ERROR_ILLEGAL_INPUT.
|
||||
aOptions.replacement = 0;
|
||||
}
|
||||
|
||||
cis.init(aInputStream, aOptions.charset, aCount,
|
||||
aOptions.replacement);
|
||||
let str = {};
|
||||
cis.readString(-1, str);
|
||||
cis.close();
|
||||
return str.value;
|
||||
} catch (e) {
|
||||
// Adjust the stack so it throws at the caller's location.
|
||||
throw new Components.Exception(e.message, e.result,
|
||||
Components.stack.caller, e.data);
|
||||
}
|
||||
}
|
||||
|
||||
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
sis.init(aInputStream);
|
||||
try {
|
||||
return sis.readBytes(aCount);
|
||||
} catch (e) {
|
||||
// Adjust the stack so it throws at the caller's location.
|
||||
throw new Components.Exception(e.message, e.result,
|
||||
Components.stack.caller, e.data);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reads aCount bytes from aInputStream into a string.
|
||||
*
|
||||
* @param {nsIInputStream} aInputStream
|
||||
* The input stream to read from.
|
||||
* @param {integer} [aCount = aInputStream.available()]
|
||||
* The number of bytes to read from the stream.
|
||||
*
|
||||
* @return the bytes from the input stream in string form.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG if aInputStream is not an nsIInputStream.
|
||||
* @throws NS_BASE_STREAM_WOULD_BLOCK if reading from aInputStream would
|
||||
* block the calling thread (non-blocking mode only).
|
||||
* @throws NS_ERROR_FAILURE if there are not enough bytes available to read
|
||||
* aCount amount of data.
|
||||
*/
|
||||
readInputStream(aInputStream, aCount) {
|
||||
if (!(aInputStream instanceof Ci.nsIInputStream)) {
|
||||
let exception = new Components.Exception(
|
||||
"First argument should be an nsIInputStream",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
Components.stack.caller
|
||||
);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (!aCount) {
|
||||
aCount = aInputStream.available();
|
||||
}
|
||||
|
||||
let stream = new BinaryInputStream(aInputStream);
|
||||
let result = new ArrayBuffer(aCount);
|
||||
stream.readArrayBuffer(result.byteLength, result);
|
||||
return result;
|
||||
},
|
||||
let stream = new BinaryInputStream(aInputStream);
|
||||
let result = new ArrayBuffer(aCount);
|
||||
stream.readArrayBuffer(result.byteLength, result);
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ CookiePolicyHelper.runTest("BroadcastChannel", {
|
|||
ok(true, "BroadcastChannel cannot be used!");
|
||||
is(e.name, "SecurityError", "We want a security error message.");
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
CookiePolicyHelper.runTest("BroadcastChannel in workers", {
|
||||
|
|
@ -25,7 +25,9 @@ CookiePolicyHelper.runTest("BroadcastChannel in workers", {
|
|||
postMessage(true);
|
||||
}
|
||||
|
||||
let blob = new w.Blob([nonBlockingCode.toString() + "; nonBlockingCode();"]);
|
||||
let blob = new w.Blob([
|
||||
nonBlockingCode.toString() + "; nonBlockingCode();",
|
||||
]);
|
||||
ok(blob, "Blob has been created");
|
||||
|
||||
let blobURL = w.URL.createObjectURL(blob);
|
||||
|
|
@ -73,5 +75,5 @@ CookiePolicyHelper.runTest("BroadcastChannel in workers", {
|
|||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,17 +2,27 @@ CookiePolicyHelper.runTest("document.cookies", {
|
|||
cookieJarAccessAllowed: async _ => {
|
||||
let hasCookie = !!content.document.cookie.length;
|
||||
|
||||
await content.fetch("server.sjs").then(r => r.text()).then(text => {
|
||||
is(text, hasCookie ? "cookie-present" : "cookie-not-present", "document.cookie is consistent with fetch requests");
|
||||
});
|
||||
await content
|
||||
.fetch("server.sjs")
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
is(
|
||||
text,
|
||||
hasCookie ? "cookie-present" : "cookie-not-present",
|
||||
"document.cookie is consistent with fetch requests"
|
||||
);
|
||||
});
|
||||
|
||||
content.document.cookie = "name=value";
|
||||
ok(content.document.cookie.includes("name=value"), "Some cookies for me");
|
||||
ok(content.document.cookie.includes("foopy=1"), "Some cookies for me");
|
||||
|
||||
await content.fetch("server.sjs").then(r => r.text()).then(text => {
|
||||
is(text, "cookie-present", "We should have cookies");
|
||||
});
|
||||
await content
|
||||
.fetch("server.sjs")
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
is(text, "cookie-present", "We should have cookies");
|
||||
});
|
||||
|
||||
ok(!!content.document.cookie.length, "Some Cookies for me");
|
||||
},
|
||||
|
|
@ -22,14 +32,20 @@ CookiePolicyHelper.runTest("document.cookies", {
|
|||
content.document.cookie = "name=value";
|
||||
is(content.document.cookie, "", "No cookies for me");
|
||||
|
||||
await content.fetch("server.sjs").then(r => r.text()).then(text => {
|
||||
is(text, "cookie-not-present", "We should not have cookies");
|
||||
});
|
||||
await content
|
||||
.fetch("server.sjs")
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
is(text, "cookie-not-present", "We should not have cookies");
|
||||
});
|
||||
// Let's do it twice.
|
||||
await content.fetch("server.sjs").then(r => r.text()).then(text => {
|
||||
is(text, "cookie-not-present", "We should not have cookies");
|
||||
});
|
||||
await content
|
||||
.fetch("server.sjs")
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
is(text, "cookie-not-present", "We should not have cookies");
|
||||
});
|
||||
|
||||
is(content.document.cookie, "", "Still no cookies for me");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
CookiePolicyHelper.runTest("DOM Cache", {
|
||||
cookieJarAccessAllowed: async w => {
|
||||
await w.caches.open("wow").then(
|
||||
_ => { ok(true, "DOM Cache can be used!"); },
|
||||
_ => { ok(false, "DOM Cache can be used!"); });
|
||||
_ => {
|
||||
ok(true, "DOM Cache can be used!");
|
||||
},
|
||||
_ => {
|
||||
ok(false, "DOM Cache can be used!");
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
cookieJarAccessDenied: async w => {
|
||||
await w.caches.open("wow").then(
|
||||
_ => { ok(false, "DOM Cache cannot be used!"); },
|
||||
_ => { ok(true, "DOM Cache cannot be used!"); });
|
||||
_ => {
|
||||
ok(false, "DOM Cache cannot be used!");
|
||||
},
|
||||
_ => {
|
||||
ok(true, "DOM Cache cannot be used!");
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
|||
// returns the newly opened tab
|
||||
async function openTabInUserContext(uri, userContextId) {
|
||||
// open the tab in the correct userContextId
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, uri, {userContextId});
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, uri, { userContextId });
|
||||
|
||||
// select tab and make sure its browser is focused
|
||||
gBrowser.selectedTab = tab;
|
||||
|
|
@ -24,15 +24,16 @@ async function openTabInUserContext(uri, userContextId) {
|
|||
// wait for tab load
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
return {tab, browser};
|
||||
return { tab, browser };
|
||||
}
|
||||
|
||||
add_task(async function setup() {
|
||||
// make sure userContext is enabled.
|
||||
await new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.userContext.enabled", true]
|
||||
]}, resolve);
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ set: [["privacy.userContext.enabled", true]] },
|
||||
resolve
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -41,15 +42,17 @@ add_task(async function test() {
|
|||
// which should only be visible in that context
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// open our tab in the given user context
|
||||
let {tab, browser} = await openTabInUserContext(TEST_URL, userContextId);
|
||||
let { tab, browser } = await openTabInUserContext(TEST_URL, userContextId);
|
||||
|
||||
await ContentTask.spawn(browser,
|
||||
{names: COOKIE_NAMES, value: USER_CONTEXTS[userContextId]},
|
||||
function(opts) {
|
||||
for (let name of opts.names) {
|
||||
content.document.cookie = name + "=" + opts.value;
|
||||
}
|
||||
});
|
||||
await ContentTask.spawn(
|
||||
browser,
|
||||
{ names: COOKIE_NAMES, value: USER_CONTEXTS[userContextId] },
|
||||
function(opts) {
|
||||
for (let name of opts.names) {
|
||||
content.document.cookie = name + "=" + opts.value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// remove the tab
|
||||
gBrowser.removeTab(tab);
|
||||
|
|
@ -59,7 +62,7 @@ add_task(async function test() {
|
|||
await checkCookies(expectedValues, "before removal");
|
||||
|
||||
// remove cookies that belongs to user context id #1
|
||||
cm.removeCookiesWithOriginAttributes(JSON.stringify({userContextId: 1}));
|
||||
cm.removeCookiesWithOriginAttributes(JSON.stringify({ userContextId: 1 }));
|
||||
|
||||
expectedValues[1] = undefined;
|
||||
await checkCookies(expectedValues, "after removal");
|
||||
|
|
@ -72,18 +75,25 @@ async function checkCookies(expectedValues, time) {
|
|||
|
||||
let expectedValue = expectedValues[userContextId];
|
||||
for (let name of COOKIE_NAMES) {
|
||||
is(cookiesFromTitle[name], expectedValue,
|
||||
`User context ${userContextId}: ${name} should be correct from title ${time}`);
|
||||
is(cookiesFromManager[name], expectedValue,
|
||||
`User context ${userContextId}: ${name} should be correct from manager ${time}`);
|
||||
is(
|
||||
cookiesFromTitle[name],
|
||||
expectedValue,
|
||||
`User context ${userContextId}: ${name} should be correct from title ${time}`
|
||||
);
|
||||
is(
|
||||
cookiesFromManager[name],
|
||||
expectedValue,
|
||||
`User context ${userContextId}: ${name} should be correct from manager ${time}`
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function getCookiesFromManager(userContextId) {
|
||||
let cookies = {};
|
||||
let enumerator = cm.getCookiesWithOriginAttributes(JSON.stringify({userContextId}));
|
||||
let enumerator = cm.getCookiesWithOriginAttributes(
|
||||
JSON.stringify({ userContextId })
|
||||
);
|
||||
for (let cookie of enumerator) {
|
||||
cookies[cookie.name] = cookie.value;
|
||||
}
|
||||
|
|
@ -91,7 +101,7 @@ function getCookiesFromManager(userContextId) {
|
|||
}
|
||||
|
||||
async function getCookiesFromJS(userContextId) {
|
||||
let {tab, browser} = await openTabInUserContext(TEST_URL, userContextId);
|
||||
let { tab, browser } = await openTabInUserContext(TEST_URL, userContextId);
|
||||
|
||||
// get the cookies
|
||||
let cookieString = await ContentTask.spawn(browser, null, function() {
|
||||
|
|
|
|||
|
|
@ -7,18 +7,37 @@ CookiePolicyHelper.runTest("ServiceWorker", {
|
|||
],
|
||||
|
||||
cookieJarAccessAllowed: async w => {
|
||||
await w.navigator.serviceWorker.register("file_empty.js").then(
|
||||
reg => { ok(true, "ServiceWorker can be used!"); return reg; },
|
||||
_ => { ok(false, "ServiceWorker cannot be used! " + _); }).then(
|
||||
reg => reg.unregister(),
|
||||
_ => { ok(false, "unregister failed"); }).
|
||||
catch(e => ok(false, "Promise rejected: " + e));
|
||||
await w.navigator.serviceWorker
|
||||
.register("file_empty.js")
|
||||
.then(
|
||||
reg => {
|
||||
ok(true, "ServiceWorker can be used!");
|
||||
return reg;
|
||||
},
|
||||
_ => {
|
||||
ok(false, "ServiceWorker cannot be used! " + _);
|
||||
}
|
||||
)
|
||||
.then(
|
||||
reg => reg.unregister(),
|
||||
_ => {
|
||||
ok(false, "unregister failed");
|
||||
}
|
||||
)
|
||||
.catch(e => ok(false, "Promise rejected: " + e));
|
||||
},
|
||||
|
||||
cookieJarAccessDenied: async w => {
|
||||
await w.navigator.serviceWorker.register("file_empty.js").then(
|
||||
_ => { ok(false, "ServiceWorker cannot be used!"); },
|
||||
_ => { ok(true, "ServiceWorker cannot be used!"); }).
|
||||
catch(e => ok(false, "Promise rejected: " + e));
|
||||
await w.navigator.serviceWorker
|
||||
.register("file_empty.js")
|
||||
.then(
|
||||
_ => {
|
||||
ok(false, "ServiceWorker cannot be used!");
|
||||
},
|
||||
_ => {
|
||||
ok(true, "ServiceWorker cannot be used!");
|
||||
}
|
||||
)
|
||||
.catch(e => ok(false, "Promise rejected: " + e));
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,52 +20,60 @@ const TEST_TOP_PAGE = TEST_DOMAIN + TEST_PATH + "file_empty.html";
|
|||
this.CookiePolicyHelper = {
|
||||
runTest(testName, config) {
|
||||
// Testing allowed to blocked by cookie behavior
|
||||
this._createTest(testName,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.cookieJarAccessDenied,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_ACCEPT,
|
||||
toBehavior: BEHAVIOR_REJECT,
|
||||
fromPermission: PERM_DEFAULT,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.cookieJarAccessDenied,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_ACCEPT,
|
||||
toBehavior: BEHAVIOR_REJECT,
|
||||
fromPermission: PERM_DEFAULT,
|
||||
toPermission: PERM_DEFAULT,
|
||||
}
|
||||
);
|
||||
|
||||
// Testing blocked to allowed by cookie behavior
|
||||
this._createTest(testName,
|
||||
config.cookieJarAccessDenied,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_REJECT,
|
||||
toBehavior: BEHAVIOR_ACCEPT,
|
||||
fromPermission: PERM_DEFAULT,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessDenied,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_REJECT,
|
||||
toBehavior: BEHAVIOR_ACCEPT,
|
||||
fromPermission: PERM_DEFAULT,
|
||||
toPermission: PERM_DEFAULT,
|
||||
}
|
||||
);
|
||||
|
||||
// Testing allowed to blocked by cookie permission
|
||||
this._createTest(testName,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.cookieJarAccessDenied,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_REJECT,
|
||||
toBehavior: BEHAVIOR_REJECT,
|
||||
fromPermission: PERM_ALLOW,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.cookieJarAccessDenied,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_REJECT,
|
||||
toBehavior: BEHAVIOR_REJECT,
|
||||
fromPermission: PERM_ALLOW,
|
||||
toPermission: PERM_DEFAULT,
|
||||
}
|
||||
);
|
||||
|
||||
// Testing blocked to allowed by cookie permission
|
||||
this._createTest(testName,
|
||||
config.cookieJarAccessDenied,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_ACCEPT,
|
||||
toBehavior: BEHAVIOR_ACCEPT,
|
||||
fromPermission: PERM_DENY,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessDenied,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.prefs,
|
||||
{
|
||||
fromBehavior: BEHAVIOR_ACCEPT,
|
||||
toBehavior: BEHAVIOR_ACCEPT,
|
||||
fromPermission: PERM_DENY,
|
||||
toPermission: PERM_DEFAULT,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_createTest(testName, goodCb, badCb, prefs, config) {
|
||||
|
|
@ -75,16 +83,16 @@ this.CookiePolicyHelper = {
|
|||
await SpecialPowers.flushPrefEnv();
|
||||
|
||||
if (prefs) {
|
||||
await SpecialPowers.pushPrefEnv({"set": prefs });
|
||||
await SpecialPowers.pushPrefEnv({ set: prefs });
|
||||
}
|
||||
|
||||
let uri = Services.io.newURI(TEST_DOMAIN);
|
||||
|
||||
// Let's set the first cookie pref.
|
||||
Services.perms.add(uri, "cookie", config.fromPermission);
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", config.fromBehavior],
|
||||
]});
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", config.fromBehavior]],
|
||||
});
|
||||
|
||||
// Let's open a tab and load content.
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
|
||||
|
|
@ -94,10 +102,9 @@ this.CookiePolicyHelper = {
|
|||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Let's create an iframe.
|
||||
await ContentTask.spawn(browser, { url: TEST_TOP_PAGE },
|
||||
async obj => {
|
||||
await ContentTask.spawn(browser, { url: TEST_TOP_PAGE }, async obj => {
|
||||
return new content.Promise(resolve => {
|
||||
let ifr = content.document.createElement('iframe');
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.setAttribute("id", "iframe");
|
||||
ifr.src = obj.url;
|
||||
ifr.onload = resolve;
|
||||
|
|
@ -106,36 +113,50 @@ this.CookiePolicyHelper = {
|
|||
});
|
||||
|
||||
// Let's exec the "good" callback.
|
||||
info("Executing the test after setting the cookie behavior to " + config.fromBehavior + " and permission to " + config.fromPermission);
|
||||
await ContentTask.spawn(browser,
|
||||
{ callback: goodCb.toString() },
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.callback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
await runnable(content);
|
||||
info(
|
||||
"Executing the test after setting the cookie behavior to " +
|
||||
config.fromBehavior +
|
||||
" and permission to " +
|
||||
config.fromPermission
|
||||
);
|
||||
await ContentTask.spawn(
|
||||
browser,
|
||||
{ callback: goodCb.toString() },
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.callback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
await runnable(content);
|
||||
|
||||
let ifr = content.document.getElementById("iframe");
|
||||
await runnable(ifr.contentWindow);
|
||||
});
|
||||
let ifr = content.document.getElementById("iframe");
|
||||
await runnable(ifr.contentWindow);
|
||||
}
|
||||
);
|
||||
|
||||
// Now, let's change the cookie settings
|
||||
Services.perms.add(uri, "cookie", config.toPermission);
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", config.toBehavior],
|
||||
]});
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", config.toBehavior]],
|
||||
});
|
||||
|
||||
// We still want the good callback to succeed.
|
||||
info("Executing the test after setting the cookie behavior to " + config.toBehavior + " and permission to " + config.toPermission);
|
||||
await ContentTask.spawn(browser,
|
||||
{ callback: goodCb.toString() },
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.callback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
await runnable(content);
|
||||
info(
|
||||
"Executing the test after setting the cookie behavior to " +
|
||||
config.toBehavior +
|
||||
" and permission to " +
|
||||
config.toPermission
|
||||
);
|
||||
await ContentTask.spawn(
|
||||
browser,
|
||||
{ callback: goodCb.toString() },
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.callback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
await runnable(content);
|
||||
|
||||
let ifr = content.document.getElementById("iframe");
|
||||
await runnable(ifr.contentWindow);
|
||||
});
|
||||
let ifr = content.document.getElementById("iframe");
|
||||
await runnable(ifr.contentWindow);
|
||||
}
|
||||
);
|
||||
|
||||
// Let's close the tab.
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
|
@ -149,20 +170,25 @@ this.CookiePolicyHelper = {
|
|||
|
||||
// Let's exec the "bad" callback.
|
||||
info("Executing the test in a new tab");
|
||||
await ContentTask.spawn(browser,
|
||||
{ callback: badCb.toString() },
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.callback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
await runnable(content);
|
||||
});
|
||||
await ContentTask.spawn(
|
||||
browser,
|
||||
{ callback: badCb.toString() },
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.callback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
await runnable(content);
|
||||
}
|
||||
);
|
||||
|
||||
// Let's close the tab.
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
||||
// Cleanup.
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, resolve);
|
||||
Services.clearData.deleteData(
|
||||
Ci.nsIClearDataService.CLEAR_ALL,
|
||||
resolve
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,13 +6,18 @@ async function cleanupData() {
|
|||
const chromeScript = SpecialPowers.loadChromeScript(_ => {
|
||||
// eslint-disable-next-line no-undef
|
||||
addMessageListener("go", __ => {
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
Services.clearData.deleteData(Services.clearData.CLEAR_COOKIES |
|
||||
Services.clearData.CLEAR_ALL_CACHES |
|
||||
Services.clearData.CLEAR_DOM_STORAGES, ___ => {
|
||||
// eslint-disable-next-line no-undef
|
||||
sendAsyncMessage("done");
|
||||
});
|
||||
const { Services } = ChromeUtils.import(
|
||||
"resource://gre/modules/Services.jsm"
|
||||
);
|
||||
Services.clearData.deleteData(
|
||||
Services.clearData.CLEAR_COOKIES |
|
||||
Services.clearData.CLEAR_ALL_CACHES |
|
||||
Services.clearData.CLEAR_DOM_STORAGES,
|
||||
___ => {
|
||||
// eslint-disable-next-line no-undef
|
||||
sendAsyncMessage("done");
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -26,23 +31,33 @@ async function cleanupData() {
|
|||
}
|
||||
|
||||
async function checkLastRequest(type, state) {
|
||||
let json = await fetch("cookie.sjs?last&" + Math.random()).then(r => r.json());
|
||||
let json = await fetch("cookie.sjs?last&" + Math.random()).then(r =>
|
||||
r.json()
|
||||
);
|
||||
is(json.type, type, "Type: " + type);
|
||||
is(json.hasCookie, state == ALLOWED, "Fetch has cookies");
|
||||
}
|
||||
|
||||
async function runTests(currentTest) {
|
||||
await cleanupData();
|
||||
await SpecialPowers.pushPrefEnv({ set: [["network.cookie.cookieBehavior", 2]] });
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", 2]],
|
||||
});
|
||||
let windowBlocked = window.open("cookie.sjs?window&" + Math.random());
|
||||
await new Promise(resolve => { windowBlocked.onload = resolve; });
|
||||
await new Promise(resolve => {
|
||||
windowBlocked.onload = resolve;
|
||||
});
|
||||
await currentTest(windowBlocked, BLOCKED);
|
||||
windowBlocked.close();
|
||||
|
||||
await cleanupData();
|
||||
await SpecialPowers.pushPrefEnv({ set: [["network.cookie.cookieBehavior", 1]] });
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", 1]],
|
||||
});
|
||||
let windowAllowed = window.open("cookie.sjs?window&" + Math.random());
|
||||
await new Promise(resolve => { windowAllowed.onload = resolve; });
|
||||
await new Promise(resolve => {
|
||||
windowAllowed.onload = resolve;
|
||||
});
|
||||
await currentTest(windowAllowed, ALLOWED);
|
||||
windowAllowed.close();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const URI = Services.io.newURI("http://example.org/");
|
||||
|
||||
const cs = Cc["@mozilla.org/cookieService;1"]
|
||||
.getService(Ci.nsICookieService);
|
||||
const cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
|
||||
function run_test() {
|
||||
// Allow all cookies.
|
||||
|
|
@ -14,29 +13,44 @@ function run_test() {
|
|||
|
||||
// Add a new cookie.
|
||||
setCookie("foo=bar", {
|
||||
type: "added", isSession: true, isSecure: false, isHttpOnly: false,
|
||||
type: "added",
|
||||
isSession: true,
|
||||
isSecure: false,
|
||||
isHttpOnly: false,
|
||||
});
|
||||
|
||||
// Update cookie with isHttpOnly=true.
|
||||
setCookie("foo=bar; HttpOnly", {
|
||||
type: "changed", isSession: true, isSecure: false, isHttpOnly: true,
|
||||
type: "changed",
|
||||
isSession: true,
|
||||
isSecure: false,
|
||||
isHttpOnly: true,
|
||||
});
|
||||
|
||||
// Update cookie with isSecure=true.
|
||||
setCookie("foo=bar; Secure", {
|
||||
type: "changed", isSession: true, isSecure: true, isHttpOnly: false,
|
||||
type: "changed",
|
||||
isSession: true,
|
||||
isSecure: true,
|
||||
isHttpOnly: false,
|
||||
});
|
||||
|
||||
// Update cookie with isSession=false.
|
||||
let expiry = new Date();
|
||||
expiry.setUTCFullYear(expiry.getUTCFullYear() + 2);
|
||||
setCookie(`foo=bar; Expires=${expiry.toGMTString()}`, {
|
||||
type: "changed", isSession: false, isSecure: false, isHttpOnly: false,
|
||||
type: "changed",
|
||||
isSession: false,
|
||||
isSecure: false,
|
||||
isHttpOnly: false,
|
||||
});
|
||||
|
||||
// Reset cookie.
|
||||
setCookie("foo=bar", {
|
||||
type: "changed", isSession: true, isSecure: false, isHttpOnly: false,
|
||||
type: "changed",
|
||||
isSession: true,
|
||||
isSecure: false,
|
||||
isHttpOnly: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
do_get_profile();
|
||||
const dirSvc = Services.dirsvc;
|
||||
|
|
@ -7,52 +7,66 @@ let dbFile = dirSvc.get("ProfD", Ci.nsIFile);
|
|||
dbFile.append("cookies.sqlite");
|
||||
|
||||
let storage = Services.storage;
|
||||
let properties = Cc["@mozilla.org/hash-property-bag;1"].
|
||||
createInstance(Ci.nsIWritablePropertyBag);
|
||||
let properties = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
|
||||
Ci.nsIWritablePropertyBag
|
||||
);
|
||||
properties.setProperty("shared", true);
|
||||
let conn = storage.openDatabase(dbFile);
|
||||
|
||||
// Write the schema v7 to the database.
|
||||
conn.schemaVersion = 7;
|
||||
conn.executeSimpleSQL("CREATE TABLE moz_cookies (" +
|
||||
"id INTEGER PRIMARY KEY, " +
|
||||
"baseDomain TEXT, " +
|
||||
"originAttributes TEXT NOT NULL DEFAULT '', " +
|
||||
"name TEXT, " +
|
||||
"value TEXT, " +
|
||||
"host TEXT, " +
|
||||
"path TEXT, " +
|
||||
"expiry INTEGER, " +
|
||||
"lastAccessed INTEGER, " +
|
||||
"creationTime INTEGER, " +
|
||||
"isSecure INTEGER, " +
|
||||
"isHttpOnly INTEGER, " +
|
||||
"appId INTEGER DEFAULT 0, " +
|
||||
"inBrowserElement INTEGER DEFAULT 0, " +
|
||||
"CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
|
||||
")");
|
||||
conn.executeSimpleSQL("CREATE INDEX moz_basedomain ON moz_cookies (baseDomain, " +
|
||||
"originAttributes)");
|
||||
conn.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies (" +
|
||||
"id INTEGER PRIMARY KEY, " +
|
||||
"baseDomain TEXT, " +
|
||||
"originAttributes TEXT NOT NULL DEFAULT '', " +
|
||||
"name TEXT, " +
|
||||
"value TEXT, " +
|
||||
"host TEXT, " +
|
||||
"path TEXT, " +
|
||||
"expiry INTEGER, " +
|
||||
"lastAccessed INTEGER, " +
|
||||
"creationTime INTEGER, " +
|
||||
"isSecure INTEGER, " +
|
||||
"isHttpOnly INTEGER, " +
|
||||
"appId INTEGER DEFAULT 0, " +
|
||||
"inBrowserElement INTEGER DEFAULT 0, " +
|
||||
"CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
|
||||
")"
|
||||
);
|
||||
conn.executeSimpleSQL(
|
||||
"CREATE INDEX moz_basedomain ON moz_cookies (baseDomain, " +
|
||||
"originAttributes)"
|
||||
);
|
||||
|
||||
conn.executeSimpleSQL("PRAGMA synchronous = OFF");
|
||||
conn.executeSimpleSQL("PRAGMA journal_mode = WAL");
|
||||
conn.executeSimpleSQL("PRAGMA wal_autocheckpoint = 16");
|
||||
|
||||
let now = Date.now();
|
||||
conn.executeSimpleSQL("INSERT INTO moz_cookies(" +
|
||||
"baseDomain, host, name, value, path, expiry, " +
|
||||
"lastAccessed, creationTime, isSecure, isHttpOnly) VALUES (" +
|
||||
"'foo.com', '.foo.com', 'foo', 'bar=baz', '/', " +
|
||||
now + ", " + now + ", " + now + ", 1, 1)");
|
||||
conn.executeSimpleSQL(
|
||||
"INSERT INTO moz_cookies(" +
|
||||
"baseDomain, host, name, value, path, expiry, " +
|
||||
"lastAccessed, creationTime, isSecure, isHttpOnly) VALUES (" +
|
||||
"'foo.com', '.foo.com', 'foo', 'bar=baz', '/', " +
|
||||
now +
|
||||
", " +
|
||||
now +
|
||||
", " +
|
||||
now +
|
||||
", 1, 1)"
|
||||
);
|
||||
|
||||
// Now start the cookie service, and then check the fields in the table.
|
||||
// Get sessionEnumerator to wait for the initialization in cookie thread
|
||||
const enumerator = Services.cookies.sessionEnumerator;
|
||||
|
||||
Assert.equal(conn.schemaVersion, 10);
|
||||
let stmt = conn.createStatement("SELECT sql FROM sqlite_master " +
|
||||
"WHERE type = 'table' AND " +
|
||||
" name = 'moz_cookies'");
|
||||
let stmt = conn.createStatement(
|
||||
"SELECT sql FROM sqlite_master " +
|
||||
"WHERE type = 'table' AND " +
|
||||
" name = 'moz_cookies'"
|
||||
);
|
||||
try {
|
||||
Assert.ok(stmt.executeStep());
|
||||
let sql = stmt.getString(0);
|
||||
|
|
@ -61,17 +75,25 @@ try {
|
|||
stmt.finalize();
|
||||
}
|
||||
|
||||
stmt = conn.createStatement("SELECT * FROM moz_cookies " +
|
||||
"WHERE baseDomain = 'foo.com' AND " +
|
||||
" host = '.foo.com' AND " +
|
||||
" name = 'foo' AND " +
|
||||
" value = 'bar=baz' AND " +
|
||||
" path = '/' AND " +
|
||||
" expiry = " + now + " AND " +
|
||||
" lastAccessed = " + now + " AND " +
|
||||
" creationTime = " + now + " AND " +
|
||||
" isSecure = 1 AND " +
|
||||
" isHttpOnly = 1");
|
||||
stmt = conn.createStatement(
|
||||
"SELECT * FROM moz_cookies " +
|
||||
"WHERE baseDomain = 'foo.com' AND " +
|
||||
" host = '.foo.com' AND " +
|
||||
" name = 'foo' AND " +
|
||||
" value = 'bar=baz' AND " +
|
||||
" path = '/' AND " +
|
||||
" expiry = " +
|
||||
now +
|
||||
" AND " +
|
||||
" lastAccessed = " +
|
||||
now +
|
||||
" AND " +
|
||||
" creationTime = " +
|
||||
now +
|
||||
" AND " +
|
||||
" isSecure = 1 AND " +
|
||||
" isHttpOnly = 1"
|
||||
);
|
||||
try {
|
||||
Assert.ok(stmt.executeStep());
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function run_test() {
|
||||
// Allow all cookies.
|
||||
|
|
@ -23,4 +23,3 @@ function run_test() {
|
|||
actual = cs.getCookieString(uri, null, null);
|
||||
Assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const BASE_HOSTNAMES = ["example.org", "example.co.uk"];
|
||||
const SUBDOMAINS = ["", "pub.", "www.", "other."];
|
||||
|
|
@ -7,138 +7,178 @@ const cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
|||
const cm = cs.QueryInterface(Ci.nsICookieManager);
|
||||
|
||||
function run_test() {
|
||||
Services.prefs.setIntPref("network.cookie.staleThreshold", 0);
|
||||
add_task(async function() {
|
||||
await test_basic_eviction("example.org");
|
||||
cm.removeAll();
|
||||
});
|
||||
Services.prefs.setIntPref("network.cookie.staleThreshold", 0);
|
||||
add_task(async function() {
|
||||
await test_basic_eviction("example.org");
|
||||
cm.removeAll();
|
||||
});
|
||||
|
||||
run_next_test();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
async function test_basic_eviction(base_host) {
|
||||
Services.prefs.setIntPref("network.cookie.quotaPerHost", 2);
|
||||
Services.prefs.setIntPref("network.cookie.maxPerHost", 5);
|
||||
Services.prefs.setIntPref("network.cookie.quotaPerHost", 2);
|
||||
Services.prefs.setIntPref("network.cookie.maxPerHost", 5);
|
||||
|
||||
const BASE_URI = Services.io.newURI("http://" + base_host);
|
||||
const FOO_PATH = Services.io.newURI("http://" + base_host + "/foo/");
|
||||
const BAR_PATH = Services.io.newURI("http://" + base_host + "/bar/");
|
||||
const BASE_URI = Services.io.newURI("http://" + base_host);
|
||||
const FOO_PATH = Services.io.newURI("http://" + base_host + "/foo/");
|
||||
const BAR_PATH = Services.io.newURI("http://" + base_host + "/bar/");
|
||||
|
||||
await setCookie("session_foo_path_1", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_2", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_3", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_4", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_5", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(["session_foo_path_1",
|
||||
"session_foo_path_2",
|
||||
"session_foo_path_3",
|
||||
"session_foo_path_4",
|
||||
"session_foo_path_5"], BASE_URI);
|
||||
await setCookie("session_foo_path_1", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_2", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_3", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_4", null, "/foo", null, FOO_PATH);
|
||||
await setCookie("session_foo_path_5", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(
|
||||
[
|
||||
"session_foo_path_1",
|
||||
"session_foo_path_2",
|
||||
"session_foo_path_3",
|
||||
"session_foo_path_4",
|
||||
"session_foo_path_5",
|
||||
],
|
||||
BASE_URI
|
||||
);
|
||||
|
||||
// Check if cookies are evicted by creation time.
|
||||
await setCookie("session_foo_path_6", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(["session_foo_path_4",
|
||||
"session_foo_path_5",
|
||||
"session_foo_path_6"], BASE_URI);
|
||||
// Check if cookies are evicted by creation time.
|
||||
await setCookie("session_foo_path_6", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(
|
||||
["session_foo_path_4", "session_foo_path_5", "session_foo_path_6"],
|
||||
BASE_URI
|
||||
);
|
||||
|
||||
await setCookie("session_bar_path_1", null, "/bar", null, BAR_PATH);
|
||||
await setCookie("session_bar_path_2", null, "/bar", null, BAR_PATH);
|
||||
await setCookie("session_bar_path_1", null, "/bar", null, BAR_PATH);
|
||||
await setCookie("session_bar_path_2", null, "/bar", null, BAR_PATH);
|
||||
|
||||
verifyCookies(["session_foo_path_4",
|
||||
"session_foo_path_5",
|
||||
"session_foo_path_6",
|
||||
"session_bar_path_1",
|
||||
"session_bar_path_2"], BASE_URI);
|
||||
verifyCookies(
|
||||
[
|
||||
"session_foo_path_4",
|
||||
"session_foo_path_5",
|
||||
"session_foo_path_6",
|
||||
"session_bar_path_1",
|
||||
"session_bar_path_2",
|
||||
],
|
||||
BASE_URI
|
||||
);
|
||||
|
||||
// Check if cookies are evicted by last accessed time.
|
||||
cs.getCookieString(FOO_PATH, null);
|
||||
await setCookie("session_foo_path_7", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(["session_foo_path_5",
|
||||
"session_foo_path_6",
|
||||
"session_foo_path_7"], BASE_URI);
|
||||
// Check if cookies are evicted by last accessed time.
|
||||
cs.getCookieString(FOO_PATH, null);
|
||||
await setCookie("session_foo_path_7", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(
|
||||
["session_foo_path_5", "session_foo_path_6", "session_foo_path_7"],
|
||||
BASE_URI
|
||||
);
|
||||
|
||||
const EXPIRED_TIME = 3;
|
||||
const EXPIRED_TIME = 3;
|
||||
|
||||
await setCookie("non_session_expired_foo_path_1", null, "/foo", EXPIRED_TIME, FOO_PATH);
|
||||
await setCookie("non_session_expired_foo_path_2", null, "/foo", EXPIRED_TIME, FOO_PATH);
|
||||
verifyCookies(["session_foo_path_5",
|
||||
"session_foo_path_6",
|
||||
"session_foo_path_7",
|
||||
"non_session_expired_foo_path_1",
|
||||
"non_session_expired_foo_path_2"], BASE_URI);
|
||||
await setCookie(
|
||||
"non_session_expired_foo_path_1",
|
||||
null,
|
||||
"/foo",
|
||||
EXPIRED_TIME,
|
||||
FOO_PATH
|
||||
);
|
||||
await setCookie(
|
||||
"non_session_expired_foo_path_2",
|
||||
null,
|
||||
"/foo",
|
||||
EXPIRED_TIME,
|
||||
FOO_PATH
|
||||
);
|
||||
verifyCookies(
|
||||
[
|
||||
"session_foo_path_5",
|
||||
"session_foo_path_6",
|
||||
"session_foo_path_7",
|
||||
"non_session_expired_foo_path_1",
|
||||
"non_session_expired_foo_path_2",
|
||||
],
|
||||
BASE_URI
|
||||
);
|
||||
|
||||
// Check if expired cookies are evicted first.
|
||||
await new Promise(resolve => do_timeout(EXPIRED_TIME * 1000, resolve));
|
||||
await setCookie("session_foo_path_8", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(["session_foo_path_6",
|
||||
"session_foo_path_7",
|
||||
"session_foo_path_8"], BASE_URI);
|
||||
// Check if expired cookies are evicted first.
|
||||
await new Promise(resolve => do_timeout(EXPIRED_TIME * 1000, resolve));
|
||||
await setCookie("session_foo_path_8", null, "/foo", null, FOO_PATH);
|
||||
verifyCookies(
|
||||
["session_foo_path_6", "session_foo_path_7", "session_foo_path_8"],
|
||||
BASE_URI
|
||||
);
|
||||
}
|
||||
|
||||
// Verify that the given cookie names exist, and are ordered from least to most recently accessed
|
||||
function verifyCookies(names, uri) {
|
||||
Assert.equal(cm.countCookiesFromHost(uri.host), names.length);
|
||||
let actual_cookies = [];
|
||||
for (let cookie of cm.getCookiesFromHost(uri.host, {})) {
|
||||
actual_cookies.push(cookie);
|
||||
}
|
||||
if (names.length != actual_cookies.length) {
|
||||
let left = names.filter(function(n) {
|
||||
return actual_cookies.findIndex(function(c) {
|
||||
return c.name == n;
|
||||
}) == -1;
|
||||
});
|
||||
let right = actual_cookies.filter(function(c) {
|
||||
return names.findIndex(function(n) {
|
||||
return c.name == n;
|
||||
}) == -1;
|
||||
}).map(function(c) { return c.name; });
|
||||
if (left.length) {
|
||||
info("unexpected cookies: " + left);
|
||||
}
|
||||
if (right.length) {
|
||||
info("expected cookies: " + right);
|
||||
}
|
||||
}
|
||||
Assert.equal(names.length, actual_cookies.length);
|
||||
actual_cookies.sort(function(a, b) {
|
||||
if (a.lastAccessed < b.lastAccessed)
|
||||
return -1;
|
||||
if (a.lastAccessed > b.lastAccessed)
|
||||
return 1;
|
||||
return 0;
|
||||
Assert.equal(cm.countCookiesFromHost(uri.host), names.length);
|
||||
let actual_cookies = [];
|
||||
for (let cookie of cm.getCookiesFromHost(uri.host, {})) {
|
||||
actual_cookies.push(cookie);
|
||||
}
|
||||
if (names.length != actual_cookies.length) {
|
||||
let left = names.filter(function(n) {
|
||||
return (
|
||||
actual_cookies.findIndex(function(c) {
|
||||
return c.name == n;
|
||||
}) == -1
|
||||
);
|
||||
});
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
Assert.equal(names[i], actual_cookies[i].name);
|
||||
Assert.equal(names[i].startsWith("session"), actual_cookies[i].isSession);
|
||||
let right = actual_cookies
|
||||
.filter(function(c) {
|
||||
return (
|
||||
names.findIndex(function(n) {
|
||||
return c.name == n;
|
||||
}) == -1
|
||||
);
|
||||
})
|
||||
.map(function(c) {
|
||||
return c.name;
|
||||
});
|
||||
if (left.length) {
|
||||
info("unexpected cookies: " + left);
|
||||
}
|
||||
if (right.length) {
|
||||
info("expected cookies: " + right);
|
||||
}
|
||||
}
|
||||
Assert.equal(names.length, actual_cookies.length);
|
||||
actual_cookies.sort(function(a, b) {
|
||||
if (a.lastAccessed < b.lastAccessed) {
|
||||
return -1;
|
||||
}
|
||||
if (a.lastAccessed > b.lastAccessed) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
Assert.equal(names[i], actual_cookies[i].name);
|
||||
Assert.equal(names[i].startsWith("session"), actual_cookies[i].isSession);
|
||||
}
|
||||
}
|
||||
|
||||
var lastValue = 0;
|
||||
function setCookie(name, domain, path, maxAge, url) {
|
||||
let value = name + "=" + ++lastValue;
|
||||
var s = "setting cookie " + value;
|
||||
if (domain) {
|
||||
value += "; Domain=" + domain;
|
||||
s += " (d=" + domain + ")";
|
||||
}
|
||||
if (path) {
|
||||
value += "; Path=" + path;
|
||||
s += " (p=" + path + ")";
|
||||
}
|
||||
if (maxAge) {
|
||||
value += "; Max-Age=" + maxAge;
|
||||
s += " (non-session)";
|
||||
} else {
|
||||
s += " (session)";
|
||||
}
|
||||
s += " for " + url.spec;
|
||||
info(s);
|
||||
cs.setCookieStringFromHttp(url, null, null, value, null, null);
|
||||
return new Promise(function(resolve) {
|
||||
// Windows XP has low precision timestamps that cause our cookie eviction
|
||||
// algorithm to produce different results from other platforms. We work around
|
||||
// this by ensuring that there's a clear gap between each cookie update.
|
||||
do_timeout(10, resolve);
|
||||
});
|
||||
let value = name + "=" + ++lastValue;
|
||||
var s = "setting cookie " + value;
|
||||
if (domain) {
|
||||
value += "; Domain=" + domain;
|
||||
s += " (d=" + domain + ")";
|
||||
}
|
||||
if (path) {
|
||||
value += "; Path=" + path;
|
||||
s += " (p=" + path + ")";
|
||||
}
|
||||
if (maxAge) {
|
||||
value += "; Max-Age=" + maxAge;
|
||||
s += " (non-session)";
|
||||
} else {
|
||||
s += " (session)";
|
||||
}
|
||||
s += " for " + url.spec;
|
||||
info(s);
|
||||
cs.setCookieStringFromHttp(url, null, null, value, null, null);
|
||||
return new Promise(function(resolve) {
|
||||
// Windows XP has low precision timestamps that cause our cookie eviction
|
||||
// algorithm to produce different results from other platforms. We work around
|
||||
// this by ensuring that there's a clear gap between each cookie update.
|
||||
do_timeout(10, resolve);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function inChildProcess() {
|
||||
return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
|
|
@ -7,8 +7,9 @@ function inChildProcess() {
|
|||
|
||||
function run_test() {
|
||||
// Allow all cookies if the pref service is available in this process.
|
||||
if (!inChildProcess())
|
||||
if (!inChildProcess()) {
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
|
||||
}
|
||||
|
||||
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
|
||||
|
|
@ -21,4 +22,3 @@ function run_test() {
|
|||
let actual = cs.getCookieStringFromHttp(uri, null, null);
|
||||
Assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function inChildProcess() {
|
||||
return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
|
|
@ -7,8 +7,9 @@ function inChildProcess() {
|
|||
|
||||
function run_test() {
|
||||
// Allow all cookies if the pref service is available in this process.
|
||||
if (!inChildProcess())
|
||||
if (!inChildProcess()) {
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
|
||||
}
|
||||
|
||||
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
|
||||
|
|
@ -21,4 +22,3 @@ function run_test() {
|
|||
let actual = cs.getCookieStringFromHttp(uri, null, null);
|
||||
Assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function inChildProcess() {
|
||||
return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
|
|
@ -12,14 +12,16 @@ add_task(async _ => {
|
|||
dbFile.append("cookies.sqlite");
|
||||
|
||||
let storage = Services.storage;
|
||||
let properties = Cc["@mozilla.org/hash-property-bag;1"].
|
||||
createInstance(Ci.nsIWritablePropertyBag);
|
||||
let properties = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
|
||||
Ci.nsIWritablePropertyBag
|
||||
);
|
||||
properties.setProperty("shared", true);
|
||||
let conn = storage.openDatabase(dbFile);
|
||||
|
||||
conn.schemaVersion = 9;
|
||||
conn.executeSimpleSQL("DROP TABLE IF EXISTS moz_cookies");
|
||||
conn.executeSimpleSQL("CREATE TABLE moz_cookies (" +
|
||||
conn.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies (" +
|
||||
"id INTEGER PRIMARY KEY, " +
|
||||
"baseDomain TEXT, " +
|
||||
"originAttributes TEXT NOT NULL DEFAULT '', " +
|
||||
|
|
@ -35,22 +37,32 @@ add_task(async _ => {
|
|||
"inBrowserElement INTEGER DEFAULT 0, " +
|
||||
"sameSite INTEGER DEFAULT 0, " +
|
||||
"CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
|
||||
")");
|
||||
")"
|
||||
);
|
||||
conn.close();
|
||||
|
||||
// Allow all cookies if the pref service is available in this process.
|
||||
if (!inChildProcess()) {
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
|
||||
Services.prefs.setBoolPref("network.cookieSettings.unblocked_for_testing", true);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookieSettings.unblocked_for_testing",
|
||||
true
|
||||
);
|
||||
Services.prefs.setBoolPref("network.cookie.sameSite.laxByDefault", true);
|
||||
Services.prefs.setBoolPref("network.cookie.sameSite.noneRequiresSecure", true);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookie.sameSite.noneRequiresSecure",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
|
||||
let uri = NetUtil.newURI("http://example.org/");
|
||||
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipal(
|
||||
uri,
|
||||
{}
|
||||
);
|
||||
|
||||
let channel = NetUtil.newChannel({
|
||||
uri,
|
||||
|
|
@ -60,18 +72,17 @@ add_task(async _ => {
|
|||
});
|
||||
|
||||
let tests = [
|
||||
{ cookie: "foo=b;max-age=3600, c=d;path=/; sameSite=strict",
|
||||
{
|
||||
cookie: "foo=b;max-age=3600, c=d;path=/; sameSite=strict",
|
||||
sameSite: 2,
|
||||
rawSameSite: 2,
|
||||
},
|
||||
{ cookie: "foo=b;max-age=3600, c=d;path=/; sameSite=lax",
|
||||
{
|
||||
cookie: "foo=b;max-age=3600, c=d;path=/; sameSite=lax",
|
||||
sameSite: 1,
|
||||
rawSameSite: 1,
|
||||
},
|
||||
{ cookie: "foo=b;max-age=3600, c=d;path=/",
|
||||
sameSite: 1,
|
||||
rawSameSite: 0,
|
||||
},
|
||||
{ cookie: "foo=b;max-age=3600, c=d;path=/", sameSite: 1, rawSameSite: 0 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < tests.length; ++i) {
|
||||
|
|
@ -93,7 +104,9 @@ add_task(async _ => {
|
|||
conn = storage.openDatabase(dbFile);
|
||||
Assert.equal(conn.schemaVersion, 10);
|
||||
|
||||
let stmt = conn.createStatement("SELECT sameSite, rawSameSite FROM moz_cookies");
|
||||
let stmt = conn.createStatement(
|
||||
"SELECT sameSite, rawSameSite FROM moz_cookies"
|
||||
);
|
||||
|
||||
let success = stmt.executeStep();
|
||||
Assert.ok(success);
|
||||
|
|
|
|||
|
|
@ -3,23 +3,29 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const {MulticastDNS} = ChromeUtils.import(
|
||||
(AppConstants.platform == "android" && !Services.prefs.getBoolPref("network.mdns.use_js_fallback"))
|
||||
? "resource://gre/modules/MulticastDNSAndroid.jsm"
|
||||
: "resource://gre/modules/MulticastDNS.jsm");
|
||||
const { MulticastDNS } = ChromeUtils.import(
|
||||
AppConstants.platform == "android" &&
|
||||
!Services.prefs.getBoolPref("network.mdns.use_js_fallback")
|
||||
? "resource://gre/modules/MulticastDNSAndroid.jsm"
|
||||
: "resource://gre/modules/MulticastDNS.jsm"
|
||||
);
|
||||
|
||||
const DNSSERVICEINFO_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-info;1";
|
||||
const DNSSERVICEINFO_CONTRACT_ID =
|
||||
"@mozilla.org/toolkit/components/mdnsresponder/dns-info;1";
|
||||
|
||||
function log(aMsg) {
|
||||
dump("-*- nsDNSServiceDiscovery.js : " + aMsg + "\n");
|
||||
}
|
||||
|
||||
function generateUuid() {
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(
|
||||
Ci.nsIUUIDGenerator
|
||||
);
|
||||
return uuidGenerator.generateUUID().toString();
|
||||
}
|
||||
|
||||
|
|
@ -40,9 +46,17 @@ function ListenerWrapper(aListener, aMdns) {
|
|||
ListenerWrapper.prototype = {
|
||||
// Helper function for transforming an Object into nsIDNSServiceInfo.
|
||||
makeServiceInfo(aServiceInfo) {
|
||||
let serviceInfo = Cc[DNSSERVICEINFO_CONTRACT_ID].createInstance(Ci.nsIDNSServiceInfo);
|
||||
let serviceInfo = Cc[DNSSERVICEINFO_CONTRACT_ID].createInstance(
|
||||
Ci.nsIDNSServiceInfo
|
||||
);
|
||||
|
||||
for (let name of ["host", "address", "port", "serviceName", "serviceType"]) {
|
||||
for (let name of [
|
||||
"host",
|
||||
"address",
|
||||
"port",
|
||||
"serviceName",
|
||||
"serviceType",
|
||||
]) {
|
||||
try {
|
||||
serviceInfo[name] = aServiceInfo[name];
|
||||
} catch (e) {
|
||||
|
|
@ -54,10 +68,11 @@ ListenerWrapper.prototype = {
|
|||
try {
|
||||
attributes = _toPropertyBag2(aServiceInfo.attributes);
|
||||
} catch (err) {
|
||||
// Ignore unset attributes in object.
|
||||
log("Caught unset attributes error: " + err + " - " + err.stack);
|
||||
attributes = Cc["@mozilla.org/hash-property-bag;1"]
|
||||
.createInstance(Ci.nsIWritablePropertyBag2);
|
||||
// Ignore unset attributes in object.
|
||||
log("Caught unset attributes error: " + err + " - " + err.stack);
|
||||
attributes = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
|
||||
Ci.nsIWritablePropertyBag2
|
||||
);
|
||||
}
|
||||
serviceInfo.attributes = attributes;
|
||||
|
||||
|
|
@ -113,15 +128,24 @@ ListenerWrapper.prototype = {
|
|||
log("onRegistrationFailed: (" + aErrorCode + ")");
|
||||
this.registrationStarting = false;
|
||||
this.stopRegistration = true;
|
||||
this.listener.onRegistrationFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
|
||||
this.listener.onRegistrationFailed(
|
||||
this.makeServiceInfo(aServiceInfo),
|
||||
aErrorCode
|
||||
);
|
||||
},
|
||||
onUnregistrationFailed(aServiceInfo, aErrorCode) {
|
||||
log("onUnregistrationFailed: (" + aErrorCode + ")");
|
||||
this.listener.onUnregistrationFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
|
||||
this.listener.onUnregistrationFailed(
|
||||
this.makeServiceInfo(aServiceInfo),
|
||||
aErrorCode
|
||||
);
|
||||
},
|
||||
onResolveFailed(aServiceInfo, aErrorCode) {
|
||||
log("onResolveFailed: (" + aErrorCode + ")");
|
||||
this.listener.onResolveFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
|
||||
this.listener.onResolveFailed(
|
||||
this.makeServiceInfo(aServiceInfo),
|
||||
aErrorCode
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -131,7 +155,10 @@ function nsDNSServiceDiscovery() {
|
|||
}
|
||||
|
||||
nsDNSServiceDiscovery.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIDNSServiceDiscovery]),
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsIDNSServiceDiscovery,
|
||||
]),
|
||||
|
||||
startDiscovery(aServiceType, aListener) {
|
||||
log("startDiscovery");
|
||||
|
|
@ -141,13 +168,13 @@ nsDNSServiceDiscovery.prototype = {
|
|||
|
||||
return {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsICancelable]),
|
||||
cancel: (function() {
|
||||
cancel: function() {
|
||||
if (this.discoveryStarting || this.stopDiscovery) {
|
||||
this.stopDiscovery = true;
|
||||
return;
|
||||
}
|
||||
this.mdns.stopDiscovery(aServiceType, listener);
|
||||
}).bind(listener),
|
||||
}.bind(listener),
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -159,13 +186,13 @@ nsDNSServiceDiscovery.prototype = {
|
|||
|
||||
return {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsICancelable]),
|
||||
cancel: (function() {
|
||||
cancel: function() {
|
||||
if (this.registrationStarting || this.stopRegistration) {
|
||||
this.stopRegistration = true;
|
||||
return;
|
||||
}
|
||||
this.mdns.unregisterService(aServiceInfo, listener);
|
||||
}).bind(listener),
|
||||
}.bind(listener),
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -182,8 +209,9 @@ function _toPropertyBag2(obj) {
|
|||
return obj.QueryInterface(Ci.nsIPropertyBag2);
|
||||
}
|
||||
|
||||
let result = Cc["@mozilla.org/hash-property-bag;1"]
|
||||
.createInstance(Ci.nsIWritablePropertyBag2);
|
||||
let result = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
|
||||
Ci.nsIWritablePropertyBag2
|
||||
);
|
||||
for (let name in obj) {
|
||||
result.setPropertyAsAString(name, obj[name]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,18 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["MulticastDNS"];
|
||||
|
||||
const {EventDispatcher} = ChromeUtils.import("resource://gre/modules/Messaging.jsm");
|
||||
const { EventDispatcher } = ChromeUtils.import(
|
||||
"resource://gre/modules/Messaging.jsm"
|
||||
);
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
var log = function(s) {};
|
||||
if (DEBUG) {
|
||||
log = ChromeUtils.import("resource://gre/modules/AndroidLog.jsm", {})
|
||||
.AndroidLog.d.bind(null, "MulticastDNS");
|
||||
log = ChromeUtils.import(
|
||||
"resource://gre/modules/AndroidLog.jsm",
|
||||
{}
|
||||
).AndroidLog.d.bind(null, "MulticastDNS");
|
||||
}
|
||||
|
||||
const FAILURE_INTERNAL_ERROR = -65537;
|
||||
|
|
@ -28,18 +32,20 @@ function send(type, data, callback) {
|
|||
for (let i in data) {
|
||||
try {
|
||||
msg[i] = data[i];
|
||||
} catch (e) {
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
EventDispatcher.instance.sendRequestForResult(msg)
|
||||
.then(result => callback(result, null),
|
||||
err => callback(null, typeof err === "number" ? err : FAILURE_INTERNAL_ERROR));
|
||||
EventDispatcher.instance
|
||||
.sendRequestForResult(msg)
|
||||
.then(
|
||||
result => callback(result, null),
|
||||
err =>
|
||||
callback(null, typeof err === "number" ? err : FAILURE_INTERNAL_ERROR)
|
||||
);
|
||||
}
|
||||
|
||||
// Receives service found/lost event from NsdManager
|
||||
function ServiceManager() {
|
||||
}
|
||||
function ServiceManager() {}
|
||||
|
||||
ServiceManager.prototype = {
|
||||
listeners: {},
|
||||
|
|
@ -145,11 +151,11 @@ function parsePropertyBag2(bag) {
|
|||
}
|
||||
|
||||
let attributes = [];
|
||||
for (let {name} of bag.enumerator) {
|
||||
for (let { name } of bag.enumerator) {
|
||||
let value = bag.getPropertyAsACString(name);
|
||||
attributes.push({
|
||||
"name": name,
|
||||
"value": value,
|
||||
name,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,20 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["DNSPacket"];
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const {DataReader} = ChromeUtils.import("resource://gre/modules/DataReader.jsm");
|
||||
const {DataWriter} = ChromeUtils.import("resource://gre/modules/DataWriter.jsm");
|
||||
const {DNSRecord} = ChromeUtils.import("resource://gre/modules/DNSRecord.jsm");
|
||||
const {DNSResourceRecord} = ChromeUtils.import("resource://gre/modules/DNSResourceRecord.jsm");
|
||||
const { DataReader } = ChromeUtils.import(
|
||||
"resource://gre/modules/DataReader.jsm"
|
||||
);
|
||||
const { DataWriter } = ChromeUtils.import(
|
||||
"resource://gre/modules/DataWriter.jsm"
|
||||
);
|
||||
const { DNSRecord } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSRecord.jsm"
|
||||
);
|
||||
const { DNSResourceRecord } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSResourceRecord.jsm"
|
||||
);
|
||||
|
||||
const DEBUG = true;
|
||||
|
||||
|
|
@ -25,7 +33,7 @@ let DNS_PACKET_SECTION_TYPES = [
|
|||
"QD", // Question
|
||||
"AN", // Answer
|
||||
"NS", // Authority
|
||||
"AR", // Additional
|
||||
"AR", // Additional
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -125,7 +133,7 @@ class DNSPacket {
|
|||
this._flags = _valueToFlags(0x0000);
|
||||
this._records = {};
|
||||
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
DNS_PACKET_SECTION_TYPES.forEach(sectionType => {
|
||||
this._records[sectionType] = [];
|
||||
});
|
||||
}
|
||||
|
|
@ -142,20 +150,24 @@ class DNSPacket {
|
|||
let recordCounts = {};
|
||||
|
||||
// Parse the record counts.
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
DNS_PACKET_SECTION_TYPES.forEach(sectionType => {
|
||||
recordCounts[sectionType] = reader.getValue(2);
|
||||
});
|
||||
|
||||
// Parse the actual records.
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
DNS_PACKET_SECTION_TYPES.forEach(sectionType => {
|
||||
let recordCount = recordCounts[sectionType];
|
||||
for (let i = 0; i < recordCount; i++) {
|
||||
if (sectionType === "QD") {
|
||||
packet.addRecord(sectionType,
|
||||
DNSRecord.parseFromPacketReader(reader));
|
||||
packet.addRecord(
|
||||
sectionType,
|
||||
DNSRecord.parseFromPacketReader(reader)
|
||||
);
|
||||
} else {
|
||||
packet.addRecord(sectionType,
|
||||
DNSResourceRecord.parseFromPacketReader(reader));
|
||||
packet.addRecord(
|
||||
sectionType,
|
||||
DNSResourceRecord.parseFromPacketReader(reader)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -182,7 +194,7 @@ class DNSPacket {
|
|||
getRecords(sectionTypes, recordType) {
|
||||
let records = [];
|
||||
|
||||
sectionTypes.forEach((sectionType) => {
|
||||
sectionTypes.forEach(sectionType => {
|
||||
records = records.concat(this._records[sectionType]);
|
||||
});
|
||||
|
||||
|
|
@ -203,13 +215,13 @@ class DNSPacket {
|
|||
writer.putValue(_flagsToValue(this._flags), 2);
|
||||
|
||||
// Write lengths of record sections (2 bytes each)
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
DNS_PACKET_SECTION_TYPES.forEach(sectionType => {
|
||||
writer.putValue(this._records[sectionType].length, 2);
|
||||
});
|
||||
|
||||
// Write records
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
this._records[sectionType].forEach((record) => {
|
||||
DNS_PACKET_SECTION_TYPES.forEach(sectionType => {
|
||||
this._records[sectionType].forEach(record => {
|
||||
writer.putBytes(record.serialize());
|
||||
});
|
||||
});
|
||||
|
|
@ -222,12 +234,12 @@ class DNSPacket {
|
|||
}
|
||||
|
||||
toJSONObject() {
|
||||
let result = {flags: this._flags};
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
let result = { flags: this._flags };
|
||||
DNS_PACKET_SECTION_TYPES.forEach(sectionType => {
|
||||
result[sectionType] = [];
|
||||
|
||||
let records = this._records[sectionType];
|
||||
records.forEach((record) => {
|
||||
records.forEach(record => {
|
||||
result[sectionType].push(record.toJSONObject());
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,22 +8,26 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["DNSRecord"];
|
||||
|
||||
const {DataWriter} = ChromeUtils.import("resource://gre/modules/DataWriter.jsm");
|
||||
const {DNS_CLASS_CODES, DNS_RECORD_TYPES} = ChromeUtils.import("resource://gre/modules/DNSTypes.jsm");
|
||||
const { DataWriter } = ChromeUtils.import(
|
||||
"resource://gre/modules/DataWriter.jsm"
|
||||
);
|
||||
const { DNS_CLASS_CODES, DNS_RECORD_TYPES } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSTypes.jsm"
|
||||
);
|
||||
|
||||
class DNSRecord {
|
||||
constructor(properties = {}) {
|
||||
this.name = properties.name || "";
|
||||
this.name = properties.name || "";
|
||||
this.recordType = properties.recordType || DNS_RECORD_TYPES.ANY;
|
||||
this.classCode = properties.classCode || DNS_CLASS_CODES.IN;
|
||||
this.classCode = properties.classCode || DNS_CLASS_CODES.IN;
|
||||
this.cacheFlush = properties.cacheFlush || false;
|
||||
}
|
||||
|
||||
static parseFromPacketReader(reader) {
|
||||
let name = reader.getLabel();
|
||||
let name = reader.getLabel();
|
||||
let recordType = reader.getValue(2);
|
||||
let classCode = reader.getValue(2);
|
||||
let cacheFlush = !!((classCode & 0x8000));
|
||||
let classCode = reader.getValue(2);
|
||||
let cacheFlush = !!(classCode & 0x8000);
|
||||
classCode &= 0xff;
|
||||
|
||||
return new this({
|
||||
|
|
|
|||
|
|
@ -8,10 +8,18 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["DNSResourceRecord"];
|
||||
|
||||
const {DataReader} = ChromeUtils.import("resource://gre/modules/DataReader.jsm");
|
||||
const {DataWriter} = ChromeUtils.import("resource://gre/modules/DataWriter.jsm");
|
||||
const {DNSRecord} = ChromeUtils.import("resource://gre/modules/DNSRecord.jsm");
|
||||
const {DNS_RECORD_TYPES} = ChromeUtils.import("resource://gre/modules/DNSTypes.jsm");
|
||||
const { DataReader } = ChromeUtils.import(
|
||||
"resource://gre/modules/DataReader.jsm"
|
||||
);
|
||||
const { DataWriter } = ChromeUtils.import(
|
||||
"resource://gre/modules/DataWriter.jsm"
|
||||
);
|
||||
const { DNSRecord } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSRecord.jsm"
|
||||
);
|
||||
const { DNS_RECORD_TYPES } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSTypes.jsm"
|
||||
);
|
||||
|
||||
const DNS_RESOURCE_RECORD_DEFAULT_TTL = 120; // 120 seconds
|
||||
|
||||
|
|
@ -19,14 +27,14 @@ class DNSResourceRecord extends DNSRecord {
|
|||
constructor(properties = {}) {
|
||||
super(properties);
|
||||
|
||||
this.ttl = properties.ttl || DNS_RESOURCE_RECORD_DEFAULT_TTL;
|
||||
this.ttl = properties.ttl || DNS_RESOURCE_RECORD_DEFAULT_TTL;
|
||||
this.data = properties.data || {};
|
||||
}
|
||||
|
||||
static parseFromPacketReader(reader) {
|
||||
let record = super.parseFromPacketReader(reader);
|
||||
|
||||
let ttl = reader.getValue(4);
|
||||
let ttl = reader.getValue(4);
|
||||
let recordData = reader.getBytes(reader.getValue(2));
|
||||
let packetData = reader.data;
|
||||
|
||||
|
|
@ -50,7 +58,7 @@ class DNSResourceRecord extends DNSRecord {
|
|||
break;
|
||||
}
|
||||
|
||||
record.ttl = ttl;
|
||||
record.ttl = ttl;
|
||||
record.data = data;
|
||||
|
||||
return record;
|
||||
|
|
@ -137,7 +145,7 @@ function _parseTXT(recordData, packetData) {
|
|||
let label = reader.getLabel(packetData);
|
||||
if (label.length > 0) {
|
||||
let parts = label.split(".");
|
||||
parts.forEach((part) => {
|
||||
parts.forEach(part => {
|
||||
let [name] = part.split("=", 1);
|
||||
let value = part.substr(name.length + 1);
|
||||
result[name] = value;
|
||||
|
|
@ -154,9 +162,9 @@ function _parseSRV(recordData, packetData) {
|
|||
let reader = new DataReader(recordData);
|
||||
|
||||
let priority = reader.getValue(2);
|
||||
let weight = reader.getValue(2);
|
||||
let port = reader.getValue(2);
|
||||
let target = reader.getLabel(packetData);
|
||||
let weight = reader.getValue(2);
|
||||
let port = reader.getValue(2);
|
||||
let target = reader.getLabel(packetData);
|
||||
|
||||
return { priority, weight, port, target };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,87 +14,87 @@ var EXPORTED_SYMBOLS = [
|
|||
];
|
||||
|
||||
let DNS_QUERY_RESPONSE_CODES = {
|
||||
QUERY: 0, // RFC 1035 - Query
|
||||
RESPONSE: 1, // RFC 1035 - Reponse
|
||||
QUERY: 0, // RFC 1035 - Query
|
||||
RESPONSE: 1, // RFC 1035 - Reponse
|
||||
};
|
||||
|
||||
let DNS_AUTHORITATIVE_ANSWER_CODES = {
|
||||
NO: 0, // RFC 1035 - Not Authoritative
|
||||
YES: 1, // RFC 1035 - Is Authoritative
|
||||
NO: 0, // RFC 1035 - Not Authoritative
|
||||
YES: 1, // RFC 1035 - Is Authoritative
|
||||
};
|
||||
|
||||
let DNS_CLASS_CODES = {
|
||||
IN: 0x01, // RFC 1035 - Internet
|
||||
CS: 0x02, // RFC 1035 - CSNET
|
||||
CH: 0x03, // RFC 1035 - CHAOS
|
||||
HS: 0x04, // RFC 1035 - Hesiod
|
||||
NONE: 0xfe, // RFC 2136 - None
|
||||
ANY: 0xff, // RFC 1035 - Any
|
||||
IN: 0x01, // RFC 1035 - Internet
|
||||
CS: 0x02, // RFC 1035 - CSNET
|
||||
CH: 0x03, // RFC 1035 - CHAOS
|
||||
HS: 0x04, // RFC 1035 - Hesiod
|
||||
NONE: 0xfe, // RFC 2136 - None
|
||||
ANY: 0xff, // RFC 1035 - Any
|
||||
};
|
||||
|
||||
let DNS_RECORD_TYPES = {
|
||||
SIGZERO: 0, // RFC 2931
|
||||
A: 1, // RFC 1035
|
||||
NS: 2, // RFC 1035
|
||||
MD: 3, // RFC 1035
|
||||
MF: 4, // RFC 1035
|
||||
CNAME: 5, // RFC 1035
|
||||
SOA: 6, // RFC 1035
|
||||
MB: 7, // RFC 1035
|
||||
MG: 8, // RFC 1035
|
||||
MR: 9, // RFC 1035
|
||||
NULL: 10, // RFC 1035
|
||||
WKS: 11, // RFC 1035
|
||||
PTR: 12, // RFC 1035
|
||||
HINFO: 13, // RFC 1035
|
||||
MINFO: 14, // RFC 1035
|
||||
MX: 15, // RFC 1035
|
||||
TXT: 16, // RFC 1035
|
||||
RP: 17, // RFC 1183
|
||||
AFSDB: 18, // RFC 1183
|
||||
X25: 19, // RFC 1183
|
||||
ISDN: 20, // RFC 1183
|
||||
RT: 21, // RFC 1183
|
||||
NSAP: 22, // RFC 1706
|
||||
NSAP_PTR: 23, // RFC 1348
|
||||
SIG: 24, // RFC 2535
|
||||
KEY: 25, // RFC 2535
|
||||
PX: 26, // RFC 2163
|
||||
GPOS: 27, // RFC 1712
|
||||
AAAA: 28, // RFC 1886
|
||||
LOC: 29, // RFC 1876
|
||||
NXT: 30, // RFC 2535
|
||||
EID: 31, // RFC ????
|
||||
NIMLOC: 32, // RFC ????
|
||||
SRV: 33, // RFC 2052
|
||||
ATMA: 34, // RFC ????
|
||||
NAPTR: 35, // RFC 2168
|
||||
KX: 36, // RFC 2230
|
||||
CERT: 37, // RFC 2538
|
||||
DNAME: 39, // RFC 2672
|
||||
OPT: 41, // RFC 2671
|
||||
APL: 42, // RFC 3123
|
||||
DS: 43, // RFC 4034
|
||||
SSHFP: 44, // RFC 4255
|
||||
IPSECKEY: 45, // RFC 4025
|
||||
RRSIG: 46, // RFC 4034
|
||||
NSEC: 47, // RFC 4034
|
||||
DNSKEY: 48, // RFC 4034
|
||||
DHCID: 49, // RFC 4701
|
||||
NSEC3: 50, // RFC ????
|
||||
NSEC3PARAM: 51, // RFC ????
|
||||
HIP: 55, // RFC 5205
|
||||
SPF: 99, // RFC 4408
|
||||
UINFO: 100, // RFC ????
|
||||
UID: 101, // RFC ????
|
||||
GID: 102, // RFC ????
|
||||
UNSPEC: 103, // RFC ????
|
||||
TKEY: 249, // RFC 2930
|
||||
TSIG: 250, // RFC 2931
|
||||
IXFR: 251, // RFC 1995
|
||||
AXFR: 252, // RFC 1035
|
||||
MAILB: 253, // RFC 1035
|
||||
MAILA: 254, // RFC 1035
|
||||
ANY: 255, // RFC 1035
|
||||
DLV: 32769, // RFC 4431
|
||||
SIGZERO: 0, // RFC 2931
|
||||
A: 1, // RFC 1035
|
||||
NS: 2, // RFC 1035
|
||||
MD: 3, // RFC 1035
|
||||
MF: 4, // RFC 1035
|
||||
CNAME: 5, // RFC 1035
|
||||
SOA: 6, // RFC 1035
|
||||
MB: 7, // RFC 1035
|
||||
MG: 8, // RFC 1035
|
||||
MR: 9, // RFC 1035
|
||||
NULL: 10, // RFC 1035
|
||||
WKS: 11, // RFC 1035
|
||||
PTR: 12, // RFC 1035
|
||||
HINFO: 13, // RFC 1035
|
||||
MINFO: 14, // RFC 1035
|
||||
MX: 15, // RFC 1035
|
||||
TXT: 16, // RFC 1035
|
||||
RP: 17, // RFC 1183
|
||||
AFSDB: 18, // RFC 1183
|
||||
X25: 19, // RFC 1183
|
||||
ISDN: 20, // RFC 1183
|
||||
RT: 21, // RFC 1183
|
||||
NSAP: 22, // RFC 1706
|
||||
NSAP_PTR: 23, // RFC 1348
|
||||
SIG: 24, // RFC 2535
|
||||
KEY: 25, // RFC 2535
|
||||
PX: 26, // RFC 2163
|
||||
GPOS: 27, // RFC 1712
|
||||
AAAA: 28, // RFC 1886
|
||||
LOC: 29, // RFC 1876
|
||||
NXT: 30, // RFC 2535
|
||||
EID: 31, // RFC ????
|
||||
NIMLOC: 32, // RFC ????
|
||||
SRV: 33, // RFC 2052
|
||||
ATMA: 34, // RFC ????
|
||||
NAPTR: 35, // RFC 2168
|
||||
KX: 36, // RFC 2230
|
||||
CERT: 37, // RFC 2538
|
||||
DNAME: 39, // RFC 2672
|
||||
OPT: 41, // RFC 2671
|
||||
APL: 42, // RFC 3123
|
||||
DS: 43, // RFC 4034
|
||||
SSHFP: 44, // RFC 4255
|
||||
IPSECKEY: 45, // RFC 4025
|
||||
RRSIG: 46, // RFC 4034
|
||||
NSEC: 47, // RFC 4034
|
||||
DNSKEY: 48, // RFC 4034
|
||||
DHCID: 49, // RFC 4701
|
||||
NSEC3: 50, // RFC ????
|
||||
NSEC3PARAM: 51, // RFC ????
|
||||
HIP: 55, // RFC 5205
|
||||
SPF: 99, // RFC 4408
|
||||
UINFO: 100, // RFC ????
|
||||
UID: 101, // RFC ????
|
||||
GID: 102, // RFC ????
|
||||
UNSPEC: 103, // RFC ????
|
||||
TKEY: 249, // RFC 2930
|
||||
TSIG: 250, // RFC 2931
|
||||
IXFR: 251, // RFC 1995
|
||||
AXFR: 252, // RFC 1035
|
||||
MAILB: 253, // RFC 1035
|
||||
MAILA: 254, // RFC 1035
|
||||
ANY: 255, // RFC 1035
|
||||
DLV: 32769, // RFC 4431
|
||||
};
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@ function _uint8ArrayToString(uint8Array) {
|
|||
|
||||
let results = [];
|
||||
for (let i = 0; i < length; i += 1024) {
|
||||
results.push(String.fromCharCode.apply(null, uint8Array.subarray(i, i + 1024)));
|
||||
results.push(
|
||||
String.fromCharCode.apply(null, uint8Array.subarray(i, i + 1024))
|
||||
);
|
||||
}
|
||||
|
||||
return results.join("");
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class DataWriter {
|
|||
// Eliminate any trailing '.'s in the label (valid in text representation).
|
||||
label = label.replace(/\.$/, "");
|
||||
let parts = label.split(".");
|
||||
parts.forEach((part) => {
|
||||
parts.forEach(part => {
|
||||
this.putLengthString(part);
|
||||
});
|
||||
this.putValue(0);
|
||||
|
|
@ -74,7 +74,7 @@ class DataWriter {
|
|||
|
||||
putLengthString(string) {
|
||||
if (string.length > 0xff) {
|
||||
throw new Error("String too long.");
|
||||
throw new Error("String too long.");
|
||||
}
|
||||
this.putValue(string.length);
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
|
|
|
|||
|
|
@ -8,33 +8,56 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["MulticastDNS"];
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {clearTimeout, setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { clearTimeout, setTimeout } = ChromeUtils.import(
|
||||
"resource://gre/modules/Timer.jsm"
|
||||
);
|
||||
|
||||
const {DNSPacket} = ChromeUtils.import("resource://gre/modules/DNSPacket.jsm");
|
||||
const {DNSRecord} = ChromeUtils.import("resource://gre/modules/DNSRecord.jsm");
|
||||
const {DNSResourceRecord} = ChromeUtils.import("resource://gre/modules/DNSResourceRecord.jsm");
|
||||
const {DNS_AUTHORITATIVE_ANSWER_CODES, DNS_CLASS_CODES, DNS_QUERY_RESPONSE_CODES, DNS_RECORD_TYPES} = ChromeUtils.import("resource://gre/modules/DNSTypes.jsm");
|
||||
const { DNSPacket } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSPacket.jsm"
|
||||
);
|
||||
const { DNSRecord } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSRecord.jsm"
|
||||
);
|
||||
const { DNSResourceRecord } = ChromeUtils.import(
|
||||
"resource://gre/modules/DNSResourceRecord.jsm"
|
||||
);
|
||||
const {
|
||||
DNS_AUTHORITATIVE_ANSWER_CODES,
|
||||
DNS_CLASS_CODES,
|
||||
DNS_QUERY_RESPONSE_CODES,
|
||||
DNS_RECORD_TYPES,
|
||||
} = ChromeUtils.import("resource://gre/modules/DNSTypes.jsm");
|
||||
|
||||
const NS_NETWORK_LINK_TOPIC = "network:link-status-changed";
|
||||
|
||||
let networkInfoService = Cc["@mozilla.org/network-info-service;1"]
|
||||
.createInstance(Ci.nsINetworkInfoService);
|
||||
let networkInfoService = Cc[
|
||||
"@mozilla.org/network-info-service;1"
|
||||
].createInstance(Ci.nsINetworkInfoService);
|
||||
|
||||
const DEBUG = true;
|
||||
|
||||
const MDNS_MULTICAST_GROUP = "224.0.0.251";
|
||||
const MDNS_PORT = 5353;
|
||||
const DEFAULT_TTL = 120;
|
||||
const MDNS_PORT = 5353;
|
||||
const DEFAULT_TTL = 120;
|
||||
|
||||
function debug(msg) {
|
||||
dump("MulticastDNS: " + msg + "\n");
|
||||
}
|
||||
|
||||
function ServiceKey(svc) {
|
||||
return "" + svc.serviceType.length + "/" + svc.serviceType + "|" +
|
||||
svc.serviceName.length + "/" + svc.serviceName + "|" +
|
||||
svc.port;
|
||||
return (
|
||||
"" +
|
||||
svc.serviceType.length +
|
||||
"/" +
|
||||
svc.serviceType +
|
||||
"|" +
|
||||
svc.serviceName.length +
|
||||
"/" +
|
||||
svc.serviceName +
|
||||
"|" +
|
||||
svc.port
|
||||
);
|
||||
}
|
||||
|
||||
function TryGet(obj, name) {
|
||||
|
|
@ -77,9 +100,11 @@ class PublishedService {
|
|||
}
|
||||
|
||||
equals(svc) {
|
||||
return (this.port == svc.port) &&
|
||||
(this.serviceName == svc.serviceName) &&
|
||||
(this.serviceType == svc.serviceType);
|
||||
return (
|
||||
this.port == svc.port &&
|
||||
this.serviceName == svc.serviceName &&
|
||||
this.serviceType == svc.serviceType
|
||||
);
|
||||
}
|
||||
|
||||
generateKey() {
|
||||
|
|
@ -87,7 +112,7 @@ class PublishedService {
|
|||
}
|
||||
|
||||
ptrMatch(name) {
|
||||
return name == (this.serviceType + "." + this.domainName);
|
||||
return name == this.serviceType + "." + this.domainName;
|
||||
}
|
||||
|
||||
clearAdvertiseTimer() {
|
||||
|
|
@ -101,17 +126,23 @@ class PublishedService {
|
|||
|
||||
class MulticastDNS {
|
||||
constructor() {
|
||||
this._listeners = new Map();
|
||||
this._sockets = new Map();
|
||||
this._services = new Map();
|
||||
this._discovered = new Map();
|
||||
this._querySocket = undefined;
|
||||
this._listeners = new Map();
|
||||
this._sockets = new Map();
|
||||
this._services = new Map();
|
||||
this._discovered = new Map();
|
||||
this._querySocket = undefined;
|
||||
this._broadcastReceiverSocket = undefined;
|
||||
this._broadcastTimer = undefined;
|
||||
this._broadcastTimer = undefined;
|
||||
|
||||
this._networkLinkObserver = {
|
||||
observe: (subject, topic, data) => {
|
||||
DEBUG && debug(NS_NETWORK_LINK_TOPIC + "(" + data + "); Clearing list of previously discovered services");
|
||||
DEBUG &&
|
||||
debug(
|
||||
NS_NETWORK_LINK_TOPIC +
|
||||
"(" +
|
||||
data +
|
||||
"); Clearing list of previously discovered services"
|
||||
);
|
||||
this._discovered.clear();
|
||||
},
|
||||
};
|
||||
|
|
@ -124,7 +155,10 @@ class MulticastDNS {
|
|||
|
||||
if (!this._isNetworkLinkObserverAttached) {
|
||||
DEBUG && debug("Attaching observer " + NS_NETWORK_LINK_TOPIC);
|
||||
Services.obs.addObserver(this._networkLinkObserver, NS_NETWORK_LINK_TOPIC);
|
||||
Services.obs.addObserver(
|
||||
this._networkLinkObserver,
|
||||
NS_NETWORK_LINK_TOPIC
|
||||
);
|
||||
this._isNetworkLinkObserverAttached = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +171,10 @@ class MulticastDNS {
|
|||
|
||||
this._networkLinkObserverTimeout = setTimeout(() => {
|
||||
DEBUG && debug("Detaching observer " + NS_NETWORK_LINK_TOPIC);
|
||||
Services.obs.removeObserver(this._networkLinkObserver, NS_NETWORK_LINK_TOPIC);
|
||||
Services.obs.removeObserver(
|
||||
this._networkLinkObserver,
|
||||
NS_NETWORK_LINK_TOPIC
|
||||
);
|
||||
this._isNetworkLinkObserverAttached = false;
|
||||
this._networkLinkObserverTimeout = null;
|
||||
}, 5000);
|
||||
|
|
@ -199,22 +236,32 @@ class MulticastDNS {
|
|||
try {
|
||||
publishedService = new PublishedService(aServiceInfo);
|
||||
} catch (e) {
|
||||
DEBUG && debug("Error constructing PublishedService: " + e + " - " + e.stack);
|
||||
setTimeout(() => aListener.onRegistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE));
|
||||
DEBUG &&
|
||||
debug("Error constructing PublishedService: " + e + " - " + e.stack);
|
||||
setTimeout(() =>
|
||||
aListener.onRegistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure such a service does not already exist.
|
||||
if (this._services.get(publishedService.key)) {
|
||||
setTimeout(() => aListener.onRegistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE));
|
||||
setTimeout(() =>
|
||||
aListener.onRegistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that the service addr is '0.0.0.0', or there is at least one
|
||||
// socket open on the address the service is open on.
|
||||
this._getSockets().then((sockets) => {
|
||||
if (publishedService.address != "0.0.0.0" && !sockets.get(publishedService.address)) {
|
||||
setTimeout(() => aListener.onRegistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE));
|
||||
this._getSockets().then(sockets => {
|
||||
if (
|
||||
publishedService.address != "0.0.0.0" &&
|
||||
!sockets.get(publishedService.address)
|
||||
) {
|
||||
setTimeout(() =>
|
||||
aListener.onRegistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -237,13 +284,17 @@ class MulticastDNS {
|
|||
try {
|
||||
serviceKey = ServiceKey(aServiceInfo);
|
||||
} catch (e) {
|
||||
setTimeout(() => aListener.onUnregistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE));
|
||||
setTimeout(() =>
|
||||
aListener.onUnregistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let publishedService = this._services.get(serviceKey);
|
||||
if (!publishedService) {
|
||||
setTimeout(() => aListener.onUnregistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE));
|
||||
setTimeout(() =>
|
||||
aListener.onUnregistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +303,9 @@ class MulticastDNS {
|
|||
|
||||
// Delete the service from the service map.
|
||||
if (!this._services.delete(serviceKey)) {
|
||||
setTimeout(() => aListener.onUnregistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE));
|
||||
setTimeout(() =>
|
||||
aListener.onUnregistrationFailed(aServiceInfo, Cr.NS_ERROR_FAILURE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -268,8 +321,15 @@ class MulticastDNS {
|
|||
_respondToQuery(serviceKey, message) {
|
||||
let address = message.fromAddr.address;
|
||||
let port = message.fromAddr.port;
|
||||
DEBUG && debug("_respondToQuery(): key=" + serviceKey + ", fromAddr="
|
||||
+ address + ":" + port);
|
||||
DEBUG &&
|
||||
debug(
|
||||
"_respondToQuery(): key=" +
|
||||
serviceKey +
|
||||
", fromAddr=" +
|
||||
address +
|
||||
":" +
|
||||
port
|
||||
);
|
||||
|
||||
let publishedService = this._services.get(serviceKey);
|
||||
if (!publishedService) {
|
||||
|
|
@ -277,15 +337,20 @@ class MulticastDNS {
|
|||
return;
|
||||
}
|
||||
|
||||
DEBUG && debug("_respondToQuery(): key=" + serviceKey + ": SENDING RESPONSE");
|
||||
this._advertiseServiceHelper(publishedService, {address, port});
|
||||
DEBUG &&
|
||||
debug("_respondToQuery(): key=" + serviceKey + ": SENDING RESPONSE");
|
||||
this._advertiseServiceHelper(publishedService, { address, port });
|
||||
}
|
||||
|
||||
_advertiseService(serviceKey, firstAdv) {
|
||||
DEBUG && debug("_advertiseService(): key=" + serviceKey);
|
||||
let publishedService = this._services.get(serviceKey);
|
||||
if (!publishedService) {
|
||||
debug("_advertiseService Could not find service to advertise (key=" + serviceKey + ")");
|
||||
debug(
|
||||
"_advertiseService Could not find service to advertise (key=" +
|
||||
serviceKey +
|
||||
")"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -307,10 +372,10 @@ class MulticastDNS {
|
|||
|
||||
_advertiseServiceHelper(svc, target) {
|
||||
if (!target) {
|
||||
target = {address: MDNS_MULTICAST_GROUP, port: MDNS_PORT};
|
||||
target = { address: MDNS_MULTICAST_GROUP, port: MDNS_PORT };
|
||||
}
|
||||
|
||||
return this._getSockets().then((sockets) => {
|
||||
return this._getSockets().then(sockets => {
|
||||
sockets.forEach((socket, address) => {
|
||||
if (svc.address == "0.0.0.0" || address == svc.address) {
|
||||
let packet = this._makeServicePacket(svc, [address]);
|
||||
|
|
@ -318,8 +383,10 @@ class MulticastDNS {
|
|||
try {
|
||||
socket.send(target.address, target.port, data);
|
||||
} catch (err) {
|
||||
DEBUG && debug("Failed to send packet to "
|
||||
+ target.address + ":" + target.port);
|
||||
DEBUG &&
|
||||
debug(
|
||||
"Failed to send packet to " + target.address + ":" + target.port
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -355,14 +422,14 @@ class MulticastDNS {
|
|||
let msSinceAdv = now - publishedService.lastAdvertised;
|
||||
|
||||
// If msSinceAdv is more than 90% of the way to the TTL, advertise now.
|
||||
if (msSinceAdv > (DEFAULT_TTL * 1000 * 0.9)) {
|
||||
if (msSinceAdv > DEFAULT_TTL * 1000 * 0.9) {
|
||||
bcastServices.push(publishedService);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, calculate the next time to advertise for this service.
|
||||
// We set that at 95% of the time to the TTL expiry.
|
||||
let nextAdvWait = (DEFAULT_TTL * 1000 * 0.95) - msSinceAdv;
|
||||
let nextAdvWait = DEFAULT_TTL * 1000 * 0.95 - msSinceAdv;
|
||||
if (nextBcastWait === undefined || nextBcastWait > nextAdvWait) {
|
||||
nextBcastWait = nextAdvWait;
|
||||
}
|
||||
|
|
@ -370,13 +437,21 @@ class MulticastDNS {
|
|||
|
||||
// Schedule an immediate advertisement of all services to be advertised now.
|
||||
for (let svc of bcastServices) {
|
||||
svc.advertiseTimer = setTimeout(() => this._advertiseService(svc.key));
|
||||
svc.advertiseTimer = setTimeout(() => this._advertiseService(svc.key));
|
||||
}
|
||||
|
||||
// Schedule next broadcast check for the next bcast time.
|
||||
if (nextBcastWait !== undefined) {
|
||||
DEBUG && debug("_checkStartBroadcastTimer(): Scheduling next check in " + nextBcastWait + "ms");
|
||||
this._broadcastTimer = setTimeout(() => this._checkStartBroadcastTimer(), nextBcastWait);
|
||||
DEBUG &&
|
||||
debug(
|
||||
"_checkStartBroadcastTimer(): Scheduling next check in " +
|
||||
nextBcastWait +
|
||||
"ms"
|
||||
);
|
||||
this._broadcastTimer = setTimeout(
|
||||
() => this._checkStartBroadcastTimer(),
|
||||
nextBcastWait
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,12 +461,15 @@ class MulticastDNS {
|
|||
packet.setFlag("QR", DNS_QUERY_RESPONSE_CODES.QUERY);
|
||||
|
||||
// PTR Record
|
||||
packet.addRecord("QD", new DNSRecord({
|
||||
name,
|
||||
recordType: DNS_RECORD_TYPES.PTR,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
cacheFlush: true,
|
||||
}));
|
||||
packet.addRecord(
|
||||
"QD",
|
||||
new DNSRecord({
|
||||
name,
|
||||
recordType: DNS_RECORD_TYPES.PTR,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
cacheFlush: true,
|
||||
})
|
||||
);
|
||||
|
||||
let data = packet.serialize();
|
||||
|
||||
|
|
@ -400,7 +478,7 @@ class MulticastDNS {
|
|||
// multicast queries/announcements on all interfaces.
|
||||
this._getBroadcastReceiverSocket();
|
||||
|
||||
this._getQuerySocket().then((querySocket) => {
|
||||
this._getQuerySocket().then(querySocket => {
|
||||
DEBUG && debug('sending query on query socket ("' + name + '")');
|
||||
querySocket.send(MDNS_MULTICAST_GROUP, MDNS_PORT, data);
|
||||
});
|
||||
|
|
@ -408,7 +486,8 @@ class MulticastDNS {
|
|||
// Automatically announce previously-discovered
|
||||
// services that match and haven't expired yet.
|
||||
setTimeout(() => {
|
||||
DEBUG && debug('announcing previously discovered services ("' + name + '")');
|
||||
DEBUG &&
|
||||
debug('announcing previously discovered services ("' + name + '")');
|
||||
let { serviceType } = _parseServiceDomainName(name);
|
||||
|
||||
this._clearExpiredDiscoveries();
|
||||
|
|
@ -419,7 +498,7 @@ class MulticastDNS {
|
|||
}
|
||||
|
||||
let listeners = this._listeners.get(serviceInfo.serviceType) || [];
|
||||
listeners.forEach((listener) => {
|
||||
listeners.forEach(listener => {
|
||||
listener.onServiceFound(serviceInfo);
|
||||
});
|
||||
});
|
||||
|
|
@ -435,16 +514,20 @@ class MulticastDNS {
|
|||
}
|
||||
|
||||
_handleQueryPacket(packet, message) {
|
||||
packet.getRecords(["QD"]).forEach((record) => {
|
||||
packet.getRecords(["QD"]).forEach(record => {
|
||||
// Don't respond if the query's class code is not IN or ANY.
|
||||
if (record.classCode !== DNS_CLASS_CODES.IN &&
|
||||
record.classCode !== DNS_CLASS_CODES.ANY) {
|
||||
if (
|
||||
record.classCode !== DNS_CLASS_CODES.IN &&
|
||||
record.classCode !== DNS_CLASS_CODES.ANY
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't respond if the query's record type is not PTR or ANY.
|
||||
if (record.recordType !== DNS_RECORD_TYPES.PTR &&
|
||||
record.recordType !== DNS_RECORD_TYPES.ANY) {
|
||||
if (
|
||||
record.recordType !== DNS_RECORD_TYPES.PTR &&
|
||||
record.recordType !== DNS_RECORD_TYPES.ANY
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -465,46 +548,59 @@ class MulticastDNS {
|
|||
let host = service.host || _hostname;
|
||||
|
||||
// e.g.: foo-bar-service._http._tcp.local
|
||||
let serviceDomainName = service.serviceName + "." + service.serviceType + ".local";
|
||||
let serviceDomainName =
|
||||
service.serviceName + "." + service.serviceType + ".local";
|
||||
|
||||
// PTR Record
|
||||
packet.addRecord("AN", new DNSResourceRecord({
|
||||
name: service.serviceType + ".local", // e.g.: _http._tcp.local
|
||||
recordType: DNS_RECORD_TYPES.PTR,
|
||||
data: serviceDomainName,
|
||||
}));
|
||||
packet.addRecord(
|
||||
"AN",
|
||||
new DNSResourceRecord({
|
||||
name: service.serviceType + ".local", // e.g.: _http._tcp.local
|
||||
recordType: DNS_RECORD_TYPES.PTR,
|
||||
data: serviceDomainName,
|
||||
})
|
||||
);
|
||||
|
||||
// SRV Record
|
||||
packet.addRecord("AR", new DNSResourceRecord({
|
||||
name: serviceDomainName,
|
||||
recordType: DNS_RECORD_TYPES.SRV,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
cacheFlush: true,
|
||||
data: {
|
||||
priority: 0,
|
||||
weight: 0,
|
||||
port: service.port,
|
||||
target: host, // e.g.: My-Android-Phone.local
|
||||
},
|
||||
}));
|
||||
packet.addRecord(
|
||||
"AR",
|
||||
new DNSResourceRecord({
|
||||
name: serviceDomainName,
|
||||
recordType: DNS_RECORD_TYPES.SRV,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
cacheFlush: true,
|
||||
data: {
|
||||
priority: 0,
|
||||
weight: 0,
|
||||
port: service.port,
|
||||
target: host, // e.g.: My-Android-Phone.local
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// A Records
|
||||
for (let address of addresses) {
|
||||
packet.addRecord("AR", new DNSResourceRecord({
|
||||
packet.addRecord(
|
||||
"AR",
|
||||
new DNSResourceRecord({
|
||||
name: host,
|
||||
recordType: DNS_RECORD_TYPES.A,
|
||||
data: address,
|
||||
}));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// TXT Record
|
||||
packet.addRecord("AR", new DNSResourceRecord({
|
||||
name: serviceDomainName,
|
||||
recordType: DNS_RECORD_TYPES.TXT,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
cacheFlush: true,
|
||||
data: service.serviceAttrs || {},
|
||||
}));
|
||||
packet.addRecord(
|
||||
"AR",
|
||||
new DNSResourceRecord({
|
||||
name: serviceDomainName,
|
||||
recordType: DNS_RECORD_TYPES.TXT,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
cacheFlush: true,
|
||||
data: service.serviceAttrs || {},
|
||||
})
|
||||
);
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
|
@ -518,7 +614,7 @@ class MulticastDNS {
|
|||
let ptrRecords = packet.getRecords(["AN", "AR"], DNS_RECORD_TYPES.PTR);
|
||||
let aRecords = packet.getRecords(["AN", "AR"], DNS_RECORD_TYPES.A);
|
||||
|
||||
srvRecords.forEach((record) => {
|
||||
srvRecords.forEach(record => {
|
||||
let data = record.data || {};
|
||||
|
||||
services[record.name] = {
|
||||
|
|
@ -528,7 +624,7 @@ class MulticastDNS {
|
|||
};
|
||||
});
|
||||
|
||||
txtRecords.forEach((record) => {
|
||||
txtRecords.forEach(record => {
|
||||
if (!services[record.name]) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -536,24 +632,26 @@ class MulticastDNS {
|
|||
services[record.name].attributes = record.data;
|
||||
});
|
||||
|
||||
aRecords.forEach((record) => {
|
||||
aRecords.forEach(record => {
|
||||
if (IsIpv4Address(record.data)) {
|
||||
hosts[record.name] = record.data;
|
||||
}
|
||||
});
|
||||
|
||||
ptrRecords.forEach((record) => {
|
||||
ptrRecords.forEach(record => {
|
||||
let name = record.data;
|
||||
if (!services[name]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let {host, port} = services[name];
|
||||
let { host, port } = services[name];
|
||||
if (!host || !port) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { serviceName, serviceType, domainName } = _parseServiceDomainName(name);
|
||||
let { serviceName, serviceType, domainName } = _parseServiceDomainName(
|
||||
name
|
||||
);
|
||||
if (!serviceName || !serviceType || !domainName) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -579,12 +677,17 @@ class MulticastDNS {
|
|||
}
|
||||
|
||||
_onServiceFound(serviceInfo, ttl = 0) {
|
||||
let expireTime = Date.now() + (ttl * 1000);
|
||||
let key = serviceInfo.serviceName + "." +
|
||||
serviceInfo.serviceType + "." +
|
||||
serviceInfo.domainName + " @" +
|
||||
serviceInfo.address + ":" +
|
||||
serviceInfo.port;
|
||||
let expireTime = Date.now() + ttl * 1000;
|
||||
let key =
|
||||
serviceInfo.serviceName +
|
||||
"." +
|
||||
serviceInfo.serviceType +
|
||||
"." +
|
||||
serviceInfo.domainName +
|
||||
" @" +
|
||||
serviceInfo.address +
|
||||
":" +
|
||||
serviceInfo.port;
|
||||
|
||||
// If this service was already discovered, just update
|
||||
// its expiration time and don't re-emit it.
|
||||
|
|
@ -599,7 +702,7 @@ class MulticastDNS {
|
|||
});
|
||||
|
||||
let listeners = this._listeners.get(serviceInfo.serviceType) || [];
|
||||
listeners.forEach((listener) => {
|
||||
listeners.forEach(listener => {
|
||||
listener.onServiceFound(serviceInfo);
|
||||
});
|
||||
|
||||
|
|
@ -636,10 +739,15 @@ class MulticastDNS {
|
|||
_getBroadcastReceiverSocket() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._broadcastReceiverSocket) {
|
||||
this._broadcastReceiverSocket = _openSocket("0.0.0.0", MDNS_PORT, {
|
||||
onPacketReceived: this._onPacketReceived.bind(this),
|
||||
onStopListening: this._onStopListening.bind(this),
|
||||
}, /* multicastInterface = */ "0.0.0.0");
|
||||
this._broadcastReceiverSocket = _openSocket(
|
||||
"0.0.0.0",
|
||||
MDNS_PORT,
|
||||
{
|
||||
onPacketReceived: this._onPacketReceived.bind(this),
|
||||
onStopListening: this._onStopListening.bind(this),
|
||||
},
|
||||
/* multicastInterface = */ "0.0.0.0"
|
||||
);
|
||||
}
|
||||
resolve(this._broadcastReceiverSocket);
|
||||
});
|
||||
|
|
@ -656,14 +764,14 @@ class MulticastDNS {
|
|||
* already handling them.
|
||||
*/
|
||||
_getSockets() {
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
if (this._sockets.size > 0) {
|
||||
resolve(this._sockets);
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.all([getAddresses(), getHostname()]).then(() => {
|
||||
_addresses.forEach((address) => {
|
||||
_addresses.forEach(address => {
|
||||
let socket = _openSocket(address, MDNS_PORT, null);
|
||||
this._sockets.set(address, socket);
|
||||
});
|
||||
|
|
@ -675,17 +783,20 @@ class MulticastDNS {
|
|||
|
||||
_checkCloseSockets() {
|
||||
// Nothing to do if no sockets to close.
|
||||
if (this._sockets.size == 0)
|
||||
if (this._sockets.size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't close sockets if discovery listeners are still present.
|
||||
if (this._listeners.size > 0)
|
||||
if (this._listeners.size > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't close sockets if advertised services are present.
|
||||
// Since we need to listen for service queries and respond to them.
|
||||
if (this._services.size > 0)
|
||||
if (this._services.size > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._closeSockets();
|
||||
}
|
||||
|
|
@ -757,10 +868,12 @@ function getAddresses() {
|
|||
|
||||
networkInfoService.listNetworkAddresses({
|
||||
onListedNetworkAddresses(aAddressArray) {
|
||||
_addresses = aAddressArray.filter((address) => {
|
||||
return !address.includes("%p2p") && // No WiFi Direct interfaces
|
||||
!address.includes(":") && // XXX: No IPv6 for now
|
||||
address != "127.0.0.1"; // No ipv4 loopback addresses.
|
||||
_addresses = aAddressArray.filter(address => {
|
||||
return (
|
||||
!address.includes("%p2p") && // No WiFi Direct interfaces
|
||||
!address.includes(":") && // XXX: No IPv6 for now
|
||||
address != "127.0.0.1"
|
||||
); // No ipv4 loopback addresses.
|
||||
});
|
||||
|
||||
DEBUG && debug("getAddresses(): " + _addresses);
|
||||
|
|
@ -781,7 +894,7 @@ let _hostname;
|
|||
* @private
|
||||
*/
|
||||
function getHostname() {
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
if (_hostname) {
|
||||
resolve(_hostname);
|
||||
return;
|
||||
|
|
@ -848,8 +961,15 @@ function _propertyBagToObject(propBag) {
|
|||
* @private
|
||||
*/
|
||||
function _openSocket(addr, port, handler, multicastInterface) {
|
||||
let socket = Cc["@mozilla.org/network/udp-socket;1"].createInstance(Ci.nsIUDPSocket);
|
||||
socket.init2(addr, port, Services.scriptSecurityManager.getSystemPrincipal(), true);
|
||||
let socket = Cc["@mozilla.org/network/udp-socket;1"].createInstance(
|
||||
Ci.nsIUDPSocket
|
||||
);
|
||||
socket.init2(
|
||||
addr,
|
||||
port,
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
true
|
||||
);
|
||||
|
||||
if (handler) {
|
||||
socket.asyncListen({
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {UserAgentOverrides} = ChromeUtils.import("resource://gre/modules/UserAgentOverrides.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { UserAgentOverrides } = ChromeUtils.import(
|
||||
"resource://gre/modules/UserAgentOverrides.jsm"
|
||||
);
|
||||
|
||||
function UAOverridesBootstrapper() {
|
||||
this.init();
|
||||
|
|
|
|||
|
|
@ -4,36 +4,43 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "UserAgentOverrides" ];
|
||||
var EXPORTED_SYMBOLS = ["UserAgentOverrides"];
|
||||
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {UserAgentUpdates} = ChromeUtils.import("resource://gre/modules/UserAgentUpdates.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { UserAgentUpdates } = ChromeUtils.import(
|
||||
"resource://gre/modules/UserAgentUpdates.jsm"
|
||||
);
|
||||
|
||||
const PREF_OVERRIDES_ENABLED = "general.useragent.site_specific_overrides";
|
||||
const MAX_OVERRIDE_FOR_HOST_CACHE_SIZE = 250;
|
||||
|
||||
// lazy load nsHttpHandler to improve startup performance.
|
||||
XPCOMUtils.defineLazyGetter(this, "DEFAULT_UA", function() {
|
||||
return Cc["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Ci.nsIHttpProtocolHandler)
|
||||
.userAgent;
|
||||
return Cc["@mozilla.org/network/protocol;1?name=http"].getService(
|
||||
Ci.nsIHttpProtocolHandler
|
||||
).userAgent;
|
||||
});
|
||||
|
||||
var gPrefBranch;
|
||||
var gOverrides = new Map;
|
||||
var gOverrides = new Map();
|
||||
var gUpdatedOverrides;
|
||||
var gOverrideForHostCache = new Map;
|
||||
var gOverrideForHostCache = new Map();
|
||||
var gInitialized = false;
|
||||
var gOverrideFunctions = [
|
||||
function(aHttpChannel) { return UserAgentOverrides.getOverrideForURI(aHttpChannel.URI); },
|
||||
function(aHttpChannel) {
|
||||
return UserAgentOverrides.getOverrideForURI(aHttpChannel.URI);
|
||||
},
|
||||
];
|
||||
var gBuiltUAs = new Map;
|
||||
var gBuiltUAs = new Map();
|
||||
|
||||
var UserAgentOverrides = {
|
||||
init: function uao_init() {
|
||||
if (gInitialized)
|
||||
if (gInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
gPrefBranch = Services.prefs.getBranch("general.useragent.override.");
|
||||
gPrefBranch.addObserver("", buildOverrides);
|
||||
|
|
@ -41,7 +48,10 @@ var UserAgentOverrides = {
|
|||
Services.prefs.addObserver(PREF_OVERRIDES_ENABLED, buildOverrides);
|
||||
|
||||
try {
|
||||
Services.obs.addObserver(HTTP_on_useragent_request, "http-on-useragent-request");
|
||||
Services.obs.addObserver(
|
||||
HTTP_on_useragent_request,
|
||||
"http-on-useragent-request"
|
||||
);
|
||||
} catch (x) {
|
||||
// The http-on-useragent-request notification is disallowed in content processes.
|
||||
}
|
||||
|
|
@ -53,7 +63,9 @@ var UserAgentOverrides = {
|
|||
for (let domain in overrides) {
|
||||
overrides[domain] = getUserAgentFromOverride(overrides[domain]);
|
||||
}
|
||||
overrides.get = function(key) { return this[key]; };
|
||||
overrides.get = function(key) {
|
||||
return this[key];
|
||||
};
|
||||
}
|
||||
gUpdatedOverrides = overrides;
|
||||
});
|
||||
|
|
@ -75,15 +87,14 @@ var UserAgentOverrides = {
|
|||
|
||||
getOverrideForURI: function uao_getOverrideForURI(aURI) {
|
||||
let host = aURI.asciiHost;
|
||||
if (!gInitialized ||
|
||||
(!gOverrides.size && !gUpdatedOverrides) ||
|
||||
!(host)) {
|
||||
if (!gInitialized || (!gOverrides.size && !gUpdatedOverrides) || !host) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let override = gOverrideForHostCache.get(host);
|
||||
if (override !== undefined)
|
||||
if (override !== undefined) {
|
||||
return override;
|
||||
}
|
||||
|
||||
function findOverride(overrides) {
|
||||
let searchHost = host;
|
||||
|
|
@ -100,8 +111,9 @@ var UserAgentOverrides = {
|
|||
return userAgent;
|
||||
}
|
||||
|
||||
override = (gOverrides.size && findOverride(gOverrides))
|
||||
|| (gUpdatedOverrides && findOverride(gUpdatedOverrides));
|
||||
override =
|
||||
(gOverrides.size && findOverride(gOverrides)) ||
|
||||
(gUpdatedOverrides && findOverride(gUpdatedOverrides));
|
||||
|
||||
if (gOverrideForHostCache.size >= MAX_OVERRIDE_FOR_HOST_CACHE_SIZE) {
|
||||
gOverrideForHostCache.clear();
|
||||
|
|
@ -112,15 +124,19 @@ var UserAgentOverrides = {
|
|||
},
|
||||
|
||||
uninit: function uao_uninit() {
|
||||
if (!gInitialized)
|
||||
if (!gInitialized) {
|
||||
return;
|
||||
}
|
||||
gInitialized = false;
|
||||
|
||||
gPrefBranch.removeObserver("", buildOverrides);
|
||||
|
||||
Services.prefs.removeObserver(PREF_OVERRIDES_ENABLED, buildOverrides);
|
||||
|
||||
Services.obs.removeObserver(HTTP_on_useragent_request, "http-on-useragent-request");
|
||||
Services.obs.removeObserver(
|
||||
HTTP_on_useragent_request,
|
||||
"http-on-useragent-request"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -143,8 +159,9 @@ function buildOverrides() {
|
|||
gOverrides.clear();
|
||||
gOverrideForHostCache.clear();
|
||||
|
||||
if (!Services.prefs.getBoolPref(PREF_OVERRIDES_ENABLED))
|
||||
if (!Services.prefs.getBoolPref(PREF_OVERRIDES_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let domains = gPrefBranch.getChildList("");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,35 +6,50 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["UserAgentUpdates"];
|
||||
|
||||
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["XMLHttpRequest"]);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this, "FileUtils", "resource://gre/modules/FileUtils.jsm");
|
||||
this,
|
||||
"FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
|
||||
this,
|
||||
"NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this, "UpdateUtils", "resource://gre/modules/UpdateUtils.jsm");
|
||||
this,
|
||||
"UpdateUtils",
|
||||
"resource://gre/modules/UpdateUtils.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this, "gUpdateTimer", "@mozilla.org/updates/timer-manager;1", "nsIUpdateTimerManager");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gDecoder",
|
||||
function() { return new TextDecoder(); }
|
||||
this,
|
||||
"gUpdateTimer",
|
||||
"@mozilla.org/updates/timer-manager;1",
|
||||
"nsIUpdateTimerManager"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gEncoder",
|
||||
function() { return new TextEncoder(); }
|
||||
);
|
||||
XPCOMUtils.defineLazyGetter(this, "gDecoder", function() {
|
||||
return new TextDecoder();
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gEncoder", function() {
|
||||
return new TextEncoder();
|
||||
});
|
||||
|
||||
const TIMER_ID = "user-agent-updates-timer";
|
||||
|
||||
|
|
@ -58,7 +73,10 @@ var gInitialized = false;
|
|||
function readChannel(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
let channel = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
let channel = NetUtil.newChannel({
|
||||
uri: url,
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
channel.contentType = "application/json";
|
||||
|
||||
NetUtil.asyncFetch(channel, (inputStream, status) => {
|
||||
|
|
@ -73,8 +91,16 @@ function readChannel(url) {
|
|||
resolve(data);
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(new Error("UserAgentUpdates: Could not fetch " + url + " " +
|
||||
ex + "\n" + ex.stack));
|
||||
reject(
|
||||
new Error(
|
||||
"UserAgentUpdates: Could not fetch " +
|
||||
url +
|
||||
" " +
|
||||
ex +
|
||||
"\n" +
|
||||
ex.stack
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -119,32 +145,40 @@ var UserAgentUpdates = {
|
|||
// try loading from profile dir, then from app dir
|
||||
let dirs = [KEY_PREFDIR, KEY_APPDIR];
|
||||
|
||||
dirs.reduce((prevLoad, dir) => {
|
||||
let file = FileUtils.getFile(dir, [FILE_UPDATES], true).path;
|
||||
// tryNext returns promise to read file under dir and parse it
|
||||
let tryNext = () => OS.File.read(file).then(
|
||||
(bytes) => {
|
||||
let update = JSON.parse(gDecoder.decode(bytes));
|
||||
if (!update) {
|
||||
throw new Error("invalid update");
|
||||
}
|
||||
return update;
|
||||
dirs
|
||||
.reduce((prevLoad, dir) => {
|
||||
let file = FileUtils.getFile(dir, [FILE_UPDATES], true).path;
|
||||
// tryNext returns promise to read file under dir and parse it
|
||||
let tryNext = () =>
|
||||
OS.File.read(file).then(bytes => {
|
||||
let update = JSON.parse(gDecoder.decode(bytes));
|
||||
if (!update) {
|
||||
throw new Error("invalid update");
|
||||
}
|
||||
return update;
|
||||
});
|
||||
// try to load next one if the previous load failed
|
||||
return prevLoad ? prevLoad.catch(tryNext) : tryNext();
|
||||
}, null)
|
||||
.catch(ex => {
|
||||
if (AppConstants.platform !== "android") {
|
||||
// All previous (non-Android) load attempts have failed, so we bail.
|
||||
throw new Error(
|
||||
"UserAgentUpdates: Failed to load " +
|
||||
FILE_UPDATES +
|
||||
ex +
|
||||
"\n" +
|
||||
ex.stack
|
||||
);
|
||||
}
|
||||
);
|
||||
// try to load next one if the previous load failed
|
||||
return prevLoad ? prevLoad.catch(tryNext) : tryNext();
|
||||
}, null).catch((ex) => {
|
||||
if (AppConstants.platform !== "android") {
|
||||
// All previous (non-Android) load attempts have failed, so we bail.
|
||||
throw new Error("UserAgentUpdates: Failed to load " + FILE_UPDATES +
|
||||
ex + "\n" + ex.stack);
|
||||
}
|
||||
// Make one last attempt to read from the Fennec APK root.
|
||||
return readChannel("resource://android/" + FILE_UPDATES);
|
||||
}).then((update) => {
|
||||
// Apply update if loading was successful
|
||||
this._applyUpdate(update);
|
||||
}).catch(Cu.reportError);
|
||||
// Make one last attempt to read from the Fennec APK root.
|
||||
return readChannel("resource://android/" + FILE_UPDATES);
|
||||
})
|
||||
.then(update => {
|
||||
// Apply update if loading was successful
|
||||
this._applyUpdate(update);
|
||||
})
|
||||
.catch(Cu.reportError);
|
||||
this._scheduleUpdate();
|
||||
},
|
||||
|
||||
|
|
@ -152,21 +186,22 @@ var UserAgentUpdates = {
|
|||
let file = FileUtils.getFile(KEY_PREFDIR, [FILE_UPDATES], true);
|
||||
let path = file.path;
|
||||
let bytes = gEncoder.encode(JSON.stringify(update));
|
||||
OS.File.writeAtomic(path, bytes, {tmpPath: path + ".tmp"}).then(
|
||||
() => {
|
||||
this._lastUpdated = Date.now();
|
||||
Services.prefs.setCharPref(
|
||||
PREF_UPDATES_LASTUPDATED, this._lastUpdated.toString());
|
||||
},
|
||||
Cu.reportError
|
||||
);
|
||||
OS.File.writeAtomic(path, bytes, { tmpPath: path + ".tmp" }).then(() => {
|
||||
this._lastUpdated = Date.now();
|
||||
Services.prefs.setCharPref(
|
||||
PREF_UPDATES_LASTUPDATED,
|
||||
this._lastUpdated.toString()
|
||||
);
|
||||
}, Cu.reportError);
|
||||
},
|
||||
|
||||
_getPref(name, def) {
|
||||
try {
|
||||
switch (typeof def) {
|
||||
case "number": return Services.prefs.getIntPref(name);
|
||||
case "boolean": return Services.prefs.getBoolPref(name);
|
||||
case "number":
|
||||
return Services.prefs.getIntPref(name);
|
||||
case "boolean":
|
||||
return Services.prefs.getBoolPref(name);
|
||||
}
|
||||
return Services.prefs.getCharPref(name);
|
||||
} catch (e) {
|
||||
|
|
@ -176,15 +211,33 @@ var UserAgentUpdates = {
|
|||
|
||||
_getParameters() {
|
||||
return {
|
||||
"%DATE%": function() { return Date.now().toString(); },
|
||||
"%PRODUCT%": function() { return Services.appinfo.name; },
|
||||
"%APP_ID%": function() { return Services.appinfo.ID; },
|
||||
"%APP_VERSION%": function() { return Services.appinfo.version; },
|
||||
"%BUILD_ID%": function() { return Services.appinfo.appBuildID; },
|
||||
"%OS%": function() { return Services.appinfo.OS; },
|
||||
"%CHANNEL%": function() { return UpdateUtils.UpdateChannel; },
|
||||
"%DISTRIBUTION%": function() { return this._getPref(PREF_APP_DISTRIBUTION, ""); },
|
||||
"%DISTRIBUTION_VERSION%": function() { return this._getPref(PREF_APP_DISTRIBUTION_VERSION, ""); },
|
||||
"%DATE%": function() {
|
||||
return Date.now().toString();
|
||||
},
|
||||
"%PRODUCT%": function() {
|
||||
return Services.appinfo.name;
|
||||
},
|
||||
"%APP_ID%": function() {
|
||||
return Services.appinfo.ID;
|
||||
},
|
||||
"%APP_VERSION%": function() {
|
||||
return Services.appinfo.version;
|
||||
},
|
||||
"%BUILD_ID%": function() {
|
||||
return Services.appinfo.appBuildID;
|
||||
},
|
||||
"%OS%": function() {
|
||||
return Services.appinfo.OS;
|
||||
},
|
||||
"%CHANNEL%": function() {
|
||||
return UpdateUtils.UpdateChannel;
|
||||
},
|
||||
"%DISTRIBUTION%": function() {
|
||||
return this._getPref(PREF_APP_DISTRIBUTION, "");
|
||||
},
|
||||
"%DISTRIBUTION_VERSION%": function() {
|
||||
return this._getPref(PREF_APP_DISTRIBUTION_VERSION, "");
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -216,21 +269,28 @@ var UserAgentUpdates = {
|
|||
|
||||
_update() {
|
||||
let url = this._getUpdateURL();
|
||||
url && this._fetchUpdate(url,
|
||||
response => { // success
|
||||
// apply update and save overrides to profile
|
||||
this._applyUpdate(response);
|
||||
this._saveToFile(response);
|
||||
this._scheduleUpdate(); // cancel any retries
|
||||
},
|
||||
response => { // error
|
||||
this._scheduleUpdate(true /* retry */);
|
||||
});
|
||||
url &&
|
||||
this._fetchUpdate(
|
||||
url,
|
||||
response => {
|
||||
// success
|
||||
// apply update and save overrides to profile
|
||||
this._applyUpdate(response);
|
||||
this._saveToFile(response);
|
||||
this._scheduleUpdate(); // cancel any retries
|
||||
},
|
||||
response => {
|
||||
// error
|
||||
this._scheduleUpdate(true /* retry */);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_scheduleUpdate(retry) {
|
||||
// only schedule updates in the main process
|
||||
if (Services.appinfo.processType !== Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
|
||||
if (
|
||||
Services.appinfo.processType !== Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
|
||||
) {
|
||||
return;
|
||||
}
|
||||
let interval = this._getPref(PREF_UPDATES_INTERVAL, 604800 /* 1 week */);
|
||||
|
|
@ -257,7 +317,9 @@ var UserAgentUpdates = {
|
|||
} else if (data === PREF_UPDATES_LASTUPDATED) {
|
||||
// reload from file if there has been an update
|
||||
let lastUpdated = parseInt(
|
||||
this._getPref(PREF_UPDATES_LASTUPDATED, "0"), 0);
|
||||
this._getPref(PREF_UPDATES_LASTUPDATED, "0"),
|
||||
0
|
||||
);
|
||||
if (lastUpdated > this._lastUpdated) {
|
||||
this._applySavedUpdate();
|
||||
this._lastUpdated = lastUpdated;
|
||||
|
|
@ -267,8 +329,5 @@ var UserAgentUpdates = {
|
|||
}
|
||||
},
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIObserver,
|
||||
Ci.nsITimerCallback,
|
||||
]),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver, Ci.nsITimerCallback]),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
|
|
|||
|
|
@ -14,54 +14,74 @@ function test() {
|
|||
}
|
||||
|
||||
function nextTest() {
|
||||
if (tests.length)
|
||||
if (tests.length) {
|
||||
executeSoon(tests.shift());
|
||||
else
|
||||
} else {
|
||||
executeSoon(finish);
|
||||
}
|
||||
}
|
||||
|
||||
var tests = [
|
||||
test_asyncFetchBadCert,
|
||||
];
|
||||
var tests = [test_asyncFetchBadCert];
|
||||
|
||||
function test_asyncFetchBadCert() {
|
||||
// Try a load from an untrusted cert, with errors supressed
|
||||
NetUtil.asyncFetch({
|
||||
uri: "https://untrusted.example.com",
|
||||
loadUsingSystemPrincipal: true
|
||||
}, function (aInputStream, aStatusCode, aRequest) {
|
||||
ok(!Components.isSuccessCode(aStatusCode), "request failed");
|
||||
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
|
||||
|
||||
// Now try again with a channel whose notificationCallbacks doesn't suprress errors
|
||||
let channel = NetUtil.newChannel({
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: "https://untrusted.example.com",
|
||||
loadUsingSystemPrincipal: true});
|
||||
channel.notificationCallbacks = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIProgressEventSink,
|
||||
Ci.nsIInterfaceRequestor]),
|
||||
getInterface (aIID) { return this.QueryInterface(aIID); },
|
||||
onProgress () {},
|
||||
onStatus () {}
|
||||
};
|
||||
NetUtil.asyncFetch(channel, function (aInputStream, aStatusCode, aRequest) {
|
||||
loadUsingSystemPrincipal: true,
|
||||
},
|
||||
function(aInputStream, aStatusCode, aRequest) {
|
||||
ok(!Components.isSuccessCode(aStatusCode), "request failed");
|
||||
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
|
||||
|
||||
// Now try a valid request
|
||||
NetUtil.asyncFetch({
|
||||
uri: "https://example.com",
|
||||
loadUsingSystemPrincipal: true
|
||||
}, function (aInputStream, aStatusCode, aRequest) {
|
||||
info("aStatusCode for valid request: " + aStatusCode);
|
||||
ok(Components.isSuccessCode(aStatusCode), "request succeeded");
|
||||
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
|
||||
ok(aRequest.requestSucceeded, "HTTP request succeeded");
|
||||
|
||||
nextTest();
|
||||
// Now try again with a channel whose notificationCallbacks doesn't suprress errors
|
||||
let channel = NetUtil.newChannel({
|
||||
uri: "https://untrusted.example.com",
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
channel.notificationCallbacks = {
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIProgressEventSink,
|
||||
Ci.nsIInterfaceRequestor,
|
||||
]),
|
||||
getInterface(aIID) {
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
onProgress() {},
|
||||
onStatus() {},
|
||||
};
|
||||
NetUtil.asyncFetch(channel, function(
|
||||
aInputStream,
|
||||
aStatusCode,
|
||||
aRequest
|
||||
) {
|
||||
ok(!Components.isSuccessCode(aStatusCode), "request failed");
|
||||
ok(
|
||||
aRequest instanceof Ci.nsIHttpChannel,
|
||||
"request is an nsIHttpChannel"
|
||||
);
|
||||
|
||||
// Now try a valid request
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: "https://example.com",
|
||||
loadUsingSystemPrincipal: true,
|
||||
},
|
||||
function(aInputStream, aStatusCode, aRequest) {
|
||||
info("aStatusCode for valid request: " + aStatusCode);
|
||||
ok(Components.isSuccessCode(aStatusCode), "request succeeded");
|
||||
ok(
|
||||
aRequest instanceof Ci.nsIHttpChannel,
|
||||
"request is an nsIHttpChannel"
|
||||
);
|
||||
ok(aRequest.requestSucceeded, "HTTP request succeeded");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function WindowListener(aURL, aCallback) {
|
||||
|
|
@ -72,15 +92,20 @@ WindowListener.prototype = {
|
|||
onOpenWindow(aXULWindow) {
|
||||
var domwindow = aXULWindow.docShell.domWindow;
|
||||
var self = this;
|
||||
domwindow.addEventListener("load", function() {
|
||||
if (domwindow.document.location.href != self.url)
|
||||
return;
|
||||
domwindow.addEventListener(
|
||||
"load",
|
||||
function() {
|
||||
if (domwindow.document.location.href != self.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow other window load listeners to execute before passing to callback
|
||||
executeSoon(function() {
|
||||
self.callback(domwindow);
|
||||
});
|
||||
}, {once: true});
|
||||
// Allow other window load listeners to execute before passing to callback
|
||||
executeSoon(function() {
|
||||
self.callback(domwindow);
|
||||
});
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
},
|
||||
onCloseWindow(aXULWindow) {},
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,28 +4,48 @@
|
|||
* Open a dummy page, then open about:cache and verify the opened page shows up in the cache.
|
||||
*/
|
||||
add_task(async function() {
|
||||
const kRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/",
|
||||
"https://example.com/");
|
||||
const kRoot = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"https://example.com/"
|
||||
);
|
||||
const kTestPage = kRoot + "dummy.html";
|
||||
// Open the dummy page to get it cached.
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, kTestPage, true);
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
kTestPage,
|
||||
true
|
||||
);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
||||
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:cache", true);
|
||||
tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"about:cache",
|
||||
true
|
||||
);
|
||||
let expectedPageCheck = function(uri) {
|
||||
info("Saw load for " + uri);
|
||||
// Can't easily use searchParms and new URL() because it's an about: URI...
|
||||
return uri.startsWith("about:cache?") && uri.includes("storage=disk");
|
||||
};
|
||||
let diskPageLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, expectedPageCheck);
|
||||
let diskPageLoaded = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
false,
|
||||
expectedPageCheck
|
||||
);
|
||||
await ContentTask.spawn(tab.linkedBrowser, null, function() {
|
||||
ok(!content.document.nodePrincipal.isSystemPrincipal,
|
||||
"about:cache should not have system principal");
|
||||
ok(
|
||||
!content.document.nodePrincipal.isSystemPrincipal,
|
||||
"about:cache should not have system principal"
|
||||
);
|
||||
let principalURI = content.document.nodePrincipal.URI;
|
||||
let channel = content.docShell.currentDocumentChannel;
|
||||
ok(!channel.loadInfo.loadingPrincipal, "Loading principal should be null.");
|
||||
is(principalURI && principalURI.spec, content.document.location.href, "Principal matches location");
|
||||
let links = [... content.document.querySelectorAll("a[href*=disk]")];
|
||||
is(
|
||||
principalURI && principalURI.spec,
|
||||
content.document.location.href,
|
||||
"Principal matches location"
|
||||
);
|
||||
let links = [...content.document.querySelectorAll("a[href*=disk]")];
|
||||
is(links.length, 1, "Should have 1 link to the disk entries");
|
||||
links[0].click();
|
||||
});
|
||||
|
|
@ -37,35 +57,64 @@ add_task(async function() {
|
|||
return uri.startsWith("about:cache-entry") && uri.includes("dummy.html");
|
||||
};
|
||||
let triggeringURISpec = tab.linkedBrowser.currentURI.spec;
|
||||
let entryLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, expectedPageCheck);
|
||||
let entryLoaded = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
false,
|
||||
expectedPageCheck
|
||||
);
|
||||
await ContentTask.spawn(tab.linkedBrowser, kTestPage, function(kTestPage) {
|
||||
ok(!content.document.nodePrincipal.isSystemPrincipal,
|
||||
"about:cache with query params should still not have system principal");
|
||||
ok(
|
||||
!content.document.nodePrincipal.isSystemPrincipal,
|
||||
"about:cache with query params should still not have system principal"
|
||||
);
|
||||
let principalURI = content.document.nodePrincipal.URI;
|
||||
is(principalURI && principalURI.spec, content.document.location.href, "Principal matches location");
|
||||
is(
|
||||
principalURI && principalURI.spec,
|
||||
content.document.location.href,
|
||||
"Principal matches location"
|
||||
);
|
||||
let channel = content.docShell.currentDocumentChannel;
|
||||
principalURI = channel.loadInfo.triggeringPrincipal.URI;
|
||||
is(principalURI && principalURI.spec, "about:cache", "Triggering principal matches previous location");
|
||||
is(
|
||||
principalURI && principalURI.spec,
|
||||
"about:cache",
|
||||
"Triggering principal matches previous location"
|
||||
);
|
||||
ok(!channel.loadInfo.loadingPrincipal, "Loading principal should be null.");
|
||||
let links = [... content.document.querySelectorAll("a[href*='" + kTestPage + "']")];
|
||||
let links = [
|
||||
...content.document.querySelectorAll("a[href*='" + kTestPage + "']"),
|
||||
];
|
||||
is(links.length, 1, "Should have 1 link to the entry for " + kTestPage);
|
||||
links[0].click();
|
||||
});
|
||||
await entryLoaded;
|
||||
info("about:cache entry loaded");
|
||||
|
||||
|
||||
await ContentTask.spawn(tab.linkedBrowser, triggeringURISpec, function(triggeringURISpec) {
|
||||
ok(!content.document.nodePrincipal.isSystemPrincipal,
|
||||
"about:cache-entry should also not have system principal");
|
||||
await ContentTask.spawn(tab.linkedBrowser, triggeringURISpec, function(
|
||||
triggeringURISpec
|
||||
) {
|
||||
ok(
|
||||
!content.document.nodePrincipal.isSystemPrincipal,
|
||||
"about:cache-entry should also not have system principal"
|
||||
);
|
||||
let principalURI = content.document.nodePrincipal.URI;
|
||||
is(principalURI && principalURI.spec, content.document.location.href, "Principal matches location");
|
||||
is(
|
||||
principalURI && principalURI.spec,
|
||||
content.document.location.href,
|
||||
"Principal matches location"
|
||||
);
|
||||
let channel = content.docShell.currentDocumentChannel;
|
||||
principalURI = channel.loadInfo.triggeringPrincipal.URI;
|
||||
is(principalURI && principalURI.spec, triggeringURISpec, "Triggering principal matches previous location");
|
||||
is(
|
||||
principalURI && principalURI.spec,
|
||||
triggeringURISpec,
|
||||
"Triggering principal matches previous location"
|
||||
);
|
||||
ok(!channel.loadInfo.loadingPrincipal, "Loading principal should be null.");
|
||||
ok(content.document.querySelectorAll("th").length,
|
||||
"Should have several table headers with data.");
|
||||
ok(
|
||||
content.document.querySelectorAll("th").length,
|
||||
"Should have several table headers with data."
|
||||
);
|
||||
});
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
add_task(_ => {
|
||||
try {
|
||||
Cc["@mozilla.org/network/effective-tld-service;1"]
|
||||
.createInstance(Ci.nsISupports);
|
||||
Cc["@mozilla.org/network/effective-tld-service;1"].createInstance(
|
||||
Ci.nsISupports
|
||||
);
|
||||
} catch (e) {
|
||||
is(e.result, Cr.NS_ERROR_XPC_CI_RETURNED_FAILURE,
|
||||
"Component creation as an instance fails with expected code");
|
||||
is(
|
||||
e.result,
|
||||
Cr.NS_ERROR_XPC_CI_RETURNED_FAILURE,
|
||||
"Component creation as an instance fails with expected code"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,21 +8,24 @@ const TEST_URL = "http://example.com/browser/netwerk/test/browser/dummy.html";
|
|||
|
||||
const expectedRemote = gMultiProcessBrowser ? "true" : "";
|
||||
|
||||
const resProtocol = Cc["@mozilla.org/network/protocol;1?name=resource"]
|
||||
.getService(Ci.nsIResProtocolHandler);
|
||||
const resProtocol = Cc[
|
||||
"@mozilla.org/network/protocol;1?name=resource"
|
||||
].getService(Ci.nsIResProtocolHandler);
|
||||
|
||||
function frameScript() {
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
let resProtocol = Cc["@mozilla.org/network/protocol;1?name=resource"]
|
||||
.getService(Ci.nsIResProtocolHandler);
|
||||
const { Services } = ChromeUtils.import(
|
||||
"resource://gre/modules/Services.jsm"
|
||||
);
|
||||
let resProtocol = Cc[
|
||||
"@mozilla.org/network/protocol;1?name=resource"
|
||||
].getService(Ci.nsIResProtocolHandler);
|
||||
|
||||
addMessageListener("Test:ResolveURI", function({ data: uri }) {
|
||||
uri = Services.io.newURI(uri);
|
||||
try {
|
||||
let resolved = resProtocol.resolveURI(uri);
|
||||
sendAsyncMessage("Test:ResolvedURI", resolved);
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
sendAsyncMessage("Test:ResolvedURI", null);
|
||||
}
|
||||
});
|
||||
|
|
@ -30,7 +33,7 @@ function frameScript() {
|
|||
|
||||
function waitForEvent(obj, name, capturing, chromeEvent) {
|
||||
info("Waiting for " + name);
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
function listener(event) {
|
||||
info("Saw " + name);
|
||||
obj.removeEventListener(name, listener, capturing, chromeEvent);
|
||||
|
|
@ -45,14 +48,13 @@ function resolveURI(uri) {
|
|||
uri = Services.io.newURI(uri);
|
||||
try {
|
||||
return resProtocol.resolveURI(uri);
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function remoteResolveURI(uri) {
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
let manager = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
function listener({ data: resolved }) {
|
||||
|
|
@ -69,7 +71,10 @@ var loadTestTab = async function() {
|
|||
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TEST_URL);
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")();", true);
|
||||
browser.messageManager.loadFrameScript(
|
||||
"data:,(" + frameScript.toString() + ")();",
|
||||
true
|
||||
);
|
||||
return browser;
|
||||
};
|
||||
|
||||
|
|
@ -77,16 +82,24 @@ var loadTestTab = async function() {
|
|||
var restart = async function() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
// If the tab isn't remote this would crash the main process so skip it
|
||||
if (browser.getAttribute("remote") != "true")
|
||||
if (browser.getAttribute("remote") != "true") {
|
||||
return browser;
|
||||
}
|
||||
|
||||
await BrowserTestUtils.crashBrowser(browser);
|
||||
|
||||
browser.reload();
|
||||
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
is(browser.getAttribute("remote"), expectedRemote, "Browser should be in the right process");
|
||||
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")();", true);
|
||||
is(
|
||||
browser.getAttribute("remote"),
|
||||
expectedRemote,
|
||||
"Browser should be in the right process"
|
||||
);
|
||||
browser.messageManager.loadFrameScript(
|
||||
"data:,(" + frameScript.toString() + ")();",
|
||||
true
|
||||
);
|
||||
return browser;
|
||||
};
|
||||
|
||||
|
|
@ -95,7 +108,11 @@ add_task(async function() {
|
|||
let browser = await loadTestTab();
|
||||
|
||||
// This must be loaded in the remote process for this test to be useful
|
||||
is(browser.getAttribute("remote"), expectedRemote, "Browser should be in the right process");
|
||||
is(
|
||||
browser.getAttribute("remote"),
|
||||
expectedRemote,
|
||||
"Browser should be in the right process"
|
||||
);
|
||||
|
||||
let local = resolveURI("resource://gre/modules/Services.jsm");
|
||||
let remote = await remoteResolveURI("resource://gre/modules/Services.jsm");
|
||||
|
|
@ -109,14 +126,28 @@ add_task(async function() {
|
|||
let browser = await loadTestTab();
|
||||
|
||||
info("Set");
|
||||
resProtocol.setSubstitution("testing", Services.io.newURI("chrome://global/content"));
|
||||
resProtocol.setSubstitution(
|
||||
"testing",
|
||||
Services.io.newURI("chrome://global/content")
|
||||
);
|
||||
let local = resolveURI("resource://testing/test.js");
|
||||
let remote = await remoteResolveURI("resource://testing/test.js");
|
||||
is(local, "chrome://global/content/test.js", "Should resolve in main process");
|
||||
is(remote, "chrome://global/content/test.js", "Should resolve in child process");
|
||||
is(
|
||||
local,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in main process"
|
||||
);
|
||||
is(
|
||||
remote,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in child process"
|
||||
);
|
||||
|
||||
info("Change");
|
||||
resProtocol.setSubstitution("testing", Services.io.newURI("chrome://global/skin"));
|
||||
resProtocol.setSubstitution(
|
||||
"testing",
|
||||
Services.io.newURI("chrome://global/skin")
|
||||
);
|
||||
local = resolveURI("resource://testing/test.js");
|
||||
remote = await remoteResolveURI("resource://testing/test.js");
|
||||
is(local, "chrome://global/skin/test.js", "Should resolve in main process");
|
||||
|
|
@ -137,21 +168,43 @@ add_task(async function() {
|
|||
let browser = await loadTestTab();
|
||||
|
||||
info("Set");
|
||||
resProtocol.setSubstitution("testing", Services.io.newURI("chrome://global/content"));
|
||||
resProtocol.setSubstitution(
|
||||
"testing",
|
||||
Services.io.newURI("chrome://global/content")
|
||||
);
|
||||
let local = resolveURI("resource://testing/test.js");
|
||||
let remote = await remoteResolveURI("resource://testing/test.js");
|
||||
is(local, "chrome://global/content/test.js", "Should resolve in main process");
|
||||
is(remote, "chrome://global/content/test.js", "Should resolve in child process");
|
||||
is(
|
||||
local,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in main process"
|
||||
);
|
||||
is(
|
||||
remote,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in child process"
|
||||
);
|
||||
|
||||
await restart();
|
||||
|
||||
local = resolveURI("resource://testing/test.js");
|
||||
remote = await remoteResolveURI("resource://testing/test.js");
|
||||
is(local, "chrome://global/content/test.js", "Should resolve in main process");
|
||||
is(remote, "chrome://global/content/test.js", "Should resolve in child process");
|
||||
is(
|
||||
local,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in main process"
|
||||
);
|
||||
is(
|
||||
remote,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in child process"
|
||||
);
|
||||
|
||||
info("Change");
|
||||
resProtocol.setSubstitution("testing", Services.io.newURI("chrome://global/skin"));
|
||||
resProtocol.setSubstitution(
|
||||
"testing",
|
||||
Services.io.newURI("chrome://global/skin")
|
||||
);
|
||||
|
||||
await restart();
|
||||
|
||||
|
|
@ -178,19 +231,41 @@ add_task(async function() {
|
|||
let browser = await loadTestTab();
|
||||
|
||||
info("Set");
|
||||
resProtocol.setSubstitution("testing", Services.io.newURI("chrome://global/content"));
|
||||
resProtocol.setSubstitution("testing2", Services.io.newURI("resource://testing"));
|
||||
resProtocol.setSubstitution(
|
||||
"testing",
|
||||
Services.io.newURI("chrome://global/content")
|
||||
);
|
||||
resProtocol.setSubstitution(
|
||||
"testing2",
|
||||
Services.io.newURI("resource://testing")
|
||||
);
|
||||
let local = resolveURI("resource://testing2/test.js");
|
||||
let remote = await remoteResolveURI("resource://testing2/test.js");
|
||||
is(local, "chrome://global/content/test.js", "Should resolve in main process");
|
||||
is(remote, "chrome://global/content/test.js", "Should resolve in child process");
|
||||
is(
|
||||
local,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in main process"
|
||||
);
|
||||
is(
|
||||
remote,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in child process"
|
||||
);
|
||||
|
||||
info("Clear");
|
||||
resProtocol.setSubstitution("testing", null);
|
||||
local = resolveURI("resource://testing2/test.js");
|
||||
remote = await remoteResolveURI("resource://testing2/test.js");
|
||||
is(local, "chrome://global/content/test.js", "Should resolve in main process");
|
||||
is(remote, "chrome://global/content/test.js", "Should resolve in child process");
|
||||
is(
|
||||
local,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in main process"
|
||||
);
|
||||
is(
|
||||
remote,
|
||||
"chrome://global/content/test.js",
|
||||
"Should resolve in child process"
|
||||
);
|
||||
|
||||
resProtocol.setSubstitution("testing2", null);
|
||||
local = resolveURI("resource://testing2/test.js");
|
||||
|
|
|
|||
|
|
@ -8,14 +8,24 @@
|
|||
add_task(async function() {
|
||||
info("Make sure cookie changes in one process are visible in the other");
|
||||
|
||||
const kRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/",
|
||||
"https://example.com/");
|
||||
const kRoot = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"https://example.com/"
|
||||
);
|
||||
const kTestPage = kRoot + "dummy.html";
|
||||
|
||||
Services.cookies.removeAll();
|
||||
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kTestPage, forceNewProcess: true });
|
||||
let tab2 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kTestPage, forceNewProcess: true });
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: kTestPage,
|
||||
forceNewProcess: true,
|
||||
});
|
||||
let tab2 = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: kTestPage,
|
||||
forceNewProcess: true,
|
||||
});
|
||||
|
||||
let browser1 = gBrowser.getBrowserForTab(tab1);
|
||||
let browser2 = gBrowser.getBrowserForTab(tab2);
|
||||
|
|
@ -49,7 +59,11 @@ add_task(async function() {
|
|||
});
|
||||
|
||||
await ContentTask.spawn(browser2, null, async function() {
|
||||
is(content.document.cookie, "a1=other_test; a2=again", "Cookie should be set");
|
||||
is(
|
||||
content.document.cookie,
|
||||
"a1=other_test; a2=again",
|
||||
"Cookie should be set"
|
||||
);
|
||||
content.document.cookie = "a1=; expires=Thu, 01-Jan-1970 00:00:01 GMT;";
|
||||
content.document.cookie = "a2=; expires=Thu, 01-Jan-1970 00:00:01 GMT;";
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,12 @@ const gRegistrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
|||
let gLoadedInProcess2Promise = null;
|
||||
|
||||
function _createProcessChooser(remoteTab, from, to, rejectPromise = false) {
|
||||
let processChooser = new ProcessChooser(remoteTab, "example.com", "example.org", rejectPromise);
|
||||
let processChooser = new ProcessChooser(
|
||||
remoteTab,
|
||||
"example.com",
|
||||
"example.org",
|
||||
rejectPromise
|
||||
);
|
||||
registerCleanupFunction(function() {
|
||||
processChooser.unregister();
|
||||
});
|
||||
|
|
@ -90,21 +95,35 @@ ProcessChooser.prototype = {
|
|||
|
||||
// nsISupports
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
|
||||
}
|
||||
};
|
||||
|
||||
add_task(async function() {
|
||||
info("Check that a redirect in process A may be correctly handled in process B");
|
||||
info(
|
||||
"Check that a redirect in process A may be correctly handled in process B"
|
||||
);
|
||||
|
||||
const kRoot1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content/",
|
||||
"https://example.com/");
|
||||
const kRoot2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content/",
|
||||
"https://example.org/");
|
||||
const kRoot1 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"https://example.com/"
|
||||
);
|
||||
const kRoot2 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"https://example.org/"
|
||||
);
|
||||
const kRoot3 = getRootDirectory(gTestPath);
|
||||
|
||||
// This process will attempt to load the page that redirects to a different origin
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kRoot1 + "dummy.html", forceNewProcess: true });
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: kRoot1 + "dummy.html",
|
||||
forceNewProcess: true,
|
||||
});
|
||||
// This process will eventually receive the redirected channel.
|
||||
let tab2 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kRoot2 + "dummy.html", forceNewProcess: true });
|
||||
let tab2 = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: kRoot2 + "dummy.html",
|
||||
forceNewProcess: true,
|
||||
});
|
||||
|
||||
let browser1 = gBrowser.getBrowserForTab(tab1);
|
||||
let browser2 = gBrowser.getBrowserForTab(tab2);
|
||||
|
|
@ -112,7 +131,11 @@ add_task(async function() {
|
|||
// This is for testing purposes only.
|
||||
// This "process chooser" will direct the channel to be opened in the second
|
||||
// tab, and thus in the second parent.
|
||||
let processChooser = _createProcessChooser(browser2.frameLoader.remoteTab, "example.com", "example.org");
|
||||
let processChooser = _createProcessChooser(
|
||||
browser2.frameLoader.remoteTab,
|
||||
"example.com",
|
||||
"example.org"
|
||||
);
|
||||
|
||||
info("Loading redirected URL");
|
||||
// Open the URL in the first process. We expect it to wind up in the second
|
||||
|
|
@ -120,18 +143,32 @@ add_task(async function() {
|
|||
|
||||
// Define the child listener in the new channel.
|
||||
await ContentTask.spawn(browser2, null, async function(arg) {
|
||||
function ChannelListener(childListener) { this.childListener = childListener; }
|
||||
function ChannelListener(childListener) {
|
||||
this.childListener = childListener;
|
||||
}
|
||||
ChannelListener.prototype = {
|
||||
onStartRequest(aRequest) {
|
||||
info("onStartRequest");
|
||||
let channel = aRequest.QueryInterface(Ci.nsIChannel);
|
||||
Assert.equal(channel.URI.spec, this.childListener.URI, "Make sure the channel has the proper URI");
|
||||
Assert.equal(channel.originalURI.spec, this.childListener.originalURI, "Make sure the originalURI is correct");
|
||||
Assert.equal(
|
||||
channel.URI.spec,
|
||||
this.childListener.URI,
|
||||
"Make sure the channel has the proper URI"
|
||||
);
|
||||
Assert.equal(
|
||||
channel.originalURI.spec,
|
||||
this.childListener.originalURI,
|
||||
"Make sure the originalURI is correct"
|
||||
);
|
||||
},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
info("onStopRequest");
|
||||
Assert.equal(aStatusCode, Cr.NS_OK, "Check the status code");
|
||||
Assert.equal(this.gotData, true, "Check that the channel received data");
|
||||
Assert.equal(
|
||||
this.gotData,
|
||||
true,
|
||||
"Check that the channel received data"
|
||||
);
|
||||
if (this.childListener.onComplete) {
|
||||
this.childListener.onComplete();
|
||||
}
|
||||
|
|
@ -141,10 +178,17 @@ add_task(async function() {
|
|||
this.gotData = true;
|
||||
info("onDataAvailable");
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener,Ci.nsIRequestObserver])
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIStreamListener,
|
||||
Ci.nsIRequestObserver,
|
||||
]),
|
||||
};
|
||||
|
||||
function ChildListener(uri, originalURI, resolve) { this.URI = uri; this.originalURI = originalURI; this.resolve = resolve;}
|
||||
function ChildListener(uri, originalURI, resolve) {
|
||||
this.URI = uri;
|
||||
this.originalURI = originalURI;
|
||||
this.resolve = resolve;
|
||||
}
|
||||
ChildListener.prototype = {
|
||||
// nsIChildProcessChannelListener
|
||||
onChannelReady(aChildChannel, aIdentifier) {
|
||||
|
|
@ -161,32 +205,54 @@ add_task(async function() {
|
|||
},
|
||||
lockFactory() {},
|
||||
// nsISupports
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIChildProcessChannelListener, Ci.nsIFactory]),
|
||||
classID: Components.ID("{a6c142a9-eb38-4a09-a940-b71cdad479e1}")
|
||||
}
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIChildProcessChannelListener,
|
||||
Ci.nsIFactory,
|
||||
]),
|
||||
classID: Components.ID("{a6c142a9-eb38-4a09-a940-b71cdad479e1}"),
|
||||
};
|
||||
|
||||
content.window.ChildListener = ChildListener;
|
||||
});
|
||||
|
||||
// This promise instantiates a ChildListener and is resolved when the redirected
|
||||
// channel is completed.
|
||||
let loadedInProcess2Promise = ContentTask.spawn(browser2, { URI: kRoot2 + "dummy.html", originalURI: kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"}, async function(arg) {
|
||||
// We register the listener in process no. 2
|
||||
return new Promise(resolve => {
|
||||
var childListener = new content.window.ChildListener(arg.URI, arg.originalURI, resolve);
|
||||
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
childListener.onComplete = () => {
|
||||
registrar.unregisterFactory(childListener.classID, childListener);
|
||||
}
|
||||
registrar.registerFactory(childListener.classID, "",
|
||||
"@mozilla.org/network/childProcessChannelListener;1",
|
||||
childListener);
|
||||
});
|
||||
});
|
||||
let loadedInProcess2Promise = ContentTask.spawn(
|
||||
browser2,
|
||||
{
|
||||
URI: kRoot2 + "dummy.html",
|
||||
originalURI: kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html",
|
||||
},
|
||||
async function(arg) {
|
||||
// We register the listener in process no. 2
|
||||
return new Promise(resolve => {
|
||||
var childListener = new content.window.ChildListener(
|
||||
arg.URI,
|
||||
arg.originalURI,
|
||||
resolve
|
||||
);
|
||||
var registrar = Components.manager.QueryInterface(
|
||||
Ci.nsIComponentRegistrar
|
||||
);
|
||||
childListener.onComplete = () => {
|
||||
registrar.unregisterFactory(childListener.classID, childListener);
|
||||
};
|
||||
registrar.registerFactory(
|
||||
childListener.classID,
|
||||
"",
|
||||
"@mozilla.org/network/childProcessChannelListener;1",
|
||||
childListener
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
let browser1LoadHasStopped = BrowserTestUtils.browserStopped(browser1);
|
||||
|
||||
await BrowserTestUtils.loadURI(browser1, kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html");
|
||||
await BrowserTestUtils.loadURI(
|
||||
browser1,
|
||||
kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"
|
||||
);
|
||||
|
||||
// Check that the channel was delivered to process no. 2
|
||||
await loadedInProcess2Promise;
|
||||
|
|
@ -195,9 +261,17 @@ add_task(async function() {
|
|||
await browser1LoadHasStopped;
|
||||
|
||||
// check that a rejected promise also works.
|
||||
processChooser = _createProcessChooser(browser2.frameLoader.remoteTab, "example.com", "example.org", true);
|
||||
processChooser = _createProcessChooser(
|
||||
browser2.frameLoader.remoteTab,
|
||||
"example.com",
|
||||
"example.org",
|
||||
true
|
||||
);
|
||||
let browser1LoadHasStoppedAgain = BrowserTestUtils.browserStopped(browser1);
|
||||
await BrowserTestUtils.loadURI(browser1, kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html");
|
||||
await BrowserTestUtils.loadURI(
|
||||
browser1,
|
||||
kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"
|
||||
);
|
||||
await browser1LoadHasStoppedAgain;
|
||||
info("this is done now");
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ const NORMAL_ACTION_URI = ACTION_BASE + "normal.html";
|
|||
const UPLOAD_ACTION_URI = ACTION_BASE + "upload.html";
|
||||
const POST_ACTION_URI = ACTION_BASE + "post.html";
|
||||
|
||||
function CustomProtocolHandler() {
|
||||
}
|
||||
function CustomProtocolHandler() {}
|
||||
CustomProtocolHandler.prototype = {
|
||||
/** nsIProtocolHandler */
|
||||
get scheme() {
|
||||
|
|
@ -28,8 +27,10 @@ CustomProtocolHandler.prototype = {
|
|||
return -1;
|
||||
},
|
||||
get protocolFlags() {
|
||||
return Ci.nsIProtocolHandler.URI_NORELATIVE |
|
||||
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE;
|
||||
return (
|
||||
Ci.nsIProtocolHandler.URI_NORELATIVE |
|
||||
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE
|
||||
);
|
||||
},
|
||||
newChannel(aURI, aLoadInfo) {
|
||||
return new CustomChannel(aURI, aLoadInfo);
|
||||
|
|
@ -48,9 +49,11 @@ CustomProtocolHandler.prototype = {
|
|||
lockFactory() {},
|
||||
|
||||
/** nsISupports */
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler,
|
||||
Ci.nsIFactory]),
|
||||
classID: Components.ID("{16d594bc-d9d8-47ae-a139-ea714dc0c35c}")
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIProtocolHandler,
|
||||
Ci.nsIFactory,
|
||||
]),
|
||||
classID: Components.ID("{16d594bc-d9d8-47ae-a139-ea714dc0c35c}"),
|
||||
};
|
||||
|
||||
function CustomChannel(aURI, aLoadInfo) {
|
||||
|
|
@ -94,8 +97,7 @@ CustomChannel.prototype = {
|
|||
get contentType() {
|
||||
return "text/html";
|
||||
},
|
||||
set contentType(val) {
|
||||
},
|
||||
set contentType(val) {},
|
||||
contentCharset: "UTF-8",
|
||||
get contentLength() {
|
||||
return -1;
|
||||
|
|
@ -137,8 +139,9 @@ document.getElementById('form').submit();
|
|||
var postData = "";
|
||||
var headers = {};
|
||||
if (this._uploadStream) {
|
||||
var bstream = Cc["@mozilla.org/binaryinputstream;1"]
|
||||
.createInstance(Ci.nsIBinaryInputStream);
|
||||
var bstream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
|
||||
Ci.nsIBinaryInputStream
|
||||
);
|
||||
bstream.setInputStream(this._uploadStream);
|
||||
postData = bstream.readBytes(bstream.available());
|
||||
|
||||
|
|
@ -160,22 +163,23 @@ document.getElementById('form').submit();
|
|||
</html>
|
||||
`;
|
||||
|
||||
var stream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
var stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
stream.setData(data, data.length);
|
||||
|
||||
var runnable = {
|
||||
run: () => {
|
||||
try {
|
||||
aListener.onStartRequest(this, null);
|
||||
} catch(e) {}
|
||||
} catch (e) {}
|
||||
try {
|
||||
aListener.onDataAvailable(this, stream, 0, stream.available());
|
||||
} catch(e) {}
|
||||
} catch (e) {}
|
||||
try {
|
||||
aListener.onStopRequest(this, null, Cr.NS_OK);
|
||||
} catch(e) {}
|
||||
}
|
||||
} catch (e) {}
|
||||
},
|
||||
};
|
||||
Services.tm.dispatchToMainThread(runnable);
|
||||
},
|
||||
|
|
@ -184,7 +188,7 @@ document.getElementById('form').submit();
|
|||
get name() {
|
||||
return this.uri.spec;
|
||||
},
|
||||
isPending () {
|
||||
isPending() {
|
||||
return false;
|
||||
},
|
||||
get status() {
|
||||
|
|
@ -192,9 +196,10 @@ document.getElementById('form').submit();
|
|||
},
|
||||
cancel(status) {},
|
||||
loadGroup: null,
|
||||
loadFlags: Ci.nsIRequest.LOAD_NORMAL |
|
||||
Ci.nsIRequest.INHIBIT_CACHING |
|
||||
Ci.nsIRequest.LOAD_BYPASS_CACHE,
|
||||
loadFlags:
|
||||
Ci.nsIRequest.LOAD_NORMAL |
|
||||
Ci.nsIRequest.INHIBIT_CACHING |
|
||||
Ci.nsIRequest.LOAD_BYPASS_CACHE,
|
||||
};
|
||||
|
||||
function frameScript() {
|
||||
|
|
@ -203,11 +208,17 @@ function frameScript() {
|
|||
if (content) {
|
||||
var frame = content.document.getElementById("frame");
|
||||
if (frame) {
|
||||
var upload_stream = frame.contentDocument.getElementById("upload_stream");
|
||||
var upload_stream = frame.contentDocument.getElementById(
|
||||
"upload_stream"
|
||||
);
|
||||
var post_data = frame.contentDocument.getElementById("post_data");
|
||||
var headers = frame.contentDocument.getElementById("upload_headers");
|
||||
if (upload_stream && post_data && headers) {
|
||||
sendAsyncMessage("Test:IFrameLoaded", [upload_stream.value, post_data.value, headers.value]);
|
||||
sendAsyncMessage("Test:IFrameLoaded", [
|
||||
upload_stream.value,
|
||||
post_data.value,
|
||||
headers.value,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +236,10 @@ function loadTestTab(uri) {
|
|||
var browser = gBrowser.selectedBrowser;
|
||||
|
||||
let manager = browser.messageManager;
|
||||
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")();", true);
|
||||
browser.messageManager.loadFrameScript(
|
||||
"data:,(" + frameScript.toString() + ")();",
|
||||
true
|
||||
);
|
||||
|
||||
return new Promise(resolve => {
|
||||
function listener({ data: [hasUploadStream, postData, headers] }) {
|
||||
|
|
@ -241,9 +255,12 @@ function loadTestTab(uri) {
|
|||
add_task(async function() {
|
||||
var handler = new CustomProtocolHandler();
|
||||
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(handler.classID, "",
|
||||
"@mozilla.org/network/protocol;1?name=" + handler.scheme,
|
||||
handler);
|
||||
registrar.registerFactory(
|
||||
handler.classID,
|
||||
"",
|
||||
"@mozilla.org/network/protocol;1?name=" + handler.scheme,
|
||||
handler
|
||||
);
|
||||
registerCleanupFunction(function() {
|
||||
registrar.unregisterFactory(handler.classID, handler);
|
||||
});
|
||||
|
|
@ -267,8 +284,7 @@ add_task(async function() {
|
|||
var [hasUploadStream, postData, headers] = await loadTestTab(POST_FORM_URI);
|
||||
|
||||
is(hasUploadStream, "yes", "post action should have uploadStream");
|
||||
is(postData, "foo=bar\r\n",
|
||||
"POST data is received correctly");
|
||||
is(postData, "foo=bar\r\n", "POST data is received correctly");
|
||||
|
||||
is(headers["Content-Type"], "text/plain", "Content-Type header is correct");
|
||||
is(headers["Content-Length"], undefined, "Content-Length header is correct");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Tests for bug 1241100: Post to local file should not overwrite the file.
|
||||
*/
|
||||
|
||||
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
async function createTestFile(filename, content) {
|
||||
let path = OS.Path.join(OS.Constants.Path.tmpDir, filename);
|
||||
|
|
@ -78,7 +78,10 @@ add_task(async function() {
|
|||
|
||||
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, postURI);
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")();", true);
|
||||
browser.messageManager.loadFrameScript(
|
||||
"data:,(" + frameScript.toString() + ")();",
|
||||
true
|
||||
);
|
||||
await new Promise(resolve => {
|
||||
let manager = browser.messageManager;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,46 +8,69 @@
|
|||
add_task(async function() {
|
||||
info("Make sure navigation through links in resource:// pages work");
|
||||
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "resource://gre/" }, async function(browser) {
|
||||
// Following a directory link shall properly open the directory (bug 1224046)
|
||||
await ContentTask.spawn(browser, {}, function() {
|
||||
let link = Array.prototype.filter.call(content.document.getElementsByClassName('dir'), function(element) {
|
||||
let name = element.textContent;
|
||||
// Depending whether resource:// is backed by jar: or file://,
|
||||
// directories either have a trailing slash or they don't.
|
||||
if (name.endsWith("/")) {
|
||||
name = name.slice(0, -1);
|
||||
}
|
||||
return name == "components";
|
||||
})[0];
|
||||
// First ensure the link is in the viewport
|
||||
link.scrollIntoView();
|
||||
// Then click on it.
|
||||
link.click();
|
||||
});
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "resource://gre/" },
|
||||
async function(browser) {
|
||||
// Following a directory link shall properly open the directory (bug 1224046)
|
||||
await ContentTask.spawn(browser, {}, function() {
|
||||
let link = Array.prototype.filter.call(
|
||||
content.document.getElementsByClassName("dir"),
|
||||
function(element) {
|
||||
let name = element.textContent;
|
||||
// Depending whether resource:// is backed by jar: or file://,
|
||||
// directories either have a trailing slash or they don't.
|
||||
if (name.endsWith("/")) {
|
||||
name = name.slice(0, -1);
|
||||
}
|
||||
return name == "components";
|
||||
}
|
||||
)[0];
|
||||
// First ensure the link is in the viewport
|
||||
link.scrollIntoView();
|
||||
// Then click on it.
|
||||
link.click();
|
||||
});
|
||||
|
||||
await BrowserTestUtils.browserLoaded(browser, undefined, "resource://gre/components/");
|
||||
await BrowserTestUtils.browserLoaded(
|
||||
browser,
|
||||
undefined,
|
||||
"resource://gre/components/"
|
||||
);
|
||||
|
||||
// Following the parent link shall properly open the parent (bug 1366180)
|
||||
await ContentTask.spawn(browser, {}, function() {
|
||||
let link = content.document.getElementById('UI_goUp').getElementsByTagName('a')[0];
|
||||
// The link should always be high enough in the page to be in the viewport.
|
||||
link.click();
|
||||
});
|
||||
// Following the parent link shall properly open the parent (bug 1366180)
|
||||
await ContentTask.spawn(browser, {}, function() {
|
||||
let link = content.document
|
||||
.getElementById("UI_goUp")
|
||||
.getElementsByTagName("a")[0];
|
||||
// The link should always be high enough in the page to be in the viewport.
|
||||
link.click();
|
||||
});
|
||||
|
||||
await BrowserTestUtils.browserLoaded(browser, undefined, "resource://gre/");
|
||||
await BrowserTestUtils.browserLoaded(
|
||||
browser,
|
||||
undefined,
|
||||
"resource://gre/"
|
||||
);
|
||||
|
||||
// Following a link to a given file shall properly open the file.
|
||||
await ContentTask.spawn(browser, {}, function() {
|
||||
let link = Array.prototype.filter.call(content.document.getElementsByClassName('file'), function(element) {
|
||||
return element.textContent == "greprefs.js";
|
||||
})[0];
|
||||
link.scrollIntoView();
|
||||
link.click();
|
||||
});
|
||||
// Following a link to a given file shall properly open the file.
|
||||
await ContentTask.spawn(browser, {}, function() {
|
||||
let link = Array.prototype.filter.call(
|
||||
content.document.getElementsByClassName("file"),
|
||||
function(element) {
|
||||
return element.textContent == "greprefs.js";
|
||||
}
|
||||
)[0];
|
||||
link.scrollIntoView();
|
||||
link.click();
|
||||
});
|
||||
|
||||
await BrowserTestUtils.browserLoaded(browser, undefined, "resource://gre/greprefs.js");
|
||||
await BrowserTestUtils.browserLoaded(
|
||||
browser,
|
||||
undefined,
|
||||
"resource://gre/greprefs.js"
|
||||
);
|
||||
|
||||
ok(true, "Got to the end of the test!");
|
||||
});
|
||||
ok(true, "Got to the end of the test!");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,9 +2,13 @@
|
|||
// domain. The cookie should be considered third party.
|
||||
|
||||
add_task(async function() {
|
||||
const iconUrl = "http://example.org/browser/netwerk/test/browser/damonbowling.jpg";
|
||||
const pageUrl = "http://example.com/browser/netwerk/test/browser/file_favicon.html";
|
||||
await SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 1]]});
|
||||
const iconUrl =
|
||||
"http://example.org/browser/netwerk/test/browser/damonbowling.jpg";
|
||||
const pageUrl =
|
||||
"http://example.com/browser/netwerk/test/browser/file_favicon.html";
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["network.cookie.cookieBehavior", 1]],
|
||||
});
|
||||
|
||||
let promise = TestUtils.topicObserved("cookie-rejected", subject => {
|
||||
let uri = subject.QueryInterface(Ci.nsIURI);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
* 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 ROOT_URL = getRootDirectory(gTestPath).replace("chrome://mochitests/content/",
|
||||
"https://example.com/");
|
||||
const ROOT_URL = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"https://example.com/"
|
||||
);
|
||||
const TEST_URL = "about:license";
|
||||
const TEST_URL2 = ROOT_URL + "ioactivity.html";
|
||||
|
||||
|
|
@ -15,34 +17,32 @@ var gotSqlite = false;
|
|||
var gotEmptyData = false;
|
||||
|
||||
function processResults(results) {
|
||||
for (let data of results) {
|
||||
console.log(data.location);
|
||||
gotEmptyData = data.rx == 0 && data.tx == 0 && !gotEmptyData
|
||||
gotSocket = data.location.startsWith("socket://127.0.0.1:") || gotSocket;
|
||||
gotFile = data.location.endsWith("aboutLicense.css") || gotFile;
|
||||
gotSqlite = data.location.endsWith("places.sqlite") || gotSqlite;
|
||||
}
|
||||
};
|
||||
for (let data of results) {
|
||||
console.log(data.location);
|
||||
gotEmptyData = data.rx == 0 && data.tx == 0 && !gotEmptyData;
|
||||
gotSocket = data.location.startsWith("socket://127.0.0.1:") || gotSocket;
|
||||
gotFile = data.location.endsWith("aboutLicense.css") || gotFile;
|
||||
gotSqlite = data.location.endsWith("places.sqlite") || gotSqlite;
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function testRequestIOActivity() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["io.activity.enabled", true],
|
||||
]
|
||||
});
|
||||
waitForExplicitFinish();
|
||||
Services.obs.notifyObservers(null, "profile-initial-state");
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["io.activity.enabled", true]],
|
||||
});
|
||||
waitForExplicitFinish();
|
||||
Services.obs.notifyObservers(null, "profile-initial-state");
|
||||
|
||||
await BrowserTestUtils.withNewTab(TEST_URL, async function(browser) {
|
||||
await BrowserTestUtils.withNewTab(TEST_URL2, async function(browser) {
|
||||
let results = await ChromeUtils.requestIOActivity();
|
||||
processResults(results);
|
||||
await BrowserTestUtils.withNewTab(TEST_URL, async function(browser) {
|
||||
await BrowserTestUtils.withNewTab(TEST_URL2, async function(browser) {
|
||||
let results = await ChromeUtils.requestIOActivity();
|
||||
processResults(results);
|
||||
|
||||
ok(gotSocket, "A socket was used");
|
||||
// test deactivated for now
|
||||
// ok(gotFile, "A file was used");
|
||||
ok(gotSqlite, "A sqlite DB was used");
|
||||
ok(!gotEmptyData, "Every I/O event had data");
|
||||
});
|
||||
ok(gotSocket, "A socket was used");
|
||||
// test deactivated for now
|
||||
// ok(gotFile, "A file was used");
|
||||
ok(gotSqlite, "A sqlite DB was used");
|
||||
ok(!gotEmptyData, "Every I/O event had data");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -13,8 +13,10 @@ load(_HTTPD_JS_PATH.path);
|
|||
// if these tests fail, we'll want the debug output
|
||||
var linDEBUG = true;
|
||||
|
||||
var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
var {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
var { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
/**
|
||||
* Constructs a new nsHttpServer instance. This function is intended to
|
||||
|
|
@ -33,8 +35,10 @@ function createServer() {
|
|||
* the URL of the channel to create
|
||||
*/
|
||||
function makeChannel(url) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true})
|
||||
.QueryInterface(Ci.nsIHttpChannel);
|
||||
return NetUtil.newChannel({
|
||||
uri: url,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,7 +51,6 @@ function makeBIS(stream) {
|
|||
return new BinaryInputStream(stream);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the contents of the file as a string.
|
||||
*
|
||||
|
|
@ -58,8 +61,12 @@ function makeBIS(stream) {
|
|||
*/
|
||||
function fileContents(file) {
|
||||
const PR_RDONLY = 0x01;
|
||||
var fis = new FileInputStream(file, PR_RDONLY, 0o444,
|
||||
Ci.nsIFileInputStream.CLOSE_ON_EOF);
|
||||
var fis = new FileInputStream(
|
||||
file,
|
||||
PR_RDONLY,
|
||||
0o444,
|
||||
Ci.nsIFileInputStream.CLOSE_ON_EOF
|
||||
);
|
||||
var sis = new ScriptableInputStream(fis);
|
||||
var contents = sis.read(file.fileSize);
|
||||
sis.close();
|
||||
|
|
@ -80,14 +87,14 @@ function* LineIterator(data) {
|
|||
var index = 0;
|
||||
do {
|
||||
index = data.indexOf("\r\n");
|
||||
if (index >= 0)
|
||||
if (index >= 0) {
|
||||
yield data.substring(0, index);
|
||||
else
|
||||
} else {
|
||||
yield data;
|
||||
}
|
||||
|
||||
data = data.substring(index + 2);
|
||||
}
|
||||
while (index >= 0);
|
||||
} while (index >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,14 +110,18 @@ function* LineIterator(data) {
|
|||
function expectLines(iter, expectedLines) {
|
||||
var index = 0;
|
||||
for (var line of iter) {
|
||||
if (expectedLines.length == index)
|
||||
throw new Error(`Error: got more than ${expectedLines.length} expected lines!`);
|
||||
if (expectedLines.length == index) {
|
||||
throw new Error(
|
||||
`Error: got more than ${expectedLines.length} expected lines!`
|
||||
);
|
||||
}
|
||||
|
||||
var expected = expectedLines[index++];
|
||||
if (expected !== line)
|
||||
if (expected !== line) {
|
||||
throw new Error(`Error on line ${index}!
|
||||
actual: '${line}',
|
||||
expect: '${expected}'`);
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedLines.length !== index) {
|
||||
|
|
@ -148,8 +159,9 @@ function writeDetails(request, response) {
|
|||
*/
|
||||
function skipHeaders(iter) {
|
||||
var line = iter.next().value;
|
||||
while (line !== "")
|
||||
while (line !== "") {
|
||||
line = iter.next().value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -162,8 +174,9 @@ function skipHeaders(iter) {
|
|||
* the expected exception
|
||||
*/
|
||||
function isException(e, code) {
|
||||
if (e !== code && e.result !== code)
|
||||
if (e !== code && e.result !== code) {
|
||||
do_throw("unexpected error: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -180,7 +193,6 @@ function callLater(msecs, callback) {
|
|||
do_timeout(msecs, callback);
|
||||
}
|
||||
|
||||
|
||||
/** *****************************************************
|
||||
* SIMPLE SUPPORT FOR LOADING/TESTING A SERIES OF URLS *
|
||||
*******************************************************/
|
||||
|
|
@ -192,7 +204,9 @@ function callLater(msecs, callback) {
|
|||
function testComplete(srv) {
|
||||
return function complete() {
|
||||
do_test_pending();
|
||||
srv.stop(function quit() { do_test_finished(); });
|
||||
srv.stop(function quit() {
|
||||
do_test_finished();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +232,7 @@ function testComplete(srv) {
|
|||
* nothing needs to be done
|
||||
*/
|
||||
function Test(path, initChannel, onStartRequest, onStopRequest) {
|
||||
function nil() { }
|
||||
function nil() {}
|
||||
|
||||
this.path = path;
|
||||
this.initChannel = initChannel || nil;
|
||||
|
|
@ -254,7 +268,10 @@ function runHttpTests(testArray, done) {
|
|||
test.initChannel(ch);
|
||||
} catch (e) {
|
||||
try {
|
||||
do_report_unexpected_exception(e, "testArray[" + testIndex + "].initChannel(ch)");
|
||||
do_report_unexpected_exception(
|
||||
e,
|
||||
"testArray[" + testIndex + "].initChannel(ch)"
|
||||
);
|
||||
} catch (x) {
|
||||
/* swallow and let tests continue */
|
||||
}
|
||||
|
|
@ -268,65 +285,74 @@ function runHttpTests(testArray, done) {
|
|||
var testIndex = -1;
|
||||
|
||||
/** Stream listener for the channels. */
|
||||
var listener =
|
||||
{
|
||||
/** Current channel being observed by this. */
|
||||
_channel: null,
|
||||
/** Array of bytes of data in body of response. */
|
||||
_data: [],
|
||||
var listener = {
|
||||
/** Current channel being observed by this. */
|
||||
_channel: null,
|
||||
/** Array of bytes of data in body of response. */
|
||||
_data: [],
|
||||
|
||||
onStartRequest(request) {
|
||||
Assert.ok(request === this._channel);
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
onStartRequest(request) {
|
||||
Assert.ok(request === this._channel);
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
this._data.length = 0;
|
||||
this._data.length = 0;
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
testArray[testIndex].onStartRequest(ch);
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e, "testArray[" + testIndex + "].onStartRequest");
|
||||
}
|
||||
testArray[testIndex].onStartRequest(ch);
|
||||
} catch (e) {
|
||||
do_note_exception(e, "!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called...");
|
||||
do_report_unexpected_exception(
|
||||
e,
|
||||
"testArray[" + testIndex + "].onStartRequest"
|
||||
);
|
||||
}
|
||||
},
|
||||
onDataAvailable(request, inputStream, offset, count) {
|
||||
var quantum = 262144; // just above half the argument-count limit
|
||||
var bis = makeBIS(inputStream);
|
||||
for (var start = 0; start < count; start += quantum) {
|
||||
var newData = bis.readByteArray(Math.min(quantum, count - start));
|
||||
Array.prototype.push.apply(this._data, newData);
|
||||
}
|
||||
},
|
||||
onStopRequest(request, status) {
|
||||
this._channel = null;
|
||||
} catch (e) {
|
||||
do_note_exception(
|
||||
e,
|
||||
"!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called..."
|
||||
);
|
||||
}
|
||||
},
|
||||
onDataAvailable(request, inputStream, offset, count) {
|
||||
var quantum = 262144; // just above half the argument-count limit
|
||||
var bis = makeBIS(inputStream);
|
||||
for (var start = 0; start < count; start += quantum) {
|
||||
var newData = bis.readByteArray(Math.min(quantum, count - start));
|
||||
Array.prototype.push.apply(this._data, newData);
|
||||
}
|
||||
},
|
||||
onStopRequest(request, status) {
|
||||
this._channel = null;
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
// NB: The onStopRequest callback must run before performNextTest here,
|
||||
// because the latter runs the next test's initChannel callback, and
|
||||
// we want one test to be sequentially processed before the next
|
||||
// one.
|
||||
// NB: The onStopRequest callback must run before performNextTest here,
|
||||
// because the latter runs the next test's initChannel callback, and
|
||||
// we want one test to be sequentially processed before the next
|
||||
// one.
|
||||
try {
|
||||
testArray[testIndex].onStopRequest(ch, status, this._data);
|
||||
} finally {
|
||||
try {
|
||||
testArray[testIndex].onStopRequest(ch, status, this._data);
|
||||
performNextTest();
|
||||
} finally {
|
||||
try {
|
||||
performNextTest();
|
||||
} finally {
|
||||
do_test_finished();
|
||||
}
|
||||
do_test_finished();
|
||||
}
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIStreamListener", "nsIRequestObserver"]),
|
||||
};
|
||||
}
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIStreamListener",
|
||||
"nsIRequestObserver",
|
||||
]),
|
||||
};
|
||||
|
||||
performNextTest();
|
||||
}
|
||||
|
||||
|
||||
/** **************************************
|
||||
* RAW REQUEST FORMAT TESTING FUNCTIONS *
|
||||
****************************************/
|
||||
|
|
@ -350,16 +376,24 @@ function runHttpTests(testArray, done) {
|
|||
* environment between tests
|
||||
*/
|
||||
function RawTest(host, port, data, responseCheck) {
|
||||
if (0 > port || 65535 < port || port % 1 !== 0)
|
||||
if (0 > port || 65535 < port || port % 1 !== 0) {
|
||||
throw new Error("bad port");
|
||||
if (!(data instanceof Array))
|
||||
}
|
||||
if (!(data instanceof Array)) {
|
||||
data = [data];
|
||||
if (data.length <= 0)
|
||||
}
|
||||
if (data.length <= 0) {
|
||||
throw new Error("bad data length");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
if (!data.every(function(v) { return /^[\x00-\xff]*$/.test(v); }))
|
||||
if (
|
||||
!data.every(function(v) {
|
||||
return /^[\x00-\xff]*$/.test(v);
|
||||
})
|
||||
) {
|
||||
throw new Error("bad data contained non-byte-valued character");
|
||||
}
|
||||
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
|
@ -380,12 +414,12 @@ function RawTest(host, port, data, responseCheck) {
|
|||
function runRawTests(testArray, done, beforeTestCallback) {
|
||||
do_test_pending();
|
||||
|
||||
var sts = Cc["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Ci.nsISocketTransportService);
|
||||
var sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(
|
||||
Ci.nsISocketTransportService
|
||||
);
|
||||
|
||||
var currentThread = Cc["@mozilla.org/thread-manager;1"]
|
||||
.getService()
|
||||
.currentThread;
|
||||
var currentThread = Cc["@mozilla.org/thread-manager;1"].getService()
|
||||
.currentThread;
|
||||
|
||||
/** Kicks off running the next test in the array. */
|
||||
function performNextTest() {
|
||||
|
|
@ -402,16 +436,17 @@ function runRawTests(testArray, done, beforeTestCallback) {
|
|||
if (beforeTestCallback) {
|
||||
try {
|
||||
beforeTestCallback(testIndex);
|
||||
} catch (e) { /* We don't care if this call fails */ }
|
||||
} catch (e) {
|
||||
/* We don't care if this call fails */
|
||||
}
|
||||
}
|
||||
|
||||
var rawTest = testArray[testIndex];
|
||||
|
||||
var transport =
|
||||
sts.createTransport([], rawTest.host, rawTest.port, null);
|
||||
var transport = sts.createTransport([], rawTest.host, rawTest.port, null);
|
||||
|
||||
var inStream = transport.openInputStream(0, 0, 0);
|
||||
var outStream = transport.openOutputStream(0, 0, 0);
|
||||
var outStream = transport.openOutputStream(0, 0, 0);
|
||||
|
||||
// reset
|
||||
dataIndex = 0;
|
||||
|
|
@ -432,8 +467,12 @@ function runRawTests(testArray, done, beforeTestCallback) {
|
|||
// guarantee that 'stream' passed in here been QIed to nsIAsyncOutputStream
|
||||
// since the last GC.
|
||||
stream = stream.QueryInterface(Ci.nsIAsyncOutputStream);
|
||||
stream.asyncWait(writer, 0, testArray[testIndex].data[dataIndex].length,
|
||||
currentThread);
|
||||
stream.asyncWait(
|
||||
writer,
|
||||
0,
|
||||
testArray[testIndex].data[dataIndex].length,
|
||||
currentThread
|
||||
);
|
||||
}
|
||||
|
||||
/** Index of the test being run. */
|
||||
|
|
@ -449,80 +488,80 @@ function runRawTests(testArray, done, beforeTestCallback) {
|
|||
var received = "";
|
||||
|
||||
/** Reads data from the socket. */
|
||||
var reader =
|
||||
{
|
||||
onInputStreamReady(stream) {
|
||||
Assert.ok(stream === this.stream);
|
||||
var reader = {
|
||||
onInputStreamReady(stream) {
|
||||
Assert.ok(stream === this.stream);
|
||||
try {
|
||||
var bis = new BinaryInputStream(stream);
|
||||
|
||||
var av = 0;
|
||||
try {
|
||||
var bis = new BinaryInputStream(stream);
|
||||
av = bis.available();
|
||||
} catch (e) {
|
||||
/* default to 0 */
|
||||
do_note_exception(e);
|
||||
}
|
||||
|
||||
var av = 0;
|
||||
try {
|
||||
av = bis.available();
|
||||
} catch (e) {
|
||||
/* default to 0 */
|
||||
do_note_exception(e);
|
||||
if (av > 0) {
|
||||
var quantum = 262144;
|
||||
for (var start = 0; start < av; start += quantum) {
|
||||
var bytes = bis.readByteArray(Math.min(quantum, av - start));
|
||||
received += String.fromCharCode.apply(null, bytes);
|
||||
}
|
||||
waitForMoreInput(stream);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
}
|
||||
|
||||
if (av > 0) {
|
||||
var quantum = 262144;
|
||||
for (var start = 0; start < av; start += quantum) {
|
||||
var bytes = bis.readByteArray(Math.min(quantum, av - start));
|
||||
received += String.fromCharCode.apply(null, bytes);
|
||||
}
|
||||
waitForMoreInput(stream);
|
||||
return;
|
||||
}
|
||||
var rawTest = testArray[testIndex];
|
||||
try {
|
||||
rawTest.responseCheck(received);
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
performNextTest();
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
}
|
||||
|
||||
var rawTest = testArray[testIndex];
|
||||
try {
|
||||
rawTest.responseCheck(received);
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
performNextTest();
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/** Writes data to the socket. */
|
||||
var writer =
|
||||
{
|
||||
onOutputStreamReady(stream) {
|
||||
var str = testArray[testIndex].data[dataIndex];
|
||||
var writer = {
|
||||
onOutputStreamReady(stream) {
|
||||
var str = testArray[testIndex].data[dataIndex];
|
||||
|
||||
var written = 0;
|
||||
try {
|
||||
written = stream.write(str, str.length);
|
||||
if (written == str.length)
|
||||
dataIndex++;
|
||||
else
|
||||
testArray[testIndex].data[dataIndex] = str.substring(written);
|
||||
} catch (e) {
|
||||
do_note_exception(e);
|
||||
/* stream could have been closed, just ignore */
|
||||
var written = 0;
|
||||
try {
|
||||
written = stream.write(str, str.length);
|
||||
if (written == str.length) {
|
||||
dataIndex++;
|
||||
} else {
|
||||
testArray[testIndex].data[dataIndex] = str.substring(written);
|
||||
}
|
||||
} catch (e) {
|
||||
do_note_exception(e);
|
||||
/* stream could have been closed, just ignore */
|
||||
}
|
||||
|
||||
try {
|
||||
// Keep writing data while we can write and
|
||||
// until there's no more data to read
|
||||
if (written > 0 && dataIndex < testArray[testIndex].data.length)
|
||||
waitToWriteOutput(stream);
|
||||
else
|
||||
stream.close();
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
try {
|
||||
// Keep writing data while we can write and
|
||||
// until there's no more data to read
|
||||
if (written > 0 && dataIndex < testArray[testIndex].data.length) {
|
||||
waitToWriteOutput(stream);
|
||||
} else {
|
||||
stream.close();
|
||||
}
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
performNextTest();
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,14 +14,30 @@ XPCOMUtils.defineLazyGetter(this, "port", function() {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + port + "/objHandler",
|
||||
null, start_objHandler, null),
|
||||
new Test("http://localhost:" + port + "/functionHandler",
|
||||
null, start_functionHandler, null),
|
||||
new Test("http://localhost:" + port + "/nonexistent-path",
|
||||
null, start_non_existent_path, null),
|
||||
new Test("http://localhost:" + port + "/lotsOfHeaders",
|
||||
null, start_lots_of_headers, null),
|
||||
new Test(
|
||||
"http://localhost:" + port + "/objHandler",
|
||||
null,
|
||||
start_objHandler,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" + port + "/functionHandler",
|
||||
null,
|
||||
start_functionHandler,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" + port + "/nonexistent-path",
|
||||
null,
|
||||
start_non_existent_path,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" + port + "/lotsOfHeaders",
|
||||
null,
|
||||
start_lots_of_headers,
|
||||
null
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -66,11 +82,13 @@ function start_objHandler(ch) {
|
|||
Assert.equal(ch.getResponseHeader("content-type"), "text/plain");
|
||||
Assert.equal(ch.responseStatusText, "OK");
|
||||
|
||||
var reqMin = {}, reqMaj = {}, respMin = {}, respMaj = {};
|
||||
var reqMin = {},
|
||||
reqMaj = {},
|
||||
respMin = {},
|
||||
respMaj = {};
|
||||
ch.getRequestVersion(reqMaj, reqMin);
|
||||
ch.getResponseVersion(respMaj, respMin);
|
||||
Assert.ok(reqMaj.value == respMaj.value &&
|
||||
reqMin.value == respMin.value);
|
||||
Assert.ok(reqMaj.value == respMaj.value && reqMin.value == respMin.value);
|
||||
}
|
||||
|
||||
function start_functionHandler(ch) {
|
||||
|
|
@ -81,7 +99,10 @@ function start_functionHandler(ch) {
|
|||
Assert.equal(ch.getResponseHeader("foopy"), "quux-baz");
|
||||
Assert.equal(ch.responseStatusText, "Page Not Found");
|
||||
|
||||
var reqMin = {}, reqMaj = {}, respMin = {}, respMaj = {};
|
||||
var reqMin = {},
|
||||
reqMaj = {},
|
||||
respMin = {},
|
||||
respMaj = {};
|
||||
ch.getRequestVersion(reqMaj, reqMin);
|
||||
ch.getResponseVersion(respMaj, respMin);
|
||||
Assert.ok(reqMaj.value == 1 && reqMin.value == 1);
|
||||
|
|
@ -101,41 +122,41 @@ function start_lots_of_headers(ch) {
|
|||
Assert.equal(ch.responseStatus, 200);
|
||||
Assert.ok(ch.requestSucceeded);
|
||||
|
||||
for (var i = 0; i < HEADER_COUNT; i++)
|
||||
for (var i = 0; i < HEADER_COUNT; i++) {
|
||||
Assert.equal(ch.getResponseHeader("X-Header-" + i), "value " + i);
|
||||
}
|
||||
}
|
||||
|
||||
// PATH HANDLERS
|
||||
|
||||
// /objHandler
|
||||
var objHandler =
|
||||
{
|
||||
handle(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
var objHandler = {
|
||||
handle(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
var body = "Request (slightly reformatted):\n\n";
|
||||
body += metadata.method + " " + metadata.path;
|
||||
var body = "Request (slightly reformatted):\n\n";
|
||||
body += metadata.method + " " + metadata.path;
|
||||
|
||||
Assert.equal(metadata.port, port);
|
||||
Assert.equal(metadata.port, port);
|
||||
|
||||
if (metadata.queryString)
|
||||
body += "?" + metadata.queryString;
|
||||
if (metadata.queryString) {
|
||||
body += "?" + metadata.queryString;
|
||||
}
|
||||
|
||||
body += " HTTP/" + metadata.httpVersion + "\n";
|
||||
body += " HTTP/" + metadata.httpVersion + "\n";
|
||||
|
||||
var headEnum = metadata.headers;
|
||||
while (headEnum.hasMoreElements()) {
|
||||
var fieldName = headEnum.getNext()
|
||||
.QueryInterface(Ci.nsISupportsString)
|
||||
.data;
|
||||
body += fieldName + ": " + metadata.getHeader(fieldName) + "\n";
|
||||
}
|
||||
var headEnum = metadata.headers;
|
||||
while (headEnum.hasMoreElements()) {
|
||||
var fieldName = headEnum.getNext().QueryInterface(Ci.nsISupportsString)
|
||||
.data;
|
||||
body += fieldName + ": " + metadata.getHeader(fieldName) + "\n";
|
||||
}
|
||||
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIHttpRequestHandler"]),
|
||||
};
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIHttpRequestHandler"]),
|
||||
};
|
||||
|
||||
// /functionHandler
|
||||
function functionHandler(metadata, response) {
|
||||
|
|
@ -154,6 +175,7 @@ function functionHandler(metadata, response) {
|
|||
function lotsOfHeadersHandler(request, response) {
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
for (var i = 0; i < HEADER_COUNT; i++)
|
||||
for (var i = 0; i < HEADER_COUNT; i++) {
|
||||
response.setHeader("X-Header-" + i, "value " + i, false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@ function contentLength(request, response) {
|
|||
|
||||
var avail;
|
||||
var data = "";
|
||||
while ((avail = body.available()) > 0)
|
||||
while ((avail = body.available()) > 0) {
|
||||
data += body.read(avail);
|
||||
}
|
||||
|
||||
Assert.equal(data, REQUEST_DATA);
|
||||
}
|
||||
|
|
@ -42,18 +43,24 @@ function contentLength(request, response) {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/content-length",
|
||||
init_content_length),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/content-length",
|
||||
init_content_length
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
function init_content_length(ch) {
|
||||
var content = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
var content = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
content.data = REQUEST_DATA;
|
||||
|
||||
ch.QueryInterface(Ci.nsIUploadChannel)
|
||||
.setUploadStream(content, "text/plain", REQUEST_DATA.length);
|
||||
ch.QueryInterface(Ci.nsIUploadChannel).setUploadStream(
|
||||
content,
|
||||
"text/plain",
|
||||
REQUEST_DATA.length
|
||||
);
|
||||
|
||||
// Override the values implicitly set by setUploadStream above.
|
||||
ch.requestMethod = "POST";
|
||||
|
|
|
|||
|
|
@ -14,35 +14,66 @@ XPCOMUtils.defineLazyGetter(this, "PREFIX", function() {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange, start_byterange, stop_byterange),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange2, start_byterange2),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange3, start_byterange3, stop_byterange3),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange4, start_byterange4),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange5, start_byterange5, stop_byterange5),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange6, start_byterange6, stop_byterange6),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange7, start_byterange7, stop_byterange7),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange8, start_byterange8, stop_byterange8),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange9, start_byterange9, stop_byterange9),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange10, start_byterange10),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
init_byterange11, start_byterange11, stop_byterange11),
|
||||
new Test(PREFIX + "/empty.txt",
|
||||
null, start_byterange12, stop_byterange12),
|
||||
new Test(PREFIX + "/headers.txt",
|
||||
init_byterange13, start_byterange13, null),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
null, start_normal, stop_normal),
|
||||
];
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange,
|
||||
start_byterange,
|
||||
stop_byterange
|
||||
),
|
||||
new Test(PREFIX + "/range.txt", init_byterange2, start_byterange2),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange3,
|
||||
start_byterange3,
|
||||
stop_byterange3
|
||||
),
|
||||
new Test(PREFIX + "/range.txt", init_byterange4, start_byterange4),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange5,
|
||||
start_byterange5,
|
||||
stop_byterange5
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange6,
|
||||
start_byterange6,
|
||||
stop_byterange6
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange7,
|
||||
start_byterange7,
|
||||
stop_byterange7
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange8,
|
||||
start_byterange8,
|
||||
stop_byterange8
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange9,
|
||||
start_byterange9,
|
||||
stop_byterange9
|
||||
),
|
||||
new Test(PREFIX + "/range.txt", init_byterange10, start_byterange10),
|
||||
new Test(
|
||||
PREFIX + "/range.txt",
|
||||
init_byterange11,
|
||||
start_byterange11,
|
||||
stop_byterange11
|
||||
),
|
||||
new Test(PREFIX + "/empty.txt", null, start_byterange12, stop_byterange12),
|
||||
new Test(
|
||||
PREFIX + "/headers.txt",
|
||||
init_byterange13,
|
||||
start_byterange13,
|
||||
null
|
||||
),
|
||||
new Test(PREFIX + "/range.txt", null, start_normal, stop_normal),
|
||||
];
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
|
|
|
|||
|
|
@ -13,16 +13,26 @@ XPCOMUtils.defineLazyGetter(this, "PREFIX", function() {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test(PREFIX + "/test_both.html",
|
||||
null, start_testBoth, null),
|
||||
new Test(PREFIX + "/test_ctype_override.txt",
|
||||
null, start_test_ctype_override_txt, null),
|
||||
new Test(PREFIX + "/test_status_override.html",
|
||||
null, start_test_status_override_html, null),
|
||||
new Test(PREFIX + "/test_status_override_nodesc.txt",
|
||||
null, start_test_status_override_nodesc_txt, null),
|
||||
new Test(PREFIX + "/caret_test.txt^",
|
||||
null, start_caret_test_txt_, null),
|
||||
new Test(PREFIX + "/test_both.html", null, start_testBoth, null),
|
||||
new Test(
|
||||
PREFIX + "/test_ctype_override.txt",
|
||||
null,
|
||||
start_test_ctype_override_txt,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/test_status_override.html",
|
||||
null,
|
||||
start_test_status_override_html,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/test_status_override_nodesc.txt",
|
||||
null,
|
||||
start_test_status_override_nodesc_txt,
|
||||
null
|
||||
),
|
||||
new Test(PREFIX + "/caret_test.txt^", null, start_caret_test_txt_, null),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -37,7 +47,6 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// TEST DATA
|
||||
|
||||
function start_testBoth(ch) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ function run_test() {
|
|||
function done() {
|
||||
do_test_pending();
|
||||
destroyTestDirectory();
|
||||
srv.stop(function() { do_test_finished(); });
|
||||
srv.stop(function() {
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
||||
|
||||
runHttpTests(tests, done);
|
||||
|
|
@ -77,7 +79,6 @@ function destroyTestDirectory() {
|
|||
dir.remove(true);
|
||||
}
|
||||
|
||||
|
||||
/** ***********
|
||||
* UTILITIES *
|
||||
*************/
|
||||
|
|
@ -115,8 +116,10 @@ function hiddenDataCheck(bytes, uri, path) {
|
|||
var top = Services.io.newURI(uri);
|
||||
|
||||
// N.B. No ERROR_IF_SEE_THIS.txt^ file!
|
||||
var dirEntries = [{name: "file.txt", isDirectory: false},
|
||||
{name: "SHOULD_SEE_THIS.txt^", isDirectory: false}];
|
||||
var dirEntries = [
|
||||
{ name: "file.txt", isDirectory: false },
|
||||
{ name: "SHOULD_SEE_THIS.txt^", isDirectory: false },
|
||||
];
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var link = items[i].childNodes[0];
|
||||
|
|
@ -202,8 +205,10 @@ function makeFile(name, isDirectory, parentDir, lst) {
|
|||
try {
|
||||
file.append(name);
|
||||
file.create(type, 0o755);
|
||||
lst.push({name, isDirectory});
|
||||
} catch (e) { /* OS probably doesn't like file name, skip */ }
|
||||
lst.push({ name, isDirectory });
|
||||
} catch (e) {
|
||||
/* OS probably doesn't like file name, skip */
|
||||
}
|
||||
}
|
||||
|
||||
/** *******
|
||||
|
|
@ -214,7 +219,12 @@ XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
|||
return [
|
||||
new Test(BASE_URL, null, start, stopRootDirectory),
|
||||
new Test(BASE_URL + "foo/", null, start, stopFooDirectory),
|
||||
new Test(BASE_URL + "bar/folder^/", null, start, stopTrailingCaretDirectory),
|
||||
new Test(
|
||||
BASE_URL + "bar/folder^/",
|
||||
null,
|
||||
start,
|
||||
stopTrailingCaretDirectory
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,18 @@ var srv;
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/empty-body-unwritten",
|
||||
null, ensureEmpty, null),
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/empty-body-written",
|
||||
null, ensureEmpty, null),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/empty-body-unwritten",
|
||||
null,
|
||||
ensureEmpty,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/empty-body-written",
|
||||
null,
|
||||
ensureEmpty,
|
||||
null
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,14 +9,28 @@
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/throws/exception",
|
||||
null, start_throws_exception, succeeded),
|
||||
new Test("http://localhost:" + srv.identity.primaryPort +
|
||||
"/this/file/does/not/exist/and/404s",
|
||||
null, start_nonexistent_404_fails_so_400, succeeded),
|
||||
new Test("http://localhost:" + srv.identity.primaryPort +
|
||||
"/attempts/404/fails/so/400/fails/so/500s",
|
||||
register400Handler, start_multiple_exceptions_500, succeeded),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/throws/exception",
|
||||
null,
|
||||
start_throws_exception,
|
||||
succeeded
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" +
|
||||
srv.identity.primaryPort +
|
||||
"/this/file/does/not/exist/and/404s",
|
||||
null,
|
||||
start_nonexistent_404_fails_so_400,
|
||||
succeeded
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" +
|
||||
srv.identity.primaryPort +
|
||||
"/attempts/404/fails/so/400/fails/so/500s",
|
||||
register400Handler,
|
||||
start_multiple_exceptions_500,
|
||||
succeeded
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -33,14 +47,20 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// TEST DATA
|
||||
|
||||
function checkStatusLine(channel, httpMaxVer, httpMinVer, httpCode, statusText) {
|
||||
function checkStatusLine(
|
||||
channel,
|
||||
httpMaxVer,
|
||||
httpMinVer,
|
||||
httpCode,
|
||||
statusText
|
||||
) {
|
||||
Assert.equal(channel.responseStatus, httpCode);
|
||||
Assert.equal(channel.responseStatusText, statusText);
|
||||
|
||||
var respMaj = {}, respMin = {};
|
||||
var respMaj = {},
|
||||
respMin = {};
|
||||
channel.getResponseVersion(respMaj, respMin);
|
||||
Assert.equal(respMaj.value, httpMaxVer);
|
||||
Assert.equal(respMin.value, httpMinVer);
|
||||
|
|
@ -66,7 +86,6 @@ function register400Handler(ch) {
|
|||
srv.registerErrorHandler(400, throwsException);
|
||||
}
|
||||
|
||||
|
||||
// PATH HANDLERS
|
||||
|
||||
// /throws/exception (and also a 404 and 400 error handler)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
/** **********
|
||||
* HANDLERS *
|
||||
************/
|
||||
|
|
@ -47,8 +46,11 @@ function pathHandler(request, response) {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/path-handler",
|
||||
null, check),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/path-handler",
|
||||
null,
|
||||
check
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
// structure and is not to be used directly outside of httpd.js itself except
|
||||
// for testing purposes
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that a fieldname-fieldvalue combination is a valid header.
|
||||
*
|
||||
|
|
@ -40,14 +39,16 @@ function assertValidHeader(fieldName, fieldValue, headers) {
|
|||
function assertInvalidHeader(fieldName, fieldValue, headers) {
|
||||
try {
|
||||
headers.setHeader(fieldName, fieldValue, false);
|
||||
throw new Error(`Setting (${fieldName}, ${fieldValue}) as header succeeded!`);
|
||||
throw new Error(
|
||||
`Setting (${fieldName}, ${fieldValue}) as header succeeded!`
|
||||
);
|
||||
} catch (e) {
|
||||
if (e.result !== Cr.NS_ERROR_INVALID_ARG)
|
||||
if (e.result !== Cr.NS_ERROR_INVALID_ARG) {
|
||||
do_throw("Unexpected exception thrown: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function run_test() {
|
||||
testHeaderValidity();
|
||||
testGetHeader();
|
||||
|
|
@ -65,7 +66,7 @@ function testHeaderValidity() {
|
|||
assertInvalidHeader("@xml", "bar", headers);
|
||||
assertInvalidHeader("fiz(", "bar", headers);
|
||||
assertInvalidHeader("HTTP/1.1", "bar", headers);
|
||||
assertInvalidHeader("b\"b", "bar", headers);
|
||||
assertInvalidHeader('b"b', "bar", headers);
|
||||
assertInvalidHeader("ascsd\t", "bar", headers);
|
||||
assertInvalidHeader("{fds", "bar", headers);
|
||||
assertInvalidHeader("baz?", "bar", headers);
|
||||
|
|
@ -106,31 +107,33 @@ function testGetHeader() {
|
|||
headers.getHeader(":");
|
||||
throw new Error("Failed to throw for invalid header");
|
||||
} catch (e) {
|
||||
if (e.result !== Cr.NS_ERROR_INVALID_ARG)
|
||||
if (e.result !== Cr.NS_ERROR_INVALID_ARG) {
|
||||
do_throw("headers.getHeader(':') must throw invalid arg");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
headers.getHeader("valid");
|
||||
throw new Error("header doesn't exist");
|
||||
} catch (e) {
|
||||
if (e.result !== Cr.NS_ERROR_NOT_AVAILABLE)
|
||||
if (e.result !== Cr.NS_ERROR_NOT_AVAILABLE) {
|
||||
do_throw("shouldn't be a header named 'valid' in headers!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testHeaderEnumerator() {
|
||||
var headers = new nsHttpHeaders();
|
||||
|
||||
var heads =
|
||||
{
|
||||
"foo": "17",
|
||||
"baz": "two six niner",
|
||||
"decaf": "class Program { int .7; int main(){ .7 = 5; return 7 - .7; } }",
|
||||
};
|
||||
var heads = {
|
||||
foo: "17",
|
||||
baz: "two six niner",
|
||||
decaf: "class Program { int .7; int main(){ .7 = 5; return 7 - .7; } }",
|
||||
};
|
||||
|
||||
for (var i in heads)
|
||||
for (var i in heads) {
|
||||
headers.setHeader(i, heads[i], false);
|
||||
}
|
||||
|
||||
var en = headers.enumerator;
|
||||
while (en.hasMoreElements()) {
|
||||
|
|
@ -159,7 +162,8 @@ function testHasHeader() {
|
|||
headers.hasHeader(":");
|
||||
throw new Error("failed to throw");
|
||||
} catch (e) {
|
||||
if (e.result !== Cr.NS_ERROR_INVALID_ARG)
|
||||
if (e.result !== Cr.NS_ERROR_INVALID_ARG) {
|
||||
do_throw(".hasHeader for an invalid name should throw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@ add_task(async function run_test1() {
|
|||
|
||||
srv.registerPathHandler("/http/1.0-request", http10Request);
|
||||
srv.registerPathHandler("/http/1.1-good-host", http11goodHost);
|
||||
srv.registerPathHandler("/http/1.1-good-host-wacky-port",
|
||||
http11goodHostWackyPort);
|
||||
srv.registerPathHandler(
|
||||
"/http/1.1-good-host-wacky-port",
|
||||
http11goodHostWackyPort
|
||||
);
|
||||
srv.registerPathHandler("/http/1.1-ip-host", http11ipHost);
|
||||
|
||||
srv.start(FAKE_PORT_ONE);
|
||||
|
|
@ -180,13 +182,14 @@ add_task(async function run_test_3() {
|
|||
|
||||
// Okay, finally done with identity testing. Our primary location is the one
|
||||
// we want it to be, so we're off!
|
||||
await new Promise(resolve => runRawTests(tests, resolve, (idx) => dump(`running test no ${idx}`)));
|
||||
await new Promise(resolve =>
|
||||
runRawTests(tests, resolve, idx => dump(`running test no ${idx}`))
|
||||
);
|
||||
|
||||
// Finally shut down the server.
|
||||
await new Promise(resolve => srv.stop(resolve));
|
||||
});
|
||||
|
||||
|
||||
/** *******************
|
||||
* UTILITY FUNCTIONS *
|
||||
*********************/
|
||||
|
|
@ -235,7 +238,6 @@ function check400(aData) {
|
|||
Assert.equal(firstLine.substring(0, HTTP_400_LEADER_LENGTH), HTTP_400_LEADER);
|
||||
}
|
||||
|
||||
|
||||
/** *************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
|
@ -252,8 +254,7 @@ function http10Request(request, response) {
|
|||
writeDetails(request, response);
|
||||
response.setStatusLine("1.0", 200, "TEST PASSED");
|
||||
}
|
||||
data = "GET /http/1.0-request HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
data = "GET /http/1.0-request HTTP/1.0\r\n" + "\r\n";
|
||||
function check10(aData) {
|
||||
let iter = LineIterator(aData);
|
||||
|
||||
|
|
@ -263,94 +264,84 @@ function check10(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /http/1.0-request",
|
||||
"Query: ",
|
||||
"Version: 1.0",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: 4444",
|
||||
];
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.0-request",
|
||||
"Query: ",
|
||||
"Version: 1.0",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: 4444",
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
test = new RawTest("localhost", PORT, data, check10);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, no Host header, expect a 400 response
|
||||
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" +
|
||||
"\r\n";
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" + "\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, wrong host, expect a 400 response
|
||||
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: not-localhost\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.1-request HTTP/1.1\r\n" + "Host: not-localhost\r\n" + "\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, wrong host/right port, expect a 400 response
|
||||
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Host header has host but no port, expect a 400 response
|
||||
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: 127.0.0.1\r\n" +
|
||||
"\r\n";
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" + "Host: 127.0.0.1\r\n" + "\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Request-URI has wrong port, expect a 400 response
|
||||
|
||||
data = "GET http://127.0.0.1/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: 127.0.0.1\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://127.0.0.1/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: 127.0.0.1\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Request-URI has wrong port, expect a 400 response
|
||||
|
||||
data = "GET http://localhost:31337/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: localhost:31337\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:31337/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: localhost:31337\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Request-URI has wrong scheme, expect a 400 response
|
||||
|
||||
data = "GET https://localhost:4444/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET https://localhost:4444/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, correct Host header, expect handler's response
|
||||
|
||||
function http11goodHost(request, response) {
|
||||
writeDetails(request, response);
|
||||
response.setStatusLine("1.1", 200, "TEST PASSED");
|
||||
}
|
||||
data = "GET /http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.1-good-host HTTP/1.1\r\n" + "Host: localhost:4444\r\n" + "\r\n";
|
||||
function check11goodHost(aData) {
|
||||
let iter = LineIterator(aData);
|
||||
|
||||
|
|
@ -360,32 +351,29 @@ function check11goodHost(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-good-host",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: 4444",
|
||||
];
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-good-host",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: 4444",
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
test = new RawTest("localhost", PORT, data, check11goodHost);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Host header is secondary identity
|
||||
|
||||
function http11ipHost(request, response) {
|
||||
writeDetails(request, response);
|
||||
response.setStatusLine("1.1", 200, "TEST PASSED");
|
||||
}
|
||||
data = "GET /http/1.1-ip-host HTTP/1.1\r\n" +
|
||||
"Host: 127.0.0.1:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.1-ip-host HTTP/1.1\r\n" + "Host: 127.0.0.1:4444\r\n" + "\r\n";
|
||||
function check11ipHost(aData) {
|
||||
let iter = LineIterator(aData);
|
||||
|
||||
|
|
@ -395,63 +383,62 @@ function check11ipHost(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-ip-host",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: 127.0.0.1",
|
||||
"Port: 4444",
|
||||
];
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-ip-host",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: 127.0.0.1",
|
||||
"Port: 4444",
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
test = new RawTest("localhost", PORT, data, check11ipHost);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute path, accurate Host header
|
||||
|
||||
// reusing previous request handler so not defining a new one
|
||||
|
||||
data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHost);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute path, inaccurate Host header
|
||||
|
||||
// reusing previous request handler so not defining a new one
|
||||
|
||||
data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: localhost:1234\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: localhost:1234\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHost);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute path, different inaccurate Host header
|
||||
|
||||
// reusing previous request handler so not defining a new one
|
||||
|
||||
data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHost);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute path, yet another inaccurate Host header
|
||||
|
||||
// reusing previous request handler so not defining a new one
|
||||
|
||||
data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: yippity-skippity\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: yippity-skippity\r\n" +
|
||||
"\r\n";
|
||||
function checkInaccurate(aData) {
|
||||
check11goodHost(aData);
|
||||
|
||||
|
|
@ -461,14 +448,14 @@ function checkInaccurate(aData) {
|
|||
test = new RawTest("localhost", PORT, data, checkInaccurate);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.0 request, absolute path, different inaccurate Host header
|
||||
|
||||
// reusing previous request handler so not defining a new one
|
||||
|
||||
data = "GET /http/1.0-request HTTP/1.0\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.0-request HTTP/1.0\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
function check10ip(aData) {
|
||||
let iter = LineIterator(aData);
|
||||
|
||||
|
|
@ -478,32 +465,31 @@ function check10ip(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /http/1.0-request",
|
||||
"Query: ",
|
||||
"Version: 1.0",
|
||||
"Scheme: http",
|
||||
"Host: 127.0.0.1",
|
||||
"Port: 4444",
|
||||
];
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.0-request",
|
||||
"Query: ",
|
||||
"Version: 1.0",
|
||||
"Scheme: http",
|
||||
"Host: 127.0.0.1",
|
||||
"Port: 4444",
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
test = new RawTest("localhost", PORT, data, check10ip);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Host header with implied port
|
||||
|
||||
function http11goodHostWackyPort(request, response) {
|
||||
writeDetails(request, response);
|
||||
response.setStatusLine("1.1", 200, "TEST PASSED");
|
||||
}
|
||||
data = "GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
function check11goodHostWackyPort(aData) {
|
||||
let iter = LineIterator(aData);
|
||||
|
||||
|
|
@ -513,108 +499,104 @@ function check11goodHostWackyPort(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-good-host-wacky-port",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: 80",
|
||||
];
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-good-host-wacky-port",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: 80",
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
test = new RawTest("localhost", PORT, data, check11goodHostWackyPort);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, Host header with wacky implied port
|
||||
|
||||
data = "GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost:\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost:\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHostWackyPort);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute URI with implied port
|
||||
|
||||
data = "GET http://localhost/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHostWackyPort);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute URI with wacky implied port
|
||||
|
||||
data = "GET http://localhost:/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHostWackyPort);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute URI with explicit implied port, ignored Host
|
||||
|
||||
data = "GET http://localhost:80/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: who-cares\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:80/http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: who-cares\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHostWackyPort);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, a malformed Request-URI
|
||||
|
||||
data = "GET is-this-the-real-life-is-this-just-fantasy HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET is-this-the-real-life-is-this-just-fantasy HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, a malformed Host header
|
||||
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: la la la\r\n" +
|
||||
"\r\n";
|
||||
data = "GET /http/1.1-request HTTP/1.1\r\n" + "Host: la la la\r\n" + "\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, a malformed Host header but absolute URI, 5.2 sez fine
|
||||
|
||||
data = "GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: la la la\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:4444/http/1.1-good-host HTTP/1.1\r\n" +
|
||||
"Host: la la la\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check11goodHost);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.0 request, absolute URI, but those aren't valid in HTTP/1.0
|
||||
|
||||
data = "GET http://localhost:4444/http/1.1-request HTTP/1.0\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://localhost:4444/http/1.1-request HTTP/1.0\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute URI with unrecognized host
|
||||
|
||||
data = "GET http://not-localhost:4444/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://not-localhost:4444/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// HTTP/1.1 request, absolute URI with unrecognized host (but not in Host)
|
||||
|
||||
data = "GET http://not-localhost:4444/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
data =
|
||||
"GET http://not-localhost:4444/http/1.1-request HTTP/1.1\r\n" +
|
||||
"Host: localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
test = new RawTest("localhost", PORT, data, check400);
|
||||
tests.push(test);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
*/
|
||||
*/
|
||||
/* 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/. */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
* Ensure httpd.js can be imported as a module and that a server starts.
|
||||
*/
|
||||
function run_test() {
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import(
|
||||
"resource://testing-common/httpd.js"
|
||||
);
|
||||
|
||||
let server = new HttpServer();
|
||||
server.start(-1);
|
||||
|
|
|
|||
|
|
@ -16,36 +16,43 @@ XPCOMUtils.defineLazyGetter(this, "PREFIX", function() {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test(PREFIX + "/bar.html^",
|
||||
null, start_bar_html_, null),
|
||||
new Test(PREFIX + "/foo.html^",
|
||||
null, start_foo_html_, null),
|
||||
new Test(PREFIX + "/normal-file.txt",
|
||||
null, start_normal_file_txt, null),
|
||||
new Test(PREFIX + "/folder^/file.txt",
|
||||
null, start_folder__file_txt, null),
|
||||
new Test(PREFIX + "/bar.html^", null, start_bar_html_, null),
|
||||
new Test(PREFIX + "/foo.html^", null, start_foo_html_, null),
|
||||
new Test(PREFIX + "/normal-file.txt", null, start_normal_file_txt, null),
|
||||
new Test(PREFIX + "/folder^/file.txt", null, start_folder__file_txt, null),
|
||||
|
||||
new Test(PREFIX + "/foo/bar.html^",
|
||||
null, start_bar_html_, null),
|
||||
new Test(PREFIX + "/foo/foo.html^",
|
||||
null, start_foo_html_, null),
|
||||
new Test(PREFIX + "/foo/normal-file.txt",
|
||||
null, start_normal_file_txt, null),
|
||||
new Test(PREFIX + "/foo/folder^/file.txt",
|
||||
null, start_folder__file_txt, null),
|
||||
new Test(PREFIX + "/foo/bar.html^", null, start_bar_html_, null),
|
||||
new Test(PREFIX + "/foo/foo.html^", null, start_foo_html_, null),
|
||||
new Test(
|
||||
PREFIX + "/foo/normal-file.txt",
|
||||
null,
|
||||
start_normal_file_txt,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/foo/folder^/file.txt",
|
||||
null,
|
||||
start_folder__file_txt,
|
||||
null
|
||||
),
|
||||
|
||||
new Test(PREFIX + "/end-caret^/bar.html^",
|
||||
null, start_bar_html_, null),
|
||||
new Test(PREFIX + "/end-caret^/foo.html^",
|
||||
null, start_foo_html_, null),
|
||||
new Test(PREFIX + "/end-caret^/normal-file.txt",
|
||||
null, start_normal_file_txt, null),
|
||||
new Test(PREFIX + "/end-caret^/folder^/file.txt",
|
||||
null, start_folder__file_txt, null),
|
||||
];
|
||||
new Test(PREFIX + "/end-caret^/bar.html^", null, start_bar_html_, null),
|
||||
new Test(PREFIX + "/end-caret^/foo.html^", null, start_foo_html_, null),
|
||||
new Test(
|
||||
PREFIX + "/end-caret^/normal-file.txt",
|
||||
null,
|
||||
start_normal_file_txt,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
PREFIX + "/end-caret^/folder^/file.txt",
|
||||
null,
|
||||
start_folder__file_txt,
|
||||
null
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
function run_test() {
|
||||
srv = createServer();
|
||||
|
||||
|
|
@ -61,7 +68,6 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// TEST DATA
|
||||
|
||||
function start_bar_html_(ch) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
* 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/. */
|
||||
|
||||
|
||||
/*
|
||||
* Tests for correct behavior of asynchronous responses.
|
||||
*/
|
||||
|
|
@ -17,14 +16,14 @@ var srv;
|
|||
|
||||
function run_test() {
|
||||
srv = createServer();
|
||||
for (var path in handlers)
|
||||
for (var path in handlers) {
|
||||
srv.registerPathHandler(path, handlers[path]);
|
||||
}
|
||||
srv.start(-1);
|
||||
|
||||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
/** *************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
|
@ -32,12 +31,24 @@ function run_test() {
|
|||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test(PREPATH + "/handleSync", null, start_handleSync, null),
|
||||
new Test(PREPATH + "/handleAsync1", null, start_handleAsync1,
|
||||
stop_handleAsync1),
|
||||
new Test(PREPATH + "/handleAsync2", init_handleAsync2, start_handleAsync2,
|
||||
stop_handleAsync2),
|
||||
new Test(PREPATH + "/handleAsyncOrdering", null, null,
|
||||
stop_handleAsyncOrdering),
|
||||
new Test(
|
||||
PREPATH + "/handleAsync1",
|
||||
null,
|
||||
start_handleAsync1,
|
||||
stop_handleAsync1
|
||||
),
|
||||
new Test(
|
||||
PREPATH + "/handleAsync2",
|
||||
init_handleAsync2,
|
||||
start_handleAsync2,
|
||||
stop_handleAsync2
|
||||
),
|
||||
new Test(
|
||||
PREPATH + "/handleAsyncOrdering",
|
||||
null,
|
||||
null,
|
||||
stop_handleAsyncOrdering
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -171,14 +182,19 @@ handlers["/handleAsync2"] = handleAsync2;
|
|||
var startTime_handleAsync2;
|
||||
|
||||
function init_handleAsync2(ch) {
|
||||
var now = startTime_handleAsync2 = Date.now();
|
||||
var now = (startTime_handleAsync2 = Date.now());
|
||||
dumpn("*** init_HandleAsync2: start time " + now);
|
||||
}
|
||||
|
||||
function start_handleAsync2(ch) {
|
||||
var now = Date.now();
|
||||
dumpn("*** start_handleAsync2: onStartRequest time " + now + ", " +
|
||||
(now - startTime_handleAsync2) + "ms after start time");
|
||||
dumpn(
|
||||
"*** start_handleAsync2: onStartRequest time " +
|
||||
now +
|
||||
", " +
|
||||
(now - startTime_handleAsync2) +
|
||||
"ms after start time"
|
||||
);
|
||||
Assert.ok(now >= startTime_handleAsync2 + startToHeaderDelay);
|
||||
|
||||
Assert.equal(ch.responseStatus, 200);
|
||||
|
|
@ -188,8 +204,13 @@ function start_handleAsync2(ch) {
|
|||
|
||||
function stop_handleAsync2(ch, status, data) {
|
||||
var now = Date.now();
|
||||
dumpn("*** stop_handleAsync2: onStopRequest time " + now + ", " +
|
||||
(now - startTime_handleAsync2) + "ms after header time");
|
||||
dumpn(
|
||||
"*** stop_handleAsync2: onStopRequest time " +
|
||||
now +
|
||||
", " +
|
||||
(now - startTime_handleAsync2) +
|
||||
"ms after header time"
|
||||
);
|
||||
Assert.ok(now >= startTime_handleAsync2 + startToFinishedDelay);
|
||||
|
||||
Assert.equal(String.fromCharCode.apply(null, data), "BODY");
|
||||
|
|
@ -206,30 +227,30 @@ function handleAsyncOrdering(request, response) {
|
|||
var out = new BinaryOutputStream(response.bodyOutputStream);
|
||||
|
||||
var data = [];
|
||||
for (var i = 0; i < 65536; i++)
|
||||
for (var i = 0; i < 65536; i++) {
|
||||
data[i] = 0;
|
||||
}
|
||||
var count = 20;
|
||||
|
||||
var writeData =
|
||||
{
|
||||
run() {
|
||||
if (count-- === 0) {
|
||||
response.finish();
|
||||
return;
|
||||
}
|
||||
var writeData = {
|
||||
run() {
|
||||
if (count-- === 0) {
|
||||
response.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
out.writeByteArray(data, data.length);
|
||||
step();
|
||||
} catch (e) {
|
||||
try {
|
||||
out.writeByteArray(data, data.length);
|
||||
step();
|
||||
} catch (e) {
|
||||
try {
|
||||
do_throw("error writing data: " + e);
|
||||
} finally {
|
||||
response.finish();
|
||||
}
|
||||
do_throw("error writing data: " + e);
|
||||
} finally {
|
||||
response.finish();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
function step() {
|
||||
// Use gThreadManager here because it's expedient, *not* because it's
|
||||
// intended for public use! If you do this in client code, expect me to
|
||||
|
|
@ -244,7 +265,8 @@ handlers["/handleAsyncOrdering"] = handleAsyncOrdering;
|
|||
function stop_handleAsyncOrdering(ch, status, data) {
|
||||
Assert.equal(data.length, 20 * 65536);
|
||||
data.forEach(function(v, index) {
|
||||
if (v !== 0)
|
||||
if (v !== 0) {
|
||||
do_throw("value " + v + " at index " + index + " should be zero");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,18 @@
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/test",
|
||||
null, start_test, null),
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/sjs/qi.sjs",
|
||||
null, start_sjs_qi, null),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/test",
|
||||
null,
|
||||
start_test,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/sjs/qi.sjs",
|
||||
null,
|
||||
start_sjs_qi,
|
||||
null
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -41,7 +49,6 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// TEST DATA
|
||||
|
||||
function start_test(ch) {
|
||||
|
|
@ -54,7 +61,6 @@ function start_sjs_qi(ch) {
|
|||
Assert.equal(ch.responseStatus, 200);
|
||||
}
|
||||
|
||||
|
||||
function testHandler(request, response) {
|
||||
var exstr;
|
||||
var qid;
|
||||
|
|
@ -67,8 +73,11 @@ function testHandler(request, response) {
|
|||
passed = qid === request;
|
||||
} catch (e) {
|
||||
exstr = ("" + e).split(/[\x09\x20-\x7f\x81-\xff]+/)[0];
|
||||
response.setStatusLine(request.httpVersion, 500,
|
||||
"request doesn't QI: " + exstr);
|
||||
response.setStatusLine(
|
||||
request.httpVersion,
|
||||
500,
|
||||
"request doesn't QI: " + exstr
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!passed) {
|
||||
|
|
@ -82,8 +91,11 @@ function testHandler(request, response) {
|
|||
passed = qid === response;
|
||||
} catch (e) {
|
||||
exstr = ("" + e).split(/[\x09\x20-\x7f\x81-\xff]+/)[0];
|
||||
response.setStatusLine(request.httpVersion, 500,
|
||||
"response doesn't QI: " + exstr);
|
||||
response.setStatusLine(
|
||||
request.httpVersion,
|
||||
500,
|
||||
"response doesn't QI: " + exstr
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!passed) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ XPCOMUtils.defineLazyGetter(this, "BASE", function() {
|
|||
return "http://localhost:" + srv.identity.primaryPort;
|
||||
});
|
||||
|
||||
|
||||
function nocache(ch) {
|
||||
ch.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; // important!
|
||||
}
|
||||
|
|
@ -38,186 +37,222 @@ function checkFile(ch, status, data) {
|
|||
|
||||
var actualFile = serverBasePath.clone();
|
||||
actualFile.append("test_registerdirectory.js");
|
||||
Assert.equal(ch.getResponseHeader("Content-Length"),
|
||||
actualFile.fileSize.toString());
|
||||
Assert.equal(data.map(v => String.fromCharCode(v)).join(""),
|
||||
fileContents(actualFile));
|
||||
Assert.equal(
|
||||
ch.getResponseHeader("Content-Length"),
|
||||
actualFile.fileSize.toString()
|
||||
);
|
||||
Assert.equal(
|
||||
data.map(v => String.fromCharCode(v)).join(""),
|
||||
fileContents(actualFile)
|
||||
);
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
/** *********************
|
||||
* without a base path *
|
||||
***********************/
|
||||
new Test(BASE + "/test_registerdirectory.js", nocache, notFound, null),
|
||||
|
||||
/** *********************
|
||||
* without a base path *
|
||||
***********************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
nocache, notFound, null),
|
||||
/** ******************
|
||||
* with a base path *
|
||||
********************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile
|
||||
),
|
||||
|
||||
/** ******************
|
||||
* with a base path *
|
||||
********************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile),
|
||||
/** ***************************
|
||||
* without a base path again *
|
||||
*****************************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = null;
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
notFound,
|
||||
null
|
||||
),
|
||||
|
||||
/** ***************************
|
||||
* without a base path again *
|
||||
*****************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = null;
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
/** *************************
|
||||
* registered path handler *
|
||||
***************************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler(
|
||||
"/test_registerdirectory.js",
|
||||
override_test_registerdirectory
|
||||
);
|
||||
},
|
||||
checkOverride,
|
||||
null
|
||||
),
|
||||
|
||||
/** *************************
|
||||
* registered path handler *
|
||||
***************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js",
|
||||
override_test_registerdirectory);
|
||||
},
|
||||
checkOverride,
|
||||
null),
|
||||
/** **********************
|
||||
* removed path handler *
|
||||
************************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function init_registerDirectory6(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js", null);
|
||||
},
|
||||
notFound,
|
||||
null
|
||||
),
|
||||
|
||||
/** **********************
|
||||
* removed path handler *
|
||||
************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function init_registerDirectory6(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
/** ******************
|
||||
* with a base path *
|
||||
********************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
|
||||
/** ******************
|
||||
* with a base path *
|
||||
********************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
// set the base path again
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile
|
||||
),
|
||||
|
||||
// set the base path again
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile),
|
||||
/** ***********************
|
||||
* ...and a path handler *
|
||||
*************************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler(
|
||||
"/test_registerdirectory.js",
|
||||
override_test_registerdirectory
|
||||
);
|
||||
},
|
||||
checkOverride,
|
||||
null
|
||||
),
|
||||
|
||||
/** ***********************
|
||||
* ...and a path handler *
|
||||
*************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js",
|
||||
override_test_registerdirectory);
|
||||
},
|
||||
checkOverride,
|
||||
null),
|
||||
/** **********************
|
||||
* removed base handler *
|
||||
************************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = null;
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
checkOverride,
|
||||
null
|
||||
),
|
||||
|
||||
/** **********************
|
||||
* removed base handler *
|
||||
************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = null;
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
checkOverride,
|
||||
null),
|
||||
/** **********************
|
||||
* removed path handler *
|
||||
************************/
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js", null);
|
||||
},
|
||||
notFound,
|
||||
null
|
||||
),
|
||||
|
||||
/** **********************
|
||||
* removed path handler *
|
||||
************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
/** ***********************
|
||||
* mapping set up, works *
|
||||
*************************/
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/foo/", serverBasePath);
|
||||
},
|
||||
check200,
|
||||
null
|
||||
),
|
||||
|
||||
/** ***********************
|
||||
* mapping set up, works *
|
||||
*************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/foo/", serverBasePath);
|
||||
},
|
||||
check200,
|
||||
null),
|
||||
/** *******************
|
||||
* no mapping, fails *
|
||||
*********************/
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache,
|
||||
notFound,
|
||||
null
|
||||
),
|
||||
|
||||
/** *******************
|
||||
* no mapping, fails *
|
||||
*********************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache,
|
||||
notFound,
|
||||
null),
|
||||
/** ****************
|
||||
* mapping, works *
|
||||
******************/
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory(
|
||||
"/foo/test_registerdirectory.js/",
|
||||
serverBasePath
|
||||
);
|
||||
},
|
||||
null,
|
||||
checkFile
|
||||
),
|
||||
|
||||
/** ****************
|
||||
* mapping, works *
|
||||
******************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/test_registerdirectory.js/",
|
||||
serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile),
|
||||
/** **********************************
|
||||
* two mappings set up, still works *
|
||||
************************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js", nocache, null, checkFile),
|
||||
|
||||
/** **********************************
|
||||
* two mappings set up, still works *
|
||||
************************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
nocache, null, checkFile),
|
||||
/** ************************
|
||||
* remove topmost mapping *
|
||||
**************************/
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/", null);
|
||||
},
|
||||
notFound,
|
||||
null
|
||||
),
|
||||
|
||||
/** ************************
|
||||
* remove topmost mapping *
|
||||
**************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
/** ************************************
|
||||
* lower mapping still present, works *
|
||||
**************************************/
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache,
|
||||
null,
|
||||
checkFile
|
||||
),
|
||||
|
||||
/** ************************************
|
||||
* lower mapping still present, works *
|
||||
**************************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache, null, checkFile),
|
||||
|
||||
/** *****************
|
||||
* mapping removed *
|
||||
*******************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/test_registerdirectory.js/", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
/** *****************
|
||||
* mapping removed *
|
||||
*******************/
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/test_registerdirectory.js/", null);
|
||||
},
|
||||
notFound,
|
||||
null
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
var srv;
|
||||
var serverBasePath;
|
||||
var testsDirectory;
|
||||
|
|
@ -231,7 +266,6 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// PATH HANDLERS
|
||||
|
||||
// override of /test_registerdirectory.js
|
||||
|
|
|
|||
|
|
@ -20,25 +20,41 @@ function notFound(ch) {
|
|||
}
|
||||
|
||||
function makeCheckOverride(magic) {
|
||||
return (function checkOverride(ch) {
|
||||
return function checkOverride(ch) {
|
||||
Assert.equal(ch.responseStatus, 200);
|
||||
Assert.equal(ch.responseStatusText, "OK");
|
||||
Assert.ok(ch.requestSucceeded);
|
||||
Assert.equal(ch.getResponseHeader("Override-Succeeded"), magic);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test(BASE + "/prefix/dummy", prefixHandler, null,
|
||||
makeCheckOverride("prefix")),
|
||||
new Test(BASE + "/prefix/dummy", pathHandler, null,
|
||||
makeCheckOverride("path")),
|
||||
new Test(BASE + "/prefix/subpath/dummy", longerPrefixHandler, null,
|
||||
makeCheckOverride("subpath")),
|
||||
new Test(
|
||||
BASE + "/prefix/dummy",
|
||||
prefixHandler,
|
||||
null,
|
||||
makeCheckOverride("prefix")
|
||||
),
|
||||
new Test(
|
||||
BASE + "/prefix/dummy",
|
||||
pathHandler,
|
||||
null,
|
||||
makeCheckOverride("path")
|
||||
),
|
||||
new Test(
|
||||
BASE + "/prefix/subpath/dummy",
|
||||
longerPrefixHandler,
|
||||
null,
|
||||
makeCheckOverride("subpath")
|
||||
),
|
||||
new Test(BASE + "/prefix/dummy", removeHandlers, null, notFound),
|
||||
new Test(BASE + "/prefix/subpath/dummy", newPrefixHandler, null,
|
||||
makeCheckOverride("subpath")),
|
||||
new Test(
|
||||
BASE + "/prefix/subpath/dummy",
|
||||
newPrefixHandler,
|
||||
null,
|
||||
makeCheckOverride("subpath")
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -105,11 +121,11 @@ function run_test() {
|
|||
|
||||
// generate an override
|
||||
function makeOverride(magic) {
|
||||
return (function override(metadata, response) {
|
||||
return function override(metadata, response) {
|
||||
response.setStatusLine("1.1", 200, "OK");
|
||||
response.setHeader("Override-Succeeded", magic, false);
|
||||
|
||||
var body = "success!";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ srv.start(-1);
|
|||
const PORT = srv.identity.primaryPort;
|
||||
|
||||
function run_test() {
|
||||
srv.registerPathHandler("/lots-of-leading-blank-lines",
|
||||
lotsOfLeadingBlankLines);
|
||||
srv.registerPathHandler("/very-long-request-line",
|
||||
veryLongRequestLine);
|
||||
srv.registerPathHandler(
|
||||
"/lots-of-leading-blank-lines",
|
||||
lotsOfLeadingBlankLines
|
||||
);
|
||||
srv.registerPathHandler("/very-long-request-line", veryLongRequestLine);
|
||||
|
||||
runRawTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
/** *************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
|
@ -31,7 +31,6 @@ function run_test() {
|
|||
var test, gData, str;
|
||||
var tests = [];
|
||||
|
||||
|
||||
function veryLongRequestLine(request, response) {
|
||||
writeDetails(request, response);
|
||||
response.setStatusLine(request.httpVersion, 200, "TEST PASSED");
|
||||
|
|
@ -46,14 +45,21 @@ reallyLong = reallyLong + reallyLong + reallyLong + reallyLong; // 8192
|
|||
reallyLong = reallyLong + reallyLong + reallyLong + reallyLong; // 32768
|
||||
reallyLong = reallyLong + reallyLong + reallyLong + reallyLong; // 131072
|
||||
reallyLong = reallyLong + reallyLong + reallyLong + reallyLong; // 524288
|
||||
if (reallyLong.length !== 524288)
|
||||
if (reallyLong.length !== 524288) {
|
||||
throw new TypeError("generated length not as long as expected");
|
||||
str = "GET /very-long-request-line?" + reallyLong + " HTTP/1.1\r\n" +
|
||||
"Host: localhost:" + PORT + "\r\n" +
|
||||
"\r\n";
|
||||
}
|
||||
str =
|
||||
"GET /very-long-request-line?" +
|
||||
reallyLong +
|
||||
" HTTP/1.1\r\n" +
|
||||
"Host: localhost:" +
|
||||
PORT +
|
||||
"\r\n" +
|
||||
"\r\n";
|
||||
gData = [];
|
||||
for (let i = 0; i < str.length; i += 16384)
|
||||
for (let i = 0; i < str.length; i += 16384) {
|
||||
gData.push(str.substr(i, 16384));
|
||||
}
|
||||
|
||||
function checkVeryLongRequestLine(data) {
|
||||
var iter = LineIterator(data);
|
||||
|
|
@ -67,38 +73,41 @@ function checkVeryLongRequestLine(data) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
var body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /very-long-request-line",
|
||||
"Query: " + reallyLong,
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: " + PORT,
|
||||
];
|
||||
var body = [
|
||||
"Method: GET",
|
||||
"Path: /very-long-request-line",
|
||||
"Query: " + reallyLong,
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: " + PORT,
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
test = new RawTest("localhost", PORT, gData, checkVeryLongRequestLine);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
function lotsOfLeadingBlankLines(request, response) {
|
||||
writeDetails(request, response);
|
||||
response.setStatusLine(request.httpVersion, 200, "TEST PASSED");
|
||||
}
|
||||
|
||||
var blankLines = "\r\n";
|
||||
for (let i = 0; i < 14; i++)
|
||||
for (let i = 0; i < 14; i++) {
|
||||
blankLines += blankLines;
|
||||
str = blankLines +
|
||||
"GET /lots-of-leading-blank-lines HTTP/1.1\r\n" +
|
||||
"Host: localhost:" + PORT + "\r\n" +
|
||||
"\r\n";
|
||||
}
|
||||
str =
|
||||
blankLines +
|
||||
"GET /lots-of-leading-blank-lines HTTP/1.1\r\n" +
|
||||
"Host: localhost:" +
|
||||
PORT +
|
||||
"\r\n" +
|
||||
"\r\n";
|
||||
gData = [];
|
||||
for (let i = 0; i < str.length; i += 100)
|
||||
for (let i = 0; i < str.length; i += 100) {
|
||||
gData.push(str.substr(i, 100));
|
||||
}
|
||||
|
||||
function checkLotsOfLeadingBlankLines(data) {
|
||||
var iter = LineIterator(data);
|
||||
|
|
@ -112,16 +121,15 @@ function checkLotsOfLeadingBlankLines(data) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
var body =
|
||||
[
|
||||
"Method: GET",
|
||||
"Path: /lots-of-leading-blank-lines",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: " + PORT,
|
||||
];
|
||||
var body = [
|
||||
"Method: GET",
|
||||
"Path: /lots-of-leading-blank-lines",
|
||||
"Query: ",
|
||||
"Version: 1.1",
|
||||
"Scheme: http",
|
||||
"Host: localhost",
|
||||
"Port: " + PORT,
|
||||
];
|
||||
|
||||
expectLines(iter, body);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,18 @@
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/writeString",
|
||||
null, check_1234, succeeded),
|
||||
new Test("http://localhost:" + srv.identity.primaryPort + "/writeInt",
|
||||
null, check_1234, succeeded),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/writeString",
|
||||
null,
|
||||
check_1234,
|
||||
succeeded
|
||||
),
|
||||
new Test(
|
||||
"http://localhost:" + srv.identity.primaryPort + "/writeInt",
|
||||
null,
|
||||
check_1234,
|
||||
succeeded
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -27,7 +35,6 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
// TEST DATA
|
||||
|
||||
function succeeded(ch, status, data) {
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ function run_test() {
|
|||
runRawTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
function checkException(fun, err, msg) {
|
||||
try {
|
||||
fun();
|
||||
} catch (e) {
|
||||
if (e !== err && e.result !== err)
|
||||
if (e !== err && e.result !== err) {
|
||||
do_throw(msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
do_throw(msg);
|
||||
|
|
@ -48,7 +48,6 @@ function callASAPLater(fun) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/** ***************
|
||||
* PATH HANDLERS *
|
||||
*****************/
|
||||
|
|
@ -65,33 +64,50 @@ function handleTooLate(request, response) {
|
|||
|
||||
response.seizePower();
|
||||
|
||||
if (response.bodyOutputStream !== output)
|
||||
if (response.bodyOutputStream !== output) {
|
||||
response.write("bodyOutputStream changed!");
|
||||
else
|
||||
} else {
|
||||
response.write("too-late passed");
|
||||
}
|
||||
response.finish();
|
||||
}
|
||||
|
||||
function handleExceptions(request, response) {
|
||||
response.seizePower();
|
||||
checkException(function() { response.setStatusLine("1.0", 500, "ISE"); },
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setStatusLine should throw not-available after seizePower");
|
||||
checkException(function() { response.setHeader("X-Fail", "FAIL", false); },
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setHeader should throw not-available after seizePower");
|
||||
checkException(function() { response.processAsync(); },
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"processAsync should throw not-available after seizePower");
|
||||
checkException(
|
||||
function() {
|
||||
response.setStatusLine("1.0", 500, "ISE");
|
||||
},
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setStatusLine should throw not-available after seizePower"
|
||||
);
|
||||
checkException(
|
||||
function() {
|
||||
response.setHeader("X-Fail", "FAIL", false);
|
||||
},
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setHeader should throw not-available after seizePower"
|
||||
);
|
||||
checkException(
|
||||
function() {
|
||||
response.processAsync();
|
||||
},
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"processAsync should throw not-available after seizePower"
|
||||
);
|
||||
var out = response.bodyOutputStream;
|
||||
var data = "exceptions test passed";
|
||||
out.write(data, data.length);
|
||||
response.seizePower(); // idempotency test of seizePower
|
||||
response.finish();
|
||||
response.finish(); // idempotency test of finish after seizePower
|
||||
checkException(function() { response.seizePower(); },
|
||||
Cr.NS_ERROR_UNEXPECTED,
|
||||
"seizePower should throw unexpected after finish");
|
||||
checkException(
|
||||
function() {
|
||||
response.seizePower();
|
||||
},
|
||||
Cr.NS_ERROR_UNEXPECTED,
|
||||
"seizePower should throw unexpected after finish"
|
||||
);
|
||||
}
|
||||
|
||||
function handleAsyncSeizure(request, response) {
|
||||
|
|
@ -108,15 +124,18 @@ function handleAsyncSeizure(request, response) {
|
|||
function handleSeizeAfterAsync(request, response) {
|
||||
response.setStatusLine(request.httpVersion, 200, "async seizure pass");
|
||||
response.processAsync();
|
||||
checkException(function() { response.seizePower(); },
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"seizePower should throw not-available after processAsync");
|
||||
checkException(
|
||||
function() {
|
||||
response.seizePower();
|
||||
},
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"seizePower should throw not-available after processAsync"
|
||||
);
|
||||
callLater(1, function() {
|
||||
response.finish();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/** *************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
|
@ -131,32 +150,30 @@ XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
|||
];
|
||||
});
|
||||
|
||||
var data0 = "GET /raw-data HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
var data0 = "GET /raw-data HTTP/1.0\r\n" + "\r\n";
|
||||
function checkRawData(data) {
|
||||
Assert.equal(data, "Raw data!");
|
||||
}
|
||||
|
||||
var data1 = "GET /called-too-late HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
var data1 = "GET /called-too-late HTTP/1.0\r\n" + "\r\n";
|
||||
function checkTooLate(data) {
|
||||
Assert.equal(LineIterator(data).next().value, "too-late passed");
|
||||
}
|
||||
|
||||
var data2 = "GET /exceptions HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
var data2 = "GET /exceptions HTTP/1.0\r\n" + "\r\n";
|
||||
function checkExceptions(data) {
|
||||
Assert.equal("exceptions test passed", data);
|
||||
}
|
||||
|
||||
var data3 = "GET /async-seizure HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
var data3 = "GET /async-seizure HTTP/1.0\r\n" + "\r\n";
|
||||
function checkAsyncSeizure(data) {
|
||||
Assert.equal(data, "async seizure passed");
|
||||
}
|
||||
|
||||
var data4 = "GET /seize-after-async HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
var data4 = "GET /seize-after-async HTTP/1.0\r\n" + "\r\n";
|
||||
function checkSeizeAfterAsync(data) {
|
||||
Assert.equal(LineIterator(data).next().value, "HTTP/1.0 200 async seizure pass");
|
||||
Assert.equal(
|
||||
LineIterator(data).next().value,
|
||||
"HTTP/1.0 200 async seizure pass"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,22 +30,27 @@ function run_test() {
|
|||
runHttpTests(tests, testComplete(srv));
|
||||
}
|
||||
|
||||
|
||||
/** ***********
|
||||
* UTILITIES *
|
||||
*************/
|
||||
|
||||
function checkStatusLine(channel, httpMaxVer, httpMinVer, httpCode, statusText) {
|
||||
function checkStatusLine(
|
||||
channel,
|
||||
httpMaxVer,
|
||||
httpMinVer,
|
||||
httpCode,
|
||||
statusText
|
||||
) {
|
||||
Assert.equal(channel.responseStatus, httpCode);
|
||||
Assert.equal(channel.responseStatusText, statusText);
|
||||
|
||||
var respMaj = {}, respMin = {};
|
||||
var respMaj = {},
|
||||
respMin = {};
|
||||
channel.getResponseVersion(respMaj, respMin);
|
||||
Assert.equal(respMaj.value, httpMaxVer);
|
||||
Assert.equal(respMin.value, httpMinVer);
|
||||
}
|
||||
|
||||
|
||||
/** *******
|
||||
* TESTS *
|
||||
*********/
|
||||
|
|
@ -63,10 +68,8 @@ XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
|||
];
|
||||
});
|
||||
|
||||
|
||||
// /no/setstatusline
|
||||
function noSetstatusline(metadata, response) {
|
||||
}
|
||||
function noSetstatusline(metadata, response) {}
|
||||
function startNoSetStatusLine(ch) {
|
||||
checkStatusLine(ch, 1, 1, 200, "OK");
|
||||
}
|
||||
|
|
@ -74,7 +77,6 @@ function stop(ch, status, data) {
|
|||
Assert.ok(Components.isSuccessCode(status));
|
||||
}
|
||||
|
||||
|
||||
// /http1_0
|
||||
function http1_0(metadata, response) {
|
||||
response.setStatusLine("1.0", 200, "OK");
|
||||
|
|
@ -83,7 +85,6 @@ function startHttp1_0(ch) {
|
|||
checkStatusLine(ch, 1, 0, 200, "OK");
|
||||
}
|
||||
|
||||
|
||||
// /http1_1
|
||||
function http1_1(metadata, response) {
|
||||
response.setStatusLine("1.1", 200, "OK");
|
||||
|
|
@ -92,7 +93,6 @@ function startHttp1_1(ch) {
|
|||
checkStatusLine(ch, 1, 1, 200, "OK");
|
||||
}
|
||||
|
||||
|
||||
// /invalidVersion
|
||||
function invalidVersion(metadata, response) {
|
||||
try {
|
||||
|
|
@ -106,7 +106,6 @@ function startPassedTrue(ch) {
|
|||
Assert.equal(ch.getResponseHeader("Passed"), "true");
|
||||
}
|
||||
|
||||
|
||||
// /invalidStatus
|
||||
function invalidStatus(metadata, response) {
|
||||
try {
|
||||
|
|
@ -116,7 +115,6 @@ function invalidStatus(metadata, response) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// /invalidDescription
|
||||
function invalidDescription(metadata, response) {
|
||||
try {
|
||||
|
|
@ -126,7 +124,6 @@ function invalidDescription(metadata, response) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// /crazyCode
|
||||
function crazyCode(metadata, response) {
|
||||
response.setStatusLine("1.1", 617, "Crazy");
|
||||
|
|
@ -135,7 +132,6 @@ function startCrazy(ch) {
|
|||
checkStatusLine(ch, 1, 1, 617, "Crazy");
|
||||
}
|
||||
|
||||
|
||||
// /nullVersion
|
||||
function nullVersion(metadata, response) {
|
||||
response.setStatusLine(null, 255, "NULL");
|
||||
|
|
|
|||
|
|
@ -20,20 +20,22 @@ const BASE = "http://localhost:" + PORT;
|
|||
var test;
|
||||
var tests = [];
|
||||
|
||||
|
||||
/** *******************
|
||||
* UTILITY FUNCTIONS *
|
||||
*********************/
|
||||
|
||||
function bytesToString(bytes) {
|
||||
return bytes.map(function(v) { return String.fromCharCode(v); }).join("");
|
||||
return bytes
|
||||
.map(function(v) {
|
||||
return String.fromCharCode(v);
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
function skipCache(ch) {
|
||||
ch.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
}
|
||||
|
||||
|
||||
/** ******************
|
||||
* DEFINE THE TESTS *
|
||||
********************/
|
||||
|
|
@ -61,7 +63,6 @@ function setupTests(throwing) {
|
|||
test = new Test(TEST_URL, setupFile, null, verifyRawText);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// add mapping, => interpreted
|
||||
|
||||
function addTypeMapping(ch) {
|
||||
|
|
@ -79,14 +80,14 @@ function setupTests(throwing) {
|
|||
}
|
||||
|
||||
function checkContents(ch, status, data) {
|
||||
if (!throwing)
|
||||
if (!throwing) {
|
||||
Assert.equal("PASS", bytesToString(data));
|
||||
}
|
||||
}
|
||||
|
||||
test = new Test(TEST_URL, addTypeMapping, checkType, checkContents);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// remove file/type mapping, map containing directory => raw text
|
||||
|
||||
function setupDirectoryAndRemoveType(ch) {
|
||||
|
|
@ -100,7 +101,6 @@ function setupTests(throwing) {
|
|||
test = new Test(TEST_URL, setupDirectoryAndRemoveType, null, verifyRawText);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
// add mapping, => interpreted
|
||||
|
||||
function contentAndCleanup(ch, status, data) {
|
||||
|
|
@ -119,7 +119,6 @@ function setupTests(throwing) {
|
|||
// after the two sets will almost certainly fail.
|
||||
}
|
||||
|
||||
|
||||
/** ***************
|
||||
* ADD THE TESTS *
|
||||
*****************/
|
||||
|
|
@ -157,34 +156,54 @@ function rangeInit(expectedRangeHeader) {
|
|||
function checkRangeResult(ch) {
|
||||
try {
|
||||
var val = ch.getResponseHeader("Content-Range");
|
||||
} catch (e) { /* IDL doesn't specify a particular exception to require */ }
|
||||
} catch (e) {
|
||||
/* IDL doesn't specify a particular exception to require */
|
||||
}
|
||||
if (val !== undefined) {
|
||||
do_throw("should not have gotten a Content-Range header, but got one " +
|
||||
"with this value: " + val);
|
||||
do_throw(
|
||||
"should not have gotten a Content-Range header, but got one " +
|
||||
"with this value: " +
|
||||
val
|
||||
);
|
||||
}
|
||||
Assert.equal(200, ch.responseStatus);
|
||||
Assert.equal("OK", ch.responseStatusText);
|
||||
}
|
||||
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
rangeInit("not-a-bytes-equals-specifier"),
|
||||
checkRangeResult, null);
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("not-a-bytes-equals-specifier"),
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=-"),
|
||||
checkRangeResult, null);
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=-"),
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=1000000-"),
|
||||
checkRangeResult, null);
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=1000000-"),
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=1-4"),
|
||||
checkRangeResult, null);
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=1-4"),
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=-4"),
|
||||
checkRangeResult, null);
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=-4"),
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
|
||||
// One last test: for file mappings, the content-type is determined by the
|
||||
|
|
@ -206,7 +225,6 @@ function onStop(ch, status, data) {
|
|||
test = new Test(BASE + "/script.html", setupFileMapping, onStart, onStop);
|
||||
tests.push(test);
|
||||
|
||||
|
||||
/** ***************
|
||||
* RUN THE TESTS *
|
||||
*****************/
|
||||
|
|
@ -215,7 +233,9 @@ function run_test() {
|
|||
// Test for a content-type which isn't a field-value
|
||||
try {
|
||||
srv.registerContentType("foo", "bar\nbaz");
|
||||
throw new Error("this server throws on content-types which aren't field-values");
|
||||
throw new Error(
|
||||
"this server throws on content-types which aren't field-values"
|
||||
);
|
||||
} catch (e) {
|
||||
isException(e, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
* Tests that the object-state-preservation mechanism works correctly.
|
||||
*/
|
||||
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "PATH", function() {
|
||||
return "http://localhost:" + srv.identity.primaryPort + "/object-state.sjs";
|
||||
});
|
||||
|
|
@ -60,32 +59,46 @@ var initialStarted = false;
|
|||
function initialStart(ch) {
|
||||
dumpn("*** initialStart");
|
||||
|
||||
if (initialStarted)
|
||||
if (initialStarted) {
|
||||
do_throw("initialStart: initialStarted is true?!?!");
|
||||
}
|
||||
|
||||
initialStarted = true;
|
||||
|
||||
new HTTPTestLoader(PATH + "?state=intermediate",
|
||||
intermediateStart, intermediateStop);
|
||||
new HTTPTestLoader(
|
||||
PATH + "?state=intermediate",
|
||||
intermediateStart,
|
||||
intermediateStop
|
||||
);
|
||||
}
|
||||
|
||||
var initialStopped = false;
|
||||
function initialStop(ch, status, data) {
|
||||
dumpn("*** initialStop");
|
||||
|
||||
Assert.equal(data.map(function(v) { return String.fromCharCode(v); }).join(""),
|
||||
"done");
|
||||
Assert.equal(
|
||||
data
|
||||
.map(function(v) {
|
||||
return String.fromCharCode(v);
|
||||
})
|
||||
.join(""),
|
||||
"done"
|
||||
);
|
||||
|
||||
Assert.equal(srv.getObjectState("object-state-test"), null);
|
||||
|
||||
if (!initialStarted)
|
||||
if (!initialStarted) {
|
||||
do_throw("initialStop: initialStarted is false?!?!");
|
||||
if (initialStopped)
|
||||
}
|
||||
if (initialStopped) {
|
||||
do_throw("initialStop: initialStopped is true?!?!");
|
||||
if (!intermediateStarted)
|
||||
}
|
||||
if (!intermediateStarted) {
|
||||
do_throw("initialStop: intermediateStarted is false?!?!");
|
||||
if (!intermediateStopped)
|
||||
}
|
||||
if (!intermediateStopped) {
|
||||
do_throw("initialStop: intermediateStopped is false?!?!");
|
||||
}
|
||||
|
||||
initialStopped = true;
|
||||
|
||||
|
|
@ -98,10 +111,12 @@ function intermediateStart(ch) {
|
|||
|
||||
Assert.notEqual(srv.getObjectState("object-state-test"), null);
|
||||
|
||||
if (!initialStarted)
|
||||
if (!initialStarted) {
|
||||
do_throw("intermediateStart: initialStarted is false?!?!");
|
||||
if (intermediateStarted)
|
||||
}
|
||||
if (intermediateStarted) {
|
||||
do_throw("intermediateStart: intermediateStarted is true?!?!");
|
||||
}
|
||||
|
||||
intermediateStarted = true;
|
||||
}
|
||||
|
|
@ -110,36 +125,48 @@ var intermediateStopped = false;
|
|||
function intermediateStop(ch, status, data) {
|
||||
dumpn("*** intermediateStop");
|
||||
|
||||
Assert.equal(data.map(function(v) { return String.fromCharCode(v); }).join(""),
|
||||
"intermediate");
|
||||
Assert.equal(
|
||||
data
|
||||
.map(function(v) {
|
||||
return String.fromCharCode(v);
|
||||
})
|
||||
.join(""),
|
||||
"intermediate"
|
||||
);
|
||||
|
||||
Assert.notEqual(srv.getObjectState("object-state-test"), null);
|
||||
|
||||
if (!initialStarted)
|
||||
if (!initialStarted) {
|
||||
do_throw("intermediateStop: initialStarted is false?!?!");
|
||||
if (!intermediateStarted)
|
||||
}
|
||||
if (!intermediateStarted) {
|
||||
do_throw("intermediateStop: intermediateStarted is false?!?!");
|
||||
if (intermediateStopped)
|
||||
}
|
||||
if (intermediateStopped) {
|
||||
do_throw("intermediateStop: intermediateStopped is true?!?!");
|
||||
}
|
||||
|
||||
intermediateStopped = true;
|
||||
|
||||
new HTTPTestLoader(PATH + "?state=trigger", triggerStart,
|
||||
triggerStop);
|
||||
new HTTPTestLoader(PATH + "?state=trigger", triggerStart, triggerStop);
|
||||
}
|
||||
|
||||
var triggerStarted = false;
|
||||
function triggerStart(ch) {
|
||||
dumpn("*** triggerStart");
|
||||
|
||||
if (!initialStarted)
|
||||
if (!initialStarted) {
|
||||
do_throw("triggerStart: initialStarted is false?!?!");
|
||||
if (!intermediateStarted)
|
||||
}
|
||||
if (!intermediateStarted) {
|
||||
do_throw("triggerStart: intermediateStarted is false?!?!");
|
||||
if (!intermediateStopped)
|
||||
}
|
||||
if (!intermediateStopped) {
|
||||
do_throw("triggerStart: intermediateStopped is false?!?!");
|
||||
if (triggerStarted)
|
||||
}
|
||||
if (triggerStarted) {
|
||||
do_throw("triggerStart: triggerStarted is true?!?!");
|
||||
}
|
||||
|
||||
triggerStarted = true;
|
||||
}
|
||||
|
|
@ -148,19 +175,30 @@ var triggerStopped = false;
|
|||
function triggerStop(ch, status, data) {
|
||||
dumpn("*** triggerStop");
|
||||
|
||||
Assert.equal(data.map(function(v) { return String.fromCharCode(v); }).join(""),
|
||||
"trigger");
|
||||
Assert.equal(
|
||||
data
|
||||
.map(function(v) {
|
||||
return String.fromCharCode(v);
|
||||
})
|
||||
.join(""),
|
||||
"trigger"
|
||||
);
|
||||
|
||||
if (!initialStarted)
|
||||
if (!initialStarted) {
|
||||
do_throw("triggerStop: initialStarted is false?!?!");
|
||||
if (!intermediateStarted)
|
||||
}
|
||||
if (!intermediateStarted) {
|
||||
do_throw("triggerStop: intermediateStarted is false?!?!");
|
||||
if (!intermediateStopped)
|
||||
}
|
||||
if (!intermediateStopped) {
|
||||
do_throw("triggerStop: intermediateStopped is false?!?!");
|
||||
if (!triggerStarted)
|
||||
}
|
||||
if (!triggerStarted) {
|
||||
do_throw("triggerStop: triggerStarted is false?!?!");
|
||||
if (triggerStopped)
|
||||
}
|
||||
if (triggerStopped) {
|
||||
do_throw("triggerStop: triggerStopped is false?!?!");
|
||||
}
|
||||
|
||||
triggerStopped = true;
|
||||
|
||||
|
|
@ -183,21 +221,24 @@ function checkForFinish() {
|
|||
try {
|
||||
Assert.equal(srv.getObjectState("object-state-test"), null);
|
||||
|
||||
if (!initialStarted)
|
||||
if (!initialStarted) {
|
||||
do_throw("checkForFinish: initialStarted is false?!?!");
|
||||
if (!intermediateStarted)
|
||||
}
|
||||
if (!intermediateStarted) {
|
||||
do_throw("checkForFinish: intermediateStarted is false?!?!");
|
||||
if (!intermediateStopped)
|
||||
}
|
||||
if (!intermediateStopped) {
|
||||
do_throw("checkForFinish: intermediateStopped is false?!?!");
|
||||
if (!triggerStarted)
|
||||
}
|
||||
if (!triggerStarted) {
|
||||
do_throw("checkForFinish: triggerStarted is false?!?!");
|
||||
}
|
||||
} finally {
|
||||
srv.stop(do_test_finished);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** *******************************
|
||||
* UTILITY OBSERVABLE URL LOADER *
|
||||
*********************************/
|
||||
|
|
@ -219,38 +260,46 @@ function HTTPTestLoader(path, start, stop) {
|
|||
var channel = makeChannel(path);
|
||||
channel.asyncOpen(this);
|
||||
}
|
||||
HTTPTestLoader.prototype =
|
||||
{
|
||||
onStartRequest(request) {
|
||||
dumpn("*** HTTPTestLoader.onStartRequest for " + this._path);
|
||||
HTTPTestLoader.prototype = {
|
||||
onStartRequest(request) {
|
||||
dumpn("*** HTTPTestLoader.onStartRequest for " + this._path);
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
this._start(ch);
|
||||
} catch (e) {
|
||||
do_throw(this._path + ": error in onStartRequest: " + e);
|
||||
}
|
||||
this._start(ch);
|
||||
} catch (e) {
|
||||
dumpn("!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called...");
|
||||
do_throw(this._path + ": error in onStartRequest: " + e);
|
||||
}
|
||||
},
|
||||
onDataAvailable(request, inputStream, offset, count) {
|
||||
dumpn("*** HTTPTestLoader.onDataAvailable for " + this._path);
|
||||
} catch (e) {
|
||||
dumpn(
|
||||
"!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called..."
|
||||
);
|
||||
}
|
||||
},
|
||||
onDataAvailable(request, inputStream, offset, count) {
|
||||
dumpn("*** HTTPTestLoader.onDataAvailable for " + this._path);
|
||||
|
||||
Array.prototype.push.apply(this._data,
|
||||
makeBIS(inputStream).readByteArray(count));
|
||||
},
|
||||
onStopRequest(request, status) {
|
||||
dumpn("*** HTTPTestLoader.onStopRequest for " + this._path);
|
||||
Array.prototype.push.apply(
|
||||
this._data,
|
||||
makeBIS(inputStream).readByteArray(count)
|
||||
);
|
||||
},
|
||||
onStopRequest(request, status) {
|
||||
dumpn("*** HTTPTestLoader.onStopRequest for " + this._path);
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
this._stop(ch, status, this._data);
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIStreamListener", "nsIRequestObserver"]),
|
||||
};
|
||||
this._stop(ch, status, this._data);
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIStreamListener",
|
||||
"nsIRequestObserver",
|
||||
]),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,20 +22,21 @@ function run_test() {
|
|||
|
||||
function done() {
|
||||
Assert.equal(srv.getSharedState("shared-value"), "done!");
|
||||
Assert.equal(srv.getState("/path-handler", "private-value"),
|
||||
"pathHandlerPrivate2");
|
||||
Assert.equal(srv.getState("/state1.sjs", "private-value"),
|
||||
"");
|
||||
Assert.equal(srv.getState("/state2.sjs", "private-value"),
|
||||
"newPrivate5");
|
||||
Assert.equal(
|
||||
srv.getState("/path-handler", "private-value"),
|
||||
"pathHandlerPrivate2"
|
||||
);
|
||||
Assert.equal(srv.getState("/state1.sjs", "private-value"), "");
|
||||
Assert.equal(srv.getState("/state2.sjs", "private-value"), "newPrivate5");
|
||||
do_test_pending();
|
||||
srv.stop(function() { do_test_finished(); });
|
||||
srv.stop(function() {
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
||||
|
||||
runHttpTests(tests, done);
|
||||
}
|
||||
|
||||
|
||||
/** **********
|
||||
* HANDLERS *
|
||||
************/
|
||||
|
|
@ -45,10 +46,16 @@ var firstTime = true;
|
|||
function pathHandler(request, response) {
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
response.setHeader("X-Old-Shared-Value", srv.getSharedState("shared-value"),
|
||||
false);
|
||||
response.setHeader("X-Old-Private-Value", srv.getState("/path-handler", "private-value"),
|
||||
false);
|
||||
response.setHeader(
|
||||
"X-Old-Shared-Value",
|
||||
srv.getSharedState("shared-value"),
|
||||
false
|
||||
);
|
||||
response.setHeader(
|
||||
"X-Old-Private-Value",
|
||||
srv.getState("/path-handler", "private-value"),
|
||||
false
|
||||
);
|
||||
|
||||
var privateValue, sharedValue;
|
||||
if (firstTime) {
|
||||
|
|
@ -67,38 +74,56 @@ function pathHandler(request, response) {
|
|||
response.setHeader("X-New-Shared-Value", sharedValue, false);
|
||||
}
|
||||
|
||||
|
||||
/** *************
|
||||
* BEGIN TESTS *
|
||||
***************/
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
return [
|
||||
new Test(URL + "/state1.sjs?" +
|
||||
"newShared=newShared&newPrivate=newPrivate",
|
||||
null, start_initial, null),
|
||||
new Test(URL + "/state1.sjs?" +
|
||||
"newShared=newShared2&newPrivate=newPrivate2",
|
||||
null, start_overwrite, null),
|
||||
new Test(URL + "/state1.sjs?" +
|
||||
"newShared=&newPrivate=newPrivate3",
|
||||
null, start_remove, null),
|
||||
new Test(URL + "/path-handler",
|
||||
null, start_handler, null),
|
||||
new Test(URL + "/path-handler",
|
||||
null, start_handler_again, null),
|
||||
new Test(URL + "/state2.sjs?" +
|
||||
"newShared=newShared4&newPrivate=newPrivate4",
|
||||
null, start_other_initial, null),
|
||||
new Test(URL + "/state2.sjs?" +
|
||||
"newShared=",
|
||||
null, start_other_remove_ignore, null),
|
||||
new Test(URL + "/state2.sjs?" +
|
||||
"newShared=newShared5&newPrivate=newPrivate5",
|
||||
null, start_other_set_new, null),
|
||||
new Test(URL + "/state1.sjs?" +
|
||||
"newShared=done!&newPrivate=",
|
||||
null, start_set_remove_original, null),
|
||||
new Test(
|
||||
URL + "/state1.sjs?" + "newShared=newShared&newPrivate=newPrivate",
|
||||
null,
|
||||
start_initial,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
URL + "/state1.sjs?" + "newShared=newShared2&newPrivate=newPrivate2",
|
||||
null,
|
||||
start_overwrite,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
URL + "/state1.sjs?" + "newShared=&newPrivate=newPrivate3",
|
||||
null,
|
||||
start_remove,
|
||||
null
|
||||
),
|
||||
new Test(URL + "/path-handler", null, start_handler, null),
|
||||
new Test(URL + "/path-handler", null, start_handler_again, null),
|
||||
new Test(
|
||||
URL + "/state2.sjs?" + "newShared=newShared4&newPrivate=newPrivate4",
|
||||
null,
|
||||
start_other_initial,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
URL + "/state2.sjs?" + "newShared=",
|
||||
null,
|
||||
start_other_remove_ignore,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
URL + "/state2.sjs?" + "newShared=newShared5&newPrivate=newPrivate5",
|
||||
null,
|
||||
start_other_set_new,
|
||||
null
|
||||
),
|
||||
new Test(
|
||||
URL + "/state1.sjs?" + "newShared=done!&newPrivate=",
|
||||
null,
|
||||
start_set_remove_original,
|
||||
null
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -108,8 +133,9 @@ function getHeaderFunction(ch) {
|
|||
try {
|
||||
return ch.getResponseHeader(name);
|
||||
} catch (e) {
|
||||
if (e.result !== Cr.NS_ERROR_NOT_AVAILABLE)
|
||||
if (e.result !== Cr.NS_ERROR_NOT_AVAILABLE) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
@ -127,7 +153,7 @@ function expectValues(ch, oldShared, newShared, oldPrivate, newPrivate) {
|
|||
}
|
||||
|
||||
function start_initial(ch) {
|
||||
dumpn("XXX start_initial");
|
||||
dumpn("XXX start_initial");
|
||||
expectValues(ch, "", "newShared", "", "newPrivate");
|
||||
}
|
||||
|
||||
|
|
@ -144,8 +170,13 @@ function start_handler(ch) {
|
|||
}
|
||||
|
||||
function start_handler_again(ch) {
|
||||
expectValues(ch, "pathHandlerShared", "",
|
||||
"pathHandlerPrivate", "pathHandlerPrivate2");
|
||||
expectValues(
|
||||
ch,
|
||||
"pathHandlerShared",
|
||||
"",
|
||||
"pathHandlerPrivate",
|
||||
"pathHandlerPrivate2"
|
||||
);
|
||||
}
|
||||
|
||||
function start_other_initial(ch) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ function run_test() {
|
|||
|
||||
function done() {
|
||||
do_test_pending();
|
||||
srv.stop(function() { do_test_finished(); });
|
||||
srv.stop(function() {
|
||||
do_test_finished();
|
||||
});
|
||||
Assert.equal(gStartCount, TEST_RUNS);
|
||||
Assert.ok(lastPassed);
|
||||
}
|
||||
|
|
@ -46,8 +48,9 @@ const TEST_RUNS = 250;
|
|||
XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
||||
var _tests = new Array(TEST_RUNS + 1);
|
||||
var _test = new Test(URL + "/thrower.sjs?throw", null, start_thrower);
|
||||
for (var i = 0; i < TEST_RUNS; i++)
|
||||
for (var i = 0; i < TEST_RUNS; i++) {
|
||||
_tests[i] = _test;
|
||||
}
|
||||
// ...and don't forget to stop!
|
||||
_tests[TEST_RUNS] = new Test(URL + "/thrower.sjs", null, start_last);
|
||||
return _tests;
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ var srv, srv2;
|
|||
|
||||
function run_test() {
|
||||
if (mozinfo.os == "win") {
|
||||
dumpn("*** not running test_start_stop.js on Windows for now, because " +
|
||||
"Windows is dumb");
|
||||
dumpn(
|
||||
"*** not running test_start_stop.js on Windows for now, because " +
|
||||
"Windows is dumb"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -65,15 +67,16 @@ function run_test_2() {
|
|||
|
||||
do_test_pending();
|
||||
try {
|
||||
srv.stop({onStopped() {
|
||||
try {
|
||||
do_test_pending();
|
||||
run_test_3();
|
||||
} finally {
|
||||
do_test_finished();
|
||||
}
|
||||
},
|
||||
});
|
||||
srv.stop({
|
||||
onStopped() {
|
||||
try {
|
||||
do_test_pending();
|
||||
run_test_3();
|
||||
} finally {
|
||||
do_test_finished();
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
do_throw("error stopping with an object: " + e);
|
||||
}
|
||||
|
|
@ -123,11 +126,11 @@ function run_test_5() {
|
|||
dumpn("*** run_test_5");
|
||||
|
||||
testsComplete = true;
|
||||
if (stopped)
|
||||
if (stopped) {
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const INTERVAL = 500;
|
||||
|
||||
function handle(request, response) {
|
||||
|
|
@ -157,6 +160,7 @@ var stopped = false;
|
|||
function serverStopped() {
|
||||
dumpn("*** server really, fully shut down now");
|
||||
stopped = true;
|
||||
if (testsComplete)
|
||||
if (testsComplete) {
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
|
||||
var observer = {
|
||||
|
|
@ -8,15 +8,15 @@ var observer = {
|
|||
sendAsyncMessage("cookieName", cookie.name + "=" + cookie.value);
|
||||
sendAsyncMessage("cookieOperation", data);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
addMessageListener("createObserver" , function(e) {
|
||||
addMessageListener("createObserver", function(e) {
|
||||
Services.obs.addObserver(observer, "cookie-changed");
|
||||
sendAsyncMessage("createObserver:return");
|
||||
});
|
||||
|
||||
addMessageListener("removeObserver" , function(e) {
|
||||
addMessageListener("removeObserver", function(e) {
|
||||
Services.obs.removeObserver(observer, "cookie-changed");
|
||||
sendAsyncMessage("removeObserver:return");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
let cs = Cc["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Ci.nsICookieManager);
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
||||
|
||||
addMessageListener("getCookieCountAndClear", () => {
|
||||
let count = 0;
|
||||
for (let cookie of cs.enumerator)
|
||||
for (let cookie of cs.enumerator) {
|
||||
++count;
|
||||
}
|
||||
cs.removeAll();
|
||||
|
||||
sendAsyncMessage("getCookieCountAndClear:return", { count });
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
function getCookieService() {
|
||||
return Cc["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Ci.nsICookieManager);
|
||||
return Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
||||
}
|
||||
|
||||
function getCookies(cs) {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@ function setupTest(uri, cookies, loads) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var prefSet = new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({ set: [
|
||||
["network.cookie.cookieBehavior", 1],
|
||||
]}, resolve);
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ set: [["network.cookie.cookieBehavior", 1]] },
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
gScript = SpecialPowers.loadChromeScript(SCRIPT_URL);
|
||||
|
|
@ -28,7 +29,7 @@ function setupTest(uri, cookies, loads) {
|
|||
prefSet.then(() => {
|
||||
// load a window which contains an iframe; each will attempt to set
|
||||
// cookies from their respective domains.
|
||||
gPopup = window.open(uri, 'hai', 'width=100,height=100');
|
||||
gPopup = window.open(uri, "hai", "width=100,height=100");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
const SCRIPT_URL = SimpleTest.getTestFileURL('file_testloadflags_chromescript.js');
|
||||
const SCRIPT_URL = SimpleTest.getTestFileURL(
|
||||
"file_testloadflags_chromescript.js"
|
||||
);
|
||||
|
||||
var gExpectedCookies;
|
||||
var gExpectedHeaders;
|
||||
|
|
@ -12,13 +14,26 @@ var gLoads = 0;
|
|||
|
||||
// setupTest() is run from 'onload='.
|
||||
function setupTest(uri, domain, cookies, loads, headers) {
|
||||
info("setupTest uri: " + uri + " domain: " + domain + " cookies: " + cookies +
|
||||
" loads: " + loads + " headers: " + headers);
|
||||
info(
|
||||
"setupTest uri: " +
|
||||
uri +
|
||||
" domain: " +
|
||||
domain +
|
||||
" cookies: " +
|
||||
cookies +
|
||||
" loads: " +
|
||||
loads +
|
||||
" headers: " +
|
||||
headers
|
||||
);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var prefSet = new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({ set: [["network.cookie.cookieBehavior", 1]] }, resolve);
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ set: [["network.cookie.cookieBehavior", 1]] },
|
||||
resolve
|
||||
);
|
||||
});
|
||||
|
||||
gExpectedCookies = cookies;
|
||||
|
|
@ -29,8 +44,11 @@ function setupTest(uri, domain, cookies, loads, headers) {
|
|||
gScript.addMessageListener("info", ({ str }) => info(str));
|
||||
gScript.addMessageListener("ok", ({ c, m }) => ok(c, m));
|
||||
gScript.addMessageListener("observer:gotCookie", ({ cookie, uri }) => {
|
||||
isnot(cookie.indexOf("oh=hai"), -1,
|
||||
"cookie 'oh=hai' is in header for " + uri);
|
||||
isnot(
|
||||
cookie.indexOf("oh=hai"),
|
||||
-1,
|
||||
"cookie 'oh=hai' is in header for " + uri
|
||||
);
|
||||
++gHeaders;
|
||||
});
|
||||
|
||||
|
|
@ -42,15 +60,14 @@ function setupTest(uri, domain, cookies, loads, headers) {
|
|||
// Listen for MessageEvents.
|
||||
window.addEventListener("message", messageReceiver);
|
||||
|
||||
Promise.all([ prefSet, scriptReady ]).then(() => {
|
||||
Promise.all([prefSet, scriptReady]).then(() => {
|
||||
// load a window which contains an iframe; each will attempt to set
|
||||
// cookies from their respective domains.
|
||||
gPopup = window.open(uri, 'hai', 'width=100,height=100');
|
||||
gPopup = window.open(uri, "hai", "width=100,height=100");
|
||||
});
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
function finishTest() {
|
||||
gScript.addMessageListener("shutdown:return", () => {
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
|
|
@ -60,10 +77,11 @@ function finishTest()
|
|||
|
||||
/** Receives MessageEvents to this window. */
|
||||
// Count and check loads.
|
||||
function messageReceiver(evt)
|
||||
{
|
||||
ok(evt.data == "f_lf_i msg data img" || evt.data == "f_lf_i msg data page",
|
||||
"message data received from popup");
|
||||
function messageReceiver(evt) {
|
||||
ok(
|
||||
evt.data == "f_lf_i msg data img" || evt.data == "f_lf_i msg data page",
|
||||
"message data received from popup"
|
||||
);
|
||||
if (evt.data == "f_lf_i msg data img") {
|
||||
info("message data received from popup for image");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ function is(a, b, m) {
|
|||
function obs() {
|
||||
info("adding observer");
|
||||
|
||||
this.os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
this.os = Cc["@mozilla.org/observer-service;1"].getService(
|
||||
Ci.nsIObserverService
|
||||
);
|
||||
this.os.addObserver(this, "http-on-modify-request");
|
||||
}
|
||||
|
||||
|
|
@ -35,21 +36,26 @@ obs.prototype = {
|
|||
channel.visitRequestHeaders({
|
||||
visitHeader(aHeader, aValue) {
|
||||
info(aHeader + ": " + aValue);
|
||||
}});
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
ok(false, "catch error " + err);
|
||||
}
|
||||
|
||||
// Ignore notifications we don't care about (like favicons)
|
||||
if (!channel.URI.spec.includes(
|
||||
"http://example.org/tests/netwerk/test/mochitests/")) {
|
||||
if (
|
||||
!channel.URI.spec.includes(
|
||||
"http://example.org/tests/netwerk/test/mochitests/"
|
||||
)
|
||||
) {
|
||||
info("ignoring this one");
|
||||
return;
|
||||
}
|
||||
|
||||
sendAsyncMessage("observer:gotCookie",
|
||||
{ cookie: channel.getRequestHeader("Cookie"),
|
||||
uri: channel.URI.spec });
|
||||
sendAsyncMessage("observer:gotCookie", {
|
||||
cookie: channel.getRequestHeader("Cookie"),
|
||||
uri: channel.URI.spec,
|
||||
});
|
||||
},
|
||||
|
||||
remove() {
|
||||
|
|
@ -57,15 +63,27 @@ obs.prototype = {
|
|||
|
||||
this.os.removeObserver(this, "http-on-modify-request");
|
||||
this.os = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function getCookieCount(cs) {
|
||||
let count = 0;
|
||||
for (let cookie of cs.enumerator) {
|
||||
info("cookie: " + cookie);
|
||||
info("cookie host " + cookie.host + " path " + cookie.path + " name " + cookie.name +
|
||||
" value " + cookie.value + " isSecure " + cookie.isSecure + " expires " + cookie.expires);
|
||||
info(
|
||||
"cookie host " +
|
||||
cookie.host +
|
||||
" path " +
|
||||
cookie.path +
|
||||
" name " +
|
||||
cookie.name +
|
||||
" value " +
|
||||
cookie.value +
|
||||
" isSecure " +
|
||||
cookie.isSecure +
|
||||
" expires " +
|
||||
cookie.expires
|
||||
);
|
||||
++count;
|
||||
}
|
||||
|
||||
|
|
@ -73,8 +91,7 @@ function getCookieCount(cs) {
|
|||
}
|
||||
|
||||
addMessageListener("init", ({ domain }) => {
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Ci.nsICookieManager);
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
||||
|
||||
info("we are going to remove these cookies");
|
||||
|
||||
|
|
@ -82,17 +99,30 @@ addMessageListener("init", ({ domain }) => {
|
|||
info(count + " cookies");
|
||||
|
||||
cs.removeAll();
|
||||
cs.add(domain, "", "oh", "hai", false, false, true, Math.pow(2, 62), {},
|
||||
Ci.nsICookie.SAMESITE_NONE);
|
||||
is(cs.countCookiesFromHost(domain), 1, "number of cookies for domain " + domain);
|
||||
cs.add(
|
||||
domain,
|
||||
"",
|
||||
"oh",
|
||||
"hai",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
Math.pow(2, 62),
|
||||
{},
|
||||
Ci.nsICookie.SAMESITE_NONE
|
||||
);
|
||||
is(
|
||||
cs.countCookiesFromHost(domain),
|
||||
1,
|
||||
"number of cookies for domain " + domain
|
||||
);
|
||||
|
||||
gObs = new obs();
|
||||
sendAsyncMessage("init:return");
|
||||
});
|
||||
|
||||
addMessageListener("getCookieCount", () => {
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Ci.nsICookieManager);
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
||||
let count = getCookieCount(cs);
|
||||
|
||||
cs.removeAll();
|
||||
|
|
@ -102,8 +132,7 @@ addMessageListener("getCookieCount", () => {
|
|||
addMessageListener("shutdown", () => {
|
||||
gObs.remove();
|
||||
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Ci.nsICookieManager);
|
||||
let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
||||
cs.removeAll();
|
||||
sendAsyncMessage("shutdown:return");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
// 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 { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
var Prompter = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrompt]),
|
||||
alert() {} // Do nothing when asked to show an alert
|
||||
alert() {}, // Do nothing when asked to show an alert
|
||||
};
|
||||
|
||||
function WindowWatcherService() {}
|
||||
|
|
@ -17,9 +19,7 @@ WindowWatcherService.prototype = {
|
|||
|
||||
getNewPrompter() {
|
||||
return Prompter;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
|
||||
WindowWatcherService
|
||||
]);
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WindowWatcherService]);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,23 @@
|
|||
var {XPCOMUtils} = ChromeUtils.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
var {Services} = ChromeUtils.import('resource://gre/modules/Services.jsm');
|
||||
var { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var _CSvc;
|
||||
function get_cache_service() {
|
||||
if (_CSvc)
|
||||
if (_CSvc) {
|
||||
return _CSvc;
|
||||
}
|
||||
|
||||
return _CSvc = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
||||
.getService(Ci.nsICacheStorageService);
|
||||
return (_CSvc = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(
|
||||
Ci.nsICacheStorageService
|
||||
));
|
||||
}
|
||||
|
||||
function evict_cache_entries(where)
|
||||
{
|
||||
var clearDisk = (!where || where == "disk" || where == "all");
|
||||
var clearMem = (!where || where == "memory" || where == "all");
|
||||
var clearAppCache = (where == "appcache");
|
||||
function evict_cache_entries(where) {
|
||||
var clearDisk = !where || where == "disk" || where == "all";
|
||||
var clearMem = !where || where == "memory" || where == "all";
|
||||
var clearAppCache = where == "appcache";
|
||||
|
||||
var svc = get_cache_service();
|
||||
var storage;
|
||||
|
|
@ -35,72 +38,79 @@ function evict_cache_entries(where)
|
|||
}
|
||||
}
|
||||
|
||||
function createURI(urispec)
|
||||
{
|
||||
var ioServ = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
function createURI(urispec) {
|
||||
var ioServ = Cc["@mozilla.org/network/io-service;1"].getService(
|
||||
Ci.nsIIOService
|
||||
);
|
||||
return ioServ.newURI(urispec);
|
||||
}
|
||||
|
||||
function getCacheStorage(where, lci, appcache)
|
||||
{
|
||||
if (!lci) lci = Services.loadContextInfo.default;
|
||||
function getCacheStorage(where, lci, appcache) {
|
||||
if (!lci) {
|
||||
lci = Services.loadContextInfo.default;
|
||||
}
|
||||
var svc = get_cache_service();
|
||||
switch (where) {
|
||||
case "disk": return svc.diskCacheStorage(lci, false);
|
||||
case "memory": return svc.memoryCacheStorage(lci);
|
||||
case "appcache": return svc.appCacheStorage(lci, appcache);
|
||||
case "pin": return svc.pinningCacheStorage(lci);
|
||||
case "disk":
|
||||
return svc.diskCacheStorage(lci, false);
|
||||
case "memory":
|
||||
return svc.memoryCacheStorage(lci);
|
||||
case "appcache":
|
||||
return svc.appCacheStorage(lci, appcache);
|
||||
case "pin":
|
||||
return svc.pinningCacheStorage(lci);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function asyncOpenCacheEntry(key, where, flags, lci, callback, appcache)
|
||||
{
|
||||
function asyncOpenCacheEntry(key, where, flags, lci, callback, appcache) {
|
||||
key = createURI(key);
|
||||
|
||||
function CacheListener() { }
|
||||
function CacheListener() {}
|
||||
CacheListener.prototype = {
|
||||
_appCache: appcache,
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI(["nsICacheEntryOpenCallback"]),
|
||||
|
||||
onCacheEntryCheck(entry, appCache) {
|
||||
if (typeof callback === "object")
|
||||
if (typeof callback === "object") {
|
||||
return callback.onCacheEntryCheck(entry, appCache);
|
||||
}
|
||||
return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
|
||||
},
|
||||
|
||||
onCacheEntryAvailable (entry, isnew, appCache, status) {
|
||||
onCacheEntryAvailable(entry, isnew, appCache, status) {
|
||||
if (typeof callback === "object") {
|
||||
// Root us at the callback
|
||||
callback.__cache_listener_root = this;
|
||||
callback.onCacheEntryAvailable(entry, isnew, appCache, status);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
callback(status, entry, appCache);
|
||||
}
|
||||
},
|
||||
|
||||
run () {
|
||||
run() {
|
||||
var storage = getCacheStorage(where, lci, this._appCache);
|
||||
storage.asyncOpenURI(key, "", flags, this);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
(new CacheListener()).run();
|
||||
new CacheListener().run();
|
||||
}
|
||||
|
||||
function syncWithCacheIOThread(callback, force)
|
||||
{
|
||||
function syncWithCacheIOThread(callback, force) {
|
||||
if (force) {
|
||||
asyncOpenCacheEntry(
|
||||
"http://nonexistententry/", "disk", Ci.nsICacheStorage.OPEN_READONLY, null,
|
||||
"http://nonexistententry/",
|
||||
"disk",
|
||||
Ci.nsICacheStorage.OPEN_READONLY,
|
||||
null,
|
||||
function(status, entry) {
|
||||
Assert.equal(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
else {
|
||||
}
|
||||
);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
|
@ -113,7 +123,7 @@ function get_device_entry_count(where, lci, continuation) {
|
|||
}
|
||||
|
||||
var visitor = {
|
||||
onCacheStorageInfo (entryCount, consumption) {
|
||||
onCacheStorageInfo(entryCount, consumption) {
|
||||
executeSoon(function() {
|
||||
continuation(entryCount, consumption);
|
||||
});
|
||||
|
|
@ -124,19 +134,32 @@ function get_device_entry_count(where, lci, continuation) {
|
|||
storage.asyncVisitStorage(visitor, false);
|
||||
}
|
||||
|
||||
function asyncCheckCacheEntryPresence(key, where, shouldExist, continuation, appCache)
|
||||
{
|
||||
asyncOpenCacheEntry(key, where, Ci.nsICacheStorage.OPEN_READONLY, null,
|
||||
function asyncCheckCacheEntryPresence(
|
||||
key,
|
||||
where,
|
||||
shouldExist,
|
||||
continuation,
|
||||
appCache
|
||||
) {
|
||||
asyncOpenCacheEntry(
|
||||
key,
|
||||
where,
|
||||
Ci.nsICacheStorage.OPEN_READONLY,
|
||||
null,
|
||||
function(status, entry) {
|
||||
if (shouldExist) {
|
||||
dump("TEST-INFO | checking cache key " + key + " exists @ " + where);
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
Assert.ok(!!entry);
|
||||
} else {
|
||||
dump("TEST-INFO | checking cache key " + key + " doesn't exist @ " + where);
|
||||
dump(
|
||||
"TEST-INFO | checking cache key " + key + " doesn't exist @ " + where
|
||||
);
|
||||
Assert.equal(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
|
||||
Assert.equal(null, entry);
|
||||
}
|
||||
continuation();
|
||||
}, appCache);
|
||||
},
|
||||
appCache
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +1,100 @@
|
|||
var callbacks = new Array();
|
||||
|
||||
// Expect an existing entry
|
||||
const NORMAL = 0;
|
||||
const NORMAL = 0;
|
||||
// Expect a new entry
|
||||
const NEW = 1 << 0;
|
||||
const NEW = 1 << 0;
|
||||
// Return early from onCacheEntryCheck and set the callback to state it expects onCacheEntryCheck to happen
|
||||
const NOTVALID = 1 << 1;
|
||||
const NOTVALID = 1 << 1;
|
||||
// Throw from onCacheEntryAvailable
|
||||
const THROWAVAIL = 1 << 2;
|
||||
const THROWAVAIL = 1 << 2;
|
||||
// Open entry for reading-only
|
||||
const READONLY = 1 << 3;
|
||||
const READONLY = 1 << 3;
|
||||
// Expect the entry to not be found
|
||||
const NOTFOUND = 1 << 4;
|
||||
const NOTFOUND = 1 << 4;
|
||||
// Return ENTRY_NEEDS_REVALIDATION from onCacheEntryCheck
|
||||
const REVAL = 1 << 5;
|
||||
const REVAL = 1 << 5;
|
||||
// Return ENTRY_PARTIAL from onCacheEntryCheck, in combo with NEW or RECREATE bypasses check for emptiness of the entry
|
||||
const PARTIAL = 1 << 6
|
||||
const PARTIAL = 1 << 6;
|
||||
// Expect the entry is doomed, i.e. the output stream should not be possible to open
|
||||
const DOOMED = 1 << 7;
|
||||
const DOOMED = 1 << 7;
|
||||
// Don't trigger the go-on callback until the entry is written
|
||||
const WAITFORWRITE = 1 << 8;
|
||||
const WAITFORWRITE = 1 << 8;
|
||||
// Don't write data (i.e. don't open output stream)
|
||||
const METAONLY = 1 << 9;
|
||||
const METAONLY = 1 << 9;
|
||||
// Do recreation of an existing cache entry
|
||||
const RECREATE = 1 << 10;
|
||||
const RECREATE = 1 << 10;
|
||||
// Do not give me the entry
|
||||
const NOTWANTED = 1 << 11;
|
||||
const NOTWANTED = 1 << 11;
|
||||
// Tell the cache to wait for the entry to be completely written first
|
||||
const COMPLETE = 1 << 12;
|
||||
const COMPLETE = 1 << 12;
|
||||
// Don't write meta/data and don't set valid in the callback, consumer will do it manually
|
||||
const DONTFILL = 1 << 13;
|
||||
const DONTFILL = 1 << 13;
|
||||
// Used in combination with METAONLY, don't call setValid() on the entry after metadata has been set
|
||||
const DONTSETVALID = 1 << 14;
|
||||
const DONTSETVALID = 1 << 14;
|
||||
// Notify before checking the data, useful for proper callback ordering checks
|
||||
const NOTIFYBEFOREREAD = 1 << 15;
|
||||
// It's allowed to not get an existing entry (result of opening is undetermined)
|
||||
const MAYBE_NEW = 1 << 16;
|
||||
const MAYBE_NEW = 1 << 16;
|
||||
|
||||
var log_c2 = true;
|
||||
function LOG_C2(o, m)
|
||||
{
|
||||
if (!log_c2) return;
|
||||
if (!m)
|
||||
function LOG_C2(o, m) {
|
||||
if (!log_c2) {
|
||||
return;
|
||||
}
|
||||
if (!m) {
|
||||
dump("TEST-INFO | CACHE2: " + o + "\n");
|
||||
else
|
||||
dump("TEST-INFO | CACHE2: callback #" + o.order + "(" + (o.workingData ? o.workingData.substr(0, 10) : "---") + ") " + m + "\n");
|
||||
} else {
|
||||
dump(
|
||||
"TEST-INFO | CACHE2: callback #" +
|
||||
o.order +
|
||||
"(" +
|
||||
(o.workingData ? o.workingData.substr(0, 10) : "---") +
|
||||
") " +
|
||||
m +
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function pumpReadStream(inputStream, goon)
|
||||
{
|
||||
function pumpReadStream(inputStream, goon) {
|
||||
if (inputStream.isNonBlocking()) {
|
||||
// non-blocking stream, must read via pump
|
||||
var pump = Cc["@mozilla.org/network/input-stream-pump;1"]
|
||||
.createInstance(Ci.nsIInputStreamPump);
|
||||
var pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(
|
||||
Ci.nsIInputStreamPump
|
||||
);
|
||||
pump.init(inputStream, 0, 0, true);
|
||||
var data = "";
|
||||
pump.asyncRead({
|
||||
onStartRequest (aRequest) { },
|
||||
onDataAvailable (aRequest, aInputStream, aOffset, aCount)
|
||||
pump.asyncRead(
|
||||
{
|
||||
var wrapper = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
wrapper.init(aInputStream);
|
||||
var str = wrapper.read(wrapper.available());
|
||||
LOG_C2("reading data '" + str.substring(0,5) + "'");
|
||||
data += str;
|
||||
onStartRequest(aRequest) {},
|
||||
onDataAvailable(aRequest, aInputStream, aOffset, aCount) {
|
||||
var wrapper = Cc[
|
||||
"@mozilla.org/scriptableinputstream;1"
|
||||
].createInstance(Ci.nsIScriptableInputStream);
|
||||
wrapper.init(aInputStream);
|
||||
var str = wrapper.read(wrapper.available());
|
||||
LOG_C2("reading data '" + str.substring(0, 5) + "'");
|
||||
data += str;
|
||||
},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
LOG_C2("done reading data: " + aStatusCode);
|
||||
Assert.equal(aStatusCode, Cr.NS_OK);
|
||||
goon(data);
|
||||
},
|
||||
},
|
||||
onStopRequest (aRequest, aStatusCode)
|
||||
{
|
||||
LOG_C2("done reading data: " + aStatusCode);
|
||||
Assert.equal(aStatusCode, Cr.NS_OK);
|
||||
goon(data);
|
||||
},
|
||||
}, null);
|
||||
}
|
||||
else {
|
||||
null
|
||||
);
|
||||
} else {
|
||||
// blocking stream
|
||||
var data = read_stream(inputStream, inputStream.available());
|
||||
goon(data);
|
||||
}
|
||||
}
|
||||
|
||||
OpenCallback.prototype =
|
||||
{
|
||||
OpenCallback.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsICacheEntryOpenCallback"]),
|
||||
onCacheEntryCheck(entry, appCache)
|
||||
{
|
||||
onCacheEntryCheck(entry, appCache) {
|
||||
LOG_C2(this, "onCacheEntryCheck");
|
||||
Assert.ok(!this.onCheckPassed);
|
||||
this.onCheckPassed = true;
|
||||
|
|
@ -103,15 +112,18 @@ OpenCallback.prototype =
|
|||
Assert.equal(entry.getMetaDataElement("meto"), this.workingMetadata);
|
||||
|
||||
// check for sane flag combination
|
||||
Assert.notEqual(this.behavior & (REVAL|PARTIAL), REVAL|PARTIAL);
|
||||
Assert.notEqual(this.behavior & (REVAL | PARTIAL), REVAL | PARTIAL);
|
||||
|
||||
if (this.behavior & (REVAL|PARTIAL)) {
|
||||
if (this.behavior & (REVAL | PARTIAL)) {
|
||||
LOG_C2(this, "onCacheEntryCheck DONE, return ENTRY_NEEDS_REVALIDATION");
|
||||
return Ci.nsICacheEntryOpenCallback.ENTRY_NEEDS_REVALIDATION;
|
||||
}
|
||||
|
||||
if (this.behavior & COMPLETE) {
|
||||
LOG_C2(this, "onCacheEntryCheck DONE, return RECHECK_AFTER_WRITE_FINISHED");
|
||||
LOG_C2(
|
||||
this,
|
||||
"onCacheEntryCheck DONE, return RECHECK_AFTER_WRITE_FINISHED"
|
||||
);
|
||||
// Specific to the new backend because of concurrent read/write:
|
||||
// when a consumer returns RECHECK_AFTER_WRITE_FINISHED from onCacheEntryCheck
|
||||
// the cache calls this callback again after the entry write has finished.
|
||||
|
|
@ -127,9 +139,8 @@ OpenCallback.prototype =
|
|||
LOG_C2(this, "onCacheEntryCheck DONE, return ENTRY_WANTED");
|
||||
return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
|
||||
},
|
||||
onCacheEntryAvailable(entry, isnew, appCache, status)
|
||||
{
|
||||
if ((this.behavior & MAYBE_NEW) && isnew) {
|
||||
onCacheEntryAvailable(entry, isnew, appCache, status) {
|
||||
if (this.behavior & MAYBE_NEW && isnew) {
|
||||
this.behavior |= NEW;
|
||||
}
|
||||
|
||||
|
|
@ -139,14 +150,14 @@ OpenCallback.prototype =
|
|||
|
||||
Assert.equal(isnew, !!(this.behavior & NEW));
|
||||
|
||||
if (this.behavior & (NOTFOUND|NOTWANTED)) {
|
||||
if (this.behavior & (NOTFOUND | NOTWANTED)) {
|
||||
Assert.equal(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
|
||||
Assert.ok(!entry);
|
||||
if (this.behavior & THROWAVAIL)
|
||||
if (this.behavior & THROWAVAIL) {
|
||||
this.throwAndNotify(entry);
|
||||
}
|
||||
this.goon(entry);
|
||||
}
|
||||
else if (this.behavior & (NEW|RECREATE)) {
|
||||
} else if (this.behavior & (NEW | RECREATE)) {
|
||||
Assert.ok(!!entry);
|
||||
|
||||
if (this.behavior & RECREATE) {
|
||||
|
|
@ -154,18 +165,19 @@ OpenCallback.prototype =
|
|||
Assert.ok(!!entry);
|
||||
}
|
||||
|
||||
if (this.behavior & THROWAVAIL)
|
||||
if (this.behavior & THROWAVAIL) {
|
||||
this.throwAndNotify(entry);
|
||||
}
|
||||
|
||||
if (!(this.behavior & WAITFORWRITE))
|
||||
if (!(this.behavior & WAITFORWRITE)) {
|
||||
this.goon(entry);
|
||||
}
|
||||
|
||||
if (!(this.behavior & PARTIAL)) {
|
||||
try {
|
||||
entry.getMetaDataElement("meto");
|
||||
Assert.ok(false);
|
||||
}
|
||||
catch (ex) {}
|
||||
} catch (ex) {}
|
||||
}
|
||||
|
||||
if (this.behavior & DONTFILL) {
|
||||
|
|
@ -174,21 +186,25 @@ OpenCallback.prototype =
|
|||
}
|
||||
|
||||
var self = this;
|
||||
executeSoon(function() { // emulate network latency
|
||||
executeSoon(function() {
|
||||
// emulate network latency
|
||||
entry.setMetaDataElement("meto", self.workingMetadata);
|
||||
entry.metaDataReady();
|
||||
if (self.behavior & METAONLY) {
|
||||
// Since forcing GC/CC doesn't trigger OnWriterClosed, we have to set the entry valid manually :(
|
||||
if (!(self.behavior & DONTSETVALID))
|
||||
if (!(self.behavior & DONTSETVALID)) {
|
||||
entry.setValid();
|
||||
}
|
||||
|
||||
entry.close();
|
||||
if (self.behavior & WAITFORWRITE)
|
||||
if (self.behavior & WAITFORWRITE) {
|
||||
self.goon(entry);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
executeSoon(function() { // emulate more network latency
|
||||
executeSoon(function() {
|
||||
// emulate more network latency
|
||||
if (self.behavior & DOOMED) {
|
||||
LOG_C2(self, "checking doom state");
|
||||
try {
|
||||
|
|
@ -200,37 +216,40 @@ OpenCallback.prototype =
|
|||
} catch (ex) {
|
||||
Assert.ok(true);
|
||||
}
|
||||
if (self.behavior & WAITFORWRITE)
|
||||
if (self.behavior & WAITFORWRITE) {
|
||||
self.goon(entry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var offset = (self.behavior & PARTIAL)
|
||||
? entry.dataSize
|
||||
: 0;
|
||||
var offset = self.behavior & PARTIAL ? entry.dataSize : 0;
|
||||
LOG_C2(self, "openOutputStream @ " + offset);
|
||||
var os = entry.openOutputStream(offset, -1);
|
||||
LOG_C2(self, "writing data");
|
||||
var wrt = os.write(self.workingData, self.workingData.length);
|
||||
Assert.equal(wrt, self.workingData.length);
|
||||
os.close();
|
||||
if (self.behavior & WAITFORWRITE)
|
||||
if (self.behavior & WAITFORWRITE) {
|
||||
self.goon(entry);
|
||||
}
|
||||
|
||||
entry.close();
|
||||
})
|
||||
})
|
||||
}
|
||||
else { // NORMAL
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// NORMAL
|
||||
Assert.ok(!!entry);
|
||||
Assert.equal(entry.getMetaDataElement("meto"), this.workingMetadata);
|
||||
if (this.behavior & THROWAVAIL)
|
||||
if (this.behavior & THROWAVAIL) {
|
||||
this.throwAndNotify(entry);
|
||||
if (this.behavior & NOTIFYBEFOREREAD)
|
||||
}
|
||||
if (this.behavior & NOTIFYBEFOREREAD) {
|
||||
this.goon(entry, true);
|
||||
}
|
||||
|
||||
var wrapper = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
var wrapper = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
var self = this;
|
||||
pumpReadStream(entry.openInputStream(0), function(data) {
|
||||
Assert.equal(data, self.workingData);
|
||||
|
|
@ -241,16 +260,14 @@ OpenCallback.prototype =
|
|||
});
|
||||
}
|
||||
},
|
||||
selfCheck()
|
||||
{
|
||||
selfCheck() {
|
||||
LOG_C2(this, "selfCheck");
|
||||
|
||||
Assert.ok(this.onCheckPassed || (this.behavior & MAYBE_NEW));
|
||||
Assert.ok(this.onCheckPassed || this.behavior & MAYBE_NEW);
|
||||
Assert.ok(this.onAvailPassed);
|
||||
Assert.ok(this.onDataCheckPassed || (this.behavior & MAYBE_NEW));
|
||||
Assert.ok(this.onDataCheckPassed || this.behavior & MAYBE_NEW);
|
||||
},
|
||||
throwAndNotify(entry)
|
||||
{
|
||||
throwAndNotify(entry) {
|
||||
LOG_C2(this, "Throwing");
|
||||
var self = this;
|
||||
executeSoon(function() {
|
||||
|
|
@ -258,47 +275,59 @@ OpenCallback.prototype =
|
|||
self.goon(entry);
|
||||
});
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function OpenCallback(behavior, workingMetadata, workingData, goon)
|
||||
{
|
||||
function OpenCallback(behavior, workingMetadata, workingData, goon) {
|
||||
this.behavior = behavior;
|
||||
this.workingMetadata = workingMetadata;
|
||||
this.workingData = workingData;
|
||||
this.goon = goon;
|
||||
this.onCheckPassed = (!!(behavior & (NEW|RECREATE)) || !workingMetadata) && !(behavior & NOTVALID);
|
||||
this.onCheckPassed =
|
||||
(!!(behavior & (NEW | RECREATE)) || !workingMetadata) &&
|
||||
!(behavior & NOTVALID);
|
||||
this.onAvailPassed = false;
|
||||
this.onDataCheckPassed = !!(behavior & (NEW|RECREATE|NOTWANTED)) || !workingMetadata;
|
||||
this.onDataCheckPassed =
|
||||
!!(behavior & (NEW | RECREATE | NOTWANTED)) || !workingMetadata;
|
||||
callbacks.push(this);
|
||||
this.order = callbacks.length;
|
||||
}
|
||||
|
||||
VisitCallback.prototype =
|
||||
{
|
||||
VisitCallback.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsICacheStorageVisitor"]),
|
||||
onCacheStorageInfo(num, consumption)
|
||||
{
|
||||
onCacheStorageInfo(num, consumption) {
|
||||
LOG_C2(this, "onCacheStorageInfo: num=" + num + ", size=" + consumption);
|
||||
Assert.equal(this.num, num);
|
||||
Assert.equal(this.consumption, consumption);
|
||||
if (!this.entries)
|
||||
if (!this.entries) {
|
||||
this.notify();
|
||||
}
|
||||
},
|
||||
onCacheEntryInfo(aURI, aIdEnhance, aDataSize, aFetchCount, aLastModifiedTime, aExpirationTime,
|
||||
aPinned, aInfo)
|
||||
{
|
||||
var key = (aIdEnhance ? (aIdEnhance + ":") : "") + aURI.asciiSpec;
|
||||
onCacheEntryInfo(
|
||||
aURI,
|
||||
aIdEnhance,
|
||||
aDataSize,
|
||||
aFetchCount,
|
||||
aLastModifiedTime,
|
||||
aExpirationTime,
|
||||
aPinned,
|
||||
aInfo
|
||||
) {
|
||||
var key = (aIdEnhance ? aIdEnhance + ":" : "") + aURI.asciiSpec;
|
||||
LOG_C2(this, "onCacheEntryInfo: key=" + key);
|
||||
|
||||
function findCacheIndex(element) {
|
||||
if (typeof(element) === "string") {
|
||||
if (typeof element === "string") {
|
||||
return element === key;
|
||||
} else if (typeof(element) === "object") {
|
||||
return element.uri === key &&
|
||||
element.lci.isAnonymous === aInfo.isAnonymous &&
|
||||
ChromeUtils.isOriginAttributesEqual(element.lci.originAttributes,
|
||||
aInfo.originAttributes);
|
||||
} else if (typeof element === "object") {
|
||||
return (
|
||||
element.uri === key &&
|
||||
element.lci.isAnonymous === aInfo.isAnonymous &&
|
||||
ChromeUtils.isOriginAttributesEqual(
|
||||
element.lci.originAttributes,
|
||||
aInfo.originAttributes
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -311,28 +340,25 @@ VisitCallback.prototype =
|
|||
|
||||
this.entries.splice(index, 1);
|
||||
},
|
||||
onCacheEntryVisitCompleted()
|
||||
{
|
||||
onCacheEntryVisitCompleted() {
|
||||
LOG_C2(this, "onCacheEntryVisitCompleted");
|
||||
if (this.entries)
|
||||
if (this.entries) {
|
||||
Assert.equal(this.entries.length, 0);
|
||||
}
|
||||
this.notify();
|
||||
},
|
||||
notify()
|
||||
{
|
||||
notify() {
|
||||
Assert.ok(!!this.goon);
|
||||
var goon = this.goon;
|
||||
this.goon = null;
|
||||
executeSoon(goon);
|
||||
},
|
||||
selfCheck()
|
||||
{
|
||||
selfCheck() {
|
||||
Assert.ok(!this.entries || !this.entries.length);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function VisitCallback(num, consumption, entries, goon)
|
||||
{
|
||||
function VisitCallback(num, consumption, entries, goon) {
|
||||
this.num = num;
|
||||
this.consumption = consumption;
|
||||
this.entries = entries;
|
||||
|
|
@ -341,64 +367,61 @@ function VisitCallback(num, consumption, entries, goon)
|
|||
this.order = callbacks.length;
|
||||
}
|
||||
|
||||
EvictionCallback.prototype =
|
||||
{
|
||||
EvictionCallback.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsICacheEntryDoomCallback"]),
|
||||
onCacheEntryDoomed(result)
|
||||
{
|
||||
onCacheEntryDoomed(result) {
|
||||
Assert.equal(this.expectedSuccess, result == Cr.NS_OK);
|
||||
this.goon();
|
||||
},
|
||||
selfCheck() {}
|
||||
}
|
||||
selfCheck() {},
|
||||
};
|
||||
|
||||
function EvictionCallback(success, goon)
|
||||
{
|
||||
function EvictionCallback(success, goon) {
|
||||
this.expectedSuccess = success;
|
||||
this.goon = goon;
|
||||
callbacks.push(this);
|
||||
this.order = callbacks.length;
|
||||
}
|
||||
|
||||
MultipleCallbacks.prototype =
|
||||
{
|
||||
fired()
|
||||
{
|
||||
if (--this.pending == 0)
|
||||
{
|
||||
MultipleCallbacks.prototype = {
|
||||
fired() {
|
||||
if (--this.pending == 0) {
|
||||
var self = this;
|
||||
if (this.delayed)
|
||||
executeSoon(function() { self.goon(); });
|
||||
else
|
||||
if (this.delayed) {
|
||||
executeSoon(function() {
|
||||
self.goon();
|
||||
});
|
||||
} else {
|
||||
this.goon();
|
||||
}
|
||||
}
|
||||
},
|
||||
add()
|
||||
{
|
||||
add() {
|
||||
++this.pending;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function MultipleCallbacks(number, goon, delayed)
|
||||
{
|
||||
function MultipleCallbacks(number, goon, delayed) {
|
||||
this.pending = number;
|
||||
this.goon = goon;
|
||||
this.delayed = delayed;
|
||||
}
|
||||
|
||||
function wait_for_cache_index(continue_func)
|
||||
{
|
||||
function wait_for_cache_index(continue_func) {
|
||||
// This callback will not fire before the index is in the ready state. nsICacheStorage.exists() will
|
||||
// no longer throw after this point.
|
||||
get_cache_service().asyncGetDiskConsumption({
|
||||
onNetworkCacheDiskConsumption() { continue_func(); },
|
||||
onNetworkCacheDiskConsumption() {
|
||||
continue_func();
|
||||
},
|
||||
// eslint-disable-next-line mozilla/use-chromeutils-generateqi
|
||||
QueryInterface() { return this; }
|
||||
QueryInterface() {
|
||||
return this;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function finish_cache2_test()
|
||||
{
|
||||
function finish_cache2_test() {
|
||||
callbacks.forEach(function(callback, index) {
|
||||
callback.selfCheck();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
*/
|
||||
function read_stream(stream, count) {
|
||||
/* assume stream has non-ASCII data */
|
||||
var wrapper =
|
||||
Cc["@mozilla.org/binaryinputstream;1"]
|
||||
.createInstance(Ci.nsIBinaryInputStream);
|
||||
var wrapper = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
|
||||
Ci.nsIBinaryInputStream
|
||||
);
|
||||
wrapper.setInputStream(stream);
|
||||
/* JS methods can be called with a maximum of 65535 arguments, and input
|
||||
streams don't have to return all the data they make .available() when
|
||||
|
|
@ -15,10 +15,11 @@ function read_stream(stream, count) {
|
|||
var bytes = wrapper.readByteArray(Math.min(65535, count));
|
||||
data.push(String.fromCharCode.apply(null, bytes));
|
||||
count -= bytes.length;
|
||||
if (bytes.length == 0)
|
||||
if (bytes.length == 0) {
|
||||
do_throw("Nothing read from input stream!");
|
||||
}
|
||||
}
|
||||
return data.join('');
|
||||
return data.join("");
|
||||
}
|
||||
|
||||
const CL_EXPECT_FAILURE = 0x1;
|
||||
|
|
@ -64,50 +65,64 @@ ChannelListener.prototype = {
|
|||
_contentLen: -1,
|
||||
_lastEvent: 0,
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIStreamListener", "nsIRequestObserver"]),
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIStreamListener",
|
||||
"nsIRequestObserver",
|
||||
]),
|
||||
|
||||
onStartRequest(request) {
|
||||
try {
|
||||
if (this._got_onstartrequest)
|
||||
if (this._got_onstartrequest) {
|
||||
do_throw("Got second onStartRequest event!");
|
||||
}
|
||||
this._got_onstartrequest = true;
|
||||
this._lastEvent = Date.now();
|
||||
|
||||
try {
|
||||
this._isFromCache = request.QueryInterface(Ci.nsICacheInfoChannel).isFromCache();
|
||||
this._isFromCache = request
|
||||
.QueryInterface(Ci.nsICacheInfoChannel)
|
||||
.isFromCache();
|
||||
} catch (e) {}
|
||||
|
||||
var thrown = false;
|
||||
try {
|
||||
this._cacheEntryId = request.QueryInterface(Ci.nsICacheInfoChannel).getCacheEntryId();
|
||||
this._cacheEntryId = request
|
||||
.QueryInterface(Ci.nsICacheInfoChannel)
|
||||
.getCacheEntryId();
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
if (this._isFromCache && thrown)
|
||||
if (this._isFromCache && thrown) {
|
||||
do_throw("Should get a CacheEntryId");
|
||||
else if (!this._isFromCache && !thrown)
|
||||
} else if (!this._isFromCache && !thrown) {
|
||||
do_throw("Shouldn't get a CacheEntryId");
|
||||
}
|
||||
|
||||
request.QueryInterface(Ci.nsIChannel);
|
||||
try {
|
||||
this._contentLen = request.contentLength;
|
||||
}
|
||||
catch (ex) {
|
||||
if (!(this._flags & (CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL)))
|
||||
} catch (ex) {
|
||||
if (!(this._flags & (CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL))) {
|
||||
do_throw("Could not get contentLength");
|
||||
}
|
||||
}
|
||||
if (!request.isPending())
|
||||
if (!request.isPending()) {
|
||||
do_throw("request reports itself as not pending from onStartRequest!");
|
||||
if (this._contentLen == -1 && !(this._flags & (CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL)))
|
||||
}
|
||||
if (
|
||||
this._contentLen == -1 &&
|
||||
!(this._flags & (CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL))
|
||||
) {
|
||||
do_throw("Content length is unknown in onStartRequest!");
|
||||
}
|
||||
|
||||
if ((this._flags & CL_FROM_CACHE)) {
|
||||
if (this._flags & CL_FROM_CACHE) {
|
||||
request.QueryInterface(Ci.nsICachingChannel);
|
||||
if (!request.isFromCache()) {
|
||||
do_throw("Response is not from the cache (CL_FROM_CACHE)");
|
||||
}
|
||||
}
|
||||
if ((this._flags & CL_NOT_FROM_CACHE)) {
|
||||
if (this._flags & CL_NOT_FROM_CACHE) {
|
||||
request.QueryInterface(Ci.nsICachingChannel);
|
||||
if (request.isFromCache()) {
|
||||
do_throw("Response is from the cache (CL_NOT_FROM_CACHE)");
|
||||
|
|
@ -116,7 +131,9 @@ ChannelListener.prototype = {
|
|||
|
||||
if (this._flags & CL_SUSPEND) {
|
||||
request.suspend();
|
||||
do_timeout(SUSPEND_DELAY, function() { request.resume(); });
|
||||
do_timeout(SUSPEND_DELAY, function() {
|
||||
request.resume();
|
||||
});
|
||||
}
|
||||
} catch (ex) {
|
||||
do_throw("Error in onStartRequest: " + ex);
|
||||
|
|
@ -127,24 +144,35 @@ ChannelListener.prototype = {
|
|||
try {
|
||||
let current = Date.now();
|
||||
|
||||
if (!this._got_onstartrequest)
|
||||
if (!this._got_onstartrequest) {
|
||||
do_throw("onDataAvailable without onStartRequest event!");
|
||||
if (this._got_onstoprequest)
|
||||
}
|
||||
if (this._got_onstoprequest) {
|
||||
do_throw("onDataAvailable after onStopRequest event!");
|
||||
if (!request.isPending())
|
||||
}
|
||||
if (!request.isPending()) {
|
||||
do_throw("request reports itself as not pending from onDataAvailable!");
|
||||
if (this._flags & CL_EXPECT_FAILURE)
|
||||
}
|
||||
if (this._flags & CL_EXPECT_FAILURE) {
|
||||
do_throw("Got data despite expecting a failure");
|
||||
}
|
||||
|
||||
if (current - this._lastEvent >= SUSPEND_DELAY &&
|
||||
!(this._flags & CL_EXPECT_3S_DELAY))
|
||||
do_throw("Data received after significant unexpected delay");
|
||||
else if (current - this._lastEvent < SUSPEND_DELAY &&
|
||||
this._flags & CL_EXPECT_3S_DELAY)
|
||||
if (
|
||||
current - this._lastEvent >= SUSPEND_DELAY &&
|
||||
!(this._flags & CL_EXPECT_3S_DELAY)
|
||||
) {
|
||||
do_throw("Data received after significant unexpected delay");
|
||||
} else if (
|
||||
current - this._lastEvent < SUSPEND_DELAY &&
|
||||
this._flags & CL_EXPECT_3S_DELAY
|
||||
) {
|
||||
do_throw("Data received sooner than expected");
|
||||
else if (current - this._lastEvent >= SUSPEND_DELAY &&
|
||||
this._flags & CL_EXPECT_3S_DELAY)
|
||||
this._flags &= ~CL_EXPECT_3S_DELAY; // No more delays expected
|
||||
} else if (
|
||||
current - this._lastEvent >= SUSPEND_DELAY &&
|
||||
this._flags & CL_EXPECT_3S_DELAY
|
||||
) {
|
||||
this._flags &= ~CL_EXPECT_3S_DELAY;
|
||||
} // No more delays expected
|
||||
|
||||
this._buffer = this._buffer.concat(read_stream(stream, count));
|
||||
this._lastEvent = current;
|
||||
|
|
@ -156,43 +184,65 @@ ChannelListener.prototype = {
|
|||
onStopRequest(request, status) {
|
||||
try {
|
||||
var success = Components.isSuccessCode(status);
|
||||
if (!this._got_onstartrequest)
|
||||
if (!this._got_onstartrequest) {
|
||||
do_throw("onStopRequest without onStartRequest event!");
|
||||
if (this._got_onstoprequest)
|
||||
}
|
||||
if (this._got_onstoprequest) {
|
||||
do_throw("Got second onStopRequest event!");
|
||||
}
|
||||
this._got_onstoprequest = true;
|
||||
if ((this._flags & (CL_EXPECT_FAILURE | CL_EXPECT_LATE_FAILURE)) && success)
|
||||
do_throw("Should have failed to load URL (status is " + status.toString(16) + ")");
|
||||
else if (!(this._flags & (CL_EXPECT_FAILURE | CL_EXPECT_LATE_FAILURE)) && !success)
|
||||
if (
|
||||
this._flags & (CL_EXPECT_FAILURE | CL_EXPECT_LATE_FAILURE) &&
|
||||
success
|
||||
) {
|
||||
do_throw(
|
||||
"Should have failed to load URL (status is " +
|
||||
status.toString(16) +
|
||||
")"
|
||||
);
|
||||
} else if (
|
||||
!(this._flags & (CL_EXPECT_FAILURE | CL_EXPECT_LATE_FAILURE)) &&
|
||||
!success
|
||||
) {
|
||||
do_throw("Failed to load URL: " + status.toString(16));
|
||||
if (status != request.status)
|
||||
}
|
||||
if (status != request.status) {
|
||||
do_throw("request.status does not match status arg to onStopRequest!");
|
||||
if (request.isPending())
|
||||
}
|
||||
if (request.isPending()) {
|
||||
do_throw("request reports itself as pending from onStopRequest!");
|
||||
if (!(this._flags & (CL_EXPECT_FAILURE | CL_EXPECT_LATE_FAILURE | CL_IGNORE_CL)) &&
|
||||
!(this._flags & CL_EXPECT_GZIP) &&
|
||||
this._contentLen != -1)
|
||||
Assert.equal(this._buffer.length, this._contentLen)
|
||||
}
|
||||
if (
|
||||
!(
|
||||
this._flags &
|
||||
(CL_EXPECT_FAILURE | CL_EXPECT_LATE_FAILURE | CL_IGNORE_CL)
|
||||
) &&
|
||||
!(this._flags & CL_EXPECT_GZIP) &&
|
||||
this._contentLen != -1
|
||||
) {
|
||||
Assert.equal(this._buffer.length, this._contentLen);
|
||||
}
|
||||
} catch (ex) {
|
||||
do_throw("Error in onStopRequest: " + ex);
|
||||
}
|
||||
try {
|
||||
this._closure(request,
|
||||
this._buffer,
|
||||
this._closurectx,
|
||||
this._isFromCache,
|
||||
this._cacheEntryId);
|
||||
this._closure(
|
||||
request,
|
||||
this._buffer,
|
||||
this._closurectx,
|
||||
this._isFromCache,
|
||||
this._cacheEntryId
|
||||
);
|
||||
this._closurectx = null;
|
||||
} catch (ex) {
|
||||
do_throw("Error in closure function: " + ex);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var ES_ABORT_REDIRECT = 0x01;
|
||||
|
||||
function ChannelEventSink(flags)
|
||||
{
|
||||
function ChannelEventSink(flags) {
|
||||
this._flags = flags;
|
||||
}
|
||||
|
||||
|
|
@ -200,17 +250,19 @@ ChannelEventSink.prototype = {
|
|||
QueryInterface: ChromeUtils.generateQI(["nsIInterfaceRequestor"]),
|
||||
|
||||
getInterface(iid) {
|
||||
if (iid.equals(Ci.nsIChannelEventSink))
|
||||
if (iid.equals(Ci.nsIChannelEventSink)) {
|
||||
return this;
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
|
||||
if (this._flags & ES_ABORT_REDIRECT)
|
||||
if (this._flags & ES_ABORT_REDIRECT) {
|
||||
throw Cr.NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
callback.onRedirectVerifyCallback(Cr.NS_OK);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -222,12 +274,13 @@ function OriginAttributes(inIsolatedMozBrowser, privateId) {
|
|||
}
|
||||
OriginAttributes.prototype = {
|
||||
inIsolatedMozBrowser: false,
|
||||
privateBrowsingId: 0
|
||||
privateBrowsingId: 0,
|
||||
};
|
||||
|
||||
function readFile(file) {
|
||||
let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
|
||||
Ci.nsIFileInputStream
|
||||
);
|
||||
fstream.init(file, -1, 0, 0);
|
||||
let data = NetUtil.readInputStreamToString(fstream, fstream.available());
|
||||
fstream.close();
|
||||
|
|
@ -237,9 +290,8 @@ function readFile(file) {
|
|||
function addCertFromFile(certdb, filename, trustString) {
|
||||
let certFile = do_get_file(filename, false);
|
||||
let pem = readFile(certFile)
|
||||
.replace(/-----BEGIN CERTIFICATE-----/, "")
|
||||
.replace(/-----END CERTIFICATE-----/, "")
|
||||
.replace(/[\r\n]/g, "");
|
||||
.replace(/-----BEGIN CERTIFICATE-----/, "")
|
||||
.replace(/-----END CERTIFICATE-----/, "")
|
||||
.replace(/[\r\n]/g, "");
|
||||
certdb.addCertFromBase64(pem, trustString);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,37 +2,46 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "cookies",
|
||||
"@mozilla.org/cookieService;1",
|
||||
"nsICookieService");
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "cookiemgr",
|
||||
"@mozilla.org/cookiemanager;1",
|
||||
"nsICookieManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
Services,
|
||||
"cookies",
|
||||
"@mozilla.org/cookieService;1",
|
||||
"nsICookieService"
|
||||
);
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
Services,
|
||||
"cookiemgr",
|
||||
"@mozilla.org/cookiemanager;1",
|
||||
"nsICookieManager"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "etld",
|
||||
"@mozilla.org/network/effective-tld-service;1",
|
||||
"nsIEffectiveTLDService");
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
Services,
|
||||
"etld",
|
||||
"@mozilla.org/network/effective-tld-service;1",
|
||||
"nsIEffectiveTLDService"
|
||||
);
|
||||
|
||||
function do_check_throws(f, result, stack)
|
||||
{
|
||||
if (!stack)
|
||||
function do_check_throws(f, result, stack) {
|
||||
if (!stack) {
|
||||
stack = Components.stack.caller;
|
||||
}
|
||||
|
||||
try {
|
||||
f();
|
||||
} catch (exc) {
|
||||
if (exc.result == result)
|
||||
if (exc.result == result) {
|
||||
return;
|
||||
}
|
||||
do_throw("expected result " + result + ", caught " + exc, stack);
|
||||
}
|
||||
do_throw("expected result " + result + ", none thrown", stack);
|
||||
}
|
||||
|
||||
// Helper to step a generator function and catch a StopIteration exception.
|
||||
function do_run_generator(generator)
|
||||
{
|
||||
function do_run_generator(generator) {
|
||||
try {
|
||||
generator.next();
|
||||
} catch (e) {
|
||||
|
|
@ -41,8 +50,7 @@ function do_run_generator(generator)
|
|||
}
|
||||
|
||||
// Helper to finish a generator function test.
|
||||
function do_finish_generator_test(generator)
|
||||
{
|
||||
function do_finish_generator_test(generator) {
|
||||
executeSoon(function() {
|
||||
generator.return();
|
||||
do_test_finished();
|
||||
|
|
@ -57,19 +65,20 @@ function _observer(generator, topic) {
|
|||
}
|
||||
|
||||
_observer.prototype = {
|
||||
observe (subject, topic, data) {
|
||||
observe(subject, topic, data) {
|
||||
Assert.equal(this.topic, topic);
|
||||
|
||||
Services.obs.removeObserver(this, this.topic);
|
||||
|
||||
// Continue executing the generator function.
|
||||
if (this.generator)
|
||||
if (this.generator) {
|
||||
do_run_generator(this.generator);
|
||||
}
|
||||
|
||||
this.generator = null;
|
||||
this.topic = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Close the cookie database. If a generator is supplied, it will be invoked
|
||||
// once the close is complete.
|
||||
|
|
@ -96,7 +105,14 @@ function do_load_profile(generator) {
|
|||
// Set a single session cookie using http and test the cookie count
|
||||
// against 'expected'
|
||||
function do_set_single_http_cookie(uri, channel, expected) {
|
||||
Services.cookies.setCookieStringFromHttp(uri, null, null, "foo=bar", null, channel);
|
||||
Services.cookies.setCookieStringFromHttp(
|
||||
uri,
|
||||
null,
|
||||
null,
|
||||
"foo=bar",
|
||||
null,
|
||||
channel
|
||||
);
|
||||
Assert.equal(Services.cookiemgr.countCookiesFromHost(uri.host), expected);
|
||||
}
|
||||
|
||||
|
|
@ -112,10 +128,24 @@ function do_set_cookies(uri, channel, session, expected) {
|
|||
Services.cookies.setCookieString(uri, null, "can=has" + suffix, channel);
|
||||
Assert.equal(Services.cookiemgr.countCookiesFromHost(uri.host), expected[1]);
|
||||
// without channel, from http
|
||||
Services.cookies.setCookieStringFromHttp(uri, null, null, "cheez=burger" + suffix, null, null);
|
||||
Services.cookies.setCookieStringFromHttp(
|
||||
uri,
|
||||
null,
|
||||
null,
|
||||
"cheez=burger" + suffix,
|
||||
null,
|
||||
null
|
||||
);
|
||||
Assert.equal(Services.cookiemgr.countCookiesFromHost(uri.host), expected[2]);
|
||||
// with channel, from http
|
||||
Services.cookies.setCookieStringFromHttp(uri, null, null, "hot=dog" + suffix, null, channel);
|
||||
Services.cookies.setCookieStringFromHttp(
|
||||
uri,
|
||||
null,
|
||||
null,
|
||||
"hot=dog" + suffix,
|
||||
null,
|
||||
channel
|
||||
);
|
||||
Assert.equal(Services.cookiemgr.countCookiesFromHost(uri.host), expected[3]);
|
||||
}
|
||||
|
||||
|
|
@ -133,17 +163,18 @@ function do_count_cookies() {
|
|||
}
|
||||
|
||||
// Helper object to store cookie data.
|
||||
function Cookie(name,
|
||||
value,
|
||||
host,
|
||||
path,
|
||||
expiry,
|
||||
lastAccessed,
|
||||
creationTime,
|
||||
isSession,
|
||||
isSecure,
|
||||
isHttpOnly)
|
||||
{
|
||||
function Cookie(
|
||||
name,
|
||||
value,
|
||||
host,
|
||||
path,
|
||||
expiry,
|
||||
lastAccessed,
|
||||
creationTime,
|
||||
isSession,
|
||||
isSecure,
|
||||
isHttpOnly
|
||||
) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.host = host;
|
||||
|
|
@ -155,33 +186,35 @@ function Cookie(name,
|
|||
this.isSecure = isSecure;
|
||||
this.isHttpOnly = isHttpOnly;
|
||||
|
||||
let strippedHost = host.charAt(0) == '.' ? host.slice(1) : host;
|
||||
let strippedHost = host.charAt(0) == "." ? host.slice(1) : host;
|
||||
|
||||
try {
|
||||
this.baseDomain = Services.etld.getBaseDomainFromHost(strippedHost);
|
||||
} catch (e) {
|
||||
if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS)
|
||||
if (
|
||||
e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
|
||||
) {
|
||||
this.baseDomain = strippedHost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Object representing a database connection and associated statements. The
|
||||
// implementation varies depending on schema version.
|
||||
function CookieDatabaseConnection(file, schema)
|
||||
{
|
||||
function CookieDatabaseConnection(file, schema) {
|
||||
// Manually generate a cookies.sqlite file with appropriate rows, columns,
|
||||
// and schema version. If it already exists, just set up our statements.
|
||||
let exists = file.exists();
|
||||
|
||||
this.db = Services.storage.openDatabase(file);
|
||||
this.schema = schema;
|
||||
if (!exists)
|
||||
if (!exists) {
|
||||
this.db.schemaVersion = schema;
|
||||
}
|
||||
|
||||
switch (schema) {
|
||||
case 1:
|
||||
{
|
||||
case 1: {
|
||||
if (!exists) {
|
||||
this.db.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies ( \
|
||||
|
|
@ -192,7 +225,8 @@ function CookieDatabaseConnection(file, schema)
|
|||
path TEXT, \
|
||||
expiry INTEGER, \
|
||||
isSecure INTEGER, \
|
||||
isHttpOnly INTEGER)");
|
||||
isHttpOnly INTEGER)"
|
||||
);
|
||||
}
|
||||
|
||||
this.stmtInsert = this.db.createStatement(
|
||||
|
|
@ -213,16 +247,17 @@ function CookieDatabaseConnection(file, schema)
|
|||
:path, \
|
||||
:expiry, \
|
||||
:isSecure, \
|
||||
:isHttpOnly)");
|
||||
:isHttpOnly)"
|
||||
);
|
||||
|
||||
this.stmtDelete = this.db.createStatement(
|
||||
"DELETE FROM moz_cookies WHERE id = :id");
|
||||
"DELETE FROM moz_cookies WHERE id = :id"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
case 2: {
|
||||
if (!exists) {
|
||||
this.db.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies ( \
|
||||
|
|
@ -234,7 +269,8 @@ function CookieDatabaseConnection(file, schema)
|
|||
expiry INTEGER, \
|
||||
lastAccessed INTEGER, \
|
||||
isSecure INTEGER, \
|
||||
isHttpOnly INTEGER)");
|
||||
isHttpOnly INTEGER)"
|
||||
);
|
||||
}
|
||||
|
||||
this.stmtInsert = this.db.createStatement(
|
||||
|
|
@ -257,19 +293,21 @@ function CookieDatabaseConnection(file, schema)
|
|||
:expiry, \
|
||||
:lastAccessed, \
|
||||
:isSecure, \
|
||||
:isHttpOnly)");
|
||||
:isHttpOnly)"
|
||||
);
|
||||
|
||||
this.stmtDelete = this.db.createStatement(
|
||||
"DELETE FROM moz_cookies WHERE id = :id");
|
||||
"DELETE FROM moz_cookies WHERE id = :id"
|
||||
);
|
||||
|
||||
this.stmtUpdate = this.db.createStatement(
|
||||
"UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id");
|
||||
"UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
case 3: {
|
||||
if (!exists) {
|
||||
this.db.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies ( \
|
||||
|
|
@ -282,10 +320,12 @@ function CookieDatabaseConnection(file, schema)
|
|||
expiry INTEGER, \
|
||||
lastAccessed INTEGER, \
|
||||
isSecure INTEGER, \
|
||||
isHttpOnly INTEGER)");
|
||||
isHttpOnly INTEGER)"
|
||||
);
|
||||
|
||||
this.db.executeSimpleSQL(
|
||||
"CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)");
|
||||
"CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)"
|
||||
);
|
||||
}
|
||||
|
||||
this.stmtInsert = this.db.createStatement(
|
||||
|
|
@ -310,19 +350,21 @@ function CookieDatabaseConnection(file, schema)
|
|||
:expiry, \
|
||||
:lastAccessed, \
|
||||
:isSecure, \
|
||||
:isHttpOnly)");
|
||||
:isHttpOnly)"
|
||||
);
|
||||
|
||||
this.stmtDelete = this.db.createStatement(
|
||||
"DELETE FROM moz_cookies WHERE id = :id");
|
||||
"DELETE FROM moz_cookies WHERE id = :id"
|
||||
);
|
||||
|
||||
this.stmtUpdate = this.db.createStatement(
|
||||
"UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id");
|
||||
"UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
case 4: {
|
||||
if (!exists) {
|
||||
this.db.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies ( \
|
||||
|
|
@ -337,13 +379,14 @@ function CookieDatabaseConnection(file, schema)
|
|||
creationTime INTEGER, \
|
||||
isSecure INTEGER, \
|
||||
isHttpOnly INTEGER \
|
||||
CONSTRAINT moz_uniqueid UNIQUE (name, host, path))");
|
||||
CONSTRAINT moz_uniqueid UNIQUE (name, host, path))"
|
||||
);
|
||||
|
||||
this.db.executeSimpleSQL(
|
||||
"CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)");
|
||||
"CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)"
|
||||
);
|
||||
|
||||
this.db.executeSimpleSQL(
|
||||
"PRAGMA journal_mode = WAL");
|
||||
this.db.executeSimpleSQL("PRAGMA journal_mode = WAL");
|
||||
}
|
||||
|
||||
this.stmtInsert = this.db.createStatement(
|
||||
|
|
@ -368,162 +411,160 @@ function CookieDatabaseConnection(file, schema)
|
|||
:lastAccessed, \
|
||||
:creationTime, \
|
||||
:isSecure, \
|
||||
:isHttpOnly)");
|
||||
:isHttpOnly)"
|
||||
);
|
||||
|
||||
this.stmtDelete = this.db.createStatement(
|
||||
"DELETE FROM moz_cookies \
|
||||
WHERE name = :name AND host = :host AND path = :path");
|
||||
WHERE name = :name AND host = :host AND path = :path"
|
||||
);
|
||||
|
||||
this.stmtUpdate = this.db.createStatement(
|
||||
"UPDATE moz_cookies SET lastAccessed = :lastAccessed \
|
||||
WHERE name = :name AND host = :host AND path = :path");
|
||||
WHERE name = :name AND host = :host AND path = :path"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
}
|
||||
}
|
||||
|
||||
CookieDatabaseConnection.prototype =
|
||||
{
|
||||
insertCookie(cookie)
|
||||
{
|
||||
if (!(cookie instanceof Cookie))
|
||||
CookieDatabaseConnection.prototype = {
|
||||
insertCookie(cookie) {
|
||||
if (!(cookie instanceof Cookie)) {
|
||||
do_throw("not a cookie");
|
||||
}
|
||||
|
||||
switch (this.schema)
|
||||
{
|
||||
case 1:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
switch (this.schema) {
|
||||
case 1:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
case 2:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
case 3:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
this.stmtInsert.bindByName("creationTime", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
case 4:
|
||||
this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
this.stmtInsert.bindByName("value", cookie.value);
|
||||
this.stmtInsert.bindByName("host", cookie.host);
|
||||
this.stmtInsert.bindByName("path", cookie.path);
|
||||
this.stmtInsert.bindByName("expiry", cookie.expiry);
|
||||
this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
this.stmtInsert.bindByName("creationTime", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("isSecure", cookie.isSecure);
|
||||
this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
|
||||
break;
|
||||
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
}
|
||||
|
||||
do_execute_stmt(this.stmtInsert);
|
||||
},
|
||||
|
||||
deleteCookie(cookie)
|
||||
{
|
||||
if (!(cookie instanceof Cookie))
|
||||
deleteCookie(cookie) {
|
||||
if (!(cookie instanceof Cookie)) {
|
||||
do_throw("not a cookie");
|
||||
}
|
||||
|
||||
switch (this.db.schemaVersion)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
this.stmtDelete.bindByName("id", cookie.creationTime);
|
||||
break;
|
||||
switch (this.db.schemaVersion) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
this.stmtDelete.bindByName("id", cookie.creationTime);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
this.stmtDelete.bindByName("name", cookie.name);
|
||||
this.stmtDelete.bindByName("host", cookie.host);
|
||||
this.stmtDelete.bindByName("path", cookie.path);
|
||||
break;
|
||||
case 4:
|
||||
this.stmtDelete.bindByName("name", cookie.name);
|
||||
this.stmtDelete.bindByName("host", cookie.host);
|
||||
this.stmtDelete.bindByName("path", cookie.path);
|
||||
break;
|
||||
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
}
|
||||
|
||||
do_execute_stmt(this.stmtDelete);
|
||||
},
|
||||
|
||||
updateCookie(cookie)
|
||||
{
|
||||
if (!(cookie instanceof Cookie))
|
||||
updateCookie(cookie) {
|
||||
if (!(cookie instanceof Cookie)) {
|
||||
do_throw("not a cookie");
|
||||
}
|
||||
|
||||
switch (this.db.schemaVersion)
|
||||
{
|
||||
case 1:
|
||||
do_throw("can't update a schema 1 cookie!");
|
||||
switch (this.db.schemaVersion) {
|
||||
case 1:
|
||||
do_throw("can't update a schema 1 cookie!");
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
this.stmtUpdate.bindByName("id", cookie.creationTime);
|
||||
this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
this.stmtUpdate.bindByName("id", cookie.creationTime);
|
||||
this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
this.stmtDelete.bindByName("name", cookie.name);
|
||||
this.stmtDelete.bindByName("host", cookie.host);
|
||||
this.stmtDelete.bindByName("path", cookie.path);
|
||||
this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
break;
|
||||
case 4:
|
||||
this.stmtDelete.bindByName("name", cookie.name);
|
||||
this.stmtDelete.bindByName("host", cookie.host);
|
||||
this.stmtDelete.bindByName("path", cookie.path);
|
||||
this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
|
||||
break;
|
||||
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
default:
|
||||
do_throw("unrecognized schemaVersion!");
|
||||
}
|
||||
|
||||
do_execute_stmt(this.stmtUpdate);
|
||||
},
|
||||
|
||||
close()
|
||||
{
|
||||
close() {
|
||||
this.stmtInsert.finalize();
|
||||
this.stmtDelete.finalize();
|
||||
if (this.stmtUpdate)
|
||||
if (this.stmtUpdate) {
|
||||
this.stmtUpdate.finalize();
|
||||
}
|
||||
this.db.close();
|
||||
|
||||
this.stmtInsert = null;
|
||||
this.stmtDelete = null;
|
||||
this.stmtUpdate = null;
|
||||
this.db = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function do_get_cookie_file(profile)
|
||||
{
|
||||
function do_get_cookie_file(profile) {
|
||||
let file = profile.clone();
|
||||
file.append("cookies.sqlite");
|
||||
return file;
|
||||
|
|
@ -531,16 +572,15 @@ function do_get_cookie_file(profile)
|
|||
|
||||
// Count the cookies from 'host' in a database. If 'host' is null, count all
|
||||
// cookies.
|
||||
function do_count_cookies_in_db(connection, host)
|
||||
{
|
||||
function do_count_cookies_in_db(connection, host) {
|
||||
let select = null;
|
||||
if (host) {
|
||||
select = connection.createStatement(
|
||||
"SELECT COUNT(1) FROM moz_cookies WHERE host = :host");
|
||||
"SELECT COUNT(1) FROM moz_cookies WHERE host = :host"
|
||||
);
|
||||
select.bindByName("host", host);
|
||||
} else {
|
||||
select = connection.createStatement(
|
||||
"SELECT COUNT(1) FROM moz_cookies");
|
||||
select = connection.createStatement("SELECT COUNT(1) FROM moz_cookies");
|
||||
}
|
||||
|
||||
select.executeStep();
|
||||
|
|
@ -551,8 +591,7 @@ function do_count_cookies_in_db(connection, host)
|
|||
}
|
||||
|
||||
// Execute 'stmt', ensuring that we reset it if it throws.
|
||||
function do_execute_stmt(stmt)
|
||||
{
|
||||
function do_execute_stmt(stmt) {
|
||||
try {
|
||||
stmt.executeStep();
|
||||
stmt.reset();
|
||||
|
|
|
|||
|
|
@ -1,40 +1,58 @@
|
|||
var CC = Components.Constructor;
|
||||
|
||||
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream");
|
||||
const ProtocolProxyService = CC("@mozilla.org/network/protocol-proxy-service;1",
|
||||
"nsIProtocolProxyService");
|
||||
var sts = Cc["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Ci.nsISocketTransportService);
|
||||
const BinaryInputStream = CC(
|
||||
"@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream"
|
||||
);
|
||||
const ProtocolProxyService = CC(
|
||||
"@mozilla.org/network/protocol-proxy-service;1",
|
||||
"nsIProtocolProxyService"
|
||||
);
|
||||
var sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(
|
||||
Ci.nsISocketTransportService
|
||||
);
|
||||
|
||||
function launchConnection(socks_vers, socks_port, dest_host, dest_port, dns)
|
||||
{
|
||||
function launchConnection(socks_vers, socks_port, dest_host, dest_port, dns) {
|
||||
var pi_flags = 0;
|
||||
if (dns == 'remote')
|
||||
if (dns == "remote") {
|
||||
pi_flags = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST;
|
||||
|
||||
}
|
||||
|
||||
var pps = new ProtocolProxyService();
|
||||
var pi = pps.newProxyInfo(socks_vers, 'localhost', socks_port, '', '',
|
||||
pi_flags, -1, null);
|
||||
var pi = pps.newProxyInfo(
|
||||
socks_vers,
|
||||
"localhost",
|
||||
socks_port,
|
||||
"",
|
||||
"",
|
||||
pi_flags,
|
||||
-1,
|
||||
null
|
||||
);
|
||||
var trans = sts.createTransport([], dest_host, dest_port, pi);
|
||||
var input = trans.openInputStream(Ci.nsITransport.OPEN_BLOCKING,0,0);
|
||||
var output = trans.openOutputStream(Ci.nsITransport.OPEN_BLOCKING,0,0);
|
||||
var input = trans.openInputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
|
||||
var output = trans.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
|
||||
var bin = new BinaryInputStream(input);
|
||||
var data = bin.readBytes(5);
|
||||
if (data == 'PING!') {
|
||||
print('client: got ping, sending pong.');
|
||||
output.write('PONG!', 5);
|
||||
if (data == "PING!") {
|
||||
print("client: got ping, sending pong.");
|
||||
output.write("PONG!", 5);
|
||||
} else {
|
||||
print('client: wrong data from server:', data);
|
||||
output.write('Error: wrong data received.', 27);
|
||||
print("client: wrong data from server:", data);
|
||||
output.write("Error: wrong data received.", 27);
|
||||
}
|
||||
output.close();
|
||||
}
|
||||
|
||||
for (var arg of arguments) {
|
||||
print('client: running test', arg);
|
||||
test = arg.split('|');
|
||||
launchConnection(test[0], parseInt(test[1]), test[2],
|
||||
parseInt(test[3]), test[4]);
|
||||
print("client: running test", arg);
|
||||
test = arg.split("|");
|
||||
launchConnection(
|
||||
test[0],
|
||||
parseInt(test[1]),
|
||||
test[2],
|
||||
parseInt(test[3]),
|
||||
test[4]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,42 @@
|
|||
// Test based on submitted one from Peter B Shalimoff
|
||||
|
||||
var test = function(s, funcName){
|
||||
function Arg(){};
|
||||
Arg.prototype.toString = function(){
|
||||
info("Testing " + funcName + " with null args");
|
||||
return this.value;
|
||||
};
|
||||
// create a generic arg lits of null, -1, and 10 nulls
|
||||
var args = [s, -1];
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
args.push(new Arg());
|
||||
}
|
||||
var up = Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci.nsIURLParser);
|
||||
try {
|
||||
up[funcName].apply(up, args);
|
||||
return args;
|
||||
} catch (x) {
|
||||
Assert.ok(true); // make sure it throws an exception instead of crashing
|
||||
return x;
|
||||
}
|
||||
// should always have an exception to catch
|
||||
Assert.ok(false);
|
||||
var test = function(s, funcName) {
|
||||
function Arg() {}
|
||||
Arg.prototype.toString = function() {
|
||||
info("Testing " + funcName + " with null args");
|
||||
return this.value;
|
||||
};
|
||||
// create a generic arg lits of null, -1, and 10 nulls
|
||||
var args = [s, -1];
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
args.push(new Arg());
|
||||
}
|
||||
var up = Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(
|
||||
Ci.nsIURLParser
|
||||
);
|
||||
try {
|
||||
up[funcName].apply(up, args);
|
||||
return args;
|
||||
} catch (x) {
|
||||
Assert.ok(true); // make sure it throws an exception instead of crashing
|
||||
return x;
|
||||
}
|
||||
// should always have an exception to catch
|
||||
Assert.ok(false);
|
||||
};
|
||||
var s = null;
|
||||
var funcs = ["parseAuthority", "parseFileName", "parseFilePath", "parsePath", "parseServerInfo", "parseURL", "parseUserInfo"];
|
||||
var funcs = [
|
||||
"parseAuthority",
|
||||
"parseFileName",
|
||||
"parseFilePath",
|
||||
"parsePath",
|
||||
"parseServerInfo",
|
||||
"parseURL",
|
||||
"parseUserInfo",
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
funcs.forEach(function(f){test(s, f);});
|
||||
funcs.forEach(function(f) {
|
||||
test(s, f);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=761228
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpServer.identity.primaryPort;
|
||||
|
|
@ -19,20 +19,22 @@ const unexpected304 = "unexpected304";
|
|||
const existingCached304 = "existingCached304";
|
||||
|
||||
function make_uri(url) {
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
return ios.newURI(url);
|
||||
}
|
||||
|
||||
function make_channel(url) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true})
|
||||
.QueryInterface(Ci.nsIHttpChannel);
|
||||
return NetUtil.newChannel({
|
||||
uri: url,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
var service = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
||||
.getService(Ci.nsICacheStorageService);
|
||||
service.clear();
|
||||
var service = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(
|
||||
Ci.nsICacheStorageService
|
||||
);
|
||||
service.clear();
|
||||
}
|
||||
|
||||
function alwaysReturn304Handler(metadata, response) {
|
||||
|
|
@ -44,10 +46,14 @@ function run_test() {
|
|||
evict_cache_entries();
|
||||
|
||||
httpServer = new HttpServer();
|
||||
httpServer.registerPathHandler(basePath + unexpected304,
|
||||
alwaysReturn304Handler);
|
||||
httpServer.registerPathHandler(basePath + existingCached304,
|
||||
alwaysReturn304Handler);
|
||||
httpServer.registerPathHandler(
|
||||
basePath + unexpected304,
|
||||
alwaysReturn304Handler
|
||||
);
|
||||
httpServer.registerPathHandler(
|
||||
basePath + existingCached304,
|
||||
alwaysReturn304Handler
|
||||
);
|
||||
httpServer.start(-1);
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -74,12 +80,16 @@ add_test(function test_unexpected_304() {
|
|||
// the cache.
|
||||
add_test(function test_304_stored_in_cache() {
|
||||
asyncOpenCacheEntry(
|
||||
baseURI + existingCached304, "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
|
||||
function (entryStatus, cacheEntry) {
|
||||
baseURI + existingCached304,
|
||||
"disk",
|
||||
Ci.nsICacheStorage.OPEN_NORMALLY,
|
||||
null,
|
||||
function(entryStatus, cacheEntry) {
|
||||
cacheEntry.setMetaDataElement("request-method", "GET");
|
||||
cacheEntry.setMetaDataElement("response-head",
|
||||
"HTTP/1.1 304 Not Modified\r\n" +
|
||||
"\r\n");
|
||||
cacheEntry.setMetaDataElement(
|
||||
"response-head",
|
||||
"HTTP/1.1 304 Not Modified\r\n" + "\r\n"
|
||||
);
|
||||
cacheEntry.metaDataReady();
|
||||
cacheEntry.close();
|
||||
|
||||
|
|
@ -90,5 +100,6 @@ add_test(function test_304_stored_in_cache() {
|
|||
chan.setRequestHeader("If-None-Match", '"foo"', false);
|
||||
|
||||
chan.asyncOpen(new ChannelListener(consume304, null));
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpserver.identity.primaryPort;
|
||||
|
|
@ -15,75 +15,80 @@ XPCOMUtils.defineLazyGetter(this, "noRedirectURI", function() {
|
|||
var httpserver = null;
|
||||
|
||||
function make_channel(url) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
|
||||
}
|
||||
|
||||
const requestBody = "request body";
|
||||
|
||||
function redirectHandler(metadata, response)
|
||||
{
|
||||
function redirectHandler(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 307, "Moved Temporarily");
|
||||
response.setHeader("Location", noRedirectURI, false);
|
||||
}
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
function contentHandler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.bodyOutputStream.writeFrom(metadata.bodyInputStream,
|
||||
metadata.bodyInputStream.available());
|
||||
response.bodyOutputStream.writeFrom(
|
||||
metadata.bodyInputStream,
|
||||
metadata.bodyInputStream.available()
|
||||
);
|
||||
}
|
||||
|
||||
function noRedirectStreamObserver(request, buffer)
|
||||
{
|
||||
function noRedirectStreamObserver(request, buffer) {
|
||||
Assert.equal(buffer, requestBody);
|
||||
var chan = make_channel(uri);
|
||||
var uploadStream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
var uploadStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
uploadStream.setData(requestBody, requestBody.length);
|
||||
chan.QueryInterface(Ci.nsIUploadChannel).setUploadStream(uploadStream,
|
||||
"text/plain",
|
||||
-1);
|
||||
chan
|
||||
.QueryInterface(Ci.nsIUploadChannel)
|
||||
.setUploadStream(uploadStream, "text/plain", -1);
|
||||
chan.asyncOpen(new ChannelListener(noHeaderStreamObserver, null));
|
||||
}
|
||||
|
||||
function noHeaderStreamObserver(request, buffer)
|
||||
{
|
||||
function noHeaderStreamObserver(request, buffer) {
|
||||
Assert.equal(buffer, requestBody);
|
||||
var chan = make_channel(uri);
|
||||
var uploadStream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
var streamBody = "Content-Type: text/plain\r\n" +
|
||||
"Content-Length: " + requestBody.length + "\r\n\r\n" +
|
||||
requestBody;
|
||||
var uploadStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
var streamBody =
|
||||
"Content-Type: text/plain\r\n" +
|
||||
"Content-Length: " +
|
||||
requestBody.length +
|
||||
"\r\n\r\n" +
|
||||
requestBody;
|
||||
uploadStream.setData(streamBody, streamBody.length);
|
||||
chan.QueryInterface(Ci.nsIUploadChannel).setUploadStream(uploadStream, "", -1);
|
||||
chan
|
||||
.QueryInterface(Ci.nsIUploadChannel)
|
||||
.setUploadStream(uploadStream, "", -1);
|
||||
chan.asyncOpen(new ChannelListener(headerStreamObserver, null));
|
||||
}
|
||||
|
||||
function headerStreamObserver(request, buffer)
|
||||
{
|
||||
function headerStreamObserver(request, buffer) {
|
||||
Assert.equal(buffer, requestBody);
|
||||
httpserver.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
httpserver = new HttpServer();
|
||||
httpserver.registerPathHandler("/redirect", redirectHandler);
|
||||
httpserver.registerPathHandler("/content", contentHandler);
|
||||
httpserver.start(-1);
|
||||
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefBranch);
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(
|
||||
Ci.nsIPrefBranch
|
||||
);
|
||||
prefs.setBoolPref("network.http.prompt-temp-redirect", false);
|
||||
|
||||
var chan = make_channel(noRedirectURI);
|
||||
var uploadStream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
var uploadStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
uploadStream.setData(requestBody, requestBody.length);
|
||||
chan.QueryInterface(Ci.nsIUploadChannel).setUploadStream(uploadStream,
|
||||
"text/plain",
|
||||
-1);
|
||||
chan
|
||||
.QueryInterface(Ci.nsIUploadChannel)
|
||||
.setUploadStream(uploadStream, "text/plain", -1);
|
||||
chan.asyncOpen(new ChannelListener(noRedirectStreamObserver, null));
|
||||
do_test_pending();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpserver.identity.primaryPort;
|
||||
|
|
@ -25,7 +25,10 @@ function setup_test() {
|
|||
}
|
||||
|
||||
function setupChannel(path) {
|
||||
var chan = NetUtil.newChannel({uri: URL + path, loadUsingSystemPrincipal: true});
|
||||
var chan = NetUtil.newChannel({
|
||||
uri: URL + path,
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
chan.QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.requestMethod = "GET";
|
||||
return chan;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -8,15 +8,15 @@
|
|||
* This file tests the methods on NetUtil.jsm.
|
||||
*/
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
// We need the profile directory so the test harness will clean up our test
|
||||
// files.
|
||||
do_get_profile();
|
||||
|
||||
const OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/file-output-stream;1";
|
||||
const SAFE_OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/safe-file-output-stream;1";
|
||||
const SAFE_OUTPUT_STREAM_CONTRACT_ID =
|
||||
"@mozilla.org/network/safe-file-output-stream;1";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Helper Methods
|
||||
|
|
@ -28,25 +28,25 @@ const SAFE_OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/safe-file-output-st
|
|||
* The file to return from.
|
||||
* @return the contents of the file in the form of a string.
|
||||
*/
|
||||
function getFileContents(aFile)
|
||||
{
|
||||
function getFileContents(aFile) {
|
||||
"use strict";
|
||||
|
||||
let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Ci.nsIFileInputStream);
|
||||
let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
|
||||
Ci.nsIFileInputStream
|
||||
);
|
||||
fstream.init(aFile, -1, 0, 0);
|
||||
|
||||
let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Ci.nsIConverterInputStream);
|
||||
let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(
|
||||
Ci.nsIConverterInputStream
|
||||
);
|
||||
cstream.init(fstream, "UTF-8", 0, 0);
|
||||
|
||||
let string = {};
|
||||
let string = {};
|
||||
cstream.readString(-1, string);
|
||||
cstream.close();
|
||||
return string.value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests asynchronously writing a file using NetUtil.asyncCopy.
|
||||
*
|
||||
|
|
@ -55,25 +55,30 @@ function getFileContents(aFile)
|
|||
* @param aDeferOpen
|
||||
* Whether to use DEFER_OPEN in the output stream.
|
||||
*/
|
||||
function async_write_file(aContractId, aDeferOpen)
|
||||
{
|
||||
function async_write_file(aContractId, aDeferOpen) {
|
||||
do_test_pending();
|
||||
|
||||
// First, we need an output file to write to.
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("ProfD", Ci.nsIFile);
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
file.append("NetUtil-async-test-file.tmp");
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
// Then, we need an output stream to our output file.
|
||||
let ostream = Cc[aContractId].createInstance(Ci.nsIFileOutputStream);
|
||||
ostream.init(file, -1, -1, aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0);
|
||||
ostream.init(
|
||||
file,
|
||||
-1,
|
||||
-1,
|
||||
aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0
|
||||
);
|
||||
|
||||
// Finally, we need an input stream to take data from.
|
||||
const TEST_DATA = "this is a test string";
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
istream.setData(TEST_DATA, TEST_DATA.length);
|
||||
|
||||
NetUtil.asyncCopy(istream, ostream, function(aResult) {
|
||||
|
|
@ -93,8 +98,7 @@ function async_write_file(aContractId, aDeferOpen)
|
|||
//// Tests
|
||||
|
||||
// Test NetUtil.asyncCopy for all possible buffering scenarios
|
||||
function test_async_copy()
|
||||
{
|
||||
function test_async_copy() {
|
||||
// Create a data sample
|
||||
function make_sample(text) {
|
||||
let data = [];
|
||||
|
|
@ -108,27 +112,30 @@ function test_async_copy()
|
|||
function make_input(isBuffered, data) {
|
||||
if (isBuffered) {
|
||||
// String input streams are buffered
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
istream.setData(data, data.length);
|
||||
return istream;
|
||||
}
|
||||
|
||||
// File input streams are not buffered, so let's create a file
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("ProfD", Ci.nsIFile);
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
file.append("NetUtil-asyncFetch-test-file.tmp");
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
let ostream = Cc[
|
||||
"@mozilla.org/network/file-output-stream;1"
|
||||
].createInstance(Ci.nsIFileOutputStream);
|
||||
ostream.init(file, -1, -1, 0);
|
||||
ostream.write(data, data.length);
|
||||
ostream.close();
|
||||
|
||||
let istream = Cc["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Ci.nsIFileInputStream);
|
||||
let istream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
|
||||
Ci.nsIFileInputStream
|
||||
);
|
||||
istream.init(file, -1, 0, 0);
|
||||
|
||||
return istream;
|
||||
|
|
@ -136,37 +143,40 @@ function test_async_copy()
|
|||
|
||||
// Create an output buffer holding some data
|
||||
function make_output(isBuffered) {
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("ProfD", Ci.nsIFile);
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
file.append("NetUtil-asyncFetch-test-file.tmp");
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
let ostream = Cc[
|
||||
"@mozilla.org/network/file-output-stream;1"
|
||||
].createInstance(Ci.nsIFileOutputStream);
|
||||
ostream.init(file, -1, -1, 0);
|
||||
|
||||
if (!isBuffered) {
|
||||
return {file, sink: ostream};
|
||||
return { file, sink: ostream };
|
||||
}
|
||||
|
||||
let bstream = Cc["@mozilla.org/network/buffered-output-stream;1"].
|
||||
createInstance(Ci.nsIBufferedOutputStream);
|
||||
let bstream = Cc[
|
||||
"@mozilla.org/network/buffered-output-stream;1"
|
||||
].createInstance(Ci.nsIBufferedOutputStream);
|
||||
bstream.init(ostream, 256);
|
||||
return {file, sink: bstream};
|
||||
return { file, sink: bstream };
|
||||
}
|
||||
(async function() {
|
||||
do_test_pending();
|
||||
for (let bufferedInput of [true, false]) {
|
||||
for (let bufferedOutput of [true, false]) {
|
||||
let text = "test_async_copy with "
|
||||
+ (bufferedInput?"buffered input":"unbuffered input")
|
||||
+ ", "
|
||||
+ (bufferedOutput?"buffered output":"unbuffered output");
|
||||
let text =
|
||||
"test_async_copy with " +
|
||||
(bufferedInput ? "buffered input" : "unbuffered input") +
|
||||
", " +
|
||||
(bufferedOutput ? "buffered output" : "unbuffered output");
|
||||
info(text);
|
||||
let TEST_DATA = "[" + make_sample(text) + "]";
|
||||
let source = make_input(bufferedInput, TEST_DATA);
|
||||
let {file, sink} = make_output(bufferedOutput);
|
||||
let { file, sink } = make_output(bufferedOutput);
|
||||
let result = await new Promise(resolve => {
|
||||
NetUtil.asyncCopy(source, sink, resolve);
|
||||
});
|
||||
|
|
@ -202,21 +212,18 @@ function test_async_write_file_safe_deferred() {
|
|||
async_write_file(SAFE_OUTPUT_STREAM_CONTRACT_ID, true);
|
||||
}
|
||||
|
||||
function test_newURI_no_spec_throws()
|
||||
{
|
||||
function test_newURI_no_spec_throws() {
|
||||
try {
|
||||
NetUtil.newURI();
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_newURI()
|
||||
{
|
||||
function test_newURI() {
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
|
||||
// Check that we get the same URI back from the IO service and the utility
|
||||
|
|
@ -229,14 +236,13 @@ function test_newURI()
|
|||
run_next_test();
|
||||
}
|
||||
|
||||
function test_newURI_takes_nsIFile()
|
||||
{
|
||||
function test_newURI_takes_nsIFile() {
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
|
||||
// Create a test file that we can pass into NetUtil.newURI
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("ProfD", Ci.nsIFile);
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
file.append("NetUtil-test-file.tmp");
|
||||
|
||||
// Check that we get the same URI back from the IO service and the utility
|
||||
|
|
@ -248,34 +254,29 @@ function test_newURI_takes_nsIFile()
|
|||
run_next_test();
|
||||
}
|
||||
|
||||
function test_asyncFetch_no_channel()
|
||||
{
|
||||
function test_asyncFetch_no_channel() {
|
||||
try {
|
||||
NetUtil.asyncFetch(null, function() { });
|
||||
NetUtil.asyncFetch(null, function() {});
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_asyncFetch_no_callback()
|
||||
{
|
||||
function test_asyncFetch_no_callback() {
|
||||
try {
|
||||
NetUtil.asyncFetch({ });
|
||||
NetUtil.asyncFetch({});
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_asyncFetch_with_nsIChannel()
|
||||
{
|
||||
function test_asyncFetch_with_nsIChannel() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
|
||||
// Start the http server, and register our handler.
|
||||
|
|
@ -300,8 +301,9 @@ function test_asyncFetch_with_nsIChannel()
|
|||
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
|
|
@ -310,8 +312,7 @@ function test_asyncFetch_with_nsIChannel()
|
|||
});
|
||||
}
|
||||
|
||||
function test_asyncFetch_with_nsIURI()
|
||||
{
|
||||
function test_asyncFetch_with_nsIURI() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
|
||||
// Start the http server, and register our handler.
|
||||
|
|
@ -324,36 +325,40 @@ function test_asyncFetch_with_nsIURI()
|
|||
server.start(-1);
|
||||
|
||||
// Create our URI.
|
||||
let uri = NetUtil.newURI("http://localhost:" +
|
||||
server.identity.primaryPort + "/test");
|
||||
let uri = NetUtil.newURI(
|
||||
"http://localhost:" + server.identity.primaryPort + "/test"
|
||||
);
|
||||
|
||||
// Open our URI asynchronously.
|
||||
NetUtil.asyncFetch({
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}, function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
},
|
||||
function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
|
||||
server.stop(run_next_test);
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
server.stop(run_next_test);
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
}
|
||||
|
||||
function test_asyncFetch_with_string()
|
||||
{
|
||||
function test_asyncFetch_with_string() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
|
||||
// Start the http server, and register our handler.
|
||||
|
|
@ -366,44 +371,48 @@ function test_asyncFetch_with_string()
|
|||
server.start(-1);
|
||||
|
||||
// Open our location asynchronously.
|
||||
NetUtil.asyncFetch({
|
||||
uri: "http://localhost:" + server.identity.primaryPort + "/test",
|
||||
loadUsingSystemPrincipal: true,
|
||||
}, function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: "http://localhost:" + server.identity.primaryPort + "/test",
|
||||
loadUsingSystemPrincipal: true,
|
||||
},
|
||||
function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
|
||||
server.stop(run_next_test);
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
server.stop(run_next_test);
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
}
|
||||
|
||||
function test_asyncFetch_with_nsIFile()
|
||||
{
|
||||
function test_asyncFetch_with_nsIFile() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
|
||||
// First we need a file to read from.
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("ProfD", Ci.nsIFile);
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
file.append("NetUtil-asyncFetch-test-file.tmp");
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
// Write the test data to the file.
|
||||
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
ostream.init(file, -1, -1, 0);
|
||||
ostream.write(TEST_DATA, TEST_DATA.length);
|
||||
|
||||
|
|
@ -412,58 +421,66 @@ function test_asyncFetch_with_nsIFile()
|
|||
|
||||
// Open our file asynchronously.
|
||||
// Note that this causes main-tread I/O and should be avoided in production.
|
||||
NetUtil.asyncFetch({
|
||||
uri: NetUtil.newURI(file),
|
||||
loadUsingSystemPrincipal: true,
|
||||
}, function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: NetUtil.newURI(file),
|
||||
loadUsingSystemPrincipal: true,
|
||||
},
|
||||
function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
is.init(aInputStream);
|
||||
let result = is.read(TEST_DATA.length);
|
||||
Assert.equal(TEST_DATA, result);
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
run_next_test();
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
}
|
||||
|
||||
function test_asyncFetch_with_nsIInputString()
|
||||
{
|
||||
function test_asyncFetch_with_nsIInputString() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
istream.setData(TEST_DATA, TEST_DATA.length);
|
||||
|
||||
// Read the input stream asynchronously.
|
||||
NetUtil.asyncFetch(istream, function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
NetUtil.asyncFetch(
|
||||
istream,
|
||||
function(aInputStream, aResult) {
|
||||
// Check that we had success.
|
||||
Assert.ok(Components.isSuccessCode(aResult));
|
||||
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
Assert.equal(NetUtil.readInputStreamToString(aInputStream, TEST_DATA.length),
|
||||
TEST_DATA);
|
||||
// Check that we got the right data.
|
||||
Assert.equal(aInputStream.available(), TEST_DATA.length);
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(aInputStream, TEST_DATA.length),
|
||||
TEST_DATA
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
run_next_test();
|
||||
},
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
}
|
||||
|
||||
function test_asyncFetch_does_not_block()
|
||||
{
|
||||
function test_asyncFetch_does_not_block() {
|
||||
// Create our channel that has no data.
|
||||
let channel = NetUtil.newChannel({
|
||||
uri: "data:text/plain,",
|
||||
|
|
@ -477,14 +494,14 @@ function test_asyncFetch_does_not_block()
|
|||
|
||||
// Check that reading a byte throws that the stream was closed (as opposed
|
||||
// saying it would block).
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
|
||||
Ci.nsIScriptableInputStream
|
||||
);
|
||||
is.init(aInputStream);
|
||||
try {
|
||||
is.read(1);
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_BASE_STREAM_CLOSED);
|
||||
}
|
||||
|
||||
|
|
@ -492,97 +509,101 @@ function test_asyncFetch_does_not_block()
|
|||
});
|
||||
}
|
||||
|
||||
function test_newChannel_no_specifier()
|
||||
{
|
||||
function test_newChannel_no_specifier() {
|
||||
try {
|
||||
NetUtil.newChannel();
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_newChannel_with_string()
|
||||
{
|
||||
function test_newChannel_with_string() {
|
||||
const TEST_SPEC = "http://mozilla.org";
|
||||
|
||||
// Check that we get the same URI back from channel the IO service creates and
|
||||
// the channel the utility method creates.
|
||||
let ios = Services.io
|
||||
let iosChannel = ios.newChannel(TEST_SPEC,
|
||||
null,
|
||||
null,
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
let ios = Services.io;
|
||||
let iosChannel = ios.newChannel(
|
||||
TEST_SPEC,
|
||||
null,
|
||||
null,
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
let NetUtilChannel = NetUtil.newChannel({
|
||||
uri: TEST_SPEC,
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
Assert.ok(iosChannel.URI.equals(NetUtilChannel.URI));
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_newChannel_with_nsIURI()
|
||||
{
|
||||
function test_newChannel_with_nsIURI() {
|
||||
const TEST_SPEC = "http://mozilla.org";
|
||||
|
||||
// Check that we get the same URI back from channel the IO service creates and
|
||||
// the channel the utility method creates.
|
||||
let uri = NetUtil.newURI(TEST_SPEC);
|
||||
let iosChannel = Services.io.newChannelFromURI(uri,
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
let iosChannel = Services.io.newChannelFromURI(
|
||||
uri,
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
let NetUtilChannel = NetUtil.newChannel({
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
Assert.ok(iosChannel.URI.equals(NetUtilChannel.URI));
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_newChannel_with_options()
|
||||
{
|
||||
function test_newChannel_with_options() {
|
||||
let uri = "data:text/plain,";
|
||||
|
||||
let iosChannel = Services.io.newChannelFromURI(NetUtil.newURI(uri),
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
let iosChannel = Services.io.newChannelFromURI(
|
||||
NetUtil.newURI(uri),
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
|
||||
function checkEqualToIOSChannel(channel) {
|
||||
Assert.ok(iosChannel.URI.equals(channel.URI));
|
||||
Assert.ok(iosChannel.URI.equals(channel.URI));
|
||||
}
|
||||
|
||||
checkEqualToIOSChannel(NetUtil.newChannel({
|
||||
uri,
|
||||
loadingPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
|
||||
}));
|
||||
checkEqualToIOSChannel(
|
||||
NetUtil.newChannel({
|
||||
uri,
|
||||
loadingPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
|
||||
})
|
||||
);
|
||||
|
||||
checkEqualToIOSChannel(NetUtil.newChannel({
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}));
|
||||
checkEqualToIOSChannel(
|
||||
NetUtil.newChannel({
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
})
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_newChannel_with_wrong_options()
|
||||
{
|
||||
function test_newChannel_with_wrong_options() {
|
||||
let uri = "data:text/plain,";
|
||||
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
|
||||
|
|
@ -628,136 +649,137 @@ function test_newChannel_with_wrong_options()
|
|||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString()
|
||||
{
|
||||
function test_readInputStreamToString() {
|
||||
const TEST_DATA = "this is a test string\0 with an embedded null";
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsISupportsCString);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsISupportsCString
|
||||
);
|
||||
istream.data = TEST_DATA;
|
||||
|
||||
Assert.equal(NetUtil.readInputStreamToString(istream, TEST_DATA.length),
|
||||
TEST_DATA);
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA.length),
|
||||
TEST_DATA
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString_no_input_stream()
|
||||
{
|
||||
function test_readInputStreamToString_no_input_stream() {
|
||||
try {
|
||||
NetUtil.readInputStreamToString("hi", 2);
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString_no_bytes_arg()
|
||||
{
|
||||
function test_readInputStreamToString_no_bytes_arg() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
istream.setData(TEST_DATA, TEST_DATA.length);
|
||||
|
||||
try {
|
||||
NetUtil.readInputStreamToString(istream);
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString_blocking_stream()
|
||||
{
|
||||
function test_readInputStreamToString_blocking_stream() {
|
||||
let pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, 0, null);
|
||||
|
||||
try {
|
||||
NetUtil.readInputStreamToString(pipe.inputStream, 10);
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_BASE_STREAM_WOULD_BLOCK);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString_too_many_bytes()
|
||||
{
|
||||
function test_readInputStreamToString_too_many_bytes() {
|
||||
const TEST_DATA = "this is a test string";
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
istream.setData(TEST_DATA, TEST_DATA.length);
|
||||
|
||||
try {
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA.length + 10);
|
||||
do_throw("should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString_with_charset()
|
||||
{
|
||||
function test_readInputStreamToString_with_charset() {
|
||||
const TEST_DATA = "\uff10\uff11\uff12\uff13";
|
||||
const TEST_DATA_UTF8 = "\xef\xbc\x90\xef\xbc\x91\xef\xbc\x92\xef\xbc\x93";
|
||||
const TEST_DATA_SJIS = "\x82\x4f\x82\x50\x82\x51\x82\x52";
|
||||
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
|
||||
istream.setData(TEST_DATA_UTF8, TEST_DATA_UTF8.length);
|
||||
Assert.equal(NetUtil.readInputStreamToString(istream,
|
||||
TEST_DATA_UTF8.length,
|
||||
{ charset: "UTF-8"}),
|
||||
TEST_DATA);
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA_UTF8.length, {
|
||||
charset: "UTF-8",
|
||||
}),
|
||||
TEST_DATA
|
||||
);
|
||||
|
||||
istream.setData(TEST_DATA_SJIS, TEST_DATA_SJIS.length);
|
||||
Assert.equal(NetUtil.readInputStreamToString(istream,
|
||||
TEST_DATA_SJIS.length,
|
||||
{ charset: "Shift_JIS"}),
|
||||
TEST_DATA);
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA_SJIS.length, {
|
||||
charset: "Shift_JIS",
|
||||
}),
|
||||
TEST_DATA
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_readInputStreamToString_invalid_sequence()
|
||||
{
|
||||
function test_readInputStreamToString_invalid_sequence() {
|
||||
const TEST_DATA = "\ufffd\ufffd\ufffd\ufffd";
|
||||
const TEST_DATA_UTF8 = "\xaa\xaa\xaa\xaa";
|
||||
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
createInstance(Ci.nsIStringInputStream);
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
|
||||
Ci.nsIStringInputStream
|
||||
);
|
||||
|
||||
istream.setData(TEST_DATA_UTF8, TEST_DATA_UTF8.length);
|
||||
try {
|
||||
NetUtil.readInputStreamToString(istream,
|
||||
TEST_DATA_UTF8.length,
|
||||
{ charset: "UTF-8" });
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA_UTF8.length, {
|
||||
charset: "UTF-8",
|
||||
});
|
||||
do_throw("should throw!");
|
||||
} catch (e) {
|
||||
Assert.equal(e.result, Cr.NS_ERROR_ILLEGAL_INPUT);
|
||||
}
|
||||
|
||||
istream.setData(TEST_DATA_UTF8, TEST_DATA_UTF8.length);
|
||||
Assert.equal(NetUtil.readInputStreamToString(istream,
|
||||
TEST_DATA_UTF8.length, {
|
||||
charset: "UTF-8",
|
||||
replacement: Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER}),
|
||||
TEST_DATA);
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA_UTF8.length, {
|
||||
charset: "UTF-8",
|
||||
replacement: Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER,
|
||||
}),
|
||||
TEST_DATA
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Runner
|
||||
|
||||
|
|
@ -792,4 +814,3 @@ function test_readInputStreamToString_invalid_sequence()
|
|||
test_readInputStreamToString_invalid_sequence,
|
||||
].forEach(f => add_test(f));
|
||||
var index = 0;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -4,8 +4,10 @@
|
|||
// etc--see HttpBaseChannel::IsSafeMethod). Since no prompting is possible
|
||||
// in xpcshell, we get an error for prompts, and the request fails.
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { Preferences } = ChromeUtils.import(
|
||||
"resource://gre/modules/Preferences.jsm"
|
||||
);
|
||||
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"]);
|
||||
|
||||
|
|
@ -23,15 +25,13 @@ XPCOMUtils.defineLazyGetter(this, "pOther", function() {
|
|||
return sOther.identity.primaryPort;
|
||||
});
|
||||
|
||||
function createXHR(async, method, path)
|
||||
{
|
||||
function createXHR(async, method, path) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open(method, "http://localhost:" + pSame + path, async);
|
||||
return xhr;
|
||||
}
|
||||
|
||||
function checkResults(xhr, method, status, unsafe)
|
||||
{
|
||||
function checkResults(xhr, method, status, unsafe) {
|
||||
if (unsafe) {
|
||||
if (sRedirectPromptPref) {
|
||||
// The method is null if we prompt for unsafe redirects
|
||||
|
|
@ -42,8 +42,9 @@ function checkResults(xhr, method, status, unsafe)
|
|||
}
|
||||
}
|
||||
|
||||
if (xhr.readyState != 4)
|
||||
if (xhr.readyState != 4) {
|
||||
return false;
|
||||
}
|
||||
Assert.equal(xhr.status, status);
|
||||
|
||||
if (status == 200) {
|
||||
|
|
@ -59,18 +60,48 @@ function run_test() {
|
|||
sSame = new HttpServer();
|
||||
|
||||
// same-origin redirects
|
||||
sSame.registerPathHandler("/bug" + BUGID + "-redirect301", bug676059redirect301);
|
||||
sSame.registerPathHandler("/bug" + BUGID + "-redirect302", bug676059redirect302);
|
||||
sSame.registerPathHandler("/bug" + BUGID + "-redirect303", bug676059redirect303);
|
||||
sSame.registerPathHandler("/bug" + BUGID + "-redirect307", bug676059redirect307);
|
||||
sSame.registerPathHandler("/bug" + BUGID + "-redirect308", bug676059redirect308);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + BUGID + "-redirect301",
|
||||
bug676059redirect301
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + BUGID + "-redirect302",
|
||||
bug676059redirect302
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + BUGID + "-redirect303",
|
||||
bug676059redirect303
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + BUGID + "-redirect307",
|
||||
bug676059redirect307
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + BUGID + "-redirect308",
|
||||
bug676059redirect308
|
||||
);
|
||||
|
||||
// cross-origin redirects
|
||||
sSame.registerPathHandler("/bug" + OTHERBUGID + "-redirect301", bug696849redirect301);
|
||||
sSame.registerPathHandler("/bug" + OTHERBUGID + "-redirect302", bug696849redirect302);
|
||||
sSame.registerPathHandler("/bug" + OTHERBUGID + "-redirect303", bug696849redirect303);
|
||||
sSame.registerPathHandler("/bug" + OTHERBUGID + "-redirect307", bug696849redirect307);
|
||||
sSame.registerPathHandler("/bug" + OTHERBUGID + "-redirect308", bug696849redirect308);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + OTHERBUGID + "-redirect301",
|
||||
bug696849redirect301
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + OTHERBUGID + "-redirect302",
|
||||
bug696849redirect302
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + OTHERBUGID + "-redirect303",
|
||||
bug696849redirect303
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + OTHERBUGID + "-redirect307",
|
||||
bug696849redirect307
|
||||
);
|
||||
sSame.registerPathHandler(
|
||||
"/bug" + OTHERBUGID + "-redirect308",
|
||||
bug696849redirect308
|
||||
);
|
||||
|
||||
// same-origin target
|
||||
sSame.registerPathHandler("/bug" + BUGID + "-target", echoMethod);
|
||||
|
|
@ -86,10 +117,10 @@ function run_test() {
|
|||
// methodToSend is the HTTP method to send
|
||||
// redirectedMethod is the method to use for the redirect, if any
|
||||
// finalStatus is 200 when the redirect takes place, redirectType otherwise
|
||||
|
||||
|
||||
// Note that unsafe methods should not follow the redirect automatically
|
||||
// Of the methods below, DELETE, POST and PUT are unsafe
|
||||
|
||||
|
||||
sRedirectPromptPref = Preferences.get("network.http.prompt-temp-redirect");
|
||||
// Following Bug 677754 we don't prompt for unsafe redirects
|
||||
|
||||
|
|
@ -136,49 +167,56 @@ function run_test() {
|
|||
var othertests = tests; // for now these have identical results
|
||||
|
||||
var xhr;
|
||||
|
||||
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
dump("Testing " + tests[i] + "\n");
|
||||
xhr = createXHR(false, tests[i][1], "/bug" + BUGID + "-redirect" + tests[i][0]);
|
||||
xhr = createXHR(
|
||||
false,
|
||||
tests[i][1],
|
||||
"/bug" + BUGID + "-redirect" + tests[i][0]
|
||||
);
|
||||
xhr.send(null);
|
||||
checkResults(xhr, tests[i][2], tests[i][3], tests[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < othertests.length; ++i) {
|
||||
dump("Testing " + othertests[i] + " (cross-origin)\n");
|
||||
xhr = createXHR(false, othertests[i][1], "/bug" + OTHERBUGID + "-redirect" + othertests[i][0]);
|
||||
xhr = createXHR(
|
||||
false,
|
||||
othertests[i][1],
|
||||
"/bug" + OTHERBUGID + "-redirect" + othertests[i][0]
|
||||
);
|
||||
xhr.send(null);
|
||||
checkResults(xhr, othertests[i][2], tests[i][3], tests[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
sSame.stop(do_test_finished);
|
||||
sOther.stop(do_test_finished);
|
||||
}
|
||||
|
||||
|
||||
function redirect(metadata, response, status, port, bugid) {
|
||||
// set a proper reason string to avoid confusion when looking at the
|
||||
// HTTP messages
|
||||
var reason;
|
||||
if (status == 301) {
|
||||
reason = "Moved Permanently";
|
||||
}
|
||||
else if (status == 302) {
|
||||
} else if (status == 302) {
|
||||
reason = "Found";
|
||||
}
|
||||
else if (status == 303) {
|
||||
} else if (status == 303) {
|
||||
reason = "See Other";
|
||||
}
|
||||
else if (status == 307) {
|
||||
} else if (status == 307) {
|
||||
reason = "Temporary Redirect";
|
||||
}
|
||||
else if (status == 308) {
|
||||
} else if (status == 308) {
|
||||
reason = "Permanent Redirect";
|
||||
}
|
||||
|
||||
|
||||
response.setStatusLine(metadata.httpVersion, status, reason);
|
||||
response.setHeader("Location", "http://localhost:" + port + "/bug" + bugid + "-target");
|
||||
}
|
||||
|
||||
response.setHeader(
|
||||
"Location",
|
||||
"http://localhost:" + port + "/bug" + bugid + "-target"
|
||||
);
|
||||
}
|
||||
|
||||
// PATH HANDLER FOR /bug676059-redirect301
|
||||
function bug676059redirect301(metadata, response) {
|
||||
redirect(metadata, response, 301, pSame, BUGID);
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@
|
|||
* 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 {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
const gDashboard = Cc['@mozilla.org/network/dashboard;1']
|
||||
.getService(Ci.nsIDashboard);
|
||||
const gDashboard = Cc["@mozilla.org/network/dashboard;1"].getService(
|
||||
Ci.nsIDashboard
|
||||
);
|
||||
|
||||
const gServerSocket = Cc["@mozilla.org/network/server-socket;1"]
|
||||
.createInstance(Ci.nsIServerSocket);
|
||||
const gServerSocket = Cc["@mozilla.org/network/server-socket;1"].createInstance(
|
||||
Ci.nsIServerSocket
|
||||
);
|
||||
const gHttpServer = new HttpServer();
|
||||
|
||||
add_test(function test_http() {
|
||||
|
|
@ -46,12 +48,17 @@ add_test(function test_dns() {
|
|||
});
|
||||
|
||||
add_test(function test_sockets() {
|
||||
let sts = Cc["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Ci.nsISocketTransportService);
|
||||
let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(
|
||||
Ci.nsISocketTransportService
|
||||
);
|
||||
let threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
|
||||
|
||||
let transport = sts.createTransport([], "127.0.0.1",
|
||||
gServerSocket.port, null);
|
||||
let transport = sts.createTransport(
|
||||
[],
|
||||
"127.0.0.1",
|
||||
gServerSocket.port,
|
||||
null
|
||||
);
|
||||
let listener = {
|
||||
onTransportStatus(aTransport, aStatus, aProgress, aProgressMax) {
|
||||
if (aStatus == Ci.nsISocketTransport.STATUS_CONNECTED_TO) {
|
||||
|
|
@ -69,7 +76,7 @@ add_test(function test_sockets() {
|
|||
run_next_test();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
transport.setEventSink(listener, threadManager.currentThread);
|
||||
|
||||
|
|
@ -77,15 +84,21 @@ add_test(function test_sockets() {
|
|||
});
|
||||
|
||||
function run_test() {
|
||||
Services.prefs.setBoolPref("network.cookieSettings.unblocked_for_testing", true);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookieSettings.unblocked_for_testing",
|
||||
true
|
||||
);
|
||||
|
||||
let ioService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
let ioService = Cc["@mozilla.org/network/io-service;1"].getService(
|
||||
Ci.nsIIOService
|
||||
);
|
||||
|
||||
gHttpServer.start(-1);
|
||||
|
||||
let uri = ioService.newURI("http://localhost:" + gHttpServer.identity.primaryPort);
|
||||
let channel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true});
|
||||
let uri = ioService.newURI(
|
||||
"http://localhost:" + gHttpServer.identity.primaryPort
|
||||
);
|
||||
let channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true });
|
||||
|
||||
channel.open();
|
||||
|
||||
|
|
@ -93,4 +106,3 @@ function run_test() {
|
|||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,43 +2,54 @@
|
|||
* 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/. */
|
||||
|
||||
|
||||
var unsafeAboutModule = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIAboutModule]),
|
||||
newChannel (aURI, aLoadInfo) {
|
||||
newChannel(aURI, aLoadInfo) {
|
||||
var uri = Services.io.newURI("about:blank");
|
||||
let chan = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
|
||||
chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
return chan;
|
||||
},
|
||||
getURIFlags (aURI) {
|
||||
getURIFlags(aURI) {
|
||||
return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var factory = {
|
||||
createInstance(aOuter, aIID) {
|
||||
if (aOuter)
|
||||
if (aOuter) {
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
return unsafeAboutModule.QueryInterface(aIID);
|
||||
},
|
||||
lockFactory(aLock) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIFactory])
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIFactory]),
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
let classID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
|
||||
registrar.registerFactory(classID, "", "@mozilla.org/network/protocol/about;1?what=unsafe", factory);
|
||||
let classID = Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator)
|
||||
.generateUUID();
|
||||
registrar.registerFactory(
|
||||
classID,
|
||||
"",
|
||||
"@mozilla.org/network/protocol/about;1?what=unsafe",
|
||||
factory
|
||||
);
|
||||
|
||||
let aboutUnsafeChan = NetUtil.newChannel({
|
||||
uri: "about:unsafe",
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
|
||||
Assert.equal(null, aboutUnsafeChan.owner, "URI_SAFE_FOR_UNTRUSTED_CONTENT channel has no owner");
|
||||
Assert.equal(
|
||||
null,
|
||||
aboutUnsafeChan.owner,
|
||||
"URI_SAFE_FOR_UNTRUSTED_CONTENT channel has no owner"
|
||||
);
|
||||
|
||||
registrar.unregisterFactory(classID, factory);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
function run_test() {
|
||||
var base = NetUtil.newURI("http://www.example.com");
|
||||
var about1 = NetUtil.newURI("about:blank");
|
||||
|
|
@ -6,19 +5,18 @@ function run_test() {
|
|||
|
||||
var chan1 = NetUtil.newChannel({
|
||||
uri: about1,
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIPropertyBag2);
|
||||
|
||||
var chan2 = NetUtil.newChannel({
|
||||
uri: about2,
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIPropertyBag2);
|
||||
|
||||
var haveProp = false;
|
||||
var propVal = null;
|
||||
try {
|
||||
propVal = chan1.getPropertyAsInterface("baseURI",
|
||||
Ci.nsIURI);
|
||||
propVal = chan1.getPropertyAsInterface("baseURI", Ci.nsIURI);
|
||||
haveProp = true;
|
||||
} catch (e) {
|
||||
if (e.result != Cr.NS_ERROR_NOT_AVAILABLE) {
|
||||
|
|
@ -28,7 +26,5 @@ function run_test() {
|
|||
}
|
||||
Assert.equal(propVal, null);
|
||||
Assert.equal(haveProp, false);
|
||||
Assert.equal(chan2.getPropertyAsInterface("baseURI",
|
||||
Ci.nsIURI),
|
||||
base);
|
||||
Assert.equal(chan2.getPropertyAsInterface("baseURI", Ci.nsIURI), base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@
|
|||
|
||||
var CC = Components.Constructor;
|
||||
|
||||
const ServerSocket = CC("@mozilla.org/network/server-socket;1",
|
||||
"nsIServerSocket",
|
||||
"init");
|
||||
const ServerSocket = CC(
|
||||
"@mozilla.org/network/server-socket;1",
|
||||
"nsIServerSocket",
|
||||
"init"
|
||||
);
|
||||
|
||||
function testAddrInUse()
|
||||
{
|
||||
function testAddrInUse() {
|
||||
// Windows lets us have as many sockets listening on the same address as
|
||||
// we like, evidently.
|
||||
if (mozinfo.os == "win") {
|
||||
|
|
@ -22,11 +23,12 @@ function testAddrInUse()
|
|||
Assert.ok(listener instanceof Ci.nsIServerSocket);
|
||||
|
||||
// Try to create another listening socket on the same port, whatever that was.
|
||||
do_check_throws_nsIException(() => ServerSocket(listener.port, true, -1),
|
||||
"NS_ERROR_SOCKET_ADDRESS_IN_USE");
|
||||
do_check_throws_nsIException(
|
||||
() => ServerSocket(listener.port, true, -1),
|
||||
"NS_ERROR_SOCKET_ADDRESS_IN_USE"
|
||||
);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
testAddrInUse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
* - again we receive the data from the server.
|
||||
*/
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpServer.identity.primaryPort + "/content";
|
||||
|
|
@ -19,21 +19,24 @@ XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
|||
var httpServer = null;
|
||||
|
||||
// needs to be rooted
|
||||
var cacheFlushObserver = cacheFlushObserver = { observe() {
|
||||
cacheFlushObserver = null;
|
||||
readServerContentAgain();
|
||||
}};
|
||||
var cacheFlushObserver = (cacheFlushObserver = {
|
||||
observe() {
|
||||
cacheFlushObserver = null;
|
||||
readServerContentAgain();
|
||||
},
|
||||
});
|
||||
|
||||
var currentThread = null;
|
||||
|
||||
function make_channel(url, callback, ctx) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
|
||||
}
|
||||
|
||||
function inChildProcess() {
|
||||
return Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
return (
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
const responseContent = "response body";
|
||||
|
|
@ -46,15 +49,14 @@ var shouldPassRevalidation = true;
|
|||
|
||||
var cache_storage = null;
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
function contentHandler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setHeader("ETag", "test-etag1");
|
||||
|
||||
try {
|
||||
var etag = metadata.getHeader("If-None-Match");
|
||||
} catch(ex) {
|
||||
} catch (ex) {
|
||||
var etag = "";
|
||||
}
|
||||
|
||||
|
|
@ -67,8 +69,7 @@ function contentHandler(metadata, response)
|
|||
}
|
||||
}
|
||||
|
||||
function check_has_alt_data_in_index(aHasAltData)
|
||||
{
|
||||
function check_has_alt_data_in_index(aHasAltData) {
|
||||
if (inChildProcess()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -77,8 +78,7 @@ function check_has_alt_data_in_index(aHasAltData)
|
|||
Assert.equal(hasAltData.value, aHasAltData);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
httpServer = new HttpServer();
|
||||
httpServer.registerPathHandler("/content", contentHandler);
|
||||
|
|
@ -86,15 +86,14 @@ function run_test()
|
|||
do_test_pending();
|
||||
|
||||
if (!inChildProcess()) {
|
||||
cache_storage = getCacheStorage("disk") ;
|
||||
cache_storage = getCacheStorage("disk");
|
||||
wait_for_cache_index(asyncOpen);
|
||||
} else {
|
||||
asyncOpen();
|
||||
}
|
||||
}
|
||||
|
||||
function asyncOpen()
|
||||
{
|
||||
function asyncOpen() {
|
||||
var chan = make_channel(URL);
|
||||
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
|
@ -103,8 +102,7 @@ function asyncOpen()
|
|||
chan.asyncOpen(new ChannelListener(readServerContent, null));
|
||||
}
|
||||
|
||||
function readServerContent(request, buffer)
|
||||
{
|
||||
function readServerContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(buffer, responseContent);
|
||||
|
|
@ -119,23 +117,29 @@ function readServerContent(request, buffer)
|
|||
var os = cc.openAlternativeOutputStream(altContentType, altContent.length);
|
||||
|
||||
var aos = os.QueryInterface(Ci.nsIAsyncOutputStream);
|
||||
aos.asyncWait(_ => {
|
||||
os.write(altContent, altContent.length);
|
||||
aos.closeWithStatus(Cr.NS_ERROR_FAILURE);
|
||||
executeSoon(flushAndReadServerContentAgain);
|
||||
}, 0, 0, currentThread);
|
||||
aos.asyncWait(
|
||||
_ => {
|
||||
os.write(altContent, altContent.length);
|
||||
aos.closeWithStatus(Cr.NS_ERROR_FAILURE);
|
||||
executeSoon(flushAndReadServerContentAgain);
|
||||
},
|
||||
0,
|
||||
0,
|
||||
currentThread
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function flushAndReadServerContentAgain()
|
||||
{
|
||||
function flushAndReadServerContentAgain() {
|
||||
// We need to do a GC pass to ensure the cache entry has been freed.
|
||||
gc();
|
||||
if (!inChildProcess()) {
|
||||
Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver);
|
||||
Services.cache2
|
||||
.QueryInterface(Ci.nsICacheTesting)
|
||||
.flush(cacheFlushObserver);
|
||||
} else {
|
||||
do_send_remote_message('flush');
|
||||
do_await_remote_message('flushed').then(() => {
|
||||
do_send_remote_message("flush");
|
||||
do_await_remote_message("flushed").then(() => {
|
||||
readServerContentAgain();
|
||||
});
|
||||
}
|
||||
|
|
@ -151,8 +155,7 @@ function readServerContentAgain() {
|
|||
chan.asyncOpen(new ChannelListener(readServerContentAgainCB, null));
|
||||
}
|
||||
|
||||
function readServerContentAgainCB(request, buffer)
|
||||
{
|
||||
function readServerContentAgainCB(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(buffer, responseContent);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* - this time the alt data must arive
|
||||
*/
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpServer.identity.primaryPort + "/content";
|
||||
|
|
@ -18,13 +18,14 @@ XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
|||
var httpServer = null;
|
||||
|
||||
function make_channel(url, callback, ctx) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
|
||||
}
|
||||
|
||||
function inChildProcess() {
|
||||
return Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
return (
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
const responseContent = "response body";
|
||||
|
|
@ -37,15 +38,14 @@ var shouldPassRevalidation = true;
|
|||
|
||||
var cache_storage = null;
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
function contentHandler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setHeader("ETag", "test-etag1");
|
||||
|
||||
try {
|
||||
var etag = metadata.getHeader("If-None-Match");
|
||||
} catch(ex) {
|
||||
} catch (ex) {
|
||||
var etag = "";
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +58,7 @@ function contentHandler(metadata, response)
|
|||
}
|
||||
}
|
||||
|
||||
function check_has_alt_data_in_index(aHasAltData)
|
||||
{
|
||||
function check_has_alt_data_in_index(aHasAltData) {
|
||||
if (inChildProcess()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -68,8 +67,7 @@ function check_has_alt_data_in_index(aHasAltData)
|
|||
Assert.equal(hasAltData.value, aHasAltData);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
httpServer = new HttpServer();
|
||||
httpServer.registerPathHandler("/content", contentHandler);
|
||||
httpServer.start(-1);
|
||||
|
|
@ -78,8 +76,7 @@ function run_test()
|
|||
asyncOpen();
|
||||
}
|
||||
|
||||
function asyncOpen()
|
||||
{
|
||||
function asyncOpen() {
|
||||
var chan = make_channel(URL);
|
||||
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
|
@ -88,8 +85,7 @@ function asyncOpen()
|
|||
chan.asyncOpen(new ChannelListener(readServerContent, null));
|
||||
}
|
||||
|
||||
function readServerContent(request, buffer)
|
||||
{
|
||||
function readServerContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(buffer, responseContent);
|
||||
|
|
@ -105,12 +101,11 @@ function readServerContent(request, buffer)
|
|||
});
|
||||
}
|
||||
|
||||
function flushAndOpenAltChannel()
|
||||
{
|
||||
function flushAndOpenAltChannel() {
|
||||
// We need to do a GC pass to ensure the cache entry has been freed.
|
||||
gc();
|
||||
do_send_remote_message('flush');
|
||||
do_await_remote_message('flushed').then(() => {
|
||||
do_send_remote_message("flush");
|
||||
do_await_remote_message("flushed").then(() => {
|
||||
openAltChannel();
|
||||
});
|
||||
}
|
||||
|
|
@ -123,8 +118,7 @@ function openAltChannel() {
|
|||
chan.asyncOpen(new ChannelListener(readAltContent, null));
|
||||
}
|
||||
|
||||
function readAltContent(request, buffer)
|
||||
{
|
||||
function readAltContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(servedNotModified, true);
|
||||
|
|
@ -132,8 +126,8 @@ function readAltContent(request, buffer)
|
|||
Assert.equal(buffer, altContent);
|
||||
|
||||
// FINISH
|
||||
do_send_remote_message('done');
|
||||
do_await_remote_message('finish').then(() => {
|
||||
do_send_remote_message("done");
|
||||
do_await_remote_message("finish").then(() => {
|
||||
httpServer.stop(do_test_finished);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* - readAltContent3 checks that it gets back the newly saved alt-data
|
||||
*/
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpServer.identity.primaryPort + "/content";
|
||||
|
|
@ -21,7 +21,7 @@ XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
|||
let httpServer = null;
|
||||
|
||||
function make_and_open_channel(url, altContentType, callback) {
|
||||
let chan = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
let chan = NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
|
||||
if (altContentType) {
|
||||
let cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType, "", true);
|
||||
|
|
@ -37,15 +37,14 @@ const altContentType2 = "text/binary2";
|
|||
|
||||
let servedNotModified = false;
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
function contentHandler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setHeader("ETag", "test-etag1");
|
||||
let etag = ""
|
||||
let etag = "";
|
||||
try {
|
||||
etag = metadata.getHeader("If-None-Match");
|
||||
} catch(ex) {
|
||||
} catch (ex) {
|
||||
etag = "";
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +57,7 @@ function contentHandler(metadata, response)
|
|||
}
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
httpServer = new HttpServer();
|
||||
httpServer.registerPathHandler("/content", contentHandler);
|
||||
|
|
@ -69,8 +67,7 @@ function run_test()
|
|||
make_and_open_channel(URL, altContentType, readServerContent);
|
||||
}
|
||||
|
||||
function readServerContent(request, buffer)
|
||||
{
|
||||
function readServerContent(request, buffer) {
|
||||
let cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(buffer, responseContent);
|
||||
|
|
@ -85,26 +82,26 @@ function readServerContent(request, buffer)
|
|||
});
|
||||
}
|
||||
|
||||
function flushAndOpenAltChannel()
|
||||
{
|
||||
function flushAndOpenAltChannel() {
|
||||
// We need to do a GC pass to ensure the cache entry has been freed.
|
||||
Cu.forceShrinkingGC();
|
||||
Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver);
|
||||
}
|
||||
|
||||
// needs to be rooted
|
||||
let cacheFlushObserver = { observe() {
|
||||
if (!cacheFlushObserver) {
|
||||
info("ignoring cacheFlushObserver\n");
|
||||
return;
|
||||
}
|
||||
cacheFlushObserver = null;
|
||||
Cu.forceShrinkingGC();
|
||||
make_and_open_channel(URL, altContentType, readAltContent);
|
||||
}};
|
||||
let cacheFlushObserver = {
|
||||
observe() {
|
||||
if (!cacheFlushObserver) {
|
||||
info("ignoring cacheFlushObserver\n");
|
||||
return;
|
||||
}
|
||||
cacheFlushObserver = null;
|
||||
Cu.forceShrinkingGC();
|
||||
make_and_open_channel(URL, altContentType, readAltContent);
|
||||
},
|
||||
};
|
||||
|
||||
function readAltContent(request, buffer, closure, fromCache)
|
||||
{
|
||||
function readAltContent(request, buffer, closure, fromCache) {
|
||||
Cu.forceShrinkingGC();
|
||||
let cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
|
|
@ -115,8 +112,7 @@ function readAltContent(request, buffer, closure, fromCache)
|
|||
make_and_open_channel(URL, "dummy/null", readServerContent2);
|
||||
}
|
||||
|
||||
function readServerContent2(request, buffer, closure, fromCache)
|
||||
{
|
||||
function readServerContent2(request, buffer, closure, fromCache) {
|
||||
Cu.forceShrinkingGC();
|
||||
let cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
|
|
@ -133,26 +129,26 @@ function readServerContent2(request, buffer, closure, fromCache)
|
|||
});
|
||||
}
|
||||
|
||||
function flushAndOpenAltChannel2()
|
||||
{
|
||||
function flushAndOpenAltChannel2() {
|
||||
// We need to do a GC pass to ensure the cache entry has been freed.
|
||||
Cu.forceShrinkingGC();
|
||||
Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver2);
|
||||
}
|
||||
|
||||
// needs to be rooted
|
||||
let cacheFlushObserver2 = { observe() {
|
||||
if (!cacheFlushObserver2) {
|
||||
info("ignoring cacheFlushObserver2\n");
|
||||
return;
|
||||
}
|
||||
cacheFlushObserver2 = null;
|
||||
Cu.forceShrinkingGC();
|
||||
make_and_open_channel(URL, altContentType, readAltContent2);
|
||||
}};
|
||||
let cacheFlushObserver2 = {
|
||||
observe() {
|
||||
if (!cacheFlushObserver2) {
|
||||
info("ignoring cacheFlushObserver2\n");
|
||||
return;
|
||||
}
|
||||
cacheFlushObserver2 = null;
|
||||
Cu.forceShrinkingGC();
|
||||
make_and_open_channel(URL, altContentType, readAltContent2);
|
||||
},
|
||||
};
|
||||
|
||||
function readAltContent2(request, buffer, closure, fromCache)
|
||||
{
|
||||
function readAltContent2(request, buffer, closure, fromCache) {
|
||||
Cu.forceShrinkingGC();
|
||||
let cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
|
|
@ -163,7 +159,10 @@ function readAltContent2(request, buffer, closure, fromCache)
|
|||
executeSoon(() => {
|
||||
Cu.forceShrinkingGC();
|
||||
info("writing other content\n");
|
||||
let os = cc.openAlternativeOutputStream(altContentType2, altContent2.length);
|
||||
let os = cc.openAlternativeOutputStream(
|
||||
altContentType2,
|
||||
altContent2.length
|
||||
);
|
||||
os.write(altContent2, altContent2.length);
|
||||
os.close();
|
||||
|
||||
|
|
@ -171,28 +170,27 @@ function readAltContent2(request, buffer, closure, fromCache)
|
|||
});
|
||||
}
|
||||
|
||||
function flushAndOpenAltChannel3()
|
||||
{
|
||||
function flushAndOpenAltChannel3() {
|
||||
// We need to do a GC pass to ensure the cache entry has been freed.
|
||||
Cu.forceShrinkingGC();
|
||||
Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver3);
|
||||
}
|
||||
|
||||
// needs to be rooted
|
||||
let cacheFlushObserver3 = { observe() {
|
||||
if (!cacheFlushObserver3) {
|
||||
info("ignoring cacheFlushObserver3\n");
|
||||
return;
|
||||
}
|
||||
let cacheFlushObserver3 = {
|
||||
observe() {
|
||||
if (!cacheFlushObserver3) {
|
||||
info("ignoring cacheFlushObserver3\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cacheFlushObserver3 = null;
|
||||
Cu.forceShrinkingGC();
|
||||
make_and_open_channel(URL, altContentType2, readAltContent3);
|
||||
}};
|
||||
cacheFlushObserver3 = null;
|
||||
Cu.forceShrinkingGC();
|
||||
make_and_open_channel(URL, altContentType2, readAltContent3);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function readAltContent3(request, buffer, closure, fromCache)
|
||||
{
|
||||
function readAltContent3(request, buffer, closure, fromCache) {
|
||||
let cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(servedNotModified || fromCache, true);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* - this time the alt data must arive
|
||||
*/
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpServer.identity.primaryPort + "/content";
|
||||
|
|
@ -18,13 +18,14 @@ XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
|||
var httpServer = null;
|
||||
|
||||
function make_channel(url, callback, ctx) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
|
||||
}
|
||||
|
||||
function inChildProcess() {
|
||||
return Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
return (
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
const responseContent = "response body";
|
||||
|
|
@ -37,15 +38,14 @@ var shouldPassRevalidation = true;
|
|||
|
||||
var cache_storage = null;
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
function contentHandler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setHeader("ETag", "test-etag1");
|
||||
|
||||
try {
|
||||
var etag = metadata.getHeader("If-None-Match");
|
||||
} catch(ex) {
|
||||
} catch (ex) {
|
||||
var etag = "";
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +58,7 @@ function contentHandler(metadata, response)
|
|||
}
|
||||
}
|
||||
|
||||
function check_has_alt_data_in_index(aHasAltData)
|
||||
{
|
||||
function check_has_alt_data_in_index(aHasAltData) {
|
||||
if (inChildProcess()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -68,8 +67,7 @@ function check_has_alt_data_in_index(aHasAltData)
|
|||
Assert.equal(hasAltData.value, aHasAltData);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
httpServer = new HttpServer();
|
||||
httpServer.registerPathHandler("/content", contentHandler);
|
||||
|
|
@ -77,15 +75,14 @@ function run_test()
|
|||
do_test_pending();
|
||||
|
||||
if (!inChildProcess()) {
|
||||
cache_storage = getCacheStorage("disk") ;
|
||||
cache_storage = getCacheStorage("disk");
|
||||
wait_for_cache_index(asyncOpen);
|
||||
} else {
|
||||
asyncOpen();
|
||||
}
|
||||
}
|
||||
|
||||
function asyncOpen()
|
||||
{
|
||||
function asyncOpen() {
|
||||
var chan = make_channel(URL);
|
||||
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
|
@ -94,8 +91,7 @@ function asyncOpen()
|
|||
chan.asyncOpen(new ChannelListener(readServerContent, null));
|
||||
}
|
||||
|
||||
function readServerContent(request, buffer)
|
||||
{
|
||||
function readServerContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(buffer, responseContent);
|
||||
|
|
@ -112,20 +108,23 @@ function readServerContent(request, buffer)
|
|||
}
|
||||
|
||||
// needs to be rooted
|
||||
var cacheFlushObserver = cacheFlushObserver = { observe() {
|
||||
cacheFlushObserver = null;
|
||||
openAltChannel();
|
||||
}};
|
||||
var cacheFlushObserver = (cacheFlushObserver = {
|
||||
observe() {
|
||||
cacheFlushObserver = null;
|
||||
openAltChannel();
|
||||
},
|
||||
});
|
||||
|
||||
function flushAndOpenAltChannel()
|
||||
{
|
||||
function flushAndOpenAltChannel() {
|
||||
// We need to do a GC pass to ensure the cache entry has been freed.
|
||||
gc();
|
||||
if (!inChildProcess()) {
|
||||
Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(cacheFlushObserver);
|
||||
Services.cache2
|
||||
.QueryInterface(Ci.nsICacheTesting)
|
||||
.flush(cacheFlushObserver);
|
||||
} else {
|
||||
do_send_remote_message('flush');
|
||||
do_await_remote_message('flushed').then(() => {
|
||||
do_send_remote_message("flush");
|
||||
do_await_remote_message("flushed").then(() => {
|
||||
openAltChannel();
|
||||
});
|
||||
}
|
||||
|
|
@ -141,8 +140,7 @@ function openAltChannel() {
|
|||
chan.asyncOpen(new ChannelListener(readAltContent, null));
|
||||
}
|
||||
|
||||
function readAltContent(request, buffer)
|
||||
{
|
||||
function readAltContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(servedNotModified, true);
|
||||
|
|
@ -153,12 +151,11 @@ function readAltContent(request, buffer)
|
|||
cc.getOriginalInputStream({
|
||||
onInputStreamReady(aInputStream) {
|
||||
executeSoon(() => readOriginalInputStream(aInputStream));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function readOriginalInputStream(aInputStream)
|
||||
{
|
||||
function readOriginalInputStream(aInputStream) {
|
||||
// We expect the async stream length to match the expected content.
|
||||
// If the test times out, it's probably because of this.
|
||||
try {
|
||||
|
|
@ -171,8 +168,7 @@ function readOriginalInputStream(aInputStream)
|
|||
}
|
||||
}
|
||||
|
||||
function requestAgain()
|
||||
{
|
||||
function requestAgain() {
|
||||
shouldPassRevalidation = false;
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
|
@ -180,8 +176,7 @@ function requestAgain()
|
|||
chan.asyncOpen(new ChannelListener(readEmptyAltContent, null));
|
||||
}
|
||||
|
||||
function readEmptyAltContent(request, buffer)
|
||||
{
|
||||
function readEmptyAltContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
// the cache is overwrite and the alt-data is reset
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpServer.identity.primaryPort + "/content";
|
||||
|
|
@ -20,36 +20,35 @@ XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
|||
var httpServer = null;
|
||||
|
||||
function make_channel(url) {
|
||||
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
|
||||
return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
|
||||
}
|
||||
|
||||
const responseContent = "response body";
|
||||
// We need a large content in order to make sure that the IPDL stream is cut
|
||||
// into several different chunks.
|
||||
// We fill each chunk with a different character for easy debugging.
|
||||
const altContent = "a".repeat(128*1024) +
|
||||
"b".repeat(128*1024) +
|
||||
"c".repeat(128*1024) +
|
||||
"d".repeat(128*1024) +
|
||||
"e".repeat(128*1024) +
|
||||
"f".repeat(128*1024) +
|
||||
"g".repeat(128*1024) +
|
||||
"h".repeat(128*1024) +
|
||||
"i".repeat(13); // Just so the chunk size doesn't match exactly.
|
||||
const altContent =
|
||||
"a".repeat(128 * 1024) +
|
||||
"b".repeat(128 * 1024) +
|
||||
"c".repeat(128 * 1024) +
|
||||
"d".repeat(128 * 1024) +
|
||||
"e".repeat(128 * 1024) +
|
||||
"f".repeat(128 * 1024) +
|
||||
"g".repeat(128 * 1024) +
|
||||
"h".repeat(128 * 1024) +
|
||||
"i".repeat(13); // Just so the chunk size doesn't match exactly.
|
||||
|
||||
const firstChunkSize = Math.floor(altContent.length / 4);
|
||||
const altContentType = "text/binary";
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
function contentHandler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.setHeader("Cache-Control", "max-age=86400");
|
||||
|
||||
response.bodyOutputStream.write(responseContent, responseContent.length);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
httpServer = new HttpServer();
|
||||
httpServer.registerPathHandler("/content", contentHandler);
|
||||
|
|
@ -67,8 +66,7 @@ function run_test()
|
|||
// Output stream used to write alt-data to the cache entry.
|
||||
var os;
|
||||
|
||||
function readServerContent(request, buffer)
|
||||
{
|
||||
function readServerContent(request, buffer) {
|
||||
var cc = request.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
|
||||
Assert.equal(buffer, responseContent);
|
||||
|
|
@ -83,8 +81,7 @@ function readServerContent(request, buffer)
|
|||
});
|
||||
}
|
||||
|
||||
function openAltChannel()
|
||||
{
|
||||
function openAltChannel() {
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType, "", true);
|
||||
|
|
@ -94,7 +91,7 @@ function openAltChannel()
|
|||
|
||||
var altDataListener = {
|
||||
buffer: "",
|
||||
onStartRequest(request) { },
|
||||
onStartRequest(request) {},
|
||||
onDataAvailable(request, stream, offset, count) {
|
||||
let string = NetUtil.readInputStreamToString(stream, count);
|
||||
this.buffer += string;
|
||||
|
|
@ -104,7 +101,10 @@ var altDataListener = {
|
|||
// data in the first chunk.
|
||||
if (this.buffer.length == firstChunkSize) {
|
||||
// write the rest of the content
|
||||
os.write(altContent.substring(firstChunkSize, altContent.length), altContent.length - firstChunkSize);
|
||||
os.write(
|
||||
altContent.substring(firstChunkSize, altContent.length),
|
||||
altContent.length - firstChunkSize
|
||||
);
|
||||
os.close();
|
||||
}
|
||||
},
|
||||
|
|
@ -117,8 +117,7 @@ var altDataListener = {
|
|||
},
|
||||
};
|
||||
|
||||
function openAltChannelWithOriginalContent()
|
||||
{
|
||||
function openAltChannelWithOriginalContent() {
|
||||
var chan = make_channel(URL);
|
||||
var cc = chan.QueryInterface(Ci.nsICacheInfoChannel);
|
||||
cc.preferAlternativeDataType(altContentType, "", false);
|
||||
|
|
@ -128,7 +127,7 @@ function openAltChannelWithOriginalContent()
|
|||
|
||||
var originalListener = {
|
||||
buffer: "",
|
||||
onStartRequest(request) { },
|
||||
onStartRequest(request) {},
|
||||
onDataAvailable(request, stream, offset, count) {
|
||||
let string = NetUtil.readInputStreamToString(stream, count);
|
||||
this.buffer += string;
|
||||
|
|
@ -142,12 +141,11 @@ var originalListener = {
|
|||
},
|
||||
};
|
||||
|
||||
function testAltDataStream(cc)
|
||||
{
|
||||
function testAltDataStream(cc) {
|
||||
cc.getAltDataInputStream(altContentType, {
|
||||
onInputStreamReady(aInputStream) {
|
||||
Assert.ok(!!aInputStream);
|
||||
httpServer.stop(do_test_finished);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue