summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_http3_prio_helpers.js
blob: c1f6d06bcb627621977c4bc78cf6cf666952ea0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// uses head_http3.js, which uses http2-ca.pem
"use strict";

/* exported inChildProcess, test_flag_priority */
function inChildProcess() {
  return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}

let Http3Listener = function (
  closure,
  expected_priority,
  expected_incremental,
  context
) {
  this._closure = closure;
  this._expected_priority = expected_priority;
  this._expected_incremental = expected_incremental;
  this._context = context;
};

// string -> [string, bool]
// "u=3,i" -> ["u=3", true]
function parse_priority_response_header(priority) {
  const priority_array = priority.split(",");

  // parse for urgency string
  const urgency = priority_array.find(element => element.includes("u="));

  // parse for incremental bool
  const incremental = !!priority_array.find(element => element == "i");

  return [urgency ? urgency : null, incremental];
}

Http3Listener.prototype = {
  resumed: false,

  onStartRequest: function testOnStartRequest(request) {
    Assert.equal(request.status, Cr.NS_OK);
    Assert.equal(request.responseStatus, 200);

    let secinfo = request.securityInfo;
    Assert.equal(secinfo.resumed, this.resumed);
    Assert.ok(secinfo.serverCert != null);

    // check priority urgency and incremental from response header
    let priority_urgency = null;
    let incremental = null;
    try {
      const prh = request.getResponseHeader("priority-mirror");
      [priority_urgency, incremental] = parse_priority_response_header(prh);
    } catch (e) {
      console.log("Failed to get priority-mirror from response header");
    }
    Assert.equal(priority_urgency, this._expected_priority, this._context);
    Assert.equal(incremental, this._expected_incremental, this._context);
  },

  onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
    read_stream(stream, cnt);
  },

  onStopRequest: function testOnStopRequest(request, status) {
    let httpVersion = "";
    try {
      httpVersion = request.protocolVersion;
    } catch (e) {}
    Assert.equal(httpVersion, "h3-29");

    try {
      this._closure();
    } catch (ex) {
      do_throw("Error in closure function: " + ex);
    }
  },
};

function make_channel(url) {
  var request = NetUtil.newChannel({
    uri: url,
    loadUsingSystemPrincipal: true,
  });
  request.QueryInterface(Ci.nsIHttpChannel);
  return request;
}

async function test_flag_priority(
  context,
  flag,
  expected_priority,
  incremental,
  expected_incremental
) {
  var chan = make_channel("https://foo.example.com/priority_mirror");
  var cos = chan.QueryInterface(Ci.nsIClassOfService);

  // configure the channel with flags
  if (flag != null) {
    cos.addClassFlags(flag);
  }

  // configure the channel with incremental
  if (incremental != null) {
    cos.incremental = incremental;
  }

  await new Promise(resolve =>
    chan.asyncOpen(
      new Http3Listener(
        resolve,
        expected_priority,
        expected_incremental,
        context
      )
    )
  );
}