summaryrefslogtreecommitdiffstats
path: root/toolkit/components/alerts/test/image_server.sjs
blob: 4caa21ce27a4c179c93dfd0ce5fb6d5354c6533f (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
const CC = Components.Constructor;

let { setTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);

const LocalFile = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath");

const FileInputStream = CC(
  "@mozilla.org/network/file-input-stream;1",
  "nsIFileInputStream",
  "init"
);

const BinaryInputStream = CC(
  "@mozilla.org/binaryinputstream;1",
  "nsIBinaryInputStream",
  "setInputStream"
);

function handleRequest(request, response) {
  let params = parseQueryString(request.queryString);

  response.setStatusLine(request.httpVersion, 200, "OK");

  // Compare and increment a cookie for this request. This is used to test
  // private browsing mode; the cookie should not be set if the image is
  // loaded anonymously.
  if (params.has("c")) {
    let expectedValue = parseInt(params.get("c"), 10);
    let actualValue = !request.hasHeader("Cookie")
      ? 0
      : parseInt(
          request.getHeader("Cookie").replace(/^counter=(\d+)/, "$1"),
          10
        );
    if (actualValue != expectedValue) {
      response.setStatusLine(request.httpVersion, 400, "Wrong counter value");
      return;
    }
    response.setHeader("Set-Cookie", `counter=${expectedValue + 1}`, false);
  }

  // Wait to send the image if a timeout is given.
  let timeout = parseInt(params.get("t"), 10);
  if (timeout > 0) {
    response.processAsync();
    setTimeout(() => {
      respond(params, request, response);
      response.finish();
    }, timeout * 1000);
    return;
  }

  respond(params, request, response);
}

function parseQueryString(queryString) {
  return queryString.split("&").reduce((params, param) => {
    let [key, value] = param.split("=", 2);
    params.set(key, value);
    return params;
  }, new Map());
}

function respond(params, request, response) {
  if (params.has("s")) {
    let statusCode = parseInt(params.get("s"), 10);
    response.setStatusLine(request.httpVersion, statusCode, "Custom status");
    return;
  }
  var filename = params.get("f");
  writeFile(filename, response);
}

function writeFile(name, response) {
  var file = new LocalFile(getState("__LOCATION__")).parent;
  file.append(name);

  let mimeType = Cc["@mozilla.org/uriloader/external-helper-app-service;1"]
    .getService(Ci.nsIMIMEService)
    .getTypeFromFile(file);

  let fileStream = new FileInputStream(file, 1, 0, false);
  let binaryStream = new BinaryInputStream(fileStream);

  response.setHeader("Content-Type", mimeType, false);
  response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available());

  binaryStream.close();
  fileStream.close();
}