//
// cleaner HTTP header test infrastructure
//
// tests bugs: 589292, [add more here: see hg log for definitive list]
//
// TO ADD NEW TESTS:
// 1) Increment up 'lastTest' to new number (say, "99")
// 2) Add new test 'handler99' and 'completeTest99' functions.
// 3) If your test should fail the necko channel, set
// test_flags[99] = CL_EXPECT_FAILURE.
//
// TO DEBUG JUST ONE TEST: temporarily change firstTest and lastTest to equal
// the test # you're interested in.
//
// For tests that need duplicate copies of headers to be sent, see
// test_duplicate_headers.js
"use strict";
var firstTest = 1;
// set to test of interest when debugging
var lastTest = 4;
// set to test of interest when debugging
////////////////////////////////////////////////////////////////////////////////
// Note: sets Cc and Ci variables
const { HttpServer } = ChromeUtils.importESModule(
"resource://testing-common/httpd.sys.mjs"
);
ChromeUtils.defineLazyGetter(
this,
"URL",
function () {
return "http://localhost:" + httpserver.identity.primaryPort;
});
var httpserver =
new HttpServer();
var nextTest = firstTest;
var test_flags = [];
var testPathBase =
"/test_headers";
function run_test() {
httpserver.start(-1);
do_test_pending();
run_test_number(nextTest);
}
function runNextTest() {
if (nextTest == lastTest) {
endTests();
return;
}
nextTest++;
// Make sure test functions exist
if (globalThis[
"handler" + nextTest] == undefined) {
do_throw(
"handler" + nextTest +
" undefined!");
}
if (globalThis[
"completeTest" + nextTest] == undefined) {
do_throw(
"completeTest" + nextTest +
" undefined!");
}
run_test_number(nextTest);
}
function run_test_number(num) {
let testPath = testPathBase + num;
httpserver.registerPathHandler(testPath, globalThis[
"handler" + num]);
var channel = setupChannel(testPath);
let flags = test_flags[num];
// OK if flags undefined for test
channel.asyncOpen(
new ChannelListener(globalThis[
"completeTest" + num], channel, flags)
);
}
function setupChannel(url) {
var chan = NetUtil.newChannel({
uri: URL + url,
loadUsingSystemPrincipal:
true,
});
var httpChan = chan.QueryInterface(Ci.nsIHttpChannel);
return httpChan;
}
function endTests() {
httpserver.stop(do_test_finished);
}
////////////////////////////////////////////////////////////////////////////////
// Test 1: test Content-Disposition channel attributes
// eslint-disable-next-line no-unused-vars
function handler1(metadata, response) {
response.setStatusLine(metadata.httpVersion, 200,
"OK");
response.setHeader(
"Content-Disposition",
"attachment; filename=foo");
response.setHeader(
"Content-Type",
"text/plain",
false);
}
// eslint-disable-next-line no-unused-vars
function completeTest1(request) {
try {
var chan = request.QueryInterface(Ci.nsIChannel);
Assert.equal(chan.contentDisposition, chan.DISPOSITION_ATTACHMENT);
Assert.equal(chan.contentDispositionFilename,
"foo");
Assert.equal(chan.contentDispositionHeader,
"attachment; filename=foo");
}
catch (ex) {
do_throw(
"error parsing Content-Disposition: " + ex);
}
runNextTest();
}
////////////////////////////////////////////////////////////////////////////////
// Test 2: no filename
// eslint-disable-next-line no-unused-vars
function handler2(metadata, response) {
response.setStatusLine(metadata.httpVersion, 200,
"OK");
response.setHeader(
"Content-Type",
"text/plain",
false);
response.setHeader(
"Content-Disposition",
"attachment");
var body =
"foo";
response.bodyOutputStream.write(body, body.length);
}
// eslint-disable-next-line no-unused-vars
function completeTest2(request) {
try {
var chan = request.QueryInterface(Ci.nsIChannel);
Assert.equal(chan.contentDisposition, chan.DISPOSITION_ATTACHMENT);
Assert.equal(chan.contentDispositionHeader,
"attachment");
chan.contentDispositionFilename;
// should barf
do_throw(
"Should have failed getting Content-Disposition filename");
}
catch (ex) {
info(
"correctly ate exception");
}
runNextTest();
}
////////////////////////////////////////////////////////////////////////////////
// Test 3: filename missing
// eslint-disable-next-line no-unused-vars
function handler3(metadata, response) {
response.setStatusLine(metadata.httpVersion, 200,
"OK");
response.setHeader(
"Content-Type",
"text/plain",
false);
response.setHeader(
"Content-Disposition",
"attachment; filename=");
var body =
"foo";
response.bodyOutputStream.write(body, body.length);
}
// eslint-disable-next-line no-unused-vars
function completeTest3(request) {
try {
var chan = request.QueryInterface(Ci.nsIChannel);
Assert.equal(chan.contentDisposition, chan.DISPOSITION_ATTACHMENT);
Assert.equal(chan.contentDispositionHeader,
"attachment; filename=");
chan.contentDispositionFilename;
// should barf
do_throw(
"Should have failed getting Content-Disposition filename");
}
catch (ex) {
info(
"correctly ate exception");
}
runNextTest();
}
////////////////////////////////////////////////////////////////////////////////
// Test 4: inline
// eslint-disable-next-line no-unused-vars
function handler4(metadata, response) {
response.setStatusLine(metadata.httpVersion, 200,
"OK");
response.setHeader(
"Content-Type",
"text/plain",
false);
response.setHeader(
"Content-Disposition",
"inline");
var body =
"foo";
response.bodyOutputStream.write(body, body.length);
}
// eslint-disable-next-line no-unused-vars
function completeTest4(request) {
try {
var chan = request.QueryInterface(Ci.nsIChannel);
Assert.equal(chan.contentDisposition, chan.DISPOSITION_INLINE);
Assert.equal(chan.contentDispositionHeader,
"inline");
chan.contentDispositionFilename;
// should barf
do_throw(
"Should have failed getting Content-Disposition filename");
}
catch (ex) {
info(
"correctly ate exception");
}
runNextTest();
}