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);