summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/test/browser_net_resend_cors.js
blob: 6d9b42f8e82da68484c6f758d11d5a3f875de43f (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
122
123
124
125
126
127
128
129
130
131
132
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/**
 * Tests if resending a CORS request avoids the security checks and doesn't send
 * a preflight OPTIONS request (bug 1270096 and friends)
 */

add_task(async function () {
  const { tab, monitor } = await initNetMonitor(HTTPS_CORS_URL, {
    requestCount: 1,
  });
  info("Starting test... ");

  const { store, windowRequire, connector } = monitor.panelWin;
  const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
  const { getRequestById, getSortedRequests } = windowRequire(
    "devtools/client/netmonitor/src/selectors/index"
  );

  store.dispatch(Actions.batchEnable(false));

  const requestUrl = "https://test1.example.com" + CORS_SJS_PATH;

  info("Waiting for OPTIONS, then POST");
  const wait = waitForNetworkEvents(monitor, 2);
  await SpecialPowers.spawn(
    tab.linkedBrowser,
    [requestUrl],
    async function (url) {
      content.wrappedJSObject.performRequests(
        url,
        "triggering/preflight",
        "post-data"
      );
    }
  );
  await wait;

  const METHODS = ["OPTIONS", "POST"];
  const ITEMS = METHODS.map((val, i) => getSortedRequests(store.getState())[i]);

  // Check the requests that were sent
  ITEMS.forEach((item, i) => {
    is(
      item.method,
      METHODS[i],
      `The ${item.method} request has the right method`
    );
    is(item.url, requestUrl, `The ${item.method} request has the right URL`);
  });

  // Resend both requests without modification. Wait for resent OPTIONS, then POST.
  // POST is supposed to have no preflight OPTIONS request this time (CORS is disabled)
  const onRequests = waitForNetworkEvents(monitor, 1);
  for (let item of ITEMS) {
    info(`Selecting the ${item.method} request`);
    store.dispatch(Actions.selectRequest(item.id));

    // Wait for requestHeaders and responseHeaders are required when fetching data
    // from back-end.
    await waitUntil(() => {
      item = getRequestById(store.getState(), item.id);
      return item.requestHeaders && item.responseHeaders;
    });

    const { length } = getSortedRequests(store.getState());

    info(`Cloning the ${item.method} request into a custom clone`);
    store.dispatch(Actions.cloneRequest(item.id));

    info("Sending the cloned request (without change)");
    store.dispatch(Actions.sendCustomRequest(item.id));

    await waitUntil(
      () => getSortedRequests(store.getState()).length === length + 1
    );
  }

  info("Waiting for both resent requests");
  await onRequests;

  // Check the resent requests
  for (let i = 0; i < ITEMS.length; i++) {
    let item = ITEMS[i];
    is(
      item.method,
      METHODS[i],
      `The ${item.method} request has the right method`
    );
    is(item.url, requestUrl, `The ${item.method} request has the right URL`);
    is(item.status, "200", `The ${item.method} response has the right status`);

    if (item.method === "POST") {
      is(
        item.method,
        "POST",
        `The ${item.method} request has the right method`
      );

      // Trigger responseContent update requires to wait until
      // responseContentAvailable set true
      await waitUntil(() => {
        item = getRequestById(store.getState(), item.id);
        return item.responseContentAvailable;
      });
      await connector.requestData(item.id, "responseContent");

      // Wait for both requestPostData & responseContent payloads arrived.
      await waitUntil(() => {
        item = getRequestById(store.getState(), item.id);
        return item.responseContent && item.requestPostData;
      });

      is(
        item.requestPostData.postData.text,
        "post-data",
        "The POST request has the right POST data"
      );
      is(
        item.responseContent.content.text,
        "Access-Control-Allow-Origin: *",
        "The POST response has the right content"
      );
    }
  }

  info("Finishing the test");
  return teardown(monitor);
});