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
|
||||
|
|
@ -19,8 +17,11 @@ const PR_UINT32_MAX = 0xffffffff;
|
|||
|
||||
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
|
||||
|
|
@ -43,8 +44,7 @@ var NetUtil = {
|
|||
* can be used to cancel the copying). The consumer can ignore the
|
||||
* return value if desired.
|
||||
*/
|
||||
asyncCopy: function NetUtil_asyncCopy(aSource, aSink,
|
||||
aCallback = null) {
|
||||
asyncCopy: function NetUtil_asyncCopy(aSource, aSink, aCallback = null) {
|
||||
if (!aSource || !aSink) {
|
||||
let exception = new Components.Exception(
|
||||
"Must have a source and a sink",
|
||||
|
|
@ -55,12 +55,17 @@ var NetUtil = {
|
|||
}
|
||||
|
||||
// make a stream copier
|
||||
var copier = Cc["@mozilla.org/network/async-stream-copier;1"].
|
||||
createInstance(Ci.nsIAsyncStreamCopier2);
|
||||
copier.init(aSource, aSink,
|
||||
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 */);
|
||||
true,
|
||||
true /* Auto-close */
|
||||
);
|
||||
|
||||
var observer;
|
||||
if (aCallback) {
|
||||
|
|
@ -109,13 +114,13 @@ var NetUtil = {
|
|||
|
||||
// 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);
|
||||
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);
|
||||
let listener = Cc[
|
||||
"@mozilla.org/network/simple-stream-listener;1"
|
||||
].createInstance(Ci.nsISimpleStreamListener);
|
||||
listener.init(pipe.outputStream, {
|
||||
onStartRequest(aRequest) {},
|
||||
onStopRequest(aRequest, aStatusCode) {
|
||||
|
|
@ -126,8 +131,9 @@ var NetUtil = {
|
|||
|
||||
// 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);
|
||||
let pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(
|
||||
Ci.nsIInputStreamPump
|
||||
);
|
||||
pump.init(aSource, 0, 0, true);
|
||||
pump.asyncRead(listener, null);
|
||||
return;
|
||||
|
|
@ -226,13 +232,15 @@ var NetUtil = {
|
|||
);
|
||||
}
|
||||
|
||||
let { uri,
|
||||
let {
|
||||
uri,
|
||||
loadingNode,
|
||||
loadingPrincipal,
|
||||
loadUsingSystemPrincipal,
|
||||
triggeringPrincipal,
|
||||
securityFlags,
|
||||
contentPolicyType } = aWhatToLoad;
|
||||
contentPolicyType,
|
||||
} = aWhatToLoad;
|
||||
|
||||
if (!uri) {
|
||||
throw new Components.Exception(
|
||||
|
|
@ -266,8 +274,7 @@ var NetUtil = {
|
|||
Components.stack.caller
|
||||
);
|
||||
}
|
||||
loadingPrincipal = Services.scriptSecurityManager
|
||||
.getSystemPrincipal();
|
||||
loadingPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
} else if (loadUsingSystemPrincipal !== undefined) {
|
||||
throw new Components.Exception(
|
||||
"newChannel requires the 'loadUsingSystemPrincipal'" +
|
||||
|
|
@ -301,12 +308,14 @@ var NetUtil = {
|
|||
contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
|
||||
}
|
||||
|
||||
return Services.io.newChannelFromURI(uri,
|
||||
return Services.io.newChannelFromURI(
|
||||
uri,
|
||||
loadingNode || null,
|
||||
loadingPrincipal || null,
|
||||
triggeringPrincipal || null,
|
||||
securityFlags,
|
||||
contentPolicyType);
|
||||
contentPolicyType
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -332,9 +341,11 @@ var NetUtil = {
|
|||
* aCount amount of data.
|
||||
* @throws NS_ERROR_ILLEGAL_INPUT if aInputStream has invalid sequences
|
||||
*/
|
||||
readInputStreamToString: function NetUtil_readInputStreamToString(aInputStream,
|
||||
readInputStreamToString: function NetUtil_readInputStreamToString(
|
||||
aInputStream,
|
||||
aCount,
|
||||
aOptions) {
|
||||
aOptions
|
||||
) {
|
||||
if (!(aInputStream instanceof Ci.nsIInputStream)) {
|
||||
let exception = new Components.Exception(
|
||||
"First argument should be an nsIInputStream",
|
||||
|
|
@ -354,8 +365,9 @@ var NetUtil = {
|
|||
}
|
||||
|
||||
if (aOptions && "charset" in aOptions) {
|
||||
let cis = Cc["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Ci.nsIConverterInputStream);
|
||||
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.
|
||||
|
|
@ -366,28 +378,36 @@ var NetUtil = {
|
|||
aOptions.replacement = 0;
|
||||
}
|
||||
|
||||
cis.init(aInputStream, aOptions.charset, aCount,
|
||||
aOptions.replacement);
|
||||
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);
|
||||
throw new Components.Exception(
|
||||
e.message,
|
||||
e.result,
|
||||
Components.stack.caller,
|
||||
e.data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(Ci.nsIScriptableInputStream);
|
||||
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);
|
||||
throw new Components.Exception(
|
||||
e.message,
|
||||
e.result,
|
||||
Components.stack.caller,
|
||||
e.data
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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,15 +2,25 @@ 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 => {
|
||||
await content
|
||||
.fetch("server.sjs")
|
||||
.then(r => r.text())
|
||||
.then(text => {
|
||||
is(text, "cookie-present", "We should have cookies");
|
||||
});
|
||||
|
||||
|
|
@ -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 => {
|
||||
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 => {
|
||||
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!");
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ async function openTabInUserContext(uri, userContextId) {
|
|||
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
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -43,13 +44,15 @@ add_task(async function test() {
|
|||
// open our tab in the given user context
|
||||
let { tab, browser } = await openTabInUserContext(TEST_URL, userContextId);
|
||||
|
||||
await ContentTask.spawn(browser,
|
||||
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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
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));
|
||||
_ => {
|
||||
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,7 +20,8 @@ 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,
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.cookieJarAccessDenied,
|
||||
config.prefs,
|
||||
|
|
@ -29,10 +30,12 @@ this.CookiePolicyHelper = {
|
|||
toBehavior: BEHAVIOR_REJECT,
|
||||
fromPermission: PERM_DEFAULT,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Testing blocked to allowed by cookie behavior
|
||||
this._createTest(testName,
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessDenied,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.prefs,
|
||||
|
|
@ -41,10 +44,12 @@ this.CookiePolicyHelper = {
|
|||
toBehavior: BEHAVIOR_ACCEPT,
|
||||
fromPermission: PERM_DEFAULT,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Testing allowed to blocked by cookie permission
|
||||
this._createTest(testName,
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.cookieJarAccessDenied,
|
||||
config.prefs,
|
||||
|
|
@ -53,10 +58,12 @@ this.CookiePolicyHelper = {
|
|||
toBehavior: BEHAVIOR_REJECT,
|
||||
fromPermission: PERM_ALLOW,
|
||||
toPermission: PERM_DEFAULT,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Testing blocked to allowed by cookie permission
|
||||
this._createTest(testName,
|
||||
this._createTest(
|
||||
testName,
|
||||
config.cookieJarAccessDenied,
|
||||
config.cookieJarAccessAllowed,
|
||||
config.prefs,
|
||||
|
|
@ -65,7 +72,8 @@ this.CookiePolicyHelper = {
|
|||
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,8 +113,14 @@ 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,
|
||||
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});})();`;
|
||||
|
|
@ -116,17 +129,24 @@ this.CookiePolicyHelper = {
|
|||
|
||||
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,
|
||||
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});})();`;
|
||||
|
|
@ -135,7 +155,8 @@ this.CookiePolicyHelper = {
|
|||
|
||||
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,
|
||||
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 |
|
||||
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, ___ => {
|
||||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ 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,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,14 +7,16 @@ 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 (" +
|
||||
conn.executeSimpleSQL(
|
||||
"CREATE TABLE moz_cookies (" +
|
||||
"id INTEGER PRIMARY KEY, " +
|
||||
"baseDomain TEXT, " +
|
||||
"originAttributes TEXT NOT NULL DEFAULT '', " +
|
||||
|
|
@ -30,29 +32,41 @@ conn.executeSimpleSQL("CREATE TABLE moz_cookies (" +
|
|||
"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 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(" +
|
||||
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 +
|
||||
", " +
|
||||
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 " +
|
||||
let stmt = conn.createStatement(
|
||||
"SELECT sql FROM sqlite_master " +
|
||||
"WHERE type = 'table' AND " +
|
||||
" name = 'moz_cookies'");
|
||||
" 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 " +
|
||||
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 " +
|
||||
" expiry = " +
|
||||
now +
|
||||
" AND " +
|
||||
" lastAccessed = " +
|
||||
now +
|
||||
" AND " +
|
||||
" creationTime = " +
|
||||
now +
|
||||
" AND " +
|
||||
" isSecure = 1 AND " +
|
||||
" isHttpOnly = 1");
|
||||
" isHttpOnly = 1"
|
||||
);
|
||||
try {
|
||||
Assert.ok(stmt.executeStep());
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -23,4 +23,3 @@ function run_test() {
|
|||
actual = cs.getCookieString(uri, null, null);
|
||||
Assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,50 +29,80 @@ async function test_basic_eviction(base_host) {
|
|||
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",
|
||||
verifyCookies(
|
||||
[
|
||||
"session_foo_path_1",
|
||||
"session_foo_path_2",
|
||||
"session_foo_path_3",
|
||||
"session_foo_path_4",
|
||||
"session_foo_path_5"], BASE_URI);
|
||||
"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);
|
||||
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);
|
||||
|
||||
verifyCookies(["session_foo_path_4",
|
||||
verifyCookies(
|
||||
[
|
||||
"session_foo_path_4",
|
||||
"session_foo_path_5",
|
||||
"session_foo_path_6",
|
||||
"session_bar_path_1",
|
||||
"session_bar_path_2"], BASE_URI);
|
||||
"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);
|
||||
verifyCookies(
|
||||
["session_foo_path_5", "session_foo_path_6", "session_foo_path_7"],
|
||||
BASE_URI
|
||||
);
|
||||
|
||||
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",
|
||||
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);
|
||||
"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);
|
||||
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
|
||||
|
|
@ -84,15 +114,23 @@ function verifyCookies(names, uri) {
|
|||
}
|
||||
if (names.length != actual_cookies.length) {
|
||||
let left = names.filter(function(n) {
|
||||
return actual_cookies.findIndex(function(c) {
|
||||
return (
|
||||
actual_cookies.findIndex(function(c) {
|
||||
return c.name == n;
|
||||
}) == -1;
|
||||
}) == -1
|
||||
);
|
||||
});
|
||||
let right = actual_cookies.filter(function(c) {
|
||||
return names.findIndex(function(n) {
|
||||
let right = actual_cookies
|
||||
.filter(function(c) {
|
||||
return (
|
||||
names.findIndex(function(n) {
|
||||
return c.name == n;
|
||||
}) == -1;
|
||||
}).map(function(c) { return c.name; });
|
||||
}) == -1
|
||||
);
|
||||
})
|
||||
.map(function(c) {
|
||||
return c.name;
|
||||
});
|
||||
if (left.length) {
|
||||
info("unexpected cookies: " + left);
|
||||
}
|
||||
|
|
@ -102,10 +140,12 @@ function verifyCookies(names, uri) {
|
|||
}
|
||||
Assert.equal(names.length, actual_cookies.length);
|
||||
actual_cookies.sort(function(a, b) {
|
||||
if (a.lastAccessed < b.lastAccessed)
|
||||
if (a.lastAccessed < b.lastAccessed) {
|
||||
return -1;
|
||||
if (a.lastAccessed > b.lastAccessed)
|
||||
}
|
||||
if (a.lastAccessed > b.lastAccessed) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 { 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"))
|
||||
AppConstants.platform == "android" &&
|
||||
!Services.prefs.getBoolPref("network.mdns.use_js_fallback")
|
||||
? "resource://gre/modules/MulticastDNSAndroid.jsm"
|
||||
: "resource://gre/modules/MulticastDNS.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) {
|
||||
|
|
@ -56,8 +70,9 @@ ListenerWrapper.prototype = {
|
|||
} 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);
|
||||
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: {},
|
||||
|
|
@ -148,8 +154,8 @@ function parsePropertyBag2(bag) {
|
|||
for (let { name } of bag.enumerator) {
|
||||
let value = bag.getPropertyAsACString(name);
|
||||
attributes.push({
|
||||
"name": name,
|
||||
"value": value,
|
||||
name,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,18 @@ var EXPORTED_SYMBOLS = ["DNSPacket"];
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -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());
|
||||
});
|
||||
});
|
||||
|
|
@ -223,11 +235,11 @@ class DNSPacket {
|
|||
|
||||
toJSONObject() {
|
||||
let result = { flags: this._flags };
|
||||
DNS_PACKET_SECTION_TYPES.forEach((sectionType) => {
|
||||
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,8 +8,12 @@
|
|||
|
||||
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 = {}) {
|
||||
|
|
@ -23,7 +27,7 @@ class DNSRecord {
|
|||
let name = reader.getLabel();
|
||||
let recordType = reader.getValue(2);
|
||||
let classCode = reader.getValue(2);
|
||||
let cacheFlush = !!((classCode & 0x8000));
|
||||
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
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -9,17 +9,31 @@
|
|||
var EXPORTED_SYMBOLS = ["MulticastDNS"];
|
||||
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {clearTimeout, setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.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;
|
||||
|
||||
|
|
@ -32,9 +46,18 @@ function debug(msg) {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
|
@ -111,7 +136,13 @@ class MulticastDNS {
|
|||
|
||||
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,7 +337,8 @@ class MulticastDNS {
|
|||
return;
|
||||
}
|
||||
|
||||
DEBUG && debug("_respondToQuery(): key=" + serviceKey + ": SENDING RESPONSE");
|
||||
DEBUG &&
|
||||
debug("_respondToQuery(): key=" + serviceKey + ": SENDING RESPONSE");
|
||||
this._advertiseServiceHelper(publishedService, { address, port });
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +346,11 @@ class MulticastDNS {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +375,7 @@ class MulticastDNS {
|
|||
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;
|
||||
}
|
||||
|
|
@ -375,8 +442,16 @@ class MulticastDNS {
|
|||
|
||||
// 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({
|
||||
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,17 +548,23 @@ 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({
|
||||
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({
|
||||
packet.addRecord(
|
||||
"AR",
|
||||
new DNSResourceRecord({
|
||||
name: serviceDomainName,
|
||||
recordType: DNS_RECORD_TYPES.SRV,
|
||||
classCode: DNS_CLASS_CODES.IN,
|
||||
|
|
@ -486,25 +575,32 @@ class MulticastDNS {
|
|||
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({
|
||||
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,13 +632,13 @@ 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;
|
||||
|
|
@ -553,7 +649,9 @@ class MulticastDNS {
|
|||
return;
|
||||
}
|
||||
|
||||
let { serviceName, serviceType, domainName } = _parseServiceDomainName(name);
|
||||
let { serviceName, serviceType, domainName } = _parseServiceDomainName(
|
||||
name
|
||||
);
|
||||
if (!serviceName || !serviceType || !domainName) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -579,11 +677,16 @@ class MulticastDNS {
|
|||
}
|
||||
|
||||
_onServiceFound(serviceInfo, ttl = 0) {
|
||||
let expireTime = Date.now() + (ttl * 1000);
|
||||
let key = serviceInfo.serviceName + "." +
|
||||
serviceInfo.serviceType + "." +
|
||||
serviceInfo.domainName + " @" +
|
||||
serviceInfo.address + ":" +
|
||||
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
|
||||
|
|
@ -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, {
|
||||
this._broadcastReceiverSocket = _openSocket(
|
||||
"0.0.0.0",
|
||||
MDNS_PORT,
|
||||
{
|
||||
onPacketReceived: this._onPacketReceived.bind(this),
|
||||
onStopListening: this._onStopListening.bind(this),
|
||||
}, /* multicastInterface = */ "0.0.0.0");
|
||||
},
|
||||
/* 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
|
||||
_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.
|
||||
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({
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
"use strict";
|
||||
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {UserAgentOverrides} = ChromeUtils.import("resource://gre/modules/UserAgentOverrides.jsm");
|
||||
const { UserAgentOverrides } = ChromeUtils.import(
|
||||
"resource://gre/modules/UserAgentOverrides.jsm"
|
||||
);
|
||||
|
||||
function UAOverridesBootstrapper() {
|
||||
this.init();
|
||||
|
|
|
|||
|
|
@ -6,34 +6,41 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["UserAgentOverrides"];
|
||||
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.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 { 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 { 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 { 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) => {
|
||||
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 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) => {
|
||||
}, 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);
|
||||
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) => {
|
||||
})
|
||||
.then(update => {
|
||||
// Apply update if loading was successful
|
||||
this._applyUpdate(update);
|
||||
}).catch(Cu.reportError);
|
||||
})
|
||||
.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(
|
||||
() => {
|
||||
OS.File.writeAtomic(path, bytes, { tmpPath: path + ".tmp" }).then(() => {
|
||||
this._lastUpdated = Date.now();
|
||||
Services.prefs.setCharPref(
|
||||
PREF_UPDATES_LASTUPDATED, this._lastUpdated.toString());
|
||||
},
|
||||
Cu.reportError
|
||||
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
|
||||
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
|
||||
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]),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: "https://untrusted.example.com",
|
||||
loadUsingSystemPrincipal: true
|
||||
}, 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 again with a channel whose notificationCallbacks doesn't suprress errors
|
||||
let channel = NetUtil.newChannel({
|
||||
uri: "https://untrusted.example.com",
|
||||
loadUsingSystemPrincipal: true});
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
channel.notificationCallbacks = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIProgressEventSink,
|
||||
Ci.nsIInterfaceRequestor]),
|
||||
getInterface (aIID) { return this.QueryInterface(aIID); },
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIProgressEventSink,
|
||||
Ci.nsIInterfaceRequestor,
|
||||
]),
|
||||
getInterface(aIID) {
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
onProgress() {},
|
||||
onStatus () {}
|
||||
onStatus() {},
|
||||
};
|
||||
NetUtil.asyncFetch(channel, function (aInputStream, aStatusCode, aRequest) {
|
||||
NetUtil.asyncFetch(channel, function(
|
||||
aInputStream,
|
||||
aStatusCode,
|
||||
aRequest
|
||||
) {
|
||||
ok(!Components.isSuccessCode(aStatusCode), "request failed");
|
||||
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
|
||||
ok(
|
||||
aRequest instanceof Ci.nsIHttpChannel,
|
||||
"request is an nsIHttpChannel"
|
||||
);
|
||||
|
||||
// Now try a valid request
|
||||
NetUtil.asyncFetch({
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: "https://example.com",
|
||||
loadUsingSystemPrincipal: true
|
||||
}, function (aInputStream, aStatusCode, aRequest) {
|
||||
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 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)
|
||||
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});
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
},
|
||||
onCloseWindow(aXULWindow) {},
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,27 +4,47 @@
|
|||
* 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");
|
||||
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) {
|
||||
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);
|
||||
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, "",
|
||||
};
|
||||
registrar.registerFactory(
|
||||
childListener.classID,
|
||||
"",
|
||||
"@mozilla.org/network/childProcessChannelListener;1",
|
||||
childListener);
|
||||
});
|
||||
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,8 +163,9 @@ 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 = {
|
||||
|
|
@ -175,7 +179,7 @@ document.getElementById('form').submit();
|
|||
try {
|
||||
aListener.onStopRequest(this, null, Cr.NS_OK);
|
||||
} catch (e) {}
|
||||
}
|
||||
},
|
||||
};
|
||||
Services.tm.dispatchToMainThread(runnable);
|
||||
},
|
||||
|
|
@ -192,7 +196,8 @@ document.getElementById('form').submit();
|
|||
},
|
||||
cancel(status) {},
|
||||
loadGroup: null,
|
||||
loadFlags: Ci.nsIRequest.LOAD_NORMAL |
|
||||
loadFlags:
|
||||
Ci.nsIRequest.LOAD_NORMAL |
|
||||
Ci.nsIRequest.INHIBIT_CACHING |
|
||||
Ci.nsIRequest.LOAD_BYPASS_CACHE,
|
||||
};
|
||||
|
|
@ -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, "",
|
||||
registrar.registerFactory(
|
||||
handler.classID,
|
||||
"",
|
||||
"@mozilla.org/network/protocol;1?name=" + handler.scheme,
|
||||
handler);
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -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,10 +8,14 @@
|
|||
add_task(async function() {
|
||||
info("Make sure navigation through links in resource:// pages work");
|
||||
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "resource://gre/" }, async function(browser) {
|
||||
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 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.
|
||||
|
|
@ -19,35 +23,54 @@ add_task(async function() {
|
|||
name = name.slice(0, -1);
|
||||
}
|
||||
return name == "components";
|
||||
})[0];
|
||||
}
|
||||
)[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];
|
||||
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) {
|
||||
let link = Array.prototype.filter.call(
|
||||
content.document.getElementsByClassName("file"),
|
||||
function(element) {
|
||||
return element.textContent == "greprefs.js";
|
||||
})[0];
|
||||
}
|
||||
)[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!");
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
@ -17,18 +19,16 @@ var gotEmptyData = false;
|
|||
function processResults(results) {
|
||||
for (let data of results) {
|
||||
console.log(data.location);
|
||||
gotEmptyData = data.rx == 0 && data.tx == 0 && !gotEmptyData
|
||||
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],
|
||||
]
|
||||
set: [["io.activity.enabled", true]],
|
||||
});
|
||||
waitForExplicitFinish();
|
||||
Services.obs.notifyObservers(null, "profile-initial-state");
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -13,7 +13,9 @@ 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 { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
/**
|
||||
|
|
@ -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,15 +110,19 @@ 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) {
|
||||
throw new Error(
|
||||
|
|
@ -148,9 +159,10 @@ function writeDetails(request, response) {
|
|||
*/
|
||||
function skipHeaders(iter) {
|
||||
var line = iter.next().value;
|
||||
while (line !== "")
|
||||
while (line !== "") {
|
||||
line = iter.next().value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the exception e (which may be an XPConnect-created exception
|
||||
|
|
@ -162,9 +174,10 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the given function at least the specified number of milliseconds later.
|
||||
|
|
@ -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();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -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,8 +285,7 @@ function runHttpTests(testArray, done) {
|
|||
var testIndex = -1;
|
||||
|
||||
/** Stream listener for the channels. */
|
||||
var listener =
|
||||
{
|
||||
var listener = {
|
||||
/** Current channel being observed by this. */
|
||||
_channel: null,
|
||||
/** Array of bytes of data in body of response. */
|
||||
|
|
@ -277,7 +293,8 @@ function runHttpTests(testArray, done) {
|
|||
|
||||
onStartRequest(request) {
|
||||
Assert.ok(request === this._channel);
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
this._data.length = 0;
|
||||
|
|
@ -285,11 +302,17 @@ function runHttpTests(testArray, done) {
|
|||
try {
|
||||
testArray[testIndex].onStartRequest(ch);
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e, "testArray[" + testIndex + "].onStartRequest");
|
||||
do_report_unexpected_exception(
|
||||
e,
|
||||
"testArray[" + testIndex + "].onStartRequest"
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
do_note_exception(e, "!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called...");
|
||||
do_note_exception(
|
||||
e,
|
||||
"!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called..."
|
||||
);
|
||||
}
|
||||
},
|
||||
onDataAvailable(request, inputStream, offset, count) {
|
||||
|
|
@ -303,7 +326,8 @@ function runHttpTests(testArray, done) {
|
|||
onStopRequest(request, status) {
|
||||
this._channel = null;
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
// NB: The onStopRequest callback must run before performNextTest here,
|
||||
|
|
@ -320,13 +344,15 @@ function runHttpTests(testArray, done) {
|
|||
}
|
||||
}
|
||||
},
|
||||
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,11 +414,11 @@ 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()
|
||||
var currentThread = Cc["@mozilla.org/thread-manager;1"].getService()
|
||||
.currentThread;
|
||||
|
||||
/** Kicks off running the next test in the array. */
|
||||
|
|
@ -402,13 +436,14 @@ 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);
|
||||
|
|
@ -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,8 +488,7 @@ function runRawTests(testArray, done, beforeTestCallback) {
|
|||
var received = "";
|
||||
|
||||
/** Reads data from the socket. */
|
||||
var reader =
|
||||
{
|
||||
var reader = {
|
||||
onInputStreamReady(stream) {
|
||||
Assert.ok(stream === this.stream);
|
||||
try {
|
||||
|
|
@ -494,18 +532,18 @@ function runRawTests(testArray, done, beforeTestCallback) {
|
|||
};
|
||||
|
||||
/** Writes data to the socket. */
|
||||
var writer =
|
||||
{
|
||||
var writer = {
|
||||
onOutputStreamReady(stream) {
|
||||
var str = testArray[testIndex].data[dataIndex];
|
||||
|
||||
var written = 0;
|
||||
try {
|
||||
written = stream.write(str, str.length);
|
||||
if (written == str.length)
|
||||
if (written == str.length) {
|
||||
dataIndex++;
|
||||
else
|
||||
} else {
|
||||
testArray[testIndex].data[dataIndex] = str.substring(written);
|
||||
}
|
||||
} catch (e) {
|
||||
do_note_exception(e);
|
||||
/* stream could have been closed, just ignore */
|
||||
|
|
@ -514,10 +552,11 @@ function runRawTests(testArray, done, beforeTestCallback) {
|
|||
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)
|
||||
if (written > 0 && dataIndex < testArray[testIndex].data.length) {
|
||||
waitToWriteOutput(stream);
|
||||
else
|
||||
} else {
|
||||
stream.close();
|
||||
}
|
||||
} catch (e) {
|
||||
do_report_unexpected_exception(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/. */
|
||||
|
||||
|
||||
/*
|
||||
* Ensures that data a request handler writes out in response is sent only as
|
||||
* quickly as the client can receive it, without racing ahead and being forced
|
||||
|
|
@ -22,9 +21,9 @@ gThreadManager = Cc["@mozilla.org/thread-manager;1"].createInstance();
|
|||
function run_test() {
|
||||
do_test_pending();
|
||||
tests.push(function testsComplete(_) {
|
||||
dumpn("******************\n" +
|
||||
"* TESTS COMPLETE *\n" +
|
||||
"******************");
|
||||
dumpn(
|
||||
"******************\n" + "* TESTS COMPLETE *\n" + "******************"
|
||||
);
|
||||
do_test_finished();
|
||||
});
|
||||
|
||||
|
|
@ -40,13 +39,13 @@ function runNextTest() {
|
|||
test(runNextTest);
|
||||
} catch (e) {
|
||||
var msg = "exception running test " + testIndex + ": " + e;
|
||||
if (e && "stack" in e)
|
||||
if (e && "stack" in e) {
|
||||
msg += "\nstack follows:\n" + e.stack;
|
||||
}
|
||||
do_throw(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** ***********
|
||||
* TEST DATA *
|
||||
*************/
|
||||
|
|
@ -76,13 +75,11 @@ const LATTER_HALF_THIRD_SEGMENT = [11, 12];
|
|||
|
||||
const TWO_HALF_SEGMENTS = [1, 2, 1, 2];
|
||||
|
||||
|
||||
/** *******
|
||||
* TESTS *
|
||||
*********/
|
||||
|
||||
var tests =
|
||||
[
|
||||
var tests = [
|
||||
sourceClosedWithoutWrite,
|
||||
writeOneSegmentThenClose,
|
||||
simpleWriteThenRead,
|
||||
|
|
@ -149,8 +146,10 @@ function writeMultipleSegmentsThenRead(next) {
|
|||
|
||||
t.addToSource(TWO_SEGMENTS);
|
||||
t.makeSourceReadable(TWO_SEGMENTS.length);
|
||||
t.makeSinkWritableAndWaitFor(TWO_SEGMENTS.length,
|
||||
[FIRST_SEGMENT, SECOND_SEGMENT]);
|
||||
t.makeSinkWritableAndWaitFor(TWO_SEGMENTS.length, [
|
||||
FIRST_SEGMENT,
|
||||
SECOND_SEGMENT,
|
||||
]);
|
||||
t.closeSource(Cr.NS_OK);
|
||||
t.expect(Cr.NS_OK, [TWO_SEGMENTS]);
|
||||
}
|
||||
|
|
@ -229,23 +228,28 @@ function partialWrite(next) {
|
|||
|
||||
t.addToSource(SEGMENT);
|
||||
t.makeSourceReadable(SEGMENT.length);
|
||||
t.makeSinkWritableByIncrementsAndWaitFor(SEGMENT.length,
|
||||
[QUARTER_SEGMENT,
|
||||
t.makeSinkWritableByIncrementsAndWaitFor(SEGMENT.length, [
|
||||
QUARTER_SEGMENT,
|
||||
MIDDLE_HALF_SEGMENT,
|
||||
LAST_QUARTER_SEGMENT]);
|
||||
LAST_QUARTER_SEGMENT,
|
||||
]);
|
||||
|
||||
t.addToSource(SEGMENT);
|
||||
t.makeSourceReadable(SEGMENT.length);
|
||||
t.makeSinkWritableByIncrementsAndWaitFor(SEGMENT.length,
|
||||
[HALF_SEGMENT, SECOND_HALF_SEGMENT]);
|
||||
t.makeSinkWritableByIncrementsAndWaitFor(SEGMENT.length, [
|
||||
HALF_SEGMENT,
|
||||
SECOND_HALF_SEGMENT,
|
||||
]);
|
||||
|
||||
t.addToSource(THREE_SEGMENTS);
|
||||
t.makeSourceReadable(THREE_SEGMENTS.length);
|
||||
t.makeSinkWritableByIncrementsAndWaitFor(THREE_SEGMENTS.length,
|
||||
[HALF_SEGMENT, SECOND_HALF_SEGMENT,
|
||||
t.makeSinkWritableByIncrementsAndWaitFor(THREE_SEGMENTS.length, [
|
||||
HALF_SEGMENT,
|
||||
SECOND_HALF_SEGMENT,
|
||||
SECOND_SEGMENT,
|
||||
HALF_THIRD_SEGMENT,
|
||||
LATTER_HALF_THIRD_SEGMENT]);
|
||||
LATTER_HALF_THIRD_SEGMENT,
|
||||
]);
|
||||
|
||||
t.closeSource(Cr.NS_OK);
|
||||
t.expect(Cr.NS_OK, [SEGMENT, SEGMENT, THREE_SEGMENTS]);
|
||||
|
|
@ -317,7 +321,6 @@ function sinkAndSourceClosedWithPendingData(next) {
|
|||
t.expect(Cr.NS_ERROR_UNEXPECTED, []);
|
||||
}
|
||||
|
||||
|
||||
/** ***********
|
||||
* UTILITIES *
|
||||
*************/
|
||||
|
|
@ -325,8 +328,9 @@ function sinkAndSourceClosedWithPendingData(next) {
|
|||
/** Returns the sum of the elements in arr. */
|
||||
function sum(arr) {
|
||||
var s = 0;
|
||||
for (var i = 0, sz = arr.length; i < sz; i++)
|
||||
for (var i = 0, sz = arr.length; i < sz; i++) {
|
||||
s += arr[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +378,6 @@ function note(m) {
|
|||
dumpn(asterisks + "\n* " + m + " *\n" + asterisks);
|
||||
}
|
||||
|
||||
|
||||
/** *********
|
||||
* MOCKERY *
|
||||
***********/
|
||||
|
|
@ -384,8 +387,12 @@ function note(m) {
|
|||
* PUBLIC API! If you use any of these I will knowingly break your code by
|
||||
* changing the names of variables and properties.
|
||||
*/
|
||||
var BinaryInputStream = function BIS(stream) { return stream; };
|
||||
var BinaryOutputStream = function BOS(stream) { return stream; };
|
||||
var BinaryInputStream = function BIS(stream) {
|
||||
return stream;
|
||||
};
|
||||
var BinaryOutputStream = function BOS(stream) {
|
||||
return stream;
|
||||
};
|
||||
Response.SEGMENT_SIZE = SEGMENT.length;
|
||||
|
||||
/**
|
||||
|
|
@ -413,8 +420,7 @@ function CustomPipe(name) {
|
|||
this._status = Cr.NS_OK;
|
||||
|
||||
/** The input end of this pipe. */
|
||||
var input = this.inputStream =
|
||||
{
|
||||
var input = (this.inputStream = {
|
||||
/** A name for this stream, used in debugging output. */
|
||||
name: name + " input",
|
||||
|
||||
|
|
@ -452,12 +458,15 @@ function CustomPipe(name) {
|
|||
interceptStreamReadyCallbacks(streamReadyInterceptCreator) {
|
||||
dumpn("*** [" + this.name + "].interceptStreamReadyCallbacks");
|
||||
|
||||
Assert.ok(this._streamReadyInterceptCreator === null,
|
||||
"intercepting twice");
|
||||
Assert.ok(
|
||||
this._streamReadyInterceptCreator === null,
|
||||
"intercepting twice"
|
||||
);
|
||||
this._streamReadyInterceptCreator = streamReadyInterceptCreator;
|
||||
if (this._waiter) {
|
||||
this._waiter.callback =
|
||||
new streamReadyInterceptCreator(this._waiter.callback);
|
||||
this._waiter.callback = new streamReadyInterceptCreator(
|
||||
this._waiter.callback
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -468,11 +477,14 @@ function CustomPipe(name) {
|
|||
removeStreamReadyInterceptor() {
|
||||
dumpn("*** [" + this.name + "].removeStreamReadyInterceptor()");
|
||||
|
||||
Assert.ok(this._streamReadyInterceptCreator !== null,
|
||||
"removing interceptor when none present?");
|
||||
Assert.ok(
|
||||
this._streamReadyInterceptCreator !== null,
|
||||
"removing interceptor when none present?"
|
||||
);
|
||||
this._streamReadyInterceptCreator = null;
|
||||
if (this._waiter)
|
||||
if (this._waiter) {
|
||||
this._waiter.callback = this._waiter.callback.wrappedCallback;
|
||||
}
|
||||
},
|
||||
|
||||
//
|
||||
|
|
@ -486,15 +498,14 @@ function CustomPipe(name) {
|
|||
var closureOnly =
|
||||
(flags & Ci.nsIAsyncInputStream.WAIT_CLOSURE_ONLY) !== 0;
|
||||
|
||||
Assert.ok(this._waiter === null ||
|
||||
(this._waiter.closureOnly && !closureOnly),
|
||||
Assert.ok(
|
||||
this._waiter === null || (this._waiter.closureOnly && !closureOnly),
|
||||
"asyncWait already called with a non-closure-only " +
|
||||
"callback? unexpected!");
|
||||
"callback? unexpected!"
|
||||
);
|
||||
|
||||
this._waiter =
|
||||
{
|
||||
callback:
|
||||
this._streamReadyInterceptCreator
|
||||
this._waiter = {
|
||||
callback: this._streamReadyInterceptCreator
|
||||
? new this._streamReadyInterceptCreator(callback)
|
||||
: callback,
|
||||
closureOnly,
|
||||
|
|
@ -502,9 +513,12 @@ function CustomPipe(name) {
|
|||
eventTarget: target,
|
||||
};
|
||||
|
||||
if (!Components.isSuccessCode(self._status) ||
|
||||
(!closureOnly && this._readable >= requestedCount &&
|
||||
self._data.length >= requestedCount)) {
|
||||
if (
|
||||
!Components.isSuccessCode(self._status) ||
|
||||
(!closureOnly &&
|
||||
this._readable >= requestedCount &&
|
||||
self._data.length >= requestedCount)
|
||||
) {
|
||||
this._notify();
|
||||
}
|
||||
},
|
||||
|
|
@ -513,24 +527,32 @@ function CustomPipe(name) {
|
|||
// see nsIAsyncInputStream.closeWithStatus
|
||||
//
|
||||
closeWithStatus: function closeWithStatus(status) {
|
||||
dumpn("*** [" + this.name + "].closeWithStatus" +
|
||||
"(" + status + ")");
|
||||
dumpn("*** [" + this.name + "].closeWithStatus" + "(" + status + ")");
|
||||
|
||||
if (!Components.isSuccessCode(self._status)) {
|
||||
dumpn("*** ignoring second closure of [input " + this.name + "] " +
|
||||
"(status " + self._status + ")");
|
||||
dumpn(
|
||||
"*** ignoring second closure of [input " +
|
||||
this.name +
|
||||
"] " +
|
||||
"(status " +
|
||||
self._status +
|
||||
")"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Components.isSuccessCode(status))
|
||||
if (Components.isSuccessCode(status)) {
|
||||
status = Cr.NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
self._status = status;
|
||||
|
||||
if (this._waiter)
|
||||
if (this._waiter) {
|
||||
this._notify();
|
||||
if (output._waiter)
|
||||
}
|
||||
if (output._waiter) {
|
||||
output._notify();
|
||||
}
|
||||
},
|
||||
|
||||
//
|
||||
|
|
@ -545,12 +567,14 @@ function CustomPipe(name) {
|
|||
: self._status;
|
||||
}
|
||||
|
||||
Assert.ok(this._readable <= self._data.length ||
|
||||
this._readable === Infinity,
|
||||
"consistency check");
|
||||
Assert.ok(
|
||||
this._readable <= self._data.length || this._readable === Infinity,
|
||||
"consistency check"
|
||||
);
|
||||
|
||||
if (this._readable < count || self._data.length < count)
|
||||
if (this._readable < count || self._data.length < count) {
|
||||
throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
this._readable -= count;
|
||||
return self._data.splice(0, count);
|
||||
},
|
||||
|
|
@ -569,9 +593,11 @@ function CustomPipe(name) {
|
|||
dumpn("*** [" + this.name + "].makeReadable(" + count + ")");
|
||||
|
||||
Assert.ok(Components.isSuccessCode(self._status), "errant call");
|
||||
Assert.ok(this._readable + count <= self._data.length ||
|
||||
Assert.ok(
|
||||
this._readable + count <= self._data.length ||
|
||||
this._readable === Infinity,
|
||||
"increasing readable beyond written amount");
|
||||
"increasing readable beyond written amount"
|
||||
);
|
||||
|
||||
this._readable += count;
|
||||
|
||||
|
|
@ -579,9 +605,10 @@ function CustomPipe(name) {
|
|||
|
||||
var waiter = this._waiter;
|
||||
if (waiter !== null) {
|
||||
if (waiter.requestedCount <= this._readable && !waiter.closureOnly)
|
||||
if (waiter.requestedCount <= this._readable && !waiter.closureOnly) {
|
||||
this._notify();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -602,8 +629,9 @@ function CustomPipe(name) {
|
|||
available: function available() {
|
||||
dumpn("*** [" + this.name + "].available()");
|
||||
|
||||
if (self._data.length === 0 && !Components.isSuccessCode(self._status))
|
||||
if (self._data.length === 0 && !Components.isSuccessCode(self._status)) {
|
||||
throw self._status;
|
||||
}
|
||||
|
||||
return Math.min(this._readable, self._data.length);
|
||||
},
|
||||
|
|
@ -625,8 +653,10 @@ function CustomPipe(name) {
|
|||
Assert.ok(this._waiter !== null, "must be waiting now");
|
||||
|
||||
if (self._data.length > 0) {
|
||||
dumpn("*** data still pending, normal notifications will signal " +
|
||||
"completion");
|
||||
dumpn(
|
||||
"*** data still pending, normal notifications will signal " +
|
||||
"completion"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -651,30 +681,33 @@ function CustomPipe(name) {
|
|||
Assert.ok(waiter !== null, "no waiter?");
|
||||
|
||||
if (this._event === null) {
|
||||
var event = this._event =
|
||||
{
|
||||
var event = (this._event = {
|
||||
run: function run() {
|
||||
input._waiter = null;
|
||||
input._event = null;
|
||||
try {
|
||||
Assert.ok(!Components.isSuccessCode(self._status) ||
|
||||
input._readable >= waiter.requestedCount);
|
||||
Assert.ok(
|
||||
!Components.isSuccessCode(self._status) ||
|
||||
input._readable >= waiter.requestedCount
|
||||
);
|
||||
waiter.callback.onInputStreamReady(input);
|
||||
} catch (e) {
|
||||
do_throw("error calling onInputStreamReady: " + e);
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
waiter.eventTarget.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIAsyncInputStream", "nsIInputStream"]),
|
||||
};
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIAsyncInputStream",
|
||||
"nsIInputStream",
|
||||
]),
|
||||
});
|
||||
|
||||
/** The output end of this pipe. */
|
||||
var output = this.outputStream =
|
||||
{
|
||||
var output = (this.outputStream = {
|
||||
/** A name for this stream, used in debugging output. */
|
||||
name: name + " output",
|
||||
|
||||
|
|
@ -723,12 +756,15 @@ function CustomPipe(name) {
|
|||
interceptStreamReadyCallbacks(streamReadyInterceptCreator) {
|
||||
dumpn("*** [" + this.name + "].interceptStreamReadyCallbacks");
|
||||
|
||||
Assert.ok(this._streamReadyInterceptCreator !== null,
|
||||
"intercepting onOutputStreamReady twice");
|
||||
Assert.ok(
|
||||
this._streamReadyInterceptCreator !== null,
|
||||
"intercepting onOutputStreamReady twice"
|
||||
);
|
||||
this._streamReadyInterceptCreator = streamReadyInterceptCreator;
|
||||
if (this._waiter) {
|
||||
this._waiter.callback =
|
||||
new streamReadyInterceptCreator(this._waiter.callback);
|
||||
this._waiter.callback = new streamReadyInterceptCreator(
|
||||
this._waiter.callback
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -739,11 +775,14 @@ function CustomPipe(name) {
|
|||
removeStreamReadyInterceptor() {
|
||||
dumpn("*** [" + this.name + "].removeStreamReadyInterceptor()");
|
||||
|
||||
Assert.ok(this._streamReadyInterceptCreator !== null,
|
||||
"removing interceptor when none present?");
|
||||
Assert.ok(
|
||||
this._streamReadyInterceptCreator !== null,
|
||||
"removing interceptor when none present?"
|
||||
);
|
||||
this._streamReadyInterceptCreator = null;
|
||||
if (this._waiter)
|
||||
if (this._waiter) {
|
||||
this._waiter.callback = this._waiter.callback.wrappedCallback;
|
||||
}
|
||||
},
|
||||
|
||||
//
|
||||
|
|
@ -757,29 +796,36 @@ function CustomPipe(name) {
|
|||
var closureOnly =
|
||||
(flags & Ci.nsIAsyncInputStream.WAIT_CLOSURE_ONLY) !== 0;
|
||||
|
||||
Assert.ok(this._waiter === null ||
|
||||
(this._waiter.closureOnly && !closureOnly),
|
||||
Assert.ok(
|
||||
this._waiter === null || (this._waiter.closureOnly && !closureOnly),
|
||||
"asyncWait already called with a non-closure-only " +
|
||||
"callback? unexpected!");
|
||||
"callback? unexpected!"
|
||||
);
|
||||
|
||||
this._waiter =
|
||||
{
|
||||
callback:
|
||||
this._streamReadyInterceptCreator
|
||||
this._waiter = {
|
||||
callback: this._streamReadyInterceptCreator
|
||||
? new this._streamReadyInterceptCreator(callback)
|
||||
: callback,
|
||||
closureOnly,
|
||||
requestedCount,
|
||||
eventTarget: target,
|
||||
toString: function toString() {
|
||||
return "waiter(" + (closureOnly ? "closure only, " : "") +
|
||||
"requestedCount: " + requestedCount + ", target: " +
|
||||
target + ")";
|
||||
return (
|
||||
"waiter(" +
|
||||
(closureOnly ? "closure only, " : "") +
|
||||
"requestedCount: " +
|
||||
requestedCount +
|
||||
", target: " +
|
||||
target +
|
||||
")"
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
if ((!closureOnly && this._writable >= requestedCount) ||
|
||||
!Components.isSuccessCode(this.status)) {
|
||||
if (
|
||||
(!closureOnly && this._writable >= requestedCount) ||
|
||||
!Components.isSuccessCode(this.status)
|
||||
) {
|
||||
this._notify();
|
||||
}
|
||||
},
|
||||
|
|
@ -791,44 +837,69 @@ function CustomPipe(name) {
|
|||
dumpn("*** [" + this.name + "].closeWithStatus(" + status + ")");
|
||||
|
||||
if (!Components.isSuccessCode(self._status)) {
|
||||
dumpn("*** ignoring redundant closure of [input " + this.name + "] " +
|
||||
"because it's already closed (status " + self._status + ")");
|
||||
dumpn(
|
||||
"*** ignoring redundant closure of [input " +
|
||||
this.name +
|
||||
"] " +
|
||||
"because it's already closed (status " +
|
||||
self._status +
|
||||
")"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Components.isSuccessCode(status))
|
||||
if (Components.isSuccessCode(status)) {
|
||||
status = Cr.NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
self._status = status;
|
||||
|
||||
if (input._waiter)
|
||||
if (input._waiter) {
|
||||
input._notify();
|
||||
if (this._waiter)
|
||||
}
|
||||
if (this._waiter) {
|
||||
this._notify();
|
||||
}
|
||||
},
|
||||
|
||||
//
|
||||
// see nsIBinaryOutputStream.writeByteArray
|
||||
//
|
||||
writeByteArray: function writeByteArray(bytes, length) {
|
||||
dumpn("*** [" + this.name + "].writeByteArray" +
|
||||
"([" + bytes + "], " + length + ")");
|
||||
dumpn(
|
||||
"*** [" +
|
||||
this.name +
|
||||
"].writeByteArray" +
|
||||
"([" +
|
||||
bytes +
|
||||
"], " +
|
||||
length +
|
||||
")"
|
||||
);
|
||||
|
||||
Assert.equal(bytes.length, length, "sanity");
|
||||
if (!Components.isSuccessCode(self._status))
|
||||
if (!Components.isSuccessCode(self._status)) {
|
||||
throw self._status;
|
||||
}
|
||||
|
||||
Assert.equal(this._writableAmounts.length, 0,
|
||||
"writeByteArray can't support specified-length writes");
|
||||
Assert.equal(
|
||||
this._writableAmounts.length,
|
||||
0,
|
||||
"writeByteArray can't support specified-length writes"
|
||||
);
|
||||
|
||||
if (this._writable < length)
|
||||
if (this._writable < length) {
|
||||
throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
self._data.push.apply(self._data, bytes);
|
||||
this._writable -= length;
|
||||
|
||||
if (input._readable === Infinity && input._waiter &&
|
||||
!input._waiter.closureOnly) {
|
||||
if (
|
||||
input._readable === Infinity &&
|
||||
input._waiter &&
|
||||
!input._waiter.closureOnly
|
||||
) {
|
||||
input._notify();
|
||||
}
|
||||
},
|
||||
|
|
@ -840,32 +911,44 @@ function CustomPipe(name) {
|
|||
dumpn("*** [" + this.name + "].write");
|
||||
|
||||
Assert.equal(str.length, length, "sanity");
|
||||
if (!Components.isSuccessCode(self._status))
|
||||
if (!Components.isSuccessCode(self._status)) {
|
||||
throw self._status;
|
||||
if (this._writable === 0)
|
||||
}
|
||||
if (this._writable === 0) {
|
||||
throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
var actualWritten;
|
||||
if (this._writableAmounts.length === 0) {
|
||||
actualWritten = Math.min(this._writable, length);
|
||||
} else {
|
||||
Assert.ok(this._writable >= this._writableAmounts[0],
|
||||
"writable amounts value greater than writable data?");
|
||||
Assert.equal(this._writable, sum(this._writableAmounts),
|
||||
"total writable amount not equal to sum of writable " +
|
||||
"increments");
|
||||
Assert.ok(
|
||||
this._writable >= this._writableAmounts[0],
|
||||
"writable amounts value greater than writable data?"
|
||||
);
|
||||
Assert.equal(
|
||||
this._writable,
|
||||
sum(this._writableAmounts),
|
||||
"total writable amount not equal to sum of writable " + "increments"
|
||||
);
|
||||
actualWritten = this._writableAmounts.shift();
|
||||
}
|
||||
|
||||
var bytes = str.substring(0, actualWritten)
|
||||
var bytes = str
|
||||
.substring(0, actualWritten)
|
||||
.split("")
|
||||
.map(function(v) { return v.charCodeAt(0); });
|
||||
.map(function(v) {
|
||||
return v.charCodeAt(0);
|
||||
});
|
||||
|
||||
self._data.push.apply(self._data, bytes);
|
||||
this._writable -= actualWritten;
|
||||
|
||||
if (input._readable === Infinity && input._waiter &&
|
||||
!input._waiter.closureOnly) {
|
||||
if (
|
||||
input._readable === Infinity &&
|
||||
input._waiter &&
|
||||
!input._waiter.closureOnly
|
||||
) {
|
||||
input._notify();
|
||||
}
|
||||
|
||||
|
|
@ -887,8 +970,11 @@ function CustomPipe(name) {
|
|||
this._writable += count;
|
||||
|
||||
var waiter = this._waiter;
|
||||
if (waiter && !waiter.closureOnly &&
|
||||
waiter.requestedCount <= this._writable) {
|
||||
if (
|
||||
waiter &&
|
||||
!waiter.closureOnly &&
|
||||
waiter.requestedCount <= this._writable
|
||||
) {
|
||||
this._notify();
|
||||
}
|
||||
},
|
||||
|
|
@ -914,12 +1000,22 @@ function CustomPipe(name) {
|
|||
* increments
|
||||
*/
|
||||
makeWritableByIncrements: function makeWritableByIncrements(increments) {
|
||||
dumpn("*** [" + this.name + "].makeWritableByIncrements" +
|
||||
"([" + increments.join(", ") + "])");
|
||||
dumpn(
|
||||
"*** [" +
|
||||
this.name +
|
||||
"].makeWritableByIncrements" +
|
||||
"([" +
|
||||
increments.join(", ") +
|
||||
"])"
|
||||
);
|
||||
|
||||
Assert.ok(increments.length > 0, "bad increments");
|
||||
Assert.ok(increments.every(function(v) { return v > 0; }),
|
||||
"zero increment?");
|
||||
Assert.ok(
|
||||
increments.every(function(v) {
|
||||
return v > 0;
|
||||
}),
|
||||
"zero increment?"
|
||||
);
|
||||
|
||||
Assert.ok(Components.isSuccessCode(self._status));
|
||||
|
||||
|
|
@ -927,8 +1023,11 @@ function CustomPipe(name) {
|
|||
this._writableAmounts = increments;
|
||||
|
||||
var waiter = this._waiter;
|
||||
if (waiter && !waiter.closureOnly &&
|
||||
waiter.requestedCount <= this._writable) {
|
||||
if (
|
||||
waiter &&
|
||||
!waiter.closureOnly &&
|
||||
waiter.requestedCount <= this._writable
|
||||
) {
|
||||
this._notify();
|
||||
}
|
||||
},
|
||||
|
|
@ -944,8 +1043,7 @@ function CustomPipe(name) {
|
|||
Assert.ok(waiter !== null, "no waiter?");
|
||||
|
||||
if (this._event === null) {
|
||||
var event = this._event =
|
||||
{
|
||||
var event = (this._event = {
|
||||
run: function run() {
|
||||
output._waiter = null;
|
||||
output._event = null;
|
||||
|
|
@ -956,13 +1054,16 @@ function CustomPipe(name) {
|
|||
do_throw("error calling onOutputStreamReady: " + e);
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
waiter.eventTarget.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIAsyncOutputStream", "nsIOutputStream"]),
|
||||
};
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIAsyncOutputStream",
|
||||
"nsIOutputStream",
|
||||
]),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1042,14 +1143,12 @@ function CopyTest(name, next) {
|
|||
this._tasks = [];
|
||||
|
||||
/** The copier used by this test. */
|
||||
this._copier =
|
||||
new WriteThroughCopier(this._source, this._sink, this, null);
|
||||
this._copier = new WriteThroughCopier(this._source, this._sink, this, null);
|
||||
|
||||
// Start watching for data written by the copier to the sink.
|
||||
this._waitForWrittenData();
|
||||
}
|
||||
CopyTest.prototype =
|
||||
{
|
||||
CopyTest.prototype = {
|
||||
/**
|
||||
* Adds the given array of bytes to data in the copier's source.
|
||||
*
|
||||
|
|
@ -1098,23 +1197,30 @@ CopyTest.prototype =
|
|||
* @param dataQuantums : [[uint]]
|
||||
* array of byte arrays to expect to be written in sequence to the sink
|
||||
*/
|
||||
makeSinkWritableAndWaitFor:
|
||||
function makeSinkWritableAndWaitFor(bytes, dataQuantums) {
|
||||
makeSinkWritableAndWaitFor: function makeSinkWritableAndWaitFor(
|
||||
bytes,
|
||||
dataQuantums
|
||||
) {
|
||||
var self = this;
|
||||
|
||||
Assert.equal(bytes,
|
||||
Assert.equal(
|
||||
bytes,
|
||||
dataQuantums.reduce(function(partial, current) {
|
||||
return partial + current.length;
|
||||
}, 0),
|
||||
"bytes/quantums mismatch");
|
||||
"bytes/quantums mismatch"
|
||||
);
|
||||
|
||||
function increaseSinkSpaceTask() {
|
||||
/* Now do the actual work to trigger the interceptor. */
|
||||
self._sink.makeWritable(bytes);
|
||||
}
|
||||
|
||||
this._waitForHelper("increaseSinkSpaceTask",
|
||||
dataQuantums, increaseSinkSpaceTask);
|
||||
this._waitForHelper(
|
||||
"increaseSinkSpaceTask",
|
||||
dataQuantums,
|
||||
increaseSinkSpaceTask
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -1128,11 +1234,15 @@ CopyTest.prototype =
|
|||
* @param dataQuantums : [[uint]]
|
||||
* array of byte arrays to expect to be written in sequence to the sink
|
||||
*/
|
||||
makeSinkWritableByIncrementsAndWaitFor:
|
||||
function makeSinkWritableByIncrementsAndWaitFor(bytes, dataQuantums) {
|
||||
makeSinkWritableByIncrementsAndWaitFor: function makeSinkWritableByIncrementsAndWaitFor(
|
||||
bytes,
|
||||
dataQuantums
|
||||
) {
|
||||
var self = this;
|
||||
|
||||
var desiredAmounts = dataQuantums.map(function(v) { return v.length; });
|
||||
var desiredAmounts = dataQuantums.map(function(v) {
|
||||
return v.length;
|
||||
});
|
||||
Assert.equal(bytes, sum(desiredAmounts), "bytes/quantums mismatch");
|
||||
|
||||
function increaseSinkSpaceByIncrementsTask() {
|
||||
|
|
@ -1140,8 +1250,11 @@ CopyTest.prototype =
|
|||
self._sink.makeWritableByIncrements(desiredAmounts);
|
||||
}
|
||||
|
||||
this._waitForHelper("increaseSinkSpaceByIncrementsTask",
|
||||
dataQuantums, increaseSinkSpaceByIncrementsTask);
|
||||
this._waitForHelper(
|
||||
"increaseSinkSpaceByIncrementsTask",
|
||||
dataQuantums,
|
||||
increaseSinkSpaceByIncrementsTask
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -1174,20 +1287,33 @@ CopyTest.prototype =
|
|||
* @param dataQuantums : [[uint]]
|
||||
* array of byte arrays to expect to be written in sequence to the sink
|
||||
*/
|
||||
closeSourceAndWaitFor:
|
||||
function closeSourceAndWaitFor(status, bytes, dataQuantums) {
|
||||
closeSourceAndWaitFor: function closeSourceAndWaitFor(
|
||||
status,
|
||||
bytes,
|
||||
dataQuantums
|
||||
) {
|
||||
var self = this;
|
||||
|
||||
Assert.equal(bytes, sum(dataQuantums.map(function(v) { return v.length; })),
|
||||
"bytes/quantums mismatch");
|
||||
Assert.equal(
|
||||
bytes,
|
||||
sum(
|
||||
dataQuantums.map(function(v) {
|
||||
return v.length;
|
||||
})
|
||||
),
|
||||
"bytes/quantums mismatch"
|
||||
);
|
||||
|
||||
function closeSourceAndWaitForTask() {
|
||||
self._sink.makeWritable(bytes);
|
||||
self._copyableDataStream.closeWithStatus(status);
|
||||
}
|
||||
|
||||
this._waitForHelper("closeSourceAndWaitForTask",
|
||||
dataQuantums, closeSourceAndWaitForTask);
|
||||
this._waitForHelper(
|
||||
"closeSourceAndWaitForTask",
|
||||
dataQuantums,
|
||||
closeSourceAndWaitForTask
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -1262,8 +1388,9 @@ CopyTest.prototype =
|
|||
expect: function expect(expectedStatus, receivedData) {
|
||||
this._expectedStatus = expectedStatus;
|
||||
this._expectedData = [];
|
||||
for (var i = 0, sz = receivedData.length; i < sz; i++)
|
||||
for (var i = 0, sz = receivedData.length; i < sz; i++) {
|
||||
this._expectedData.push.apply(this._expectedData, receivedData[i]);
|
||||
}
|
||||
|
||||
this._stageNextTask();
|
||||
},
|
||||
|
|
@ -1295,11 +1422,14 @@ CopyTest.prototype =
|
|||
* Intercept all data-available notifications so we can continue when all
|
||||
* the ones we expect have been received.
|
||||
*/
|
||||
var streamReadyCallback =
|
||||
{
|
||||
var streamReadyCallback = {
|
||||
onInputStreamReady: function wrapperOnInputStreamReady(input) {
|
||||
dumpn("*** streamReadyCallback.onInputStreamReady" +
|
||||
"(" + input.name + ")");
|
||||
dumpn(
|
||||
"*** streamReadyCallback.onInputStreamReady" +
|
||||
"(" +
|
||||
input.name +
|
||||
")"
|
||||
);
|
||||
|
||||
Assert.equal(this, streamReadyCallback, "sanity");
|
||||
|
||||
|
|
@ -1307,15 +1437,24 @@ CopyTest.prototype =
|
|||
if (quantumIndex < dataQuantums.length) {
|
||||
var quantum = dataQuantums[quantumIndex++];
|
||||
var sz = quantum.length;
|
||||
Assert.equal(self._lastQuantum.length, sz,
|
||||
"different quantum lengths");
|
||||
Assert.equal(
|
||||
self._lastQuantum.length,
|
||||
sz,
|
||||
"different quantum lengths"
|
||||
);
|
||||
for (var i = 0; i < sz; i++) {
|
||||
Assert.equal(self._lastQuantum[i], quantum[i],
|
||||
"bad data at " + i);
|
||||
Assert.equal(
|
||||
self._lastQuantum[i],
|
||||
quantum[i],
|
||||
"bad data at " + i
|
||||
);
|
||||
}
|
||||
|
||||
dumpn("*** waiting to check remaining " +
|
||||
(dataQuantums.length - quantumIndex) + " quantums...");
|
||||
dumpn(
|
||||
"*** waiting to check remaining " +
|
||||
(dataQuantums.length - quantumIndex) +
|
||||
" quantums..."
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (quantumIndex === dataQuantums.length) {
|
||||
|
|
@ -1327,8 +1466,10 @@ CopyTest.prototype =
|
|||
},
|
||||
};
|
||||
|
||||
var interceptor =
|
||||
createStreamReadyInterceptor(streamReadyCallback, "onInputStreamReady");
|
||||
var interceptor = createStreamReadyInterceptor(
|
||||
streamReadyCallback,
|
||||
"onInputStreamReady"
|
||||
);
|
||||
self._copiedDataStream.interceptStreamReadyCallbacks(interceptor);
|
||||
|
||||
/* Do the deed. */
|
||||
|
|
@ -1349,15 +1490,17 @@ CopyTest.prototype =
|
|||
dumpn("*** _waitForWrittenData (" + this.name + ")");
|
||||
|
||||
var self = this;
|
||||
var outputWrittenWatcher =
|
||||
{
|
||||
var outputWrittenWatcher = {
|
||||
onInputStreamReady: function onInputStreamReady(input) {
|
||||
dumpn("*** outputWrittenWatcher.onInputStreamReady" +
|
||||
"(" + input.name + ")");
|
||||
dumpn(
|
||||
"*** outputWrittenWatcher.onInputStreamReady" + "(" + input.name + ")"
|
||||
);
|
||||
|
||||
if (self._allDataWritten) {
|
||||
do_throw("ruh-roh! why are we getting notified of more data " +
|
||||
"after we should have received all of it?");
|
||||
do_throw(
|
||||
"ruh-roh! why are we getting notified of more data " +
|
||||
"after we should have received all of it?"
|
||||
);
|
||||
}
|
||||
|
||||
self._waitingForData = false;
|
||||
|
|
@ -1367,18 +1510,23 @@ CopyTest.prototype =
|
|||
} catch (e) {
|
||||
dumpn("*** available() threw! error: " + e);
|
||||
if (self._completed) {
|
||||
dumpn("*** NB: this isn't a problem, because we've copied " +
|
||||
dumpn(
|
||||
"*** NB: this isn't a problem, because we've copied " +
|
||||
"completely now, and this notify may have been expedited " +
|
||||
"by maybeNotifyFinally such that we're being called when " +
|
||||
"we can *guarantee* nothing is available any more");
|
||||
"we can *guarantee* nothing is available any more"
|
||||
);
|
||||
}
|
||||
avail = 0;
|
||||
}
|
||||
|
||||
if (avail > 0) {
|
||||
var data = input.readByteArray(avail);
|
||||
Assert.equal(data.length, avail,
|
||||
"readByteArray returned wrong number of bytes?");
|
||||
Assert.equal(
|
||||
data.length,
|
||||
avail,
|
||||
"readByteArray returned wrong number of bytes?"
|
||||
);
|
||||
self._lastQuantum = data;
|
||||
self._receivedData.push.apply(self._receivedData, data);
|
||||
}
|
||||
|
|
@ -1402,8 +1550,12 @@ CopyTest.prototype =
|
|||
},
|
||||
};
|
||||
|
||||
this._copiedDataStream.asyncWait(outputWrittenWatcher, 0, 1,
|
||||
gThreadManager.currentThread);
|
||||
this._copiedDataStream.asyncWait(
|
||||
outputWrittenWatcher,
|
||||
0,
|
||||
1,
|
||||
gThreadManager.currentThread
|
||||
);
|
||||
this._waitingForData = true;
|
||||
},
|
||||
|
||||
|
|
@ -1413,27 +1565,37 @@ CopyTest.prototype =
|
|||
* this test was first created.
|
||||
*/
|
||||
_testComplete: function _testComplete() {
|
||||
dumpn("*** CopyTest(" + this.name + ") complete! " +
|
||||
"On to the next test...");
|
||||
dumpn(
|
||||
"*** CopyTest(" + this.name + ") complete! " + "On to the next test..."
|
||||
);
|
||||
|
||||
try {
|
||||
Assert.ok(this._allDataWritten, "expect all data written now!");
|
||||
Assert.ok(this._copyingFinished, "expect copying finished now!");
|
||||
|
||||
Assert.equal(this._actualStatus, this._expectedStatus,
|
||||
"wrong final status");
|
||||
Assert.equal(
|
||||
this._actualStatus,
|
||||
this._expectedStatus,
|
||||
"wrong final status"
|
||||
);
|
||||
|
||||
var expected = this._expectedData, received = this._receivedData;
|
||||
var expected = this._expectedData,
|
||||
received = this._receivedData;
|
||||
dumpn("received: [" + received + "], expected: [" + expected + "]");
|
||||
Assert.equal(received.length, expected.length, "wrong data");
|
||||
for (var i = 0, sz = expected.length; i < sz; i++)
|
||||
for (var i = 0, sz = expected.length; i < sz; i++) {
|
||||
Assert.equal(received[i], expected[i], "bad data at " + i);
|
||||
}
|
||||
} catch (e) {
|
||||
dumpn("!!! ERROR PERFORMING FINAL " + this.name + " CHECKS! " + e);
|
||||
throw e;
|
||||
} finally {
|
||||
dumpn("*** CopyTest(" + this.name + ") complete! " +
|
||||
"Invoking test-completion callback...");
|
||||
dumpn(
|
||||
"*** CopyTest(" +
|
||||
this.name +
|
||||
") complete! " +
|
||||
"Invoking test-completion callback..."
|
||||
);
|
||||
this._done();
|
||||
}
|
||||
},
|
||||
|
|
@ -1448,8 +1610,7 @@ CopyTest.prototype =
|
|||
}
|
||||
|
||||
var task = this._tasks[this._currentTask++];
|
||||
var event =
|
||||
{
|
||||
var event = {
|
||||
run: function run() {
|
||||
try {
|
||||
task();
|
||||
|
|
@ -1508,8 +1669,9 @@ CopyTest.prototype =
|
|||
*/
|
||||
dumpn("*** not all data copied, waiting for that to happen...");
|
||||
|
||||
if (!this._waitingForData)
|
||||
if (!this._waitingForData) {
|
||||
this._waitForWrittenData();
|
||||
}
|
||||
|
||||
this._copiedDataStream.maybeNotifyFinally();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,15 +122,15 @@ 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 =
|
||||
{
|
||||
var objHandler = {
|
||||
handle(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
|
|
@ -119,15 +140,15 @@ var objHandler =
|
|||
|
||||
Assert.equal(metadata.port, port);
|
||||
|
||||
if (metadata.queryString)
|
||||
if (metadata.queryString) {
|
||||
body += "?" + metadata.queryString;
|
||||
}
|
||||
|
||||
body += " HTTP/" + metadata.httpVersion + "\n";
|
||||
|
||||
var headEnum = metadata.headers;
|
||||
while (headEnum.hasMoreElements()) {
|
||||
var fieldName = headEnum.getNext()
|
||||
.QueryInterface(Ci.nsISupportsString)
|
||||
var fieldName = headEnum.getNext().QueryInterface(Ci.nsISupportsString)
|
||||
.data;
|
||||
body += fieldName + ": " + metadata.getHeader(fieldName) + "\n";
|
||||
}
|
||||
|
|
@ -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,34 +14,65 @@ 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),
|
||||
];
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
@ -203,7 +206,9 @@ function makeFile(name, isDirectory, parentDir, lst) {
|
|||
file.append(name);
|
||||
file.create(type, 0o755);
|
||||
lst.push({ name, isDirectory });
|
||||
} catch (e) { /* OS probably doesn't like file name, skip */ }
|
||||
} 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 +
|
||||
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 +
|
||||
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),
|
||||
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,13 +39,15 @@ 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();
|
||||
|
|
@ -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,8 +264,7 @@ function check10(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.0-request",
|
||||
"Query: ",
|
||||
|
|
@ -279,78 +279,69 @@ function check10(aData) {
|
|||
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" +
|
||||
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" +
|
||||
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";
|
||||
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";
|
||||
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" +
|
||||
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" +
|
||||
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,8 +351,7 @@ function check11goodHost(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-good-host",
|
||||
"Query: ",
|
||||
|
|
@ -376,16 +366,14 @@ function check11goodHost(aData) {
|
|||
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,8 +383,7 @@ function check11ipHost(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-ip-host",
|
||||
"Query: ",
|
||||
|
|
@ -411,45 +398,45 @@ function check11ipHost(aData) {
|
|||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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) {
|
||||
|
|
@ -461,12 +448,12 @@ 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" +
|
||||
data =
|
||||
"GET /http/1.0-request HTTP/1.0\r\n" +
|
||||
"Host: not-localhost:4444\r\n" +
|
||||
"\r\n";
|
||||
function check10ip(aData) {
|
||||
|
|
@ -478,8 +465,7 @@ function check10ip(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.0-request",
|
||||
"Query: ",
|
||||
|
|
@ -494,14 +480,14 @@ function check10ip(aData) {
|
|||
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" +
|
||||
data =
|
||||
"GET /http/1.1-good-host-wacky-port HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
function check11goodHostWackyPort(aData) {
|
||||
|
|
@ -513,8 +499,7 @@ function check11goodHostWackyPort(aData) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
let body =
|
||||
[
|
||||
let body = [
|
||||
"Method: GET",
|
||||
"Path: /http/1.1-good-host-wacky-port",
|
||||
"Query: ",
|
||||
|
|
@ -529,91 +514,88 @@ function check11goodHostWackyPort(aData) {
|
|||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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" +
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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,12 +227,12 @@ 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 =
|
||||
{
|
||||
var writeData = {
|
||||
run() {
|
||||
if (count-- === 0) {
|
||||
response.finish();
|
||||
|
|
@ -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,72 +37,85 @@ 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),
|
||||
new Test(BASE + "/test_registerdirectory.js", nocache, notFound, null),
|
||||
|
||||
/** ******************
|
||||
* with a base path *
|
||||
********************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile),
|
||||
checkFile
|
||||
),
|
||||
|
||||
/** ***************************
|
||||
* without a base path again *
|
||||
*****************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = null;
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** *************************
|
||||
* registered path handler *
|
||||
***************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js",
|
||||
override_test_registerdirectory);
|
||||
srv.registerPathHandler(
|
||||
"/test_registerdirectory.js",
|
||||
override_test_registerdirectory
|
||||
);
|
||||
},
|
||||
checkOverride,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** **********************
|
||||
* removed path handler *
|
||||
************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function init_registerDirectory6(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** ******************
|
||||
* with a base path *
|
||||
********************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
|
||||
|
|
@ -112,112 +124,135 @@ XPCOMUtils.defineLazyGetter(this, "tests", function() {
|
|||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
null,
|
||||
checkFile),
|
||||
checkFile
|
||||
),
|
||||
|
||||
/** ***********************
|
||||
* ...and a path handler *
|
||||
*************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js",
|
||||
override_test_registerdirectory);
|
||||
srv.registerPathHandler(
|
||||
"/test_registerdirectory.js",
|
||||
override_test_registerdirectory
|
||||
);
|
||||
},
|
||||
checkOverride,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** **********************
|
||||
* removed base handler *
|
||||
************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = null;
|
||||
srv.registerDirectory("/", serverBasePath);
|
||||
},
|
||||
checkOverride,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** **********************
|
||||
* removed path handler *
|
||||
************************/
|
||||
new Test(BASE + "/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerPathHandler("/test_registerdirectory.js", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** ***********************
|
||||
* mapping set up, works *
|
||||
*************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
serverBasePath = testsDirectory.clone();
|
||||
srv.registerDirectory("/foo/", serverBasePath);
|
||||
},
|
||||
check200,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** *******************
|
||||
* no mapping, fails *
|
||||
*********************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache,
|
||||
notFound,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** ****************
|
||||
* mapping, works *
|
||||
******************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/test_registerdirectory.js/",
|
||||
serverBasePath);
|
||||
srv.registerDirectory(
|
||||
"/foo/test_registerdirectory.js/",
|
||||
serverBasePath
|
||||
);
|
||||
},
|
||||
null,
|
||||
checkFile),
|
||||
checkFile
|
||||
),
|
||||
|
||||
/** **********************************
|
||||
* two mappings set up, still works *
|
||||
************************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
nocache, null, checkFile),
|
||||
new Test(BASE + "/foo/test_registerdirectory.js", nocache, null, checkFile),
|
||||
|
||||
/** ************************
|
||||
* remove topmost mapping *
|
||||
**************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js",
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
null
|
||||
),
|
||||
|
||||
/** ************************************
|
||||
* lower mapping still present, works *
|
||||
**************************************/
|
||||
new Test(BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
nocache, null, checkFile),
|
||||
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",
|
||||
new Test(
|
||||
BASE + "/foo/test_registerdirectory.js/test_registerdirectory.js",
|
||||
function(ch) {
|
||||
nocache(ch);
|
||||
srv.registerDirectory("/foo/test_registerdirectory.js/", null);
|
||||
},
|
||||
notFound,
|
||||
null),
|
||||
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" +
|
||||
}
|
||||
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,8 +73,7 @@ function checkVeryLongRequestLine(data) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
var body =
|
||||
[
|
||||
var body = [
|
||||
"Method: GET",
|
||||
"Path: /very-long-request-line",
|
||||
"Query: " + reallyLong,
|
||||
|
|
@ -83,22 +88,26 @@ function checkVeryLongRequestLine(data) {
|
|||
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 +
|
||||
}
|
||||
str =
|
||||
blankLines +
|
||||
"GET /lots-of-leading-blank-lines HTTP/1.1\r\n" +
|
||||
"Host: localhost:" + PORT + "\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,8 +121,7 @@ function checkLotsOfLeadingBlankLines(data) {
|
|||
skipHeaders(iter);
|
||||
|
||||
// Okay, next line must be the data we expected to be written
|
||||
var body =
|
||||
[
|
||||
var body = [
|
||||
"Method: GET",
|
||||
"Path: /lots-of-leading-blank-lines",
|
||||
"Query: ",
|
||||
|
|
|
|||
|
|
@ -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"); },
|
||||
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); },
|
||||
"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(); },
|
||||
"setHeader should throw not-available after seizePower"
|
||||
);
|
||||
checkException(
|
||||
function() {
|
||||
response.processAsync();
|
||||
},
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"processAsync should throw not-available after seizePower");
|
||||
"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(); },
|
||||
checkException(
|
||||
function() {
|
||||
response.seizePower();
|
||||
},
|
||||
Cr.NS_ERROR_UNEXPECTED,
|
||||
"seizePower should throw unexpected after finish");
|
||||
"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(); },
|
||||
checkException(
|
||||
function() {
|
||||
response.seizePower();
|
||||
},
|
||||
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"seizePower should throw not-available after processAsync");
|
||||
"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",
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("not-a-bytes-equals-specifier"),
|
||||
checkRangeResult, null);
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=-"),
|
||||
checkRangeResult, null);
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=1000000-"),
|
||||
checkRangeResult, null);
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=1-4"),
|
||||
checkRangeResult, null);
|
||||
checkRangeResult,
|
||||
null
|
||||
);
|
||||
tests.push(test);
|
||||
test = new Test(BASE + "/range-checker.sjs",
|
||||
test = new Test(
|
||||
BASE + "/range-checker.sjs",
|
||||
rangeInit("bytes=-4"),
|
||||
checkRangeResult, null);
|
||||
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,12 +260,12 @@ function HTTPTestLoader(path, start, stop) {
|
|||
var channel = makeChannel(path);
|
||||
channel.asyncOpen(this);
|
||||
}
|
||||
HTTPTestLoader.prototype =
|
||||
{
|
||||
HTTPTestLoader.prototype = {
|
||||
onStartRequest(request) {
|
||||
dumpn("*** HTTPTestLoader.onStartRequest for " + this._path);
|
||||
|
||||
var ch = request.QueryInterface(Ci.nsIHttpChannel)
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
try {
|
||||
|
|
@ -234,23 +275,31 @@ HTTPTestLoader.prototype =
|
|||
do_throw(this._path + ": error in onStartRequest: " + e);
|
||||
}
|
||||
} catch (e) {
|
||||
dumpn("!!! swallowing onStartRequest exception so onStopRequest is " +
|
||||
"called...");
|
||||
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));
|
||||
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)
|
||||
var ch = request
|
||||
.QueryInterface(Ci.nsIHttpChannel)
|
||||
.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
|
||||
this._stop(ch, status, this._data);
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIStreamListener", "nsIRequestObserver"]),
|
||||
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,9 +133,10 @@ 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 "";
|
||||
}
|
||||
return getHeader;
|
||||
|
|
@ -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,7 +67,8 @@ function run_test_2() {
|
|||
|
||||
do_test_pending();
|
||||
try {
|
||||
srv.stop({onStopped() {
|
||||
srv.stop({
|
||||
onStopped() {
|
||||
try {
|
||||
do_test_pending();
|
||||
run_test_3();
|
||||
|
|
@ -123,10 +126,10 @@ function run_test_5() {
|
|||
dumpn("*** run_test_5");
|
||||
|
||||
testsComplete = true;
|
||||
if (stopped)
|
||||
if (stopped) {
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const INTERVAL = 500;
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ var observer = {
|
|||
sendAsyncMessage("cookieName", cookie.name + "=" + cookie.value);
|
||||
sendAsyncMessage("cookieOperation", data);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
addMessageListener("createObserver", function(e) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
|
||||
|
|
@ -45,12 +63,11 @@ function setupTest(uri, domain, cookies, loads, headers) {
|
|||
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);
|
||||
}
|
||||
|
||||
function evict_cache_entries(where)
|
||||
{
|
||||
var clearDisk = (!where || where == "disk" || where == "all");
|
||||
var clearMem = (!where || where == "memory" || where == "all");
|
||||
var clearAppCache = (where == "appcache");
|
||||
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";
|
||||
|
||||
var svc = get_cache_service();
|
||||
var storage;
|
||||
|
|
@ -35,28 +38,32 @@ 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() {}
|
||||
|
|
@ -66,8 +73,9 @@ function asyncOpenCacheEntry(key, where, flags, lci, callback, 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;
|
||||
},
|
||||
|
||||
|
|
@ -76,31 +84,33 @@ function asyncOpenCacheEntry(key, where, flags, lci, callback, appcache)
|
|||
// Root us at the callback
|
||||
callback.__cache_listener_root = this;
|
||||
callback.onCacheEntryAvailable(entry, isnew, appCache, status);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
callback(status, entry, appCache);
|
||||
}
|
||||
},
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const NOTFOUND = 1 << 4;
|
|||
// Return ENTRY_NEEDS_REVALIDATION from onCacheEntryCheck
|
||||
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;
|
||||
// Don't trigger the go-on callback until the entry is written
|
||||
|
|
@ -38,54 +38,63 @@ const NOTIFYBEFOREREAD = 1 << 15;
|
|||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
|
@ -111,7 +120,10 @@ OpenCallback.prototype =
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -142,11 +153,11 @@ OpenCallback.prototype =
|
|||
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)) {
|
||||
this.goon(entry);
|
||||
} 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 &&
|
||||
} else if (typeof element === "object") {
|
||||
return (
|
||||
element.uri === key &&
|
||||
element.lci.isAnonymous === aInfo.isAnonymous &&
|
||||
ChromeUtils.isOriginAttributesEqual(element.lci.originAttributes,
|
||||
aInfo.originAttributes);
|
||||
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))
|
||||
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)
|
||||
} 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)) &&
|
||||
}
|
||||
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)
|
||||
this._contentLen != -1
|
||||
) {
|
||||
Assert.equal(this._buffer.length, this._contentLen);
|
||||
}
|
||||
} catch (ex) {
|
||||
do_throw("Error in onStopRequest: " + ex);
|
||||
}
|
||||
try {
|
||||
this._closure(request,
|
||||
this._closure(
|
||||
request,
|
||||
this._buffer,
|
||||
this._closurectx,
|
||||
this._isFromCache,
|
||||
this._cacheEntryId);
|
||||
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();
|
||||
|
|
@ -242,4 +295,3 @@ function addCertFromFile(certdb, filename, trustString) {
|
|||
.replace(/[\r\n]/g, "");
|
||||
certdb.addCertFromBase64(pem, trustString);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,35 +4,44 @@
|
|||
|
||||
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "cookies",
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
Services,
|
||||
"cookies",
|
||||
"@mozilla.org/cookieService;1",
|
||||
"nsICookieService");
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "cookiemgr",
|
||||
"nsICookieService"
|
||||
);
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
Services,
|
||||
"cookiemgr",
|
||||
"@mozilla.org/cookiemanager;1",
|
||||
"nsICookieManager");
|
||||
"nsICookieManager"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "etld",
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
Services,
|
||||
"etld",
|
||||
"@mozilla.org/network/effective-tld-service;1",
|
||||
"nsIEffectiveTLDService");
|
||||
"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();
|
||||
|
|
@ -63,13 +71,14 @@ _observer.prototype = {
|
|||
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,7 +163,8 @@ function do_count_cookies() {
|
|||
}
|
||||
|
||||
// Helper object to store cookie data.
|
||||
function Cookie(name,
|
||||
function Cookie(
|
||||
name,
|
||||
value,
|
||||
host,
|
||||
path,
|
||||
|
|
@ -142,8 +173,8 @@ function Cookie(name,
|
|||
creationTime,
|
||||
isSession,
|
||||
isSecure,
|
||||
isHttpOnly)
|
||||
{
|
||||
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,15 +411,18 @@ 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;
|
||||
}
|
||||
|
|
@ -386,15 +432,13 @@ function CookieDatabaseConnection(file, schema)
|
|||
}
|
||||
}
|
||||
|
||||
CookieDatabaseConnection.prototype =
|
||||
{
|
||||
insertCookie(cookie)
|
||||
{
|
||||
if (!(cookie instanceof Cookie))
|
||||
CookieDatabaseConnection.prototype = {
|
||||
insertCookie(cookie) {
|
||||
if (!(cookie instanceof Cookie)) {
|
||||
do_throw("not a cookie");
|
||||
}
|
||||
|
||||
switch (this.schema)
|
||||
{
|
||||
switch (this.schema) {
|
||||
case 1:
|
||||
this.stmtInsert.bindByName("id", cookie.creationTime);
|
||||
this.stmtInsert.bindByName("name", cookie.name);
|
||||
|
|
@ -451,13 +495,12 @@ CookieDatabaseConnection.prototype =
|
|||
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)
|
||||
{
|
||||
switch (this.db.schemaVersion) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
|
|
@ -477,13 +520,12 @@ CookieDatabaseConnection.prototype =
|
|||
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)
|
||||
{
|
||||
switch (this.db.schemaVersion) {
|
||||
case 1:
|
||||
do_throw("can't update a schema 1 cookie!");
|
||||
|
||||
|
|
@ -507,23 +549,22 @@ CookieDatabaseConnection.prototype =
|
|||
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",
|
||||
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);
|
||||
"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 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,7 +1,7 @@
|
|||
// Test based on submitted one from Peter B Shalimoff
|
||||
|
||||
var test = function(s, funcName) {
|
||||
function Arg(){};
|
||||
function Arg() {}
|
||||
Arg.prototype.toString = function() {
|
||||
info("Testing " + funcName + " with null args");
|
||||
return this.value;
|
||||
|
|
@ -11,7 +11,9 @@ var test = function(s, funcName){
|
|||
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);
|
||||
var up = Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(
|
||||
Ci.nsIURLParser
|
||||
);
|
||||
try {
|
||||
up[funcName].apply(up, args);
|
||||
return args;
|
||||
|
|
@ -23,8 +25,18 @@ var test = function(s, funcName){
|
|||
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);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,21 @@ 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);
|
||||
var service = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(
|
||||
Ci.nsICacheStorageService
|
||||
);
|
||||
service.clear();
|
||||
}
|
||||
|
||||
|
|
@ -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,
|
||||
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));
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,70 +20,75 @@ function make_channel(url) {
|
|||
|
||||
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" +
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* See also https://bugzilla.mozilla.org/show_bug.cgi?id=609667
|
||||
*/
|
||||
|
||||
var BS = '\\';
|
||||
var BS = "\\";
|
||||
var DQUOTE = '"';
|
||||
|
||||
// Test array:
|
||||
|
|
@ -23,257 +23,358 @@ var DQUOTE = '"';
|
|||
|
||||
var tests = [
|
||||
// No filename parameter: return nothing
|
||||
["attachment;",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
["attachment;", "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// basic
|
||||
["attachment; filename=basic",
|
||||
"attachment", "basic"],
|
||||
["attachment; filename=basic", "attachment", "basic"],
|
||||
|
||||
// extended
|
||||
["attachment; filename*=UTF-8''extended",
|
||||
"attachment", "extended"],
|
||||
["attachment; filename*=UTF-8''extended", "attachment", "extended"],
|
||||
|
||||
// prefer extended to basic (bug 588781)
|
||||
["attachment; filename=basic; filename*=UTF-8''extended",
|
||||
"attachment", "extended"],
|
||||
[
|
||||
"attachment; filename=basic; filename*=UTF-8''extended",
|
||||
"attachment",
|
||||
"extended",
|
||||
],
|
||||
|
||||
// prefer extended to basic (bug 588781)
|
||||
["attachment; filename*=UTF-8''extended; filename=basic",
|
||||
"attachment", "extended"],
|
||||
[
|
||||
"attachment; filename*=UTF-8''extended; filename=basic",
|
||||
"attachment",
|
||||
"extended",
|
||||
],
|
||||
|
||||
// use first basic value (invalid; error recovery)
|
||||
["attachment; filename=first; filename=wrong",
|
||||
"attachment", "first"],
|
||||
["attachment; filename=first; filename=wrong", "attachment", "first"],
|
||||
|
||||
// old school bad HTTP servers: missing 'attachment' or 'inline'
|
||||
// (invalid; error recovery)
|
||||
["filename=old",
|
||||
"filename=old", "old"],
|
||||
["filename=old", "filename=old", "old"],
|
||||
|
||||
["attachment; filename*=UTF-8''extended",
|
||||
"attachment", "extended"],
|
||||
["attachment; filename*=UTF-8''extended", "attachment", "extended"],
|
||||
|
||||
// continuations not part of RFC 5987 (bug 610054)
|
||||
["attachment; filename*0=foo; filename*1=bar",
|
||||
"attachment", "foobar",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */],
|
||||
[
|
||||
"attachment; filename*0=foo; filename*1=bar",
|
||||
"attachment",
|
||||
"foobar",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */
|
||||
],
|
||||
|
||||
// Return first continuation (invalid; error recovery)
|
||||
["attachment; filename*0=first; filename*0=wrong; filename=basic",
|
||||
"attachment", "first",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename*0=first; filename*0=wrong; filename=basic",
|
||||
"attachment",
|
||||
"first",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// Only use correctly ordered continuations (invalid; error recovery)
|
||||
["attachment; filename*0=first; filename*1=second; filename*0=wrong",
|
||||
"attachment", "firstsecond",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */],
|
||||
[
|
||||
"attachment; filename*0=first; filename*1=second; filename*0=wrong",
|
||||
"attachment",
|
||||
"firstsecond",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */
|
||||
],
|
||||
|
||||
// prefer continuation to basic (unless RFC 5987)
|
||||
["attachment; filename=basic; filename*0=foo; filename*1=bar",
|
||||
"attachment", "foobar",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0=foo; filename*1=bar",
|
||||
"attachment",
|
||||
"foobar",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// Prefer extended to basic and/or (broken or not) continuation
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename=basic; filename*0=first; filename*0=wrong; filename*=UTF-8''extended",
|
||||
"attachment", "extended"],
|
||||
[
|
||||
"attachment; filename=basic; filename*0=first; filename*0=wrong; filename*=UTF-8''extended",
|
||||
"attachment",
|
||||
"extended",
|
||||
],
|
||||
|
||||
// RFC 2231 not clear on correct outcome: we prefer non-continued extended
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename=basic; filename*=UTF-8''extended; filename*0=foo; filename*1=bar",
|
||||
"attachment", "extended"],
|
||||
[
|
||||
"attachment; filename=basic; filename*=UTF-8''extended; filename*0=foo; filename*1=bar",
|
||||
"attachment",
|
||||
"extended",
|
||||
],
|
||||
|
||||
// Gaps should result in returning only value until gap hit
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename*0=foo; filename*2=bar",
|
||||
"attachment", "foo",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */],
|
||||
[
|
||||
"attachment; filename*0=foo; filename*2=bar",
|
||||
"attachment",
|
||||
"foo",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */
|
||||
],
|
||||
|
||||
// Don't allow leading 0's (*01) (invalid; error recovery)
|
||||
["attachment; filename*0=foo; filename*01=bar",
|
||||
"attachment", "foo",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */],
|
||||
[
|
||||
"attachment; filename*0=foo; filename*01=bar",
|
||||
"attachment",
|
||||
"foo",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */
|
||||
],
|
||||
|
||||
// continuations should prevail over non-extended (unless RFC 5987)
|
||||
["attachment; filename=basic; filename*0*=UTF-8''multi;\r\n"
|
||||
+ " filename*1=line;\r\n"
|
||||
+ " filename*2*=%20extended",
|
||||
"attachment", "multiline extended",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''multi;\r\n" +
|
||||
" filename*1=line;\r\n" +
|
||||
" filename*2*=%20extended",
|
||||
"attachment",
|
||||
"multiline extended",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// Gaps should result in returning only value until gap hit
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename=basic; filename*0*=UTF-8''multi;\r\n"
|
||||
+ " filename*1=line;\r\n"
|
||||
+ " filename*3*=%20extended",
|
||||
"attachment", "multiline",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''multi;\r\n" +
|
||||
" filename*1=line;\r\n" +
|
||||
" filename*3*=%20extended",
|
||||
"attachment",
|
||||
"multiline",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// First series, only please, and don't slurp up higher elements (*2 in this
|
||||
// case) from later series into earlier one (invalid; error recovery)
|
||||
["attachment; filename=basic; filename*0*=UTF-8''multi;\r\n"
|
||||
+ " filename*1=line;\r\n"
|
||||
+ " filename*0*=UTF-8''wrong;\r\n"
|
||||
+ " filename*1=bad;\r\n"
|
||||
+ " filename*2=evil",
|
||||
"attachment", "multiline",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''multi;\r\n" +
|
||||
" filename*1=line;\r\n" +
|
||||
" filename*0*=UTF-8''wrong;\r\n" +
|
||||
" filename*1=bad;\r\n" +
|
||||
" filename*2=evil",
|
||||
"attachment",
|
||||
"multiline",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// RFC 2231 not clear on correct outcome: we prefer non-continued extended
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename=basic; filename*0=UTF-8''multi\r\n;"
|
||||
+ " filename*=UTF-8''extended;\r\n"
|
||||
+ " filename*1=line;\r\n"
|
||||
+ " filename*2*=%20extended",
|
||||
"attachment", "extended"],
|
||||
[
|
||||
"attachment; filename=basic; filename*0=UTF-8''multi\r\n;" +
|
||||
" filename*=UTF-8''extended;\r\n" +
|
||||
" filename*1=line;\r\n" +
|
||||
" filename*2*=%20extended",
|
||||
"attachment",
|
||||
"extended",
|
||||
],
|
||||
|
||||
// sneaky: if unescaped, make sure we leave UTF-8'' in value
|
||||
["attachment; filename*0=UTF-8''unescaped;\r\n"
|
||||
+ " filename*1*=%20so%20includes%20UTF-8''%20in%20value",
|
||||
"attachment", "UTF-8''unescaped so includes UTF-8'' in value",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */],
|
||||
[
|
||||
"attachment; filename*0=UTF-8''unescaped;\r\n" +
|
||||
" filename*1*=%20so%20includes%20UTF-8''%20in%20value",
|
||||
"attachment",
|
||||
"UTF-8''unescaped so includes UTF-8'' in value",
|
||||
/* "attachment", Cr.NS_ERROR_INVALID_ARG */
|
||||
],
|
||||
|
||||
// sneaky: if unescaped, make sure we leave UTF-8'' in value
|
||||
["attachment; filename=basic; filename*0=UTF-8''unescaped;\r\n"
|
||||
+ " filename*1*=%20so%20includes%20UTF-8''%20in%20value",
|
||||
"attachment", "UTF-8''unescaped so includes UTF-8'' in value",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0=UTF-8''unescaped;\r\n" +
|
||||
" filename*1*=%20so%20includes%20UTF-8''%20in%20value",
|
||||
"attachment",
|
||||
"UTF-8''unescaped so includes UTF-8'' in value",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// Prefer basic over invalid continuation
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename=basic; filename*1=multi;\r\n"
|
||||
+ " filename*2=line;\r\n"
|
||||
+ " filename*3*=%20extended",
|
||||
"attachment", "basic"],
|
||||
[
|
||||
"attachment; filename=basic; filename*1=multi;\r\n" +
|
||||
" filename*2=line;\r\n" +
|
||||
" filename*3*=%20extended",
|
||||
"attachment",
|
||||
"basic",
|
||||
],
|
||||
|
||||
// support digits over 10
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n"
|
||||
+ " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n"
|
||||
+ " filename*11=b; filename*12=c;filename*13=d;filename*14=e;filename*15=f\r\n",
|
||||
"attachment", "0123456789abcdef",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
|
||||
" filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n" +
|
||||
" filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n" +
|
||||
" filename*11=b; filename*12=c;filename*13=d;filename*14=e;filename*15=f\r\n",
|
||||
"attachment",
|
||||
"0123456789abcdef",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// support digits over 10 (detect gaps)
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n"
|
||||
+ " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n"
|
||||
+ " filename*11=b; filename*12=c;filename*14=e\r\n",
|
||||
"attachment", "0123456789abc",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
|
||||
" filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n" +
|
||||
" filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n" +
|
||||
" filename*11=b; filename*12=c;filename*14=e\r\n",
|
||||
"attachment",
|
||||
"0123456789abc",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// return nothing: invalid
|
||||
// (invalid; error recovery)
|
||||
["attachment; filename*1=multi;\r\n"
|
||||
+ " filename*2=line;\r\n"
|
||||
+ " filename*3*=%20extended",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
[
|
||||
"attachment; filename*1=multi;\r\n" +
|
||||
" filename*2=line;\r\n" +
|
||||
" filename*3*=%20extended",
|
||||
"attachment",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
|
||||
// Bug 272541: Empty disposition type treated as "attachment"
|
||||
|
||||
// sanity check
|
||||
["attachment; filename=foo.html",
|
||||
"attachment", "foo.html",
|
||||
"attachment", "foo.html"],
|
||||
[
|
||||
"attachment; filename=foo.html",
|
||||
"attachment",
|
||||
"foo.html",
|
||||
"attachment",
|
||||
"foo.html",
|
||||
],
|
||||
|
||||
// the actual bug
|
||||
["; filename=foo.html",
|
||||
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "foo.html",
|
||||
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "foo.html"],
|
||||
[
|
||||
"; filename=foo.html",
|
||||
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY,
|
||||
"foo.html",
|
||||
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY,
|
||||
"foo.html",
|
||||
],
|
||||
|
||||
// regression check, but see bug 671204
|
||||
["filename=foo.html",
|
||||
"filename=foo.html", "foo.html",
|
||||
"filename=foo.html", "foo.html"],
|
||||
[
|
||||
"filename=foo.html",
|
||||
"filename=foo.html",
|
||||
"foo.html",
|
||||
"filename=foo.html",
|
||||
"foo.html",
|
||||
],
|
||||
|
||||
// Bug 384571: RFC 2231 parameters not decoded when appearing in reversed order
|
||||
|
||||
// check ordering
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n"
|
||||
+ " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n"
|
||||
+ " filename*11=b; filename*12=c;filename*13=d;filename*15=f;filename*14=e;\r\n",
|
||||
"attachment", "0123456789abcdef",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
|
||||
" filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n" +
|
||||
" filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n" +
|
||||
" filename*11=b; filename*12=c;filename*13=d;filename*15=f;filename*14=e;\r\n",
|
||||
"attachment",
|
||||
"0123456789abcdef",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// check non-digits in sequence numbers
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*1a=1\r\n",
|
||||
"attachment", "0",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
|
||||
" filename*1a=1\r\n",
|
||||
"attachment",
|
||||
"0",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// check duplicate sequence numbers
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*0=bad; filename*1=1;\r\n",
|
||||
"attachment", "0",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
|
||||
" filename*0=bad; filename*1=1;\r\n",
|
||||
"attachment",
|
||||
"0",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// check overflow
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*11111111111111111111111111111111111111111111111111111111111=1",
|
||||
"attachment", "0",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
|
||||
" filename*11111111111111111111111111111111111111111111111111111111111=1",
|
||||
"attachment",
|
||||
"0",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// check underflow
|
||||
["attachment; filename=basic; filename*0*=UTF-8''0;\r\n"
|
||||
+ " filename*-1=1",
|
||||
"attachment", "0",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
"attachment; filename=basic; filename*0*=UTF-8''0;\r\n" + " filename*-1=1",
|
||||
"attachment",
|
||||
"0",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// check mixed token/quoted-string
|
||||
["attachment; filename=basic; filename*0=\"0\";\r\n"
|
||||
+ " filename*1=1;\r\n"
|
||||
+ " filename*2*=%32",
|
||||
"attachment", "012",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
'attachment; filename=basic; filename*0="0";\r\n' +
|
||||
" filename*1=1;\r\n" +
|
||||
" filename*2*=%32",
|
||||
"attachment",
|
||||
"012",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// check empty sequence number
|
||||
["attachment; filename=basic; filename**=UTF-8''0\r\n",
|
||||
"attachment", "basic",
|
||||
"attachment", "basic"],
|
||||
|
||||
[
|
||||
"attachment; filename=basic; filename**=UTF-8''0\r\n",
|
||||
"attachment",
|
||||
"basic",
|
||||
"attachment",
|
||||
"basic",
|
||||
],
|
||||
|
||||
// Bug 419157: ensure that a MIME parameter with no charset information
|
||||
// fallbacks to Latin-1
|
||||
|
||||
["attachment;filename=IT839\x04\xB5(m8)2.pdf;",
|
||||
"attachment", "IT839\u0004\u00b5(m8)2.pdf"],
|
||||
[
|
||||
"attachment;filename=IT839\x04\xB5(m8)2.pdf;",
|
||||
"attachment",
|
||||
"IT839\u0004\u00b5(m8)2.pdf",
|
||||
],
|
||||
|
||||
// Bug 588389: unescaping backslashes in quoted string parameters
|
||||
|
||||
// '\"', should be parsed as '"'
|
||||
["attachment; filename=" + DQUOTE + (BS + DQUOTE) + DQUOTE,
|
||||
"attachment", DQUOTE],
|
||||
[
|
||||
"attachment; filename=" + DQUOTE + (BS + DQUOTE) + DQUOTE,
|
||||
"attachment",
|
||||
DQUOTE,
|
||||
],
|
||||
|
||||
// 'a\"b', should be parsed as 'a"b'
|
||||
["attachment; filename=" + DQUOTE + 'a' + (BS + DQUOTE) + 'b' + DQUOTE,
|
||||
"attachment", "a" + DQUOTE + "b"],
|
||||
[
|
||||
"attachment; filename=" + DQUOTE + "a" + (BS + DQUOTE) + "b" + DQUOTE,
|
||||
"attachment",
|
||||
"a" + DQUOTE + "b",
|
||||
],
|
||||
|
||||
// '\x', should be parsed as 'x'
|
||||
["attachment; filename=" + DQUOTE + (BS + "x") + DQUOTE,
|
||||
"attachment", "x"],
|
||||
["attachment; filename=" + DQUOTE + (BS + "x") + DQUOTE, "attachment", "x"],
|
||||
|
||||
// test empty param (quoted-string)
|
||||
["attachment; filename=" + DQUOTE + DQUOTE,
|
||||
"attachment", ""],
|
||||
["attachment; filename=" + DQUOTE + DQUOTE, "attachment", ""],
|
||||
|
||||
// test empty param
|
||||
["attachment; filename=",
|
||||
"attachment", ""],
|
||||
["attachment; filename=", "attachment", ""],
|
||||
|
||||
// Bug 601933: RFC 2047 does not apply to parameters (at least in HTTP)
|
||||
["attachment; filename==?ISO-8859-1?Q?foo-=E4.html?=",
|
||||
"attachment", "foo-\u00e4.html",
|
||||
/* "attachment", "=?ISO-8859-1?Q?foo-=E4.html?=" */],
|
||||
[
|
||||
"attachment; filename==?ISO-8859-1?Q?foo-=E4.html?=",
|
||||
"attachment",
|
||||
"foo-\u00e4.html",
|
||||
/* "attachment", "=?ISO-8859-1?Q?foo-=E4.html?=" */
|
||||
],
|
||||
|
||||
["attachment; filename=\"=?ISO-8859-1?Q?foo-=E4.html?=\"",
|
||||
"attachment", "foo-\u00e4.html",
|
||||
/* "attachment", "=?ISO-8859-1?Q?foo-=E4.html?=" */],
|
||||
[
|
||||
'attachment; filename="=?ISO-8859-1?Q?foo-=E4.html?="',
|
||||
"attachment",
|
||||
"foo-\u00e4.html",
|
||||
/* "attachment", "=?ISO-8859-1?Q?foo-=E4.html?=" */
|
||||
],
|
||||
|
||||
// format sent by GMail as of 2012-07-23 (5987 overrides 2047)
|
||||
["attachment; filename=\"=?ISO-8859-1?Q?foo-=E4.html?=\"; filename*=UTF-8''5987",
|
||||
"attachment", "5987"],
|
||||
[
|
||||
"attachment; filename=\"=?ISO-8859-1?Q?foo-=E4.html?=\"; filename*=UTF-8''5987",
|
||||
"attachment",
|
||||
"5987",
|
||||
],
|
||||
|
||||
// Bug 651185: double quotes around 2231/5987 encoded param
|
||||
// Change reverted to backwards compat issues with various web services,
|
||||
|
|
@ -281,12 +382,14 @@ var tests = [
|
|||
// is tried again in the future, email probably needs to be special-cased.
|
||||
|
||||
// sanity check
|
||||
["attachment; filename*=utf-8''%41",
|
||||
"attachment", "A"],
|
||||
["attachment; filename*=utf-8''%41", "attachment", "A"],
|
||||
|
||||
// the actual bug
|
||||
["attachment; filename*=" + DQUOTE + "utf-8''%41" + DQUOTE,
|
||||
"attachment", "A"],
|
||||
[
|
||||
"attachment; filename*=" + DQUOTE + "utf-8''%41" + DQUOTE,
|
||||
"attachment",
|
||||
"A",
|
||||
],
|
||||
// previously with the fix for 651185:
|
||||
// "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
|
|
@ -294,52 +397,51 @@ var tests = [
|
|||
// in params
|
||||
|
||||
// sanity check
|
||||
["attachment; filename*=UTF-8''foo-%41.html",
|
||||
"attachment", "foo-A.html"],
|
||||
["attachment; filename*=UTF-8''foo-%41.html", "attachment", "foo-A.html"],
|
||||
|
||||
// the actual bug
|
||||
["attachment; filename *=UTF-8''foo-%41.html",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
[
|
||||
"attachment; filename *=UTF-8''foo-%41.html",
|
||||
"attachment",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
|
||||
// the actual bug, without 2231/5987 encoding
|
||||
["attachment; filename X",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
["attachment; filename X", "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// sanity check with WS on both sides
|
||||
["attachment; filename = foo-A.html",
|
||||
"attachment", "foo-A.html"],
|
||||
["attachment; filename = foo-A.html", "attachment", "foo-A.html"],
|
||||
|
||||
// Bug 685192: in RFC2231/5987 encoding, a missing charset field should be
|
||||
// treated as error
|
||||
|
||||
// the actual bug
|
||||
["attachment; filename*=''foo",
|
||||
"attachment", "foo"],
|
||||
["attachment; filename*=''foo", "attachment", "foo"],
|
||||
// previously with the fix for 692574:
|
||||
// "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// sanity check
|
||||
["attachment; filename*=a''foo",
|
||||
"attachment", "foo"],
|
||||
["attachment; filename*=a''foo", "attachment", "foo"],
|
||||
|
||||
// Bug 692574: RFC2231/5987 decoding should not tolerate missing single
|
||||
// quotes
|
||||
|
||||
// one missing
|
||||
["attachment; filename*=UTF-8'foo-%41.html",
|
||||
"attachment", "foo-A.html"],
|
||||
["attachment; filename*=UTF-8'foo-%41.html", "attachment", "foo-A.html"],
|
||||
// previously with the fix for 692574:
|
||||
// "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// both missing
|
||||
["attachment; filename*=foo-%41.html",
|
||||
"attachment","foo-A.html"],
|
||||
["attachment; filename*=foo-%41.html", "attachment", "foo-A.html"],
|
||||
// previously with the fix for 692574:
|
||||
// "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// make sure fallback works
|
||||
["attachment; filename*=UTF-8'foo-%41.html; filename=bar.html",
|
||||
"attachment", "foo-A.html"],
|
||||
[
|
||||
"attachment; filename*=UTF-8'foo-%41.html; filename=bar.html",
|
||||
"attachment",
|
||||
"foo-A.html",
|
||||
],
|
||||
// previously with the fix for 692574:
|
||||
// "attachment", "bar.html"],
|
||||
|
||||
|
|
@ -347,134 +449,209 @@ var tests = [
|
|||
// as authoritative
|
||||
|
||||
// UTF-8 labeled ISO-8859-1
|
||||
["attachment; filename*=ISO-8859-1''%c3%a4",
|
||||
"attachment", "\u00c3\u00a4"],
|
||||
["attachment; filename*=ISO-8859-1''%c3%a4", "attachment", "\u00c3\u00a4"],
|
||||
|
||||
// UTF-8 labeled ISO-8859-1, but with octets not allowed in ISO-8859-1
|
||||
// accepts x82, understands it as Win1252, maps it to Unicode \u20a1
|
||||
["attachment; filename*=ISO-8859-1''%e2%82%ac",
|
||||
"attachment", "\u00e2\u201a\u00ac"],
|
||||
[
|
||||
"attachment; filename*=ISO-8859-1''%e2%82%ac",
|
||||
"attachment",
|
||||
"\u00e2\u201a\u00ac",
|
||||
],
|
||||
|
||||
// defective UTF-8
|
||||
["attachment; filename*=UTF-8''A%e4B",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
["attachment; filename*=UTF-8''A%e4B", "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// defective UTF-8, with fallback
|
||||
["attachment; filename*=UTF-8''A%e4B; filename=fallback",
|
||||
"attachment", "fallback"],
|
||||
[
|
||||
"attachment; filename*=UTF-8''A%e4B; filename=fallback",
|
||||
"attachment",
|
||||
"fallback",
|
||||
],
|
||||
|
||||
// defective UTF-8 (continuations), with fallback
|
||||
["attachment; filename*0*=UTF-8''A%e4B; filename=fallback",
|
||||
"attachment", "fallback"],
|
||||
[
|
||||
"attachment; filename*0*=UTF-8''A%e4B; filename=fallback",
|
||||
"attachment",
|
||||
"fallback",
|
||||
],
|
||||
|
||||
// check that charsets aren't mixed up
|
||||
["attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4; filename*=ISO-8859-1''currency-sign%3d%a4",
|
||||
"attachment", "currency-sign=\u00a4"],
|
||||
[
|
||||
"attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4; filename*=ISO-8859-1''currency-sign%3d%a4",
|
||||
"attachment",
|
||||
"currency-sign=\u00a4",
|
||||
],
|
||||
|
||||
// same as above, except reversed
|
||||
["attachment; filename*=ISO-8859-1''currency-sign%3d%a4; filename*0*=ISO-8859-15''euro-sign%3d%a4",
|
||||
"attachment", "currency-sign=\u00a4"],
|
||||
[
|
||||
"attachment; filename*=ISO-8859-1''currency-sign%3d%a4; filename*0*=ISO-8859-15''euro-sign%3d%a4",
|
||||
"attachment",
|
||||
"currency-sign=\u00a4",
|
||||
],
|
||||
|
||||
// Bug 704989: add workaround for broken Outlook Web App (OWA)
|
||||
// attachment handling
|
||||
|
||||
["attachment; filename*=\"a%20b\"",
|
||||
"attachment", "a b"],
|
||||
['attachment; filename*="a%20b"', "attachment", "a b"],
|
||||
|
||||
// Bug 717121: crash nsMIMEHeaderParamImpl::DoParameterInternal
|
||||
|
||||
["attachment; filename=\"",
|
||||
"attachment", ""],
|
||||
['attachment; filename="', "attachment", ""],
|
||||
|
||||
// We used to read past string if last param w/o = and ;
|
||||
// Note: was only detected on windows PGO builds
|
||||
["attachment; filename=foo; trouble",
|
||||
"attachment", "foo"],
|
||||
["attachment; filename=foo; trouble", "attachment", "foo"],
|
||||
|
||||
// Same, followed by space, hits another case
|
||||
["attachment; filename=foo; trouble ",
|
||||
"attachment", "foo"],
|
||||
["attachment; filename=foo; trouble ", "attachment", "foo"],
|
||||
|
||||
["attachment",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
["attachment", "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// Bug 730574: quoted-string in RFC2231-continuations not handled
|
||||
|
||||
['attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\r.html"',
|
||||
"attachment", "foobar.html",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
'attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\r.html"',
|
||||
"attachment",
|
||||
"foobar.html",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// unmatched escape char
|
||||
['attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\',
|
||||
"attachment", "fooba\\",
|
||||
/* "attachment", "basic" */],
|
||||
[
|
||||
'attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\',
|
||||
"attachment",
|
||||
"fooba\\",
|
||||
/* "attachment", "basic" */
|
||||
],
|
||||
|
||||
// Bug 732369: Content-Disposition parser does not require presence of ";" between params
|
||||
// optimally, this would not even return the disposition type "attachment"
|
||||
|
||||
["attachment; extension=bla filename=foo",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
[
|
||||
"attachment; extension=bla filename=foo",
|
||||
"attachment",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
|
||||
["attachment; filename=foo extension=bla",
|
||||
"attachment", "foo"],
|
||||
["attachment; filename=foo extension=bla", "attachment", "foo"],
|
||||
|
||||
["attachment filename=foo",
|
||||
"attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
["attachment filename=foo", "attachment", Cr.NS_ERROR_INVALID_ARG],
|
||||
|
||||
// Bug 777687: handling of broken %escapes
|
||||
|
||||
["attachment; filename*=UTF-8''f%oo; filename=bar",
|
||||
"attachment", "bar"],
|
||||
["attachment; filename*=UTF-8''f%oo; filename=bar", "attachment", "bar"],
|
||||
|
||||
["attachment; filename*=UTF-8''foo%; filename=bar",
|
||||
"attachment", "bar"],
|
||||
["attachment; filename*=UTF-8''foo%; filename=bar", "attachment", "bar"],
|
||||
|
||||
// Bug 783502 - xpcshell test netwerk/test/unit/test_MIME_params.js fails on AddressSanitizer
|
||||
['attachment; filename="\\b\\a\\',
|
||||
"attachment", "ba\\"],
|
||||
['attachment; filename="\\b\\a\\', "attachment", "ba\\"],
|
||||
|
||||
// Bug 1412213 - do continue to parse, behind an empty parameter
|
||||
['attachment; ; filename=foo',
|
||||
"attachment", "foo"],
|
||||
["attachment; ; filename=foo", "attachment", "foo"],
|
||||
|
||||
// Bug 1412213 - do continue to parse, behind a parameter w/o =
|
||||
['attachment; badparameter; filename=foo',
|
||||
"attachment", "foo"],
|
||||
["attachment; badparameter; filename=foo", "attachment", "foo"],
|
||||
];
|
||||
|
||||
var rfc5987paramtests = [
|
||||
[ // basic test
|
||||
"UTF-8'language'value", "value", "language", Cr.NS_OK ],
|
||||
[ // percent decoding
|
||||
"UTF-8''1%202", "1 2", "", Cr.NS_OK ],
|
||||
[ // UTF-8
|
||||
"UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", "\u00a3 and \u20ac rates", "", Cr.NS_OK ],
|
||||
[ // missing charset
|
||||
"''abc", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // ISO-8859-1: unsupported
|
||||
"ISO-8859-1''%A3%20rates", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // unknown charset
|
||||
"foo''abc", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // missing component
|
||||
"abc", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // missing component
|
||||
"'abc", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // illegal chars
|
||||
"UTF-8''a b", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // broken % escapes
|
||||
"UTF-8''a%zz", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // broken % escapes
|
||||
"UTF-8''a%b", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // broken % escapes
|
||||
"UTF-8''a%", "", "", Cr.NS_ERROR_INVALID_ARG ],
|
||||
[ // broken UTF-8
|
||||
"UTF-8''%A3%20rates", "", "", 0x8050000E /* NS_ERROR_UDEC_ILLEGALINPUT */ ],
|
||||
[
|
||||
// basic test
|
||||
"UTF-8'language'value",
|
||||
"value",
|
||||
"language",
|
||||
Cr.NS_OK,
|
||||
],
|
||||
[
|
||||
// percent decoding
|
||||
"UTF-8''1%202",
|
||||
"1 2",
|
||||
"",
|
||||
Cr.NS_OK,
|
||||
],
|
||||
[
|
||||
// UTF-8
|
||||
"UTF-8''%c2%a3%20and%20%e2%82%ac%20rates",
|
||||
"\u00a3 and \u20ac rates",
|
||||
"",
|
||||
Cr.NS_OK,
|
||||
],
|
||||
[
|
||||
// missing charset
|
||||
"''abc",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// ISO-8859-1: unsupported
|
||||
"ISO-8859-1''%A3%20rates",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// unknown charset
|
||||
"foo''abc",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// missing component
|
||||
"abc",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// missing component
|
||||
"'abc",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// illegal chars
|
||||
"UTF-8''a b",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// broken % escapes
|
||||
"UTF-8''a%zz",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// broken % escapes
|
||||
"UTF-8''a%b",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// broken % escapes
|
||||
"UTF-8''a%",
|
||||
"",
|
||||
"",
|
||||
Cr.NS_ERROR_INVALID_ARG,
|
||||
],
|
||||
[
|
||||
// broken UTF-8
|
||||
"UTF-8''%A3%20rates",
|
||||
"",
|
||||
"",
|
||||
0x8050000e /* NS_ERROR_UDEC_ILLEGALINPUT */,
|
||||
],
|
||||
];
|
||||
|
||||
function do_tests(whichRFC)
|
||||
{
|
||||
var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"]
|
||||
.getService(Ci.nsIMIMEHeaderParam);
|
||||
function do_tests(whichRFC) {
|
||||
var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"].getService(
|
||||
Ci.nsIMIMEHeaderParam
|
||||
);
|
||||
|
||||
var unused = { value: null };
|
||||
|
||||
|
|
@ -482,19 +659,20 @@ function do_tests(whichRFC)
|
|||
dump("Testing #" + i + ": " + tests[i] + "\n");
|
||||
|
||||
// check disposition type
|
||||
var expectedDt = tests[i].length == 3 || whichRFC == 0 ? tests[i][1] : tests[i][3];
|
||||
var expectedDt =
|
||||
tests[i].length == 3 || whichRFC == 0 ? tests[i][1] : tests[i][3];
|
||||
|
||||
try {
|
||||
var result;
|
||||
|
||||
if (whichRFC == 0)
|
||||
if (whichRFC == 0) {
|
||||
result = mhp.getParameter(tests[i][0], "", "UTF-8", true, unused);
|
||||
else
|
||||
} else {
|
||||
result = mhp.getParameterHTTP(tests[i][0], "", "UTF-8", true, unused);
|
||||
}
|
||||
|
||||
Assert.equal(result, expectedDt);
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
// Tests can also succeed by expecting to fail with given error code
|
||||
if (e.result) {
|
||||
// Allow following tests to run by catching exception from do_check_eq()
|
||||
|
|
@ -506,19 +684,32 @@ function do_tests(whichRFC)
|
|||
}
|
||||
|
||||
// check filename parameter
|
||||
var expectedFn = tests[i].length == 3 || whichRFC == 0 ? tests[i][2] : tests[i][4];
|
||||
var expectedFn =
|
||||
tests[i].length == 3 || whichRFC == 0 ? tests[i][2] : tests[i][4];
|
||||
|
||||
try {
|
||||
var result;
|
||||
|
||||
if (whichRFC == 0)
|
||||
result = mhp.getParameter(tests[i][0], "filename", "UTF-8", true, unused);
|
||||
else
|
||||
result = mhp.getParameterHTTP(tests[i][0], "filename", "UTF-8", true, unused);
|
||||
if (whichRFC == 0) {
|
||||
result = mhp.getParameter(
|
||||
tests[i][0],
|
||||
"filename",
|
||||
"UTF-8",
|
||||
true,
|
||||
unused
|
||||
);
|
||||
} else {
|
||||
result = mhp.getParameterHTTP(
|
||||
tests[i][0],
|
||||
"filename",
|
||||
"UTF-8",
|
||||
true,
|
||||
unused
|
||||
);
|
||||
}
|
||||
|
||||
Assert.equal(result, expectedFn);
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
// Tests can also succeed by expecting to fail with given error code
|
||||
if (e.result) {
|
||||
// Allow following tests to run by catching exception from do_check_eq()
|
||||
|
|
@ -532,8 +723,9 @@ function do_tests(whichRFC)
|
|||
}
|
||||
|
||||
function test_decode5987Param() {
|
||||
var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"]
|
||||
.getService(Ci.nsIMIMEHeaderParam);
|
||||
var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"].getService(
|
||||
Ci.nsIMIMEHeaderParam
|
||||
);
|
||||
|
||||
for (var i = 0; i < rfc5987paramtests.length; ++i) {
|
||||
dump("Testing #" + i + ": " + rfc5987paramtests[i] + "\n");
|
||||
|
|
@ -544,19 +736,16 @@ function test_decode5987Param() {
|
|||
if (rfc5987paramtests[i][3] == Cr.NS_OK) {
|
||||
Assert.equal(rfc5987paramtests[i][1], decoded);
|
||||
Assert.equal(rfc5987paramtests[i][2], lang.value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Assert.equal(rfc5987paramtests[i][3], "instead got: " + decoded);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
Assert.equal(rfc5987paramtests[i][3], e.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
||||
// Test RFC 2231 (complete header field values)
|
||||
do_tests(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
|
||||
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,16 +28,17 @@ 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 = {};
|
||||
|
|
@ -46,7 +47,6 @@ function getFileContents(aFile)
|
|||
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,22 +143,24 @@ 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 };
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
|
|
@ -159,10 +168,11 @@ function test_async_copy()
|
|||
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);
|
||||
|
|
@ -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() {});
|
||||
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({});
|
||||
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,21 +325,25 @@ 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({
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}, function(aInputStream, aResult) {
|
||||
},
|
||||
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);
|
||||
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);
|
||||
|
|
@ -349,11 +354,11 @@ function test_asyncFetch_with_nsIURI()
|
|||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
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,17 +371,20 @@ function test_asyncFetch_with_string()
|
|||
server.start(-1);
|
||||
|
||||
// Open our location asynchronously.
|
||||
NetUtil.asyncFetch({
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: "http://localhost:" + server.identity.primaryPort + "/test",
|
||||
loadUsingSystemPrincipal: true,
|
||||
}, function(aInputStream, aResult) {
|
||||
},
|
||||
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);
|
||||
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);
|
||||
|
|
@ -387,23 +395,24 @@ function test_asyncFetch_with_string()
|
|||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
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,17 +421,20 @@ 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({
|
||||
NetUtil.asyncFetch(
|
||||
{
|
||||
uri: NetUtil.newURI(file),
|
||||
loadUsingSystemPrincipal: true,
|
||||
}, function(aInputStream, aResult) {
|
||||
},
|
||||
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);
|
||||
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);
|
||||
|
|
@ -433,25 +445,30 @@ function test_asyncFetch_with_nsIFile()
|
|||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
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) {
|
||||
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);
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(aInputStream, TEST_DATA.length),
|
||||
TEST_DATA
|
||||
);
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
|
|
@ -459,11 +476,11 @@ function test_asyncFetch_with_nsIInputString()
|
|||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER);
|
||||
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,
|
||||
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);
|
||||
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,
|
||||
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);
|
||||
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),
|
||||
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);
|
||||
Ci.nsIContentPolicy.TYPE_OTHER
|
||||
);
|
||||
|
||||
function checkEqualToIOSChannel(channel) {
|
||||
Assert.ok(iosChannel.URI.equals(channel.URI));
|
||||
}
|
||||
|
||||
checkEqualToIOSChannel(NetUtil.newChannel({
|
||||
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({
|
||||
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, {
|
||||
Assert.equal(
|
||||
NetUtil.readInputStreamToString(istream, TEST_DATA_UTF8.length, {
|
||||
charset: "UTF-8",
|
||||
replacement: Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER}),
|
||||
TEST_DATA);
|
||||
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
|
|
@ -1,8 +1,8 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
|
||||
var gIoService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
|
||||
var gIoService = Cc["@mozilla.org/network/io-service;1"].getService(
|
||||
Ci.nsIIOService
|
||||
);
|
||||
|
||||
// Run by: cd objdir; make -C netwerk/test/ xpcshell-tests
|
||||
// or: cd objdir; make SOLO_FILE="test_URIs2.js" -C netwerk/test/ check-one
|
||||
|
|
@ -19,81 +19,117 @@ var gIoService = Cc["@mozilla.org/network/io-service;1"]
|
|||
// TEST DATA
|
||||
// ---------
|
||||
var gTests = [
|
||||
{ spec: "view-source:about:blank",
|
||||
{
|
||||
spec: "view-source:about:blank",
|
||||
scheme: "view-source",
|
||||
prePath: "view-source:",
|
||||
pathQueryRef: "about:blank",
|
||||
ref: "",
|
||||
nsIURL: false, nsINestedURI: true, immutable: true },
|
||||
{ spec: "view-source:http://www.mozilla.org/",
|
||||
nsIURL: false,
|
||||
nsINestedURI: true,
|
||||
immutable: true,
|
||||
},
|
||||
{
|
||||
spec: "view-source:http://www.mozilla.org/",
|
||||
scheme: "view-source",
|
||||
prePath: "view-source:",
|
||||
pathQueryRef: "http://www.mozilla.org/",
|
||||
ref: "",
|
||||
nsIURL: false, nsINestedURI: true, immutable: true },
|
||||
{ spec: "x-external:",
|
||||
nsIURL: false,
|
||||
nsINestedURI: true,
|
||||
immutable: true,
|
||||
},
|
||||
{
|
||||
spec: "x-external:",
|
||||
scheme: "x-external",
|
||||
prePath: "x-external:",
|
||||
pathQueryRef: "",
|
||||
ref: "",
|
||||
nsIURL: false, nsINestedURI: false },
|
||||
{ spec: "x-external:abc",
|
||||
nsIURL: false,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "x-external:abc",
|
||||
scheme: "x-external",
|
||||
prePath: "x-external:",
|
||||
pathQueryRef: "abc",
|
||||
ref: "",
|
||||
nsIURL: false, nsINestedURI: false },
|
||||
{ spec: "http://www2.example.com/",
|
||||
nsIURL: false,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://www2.example.com/",
|
||||
relativeURI: "a/b/c/d",
|
||||
scheme: "http",
|
||||
prePath: "http://www2.example.com",
|
||||
pathQueryRef: "/a/b/c/d",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
// relative URL testcases from http://greenbytes.de/tech/webdav/rfc3986.html#rfc.section.5.4
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g:h",
|
||||
scheme: "g",
|
||||
prePath: "g:",
|
||||
pathQueryRef: "h",
|
||||
ref: "",
|
||||
nsIURL: false, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: false,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "./g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g/",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "/g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "?y",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/d;p?y",
|
||||
ref: "", // fix
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g?y",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
|
|
@ -101,8 +137,11 @@ var gTests = [
|
|||
ref: "", // fix
|
||||
specIgnoringRef: "http://a/b/c/g?y",
|
||||
hasRef: false,
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "#s",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
|
|
@ -110,21 +149,29 @@ var gTests = [
|
|||
ref: "s", // fix
|
||||
specIgnoringRef: "http://a/b/c/d;p?q",
|
||||
hasRef: true,
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g#s",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g#s",
|
||||
ref: "s",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g?y#s",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g?y#s",
|
||||
ref: "s",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
/*
|
||||
Bug xxxxxx - we return a path of b/c/;x
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
|
|
@ -135,20 +182,26 @@ var gTests = [
|
|||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
*/
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g;x",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g;x",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g;x?y#s",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g;x?y#s",
|
||||
ref: "s",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
/*
|
||||
Can't easily specify a relative URI of "" to the test code
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
|
|
@ -159,205 +212,284 @@ var gTests = [
|
|||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
*/
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: ".",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "./",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "..",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../..",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../../",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../../g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
|
||||
// abnormal examples
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../../../g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "../../../../g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
|
||||
// coalesce
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "/./g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "/../g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g.",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g.",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: ".g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/.g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g..",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g..",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "..g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/..g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: ".",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "./../g",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/g",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "./g/.",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g/",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g/./h",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g/h",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g/../h",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/h",
|
||||
ref: "", // fix
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g;x=1/./y",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/g;x=1/y",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "http://a/b/c/d;p?q",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "http://a/b/c/d;p?q",
|
||||
relativeURI: "g;x=1/../y",
|
||||
scheme: "http",
|
||||
prePath: "http://a",
|
||||
pathQueryRef: "/b/c/y",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
// protocol-relative http://tools.ietf.org/html/rfc3986#section-4.2
|
||||
{ spec: "http://www2.example.com/",
|
||||
{
|
||||
spec: "http://www2.example.com/",
|
||||
relativeURI: "//www3.example2.com/bar",
|
||||
scheme: "http",
|
||||
prePath: "http://www3.example2.com",
|
||||
pathQueryRef: "/bar",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
{ spec: "https://www2.example.com/",
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
{
|
||||
spec: "https://www2.example.com/",
|
||||
relativeURI: "//www3.example2.com/bar",
|
||||
scheme: "https",
|
||||
prePath: "https://www3.example2.com",
|
||||
pathQueryRef: "/bar",
|
||||
ref: "",
|
||||
nsIURL: true, nsINestedURI: false },
|
||||
nsIURL: true,
|
||||
nsINestedURI: false,
|
||||
},
|
||||
];
|
||||
|
||||
var gHashSuffixes = [
|
||||
"#",
|
||||
"#myRef",
|
||||
"#myRef?a=b",
|
||||
"#myRef#",
|
||||
"#myRef#x:yz"
|
||||
];
|
||||
var gHashSuffixes = ["#", "#myRef", "#myRef?a=b", "#myRef#", "#myRef#x:yz"];
|
||||
|
||||
// TEST HELPER FUNCTIONS
|
||||
// ---------------------
|
||||
function do_info(text, stack) {
|
||||
if (!stack)
|
||||
if (!stack) {
|
||||
stack = Components.stack.caller;
|
||||
}
|
||||
|
||||
dump( "\n" +
|
||||
"TEST-INFO | " + stack.filename + " | [" + stack.name + " : " +
|
||||
stack.lineNumber + "] " + text + "\n");
|
||||
dump(
|
||||
"\n" +
|
||||
"TEST-INFO | " +
|
||||
stack.filename +
|
||||
" | [" +
|
||||
stack.name +
|
||||
" : " +
|
||||
stack.lineNumber +
|
||||
"] " +
|
||||
text +
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
// Checks that the URIs satisfy equals(), in both possible orderings.
|
||||
|
|
@ -385,11 +517,13 @@ function do_check_uri_eq(aURI1, aURI2, aCheckTrueFunc = ok) {
|
|||
// The third argument is optional. If the client passes a third argument
|
||||
// (e.g. todo_check_true), we'll use that in lieu of ok.
|
||||
function do_check_uri_eqExceptRef(aURI1, aURI2, aCheckTrueFunc = ok) {
|
||||
do_info("(uri equalsExceptRef check: '" +
|
||||
aURI1.spec + "' == '" + aURI2.spec + "')");
|
||||
do_info(
|
||||
"(uri equalsExceptRef check: '" + aURI1.spec + "' == '" + aURI2.spec + "')"
|
||||
);
|
||||
aCheckTrueFunc(aURI1.equalsExceptRef(aURI2));
|
||||
do_info("(uri equalsExceptRef check: '" +
|
||||
aURI2.spec + "' == '" + aURI1.spec + "')");
|
||||
do_info(
|
||||
"(uri equalsExceptRef check: '" + aURI2.spec + "' == '" + aURI1.spec + "')"
|
||||
);
|
||||
aCheckTrueFunc(aURI2.equalsExceptRef(aURI1));
|
||||
}
|
||||
|
||||
|
|
@ -398,13 +532,20 @@ function do_check_uri_eqExceptRef(aURI1, aURI2, aCheckTrueFunc = ok) {
|
|||
// if aTestFunctor is passed in).
|
||||
function do_check_property(aTest, aURI, aPropertyName, aTestFunctor) {
|
||||
if (aTest[aPropertyName]) {
|
||||
var expectedVal = aTestFunctor ?
|
||||
aTestFunctor(aTest[aPropertyName]) :
|
||||
aTest[aPropertyName];
|
||||
var expectedVal = aTestFunctor
|
||||
? aTestFunctor(aTest[aPropertyName])
|
||||
: aTest[aPropertyName];
|
||||
|
||||
do_info("testing " + aPropertyName + " of " +
|
||||
(aTestFunctor ? "modified '" : "'" ) + aTest.spec +
|
||||
"' is '" + expectedVal + "'");
|
||||
do_info(
|
||||
"testing " +
|
||||
aPropertyName +
|
||||
" of " +
|
||||
(aTestFunctor ? "modified '" : "'") +
|
||||
aTest.spec +
|
||||
"' is '" +
|
||||
expectedVal +
|
||||
"'"
|
||||
);
|
||||
Assert.equal(aURI[aPropertyName], expectedVal);
|
||||
}
|
||||
}
|
||||
|
|
@ -413,7 +554,9 @@ function do_check_property(aTest, aURI, aPropertyName, aTestFunctor) {
|
|||
function do_test_uri_basic(aTest) {
|
||||
var URI;
|
||||
|
||||
do_info("Basic tests for " + aTest.spec + " relative URI: " + aTest.relativeURI);
|
||||
do_info(
|
||||
"Basic tests for " + aTest.spec + " relative URI: " + aTest.relativeURI
|
||||
);
|
||||
|
||||
try {
|
||||
URI = NetUtil.newURI(aTest.spec);
|
||||
|
|
@ -432,14 +575,26 @@ function do_test_uri_basic(aTest) {
|
|||
try {
|
||||
relURI = gIoService.newURI(aTest.relativeURI, null, URI);
|
||||
} catch (e) {
|
||||
do_info("Caught error on Relative parse of " + aTest.spec + " + " + aTest.relativeURI +" Error: " + e.result);
|
||||
do_info(
|
||||
"Caught error on Relative parse of " +
|
||||
aTest.spec +
|
||||
" + " +
|
||||
aTest.relativeURI +
|
||||
" Error: " +
|
||||
e.result
|
||||
);
|
||||
if (aTest.relativeFail) {
|
||||
Assert.equal(e.result, aTest.relativeFail);
|
||||
return;
|
||||
}
|
||||
do_throw(e.result);
|
||||
}
|
||||
do_info("relURI.pathQueryRef = " + relURI.pathQueryRef + ", was " + URI.pathQueryRef);
|
||||
do_info(
|
||||
"relURI.pathQueryRef = " +
|
||||
relURI.pathQueryRef +
|
||||
", was " +
|
||||
URI.pathQueryRef
|
||||
);
|
||||
URI = relURI;
|
||||
do_info("URI.pathQueryRef now = " + URI.pathQueryRef);
|
||||
}
|
||||
|
|
@ -447,15 +602,23 @@ function do_test_uri_basic(aTest) {
|
|||
// Sanity-check
|
||||
do_info("testing " + aTest.spec + " equals a clone of itself");
|
||||
do_check_uri_eq(URI, URI.mutate().finalize());
|
||||
do_check_uri_eqExceptRef(URI, URI.mutate().setRef("").finalize());
|
||||
do_check_uri_eqExceptRef(
|
||||
URI,
|
||||
URI.mutate()
|
||||
.setRef("")
|
||||
.finalize()
|
||||
);
|
||||
do_info("testing " + aTest.spec + " instanceof nsIURL");
|
||||
Assert.equal(URI instanceof Ci.nsIURL, aTest.nsIURL);
|
||||
do_info("testing " + aTest.spec + " instanceof nsINestedURI");
|
||||
Assert.equal(URI instanceof Ci.nsINestedURI,
|
||||
aTest.nsINestedURI);
|
||||
Assert.equal(URI instanceof Ci.nsINestedURI, aTest.nsINestedURI);
|
||||
|
||||
do_info("testing that " + aTest.spec + " throws or returns false " +
|
||||
"from equals(null)");
|
||||
do_info(
|
||||
"testing that " +
|
||||
aTest.spec +
|
||||
" throws or returns false " +
|
||||
"from equals(null)"
|
||||
);
|
||||
// XXXdholbert At some point it'd probably be worth making this behavior
|
||||
// (throwing vs. returning false) consistent across URI implementations.
|
||||
var threw = false;
|
||||
|
|
@ -467,7 +630,6 @@ function do_test_uri_basic(aTest) {
|
|||
}
|
||||
Assert.ok(threw || !isEqualToNull);
|
||||
|
||||
|
||||
// Check the various components
|
||||
do_check_property(aTest, URI, "scheme");
|
||||
do_check_property(aTest, URI, "prePath");
|
||||
|
|
@ -497,39 +659,77 @@ function do_test_uri_with_hash_suffix(aTest, aSuffix) {
|
|||
try {
|
||||
origURI = gIoService.newURI(aTest.relativeURI, null, origURI);
|
||||
} catch (e) {
|
||||
do_info("Caught error on Relative parse of " + aTest.spec + " + " + aTest.relativeURI +" Error: " + e.result);
|
||||
do_info(
|
||||
"Caught error on Relative parse of " +
|
||||
aTest.spec +
|
||||
" + " +
|
||||
aTest.relativeURI +
|
||||
" Error: " +
|
||||
e.result
|
||||
);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
testURI = gIoService.newURI(aSuffix, null, origURI);
|
||||
} catch (e) {
|
||||
do_info("Caught error adding suffix to " + aTest.spec + " + " + aTest.relativeURI + ", suffix " + aSuffix + " Error: " + e.result);
|
||||
do_info(
|
||||
"Caught error adding suffix to " +
|
||||
aTest.spec +
|
||||
" + " +
|
||||
aTest.relativeURI +
|
||||
", suffix " +
|
||||
aSuffix +
|
||||
" Error: " +
|
||||
e.result
|
||||
);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
testURI = NetUtil.newURI(aTest.spec + aSuffix);
|
||||
}
|
||||
|
||||
do_info("testing " + aTest.spec + " with '" + aSuffix + "' appended " +
|
||||
"equals a clone of itself");
|
||||
do_info(
|
||||
"testing " +
|
||||
aTest.spec +
|
||||
" with '" +
|
||||
aSuffix +
|
||||
"' appended " +
|
||||
"equals a clone of itself"
|
||||
);
|
||||
do_check_uri_eq(testURI, testURI.mutate().finalize());
|
||||
|
||||
do_info("testing " + aTest.spec +
|
||||
" doesn't equal self with '" + aSuffix + "' appended");
|
||||
do_info(
|
||||
"testing " +
|
||||
aTest.spec +
|
||||
" doesn't equal self with '" +
|
||||
aSuffix +
|
||||
"' appended"
|
||||
);
|
||||
|
||||
Assert.ok(!origURI.equals(testURI));
|
||||
|
||||
do_info("testing " + aTest.spec +
|
||||
" is equalExceptRef to self with '" + aSuffix + "' appended");
|
||||
do_info(
|
||||
"testing " +
|
||||
aTest.spec +
|
||||
" is equalExceptRef to self with '" +
|
||||
aSuffix +
|
||||
"' appended"
|
||||
);
|
||||
do_check_uri_eqExceptRef(origURI, testURI);
|
||||
|
||||
Assert.equal(testURI.hasRef, true);
|
||||
|
||||
if (!origURI.ref) {
|
||||
// These tests fail if origURI has a ref
|
||||
do_info("testing cloneIgnoringRef on " + testURI.spec +
|
||||
" is equal to no-ref version but not equal to ref version");
|
||||
var cloneNoRef = testURI.mutate().setRef("").finalize();
|
||||
do_info(
|
||||
"testing cloneIgnoringRef on " +
|
||||
testURI.spec +
|
||||
" is equal to no-ref version but not equal to ref version"
|
||||
);
|
||||
var cloneNoRef = testURI
|
||||
.mutate()
|
||||
.setRef("")
|
||||
.finalize();
|
||||
do_check_uri_eq(cloneNoRef, origURI);
|
||||
Assert.ok(!cloneNoRef.equals(testURI));
|
||||
}
|
||||
|
|
@ -538,10 +738,12 @@ function do_test_uri_with_hash_suffix(aTest, aSuffix) {
|
|||
do_check_property(aTest, testURI, "prePath");
|
||||
if (!origURI.ref) {
|
||||
// These don't work if it's a ref already because '+' doesn't give the right result
|
||||
do_check_property(aTest, testURI, "pathQueryRef",
|
||||
function(aStr) { return aStr + aSuffix; });
|
||||
do_check_property(aTest, testURI, "ref",
|
||||
function(aStr) { return aSuffix.substr(1); });
|
||||
do_check_property(aTest, testURI, "pathQueryRef", function(aStr) {
|
||||
return aStr + aSuffix;
|
||||
});
|
||||
do_check_property(aTest, testURI, "ref", function(aStr) {
|
||||
return aSuffix.substr(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -556,26 +758,47 @@ function do_test_mutate_ref(aTest, aSuffix) {
|
|||
var testURI = NetUtil.newURI(aTest.spec);
|
||||
|
||||
// First: Try setting .ref to our suffix
|
||||
do_info("testing that setting .ref on " + aTest.spec +
|
||||
" to '" + aSuffix + "' does what we expect");
|
||||
testURI = testURI.mutate().setRef(aSuffix).finalize();
|
||||
do_info(
|
||||
"testing that setting .ref on " +
|
||||
aTest.spec +
|
||||
" to '" +
|
||||
aSuffix +
|
||||
"' does what we expect"
|
||||
);
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setRef(aSuffix)
|
||||
.finalize();
|
||||
do_check_uri_eq(testURI, refURIWithSuffix);
|
||||
do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
|
||||
|
||||
// Now try setting .ref but leave off the initial hash (expect same result)
|
||||
var suffixLackingHash = aSuffix.substr(1);
|
||||
if (suffixLackingHash) { // (skip this our suffix was *just* a #)
|
||||
do_info("testing that setting .ref on " + aTest.spec +
|
||||
" to '" + suffixLackingHash + "' does what we expect");
|
||||
testURI = testURI.mutate().setRef(suffixLackingHash).finalize();
|
||||
if (suffixLackingHash) {
|
||||
// (skip this our suffix was *just* a #)
|
||||
do_info(
|
||||
"testing that setting .ref on " +
|
||||
aTest.spec +
|
||||
" to '" +
|
||||
suffixLackingHash +
|
||||
"' does what we expect"
|
||||
);
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setRef(suffixLackingHash)
|
||||
.finalize();
|
||||
do_check_uri_eq(testURI, refURIWithSuffix);
|
||||
do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
|
||||
}
|
||||
|
||||
// Now, clear .ref (should get us back the original spec)
|
||||
do_info("testing that clearing .ref on " + testURI.spec +
|
||||
" does what we expect");
|
||||
testURI = testURI.mutate().setRef("").finalize();
|
||||
do_info(
|
||||
"testing that clearing .ref on " + testURI.spec + " does what we expect"
|
||||
);
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setRef("")
|
||||
.finalize();
|
||||
do_check_uri_eq(testURI, refURIWithoutSuffix);
|
||||
do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
|
||||
|
||||
|
|
@ -584,9 +807,13 @@ function do_test_mutate_ref(aTest, aSuffix) {
|
|||
|
||||
// Now try setting .spec directly (including suffix) and then clearing .ref
|
||||
var specWithSuffix = aTest.spec + aSuffix;
|
||||
do_info("testing that setting spec to " +
|
||||
specWithSuffix + " and then clearing ref does what we expect");
|
||||
testURI = testURI.mutate()
|
||||
do_info(
|
||||
"testing that setting spec to " +
|
||||
specWithSuffix +
|
||||
" and then clearing ref does what we expect"
|
||||
);
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setSpec(specWithSuffix)
|
||||
.setRef("")
|
||||
.finalize();
|
||||
|
|
@ -600,9 +827,13 @@ function do_test_mutate_ref(aTest, aSuffix) {
|
|||
testURI = NetUtil.newURI(aTest.spec);
|
||||
|
||||
var pathWithSuffix = aTest.pathQueryRef + aSuffix;
|
||||
do_info("testing that setting path to " +
|
||||
pathWithSuffix + " and then clearing ref does what we expect");
|
||||
testURI = testURI.mutate()
|
||||
do_info(
|
||||
"testing that setting path to " +
|
||||
pathWithSuffix +
|
||||
" and then clearing ref does what we expect"
|
||||
);
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setPathQueryRef(pathWithSuffix)
|
||||
.setRef("")
|
||||
.finalize();
|
||||
|
|
@ -610,10 +841,19 @@ function do_test_mutate_ref(aTest, aSuffix) {
|
|||
do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
|
||||
|
||||
// Also: make sure that clearing .pathQueryRef also clears .ref
|
||||
testURI = testURI.mutate().setPathQueryRef(pathWithSuffix).finalize();
|
||||
do_info("testing that clearing path from " +
|
||||
pathWithSuffix + " also clears .ref");
|
||||
testURI = testURI.mutate().setPathQueryRef("").finalize();
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setPathQueryRef(pathWithSuffix)
|
||||
.finalize();
|
||||
do_info(
|
||||
"testing that clearing path from " +
|
||||
pathWithSuffix +
|
||||
" also clears .ref"
|
||||
);
|
||||
testURI = testURI
|
||||
.mutate()
|
||||
.setPathQueryRef("")
|
||||
.finalize();
|
||||
Assert.equal(testURI.ref, "");
|
||||
}
|
||||
}
|
||||
|
|
@ -621,14 +861,15 @@ function do_test_mutate_ref(aTest, aSuffix) {
|
|||
|
||||
// TEST MAIN FUNCTION
|
||||
// ------------------
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
// UTF-8 check - From bug 622981
|
||||
// ASCII
|
||||
let base = gIoService.newURI("http://example.org/xenia?");
|
||||
let resolved = gIoService.newURI("?x", null, base);
|
||||
let expected = gIoService.newURI("http://example.org/xenia?x");
|
||||
do_info("Bug 662981: ACSII - comparing " + resolved.spec + " and " + expected.spec);
|
||||
do_info(
|
||||
"Bug 662981: ACSII - comparing " + resolved.spec + " and " + expected.spec
|
||||
);
|
||||
Assert.ok(resolved.equals(expected));
|
||||
|
||||
// UTF-8 character "è"
|
||||
|
|
@ -636,7 +877,9 @@ function run_test()
|
|||
base = gIoService.newURI("http://example.org/xènia?");
|
||||
resolved = gIoService.newURI("?x", null, base);
|
||||
expected = gIoService.newURI("http://example.org/xènia?x");
|
||||
do_info("Bug 662981: UTF8 - comparing " + resolved.spec + " and " + expected.spec);
|
||||
do_info(
|
||||
"Bug 662981: UTF8 - comparing " + resolved.spec + " and " + expected.spec
|
||||
);
|
||||
Assert.ok(resolved.equals(expected));
|
||||
|
||||
gTests.forEach(function(aTest) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
// 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 { 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);
|
||||
|
|
@ -139,14 +170,22 @@ function run_test() {
|
|||
|
||||
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]);
|
||||
}
|
||||
|
|
@ -161,22 +200,21 @@ function redirect(metadata, response, status, port, bugid) {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@
|
|||
|
||||
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,14 +84,20 @@ 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 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,7 +2,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/. */
|
||||
|
||||
|
||||
var unsafeAboutModule = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIAboutModule]),
|
||||
newChannel(aURI, aLoadInfo) {
|
||||
|
|
@ -13,32 +12,44 @@ var unsafeAboutModule = {
|
|||
},
|
||||
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",
|
||||
const ServerSocket = CC(
|
||||
"@mozilla.org/network/server-socket;1",
|
||||
"nsIServerSocket",
|
||||
"init");
|
||||
"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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@ XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
|||
var httpServer = null;
|
||||
|
||||
// needs to be rooted
|
||||
var cacheFlushObserver = cacheFlushObserver = { observe() {
|
||||
var cacheFlushObserver = (cacheFlushObserver = {
|
||||
observe() {
|
||||
cacheFlushObserver = null;
|
||||
readServerContentAgain();
|
||||
}};
|
||||
},
|
||||
});
|
||||
|
||||
var currentThread = null;
|
||||
|
||||
|
|
@ -31,9 +33,10 @@ function make_channel(url, callback, ctx) {
|
|||
}
|
||||
|
||||
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,8 +49,7 @@ 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");
|
||||
|
|
@ -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);
|
||||
|
|
@ -93,8 +93,7 @@ function run_test()
|
|||
}
|
||||
}
|
||||
|
||||
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(_ => {
|
||||
aos.asyncWait(
|
||||
_ => {
|
||||
os.write(altContent, altContent.length);
|
||||
aos.closeWithStatus(Cr.NS_ERROR_FAILURE);
|
||||
executeSoon(flushAndReadServerContentAgain);
|
||||
}, 0, 0, currentThread);
|
||||
},
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ function make_channel(url, callback, ctx) {
|
|||
}
|
||||
|
||||
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,8 +38,7 @@ 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");
|
||||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,11 @@ 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) {
|
||||
|
|
@ -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,15 +82,15 @@ 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() {
|
||||
let cacheFlushObserver = {
|
||||
observe() {
|
||||
if (!cacheFlushObserver) {
|
||||
info("ignoring cacheFlushObserver\n");
|
||||
return;
|
||||
|
|
@ -101,10 +98,10 @@ let cacheFlushObserver = { observe() {
|
|||
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,15 +129,15 @@ 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() {
|
||||
let cacheFlushObserver2 = {
|
||||
observe() {
|
||||
if (!cacheFlushObserver2) {
|
||||
info("ignoring cacheFlushObserver2\n");
|
||||
return;
|
||||
|
|
@ -149,10 +145,10 @@ let cacheFlushObserver2 = { observe() {
|
|||
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,15 +170,15 @@ 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() {
|
||||
let cacheFlushObserver3 = {
|
||||
observe() {
|
||||
if (!cacheFlushObserver3) {
|
||||
info("ignoring cacheFlushObserver3\n");
|
||||
return;
|
||||
|
|
@ -188,11 +187,10 @@ let cacheFlushObserver3 = { observe() {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ function make_channel(url, callback, ctx) {
|
|||
}
|
||||
|
||||
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,8 +38,7 @@ 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");
|
||||
|
|
@ -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);
|
||||
|
|
@ -84,8 +82,7 @@ function run_test()
|
|||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ 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) +
|
||||
const altContent =
|
||||
"a".repeat(128 * 1024) +
|
||||
"b".repeat(128 * 1024) +
|
||||
"c".repeat(128 * 1024) +
|
||||
"d".repeat(128 * 1024) +
|
||||
|
|
@ -40,16 +41,14 @@ const altContent = "a".repeat(128*1024) +
|
|||
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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,9 @@
|
|||
*/
|
||||
|
||||
var data = "data ";
|
||||
var altData = "alt-data"
|
||||
var altData = "alt-data";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
|
||||
// Expand both data to 1MB
|
||||
|
|
@ -30,9 +29,13 @@ function run_test()
|
|||
do_test_pending();
|
||||
}
|
||||
|
||||
function write_data()
|
||||
{
|
||||
asyncOpenCacheEntry("http://data/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null, function (status, entry) {
|
||||
function write_data() {
|
||||
asyncOpenCacheEntry(
|
||||
"http://data/",
|
||||
"disk",
|
||||
Ci.nsICacheStorage.OPEN_NORMALLY,
|
||||
null,
|
||||
function(status, entry) {
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
|
||||
var os = entry.openOutputStream(0, -1);
|
||||
|
|
@ -41,11 +44,11 @@ function write_data()
|
|||
os.close();
|
||||
|
||||
open_big_altdata_output(entry);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function open_big_altdata_output(entry)
|
||||
{
|
||||
function open_big_altdata_output(entry) {
|
||||
try {
|
||||
var os = entry.openAlternativeOutputStream("text/binary", altData.length);
|
||||
} catch (e) {
|
||||
|
|
@ -56,9 +59,13 @@ function open_big_altdata_output(entry)
|
|||
check_entry(write_big_altdata);
|
||||
}
|
||||
|
||||
function write_big_altdata()
|
||||
{
|
||||
asyncOpenCacheEntry("http://data/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null, function (status, entry) {
|
||||
function write_big_altdata() {
|
||||
asyncOpenCacheEntry(
|
||||
"http://data/",
|
||||
"disk",
|
||||
Ci.nsICacheStorage.OPEN_NORMALLY,
|
||||
null,
|
||||
function(status, entry) {
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
|
||||
var os = entry.openAlternativeOutputStream("text/binary", -1);
|
||||
|
|
@ -71,12 +78,17 @@ function write_big_altdata()
|
|||
entry.close();
|
||||
|
||||
check_entry(do_test_finished);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function check_entry(cb)
|
||||
{
|
||||
asyncOpenCacheEntry("http://data/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null, function (status, entry) {
|
||||
function check_entry(cb) {
|
||||
asyncOpenCacheEntry(
|
||||
"http://data/",
|
||||
"disk",
|
||||
Ci.nsICacheStorage.OPEN_NORMALLY,
|
||||
null,
|
||||
function(status, entry) {
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
|
||||
var is = null;
|
||||
|
|
@ -94,5 +106,6 @@ function check_entry(cb)
|
|||
|
||||
executeSoon(cb);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ var httpBarOrigin; // http://bar.example.com:PORT/
|
|||
var httpsBarOrigin; // https://bar.example.com:PORT/
|
||||
|
||||
function run_test() {
|
||||
var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||
var env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
h2Port = env.get("MOZHTTP2_PORT");
|
||||
Assert.notEqual(h2Port, null);
|
||||
Assert.notEqual(h2Port, "");
|
||||
|
|
@ -41,26 +43,38 @@ function run_test() {
|
|||
prefs.setBoolPref("network.http.spdy.enabled.http2", true);
|
||||
prefs.setBoolPref("network.http.altsvc.enabled", true);
|
||||
prefs.setBoolPref("network.http.altsvc.oe", true);
|
||||
prefs.setCharPref("network.dns.localDomains", "foo.example.com, bar.example.com");
|
||||
prefs.setCharPref(
|
||||
"network.dns.localDomains",
|
||||
"foo.example.com, bar.example.com"
|
||||
);
|
||||
|
||||
// The moz-http2 cert is for foo.example.com and is signed by http2-ca.pem
|
||||
// so add that cert to the trust list as a signing cert. The same cert is used
|
||||
// for both h2FooRoute and h2BarRoute though it is only valid for
|
||||
// the foo.example.com domain name.
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
|
||||
h1Foo = new HttpServer();
|
||||
h1Foo.registerPathHandler("/altsvc-test", h1Server);
|
||||
h1Foo.registerPathHandler("/.well-known/http-opportunistic", h1ServerWK);
|
||||
h1Foo.start(-1);
|
||||
h1Foo.identity.setPrimary("http", "foo.example.com", h1Foo.identity.primaryPort);
|
||||
h1Foo.identity.setPrimary(
|
||||
"http",
|
||||
"foo.example.com",
|
||||
h1Foo.identity.primaryPort
|
||||
);
|
||||
|
||||
h1Bar = new HttpServer();
|
||||
h1Bar.registerPathHandler("/altsvc-test", h1Server);
|
||||
h1Bar.start(-1);
|
||||
h1Bar.identity.setPrimary("http", "bar.example.com", h1Bar.identity.primaryPort);
|
||||
h1Bar.identity.setPrimary(
|
||||
"http",
|
||||
"bar.example.com",
|
||||
h1Bar.identity.primaryPort
|
||||
);
|
||||
|
||||
h2FooRoute = "foo.example.com:" + h2Port;
|
||||
h2BarRoute = "bar.example.com:" + h2Port;
|
||||
|
|
@ -70,10 +84,20 @@ function run_test() {
|
|||
httpsFooOrigin = "https://" + h2FooRoute + "/";
|
||||
httpBarOrigin = "http://bar.example.com:" + h1Bar.identity.primaryPort + "/";
|
||||
httpsBarOrigin = "https://" + h2BarRoute + "/";
|
||||
dump ("http foo - " + httpFooOrigin + "\n" +
|
||||
"https foo - " + httpsFooOrigin + "\n" +
|
||||
"http bar - " + httpBarOrigin + "\n" +
|
||||
"https bar - " + httpsBarOrigin + "\n");
|
||||
dump(
|
||||
"http foo - " +
|
||||
httpFooOrigin +
|
||||
"\n" +
|
||||
"https foo - " +
|
||||
httpsFooOrigin +
|
||||
"\n" +
|
||||
"http bar - " +
|
||||
httpBarOrigin +
|
||||
"\n" +
|
||||
"https bar - " +
|
||||
httpsBarOrigin +
|
||||
"\n"
|
||||
);
|
||||
|
||||
doTest1();
|
||||
}
|
||||
|
|
@ -121,7 +145,7 @@ function resetPrefs() {
|
|||
function makeChan(origin) {
|
||||
return NetUtil.newChannel({
|
||||
uri: origin + "altsvc-test",
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +165,9 @@ Listener.prototype = {
|
|||
|
||||
if (expectPass) {
|
||||
if (!Components.isSuccessCode(request.status)) {
|
||||
do_throw("Channel should have a success code! (" + request.status + ")");
|
||||
do_throw(
|
||||
"Channel should have a success code! (" + request.status + ")"
|
||||
);
|
||||
}
|
||||
Assert.equal(request.responseStatus, 200);
|
||||
} else {
|
||||
|
|
@ -182,11 +208,10 @@ Listener.prototype = {
|
|||
}
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function testsDone()
|
||||
{
|
||||
function testsDone() {
|
||||
dump("testDone\n");
|
||||
resetPrefs();
|
||||
do_test_pending();
|
||||
|
|
@ -197,8 +222,7 @@ function testsDone()
|
|||
h1Bar.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
function doTest() {
|
||||
dump("execute doTest " + origin + "\n");
|
||||
var chan = makeChan(origin);
|
||||
var listener = new Listener();
|
||||
|
|
@ -208,7 +232,8 @@ function doTest()
|
|||
if (loadWithoutClearingMappings) {
|
||||
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
} else {
|
||||
chan.loadFlags = Ci.nsIRequest.LOAD_FRESH_CONNECTION |
|
||||
chan.loadFlags =
|
||||
Ci.nsIRequest.LOAD_FRESH_CONNECTION |
|
||||
Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
}
|
||||
loadWithoutClearingMappings = false;
|
||||
|
|
@ -225,8 +250,7 @@ function doTest()
|
|||
// listener is invoked
|
||||
|
||||
// http://foo served from h2=:port
|
||||
function doTest1()
|
||||
{
|
||||
function doTest1() {
|
||||
dump("doTest1()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = h2Route;
|
||||
|
|
@ -237,8 +261,7 @@ function doTest1()
|
|||
}
|
||||
|
||||
// http://foo served from h2=foo:port
|
||||
function doTest2()
|
||||
{
|
||||
function doTest2() {
|
||||
dump("doTest2()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = h2FooRoute;
|
||||
|
|
@ -249,8 +272,7 @@ function doTest2()
|
|||
|
||||
// http://foo served from h2=bar:port
|
||||
// requires cert for foo
|
||||
function doTest3()
|
||||
{
|
||||
function doTest3() {
|
||||
dump("doTest3()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = h2BarRoute;
|
||||
|
|
@ -260,11 +282,10 @@ function doTest3()
|
|||
}
|
||||
|
||||
// https://bar should fail because host bar has cert for foo
|
||||
function doTest4()
|
||||
{
|
||||
function doTest4() {
|
||||
dump("doTest4()\n");
|
||||
origin = httpsBarOrigin;
|
||||
xaltsvc = '';
|
||||
xaltsvc = "";
|
||||
expectPass = false;
|
||||
nextTest = doTest5;
|
||||
do_test_pending();
|
||||
|
|
@ -272,11 +293,10 @@ function doTest4()
|
|||
}
|
||||
|
||||
// https://foo no alt-svc (just check cert setup)
|
||||
function doTest5()
|
||||
{
|
||||
function doTest5() {
|
||||
dump("doTest5()\n");
|
||||
origin = httpsFooOrigin;
|
||||
xaltsvc = 'NA';
|
||||
xaltsvc = "NA";
|
||||
expectPass = true;
|
||||
nextTest = doTest6;
|
||||
do_test_pending();
|
||||
|
|
@ -284,8 +304,7 @@ function doTest5()
|
|||
}
|
||||
|
||||
// https://foo via bar (bar has cert for foo)
|
||||
function doTest6()
|
||||
{
|
||||
function doTest6() {
|
||||
dump("doTest6()\n");
|
||||
origin = httpsFooOrigin;
|
||||
xaltsvc = h2BarRoute;
|
||||
|
|
@ -295,11 +314,10 @@ function doTest6()
|
|||
}
|
||||
|
||||
// check again https://bar should fail because host bar has cert for foo
|
||||
function doTest7()
|
||||
{
|
||||
function doTest7() {
|
||||
dump("doTest7()\n");
|
||||
origin = httpsBarOrigin;
|
||||
xaltsvc = '';
|
||||
xaltsvc = "";
|
||||
expectPass = false;
|
||||
nextTest = doTest8;
|
||||
do_test_pending();
|
||||
|
|
@ -310,8 +328,7 @@ function doTest7()
|
|||
// should not use TLS/h2 because h2BarRoute is not auth'd for bar
|
||||
// however the test ought to PASS (i.e. get a 200) because fallback
|
||||
// to plaintext happens.. thus the timeout
|
||||
function doTest8()
|
||||
{
|
||||
function doTest8() {
|
||||
dump("doTest8()\n");
|
||||
origin = httpBarOrigin;
|
||||
xaltsvc = h2BarRoute;
|
||||
|
|
@ -323,8 +340,7 @@ function doTest8()
|
|||
}
|
||||
|
||||
// http://bar served from h2=:port, which is like the bar route in 8
|
||||
function doTest9()
|
||||
{
|
||||
function doTest9() {
|
||||
dump("doTest9()\n");
|
||||
origin = httpBarOrigin;
|
||||
xaltsvc = h2Route;
|
||||
|
|
@ -337,11 +353,10 @@ function doTest9()
|
|||
}
|
||||
|
||||
// check again https://bar should fail because host bar has cert for foo
|
||||
function doTest10()
|
||||
{
|
||||
function doTest10() {
|
||||
dump("doTest10()\n");
|
||||
origin = httpsBarOrigin;
|
||||
xaltsvc = '';
|
||||
xaltsvc = "";
|
||||
expectPass = false;
|
||||
nextTest = doTest11;
|
||||
do_test_pending();
|
||||
|
|
@ -351,8 +366,7 @@ function doTest10()
|
|||
// http://bar served from h2=foo, should fail because host foo only has
|
||||
// cert for foo. Fail in this case means alt-svc is not used, but content
|
||||
// is served
|
||||
function doTest11()
|
||||
{
|
||||
function doTest11() {
|
||||
dump("doTest11()\n");
|
||||
origin = httpBarOrigin;
|
||||
xaltsvc = h2FooRoute;
|
||||
|
|
@ -365,8 +379,7 @@ function doTest11()
|
|||
|
||||
// Test 12-15:
|
||||
// Insert a cache of http://foo served from h2=:port with origin attributes.
|
||||
function doTest12()
|
||||
{
|
||||
function doTest12() {
|
||||
dump("doTest12()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = h2Route;
|
||||
|
|
@ -381,11 +394,10 @@ function doTest12()
|
|||
}
|
||||
|
||||
// Make sure we get a cache miss with a different userContextId.
|
||||
function doTest13()
|
||||
{
|
||||
function doTest13() {
|
||||
dump("doTest13()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = 'NA';
|
||||
xaltsvc = "NA";
|
||||
originAttributes = {
|
||||
userContextId: 2,
|
||||
firstPartyDomain: "a.com",
|
||||
|
|
@ -397,11 +409,10 @@ function doTest13()
|
|||
}
|
||||
|
||||
// Make sure we get a cache miss with a different firstPartyDomain.
|
||||
function doTest14()
|
||||
{
|
||||
function doTest14() {
|
||||
dump("doTest14()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = 'NA';
|
||||
xaltsvc = "NA";
|
||||
originAttributes = {
|
||||
userContextId: 1,
|
||||
firstPartyDomain: "b.com",
|
||||
|
|
@ -413,11 +424,10 @@ function doTest14()
|
|||
}
|
||||
//
|
||||
// Make sure we get a cache hit with the same origin attributes.
|
||||
function doTest15()
|
||||
{
|
||||
function doTest15() {
|
||||
dump("doTest15()\n");
|
||||
origin = httpFooOrigin;
|
||||
xaltsvc = 'NA';
|
||||
xaltsvc = "NA";
|
||||
originAttributes = {
|
||||
userContextId: 1,
|
||||
firstPartyDomain: "a.com",
|
||||
|
|
@ -431,15 +441,19 @@ function doTest15()
|
|||
}
|
||||
|
||||
// Check we don't connect to blocked ports
|
||||
function doTest16()
|
||||
{
|
||||
function doTest16() {
|
||||
dump("doTest16()\n");
|
||||
origin = httpFooOrigin;
|
||||
nextTest = testsDone;
|
||||
otherServer = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
|
||||
otherServer = Cc["@mozilla.org/network/server-socket;1"].createInstance(
|
||||
Ci.nsIServerSocket
|
||||
);
|
||||
otherServer.init(-1, true, -1);
|
||||
xaltsvc = "localhost:" + otherServer.port;
|
||||
Services.prefs.setCharPref("network.security.ports.banned", "" + otherServer.port);
|
||||
Services.prefs.setCharPref(
|
||||
"network.security.ports.banned",
|
||||
"" + otherServer.port
|
||||
);
|
||||
dump("Blocked port: " + otherServer.port);
|
||||
waitFor = 500;
|
||||
otherServer.asyncListen({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
- test to check we use only a single connection for both onymous and anonymous requests over an existing h2 session
|
||||
- request from a domain w/o LOAD_ANONYMOUS flag
|
||||
|
|
@ -13,7 +12,9 @@ var http2pref;
|
|||
var extpref;
|
||||
|
||||
function run_test() {
|
||||
var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||
var env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
h2Port = env.get("MOZHTTP2_PORT");
|
||||
Assert.notEqual(h2Port, null);
|
||||
Assert.notEqual(h2Port, "");
|
||||
|
|
@ -29,12 +30,16 @@ function run_test() {
|
|||
prefs.setBoolPref("network.http.spdy.enabled", true);
|
||||
prefs.setBoolPref("network.http.spdy.enabled.http2", true);
|
||||
prefs.setBoolPref("network.http.originextension", true);
|
||||
prefs.setCharPref("network.dns.localDomains", "foo.example.com, alt1.example.com");
|
||||
prefs.setCharPref(
|
||||
"network.dns.localDomains",
|
||||
"foo.example.com, alt1.example.com"
|
||||
);
|
||||
|
||||
// The moz-http2 cert is for {foo, alt1, alt2}.example.com and is signed by http2-ca.pem
|
||||
// so add that cert to the trust list as a signing cert.
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
|
||||
doTest1();
|
||||
|
|
@ -50,7 +55,7 @@ function resetPrefs() {
|
|||
function makeChan(origin) {
|
||||
return NetUtil.newChannel({
|
||||
uri: origin,
|
||||
loadUsingSystemPrincipal: true
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
}
|
||||
|
||||
|
|
@ -88,17 +93,15 @@ Listener.prototype = {
|
|||
currentPort = this.clientPort;
|
||||
nextTest();
|
||||
do_test_finished();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function testsDone()
|
||||
{
|
||||
function testsDone() {
|
||||
dump("testsDone\n");
|
||||
resetPrefs();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
function doTest() {
|
||||
dump("execute doTest " + origin + "\n");
|
||||
|
||||
var loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
|
|
@ -118,8 +121,7 @@ function doTest()
|
|||
chan.asyncOpen(listener);
|
||||
}
|
||||
|
||||
function doTest1()
|
||||
{
|
||||
function doTest1() {
|
||||
dump("doTest1()\n");
|
||||
origin = "https://foo.example.com:" + h2Port + "/origin-1";
|
||||
nextTest = doTest2;
|
||||
|
|
@ -128,8 +130,7 @@ function doTest1()
|
|||
doTest();
|
||||
}
|
||||
|
||||
function doTest2()
|
||||
{
|
||||
function doTest2() {
|
||||
// connection expected to be reused for an anonymous request
|
||||
dump("doTest2()\n");
|
||||
origin = "https://foo.example.com:" + h2Port + "/origin-2";
|
||||
|
|
@ -140,8 +141,7 @@ function doTest2()
|
|||
doTest();
|
||||
}
|
||||
|
||||
function doTest3()
|
||||
{
|
||||
function doTest3() {
|
||||
dump("doTest3()\n");
|
||||
origin = "https://foo.example.com:" + h2Port + "/origin-3";
|
||||
nextTest = doTest4;
|
||||
|
|
@ -152,8 +152,7 @@ function doTest3()
|
|||
doTest();
|
||||
}
|
||||
|
||||
function doTest4()
|
||||
{
|
||||
function doTest4() {
|
||||
dump("doTest4()\n");
|
||||
origin = "https://foo.example.com:" + h2Port + "/origin-4";
|
||||
nextTest = testsDone;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue