summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_plaintext_sniff.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--netwerk/test/unit/test_plaintext_sniff.js209
1 files changed, 209 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_plaintext_sniff.js b/netwerk/test/unit/test_plaintext_sniff.js
new file mode 100644
index 0000000000..fb9620e04c
--- /dev/null
+++ b/netwerk/test/unit/test_plaintext_sniff.js
@@ -0,0 +1,209 @@
+// Test the plaintext-or-binary sniffer
+
+"use strict";
+
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+
+// List of Content-Type headers to test. For each header we have an array.
+// The first element in the array is the Content-Type header string. The
+// second element in the array is a boolean indicating whether we allow
+// sniffing for that type.
+var contentTypeHeaderList = [
+ ["text/plain", true],
+ ["text/plain; charset=ISO-8859-1", true],
+ ["text/plain; charset=iso-8859-1", true],
+ ["text/plain; charset=UTF-8", true],
+ ["text/plain; charset=unknown", false],
+ ["text/plain; param", false],
+ ["text/plain; charset=ISO-8859-1; param", false],
+ ["text/plain; charset=iso-8859-1; param", false],
+ ["text/plain; charset=UTF-8; param", false],
+ ["text/plain; charset=utf-8", false],
+ ["text/plain; charset=utf8", false],
+ ["text/plain; charset=UTF8", false],
+ ["text/plain; charset=iSo-8859-1", false],
+];
+
+// List of response bodies to test. For each response we have an array. The
+// first element in the array is the body string. The second element in the
+// array is a boolean indicating whether that string should sniff as binary.
+var bodyList = [["Plaintext", false]];
+
+// List of possible BOMs
+var BOMList = [
+ "\xFE\xFF", // UTF-16BE
+ "\xFF\xFE", // UTF-16LE
+ "\xEF\xBB\xBF", // UTF-8
+ "\x00\x00\xFE\xFF", // UCS-4BE
+ "\x00\x00\xFF\xFE", // UCS-4LE
+];
+
+// Build up bodyList. The things we treat as binary are ASCII codes 0-8,
+// 14-26, 28-31. That is, the control char range, except for tab, newline,
+// vertical tab, form feed, carriage return, and ESC (this last being used by
+// Shift_JIS, apparently).
+function isBinaryChar(ch) {
+ return (
+ (0 <= ch && ch <= 8) || (14 <= ch && ch <= 26) || (28 <= ch && ch <= 31)
+ );
+}
+
+// Test chars on their own
+var i;
+for (i = 0; i <= 127; ++i) {
+ bodyList.push([String.fromCharCode(i), isBinaryChar(i)]);
+}
+
+// Test that having a BOM prevents plaintext sniffing
+var j;
+for (i = 0; i <= 127; ++i) {
+ for (j = 0; j < BOMList.length; ++j) {
+ bodyList.push([BOMList[j] + String.fromCharCode(i, i), false]);
+ }
+}
+
+// Test that having a BOM requires at least 4 chars to kick in
+for (i = 0; i <= 127; ++i) {
+ for (j = 0; j < BOMList.length; ++j) {
+ bodyList.push([
+ BOMList[j] + String.fromCharCode(i),
+ BOMList[j].length == 2 && isBinaryChar(i),
+ ]);
+ }
+}
+
+function makeChan(headerIdx, bodyIdx) {
+ var chan = NetUtil.newChannel({
+ uri:
+ "http://localhost:" +
+ httpserv.identity.primaryPort +
+ "/" +
+ headerIdx +
+ "/" +
+ bodyIdx,
+ loadUsingSystemPrincipal: true,
+ }).QueryInterface(Ci.nsIHttpChannel);
+
+ chan.loadFlags |= Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
+
+ return chan;
+}
+
+function makeListener(headerIdx, bodyIdx) {
+ var listener = {
+ onStartRequest: function test_onStartR(request) {
+ try {
+ var chan = request.QueryInterface(Ci.nsIChannel);
+
+ Assert.equal(chan.status, Cr.NS_OK);
+
+ var type = chan.contentType;
+
+ var expectedType =
+ contentTypeHeaderList[headerIdx][1] && bodyList[bodyIdx][1]
+ ? "application/x-vnd.mozilla.guess-from-ext"
+ : "text/plain";
+ if (expectedType != type) {
+ do_throw(
+ "Unexpected sniffed type '" +
+ type +
+ "'. " +
+ "Should be '" +
+ expectedType +
+ "'. " +
+ "Header is ['" +
+ contentTypeHeaderList[headerIdx][0] +
+ "', " +
+ contentTypeHeaderList[headerIdx][1] +
+ "]. " +
+ "Body is ['" +
+ bodyList[bodyIdx][0].toSource() +
+ "', " +
+ bodyList[bodyIdx][1] +
+ "]."
+ );
+ }
+ Assert.equal(expectedType, type);
+ } catch (e) {
+ do_throw("Unexpected exception: " + e);
+ }
+
+ throw Components.Exception("", Cr.NS_ERROR_ABORT);
+ },
+
+ onDataAvailable: function test_ODA() {
+ do_throw("Should not get any data!");
+ },
+
+ onStopRequest: function test_onStopR(request, status) {
+ // Advance to next test
+ ++headerIdx;
+ if (headerIdx == contentTypeHeaderList.length) {
+ headerIdx = 0;
+ ++bodyIdx;
+ }
+
+ if (bodyIdx == bodyList.length) {
+ do_test_pending();
+ httpserv.stop(do_test_finished);
+ } else {
+ doTest(headerIdx, bodyIdx);
+ }
+
+ do_test_finished();
+ },
+ };
+
+ return listener;
+}
+
+function doTest(headerIdx, bodyIdx) {
+ var chan = makeChan(headerIdx, bodyIdx);
+
+ var listener = makeListener(headerIdx, bodyIdx);
+
+ chan.asyncOpen(listener);
+
+ do_test_pending();
+}
+
+function createResponse(headerIdx, bodyIdx, metadata, response) {
+ response.setHeader(
+ "Content-Type",
+ contentTypeHeaderList[headerIdx][0],
+ false
+ );
+ response.bodyOutputStream.write(
+ bodyList[bodyIdx][0],
+ bodyList[bodyIdx][0].length
+ );
+}
+
+function makeHandler(headerIdx, bodyIdx) {
+ var f = function handlerClosure(metadata, response) {
+ return createResponse(headerIdx, bodyIdx, metadata, response);
+ };
+ return f;
+}
+
+var httpserv;
+function run_test() {
+ // disable on Windows for now, because it seems to leak sockets and die.
+ // Silly operating system!
+ // This is a really nasty way to detect Windows. I wish we could do better.
+ if (mozinfo.os == "win") {
+ //failing eslint no-empty test
+ }
+
+ httpserv = new HttpServer();
+
+ for (i = 0; i < contentTypeHeaderList.length; ++i) {
+ for (j = 0; j < bodyList.length; ++j) {
+ httpserv.registerPathHandler("/" + i + "/" + j, makeHandler(i, j));
+ }
+ }
+
+ httpserv.start(-1);
+
+ doTest(0, 0);
+}