tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_proxy-slow-upload.js (3902B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  NodeHTTPProxyServer,
      9  NodeHTTPSProxyServer,
     10  NodeHTTP2ProxyServer,
     11  with_node_servers,
     12  NodeHTTPServer,
     13  NodeHTTPSServer,
     14  NodeHTTP2Server,
     15 } = ChromeUtils.importESModule("resource://testing-common/NodeServer.sys.mjs");
     16 
     17 /* import-globals-from head_cache.js */
     18 /* import-globals-from head_cookies.js */
     19 /* import-globals-from head_channels.js */
     20 
     21 // We don't normally allow localhost channels to be proxied, but this
     22 // is easier than updating all the certs and/or domains.
     23 Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true);
     24 registerCleanupFunction(() => {
     25  Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost");
     26 });
     27 
     28 const SIZE = 4096;
     29 const CONTENT = "x".repeat(SIZE);
     30 
     31 add_task(async function test_slow_upload() {
     32  let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
     33    Ci.nsIX509CertDB
     34  );
     35  addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
     36  addCertFromFile(certdb, "proxy-ca.pem", "CTu,u,u");
     37 
     38  let proxies = [
     39    NodeHTTPProxyServer,
     40    NodeHTTPSProxyServer,
     41    NodeHTTP2ProxyServer,
     42  ];
     43  for (let p of proxies) {
     44    let proxy = new p();
     45    await proxy.start();
     46    registerCleanupFunction(async () => {
     47      await proxy.stop();
     48    });
     49 
     50    await with_node_servers(
     51      [NodeHTTPServer, NodeHTTPSServer, NodeHTTP2Server],
     52      async server => {
     53        info(`Testing ${p.name} with ${server.constructor.name}`);
     54        await server.execute(
     55          `global.server_name = "${server.constructor.name}";`
     56        );
     57        await server.registerPathHandler("/test", (req, resp) => {
     58          let content = "";
     59          req.on("data", data => {
     60            global.data_count = (global.data_count || 0) + 1;
     61            content += data;
     62          });
     63          req.on("end", () => {
     64            resp.writeHead(200);
     65            resp.end(content);
     66          });
     67        });
     68 
     69        let sstream = Cc[
     70          "@mozilla.org/io/string-input-stream;1"
     71        ].createInstance(Ci.nsIStringInputStream);
     72        sstream.setByteStringData(CONTENT);
     73 
     74        let mime = Cc[
     75          "@mozilla.org/network/mime-input-stream;1"
     76        ].createInstance(Ci.nsIMIMEInputStream);
     77        mime.addHeader("Content-Type", "multipart/form-data; boundary=zzzzz");
     78        mime.setData(sstream);
     79 
     80        let tq = Cc["@mozilla.org/network/throttlequeue;1"].createInstance(
     81          Ci.nsIInputChannelThrottleQueue
     82        );
     83        // Make sure the request takes more than one read.
     84        tq.init(100 + SIZE / 2, 100 + SIZE / 2);
     85 
     86        let chan = NetUtil.newChannel({
     87          uri: `${server.origin()}/test`,
     88          loadUsingSystemPrincipal: true,
     89        }).QueryInterface(Ci.nsIHttpChannel);
     90 
     91        let tic = chan.QueryInterface(Ci.nsIThrottledInputChannel);
     92        tic.throttleQueue = tq;
     93 
     94        chan
     95          .QueryInterface(Ci.nsIUploadChannel)
     96          .setUploadStream(mime, "", mime.available());
     97        chan.requestMethod = "POST";
     98 
     99        let { req, buff } = await new Promise(resolve => {
    100          chan.asyncOpen(
    101            new ChannelListener(
    102              (req1, buff1) => resolve({ req: req1, buff: buff1 }),
    103              null,
    104              CL_ALLOW_UNKNOWN_CL
    105            )
    106          );
    107        });
    108        equal(req.status, Cr.NS_OK);
    109        equal(req.QueryInterface(Ci.nsIHttpChannel).responseStatus, 200);
    110        Assert.equal(buff, CONTENT, "Content must match");
    111        ok(!!req.QueryInterface(Ci.nsIProxiedChannel).proxyInfo);
    112        greater(
    113          await server.execute(`global.data_count`),
    114          1,
    115          "Content should have been streamed to the server in several chunks"
    116        );
    117      }
    118    );
    119    await proxy.stop();
    120  }
    121 });