tor-browser

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

test_bug1355539_http1.js (5307B)


      1 // test bug 1355539.
      2 //
      3 // Summary:
      4 // Transactions in one pending queue are splited into two groups:
      5 // [(Blocking Group)|(Non Blocking Group)]
      6 // In each group, the transactions are ordered by its priority.
      7 // This test will check if the transaction's order in pending queue is correct.
      8 //
      9 // Test step:
     10 // 1. Create 6 dummy http requests. Server would not process responses until get
     11 //    all 6 requests.
     12 // 2. Once server receive 6 dummy requests, create another 6 http requests with the
     13 //    defined priority and class flag in |transactionQueue|.
     14 // 3. Server starts to process the 6 dummy http requests, so the client can start to
     15 //    process the pending queue. Server will queue those http requests and put them in
     16 //    |responseQueue|.
     17 // 4. When the server receive all 6 requests, check if the order in |responseQueue| is
     18 //    equal to |transactionQueue| by comparing the value of X-ID.
     19 
     20 "use strict";
     21 
     22 const { HttpServer } = ChromeUtils.importESModule(
     23  "resource://testing-common/httpd.sys.mjs"
     24 );
     25 
     26 var server = new HttpServer();
     27 server.start(-1);
     28 var baseURL = "http://localhost:" + server.identity.primaryPort + "/";
     29 var maxConnections = 0;
     30 var debug = false;
     31 var dummyResponseQueue = [];
     32 var responseQueue = [];
     33 
     34 function log(msg) {
     35  if (!debug) {
     36    return;
     37  }
     38 
     39  if (msg) {
     40    dump("TEST INFO | " + msg + "\n");
     41  }
     42 }
     43 
     44 function make_channel(url) {
     45  var request = NetUtil.newChannel({
     46    uri: url,
     47    loadUsingSystemPrincipal: true,
     48  });
     49  request.QueryInterface(Ci.nsIHttpChannel);
     50  return request;
     51 }
     52 
     53 function serverStopListener() {
     54  server.stop();
     55 }
     56 
     57 function createHttpRequest(requestId, priority, isBlocking, callback) {
     58  let uri = baseURL;
     59  var chan = make_channel(uri);
     60  var listner = new HttpResponseListener(requestId, callback);
     61  chan.setRequestHeader("X-ID", requestId, false);
     62  chan.setRequestHeader("Cache-control", "no-store", false);
     63  chan.QueryInterface(Ci.nsISupportsPriority).priority = priority;
     64  if (isBlocking) {
     65    var cos = chan.QueryInterface(Ci.nsIClassOfService);
     66    cos.addClassFlags(Ci.nsIClassOfService.Leader);
     67  }
     68  chan.asyncOpen(listner);
     69  log("Create http request id=" + requestId);
     70 }
     71 
     72 function setup_dummyHttpRequests(callback) {
     73  log("setup_dummyHttpRequests");
     74  for (var i = 0; i < maxConnections; i++) {
     75    createHttpRequest(i, i, false, callback);
     76    do_test_pending();
     77  }
     78 }
     79 
     80 var transactionQueue = [
     81  {
     82    requestId: 101,
     83    priority: Ci.nsISupportsPriority.PRIORITY_HIGH,
     84    isBlocking: true,
     85  },
     86  {
     87    requestId: 102,
     88    priority: Ci.nsISupportsPriority.PRIORITY_NORMAL,
     89    isBlocking: true,
     90  },
     91  {
     92    requestId: 103,
     93    priority: Ci.nsISupportsPriority.PRIORITY_LOW,
     94    isBlocking: true,
     95  },
     96  {
     97    requestId: 104,
     98    priority: Ci.nsISupportsPriority.PRIORITY_HIGH,
     99    isBlocking: false,
    100  },
    101  {
    102    requestId: 105,
    103    priority: Ci.nsISupportsPriority.PRIORITY_NORMAL,
    104    isBlocking: false,
    105  },
    106  {
    107    requestId: 106,
    108    priority: Ci.nsISupportsPriority.PRIORITY_LOW,
    109    isBlocking: false,
    110  },
    111 ];
    112 
    113 function setup_HttpRequests() {
    114  log("setup_HttpRequests");
    115  // Create channels in reverse order
    116  for (var i = transactionQueue.length - 1; i > -1; ) {
    117    var e = transactionQueue[i];
    118    createHttpRequest(e.requestId, e.priority, e.isBlocking);
    119    do_test_pending();
    120    --i;
    121  }
    122 }
    123 
    124 function check_response_id(responses) {
    125  for (var i = 0; i < responses.length; i++) {
    126    var id = responses[i].getHeader("X-ID");
    127    Assert.equal(id, transactionQueue[i].requestId);
    128  }
    129 }
    130 
    131 function HttpResponseListener(id, onStopCallback) {
    132  this.id = id;
    133  this.stopCallback = onStopCallback;
    134 }
    135 
    136 HttpResponseListener.prototype = {
    137  onStartRequest() {},
    138 
    139  onDataAvailable() {},
    140 
    141  onStopRequest() {
    142    log("STOP id=" + this.id);
    143    do_test_finished();
    144    if (this.stopCallback) {
    145      this.stopCallback();
    146    }
    147  },
    148 };
    149 
    150 function setup_http_server() {
    151  log("setup_http_server");
    152  maxConnections = Services.prefs.getIntPref(
    153    "network.http.max-persistent-connections-per-server"
    154  );
    155 
    156  var allDummyHttpRequestReceived = false;
    157  // Start server; will be stopped at test cleanup time.
    158  server.registerPathHandler("/", function (metadata, response) {
    159    var id = metadata.getHeader("X-ID");
    160    log("Server recived the response id=" + id);
    161 
    162    response.processAsync();
    163    response.setHeader("X-ID", id);
    164 
    165    if (!allDummyHttpRequestReceived) {
    166      dummyResponseQueue.push(response);
    167    } else {
    168      responseQueue.push(response);
    169    }
    170 
    171    if (dummyResponseQueue.length == maxConnections) {
    172      log("received all dummy http requets");
    173      allDummyHttpRequestReceived = true;
    174      setup_HttpRequests();
    175      processDummyResponse();
    176    } else if (responseQueue.length == maxConnections) {
    177      log("received all http requets");
    178      check_response_id(responseQueue);
    179      processResponses();
    180    }
    181  });
    182 
    183  registerCleanupFunction(function () {
    184    server.stop(serverStopListener);
    185  });
    186 }
    187 
    188 function processDummyResponse() {
    189  if (!dummyResponseQueue.length) {
    190    return;
    191  }
    192  var resposne = dummyResponseQueue.pop();
    193  resposne.finish();
    194 }
    195 
    196 function processResponses() {
    197  while (responseQueue.length) {
    198    var resposne = responseQueue.pop();
    199    resposne.finish();
    200  }
    201 }
    202 
    203 function run_test() {
    204  setup_http_server();
    205  setup_dummyHttpRequests(processDummyResponse);
    206 }