summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/test/browser_net_resend_cors.js
blob: f9243ce6d5a79cdf3de7954263e8e44dd3f7f300 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* 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 onEvents = waitForNetworkEvents(monitor, 2);
  await SpecialPowers.spawn(
    tab.linkedBrowser,
    [requestUrl],
    async function (url) {
      content.wrappedJSObject.performRequests(
        url,
        "triggering/preflight",
        "post-data"
      );
    }
  );
  await onEvents;

  // Check the requests that were sent
  let sortedRequests = getSortedRequests(store.getState());

  const optRequest = sortedRequests[0];
  is(optRequest.method, "OPTIONS", `The OPTIONS request has the right method`);
  is(optRequest.url, requestUrl, `The OPTIONS request has the right URL`);

  const postRequest = sortedRequests[1];
  is(postRequest.method, "POST", `The POST request has the right method`);
  is(postRequest.url, requestUrl, `The POST 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)
  for (let item of [optRequest, postRequest]) {
    const onRequest = waitForNetworkEvents(monitor, 1);
    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;
    });

    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));

    info("Waiting for the resent request");
    await onRequest;
  }

  // Retrieve the new list of sorted requests, which should include 2 resent
  // requests.
  sortedRequests = getSortedRequests(store.getState());
  is(sortedRequests.length, 4, "There are 4 requests in total");

  const resentOptRequest = sortedRequests[2];
  is(
    resentOptRequest.method,
    "OPTIONS",
    `The resent OPTIONS request has the right method`
  );
  is(
    resentOptRequest.url,
    requestUrl,
    `The resent OPTIONS request has the right URL`
  );
  is(
    resentOptRequest.status,
    "200",
    `The resent OPTIONS response has the right status`
  );
  is(
    resentOptRequest.blockedReason,
    0,
    `The resent OPTIONS request was not blocked`
  );

  let resentPostRequest = sortedRequests[3];
  is(
    resentPostRequest.method,
    "POST",
    `The resent POST request has the right method`
  );
  is(
    resentPostRequest.url,
    requestUrl,
    `The resent POST request has the right URL`
  );
  is(
    resentPostRequest.status,
    "200",
    `The resent POST response has the right status`
  );
  is(
    resentPostRequest.blockedReason,
    0,
    `The resent POST request was not blocked`
  );

  await Promise.all([
    connector.requestData(resentPostRequest.id, "requestPostData"),
    connector.requestData(resentPostRequest.id, "responseContent"),
  ]);

  // Wait until responseContent and requestPostData are available.
  await waitUntil(() => {
    resentPostRequest = getRequestById(store.getState(), resentPostRequest.id);
    return (
      resentPostRequest.responseContent && resentPostRequest.requestPostData
    );
  });

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

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