// This testcase verifies that channels can't be reopened
// See https://bugzilla.mozilla.org/show_bug.cgi?id=372486
"use strict";
const { HttpServer } = ChromeUtils.importESModule(
"resource://testing-common/httpd.sys.mjs"
);
const BinaryInputStream = Components.Constructor(
"@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream"
);
const NS_ERROR_IN_PROGRESS = 0x804b000f;
const NS_ERROR_ALREADY_OPENED = 0x804b0049;
var chan =
null;
var httpserv =
null;
[test_data_channel, test_http_channel, test_file_channel, end].forEach(f =>
add_test(f)
);
// Utility functions
function makeChan(url) {
return (chan = NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal:
true,
}).QueryInterface(Ci.nsIChannel));
}
function new_file_channel(file) {
return NetUtil.newChannel({
uri: Services.io.newFileURI(file),
loadUsingSystemPrincipal:
true,
});
}
function check_throws(closure, error) {
var thrown =
false;
try {
closure();
}
catch (e) {
if (error
instanceof Array) {
Assert.notEqual(error.indexOf(e.result), -1);
}
else {
Assert.equal(e.result, error);
}
thrown =
true;
}
Assert.ok(thrown);
}
function check_open_throws(error) {
check_throws(
function () {
chan.open(listener);
}, error);
}
function check_async_open_throws(error) {
check_throws(
function () {
chan.asyncOpen(listener);
}, error);
}
var listener = {
onStartRequest:
function test_onStartR() {
check_async_open_throws(NS_ERROR_IN_PROGRESS);
},
onDataAvailable:
function test_ODA(request, inputStream, offset, count) {
new BinaryInputStream(inputStream).readByteArray(count);
// required by API
check_async_open_throws(NS_ERROR_IN_PROGRESS);
},
onStopRequest:
function test_onStopR() {
// Once onStopRequest is reached, the channel is marked as having been
// opened
check_async_open_throws(NS_ERROR_ALREADY_OPENED);
do_timeout(0, after_channel_closed);
},
};
function after_channel_closed() {
check_async_open_throws(NS_ERROR_ALREADY_OPENED);
run_next_test();
}
function test_channel(createChanClosure) {
// First, synchronous reopening test
chan = createChanClosure();
chan.open();
check_open_throws(NS_ERROR_IN_PROGRESS);
check_async_open_throws([NS_ERROR_IN_PROGRESS, NS_ERROR_ALREADY_OPENED]);
// Then, asynchronous one
chan = createChanClosure();
chan.asyncOpen(listener);
check_open_throws(NS_ERROR_IN_PROGRESS);
check_async_open_throws(NS_ERROR_IN_PROGRESS);
}
function test_data_channel() {
test_channel(
function () {
return makeChan(
"data:text/plain,foo");
});
}
function test_http_channel() {
test_channel(
function () {
return makeChan(
"http://localhost:" + httpserv.identity.primaryPort + "/");
});
}
function test_file_channel() {
var file = do_get_file(
"data/test_readline1.txt");
test_channel(
function () {
return new_file_channel(file);
});
}
function end() {
httpserv.stop(do_test_finished);
}
function run_test() {
// start server
httpserv =
new HttpServer();
httpserv.start(-1);
run_next_test();
}