tor-browser

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

test_traceable_channel.js (4162B)


      1 "use strict";
      2 
      3 // Test nsITraceableChannel interface.
      4 // Replace original listener with TracingListener that modifies body of HTTP
      5 // response. Make sure that body received by original channel's listener
      6 // is correctly modified.
      7 
      8 const { HttpServer } = ChromeUtils.importESModule(
      9  "resource://testing-common/httpd.sys.mjs"
     10 );
     11 
     12 var httpserver = new HttpServer();
     13 httpserver.start(-1);
     14 const PORT = httpserver.identity.primaryPort;
     15 
     16 var pipe = null;
     17 var streamSink = null;
     18 
     19 var originalBody = "original http response body";
     20 var gotOnStartRequest = false;
     21 
     22 function TracingListener() {}
     23 
     24 TracingListener.prototype = {
     25  onStartRequest(request) {
     26    dump("*** tracing listener onStartRequest\n");
     27 
     28    gotOnStartRequest = true;
     29 
     30    request.QueryInterface(Ci.nsIHttpChannelInternal);
     31 
     32    // local/remote addresses broken in e10s: disable for now
     33    Assert.equal(request.localAddress, "127.0.0.1");
     34    Assert.equal(request.localPort > 0, true);
     35    Assert.notEqual(request.localPort, PORT);
     36    Assert.equal(request.remoteAddress, "127.0.0.1");
     37    Assert.equal(request.remotePort, PORT);
     38 
     39    // Make sure listener can't be replaced after OnStartRequest was called.
     40    request.QueryInterface(Ci.nsITraceableChannel);
     41    try {
     42      var newListener = new TracingListener();
     43      newListener.listener = request.setNewListener(newListener);
     44    } catch (e) {
     45      dump("TracingListener.onStartRequest swallowing exception: " + e + "\n");
     46      return; // OK
     47    }
     48    do_throw("replaced channel's listener during onStartRequest.");
     49  },
     50 
     51  onStopRequest() {
     52    dump("*** tracing listener onStopRequest\n");
     53 
     54    Assert.equal(gotOnStartRequest, true);
     55 
     56    try {
     57      var sin = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
     58        Ci.nsIScriptableInputStream
     59      );
     60 
     61      streamSink.close();
     62      var input = pipe.inputStream;
     63      sin.init(input);
     64      Assert.equal(sin.available(), originalBody.length);
     65 
     66      var result = sin.read(originalBody.length);
     67      Assert.equal(result, originalBody);
     68 
     69      input.close();
     70    } catch (e) {
     71      dump("TracingListener.onStopRequest swallowing exception: " + e + "\n");
     72    } finally {
     73      httpserver.stop(do_test_finished);
     74    }
     75  },
     76 
     77  QueryInterface: ChromeUtils.generateQI(["nsIRequestObserver"]),
     78 
     79  listener: null,
     80 };
     81 
     82 function HttpResponseExaminer() {}
     83 
     84 HttpResponseExaminer.prototype = {
     85  register() {
     86    Services.obs.addObserver(this, "http-on-examine-response", true);
     87    dump("Did HttpResponseExaminer.register\n");
     88  },
     89 
     90  // Replace channel's listener.
     91  observe(subject) {
     92    dump("In HttpResponseExaminer.observe\n");
     93    try {
     94      subject.QueryInterface(Ci.nsITraceableChannel);
     95 
     96      var tee = Cc["@mozilla.org/network/stream-listener-tee;1"].createInstance(
     97        Ci.nsIStreamListenerTee
     98      );
     99      var newListener = new TracingListener();
    100      pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
    101      pipe.init(false, false, 0, 0xffffffff, null);
    102      streamSink = pipe.outputStream;
    103 
    104      var originalListener = subject.setNewListener(tee);
    105      tee.init(originalListener, streamSink, newListener);
    106    } catch (e) {
    107      do_throw("can't replace listener " + e);
    108    }
    109    dump("Did HttpResponseExaminer.observe\n");
    110  },
    111 
    112  QueryInterface: ChromeUtils.generateQI([
    113    "nsIObserver",
    114    "nsISupportsWeakReference",
    115  ]),
    116 };
    117 
    118 function test_handler(metadata, response) {
    119  response.setHeader("Content-Type", "text/html", false);
    120  response.setStatusLine(metadata.httpVersion, 200, "OK");
    121  response.bodyOutputStream.write(originalBody, originalBody.length);
    122 }
    123 
    124 function make_channel(url) {
    125  return NetUtil.newChannel({
    126    uri: url,
    127    loadUsingSystemPrincipal: true,
    128  }).QueryInterface(Ci.nsIHttpChannel);
    129 }
    130 
    131 // Check if received body is correctly modified.
    132 function channel_finished() {
    133  httpserver.stop(do_test_finished);
    134 }
    135 
    136 function run_test() {
    137  var observer = new HttpResponseExaminer();
    138  observer.register();
    139 
    140  httpserver.registerPathHandler("/testdir", test_handler);
    141 
    142  var channel = make_channel("http://localhost:" + PORT + "/testdir");
    143  channel.asyncOpen(new ChannelListener(channel_finished));
    144  do_test_pending();
    145 }