5 /* import-globals-from head_channels.js */
7 // Generate a small and a large post with known pre-calculated md5 sums
8 function generateContent(size
) {
10 for (var i
= 0; i
< size
; i
++) {
17 posts
.push(generateContent(10));
18 posts
.push(generateContent(250000));
19 posts
.push(generateContent(128000));
21 // pre-calculated md5sums (in hex) of the above posts
23 "f1b708bba17f1ce948dc979f4d7092bc",
24 "2ef8d3b6c8f329318eb1a119b12622b6",
27 var bigListenerData
= generateContent(128 * 1024);
28 var bigListenerMD5
= "8f607cfdd2c87d6a7eedb657dafbd836";
30 function checkIsHttp2(request
) {
32 if (request
.getResponseHeader("X-Firefox-Spdy") == "h2") {
33 if (request
.getResponseHeader("X-Connection-Http2") == "yes") {
36 return false; // Weird case, but the server disagrees with us
44 var Http2CheckListener = function () {};
46 Http2CheckListener
.prototype = {
47 onStartRequestFired
: false,
48 onDataAvailableFired
: false,
49 isHttp2Connection
: false,
55 onStartRequest
: function testOnStartRequest(request
) {
56 this.onStartRequestFired
= true;
57 if (this.shouldSucceed
&& !Components
.isSuccessCode(request
.status
)) {
58 do_throw("Channel should have a success code! (" + request
.status
+ ")");
60 !this.shouldSucceed
&&
61 Components
.isSuccessCode(request
.status
)
63 do_throw("Channel succeeded unexpectedly!");
66 Assert
.ok(request
instanceof Ci
.nsIHttpChannel
);
67 Assert
.equal(request
.requestSucceeded
, this.shouldSucceed
);
68 if (this.shouldSucceed
) {
69 Assert
.equal(request
.responseStatus
, 200);
73 onDataAvailable
: function testOnDataAvailable(request
, stream
, off
, cnt
) {
74 this.onDataAvailableFired
= true;
75 this.isHttp2Connection
= checkIsHttp2(request
);
77 read_stream(stream
, cnt
);
80 onStopRequest
: function testOnStopRequest(request
, status
) {
81 Assert
.ok(this.onStartRequestFired
);
82 if (this.expected
!= -1) {
83 Assert
.equal(this.accum
, this.expected
);
86 if (this.shouldSucceed
) {
87 Assert
.ok(Components
.isSuccessCode(status
));
88 Assert
.ok(this.onDataAvailableFired
);
89 Assert
.ok(this.isHttp2Connection
== this.shouldBeHttp2
);
91 Assert
.ok(!Components
.isSuccessCode(status
));
93 request
.QueryInterface(Ci
.nsIProxiedChannel
);
94 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
95 this.finish({ httpProxyConnectResponseCode
});
100 * Support for testing valid multiplexing of streams
103 var multiplexContent
= generateContent(30 * 1024);
105 /* Listener class to control the testing of multiplexing */
106 var Http2MultiplexListener = function () {};
108 Http2MultiplexListener
.prototype = new Http2CheckListener();
110 Http2MultiplexListener
.prototype.streamID
= 0;
111 Http2MultiplexListener
.prototype.buffer
= "";
113 Http2MultiplexListener
.prototype.onDataAvailable = function (
119 this.onDataAvailableFired
= true;
120 this.isHttp2Connection
= checkIsHttp2(request
);
121 this.streamID
= parseInt(request
.getResponseHeader("X-Http2-StreamID"));
122 var data
= read_stream(stream
, cnt
);
123 this.buffer
= this.buffer
.concat(data
);
126 Http2MultiplexListener
.prototype.onStopRequest = function (request
) {
127 Assert
.ok(this.onStartRequestFired
);
128 Assert
.ok(this.onDataAvailableFired
);
129 Assert
.ok(this.isHttp2Connection
);
130 Assert
.ok(this.buffer
== multiplexContent
);
132 request
.QueryInterface(Ci
.nsIProxiedChannel
);
133 // This is what does most of the hard work for us
134 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
135 var streamID
= this.streamID
;
136 this.finish({ httpProxyConnectResponseCode
, streamID
});
139 // Does the appropriate checks for header gatewaying
140 var Http2HeaderListener = function (name
, callback
) {
142 this.callback
= callback
;
145 Http2HeaderListener
.prototype = new Http2CheckListener();
146 Http2HeaderListener
.prototype.value
= "";
148 Http2HeaderListener
.prototype.onDataAvailable = function (
154 this.onDataAvailableFired
= true;
155 this.isHttp2Connection
= checkIsHttp2(request
);
156 var hvalue
= request
.getResponseHeader(this.name
);
157 Assert
.notEqual(hvalue
, "");
158 this.callback(hvalue
);
159 read_stream(stream
, cnt
);
162 var Http2PushListener = function (shouldBePushed
) {
163 this.shouldBePushed
= shouldBePushed
;
166 Http2PushListener
.prototype = new Http2CheckListener();
168 Http2PushListener
.prototype.onDataAvailable = function (
174 this.onDataAvailableFired
= true;
175 this.isHttp2Connection
= checkIsHttp2(request
);
177 request
.originalURI
.spec
==
178 `https://localhost:${this.serverPort}/push.js` ||
179 request
.originalURI
.spec
==
180 `https://localhost:${this.serverPort}/push2.js` ||
181 request
.originalURI
.spec
== `https://localhost:${this.serverPort}/push5.js`
184 request
.getResponseHeader("pushed"),
185 this.shouldBePushed
? "yes" : "no"
188 read_stream(stream
, cnt
);
192 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
193 const pullHdrTxt
= pushHdrTxt
.split("").reverse().join("");
195 function checkContinuedHeaders(getHeader
, headerPrefix
, headerText
) {
196 for (var i
= 0; i
< 265; i
++) {
197 Assert
.equal(getHeader(headerPrefix
+ 1), headerText
);
201 var Http2ContinuedHeaderListener = function () {};
203 Http2ContinuedHeaderListener
.prototype = new Http2CheckListener();
205 Http2ContinuedHeaderListener
.prototype.onStopsLeft
= 2;
207 Http2ContinuedHeaderListener
.prototype.QueryInterface
= ChromeUtils
.generateQI([
208 "nsIHttpPushListener",
212 Http2ContinuedHeaderListener
.prototype.getInterface = function (aIID
) {
213 return this.QueryInterface(aIID
);
216 Http2ContinuedHeaderListener
.prototype.onDataAvailable = function (
222 this.onDataAvailableFired
= true;
223 this.isHttp2Connection
= checkIsHttp2(request
);
225 request
.originalURI
.spec
==
226 `https://localhost:${this.serverPort}/continuedheaders`
228 // This is the original request, so the only one where we'll have continued response headers
229 checkContinuedHeaders(
230 request
.getResponseHeader
,
231 "X-Pull-Test-Header-",
235 read_stream(stream
, cnt
);
238 Http2ContinuedHeaderListener
.prototype.onStopRequest = function (
242 Assert
.ok(this.onStartRequestFired
);
243 Assert
.ok(Components
.isSuccessCode(status
));
244 Assert
.ok(this.onDataAvailableFired
);
245 Assert
.ok(this.isHttp2Connection
);
248 if (this.onStopsLeft
=== 0) {
249 request
.QueryInterface(Ci
.nsIProxiedChannel
);
250 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
251 this.finish({ httpProxyConnectResponseCode
});
255 Http2ContinuedHeaderListener
.prototype.onPush = function (
260 associatedChannel
.originalURI
.spec
,
261 "https://localhost:" + this.serverPort
+ "/continuedheaders"
263 Assert
.equal(pushChannel
.getRequestHeader("x-pushed-request"), "true");
264 checkContinuedHeaders(
265 pushChannel
.getRequestHeader
,
266 "X-Push-Test-Header-",
270 pushChannel
.asyncOpen(this);
273 // Does the appropriate checks for a large GET response
274 var Http2BigListener = function () {};
276 Http2BigListener
.prototype = new Http2CheckListener();
277 Http2BigListener
.prototype.buffer
= "";
279 Http2BigListener
.prototype.onDataAvailable = function (
285 this.onDataAvailableFired
= true;
286 this.isHttp2Connection
= checkIsHttp2(request
);
287 this.buffer
= this.buffer
.concat(read_stream(stream
, cnt
));
288 // We know the server should send us the same data as our big post will be,
289 // so the md5 should be the same
290 Assert
.equal(bigListenerMD5
, request
.getResponseHeader("X-Expected-MD5"));
293 Http2BigListener
.prototype.onStopRequest = function (request
) {
294 Assert
.ok(this.onStartRequestFired
);
295 Assert
.ok(this.onDataAvailableFired
);
296 Assert
.ok(this.isHttp2Connection
);
298 // Don't want to flood output, so don't use do_check_eq
299 Assert
.ok(this.buffer
== bigListenerData
);
301 request
.QueryInterface(Ci
.nsIProxiedChannel
);
302 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
303 this.finish({ httpProxyConnectResponseCode
});
306 var Http2HugeSuspendedListener = function () {};
308 Http2HugeSuspendedListener
.prototype = new Http2CheckListener();
309 Http2HugeSuspendedListener
.prototype.count
= 0;
311 Http2HugeSuspendedListener
.prototype.onDataAvailable = function (
317 this.onDataAvailableFired
= true;
318 this.isHttp2Connection
= checkIsHttp2(request
);
320 read_stream(stream
, cnt
);
323 Http2HugeSuspendedListener
.prototype.onStopRequest = function (request
) {
324 Assert
.ok(this.onStartRequestFired
);
325 Assert
.ok(this.onDataAvailableFired
);
326 Assert
.ok(this.isHttp2Connection
);
327 Assert
.equal(this.count
, 1024 * 1024 * 1); // 1mb of data expected
328 request
.QueryInterface(Ci
.nsIProxiedChannel
);
329 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
330 this.finish({ httpProxyConnectResponseCode
});
333 // Does the appropriate checks for POSTs
334 var Http2PostListener = function (expected_md5
) {
335 this.expected_md5
= expected_md5
;
338 Http2PostListener
.prototype = new Http2CheckListener();
339 Http2PostListener
.prototype.expected_md5
= "";
341 Http2PostListener
.prototype.onDataAvailable = function (
347 this.onDataAvailableFired
= true;
348 this.isHttp2Connection
= checkIsHttp2(request
);
349 read_stream(stream
, cnt
);
352 request
.getResponseHeader("X-Calculated-MD5")
356 var ResumeStalledChannelListener = function () {};
358 ResumeStalledChannelListener
.prototype = {
359 onStartRequestFired
: false,
360 onDataAvailableFired
: false,
361 isHttp2Connection
: false,
365 onStartRequest
: function testOnStartRequest(request
) {
366 this.onStartRequestFired
= true;
367 if (!Components
.isSuccessCode(request
.status
)) {
368 do_throw("Channel should have a success code! (" + request
.status
+ ")");
371 Assert
.ok(request
instanceof Ci
.nsIHttpChannel
);
372 Assert
.equal(request
.responseStatus
, 200);
373 Assert
.equal(request
.requestSucceeded
, true);
376 onDataAvailable
: function testOnDataAvailable(request
, stream
, off
, cnt
) {
377 this.onDataAvailableFired
= true;
378 this.isHttp2Connection
= checkIsHttp2(request
);
379 read_stream(stream
, cnt
);
382 onStopRequest
: function testOnStopRequest(request
, status
) {
383 Assert
.ok(this.onStartRequestFired
);
384 Assert
.ok(Components
.isSuccessCode(status
));
385 Assert
.ok(this.onDataAvailableFired
);
386 Assert
.ok(this.isHttp2Connection
== this.shouldBeHttp2
);
387 this.resumable
.resume();
391 // test a large download that creates stream flow control and
392 // confirm we can do another independent stream while the download
394 async
function test_http2_blocking_download(serverPort
) {
395 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/bigdownload`);
396 var internalChannel
= chan
.QueryInterface(Ci
.nsIHttpChannelInternal
);
397 internalChannel
.initialRwin
= 500000; // make the stream.suspend push back in h2
398 var p
= new Promise(resolve
=> {
399 var listener
= new Http2CheckListener();
400 listener
.finish
= resolve
;
401 listener
.expected
= 3 * 1024 * 1024;
402 chan
.asyncOpen(listener
);
405 // wait 5 seconds so that stream flow control kicks in and then see if we
406 // can do a basic transaction (i.e. session not blocked). afterwards resume
408 do_timeout(5000, function () {
409 var simpleChannel
= makeHTTPChannel(`https://localhost:${serverPort}/`);
410 var sl
= new ResumeStalledChannelListener();
412 simpleChannel
.asyncOpen(sl
);
417 // Make sure we make a HTTP2 connection and both us and the server mark it as such
418 async
function test_http2_basic(serverPort
) {
419 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/`);
420 var p
= new Promise(resolve
=> {
421 var listener
= new Http2CheckListener();
422 listener
.finish
= resolve
;
423 chan
.asyncOpen(listener
);
428 async
function test_http2_basic_unblocked_dep(serverPort
) {
429 var chan
= makeHTTPChannel(
430 `https://localhost:${serverPort}/basic_unblocked_dep`
432 var cos
= chan
.QueryInterface(Ci
.nsIClassOfService
);
433 cos
.addClassFlags(Ci
.nsIClassOfService
.Unblocked
);
434 return new Promise(resolve
=> {
435 var listener
= new Http2CheckListener();
436 listener
.finish
= resolve
;
437 chan
.asyncOpen(listener
);
441 // make sure we don't use h2 when disallowed
442 async
function test_http2_nospdy(serverPort
) {
443 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/`);
444 return new Promise(resolve
=> {
445 var listener
= new Http2CheckListener();
446 listener
.finish
= resolve
;
447 var internalChannel
= chan
.QueryInterface(Ci
.nsIHttpChannelInternal
);
448 internalChannel
.allowSpdy
= false;
449 listener
.shouldBeHttp2
= false;
450 chan
.asyncOpen(listener
);
454 // Support for making sure XHR works over SPDY
455 function checkXhr(xhr
, finish
) {
456 if (xhr
.readyState
!= 4) {
460 Assert
.equal(xhr
.status
, 200);
461 Assert
.equal(checkIsHttp2(xhr
), true);
465 // Fires off an XHR request over h2
466 async
function test_http2_xhr(serverPort
) {
467 return new Promise(resolve
=> {
468 var req
= new XMLHttpRequest();
469 req
.open("GET", `https://localhost:${serverPort}/`, true);
470 req
.addEventListener("readystatechange", function () {
471 checkXhr(req
, resolve
);
477 var Http2ConcurrentListener = function () {};
479 Http2ConcurrentListener
.prototype = new Http2CheckListener();
480 Http2ConcurrentListener
.prototype.count
= 0;
481 Http2ConcurrentListener
.prototype.target
= 0;
482 Http2ConcurrentListener
.prototype.reset
= 0;
483 Http2ConcurrentListener
.prototype.recvdHdr
= 0;
485 Http2ConcurrentListener
.prototype.onStopRequest = function (request
) {
487 Assert
.ok(this.isHttp2Connection
);
488 if (this.recvdHdr
> 0) {
489 Assert
.equal(request
.getResponseHeader("X-Recvd"), this.recvdHdr
);
492 if (this.count
== this.target
) {
493 if (this.reset
> 0) {
494 Services
.prefs
.setIntPref(
495 "network.http.http2.default-concurrent",
499 request
.QueryInterface(Ci
.nsIProxiedChannel
);
500 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
501 this.finish({ httpProxyConnectResponseCode
});
505 async
function test_http2_concurrent(concurrent_channels
, serverPort
) {
506 var p
= new Promise(resolve
=> {
507 var concurrent_listener
= new Http2ConcurrentListener();
508 concurrent_listener
.finish
= resolve
;
509 concurrent_listener
.target
= 201;
510 concurrent_listener
.reset
= Services
.prefs
.getIntPref(
511 "network.http.http2.default-concurrent"
513 Services
.prefs
.setIntPref("network.http.http2.default-concurrent", 100);
515 for (var i
= 0; i
< concurrent_listener
.target
; i
++) {
516 concurrent_channels
[i
] = makeHTTPChannel(
517 `https://localhost:${serverPort}/750ms`
519 concurrent_channels
[i
].loadFlags
= Ci
.nsIRequest
.LOAD_BYPASS_CACHE
;
520 concurrent_channels
[i
].asyncOpen(concurrent_listener
);
526 async
function test_http2_concurrent_post(concurrent_channels
, serverPort
) {
527 return new Promise(resolve
=> {
528 var concurrent_listener
= new Http2ConcurrentListener();
529 concurrent_listener
.finish
= resolve
;
530 concurrent_listener
.target
= 8;
531 concurrent_listener
.recvdHdr
= posts
[2].length
;
532 concurrent_listener
.reset
= Services
.prefs
.getIntPref(
533 "network.http.http2.default-concurrent"
535 Services
.prefs
.setIntPref("network.http.http2.default-concurrent", 3);
537 for (var i
= 0; i
< concurrent_listener
.target
; i
++) {
538 concurrent_channels
[i
] = makeHTTPChannel(
539 `https://localhost:${serverPort}/750msPost`
541 concurrent_channels
[i
].loadFlags
= Ci
.nsIRequest
.LOAD_BYPASS_CACHE
;
542 var stream
= Cc
["@mozilla.org/io/string-input-stream;1"].createInstance(
543 Ci
.nsIStringInputStream
545 stream
.setByteStringData(posts
[2]);
546 var uchan
= concurrent_channels
[i
].QueryInterface(Ci
.nsIUploadChannel
);
547 uchan
.setUploadStream(stream
, "text/plain", stream
.available());
548 concurrent_channels
[i
].requestMethod
= "POST";
549 concurrent_channels
[i
].asyncOpen(concurrent_listener
);
554 // Test to make sure we get multiplexing right
555 async
function test_http2_multiplex(serverPort
) {
556 let chan1
= makeHTTPChannel(`https://localhost:${serverPort}/multiplex1`);
557 let chan2
= makeHTTPChannel(`https://localhost:${serverPort}/multiplex2`);
558 let listener1
= new Http2MultiplexListener();
559 let listener2
= new Http2MultiplexListener();
562 let p1
= new Promise(resolve
=> {
563 listener1
.finish
= resolve
;
566 let p2
= new Promise(resolve
=> {
567 listener2
.finish
= resolve
;
571 chan1
.asyncOpen(listener1
);
572 chan2
.asyncOpen(listener2
);
573 return Promise
.all(promises
);
576 // Test to make sure we gateway non-standard headers properly
577 async
function test_http2_header(serverPort
) {
578 let chan
= makeHTTPChannel(`https://localhost:${serverPort}/header`);
579 let hvalue
= "Headers are fun";
580 chan
.setRequestHeader("X-Test-Header", hvalue
, false);
581 return new Promise(resolve
=> {
582 let listener
= new Http2HeaderListener("X-Received-Test-Header", function (
585 Assert
.equal(received_hvalue
, hvalue
);
587 listener
.finish
= resolve
;
588 chan
.asyncOpen(listener
);
592 // Test to make sure headers with invalid characters in the name are rejected
593 async
function test_http2_invalid_response_header(serverPort
, invalid_kind
) {
594 return new Promise(resolve
=> {
595 var listener
= new Http2CheckListener();
596 listener
.finish
= resolve
;
597 listener
.shouldSucceed
= false;
598 var chan
= makeHTTPChannel(
599 `https://localhost:${serverPort}/invalid_response_header/${invalid_kind}`
601 chan
.asyncOpen(listener
);
605 // Test to make sure cookies are split into separate fields before compression
606 async
function test_http2_cookie_crumbling(serverPort
) {
607 var chan
= makeHTTPChannel(
608 `https://localhost:${serverPort}/cookie_crumbling`
610 var cookiesSent
= ["a=b", "c=d01234567890123456789", "e=f"].sort();
611 chan
.setRequestHeader("Cookie", cookiesSent
.join("; "), false);
612 return new Promise(resolve
=> {
613 var listener
= new Http2HeaderListener("X-Received-Header-Pairs", function (
616 var cookiesReceived
= JSON
.parse(pairsReceived
)
617 .filter(function (pair
) {
618 return pair
[0] == "cookie";
620 .map(function (pair
) {
624 Assert
.equal(cookiesReceived
.length
, cookiesSent
.length
);
625 cookiesReceived
.forEach(function (cookieReceived
, index
) {
626 Assert
.equal(cookiesSent
[index
], cookieReceived
);
629 listener
.finish
= resolve
;
630 chan
.asyncOpen(listener
);
634 async
function test_http2_push1(loadGroup
, serverPort
) {
635 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push`);
636 chan
.loadGroup
= loadGroup
;
637 return new Promise(resolve
=> {
638 var listener
= new Http2PushListener(true);
639 listener
.finish
= resolve
;
640 listener
.serverPort
= serverPort
;
641 chan
.asyncOpen(listener
);
645 async
function test_http2_push2(loadGroup
, serverPort
) {
646 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push.js`);
647 chan
.loadGroup
= loadGroup
;
648 return new Promise(resolve
=> {
649 var listener
= new Http2PushListener(true);
650 listener
.finish
= resolve
;
651 listener
.serverPort
= serverPort
;
652 chan
.asyncOpen(listener
);
656 async
function test_http2_push3(loadGroup
, serverPort
) {
657 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push2`);
658 chan
.loadGroup
= loadGroup
;
659 return new Promise(resolve
=> {
660 var listener
= new Http2PushListener(true);
661 listener
.finish
= resolve
;
662 listener
.serverPort
= serverPort
;
663 chan
.asyncOpen(listener
);
667 async
function test_http2_push4(loadGroup
, serverPort
) {
668 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push2.js`);
669 chan
.loadGroup
= loadGroup
;
670 return new Promise(resolve
=> {
671 var listener
= new Http2PushListener(true);
672 listener
.finish
= resolve
;
673 listener
.serverPort
= serverPort
;
674 chan
.asyncOpen(listener
);
678 async
function test_http2_push5(loadGroup
, serverPort
) {
679 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push5`);
680 chan
.loadGroup
= loadGroup
;
681 return new Promise(resolve
=> {
682 var listener
= new Http2PushListener(true);
683 listener
.finish
= resolve
;
684 listener
.serverPort
= serverPort
;
685 chan
.asyncOpen(listener
);
689 async
function test_http2_push6(loadGroup
, serverPort
) {
690 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push5.js`);
691 chan
.loadGroup
= loadGroup
;
692 return new Promise(resolve
=> {
693 var listener
= new Http2PushListener(true);
694 listener
.finish
= resolve
;
695 listener
.serverPort
= serverPort
;
696 chan
.asyncOpen(listener
);
700 // this is a basic test where the server sends a simple document with 2 header
701 // blocks. bug 1027364
702 async
function test_http2_doubleheader(serverPort
) {
703 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/doubleheader`);
704 return new Promise(resolve
=> {
705 var listener
= new Http2CheckListener();
706 listener
.finish
= resolve
;
707 chan
.asyncOpen(listener
);
711 // Make sure we handle GETs that cover more than 2 frames properly
712 async
function test_http2_big(serverPort
) {
713 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/big`);
714 return new Promise(resolve
=> {
715 var listener
= new Http2BigListener();
716 listener
.finish
= resolve
;
717 chan
.asyncOpen(listener
);
721 async
function test_http2_huge_suspended(serverPort
) {
722 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/huge`);
723 return new Promise(resolve
=> {
724 var listener
= new Http2HugeSuspendedListener();
725 listener
.finish
= resolve
;
726 chan
.asyncOpen(listener
);
728 do_timeout(500, chan
.resume
);
732 // Support for doing a POST
733 function do_post(content
, chan
, listener
, method
) {
734 var stream
= Cc
["@mozilla.org/io/string-input-stream;1"].createInstance(
735 Ci
.nsIStringInputStream
737 stream
.setByteStringData(content
);
739 var uchan
= chan
.QueryInterface(Ci
.nsIUploadChannel
);
740 uchan
.setUploadStream(stream
, "text/plain", stream
.available());
742 chan
.requestMethod
= method
;
744 chan
.asyncOpen(listener
);
747 // Make sure we can do a simple POST
748 async
function test_http2_post(serverPort
) {
749 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/post`);
750 var p
= new Promise(resolve
=> {
751 var listener
= new Http2PostListener(md5s
[0]);
752 listener
.finish
= resolve
;
753 do_post(posts
[0], chan
, listener
, "POST");
758 async
function test_http2_empty_post(serverPort
) {
759 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/post`);
760 var p
= new Promise(resolve
=> {
761 var listener
= new Http2PostListener("0");
762 listener
.finish
= resolve
;
763 do_post("", chan
, listener
, "POST");
768 // Make sure we can do a simple PATCH
769 async
function test_http2_patch(serverPort
) {
770 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/patch`);
771 return new Promise(resolve
=> {
772 var listener
= new Http2PostListener(md5s
[0]);
773 listener
.finish
= resolve
;
774 do_post(posts
[0], chan
, listener
, "PATCH");
778 // Make sure we can do a POST that covers more than 2 frames
779 async
function test_http2_post_big(serverPort
) {
780 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/post`);
781 return new Promise(resolve
=> {
782 var listener
= new Http2PostListener(md5s
[1]);
783 listener
.finish
= resolve
;
784 do_post(posts
[1], chan
, listener
, "POST");
788 // When a http proxy is used alt-svc is disable. Therefore if withProxy is true,
789 // try numberOfTries times to connect and make sure that alt-svc is not use and we never
790 // connect to the HTTP/2 server.
791 var altsvcClientListener = function (
798 this.finish
= finish
;
799 this.httpserv
= httpserv
;
800 this.httpserv2
= httpserv2
;
801 this.withProxy
= withProxy
;
802 this.numberOfTries
= numberOfTries
;
805 altsvcClientListener
.prototype = {
806 onStartRequest
: function test_onStartR(request
) {
807 Assert
.equal(request
.status
, Cr
.NS_OK
);
810 onDataAvailable
: function test_ODA(request
, stream
, offset
, cnt
) {
811 read_stream(stream
, cnt
);
814 onStopRequest
: function test_onStopR(request
) {
815 var isHttp2Connection
= checkIsHttp2(
816 request
.QueryInterface(Ci
.nsIHttpChannel
)
818 if (!isHttp2Connection
) {
819 dump("/altsvc1 not over h2 yet - retry\n");
820 if (this.withProxy
&& this.numberOfTries
== 0) {
821 request
.QueryInterface(Ci
.nsIProxiedChannel
);
822 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
823 this.finish({ httpProxyConnectResponseCode
});
826 let chan
= makeHTTPChannel(
827 `http://foo.example.com:${this.httpserv}/altsvc1`,
829 ).QueryInterface(Ci
.nsIHttpChannel
);
830 // we use this header to tell the server to issue a altsvc frame for the
831 // speficied origin we will use in the next part of the test
832 chan
.setRequestHeader(
834 `http://foo.example.com:${this.httpserv2}`,
837 chan
.loadFlags
= Ci
.nsIRequest
.LOAD_BYPASS_CACHE
;
839 new altsvcClientListener(
844 this.numberOfTries
- 1
848 Assert
.ok(isHttp2Connection
);
849 let chan
= makeHTTPChannel(
850 `http://foo.example.com:${this.httpserv2}/altsvc2`
851 ).QueryInterface(Ci
.nsIHttpChannel
);
852 chan
.loadFlags
= Ci
.nsIRequest
.LOAD_BYPASS_CACHE
;
854 new altsvcClientListener2(this.finish
, this.httpserv
, this.httpserv2
)
860 var altsvcClientListener2 = function (finish
, httpserv
, httpserv2
) {
861 this.finish
= finish
;
862 this.httpserv
= httpserv
;
863 this.httpserv2
= httpserv2
;
866 altsvcClientListener2
.prototype = {
867 onStartRequest
: function test_onStartR(request
) {
868 Assert
.equal(request
.status
, Cr
.NS_OK
);
871 onDataAvailable
: function test_ODA(request
, stream
, offset
, cnt
) {
872 read_stream(stream
, cnt
);
875 onStopRequest
: function test_onStopR(request
) {
876 var isHttp2Connection
= checkIsHttp2(
877 request
.QueryInterface(Ci
.nsIHttpChannel
)
879 if (!isHttp2Connection
) {
880 dump("/altsvc2 not over h2 yet - retry\n");
881 var chan
= makeHTTPChannel(
882 `http://foo.example.com:${this.httpserv2}/altsvc2`
883 ).QueryInterface(Ci
.nsIHttpChannel
);
884 chan
.loadFlags
= Ci
.nsIRequest
.LOAD_BYPASS_CACHE
;
886 new altsvcClientListener2(this.finish
, this.httpserv
, this.httpserv2
)
889 Assert
.ok(isHttp2Connection
);
890 request
.QueryInterface(Ci
.nsIProxiedChannel
);
891 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
892 this.finish({ httpProxyConnectResponseCode
});
897 async
function test_http2_altsvc(httpserv
, httpserv2
, withProxy
) {
898 var chan
= makeHTTPChannel(
899 `http://foo.example.com:${httpserv}/altsvc1`,
901 ).QueryInterface(Ci
.nsIHttpChannel
);
902 return new Promise(resolve
=> {
903 var numberOfTries
= 0;
908 new altsvcClientListener(
919 var Http2PushApiListener = function (finish
, serverPort
) {
920 this.finish
= finish
;
921 this.serverPort
= serverPort
;
924 Http2PushApiListener
.prototype = {
925 checksPending
: 9, // 4 onDataAvailable and 5 onStop
928 return this.QueryInterface(aIID
);
931 QueryInterface
: ChromeUtils
.generateQI([
932 "nsIHttpPushListener",
936 // nsIHttpPushListener
937 onPush
: function onPush(associatedChannel
, pushChannel
) {
939 associatedChannel
.originalURI
.spec
,
940 "https://localhost:" + this.serverPort
+ "/pushapi1"
942 Assert
.equal(pushChannel
.getRequestHeader("x-pushed-request"), "true");
944 pushChannel
.asyncOpen(this);
946 pushChannel
.originalURI
.spec
==
947 "https://localhost:" + this.serverPort
+ "/pushapi1/2"
949 pushChannel
.cancel(Cr
.NS_ERROR_ABORT
);
951 pushChannel
.originalURI
.spec
==
952 "https://localhost:" + this.serverPort
+ "/pushapi1/3"
954 Assert
.ok(pushChannel
.getRequestHeader("Accept-Encoding").includes("br"));
958 // normal Channel listeners
959 onStartRequest
: function pushAPIOnStart() {},
961 onDataAvailable
: function pushAPIOnDataAvailable(
968 request
.originalURI
.spec
,
969 `https://localhost:${this.serverPort}/pushapi1/2`
972 var data
= read_stream(stream
, cnt
);
975 request
.originalURI
.spec
==
976 `https://localhost:${this.serverPort}/pushapi1`
978 Assert
.equal(data
[0], "0");
979 --this.checksPending
;
981 request
.originalURI
.spec
==
982 `https://localhost:${this.serverPort}/pushapi1/1`
984 Assert
.equal(data
[0], "1");
985 --this.checksPending
; // twice
987 request
.originalURI
.spec
==
988 `https://localhost:${this.serverPort}/pushapi1/3`
990 Assert
.equal(data
[0], "3");
991 --this.checksPending
;
993 Assert
.equal(true, false);
997 onStopRequest
: function test_onStopR(request
) {
999 request
.originalURI
.spec
==
1000 `https://localhost:${this.serverPort}/pushapi1/2`
1002 Assert
.equal(request
.status
, Cr
.NS_ERROR_ABORT
);
1004 Assert
.equal(request
.status
, Cr
.NS_OK
);
1007 --this.checksPending
; // 5 times - one for each push plus the pull
1008 if (!this.checksPending
) {
1009 request
.QueryInterface(Ci
.nsIProxiedChannel
);
1010 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
1011 this.finish({ httpProxyConnectResponseCode
});
1016 // pushAPI testcase 1 expects
1017 // 1 to pull /pushapi1 with 0
1018 // 2 to see /pushapi1/1 with 1
1019 // 3 to see /pushapi1/1 with 1 (again)
1020 // 4 to see /pushapi1/2 that it will cancel
1021 // 5 to see /pushapi1/3 with 3 with brotli
1023 async
function test_http2_pushapi_1(loadGroup
, serverPort
) {
1024 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/pushapi1`);
1025 chan
.loadGroup
= loadGroup
;
1026 return new Promise(resolve
=> {
1027 var listener
= new Http2PushApiListener(resolve
, serverPort
);
1028 chan
.notificationCallbacks
= listener
;
1029 chan
.asyncOpen(listener
);
1033 var WrongSuiteListener = function () {};
1035 WrongSuiteListener
.prototype = new Http2CheckListener();
1036 WrongSuiteListener
.prototype.shouldBeHttp2
= false;
1037 WrongSuiteListener
.prototype.onStopRequest = function (request
, status
) {
1038 Services
.prefs
.setBoolPref(
1039 "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256",
1042 Services
.prefs
.clearUserPref("security.tls.version.max");
1043 Http2CheckListener
.prototype.onStopRequest
.call(this, request
, status
);
1046 // test that we use h1 without the mandatory cipher suite available when
1047 // offering at most tls1.2
1048 async
function test_http2_wrongsuite_tls12(serverPort
) {
1049 Services
.prefs
.setBoolPref(
1050 "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256",
1053 Services
.prefs
.setIntPref("security.tls.version.max", 3);
1054 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/wrongsuite`);
1056 Ci
.nsIRequest
.LOAD_FRESH_CONNECTION
|
1057 Ci
.nsIChannel
.LOAD_INITIAL_DOCUMENT_URI
;
1058 return new Promise(resolve
=> {
1059 var listener
= new WrongSuiteListener();
1060 listener
.finish
= resolve
;
1061 chan
.asyncOpen(listener
);
1065 // test that we use h2 when offering tls1.3 or higher regardless of if the
1066 // mandatory cipher suite is available
1067 async
function test_http2_wrongsuite_tls13(serverPort
) {
1068 Services
.prefs
.setBoolPref(
1069 "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256",
1072 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/wrongsuite`);
1074 Ci
.nsIRequest
.LOAD_FRESH_CONNECTION
|
1075 Ci
.nsIChannel
.LOAD_INITIAL_DOCUMENT_URI
;
1076 return new Promise(resolve
=> {
1077 var listener
= new WrongSuiteListener();
1078 listener
.finish
= resolve
;
1079 listener
.shouldBeHttp2
= true;
1080 chan
.asyncOpen(listener
);
1084 async
function test_http2_h11required_stream(serverPort
) {
1085 var chan
= makeHTTPChannel(
1086 `https://localhost:${serverPort}/h11required_stream`
1088 return new Promise(resolve
=> {
1089 var listener
= new Http2CheckListener();
1090 listener
.finish
= resolve
;
1091 listener
.shouldBeHttp2
= false;
1092 chan
.asyncOpen(listener
);
1096 function H11RequiredSessionListener() {}
1098 H11RequiredSessionListener
.prototype = new Http2CheckListener();
1100 H11RequiredSessionListener
.prototype.onStopRequest = function (request
) {
1101 var streamReused
= request
.getResponseHeader("X-H11Required-Stream-Ok");
1102 Assert
.equal(streamReused
, "yes");
1104 Assert
.ok(this.onStartRequestFired
);
1105 Assert
.ok(this.onDataAvailableFired
);
1106 Assert
.ok(this.isHttp2Connection
== this.shouldBeHttp2
);
1108 request
.QueryInterface(Ci
.nsIProxiedChannel
);
1109 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
1110 this.finish({ httpProxyConnectResponseCode
});
1113 async
function test_http2_h11required_session(serverPort
) {
1114 var chan
= makeHTTPChannel(
1115 `https://localhost:${serverPort}/h11required_session`
1117 return new Promise(resolve
=> {
1118 var listener
= new H11RequiredSessionListener();
1119 listener
.finish
= resolve
;
1120 listener
.shouldBeHttp2
= false;
1121 chan
.asyncOpen(listener
);
1125 async
function test_http2_retry_rst(serverPort
) {
1126 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/rstonce`);
1127 return new Promise(resolve
=> {
1128 var listener
= new Http2CheckListener();
1129 listener
.finish
= resolve
;
1130 chan
.asyncOpen(listener
);
1134 async
function test_http2_continuations(loadGroup
, serverPort
) {
1135 var chan
= makeHTTPChannel(
1136 `https://localhost:${serverPort}/continuedheaders`
1138 chan
.loadGroup
= loadGroup
;
1139 return new Promise(resolve
=> {
1140 var listener
= new Http2ContinuedHeaderListener();
1141 listener
.finish
= resolve
;
1142 listener
.serverPort
= serverPort
;
1143 chan
.notificationCallbacks
= listener
;
1144 chan
.asyncOpen(listener
);
1148 async
function test_http2_continuations_over_max_response_limit(
1152 var chan
= makeHTTPChannel(
1153 `https://localhost:${serverPort}/hugecontinuedheaders?size=385`
1155 chan
.loadGroup
= loadGroup
;
1156 return new Promise(resolve
=> {
1157 var listener
= new Http2CheckListener();
1158 listener
.finish
= resolve
;
1159 listener
.shouldSucceed
= false;
1160 chan
.asyncOpen(listener
);
1164 function Http2IllegalHpackValidationListener() {}
1166 Http2IllegalHpackValidationListener
.prototype = new Http2CheckListener();
1167 Http2IllegalHpackValidationListener
.prototype.shouldGoAway
= false;
1169 Http2IllegalHpackValidationListener
.prototype.onStopRequest = function (
1172 var wentAway
= request
.getResponseHeader("X-Did-Goaway") === "yes";
1173 Assert
.equal(wentAway
, this.shouldGoAway
);
1175 Assert
.ok(this.onStartRequestFired
);
1176 Assert
.ok(this.onDataAvailableFired
);
1177 Assert
.ok(this.isHttp2Connection
== this.shouldBeHttp2
);
1179 request
.QueryInterface(Ci
.nsIProxiedChannel
);
1180 var httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
1181 this.finish({ httpProxyConnectResponseCode
});
1184 function Http2IllegalHpackListener() {}
1185 Http2IllegalHpackListener
.prototype = new Http2CheckListener();
1186 Http2IllegalHpackListener
.prototype.shouldGoAway
= false;
1188 Http2IllegalHpackListener
.prototype.onStopRequest = function () {
1189 var chan
= makeHTTPChannel(
1190 `https://localhost:${this.serverPort}/illegalhpack_validate`
1192 var listener
= new Http2IllegalHpackValidationListener();
1193 listener
.finish
= this.finish
;
1194 listener
.shouldGoAway
= this.shouldGoAway
;
1195 chan
.asyncOpen(listener
);
1198 async
function test_http2_illegalhpacksoft(serverPort
) {
1199 var chan
= makeHTTPChannel(
1200 `https://localhost:${serverPort}/illegalhpacksoft`
1202 return new Promise(resolve
=> {
1203 var listener
= new Http2IllegalHpackListener();
1204 listener
.finish
= resolve
;
1205 listener
.serverPort
= serverPort
;
1206 listener
.shouldGoAway
= false;
1207 listener
.shouldSucceed
= false;
1208 chan
.asyncOpen(listener
);
1212 async
function test_http2_illegalhpackhard(serverPort
) {
1213 var chan
= makeHTTPChannel(
1214 `https://localhost:${serverPort}/illegalhpackhard`
1216 return new Promise(resolve
=> {
1217 var listener
= new Http2IllegalHpackListener();
1218 listener
.finish
= resolve
;
1219 listener
.serverPort
= serverPort
;
1220 listener
.shouldGoAway
= true;
1221 listener
.shouldSucceed
= false;
1222 chan
.asyncOpen(listener
);
1226 async
function test_http2_folded_header(loadGroup
, serverPort
) {
1227 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/foldedheader`);
1228 chan
.loadGroup
= loadGroup
;
1229 return new Promise(resolve
=> {
1230 var listener
= new Http2CheckListener();
1231 listener
.finish
= resolve
;
1232 listener
.shouldSucceed
= false;
1233 chan
.asyncOpen(listener
);
1237 async
function test_http2_empty_data(serverPort
) {
1238 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/emptydata`);
1239 return new Promise(resolve
=> {
1240 var listener
= new Http2CheckListener();
1241 listener
.finish
= resolve
;
1242 chan
.asyncOpen(listener
);
1246 async
function test_http2_push_firstparty1(loadGroup
, serverPort
) {
1247 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push`);
1248 chan
.loadGroup
= loadGroup
;
1249 chan
.loadInfo
.originAttributes
= { firstPartyDomain
: "foo.com" };
1250 return new Promise(resolve
=> {
1251 var listener
= new Http2PushListener(true);
1252 listener
.finish
= resolve
;
1253 listener
.serverPort
= serverPort
;
1254 chan
.asyncOpen(listener
);
1258 async
function test_http2_push_firstparty2(loadGroup
, serverPort
) {
1259 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push.js`);
1260 chan
.loadGroup
= loadGroup
;
1261 chan
.loadInfo
.originAttributes
= { firstPartyDomain
: "bar.com" };
1262 return new Promise(resolve
=> {
1263 var listener
= new Http2PushListener(false);
1264 listener
.finish
= resolve
;
1265 listener
.serverPort
= serverPort
;
1266 chan
.asyncOpen(listener
);
1270 async
function test_http2_push_firstparty3(loadGroup
, serverPort
) {
1271 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push.js`);
1272 chan
.loadGroup
= loadGroup
;
1273 chan
.loadInfo
.originAttributes
= { firstPartyDomain
: "foo.com" };
1274 return new Promise(resolve
=> {
1275 var listener
= new Http2PushListener(true);
1276 listener
.finish
= resolve
;
1277 listener
.serverPort
= serverPort
;
1278 chan
.asyncOpen(listener
);
1282 async
function test_http2_push_userContext1(loadGroup
, serverPort
) {
1283 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push`);
1284 chan
.loadGroup
= loadGroup
;
1285 chan
.loadInfo
.originAttributes
= { userContextId
: 1 };
1286 return new Promise(resolve
=> {
1287 var listener
= new Http2PushListener(true);
1288 listener
.finish
= resolve
;
1289 listener
.serverPort
= serverPort
;
1290 chan
.asyncOpen(listener
);
1294 async
function test_http2_push_userContext2(loadGroup
, serverPort
) {
1295 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push.js`);
1296 chan
.loadGroup
= loadGroup
;
1297 chan
.loadInfo
.originAttributes
= { userContextId
: 2 };
1298 return new Promise(resolve
=> {
1299 var listener
= new Http2PushListener(false);
1300 listener
.finish
= resolve
;
1301 listener
.serverPort
= serverPort
;
1302 chan
.asyncOpen(listener
);
1306 async
function test_http2_push_userContext3(loadGroup
, serverPort
) {
1307 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/push.js`);
1308 chan
.loadGroup
= loadGroup
;
1309 chan
.loadInfo
.originAttributes
= { userContextId
: 1 };
1310 return new Promise(resolve
=> {
1311 var listener
= new Http2PushListener(true);
1312 listener
.finish
= resolve
;
1313 listener
.serverPort
= serverPort
;
1314 chan
.asyncOpen(listener
);
1318 async
function test_http2_status_phrase(serverPort
) {
1319 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/statusphrase`);
1320 return new Promise(resolve
=> {
1321 var listener
= new Http2CheckListener();
1322 listener
.finish
= resolve
;
1323 listener
.shouldSucceed
= false;
1324 chan
.asyncOpen(listener
);
1328 var PulledDiskCacheListener = function () {};
1329 PulledDiskCacheListener
.prototype = new Http2CheckListener();
1330 PulledDiskCacheListener
.prototype.EXPECTED_DATA
= "this was pulled via h2";
1331 PulledDiskCacheListener
.prototype.readData
= "";
1332 PulledDiskCacheListener
.prototype.onDataAvailable
=
1333 function testOnDataAvailable(request
, stream
, off
, cnt
) {
1334 this.onDataAvailableFired
= true;
1335 this.isHttp2Connection
= checkIsHttp2(request
);
1337 this.readData
+= read_stream(stream
, cnt
);
1339 PulledDiskCacheListener
.prototype.onStopRequest
= function testOnStopRequest(
1343 Assert
.equal(this.EXPECTED_DATA
, this.readData
);
1344 Http2CheckListener
.prorotype
.onStopRequest
.call(this, request
, status
);
1347 const DISK_CACHE_DATA
= "this is from disk cache";
1349 var FromDiskCacheListener = function (finish
, loadGroup
, serverPort
) {
1350 this.finish
= finish
;
1351 this.loadGroup
= loadGroup
;
1352 this.serverPort
= serverPort
;
1354 FromDiskCacheListener
.prototype = {
1355 onStartRequestFired
: false,
1356 onDataAvailableFired
: false,
1359 onStartRequest
: function testOnStartRequest(request
) {
1360 this.onStartRequestFired
= true;
1361 if (!Components
.isSuccessCode(request
.status
)) {
1362 do_throw("Channel should have a success code! (" + request
.status
+ ")");
1365 Assert
.ok(request
instanceof Ci
.nsIHttpChannel
);
1366 Assert
.ok(request
.requestSucceeded
);
1367 Assert
.equal(request
.responseStatus
, 200);
1370 onDataAvailable
: function testOnDataAvailable(request
, stream
, off
, cnt
) {
1371 this.onDataAvailableFired
= true;
1372 this.readData
+= read_stream(stream
, cnt
);
1375 onStopRequest
: function testOnStopRequest(request
, status
) {
1376 Assert
.ok(this.onStartRequestFired
);
1377 Assert
.ok(Components
.isSuccessCode(status
));
1378 Assert
.ok(this.onDataAvailableFired
);
1379 Assert
.equal(this.readData
, DISK_CACHE_DATA
);
1381 evict_cache_entries("disk");
1382 syncWithCacheIOThread(() => {
1383 // Now that we know the entry is out of the disk cache, check to make sure
1384 // we don't have this hiding in the push cache somewhere - if we do, it
1385 // didn't get cancelled, and we have a bug.
1386 var chan
= makeHTTPChannel(
1387 `https://localhost:${this.serverPort}/diskcache`
1389 var listener
= new PulledDiskCacheListener();
1390 listener
.finish
= this.finish
;
1391 chan
.loadGroup
= this.loadGroup
;
1392 chan
.asyncOpen(listener
);
1397 var Http2DiskCachePushListener = function () {};
1398 Http2DiskCachePushListener
.prototype = new Http2CheckListener();
1400 Http2DiskCachePushListener
.onStopRequest = function (request
, status
) {
1401 Assert
.ok(this.onStartRequestFired
);
1402 Assert
.ok(Components
.isSuccessCode(status
));
1403 Assert
.ok(this.onDataAvailableFired
);
1404 Assert
.ok(this.isHttp2Connection
== this.shouldBeHttp2
);
1406 // Now we need to open a channel to ensure we get data from the disk cache
1407 // for the pushed item, instead of from the push cache.
1408 var chan
= makeHTTPChannel(`https://localhost:${this.serverPort}/diskcache`);
1409 var listener
= new FromDiskCacheListener(
1414 chan
.loadGroup
= this.loadGroup
;
1415 chan
.asyncOpen(listener
);
1418 function continue_test_http2_disk_cache_push(
1425 // TODO - store stuff in cache entry, then open an h2 channel that will push
1426 // this, once that completes, open a channel for the cache entry we made and
1427 // ensure it came from disk cache, not the push cache.
1428 var outputStream
= entry
.openOutputStream(0, -1);
1429 outputStream
.write(DISK_CACHE_DATA
, DISK_CACHE_DATA
.length
);
1431 // Now we open our URL that will push data for the URL above
1432 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/pushindisk`);
1433 var listener
= new Http2DiskCachePushListener();
1434 listener
.finish
= finish
;
1435 listener
.loadGroup
= loadGroup
;
1436 listener
.serverPort
= serverPort
;
1437 chan
.loadGroup
= loadGroup
;
1438 chan
.asyncOpen(listener
);
1441 async
function test_http2_disk_cache_push(loadGroup
, serverPort
) {
1442 return new Promise(resolve
=> {
1443 asyncOpenCacheEntry(
1444 `https://localhost:${serverPort}/diskcache`,
1446 Ci
.nsICacheStorage
.OPEN_NORMALLY
,
1448 function (status
, entry
) {
1449 continue_test_http2_disk_cache_push(
1462 var Http2DoublepushListener = function () {};
1463 Http2DoublepushListener
.prototype = new Http2CheckListener();
1464 Http2DoublepushListener
.prototype.onStopRequest = function (request
, status
) {
1465 Assert
.ok(this.onStartRequestFired
);
1466 Assert
.ok(Components
.isSuccessCode(status
));
1467 Assert
.ok(this.onDataAvailableFired
);
1468 Assert
.ok(this.isHttp2Connection
== this.shouldBeHttp2
);
1470 var chan
= makeHTTPChannel(
1471 `https://localhost:${this.serverPort}/doublypushed`
1473 var listener
= new Http2DoublypushedListener();
1474 listener
.finish
= this.finish
;
1475 chan
.loadGroup
= this.loadGroup
;
1476 chan
.asyncOpen(listener
);
1479 var Http2DoublypushedListener = function () {};
1480 Http2DoublypushedListener
.prototype = new Http2CheckListener();
1481 Http2DoublypushedListener
.prototype.readData
= "";
1482 Http2DoublypushedListener
.prototype.onDataAvailable = function (
1488 this.onDataAvailableFired
= true;
1490 this.readData
+= read_stream(stream
, cnt
);
1492 Http2DoublypushedListener
.prototype.onStopRequest = function (request
, status
) {
1493 Assert
.ok(this.onStartRequestFired
);
1494 Assert
.ok(Components
.isSuccessCode(status
));
1495 Assert
.ok(this.onDataAvailableFired
);
1496 Assert
.equal(this.readData
, "pushed");
1498 request
.QueryInterface(Ci
.nsIProxiedChannel
);
1499 let httpProxyConnectResponseCode
= request
.httpProxyConnectResponseCode
;
1500 this.finish({ httpProxyConnectResponseCode
});
1503 function test_http2_doublepush(loadGroup
, serverPort
) {
1504 var chan
= makeHTTPChannel(`https://localhost:${serverPort}/doublepush`);
1505 return new Promise(resolve
=> {
1506 var listener
= new Http2DoublepushListener();
1507 listener
.finish
= resolve
;
1508 listener
.loadGroup
= loadGroup
;
1509 listener
.serverPort
= serverPort
;
1510 chan
.loadGroup
= loadGroup
;
1511 chan
.asyncOpen(listener
);