summaryrefslogtreecommitdiffstats
path: root/dom/reporting/tests/delivering.sjs
blob: 9d378a9c82306f83f2a108ed717fadfe309d03b7 (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
const CC = Components.Constructor;
const BinaryInputStream = CC(
  "@mozilla.org/binaryinputstream;1",
  "nsIBinaryInputStream",
  "setInputStream"
);

Cu.importGlobalProperties(["URLSearchParams"]);

function handleRequest(aRequest, aResponse) {
  var params = new URLSearchParams(aRequest.queryString);

  // Report-to setter
  if (aRequest.method == "GET" && params.get("task") == "header") {
    let extraParams = [];

    if (params.has("410")) {
      extraParams.push("410=true");
    }

    if (params.has("worker")) {
      extraParams.push("worker=true");
    }

    let body = {
      max_age: 1,
      endpoints: [
        {
          url:
            "https://example.org/tests/dom/reporting/tests/delivering.sjs" +
            (extraParams.length ? "?" + extraParams.join("&") : ""),
          priority: 1,
          weight: 1,
        },
      ],
    };

    aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
    aResponse.setHeader("Report-to", JSON.stringify(body), false);
    aResponse.write("OK");
    return;
  }

  // Report check
  if (aRequest.method == "GET" && params.get("task") == "check") {
    aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");

    let reports = getState("report");
    if (!reports) {
      aResponse.write("");
      return;
    }

    if (params.has("min")) {
      let json = JSON.parse(reports);
      if (json.length < params.get("min")) {
        aResponse.write("");
        return;
      }
    }

    aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
    aResponse.write(getState("report"));

    setState("report", "");
    return;
  }

  if (aRequest.method == "POST") {
    var body = new BinaryInputStream(aRequest.bodyInputStream);

    var avail;
    var bytes = [];
    while ((avail = body.available()) > 0) {
      Array.prototype.push.apply(bytes, body.readByteArray(avail));
    }

    let reports = getState("report");
    if (!reports) {
      reports = [];
    } else {
      reports = JSON.parse(reports);
    }

    const incoming_reports = JSON.parse(String.fromCharCode.apply(null, bytes));
    for (let report of incoming_reports) {
      let data = {
        contentType: aRequest.getHeader("content-type"),
        origin: aRequest.getHeader("origin"),
        body: report,
        url:
          aRequest.scheme +
          "://" +
          aRequest.host +
          aRequest.path +
          (aRequest.queryString ? "&" + aRequest.queryString : ""),
      };
      reports.push(data);
    }

    setState("report", JSON.stringify(reports));

    if (params.has("410")) {
      aResponse.setStatusLine(aRequest.httpVersion, 410, "Gone");
    } else {
      aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
    }
    return;
  }

  aResponse.setStatusLine(aRequest.httpVersion, 500, "Internal error");
  aResponse.write("Invalid request");
}