summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_plaintext_sniff.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/test_plaintext_sniff.js')
-rw-r--r--netwerk/test/unit/test_plaintext_sniff.js194
1 files changed, 194 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 000000000..9955a86b9
--- /dev/null
+++ b/netwerk/test/unit/test_plaintext_sniff.js
@@ -0,0 +1,194 @@
+// Test the plaintext-or-binary sniffer
+
+Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+// 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(Components.interfaces.nsIHttpChannel);
+
+ chan.loadFlags |=
+ Components.interfaces.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
+
+ return chan;
+}
+
+function makeListener(headerIdx, bodyIdx) {
+ var listener = {
+ onStartRequest : function test_onStartR(request, ctx) {
+ try {
+ var chan = request.QueryInterface(Components.interfaces.nsIChannel);
+
+ do_check_eq(chan.status, Components.results.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] +
+ "].");
+ }
+ do_check_eq(expectedType, type);
+ } catch (e) {
+ do_throw("Unexpected exception: " + e);
+ }
+
+ throw Components.results.NS_ERROR_ABORT;
+ },
+
+ onDataAvailable: function test_ODA() {
+ do_throw("Should not get any data!");
+ },
+
+ onStopRequest: function test_onStopR(request, ctx, 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.asyncOpen2(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 again for everything for now (causes sporatic oranges)
+ return;
+
+ // 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") {
+ return;
+ }
+
+ 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);
+}