Bug 1807268 - Re-enable verifyShowClipboardSuggestionsToggleTest UI test r=jajohnson
[gecko.git] / netwerk / test / unit / test_XHR_redirects.js
blobe3bee4c76ff61cd901cc687c2c82a50ca119f399
1 // This file tests whether XmlHttpRequests correctly handle redirects,
2 // including rewriting POSTs to GETs (on 301/302/303), as well as
3 // prompting for redirects of other unsafe methods (such as PUTs, DELETEs,
4 // etc--see HttpBaseChannel::IsSafeMethod).  Since no prompting is possible
5 // in xpcshell, we get an error for prompts, and the request fails.
6 "use strict";
8 const { HttpServer } = ChromeUtils.importESModule(
9   "resource://testing-common/httpd.sys.mjs"
11 const { Preferences } = ChromeUtils.importESModule(
12   "resource://gre/modules/Preferences.sys.mjs"
15 var sSame;
16 var sOther;
17 var sRedirectPromptPref;
19 const BUGID = "676059";
20 const OTHERBUGID = "696849";
22 ChromeUtils.defineLazyGetter(this, "pSame", function () {
23   return sSame.identity.primaryPort;
24 });
25 ChromeUtils.defineLazyGetter(this, "pOther", function () {
26   return sOther.identity.primaryPort;
27 });
29 function createXHR(async, method, path) {
30   var xhr = new XMLHttpRequest();
31   xhr.open(method, "http://localhost:" + pSame + path, async);
32   return xhr;
35 function checkResults(xhr, method, status, unsafe) {
36   if (unsafe) {
37     if (sRedirectPromptPref) {
38       // The method is null if we prompt for unsafe redirects
39       method = null;
40     } else {
41       // The status code is 200 when we don't prompt for unsafe redirects
42       status = 200;
43     }
44   }
46   if (xhr.readyState != 4) {
47     return false;
48   }
49   Assert.equal(xhr.status, status);
51   if (status == 200) {
52     // if followed then check for echoed method name
53     Assert.equal(xhr.getResponseHeader("X-Received-Method"), method);
54   }
56   return true;
59 function run_test() {
60   // start servers
61   sSame = new HttpServer();
63   // same-origin redirects
64   sSame.registerPathHandler(
65     "/bug" + BUGID + "-redirect301",
66     bug676059redirect301
67   );
68   sSame.registerPathHandler(
69     "/bug" + BUGID + "-redirect302",
70     bug676059redirect302
71   );
72   sSame.registerPathHandler(
73     "/bug" + BUGID + "-redirect303",
74     bug676059redirect303
75   );
76   sSame.registerPathHandler(
77     "/bug" + BUGID + "-redirect307",
78     bug676059redirect307
79   );
80   sSame.registerPathHandler(
81     "/bug" + BUGID + "-redirect308",
82     bug676059redirect308
83   );
85   // cross-origin redirects
86   sSame.registerPathHandler(
87     "/bug" + OTHERBUGID + "-redirect301",
88     bug696849redirect301
89   );
90   sSame.registerPathHandler(
91     "/bug" + OTHERBUGID + "-redirect302",
92     bug696849redirect302
93   );
94   sSame.registerPathHandler(
95     "/bug" + OTHERBUGID + "-redirect303",
96     bug696849redirect303
97   );
98   sSame.registerPathHandler(
99     "/bug" + OTHERBUGID + "-redirect307",
100     bug696849redirect307
101   );
102   sSame.registerPathHandler(
103     "/bug" + OTHERBUGID + "-redirect308",
104     bug696849redirect308
105   );
107   // same-origin target
108   sSame.registerPathHandler("/bug" + BUGID + "-target", echoMethod);
109   sSame.start(-1);
111   // cross-origin target
112   sOther = new HttpServer();
113   sOther.registerPathHandler("/bug" + OTHERBUGID + "-target", echoMethod);
114   sOther.start(-1);
116   // format: redirectType, methodToSend, redirectedMethod, finalStatus
117   //   redirectType sets the URI the initial request goes to
118   //   methodToSend is the HTTP method to send
119   //   redirectedMethod is the method to use for the redirect, if any
120   //   finalStatus is 200 when the redirect takes place, redirectType otherwise
122   // Note that unsafe methods should not follow the redirect automatically
123   // Of the methods below, DELETE, POST and PUT are unsafe
125   sRedirectPromptPref = Preferences.get("network.http.prompt-temp-redirect");
126   // Following Bug 677754 we don't prompt for unsafe redirects
128   // same-origin variant
129   var tests = [
130     // 301: rewrite just POST
131     [301, "DELETE", "DELETE", 301, true],
132     [301, "GET", "GET", 200, false],
133     [301, "HEAD", "HEAD", 200, false],
134     [301, "POST", "GET", 200, false],
135     [301, "PUT", "PUT", 301, true],
136     [301, "PROPFIND", "PROPFIND", 200, false],
137     // 302: see 301
138     [302, "DELETE", "DELETE", 302, true],
139     [302, "GET", "GET", 200, false],
140     [302, "HEAD", "HEAD", 200, false],
141     [302, "POST", "GET", 200, false],
142     [302, "PUT", "PUT", 302, true],
143     [302, "PROPFIND", "PROPFIND", 200, false],
144     // 303: rewrite to GET except HEAD
145     [303, "DELETE", "GET", 200, false],
146     [303, "GET", "GET", 200, false],
147     [303, "HEAD", "HEAD", 200, false],
148     [303, "POST", "GET", 200, false],
149     [303, "PUT", "GET", 200, false],
150     [303, "PROPFIND", "GET", 200, false],
151     // 307: never rewrite
152     [307, "DELETE", "DELETE", 307, true],
153     [307, "GET", "GET", 200, false],
154     [307, "HEAD", "HEAD", 200, false],
155     [307, "POST", "POST", 307, true],
156     [307, "PUT", "PUT", 307, true],
157     [307, "PROPFIND", "PROPFIND", 200, false],
158     // 308: never rewrite
159     [308, "DELETE", "DELETE", 308, true],
160     [308, "GET", "GET", 200, false],
161     [308, "HEAD", "HEAD", 200, false],
162     [308, "POST", "POST", 308, true],
163     [308, "PUT", "PUT", 308, true],
164     [308, "PROPFIND", "PROPFIND", 200, false],
165   ];
167   // cross-origin variant
168   var othertests = tests; // for now these have identical results
170   var xhr;
172   for (let i = 0; i < tests.length; ++i) {
173     dump("Testing " + tests[i] + "\n");
174     xhr = createXHR(
175       false,
176       tests[i][1],
177       "/bug" + BUGID + "-redirect" + tests[i][0]
178     );
179     xhr.send(null);
180     checkResults(xhr, tests[i][2], tests[i][3], tests[i][4]);
181   }
183   for (let i = 0; i < othertests.length; ++i) {
184     dump("Testing " + othertests[i] + " (cross-origin)\n");
185     xhr = createXHR(
186       false,
187       othertests[i][1],
188       "/bug" + OTHERBUGID + "-redirect" + othertests[i][0]
189     );
190     xhr.send(null);
191     checkResults(xhr, othertests[i][2], tests[i][3], tests[i][4]);
192   }
194   sSame.stop(do_test_finished);
195   sOther.stop(do_test_finished);
198 function redirect(metadata, response, status, port, bugid) {
199   // set a proper reason string to avoid confusion when looking at the
200   // HTTP messages
201   var reason;
202   if (status == 301) {
203     reason = "Moved Permanently";
204   } else if (status == 302) {
205     reason = "Found";
206   } else if (status == 303) {
207     reason = "See Other";
208   } else if (status == 307) {
209     reason = "Temporary Redirect";
210   } else if (status == 308) {
211     reason = "Permanent Redirect";
212   }
214   response.setStatusLine(metadata.httpVersion, status, reason);
215   response.setHeader(
216     "Location",
217     "http://localhost:" + port + "/bug" + bugid + "-target"
218   );
221 // PATH HANDLER FOR /bug676059-redirect301
222 function bug676059redirect301(metadata, response) {
223   redirect(metadata, response, 301, pSame, BUGID);
226 // PATH HANDLER FOR /bug696849-redirect301
227 function bug696849redirect301(metadata, response) {
228   redirect(metadata, response, 301, pOther, OTHERBUGID);
231 // PATH HANDLER FOR /bug676059-redirect302
232 function bug676059redirect302(metadata, response) {
233   redirect(metadata, response, 302, pSame, BUGID);
236 // PATH HANDLER FOR /bug696849-redirect302
237 function bug696849redirect302(metadata, response) {
238   redirect(metadata, response, 302, pOther, OTHERBUGID);
241 // PATH HANDLER FOR /bug676059-redirect303
242 function bug676059redirect303(metadata, response) {
243   redirect(metadata, response, 303, pSame, BUGID);
246 // PATH HANDLER FOR /bug696849-redirect303
247 function bug696849redirect303(metadata, response) {
248   redirect(metadata, response, 303, pOther, OTHERBUGID);
251 // PATH HANDLER FOR /bug676059-redirect307
252 function bug676059redirect307(metadata, response) {
253   redirect(metadata, response, 307, pSame, BUGID);
256 // PATH HANDLER FOR /bug676059-redirect308
257 function bug676059redirect308(metadata, response) {
258   redirect(metadata, response, 308, pSame, BUGID);
261 // PATH HANDLER FOR /bug696849-redirect307
262 function bug696849redirect307(metadata, response) {
263   redirect(metadata, response, 307, pOther, OTHERBUGID);
266 // PATH HANDLER FOR /bug696849-redirect308
267 function bug696849redirect308(metadata, response) {
268   redirect(metadata, response, 308, pOther, OTHERBUGID);
271 // Echo the request method in "X-Received-Method" header field
272 function echoMethod(metadata, response) {
273   response.setStatusLine(metadata.httpVersion, 200, "OK");
274   response.setHeader("X-Received-Method", metadata.method);