Bug 1845311 - [Part 2] Use ChromeUtils.defineLazyGetter in more places r=arai,webcomp...
[gecko.git] / netwerk / test / unit / test_http2-proxy-failing.js
blob8530f55373e0efc16689cfe651cc6a39c60e2d2f
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Test stream failure on the session to the proxy:
8  *  - Test the case the error closes the affected stream only
9  *  - Test the case the error closes the whole session and cancels existing
10  *    streams.
11  */
13 /* eslint-env node */
15 "use strict";
17 const pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
19 let filter;
21 class ProxyFilter {
22   constructor(type, host, port, flags) {
23     this._type = type;
24     this._host = host;
25     this._port = port;
26     this._flags = flags;
27     this.QueryInterface = ChromeUtils.generateQI(["nsIProtocolProxyFilter"]);
28   }
29   applyFilter(uri, pi, cb) {
30     cb.onProxyFilterResult(
31       pps.newProxyInfo(
32         this._type,
33         this._host,
34         this._port,
35         null,
36         null,
37         this._flags,
38         1000,
39         null
40       )
41     );
42   }
45 function createPrincipal(url) {
46   var ssm = Services.scriptSecurityManager;
47   try {
48     return ssm.createContentPrincipal(Services.io.newURI(url), {});
49   } catch (e) {
50     return null;
51   }
54 function make_channel(url) {
55   return Services.io.newChannelFromURIWithProxyFlags(
56     Services.io.newURI(url),
57     null,
58     16,
59     null,
60     createPrincipal(url),
61     createPrincipal(url),
62     Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT,
63     Ci.nsIContentPolicy.TYPE_OTHER
64   );
67 function get_response(channel, flags = CL_ALLOW_UNKNOWN_CL, delay = 0) {
68   return new Promise(resolve => {
69     var listener = new ChannelListener(
70       (request, data) => {
71         request.QueryInterface(Ci.nsIHttpChannel);
72         const status = request.status;
73         const http_code = status ? undefined : request.responseStatus;
74         request.QueryInterface(Ci.nsIProxiedChannel);
75         const proxy_connect_response_code =
76           request.httpProxyConnectResponseCode;
77         resolve({ status, http_code, data, proxy_connect_response_code });
78       },
79       null,
80       flags
81     );
82     if (delay > 0) {
83       do_timeout(delay, function () {
84         channel.asyncOpen(listener);
85       });
86     } else {
87       channel.asyncOpen(listener);
88     }
89   });
92 add_task(async function setup() {
93   // Set to allow the cert presented by our H2 server
94   do_get_profile();
96   // The moz-http2 cert is for foo.example.com and is signed by http2-ca.pem
97   // so add that cert to the trust list as a signing cert.
98   let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
99     Ci.nsIX509CertDB
100   );
101   addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
103   let proxy_port = Services.env.get("MOZHTTP2_PORT");
104   Assert.notEqual(proxy_port, null);
106   Services.prefs.setBoolPref("network.http.http2.enabled", true);
107   // make all native resolve calls "secretly" resolve localhost instead
108   Services.prefs.setBoolPref("network.dns.native-is-localhost", true);
110   filter = new ProxyFilter("https", "localhost", proxy_port, 16);
111   pps.registerFilter(filter, 10);
114 registerCleanupFunction(async () => {
115   Services.prefs.clearUserPref("network.http.http2.enabled");
116   Services.prefs.clearUserPref("network.dns.native-is-localhost");
118   pps.unregisterFilter(filter);
121 add_task(
122   async function proxy_server_stream_soft_failure_multiple_streams_not_affected() {
123     let should_succeed = get_response(make_channel(`http://750.example.com`));
124     const failed = await get_response(
125       make_channel(`http://illegalhpacksoft.example.com`),
126       CL_EXPECT_FAILURE,
127       20
128     );
130     const succeeded = await should_succeed;
132     Assert.equal(failed.status, Cr.NS_ERROR_ILLEGAL_VALUE);
133     Assert.equal(failed.proxy_connect_response_code, 0);
134     Assert.equal(failed.http_code, undefined);
135     Assert.equal(succeeded.status, Cr.NS_OK);
136     Assert.equal(succeeded.proxy_connect_response_code, 200);
137     Assert.equal(succeeded.http_code, 200);
138   }
141 add_task(
142   async function proxy_server_stream_hard_failure_multiple_streams_affected() {
143     let should_failed = get_response(
144       make_channel(`http://750.example.com`),
145       CL_EXPECT_FAILURE
146     );
147     const failed1 = await get_response(
148       make_channel(`http://illegalhpackhard.example.com`),
149       CL_EXPECT_FAILURE
150     );
152     const failed2 = await should_failed;
154     Assert.equal(failed1.status, 0x804b0053);
155     Assert.equal(failed1.proxy_connect_response_code, 0);
156     Assert.equal(failed1.http_code, undefined);
157     Assert.equal(failed2.status, 0x804b0053);
158     Assert.equal(failed2.proxy_connect_response_code, 0);
159     Assert.equal(failed2.http_code, undefined);
160   }
163 add_task(async function test_http2_h11required_stream() {
164   let should_failed = await get_response(
165     make_channel(`http://h11required.com`),
166     CL_EXPECT_FAILURE
167   );
169   // See HTTP/1.1 connect handler in moz-http2.js. The handler returns
170   // "404 Not Found", so the expected error code is NS_ERROR_UNKNOWN_HOST.
171   Assert.equal(should_failed.status, Cr.NS_ERROR_UNKNOWN_HOST);
172   Assert.equal(should_failed.proxy_connect_response_code, 404);
173   Assert.equal(should_failed.http_code, undefined);