netwerk/test/unit/test_plaintext_sniff.js

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

michael@0 1 // Test the plaintext-or-binary sniffer
michael@0 2
michael@0 3 Cu.import("resource://testing-common/httpd.js");
michael@0 4
michael@0 5 // List of Content-Type headers to test. For each header we have an array.
michael@0 6 // The first element in the array is the Content-Type header string. The
michael@0 7 // second element in the array is a boolean indicating whether we allow
michael@0 8 // sniffing for that type.
michael@0 9 var contentTypeHeaderList =
michael@0 10 [
michael@0 11 [ "text/plain", true ],
michael@0 12 [ "text/plain; charset=ISO-8859-1", true ],
michael@0 13 [ "text/plain; charset=iso-8859-1", true ],
michael@0 14 [ "text/plain; charset=UTF-8", true ],
michael@0 15 [ "text/plain; charset=unknown", false ],
michael@0 16 [ "text/plain; param", false ],
michael@0 17 [ "text/plain; charset=ISO-8859-1; param", false ],
michael@0 18 [ "text/plain; charset=iso-8859-1; param", false ],
michael@0 19 [ "text/plain; charset=UTF-8; param", false ],
michael@0 20 [ "text/plain; charset=utf-8", false ],
michael@0 21 [ "text/plain; charset=utf8", false ],
michael@0 22 [ "text/plain; charset=UTF8", false ],
michael@0 23 [ "text/plain; charset=iSo-8859-1", false ]
michael@0 24 ];
michael@0 25
michael@0 26 // List of response bodies to test. For each response we have an array. The
michael@0 27 // first element in the array is the body string. The second element in the
michael@0 28 // array is a boolean indicating whether that string should sniff as binary.
michael@0 29 var bodyList =
michael@0 30 [
michael@0 31 [ "Plaintext", false ]
michael@0 32 ];
michael@0 33
michael@0 34 // List of possible BOMs
michael@0 35 var BOMList =
michael@0 36 [
michael@0 37 "\xFE\xFF", // UTF-16BE
michael@0 38 "\xFF\xFE", // UTF-16LE
michael@0 39 "\xEF\xBB\xBF", // UTF-8
michael@0 40 "\x00\x00\xFE\xFF", // UCS-4BE
michael@0 41 "\x00\x00\xFF\xFE" // UCS-4LE
michael@0 42 ];
michael@0 43
michael@0 44 // Build up bodyList. The things we treat as binary are ASCII codes 0-8,
michael@0 45 // 14-26, 28-31. That is, the control char range, except for tab, newline,
michael@0 46 // vertical tab, form feed, carriage return, and ESC (this last being used by
michael@0 47 // Shift_JIS, apparently).
michael@0 48 function isBinaryChar(ch) {
michael@0 49 return (0 <= ch && ch <= 8) || (14 <= ch && ch <= 26) ||
michael@0 50 (28 <= ch && ch <= 31);
michael@0 51 }
michael@0 52
michael@0 53 // Test chars on their own
michael@0 54 var i;
michael@0 55 for (i = 0; i <= 127; ++i) {
michael@0 56 bodyList.push([ String.fromCharCode(i), isBinaryChar(i) ]);
michael@0 57 }
michael@0 58
michael@0 59 // Test that having a BOM prevents plaintext sniffing
michael@0 60 var j;
michael@0 61 for (i = 0; i <= 127; ++i) {
michael@0 62 for (j = 0; j < BOMList.length; ++j) {
michael@0 63 bodyList.push([ BOMList[j] + String.fromCharCode(i, i), false ]);
michael@0 64 }
michael@0 65 }
michael@0 66
michael@0 67 // Test that having a BOM requires at least 4 chars to kick in
michael@0 68 for (i = 0; i <= 127; ++i) {
michael@0 69 for (j = 0; j < BOMList.length; ++j) {
michael@0 70 bodyList.push([ BOMList[j] + String.fromCharCode(i),
michael@0 71 BOMList[j].length == 2 && isBinaryChar(i) ]);
michael@0 72 }
michael@0 73 }
michael@0 74
michael@0 75 function makeChan(headerIdx, bodyIdx) {
michael@0 76 var ios = Components.classes["@mozilla.org/network/io-service;1"]
michael@0 77 .getService(Components.interfaces.nsIIOService);
michael@0 78 var chan =
michael@0 79 ios.newChannel("http://localhost:" + httpserv.identity.primaryPort +
michael@0 80 "/" + headerIdx + "/" + bodyIdx, null, null)
michael@0 81 .QueryInterface(Components.interfaces.nsIHttpChannel);
michael@0 82
michael@0 83 chan.loadFlags |=
michael@0 84 Components.interfaces.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
michael@0 85
michael@0 86 return chan;
michael@0 87 }
michael@0 88
michael@0 89 function makeListener(headerIdx, bodyIdx) {
michael@0 90 var listener = {
michael@0 91 onStartRequest : function test_onStartR(request, ctx) {
michael@0 92 try {
michael@0 93 var chan = request.QueryInterface(Components.interfaces.nsIChannel);
michael@0 94
michael@0 95 do_check_eq(chan.status, Components.results.NS_OK);
michael@0 96
michael@0 97 var type = chan.contentType;
michael@0 98
michael@0 99 var expectedType =
michael@0 100 contentTypeHeaderList[headerIdx][1] && bodyList[bodyIdx][1] ?
michael@0 101 "application/x-vnd.mozilla.guess-from-ext" : "text/plain";
michael@0 102 if (expectedType != type) {
michael@0 103 do_throw("Unexpected sniffed type '" + type + "'. " +
michael@0 104 "Should be '" + expectedType + "'. " +
michael@0 105 "Header is ['" +
michael@0 106 contentTypeHeaderList[headerIdx][0] + "', " +
michael@0 107 contentTypeHeaderList[headerIdx][1] + "]. " +
michael@0 108 "Body is ['" +
michael@0 109 bodyList[bodyIdx][0].toSource() + "', " +
michael@0 110 bodyList[bodyIdx][1] +
michael@0 111 "].");
michael@0 112 }
michael@0 113 do_check_eq(expectedType, type);
michael@0 114 } catch (e) {
michael@0 115 do_throw("Unexpected exception: " + e);
michael@0 116 }
michael@0 117
michael@0 118 throw Components.results.NS_ERROR_ABORT;
michael@0 119 },
michael@0 120
michael@0 121 onDataAvailable: function test_ODA() {
michael@0 122 do_throw("Should not get any data!");
michael@0 123 },
michael@0 124
michael@0 125 onStopRequest: function test_onStopR(request, ctx, status) {
michael@0 126 // Advance to next test
michael@0 127 ++headerIdx;
michael@0 128 if (headerIdx == contentTypeHeaderList.length) {
michael@0 129 headerIdx = 0;
michael@0 130 ++bodyIdx;
michael@0 131 }
michael@0 132
michael@0 133 if (bodyIdx == bodyList.length) {
michael@0 134 do_test_pending();
michael@0 135 httpserv.stop(do_test_finished);
michael@0 136 } else {
michael@0 137 doTest(headerIdx, bodyIdx);
michael@0 138 }
michael@0 139
michael@0 140 do_test_finished();
michael@0 141 }
michael@0 142 };
michael@0 143
michael@0 144 return listener;
michael@0 145 }
michael@0 146
michael@0 147 function doTest(headerIdx, bodyIdx) {
michael@0 148 var chan = makeChan(headerIdx, bodyIdx);
michael@0 149
michael@0 150 var listener = makeListener(headerIdx, bodyIdx);
michael@0 151
michael@0 152 chan.asyncOpen(listener, null);
michael@0 153
michael@0 154 do_test_pending();
michael@0 155 }
michael@0 156
michael@0 157 function createResponse(headerIdx, bodyIdx, metadata, response) {
michael@0 158 response.setHeader("Content-Type", contentTypeHeaderList[headerIdx][0], false);
michael@0 159 response.bodyOutputStream.write(bodyList[bodyIdx][0],
michael@0 160 bodyList[bodyIdx][0].length);
michael@0 161 }
michael@0 162
michael@0 163 function makeHandler(headerIdx, bodyIdx) {
michael@0 164 var f =
michael@0 165 function handlerClosure(metadata, response) {
michael@0 166 return createResponse(headerIdx, bodyIdx, metadata, response);
michael@0 167 };
michael@0 168 return f;
michael@0 169 }
michael@0 170
michael@0 171 var httpserv;
michael@0 172 function run_test() {
michael@0 173 // disable again for everything for now (causes sporatic oranges)
michael@0 174 return;
michael@0 175
michael@0 176 // disable on Windows for now, because it seems to leak sockets and die.
michael@0 177 // Silly operating system!
michael@0 178 // This is a really nasty way to detect Windows. I wish we could do better.
michael@0 179 if ("@mozilla.org/windows-registry-key;1" in Cc) {
michael@0 180 return;
michael@0 181 }
michael@0 182
michael@0 183 httpserv = new HttpServer();
michael@0 184
michael@0 185 for (i = 0; i < contentTypeHeaderList.length; ++i) {
michael@0 186 for (j = 0; j < bodyList.length; ++j) {
michael@0 187 httpserv.registerPathHandler("/" + i + "/" + j, makeHandler(i, j));
michael@0 188 }
michael@0 189 }
michael@0 190
michael@0 191 httpserv.start(-1);
michael@0 192
michael@0 193 doTest(0, 0);
michael@0 194 }

mercurial