1 // Test the plaintext-or-binary sniffer
3 do_import_script("netwerk/test/httpserver/httpd.js");
5 // List of Content-Type headers to test. For each header we have an array.
6 // The first element in the array is the Content-Type header string. The
7 // second element in the array is a boolean indicating whether we allow
8 // sniffing for that type.
9 var contentTypeHeaderList =
11 [ "text/plain", true ],
12 [ "text/plain; charset=ISO-8859-1", true ],
13 [ "text/plain; charset=iso-8859-1", true ],
14 [ "text/plain; charset=UTF-8", true ],
15 [ "text/plain; charset=unknown", false ],
16 [ "text/plain; param", false ],
17 [ "text/plain; charset=ISO-8859-1; param", false ],
18 [ "text/plain; charset=iso-8859-1; param", false ],
19 [ "text/plain; charset=UTF-8; param", false ],
20 [ "text/plain; charset=utf-8", false ],
21 [ "text/plain; charset=utf8", false ],
22 [ "text/plain; charset=UTF8", false ],
23 [ "text/plain; charset=iSo-8859-1", false ]
26 // List of response bodies to test. For each response we have an array. The
27 // first element in the array is the body string. The second element in the
28 // array is a boolean indicating whether that string should sniff as binary.
31 [ "Plaintext", false ]
34 // List of possible BOMs
37 "\xFE\xFF", // UTF-16BE
38 "\xFF\xFE", // UTF-16LE
39 "\xEF\xBB\xBF", // UTF-8
40 "\x00\x00\xFE\xFF", // UCS-4BE
41 "\x00\x00\xFF\xFE" // UCS-4LE
44 // Build up bodyList. The things we treat as binary are ASCII codes 0-8,
45 // 14-26, 28-31. That is, the control char range, except for tab, newline,
46 // vertical tab, form feed, carriage return, and ESC (this last being used by
47 // Shift_JIS, apparently).
48 function isBinaryChar(ch) {
49 return (0 <= ch && ch <= 8) || (14 <= ch && ch <= 26) ||
50 (28 <= ch && ch <= 31);
53 // Test chars on their own
55 for (i = 0; i <= 127; ++i) {
56 bodyList.push([ String.fromCharCode(i), isBinaryChar(i) ]);
59 // Test that having a BOM prevents plaintext sniffing
61 for (i = 0; i <= 127; ++i) {
62 for (j = 0; j < BOMList.length; ++j) {
63 bodyList.push([ BOMList[j] + String.fromCharCode(i, i), false ]);
67 // Test that having a BOM requires at least 4 chars to kick in
68 for (i = 0; i <= 127; ++i) {
69 for (j = 0; j < BOMList.length; ++j) {
70 bodyList.push([ BOMList[j] + String.fromCharCode(i),
71 BOMList[j].length == 2 && isBinaryChar(i) ]);
75 function makeChan(headerIdx, bodyIdx) {
76 var ios = Components.classes["@mozilla.org/network/io-service;1"]
77 .getService(Components.interfaces.nsIIOService);
79 ios.newChannel("http://localhost:4444/" + headerIdx + "/" + bodyIdx, null,
81 .QueryInterface(Components.interfaces.nsIHttpChannel);
84 Components.interfaces.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
89 function makeListener(headerIdx, bodyIdx) {
91 onStartRequest : function test_onStartR(request, ctx) {
93 var chan = request.QueryInterface(Components.interfaces.nsIChannel);
95 do_check_eq(chan.status, Components.results.NS_OK);
97 var type = chan.contentType;
100 contentTypeHeaderList[headerIdx][1] && bodyList[bodyIdx][1] ?
101 "application/x-vnd.mozilla.guess-from-ext" : "text/plain";
102 if (expectedType != type) {
103 do_throw("Unexpected sniffed type '" + type + "'. " +
104 "Should be '" + expectedType + "'. " +
106 contentTypeHeaderList[headerIdx][0] + "', " +
107 contentTypeHeaderList[headerIdx][1] + "]. " +
109 bodyList[bodyIdx][0].toSource() + "', " +
110 bodyList[bodyIdx][1] +
113 do_check_eq(expectedType, type);
115 do_throw("Unexpected exception: " + e);
118 throw Components.results.NS_ERROR_ABORT;
121 onDataAvailable: function test_ODA() {
122 do_throw("Should not get any data!");
125 onStopRequest: function test_onStopR(request, ctx, status) {
126 // Advance to next test
128 if (headerIdx == contentTypeHeaderList.length) {
133 if (bodyIdx == bodyList.length) {
136 doTest(headerIdx, bodyIdx);
146 function doTest(headerIdx, bodyIdx) {
147 var chan = makeChan(headerIdx, bodyIdx);
149 var listener = makeListener(headerIdx, bodyIdx);
151 chan.asyncOpen(listener, null);
156 function createResponse(headerIdx, bodyIdx, metadata, response) {
157 response.setHeader("Content-Type", contentTypeHeaderList[headerIdx][0], false);
158 response.bodyOutputStream.write(bodyList[bodyIdx][0],
159 bodyList[bodyIdx][0].length);
162 function makeHandler(headerIdx, bodyIdx) {
164 function handlerClosure(metadata, response) {
165 return createResponse(headerIdx, bodyIdx, metadata, response);
171 function run_test() {
172 // disable again for everything for now (causes sporatic oranges)
175 // disable on Windows for now, because it seems to leak sockets and die.
176 // Silly operating system!
177 // This is a really nasty way to detect Windows. I wish we could do better.
178 if ("@mozilla.org/windows-registry-key;1" in Cc) {
182 httpserv = new nsHttpServer();
184 for (i = 0; i < contentTypeHeaderList.length; ++i) {
185 for (j = 0; j < bodyList.length; ++j) {
186 httpserv.registerPathHandler("/" + i + "/" + j, makeHandler(i, j));
190 httpserv.start(4444);