77
88"use strict" ;
99
10- var h2Port ;
11- var prefs ;
12- var http2pref ;
10+ const { NodeHTTP2Server } = ChromeUtils . importESModule (
11+ "resource://testing-common/NodeServer.sys.mjs"
12+ ) ;
1313
14- function run_test ( ) {
15- h2Port = Services . env . get ( "MOZHTTP2_PORT" ) ;
16- Assert . notEqual ( h2Port , null ) ;
17- Assert . notEqual ( h2Port , "" ) ;
14+ let server ;
1815
19- // Set to allow the cert presented by our H2 server
16+ add_setup ( async function test_setup ( ) {
2017 do_get_profile ( ) ;
21- prefs = Services . prefs ;
22-
23- http2pref = prefs . getBoolPref ( "network.http.http2.enabled" ) ;
24-
25- prefs . setBoolPref ( "network.http.http2.enabled" , true ) ;
26- prefs . setCharPref (
27- "network.dns.localDomains" ,
28- "foo.example.com, alt1.example.com"
29- ) ;
30-
31- // The moz-http2 cert is for {foo, alt1, alt2}.example.com and is signed by http2-ca.pem
32- // so add that cert to the trust list as a signing cert.
33- let certdb = Cc [ "@mozilla.org/security/x509certdb;1" ] . getService (
34- Ci . nsIX509CertDB
35- ) ;
36- addCertFromFile ( certdb , "http2-ca.pem" , "CTu,u,u" ) ;
37-
38- doTest1 ( ) ;
39- }
40-
41- function resetPrefs ( ) {
42- prefs . setBoolPref ( "network.http.http2.enabled" , http2pref ) ;
43- prefs . clearUserPref ( "network.dns.localDomains" ) ;
44- }
18+ Services . prefs . setBoolPref ( "network.http.http2.enabled" , true ) ;
19+ Services . prefs . setCharPref ( "network.dns.localDomains" , "foo.example.com" ) ;
20+
21+ server = new NodeHTTP2Server ( ) ;
22+ await server . start ( ) ;
23+ registerCleanupFunction ( async ( ) => {
24+ await server . stop ( ) ;
25+ } ) ;
26+
27+ // Register path handlers for all test endpoints - copy from moz-http2.js
28+ await server . registerPathHandler ( "/origin-1" , ( req , resp ) => {
29+ resp . setHeader ( "x-client-port" , req . socket . remotePort ) ;
30+ resp . writeHead ( 200 , { "Content-Type" : "text/plain" } ) ;
31+ resp . end ( "origin-1" ) ;
32+ } ) ;
33+ await server . registerPathHandler ( "/origin-2" , ( req , resp ) => {
34+ resp . setHeader ( "x-client-port" , req . socket . remotePort ) ;
35+ resp . writeHead ( 200 , { "Content-Type" : "text/plain" } ) ;
36+ resp . end ( "origin-2" ) ;
37+ } ) ;
38+ await server . registerPathHandler ( "/origin-3" , ( req , resp ) => {
39+ resp . setHeader ( "x-client-port" , req . socket . remotePort ) ;
40+ resp . writeHead ( 200 , { "Content-Type" : "text/plain" } ) ;
41+ resp . end ( "origin-3" ) ;
42+ } ) ;
43+ await server . registerPathHandler ( "/origin-4" , ( req , resp ) => {
44+ resp . setHeader ( "x-client-port" , req . socket . remotePort ) ;
45+ resp . writeHead ( 200 , { "Content-Type" : "text/plain" } ) ;
46+ resp . end ( "origin-4" ) ;
47+ } ) ;
48+ } ) ;
49+
50+ registerCleanupFunction ( ( ) => {
51+ Services . prefs . clearUserPref ( "network.http.http2.enabled" ) ;
52+ Services . prefs . clearUserPref ( "network.dns.localDomains" ) ;
53+ } ) ;
4554
4655function makeChan ( origin ) {
4756 return NetUtil . newChannel ( {
@@ -50,126 +59,67 @@ function makeChan(origin) {
5059 } ) . QueryInterface ( Ci . nsIHttpChannel ) ;
5160}
5261
53- var nextTest ;
54- var origin ;
55- var nextPortExpectedToBeSame = false ;
56- var currentPort = 0 ;
57- var forceReload = false ;
58- var anonymous = false ;
59-
60- var Listener = function ( ) { } ;
61- Listener . prototype . clientPort = 0 ;
62- Listener . prototype = {
63- onStartRequest : function testOnStartRequest ( request ) {
64- Assert . ok ( request instanceof Ci . nsIHttpChannel ) ;
65-
66- if ( ! Components . isSuccessCode ( request . status ) ) {
67- do_throw ( "Channel should have a success code! (" + request . status + ")" ) ;
68- }
69- Assert . equal ( request . responseStatus , 200 ) ;
70- this . clientPort = parseInt ( request . getResponseHeader ( "x-client-port" ) ) ;
71- } ,
72-
73- onDataAvailable : function testOnDataAvailable ( request , stream , off , cnt ) {
74- read_stream ( stream , cnt ) ;
75- } ,
76-
77- onStopRequest : function testOnStopRequest ( request , status ) {
78- Assert . ok ( Components . isSuccessCode ( status ) ) ;
79- if ( nextPortExpectedToBeSame ) {
80- Assert . equal ( currentPort , this . clientPort ) ;
81- } else {
82- Assert . notEqual ( currentPort , this . clientPort ) ;
62+ function channelOpenPromise ( chan , loadFlags = 0 ) {
63+ return new Promise ( ( resolve , reject ) => {
64+ chan . loadFlags = Ci . nsIChannel . LOAD_INITIAL_DOCUMENT_URI | loadFlags ;
65+
66+ function finish ( req , buffer ) {
67+ try {
68+ Assert . ok ( req instanceof Ci . nsIHttpChannel ) ;
69+ Assert . ok ( Components . isSuccessCode ( req . status ) ) ;
70+ Assert . equal ( req . responseStatus , 200 ) ;
71+ const clientPort = parseInt ( req . getResponseHeader ( "x-client-port" ) ) ;
72+ resolve ( { req, buffer, clientPort } ) ;
73+ } catch ( e ) {
74+ reject ( e ) ;
75+ }
8376 }
84- currentPort = this . clientPort ;
85- nextTest ( ) ;
86- do_test_finished ( ) ;
87- } ,
88- } ;
89-
90- function testsDone ( ) {
91- dump ( "testsDone\n" ) ;
92- resetPrefs ( ) ;
93- }
94-
95- function doTest ( ) {
96- dump ( "execute doTest " + origin + "\n" ) ;
97-
98- var loadFlags = Ci . nsIChannel . LOAD_INITIAL_DOCUMENT_URI ;
99- if ( anonymous ) {
100- loadFlags |= Ci . nsIRequest . LOAD_ANONYMOUS ;
101- }
102- anonymous = false ;
103- if ( forceReload ) {
104- loadFlags |= Ci . nsIRequest . LOAD_FRESH_CONNECTION ;
105- }
106- forceReload = false ;
10777
108- var chan = makeChan ( origin ) ;
109- chan . loadFlags = loadFlags ;
110-
111- var listener = new Listener ( ) ;
112- chan . asyncOpen ( listener ) ;
113- }
114-
115- function doTest1 ( ) {
116- dump ( "doTest1()\n" ) ;
117- origin = "https://foo.example.com:" + h2Port + "/origin-1" ;
118- nextTest = doTest2 ;
119- nextPortExpectedToBeSame = false ;
120- do_test_pending ( ) ;
121- doTest ( ) ;
122- }
123-
124- function doTest2 ( ) {
125- // Run the same test as above to make sure connection is marked experienced.
126- dump ( "doTest2()\n" ) ;
127- origin = "https://foo.example.com:" + h2Port + "/origin-1" ;
128- nextTest = doTest3 ;
129- nextPortExpectedToBeSame = true ;
130- do_test_pending ( ) ;
131- doTest ( ) ;
132- }
133-
134- function doTest3 ( ) {
135- // connection expected to be reused for an anonymous request
136- dump ( "doTest3()\n" ) ;
137- origin = "https://foo.example.com:" + h2Port + "/origin-2" ;
138- nextTest = doTest4 ;
139- nextPortExpectedToBeSame = true ;
140- anonymous = true ;
141- do_test_pending ( ) ;
142- doTest ( ) ;
78+ chan . asyncOpen ( new ChannelListener ( finish , null , CL_ALLOW_UNKNOWN_CL ) ) ;
79+ } ) ;
14380}
14481
145- function doTest4 ( ) {
146- dump ( "doTest4()\n" ) ;
147- origin = "https://foo.example.com:" + h2Port + "/origin-3" ;
148- nextTest = doTest5 ;
149- nextPortExpectedToBeSame = false ;
150- forceReload = true ;
151- anonymous = true ;
152- do_test_pending ( ) ;
153- doTest ( ) ;
154- }
155-
156- function doTest5 ( ) {
157- // Run the same test as above just without forceReload to make sure connection
158- // is marked experienced.
159- dump ( "doTest5()\n" ) ;
160- origin = "https://foo.example.com:" + h2Port + "/origin-3" ;
161- nextTest = doTest6 ;
162- nextPortExpectedToBeSame = true ;
163- anonymous = true ;
164- do_test_pending ( ) ;
165- doTest ( ) ;
166- }
167-
168- function doTest6 ( ) {
169- dump ( "doTest6()\n" ) ;
170- origin = "https://foo.example.com:" + h2Port + "/origin-4" ;
171- nextTest = testsDone ;
172- nextPortExpectedToBeSame = true ;
173- do_test_pending ( ) ;
174- doTest ( ) ;
175- }
82+ add_task ( async function test_anonymous_coalescing_sequence ( ) {
83+ let currentPort = 0 ;
84+
85+ // Test 1: First non-anonymous request
86+ info ( "Test 1: First non-anonymous request" ) ;
87+ let chan = makeChan ( `https://foo.example.com:${ server . port ( ) } /origin-1` ) ;
88+ let result = await channelOpenPromise ( chan ) ;
89+ Assert . notEqual ( currentPort , result . clientPort ) ;
90+ currentPort = result . clientPort ;
91+
92+ // Test 2: Same request to mark connection as experienced
93+ info ( "Test 2: Second non-anonymous request (same endpoint)" ) ;
94+ chan = makeChan ( `https://foo.example.com:${ server . port ( ) } /origin-1` ) ;
95+ result = await channelOpenPromise ( chan ) ;
96+ Assert . equal ( currentPort , result . clientPort ) ;
97+
98+ // Test 3: Anonymous request should reuse connection
99+ info ( "Test 3: Anonymous request should reuse connection" ) ;
100+ chan = makeChan ( `https://foo.example.com:${ server . port ( ) } /origin-2` ) ;
101+ result = await channelOpenPromise ( chan , Ci . nsIRequest . LOAD_ANONYMOUS ) ;
102+ Assert . equal ( currentPort , result . clientPort ) ;
103+
104+ // Test 4: Force new connection with anonymous request
105+ info ( "Test 4: Force new connection with anonymous request" ) ;
106+ chan = makeChan ( `https://foo.example.com:${ server . port ( ) } /origin-3` ) ;
107+ result = await channelOpenPromise (
108+ chan ,
109+ Ci . nsIRequest . LOAD_ANONYMOUS | Ci . nsIRequest . LOAD_FRESH_CONNECTION
110+ ) ;
111+ Assert . notEqual ( currentPort , result . clientPort ) ;
112+ currentPort = result . clientPort ;
113+
114+ // Test 5: Same anonymous request to mark connection as experienced
115+ info ( "Test 5: Same anonymous request (mark connection experienced)" ) ;
116+ chan = makeChan ( `https://foo.example.com:${ server . port ( ) } /origin-3` ) ;
117+ result = await channelOpenPromise ( chan , Ci . nsIRequest . LOAD_ANONYMOUS ) ;
118+ Assert . equal ( currentPort , result . clientPort ) ;
119+
120+ // Test 6: Non-anonymous request should reuse connection
121+ info ( "Test 6: Non-anonymous request should reuse connection" ) ;
122+ chan = makeChan ( `https://foo.example.com:${ server . port ( ) } /origin-4` ) ;
123+ result = await channelOpenPromise ( chan ) ;
124+ Assert . equal ( currentPort , result . clientPort ) ;
125+ } ) ;
0 commit comments