// // 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(); }