2 * Test Content-Length underrun behavior
5 ////////////////////////////////////////////////////////////////////////////////
10 const { HttpServer
} = ChromeUtils
.importESModule(
11 "resource://testing-common/httpd.sys.mjs"
14 ChromeUtils
.defineLazyGetter(this, "URL", function () {
15 return "http://localhost:" + httpserver
.identity
.primaryPort
;
18 var httpserver
= new HttpServer();
20 var testPathBase
= "/cl_hdrs";
23 var enforcePrefStrict
;
25 var enforcePrefStrictChunked
;
27 Services
.prefs
.setBoolPref("security.allow_eval_with_system_principal", true);
28 registerCleanupFunction(() => {
29 Services
.prefs
.clearUserPref("security.allow_eval_with_system_principal");
33 prefs
= Services
.prefs
;
34 enforcePrefStrict
= prefs
.getBoolPref("network.http.enforce-framing.http1");
35 enforcePrefSoft
= prefs
.getBoolPref("network.http.enforce-framing.soft");
36 enforcePrefStrictChunked
= prefs
.getBoolPref(
37 "network.http.enforce-framing.strict_chunked_encoding"
40 prefs
.setBoolPref("network.http.enforce-framing.http1", true);
48 function run_test_number(num
) {
49 let testPath
= testPathBase
+ num
;
50 // eslint-disable-next-line no-eval
51 httpserver
.registerPathHandler(testPath
, eval("handler" + num
));
53 var channel
= setupChannel(testPath
);
54 let flags
= test_flags
[num
]; // OK if flags undefined for test
56 // eslint-disable-next-line no-eval
57 new ChannelListener(eval("completeTest" + num
), channel
, flags
)
61 function run_gzip_test(num
) {
62 let testPath
= testPathBase
+ num
;
63 // eslint-disable-next-line no-eval
64 httpserver
.registerPathHandler(testPath
, eval("handler" + num
));
66 var channel
= setupChannel(testPath
);
68 function StreamListener() {}
70 StreamListener
.prototype = {
71 QueryInterface
: ChromeUtils
.generateQI([
78 onStopRequest(aRequest
, aStatusCode
) {
79 // Make sure we catch the error NS_ERROR_NET_PARTIAL_TRANSFER here.
80 Assert
.equal(aStatusCode
, Cr
.NS_ERROR_NET_PARTIAL_TRANSFER
);
81 // do_test_finished();
88 let listener
= new StreamListener();
90 channel
.asyncOpen(listener
);
93 function setupChannel(url
) {
94 var chan
= NetUtil
.newChannel({
96 loadUsingSystemPrincipal
: true,
98 var httpChan
= chan
.QueryInterface(Ci
.nsIHttpChannel
);
102 function endTests() {
103 // restore the prefs to pre-test values
104 prefs
.setBoolPref("network.http.enforce-framing.http1", enforcePrefStrict
);
105 prefs
.setBoolPref("network.http.enforce-framing.soft", enforcePrefSoft
);
107 "network.http.enforce-framing.strict_chunked_encoding",
108 enforcePrefStrictChunked
110 httpserver
.stop(do_test_finished
);
113 ////////////////////////////////////////////////////////////////////////////////
114 // Test 1: FAIL because of Content-Length underrun with HTTP 1.1
115 test_flags
[1] = CL_EXPECT_LATE_FAILURE
;
117 // eslint-disable-next-line no-unused-vars
118 function handler1(metadata
, response
) {
119 var body
= "blablabla";
121 response
.seizePower();
122 response
.write("HTTP/1.1 200 OK\r\n");
123 response
.write("Content-Type: text/plain\r\n");
124 response
.write("Content-Length: 556677\r\n");
125 response
.write("\r\n");
126 response
.write(body
);
130 // eslint-disable-next-line no-unused-vars
131 function completeTest1(request
) {
132 Assert
.equal(request
.status
, Cr
.NS_ERROR_NET_PARTIAL_TRANSFER
);
137 ////////////////////////////////////////////////////////////////////////////////
138 // Test 11: PASS because of Content-Length underrun with HTTP 1.1 but non 2xx
139 test_flags
[11] = CL_IGNORE_CL
;
141 // eslint-disable-next-line no-unused-vars
142 function handler11(metadata
, response
) {
143 var body
= "blablabla";
145 response
.seizePower();
146 response
.write("HTTP/1.1 404 NotOK\r\n");
147 response
.write("Content-Type: text/plain\r\n");
148 response
.write("Content-Length: 556677\r\n");
149 response
.write("\r\n");
150 response
.write(body
);
154 // eslint-disable-next-line no-unused-vars
155 function completeTest11(request
) {
156 Assert
.equal(request
.status
, Cr
.NS_OK
);
160 ////////////////////////////////////////////////////////////////////////////////
161 // Test 2: Succeed because Content-Length underrun is with HTTP 1.0
163 test_flags
[2] = CL_IGNORE_CL
;
165 // eslint-disable-next-line no-unused-vars
166 function handler2(metadata
, response
) {
167 var body
= "short content";
169 response
.seizePower();
170 response
.write("HTTP/1.0 200 OK\r\n");
171 response
.write("Content-Type: text/plain\r\n");
172 response
.write("Content-Length: 12345678\r\n");
173 response
.write("\r\n");
174 response
.write(body
);
178 // eslint-disable-next-line no-unused-vars
179 function completeTest2(request
) {
180 Assert
.equal(request
.status
, Cr
.NS_OK
);
182 // test 3 requires the enforce-framing prefs to be false
183 prefs
.setBoolPref("network.http.enforce-framing.http1", false);
184 prefs
.setBoolPref("network.http.enforce-framing.soft", false);
186 "network.http.enforce-framing.strict_chunked_encoding",
192 ////////////////////////////////////////////////////////////////////////////////
193 // Test 3: SUCCEED with bad Content-Length because pref allows it
194 test_flags
[3] = CL_IGNORE_CL
;
196 // eslint-disable-next-line no-unused-vars
197 function handler3(metadata
, response
) {
198 var body
= "blablabla";
200 response
.seizePower();
201 response
.write("HTTP/1.1 200 OK\r\n");
202 response
.write("Content-Type: text/plain\r\n");
203 response
.write("Content-Length: 556677\r\n");
204 response
.write("\r\n");
205 response
.write(body
);
209 // eslint-disable-next-line no-unused-vars
210 function completeTest3(request
) {
211 Assert
.equal(request
.status
, Cr
.NS_OK
);
212 prefs
.setBoolPref("network.http.enforce-framing.soft", true);
216 ////////////////////////////////////////////////////////////////////////////////
217 // Test 4: Succeed because a cut off deflate stream can't be detected
218 test_flags
[4] = CL_IGNORE_CL
;
220 // eslint-disable-next-line no-unused-vars
221 function handler4(metadata
, response
) {
222 // this is the beginning of a deflate compressed response body
225 "\xcd\x57\xcd\x6e\x1b\x37\x10\xbe\x07\xc8\x3b\x0c\x36\x68\x72\xd1" +
226 "\xbf\x92\x22\xb1\x57\x0a\x64\x4b\x6a\x0c\x28\xb6\x61\xa9\x41\x73" +
227 "\x2a\xb8\xbb\x94\x44\x98\xfb\x03\x92\x92\xec\x06\x7d\x97\x1e\xeb" +
228 "\xbe\x86\x5e\xac\xc3\x25\x97\xa2\x64\xb9\x75\x0b\x14\xe8\x69\x87" +
229 "\x33\x9c\x1f\x7e\x33\x9c\xe1\x86\x9f\x66\x9f\x27\xfd\x97\x2f\x20" +
230 "\xfc\x34\x1a\x0c\x35\x01\xa1\x62\x8a\xd3\xfe\xf5\xcd\xd5\xe5\xd5" +
231 "\x6c\x54\x83\x49\xbe\x60\x31\xa3\x1c\x12\x0a\x0b\x2a\x15\xcb\x33" +
232 "\x4d\xae\x19\x05\x19\xe7\x9c\x30\x41\x1b\x61\xd3\x28\x95\xfa\x29" +
233 "\x55\x04\x32\x92\xd2\x5e\x90\x50\x19\x0b\x56\x68\x9d\x00\xe2\x3c" +
234 "\x53\x34\x53\xbd\xc0\x99\x56\xf9\x4a\x51\xe0\x64\xcf\x18\x24\x24" +
235 "\x93\xb0\xca\x40\xd2\x15\x07\x6e\xbd\x37\x60\x82\x3b\x8f\x86\x22" +
236 "\x21\xcb\x15\x95\x35\x20\x91\xa4\x59\xac\xa9\x62\x95\x31\xed\x14" +
237 "\xc9\x98\x2c\x19\x15\x3a\x62\x45\xef\x70\x1b\x50\x05\xa4\x28\xc4" +
238 "\xf6\x21\x66\xa4\xdc\x83\x32\x09\x85\xc8\xe7\x54\xa2\x4b\x81\x74" +
239 "\xbe\x12\xc0\x91\xb9\x7d\x50\x24\xe2\x0c\xd9\x29\x06\x2e\xdd\x79";
241 response
.seizePower();
242 response
.write("HTTP/1.1 200 OK\r\n");
243 response
.write("Content-Type: text/plain\r\n");
244 response
.write("Content-Length: 553677\r\n");
245 response
.write("Content-Encoding: deflate\r\n");
246 response
.write("\r\n");
247 response
.write(body
);
251 // eslint-disable-next-line no-unused-vars
252 function completeTest4(request
) {
253 Assert
.equal(request
.status
, Cr
.NS_OK
);
255 prefs
.setBoolPref("network.http.enforce-framing.http1", true);
259 ////////////////////////////////////////////////////////////////////////////////
260 // Test 99: FAIL because a cut off gzip stream CAN be detected
262 // Note that test 99 here is run completely different than the other tests in
263 // this file so if you add more tests here, consider adding them before this.
265 // eslint-disable-next-line no-unused-vars
266 function handler99(metadata
, response
) {
267 // this is the beginning of a gzip compressed response body
270 "\x1f\x8b\x08\x00\x80\xb9\x25\x53\x00\x03\xd4\xd9\x79\xb8\x8e\xe5" +
271 "\xba\x00\xf0\x65\x19\x33\x24\x15\x29\xf3\x50\x52\xc6\xac\x85\x10" +
272 "\x8b\x12\x22\x45\xe6\xb6\x21\x9a\x96\x84\x4c\x69\x32\xec\x84\x92" +
273 "\xcc\x99\x6a\xd9\x32\xa5\xd0\x40\xd9\xc6\x14\x15\x95\x28\x62\x9b" +
274 "\x09\xc9\x70\x4a\x25\x53\xec\x8e\x9c\xe5\x1c\x9d\xeb\xfe\x9d\x73" +
275 "\x9d\x3f\xf6\x1f\xe7\xbd\xae\xcf\xf3\xbd\xbf\xef\x7e\x9f\xeb\x79" +
276 "\xef\xf7\x99\xde\xe5\xee\x6e\xdd\x3b\x75\xeb\xd1\xb5\x6c\xb3\xd4" +
277 "\x47\x1f\x48\xf8\x17\x1d\x15\xce\x1d\x55\x92\x93\xcf\x97\xe7\x8e" +
278 "\x8b\xca\xe4\xca\x55\x92\x2a\x54\x4e\x4e\x4e\x4a\xa8\x78\x53\xa5" +
279 "\x8a\x15\x2b\x55\x4a\xfa\xe3\x7b\x85\x8a\x37\x55\x48\xae\x92\x50" +
280 "\xb4\xc2\xbf\xaa\x41\x17\x1f\xbd\x7b\xf6\xba\xaf\x47\xd1\xa2\x09" +
281 "\x3d\xba\x75\xeb\xf5\x3f\xc5\xfd\x6f\xbf\xff\x3f\x3d\xfa\xd7\x6d" +
282 "\x74\x7b\x62\x86\x0c\xff\x79\x9e\x98\x50\x33\xe1\x8f\xb3\x01\xef" +
283 "\xb6\x38\x7f\x9e\x92\xee\xf9\xa7\xee\xcb\x74\x21\x26\x25\xa1\x6a" +
284 "\x42\xf6\x73\xff\x96\x4c\x28\x91\x90\xe5\xdc\x79\xa6\x8b\xe2\x52" +
285 "\xd2\xbf\x5d\x28\x2b\x24\x26\xfc\xa9\xcc\x96\x1e\x97\x31\xfd\xba" +
286 "\xee\xe9\xde\x3d\x31\xe5\x4f\x65\xc1\xf4\xb8\x0b\x65\x86\x8b\xca";
287 response
.seizePower();
288 response
.write("HTTP/1.1 200 OK\r\n");
289 response
.write("Content-Type: text/plain\r\n");
290 response
.write("Content-Length: 553677\r\n");
291 response
.write("Content-Encoding: gzip\r\n");
292 response
.write("\r\n");
293 response
.write(body
);