1var BASE_URL = "example.com/tests/dom/base/test/bug704320.sjs";
2
3function createTestUrl(schemeFrom, schemeTo, policy, action, type) {
4  return (
5    schemeTo +
6    "://" +
7    BASE_URL +
8    "?" +
9    "action=" +
10    action +
11    "&" +
12    "scheme=" +
13    schemeFrom +
14    "-to-" +
15    schemeTo +
16    "&" +
17    "policy=" +
18    policy +
19    "&" +
20    "type=" +
21    type
22  );
23}
24
25function create2ndLevelIframeUrl(schemeFrom, schemeTo, policy, type) {
26  return (
27    schemeFrom +
28    "://" +
29    BASE_URL +
30    "?" +
31    "action=create-2nd-level-iframe&" +
32    "scheme-from=" +
33    schemeFrom +
34    "&" +
35    "scheme-to=" +
36    schemeTo +
37    "&" +
38    "policy=" +
39    policy +
40    "&" +
41    "type=" +
42    type
43  );
44}
45
46// Creates the following test cases for the specified scheme and referrer
47// policy combination:
48//   <link>
49//   @import
50//   font-face
51//   bg-url
52//   <script>
53//   <img>
54//   <iframe>
55//   <audio>
56//   <video>
57//   <object type="bogus">
58//   <object type="image/svg+xml">
59//   <a>
60//   <a ping>
61//   <form>
62//   window.location
63//   window.open
64//   XMLHttpRequest
65//   EventSource
66//   TODO: XSLT?
67//
68// This returns a page that loads all of the above resources and contains a
69// script that clicks a link after all resources are (hopefully)
70// loaded. The click triggers a redirection to file_bug704320_redirect.html,
71// which in turn notifies the main window that it's time to check the test
72// results.
73function createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy) {
74  var _createTestUrl = createTestUrl.bind(
75    null,
76    schemeFrom,
77    schemeTo,
78    policy,
79    "test"
80  );
81
82  var _create2ndLevelIframeUrl = create2ndLevelIframeUrl.bind(
83    null,
84    schemeFrom,
85    schemeTo,
86    policy
87  );
88
89  var metaReferrerPolicyString = "";
90  if (optionalEarlierPolicy && optionalEarlierPolicy != "") {
91    metaReferrerPolicyString +=
92      '<meta name="referrer" content="' + optionalEarlierPolicy + '">\n';
93  }
94  metaReferrerPolicyString += '<meta name="referrer" content="' + policy + '">';
95
96  return (
97    "<!DOCTYPE HTML>\n\
98         <html>\n\
99         <head>\n\
100	    " +
101    metaReferrerPolicyString +
102    '\n\
103           <link rel="stylesheet" type="text/css" href="' +
104    _createTestUrl("stylesheet") +
105    '">\n\
106           <style type="text/css">\n\
107             @import "' +
108    _createTestUrl("import-css") +
109    '";\n\
110             @font-face {\n\
111               font-family: "Fake Serif Bold";\n\
112               src: url("' +
113    _createTestUrl("font-face") +
114    '");\n\
115             }\n\
116             body {\n\
117               font-family: "Fake Serif Bold", serif;\n\
118               background: url("' +
119    _createTestUrl("bg-url") +
120    '");\n\
121             }\n\
122           </style>\n\
123         </head>\n\
124         <body>\n\
125           <script src="' +
126    _createTestUrl("script") +
127    '"></script>\n\
128           <img src="' +
129    _createTestUrl("img") +
130    '"></img>\n\
131           <iframe src="' +
132    _createTestUrl("iframe") +
133    '"></iframe>\n\
134           <audio src="' +
135    _createTestUrl("audio") +
136    '"></audio>\n\
137           <video src="' +
138    _createTestUrl("video") +
139    '"></video>\n\
140           <object type="bogus" data="' +
141    _createTestUrl("object") +
142    '"></object>\n\
143           <object type="image/svg+xml" data="' +
144    _createTestUrl("object-svg") +
145    '"></object>\n\
146           <a id="link" href="' +
147    _createTestUrl("link") +
148    '" ping="' +
149    _createTestUrl("link-ping") +
150    '"></a>\n\
151           <iframe src="' +
152    _create2ndLevelIframeUrl("form") +
153    '"></iframe>\n\
154           <iframe src="' +
155    _create2ndLevelIframeUrl("window.location") +
156    '"></iframe>\n\
157           <script>\n\
158              var _testFinished = 0\n\
159             (function() {\n\
160               var x = new XMLHttpRequest();\n\
161               x.open("GET", "' +
162    _createTestUrl("xmlhttprequest") +
163    '");\n\
164               x.send();\n\
165             })();\n\
166             (function() {\n\
167               var eventSource = new EventSource("' +
168    _createTestUrl("eventsource") +
169    '");\n\
170             })();' +
171    // LOAD EVENT (most of the tests)
172    // fires when the resources for the page are loaded
173    'var _isLoaded = false;\n\
174             window.addEventListener("load", function() {\n\
175               this._isLoaded = true;\n\
176               this.checkForFinish();\n\
177             }.bind(window), false);' +
178    // WINDOW.OPEN test
179    // listen for incoming status from window.open, close the window
180    // and check if we're done.
181    'var _openedWindowLoaded = false;\n\
182             window.addEventListener("message", function(message) {\n\
183               if (message.data == "window.open") {\n\
184                 this._openedWindowLoaded = true;\n\
185                 this.win.close();\n\
186                 this.checkForFinish();\n\
187               }\n\
188             }.bind(window), false);\n\
189             var win = window.open("' +
190    _createTestUrl("window.open") +
191    '", "");' +
192    // called by the two things that must complete: window.open page
193    // and the window load event.  When both are complete, this
194    // "finishes" the iframe subtest by clicking the link.
195    // _testFinished avoids calling this function twice (which may happen)
196    'function checkForFinish() {\n\
197               if (window._isLoaded && window._openedWindowLoaded && !window._testFinished) {\n\
198                 window._testFinished = 1;\n\
199                 document.getElementById("link").click();\n\
200               }\n\
201             }\n\
202           </script>\n\
203         </body>\n\
204         </html>'
205  );
206}
207
208function createIframedFormTest(schemeFrom, schemeTo, policy) {
209  var actionUrl = schemeTo + "://" + BASE_URL;
210
211  return (
212    '<!DOCTYPE HTML>\n\
213         <html>\n\
214         <head>\n\
215           <meta name="referrer" content="' +
216    policy +
217    '">\n\
218         </head>\n\
219         <body>\n\
220           <form id="form" action="' +
221    actionUrl +
222    '">\n\
223             <input type="hidden" name="action" value="test">\n\
224             <input type="hidden" name="scheme" value="' +
225    schemeFrom +
226    "-to-" +
227    schemeTo +
228    '">\n\
229             <input type="hidden" name="policy" value="' +
230    policy +
231    '">\n\
232             <input type="hidden" name="type" value="form">\n\
233           </form>\n\
234           <script>\n\
235             document.getElementById("form").submit();\n\
236           </script>\n\
237         </body>\n\
238         </html>'
239  );
240}
241
242function createIframedWindowLocationTest(schemeFrom, schemeTo, policy) {
243  var url = createTestUrl(
244    schemeFrom,
245    schemeTo,
246    policy,
247    "test",
248    "window.location"
249  );
250
251  return (
252    '<!DOCTYPE HTML>\n\
253         <html>\n\
254         <head>\n\
255           <meta name="referrer" content="' +
256    policy +
257    '">\n\
258         </head>\n\
259         <body>\n\
260           <script>\n\
261            window.location = "' +
262    url +
263    '";\n\
264           </script>\n\
265         </body>\n\
266         </html>'
267  );
268}
269
270function createPolicyTest(policy, optionalEarlierPolicy) {
271  var metaReferrerPolicyString = "";
272  if (optionalEarlierPolicy && optionalEarlierPolicy != "") {
273    metaReferrerPolicyString +=
274      '<meta name="referrer" content="' + optionalEarlierPolicy + '">\n';
275  }
276  metaReferrerPolicyString += '<meta name="referrer" content="' + policy + '">';
277
278  return (
279    "<!DOCTYPE HTML>\n\
280          <html>\n\
281          <head>\n\
282	    " +
283    metaReferrerPolicyString +
284    '\n\
285            <script type="text/javascript" src="/tests/dom/base/test/file_bug704320_preload_common.js"></script>\n\
286          </head>\n\
287          <body>\n\
288            <img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\
289                    onload="incrementLoad2(\'img\', 2);">\n\
290            <img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\
291                    onload="incrementLoad2(\'img\', 2);">\n\
292          </body>\n\
293          </html>'
294  );
295}
296
297function handleRequest(request, response) {
298  var sharedKey = "bug704320.sjs";
299  var params = request.queryString.split("&");
300  var action = params[0].split("=")[1];
301
302  if (action === "create-1st-level-iframe") {
303    // ?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=origin
304    var schemeFrom = params[1].split("=")[1];
305    var schemeTo = params[2].split("=")[1];
306    var policy = params[3].split("=")[1];
307    var optionalEarlierPolicy = "";
308    if (params[4]) {
309      optionalEarlierPolicy = params[4].split("=")[1];
310    }
311
312    response.setHeader("Content-Type", "text/html; charset=utf-8", false);
313    response.setHeader("Cache-Control", "no-cache", false);
314    response.write(
315      createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy)
316    );
317  } else if (action === "create-2nd-level-iframe") {
318    // ?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=origin&type=form"
319    var schemeFrom = params[1].split("=")[1];
320    var schemeTo = params[2].split("=")[1];
321    var policy = params[3].split("=")[1];
322    var type = params[4].split("=")[1];
323
324    response.setHeader("Content-Type", "text/html; charset=utf-8", false);
325    response.setHeader("Cache-Control", "no-cache", false);
326
327    if (type === "form") {
328      response.write(createIframedFormTest(schemeFrom, schemeTo, policy));
329    } else if (type === "window.location") {
330      response.write(
331        createIframedWindowLocationTest(schemeFrom, schemeTo, policy)
332      );
333    }
334  } else if (action === "test") {
335    // ?action=test&scheme=http-to-https&policy=origin&type=img
336    var scheme = params[1].split("=")[1];
337    var policy = params[2].split("=")[1];
338    var type = params[3].split("=")[1];
339    var result = getSharedState(sharedKey);
340
341    if (result === "") {
342      result = {};
343    } else {
344      result = JSON.parse(result);
345    }
346
347    if (!result[type]) {
348      result[type] = {};
349    }
350
351    if (!result[type][scheme]) {
352      result[type][scheme] = {};
353    }
354
355    if (request.hasHeader("Referer")) {
356      result[type][scheme][policy] = request.getHeader("Referer");
357    } else {
358      result[type][scheme][policy] = "";
359    }
360
361    setSharedState(sharedKey, JSON.stringify(result));
362
363    if (type === "link") {
364      var loc =
365        "https://example.com/tests/dom/base/test/file_bug704320_redirect.html";
366      response.setStatusLine("1.1", 302, "Found");
367      response.setHeader("Location", loc, false);
368    }
369
370    if (type === "window.open") {
371      response.setHeader("Cache-Control", "no-cache", false);
372      response.setHeader("Content-Type", "text/html", false);
373      response.write(
374        "<html><body><script>" +
375          'window.opener.postMessage("window.open", "*");' +
376          "</script></body></html>"
377      );
378    }
379  } else if (action === "get-test-results") {
380    // ?action=get-result
381    response.setHeader("Cache-Control", "no-cache", false);
382    response.setHeader("Content-Type", "text/plain", false);
383    response.write(getSharedState(sharedKey));
384  } else if (action === "generate-policy-test") {
385    // ?action=generate-policy-test&policy=b64-encoded-string
386    response.setHeader("Cache-Control", "no-cache", false);
387    response.setHeader("Content-Type", "text/html", false);
388    var policy = unescape(params[1].split("=")[1]);
389    var optionalEarlierPolicy = "";
390    if (params[2]) {
391      optionalEarlierPolicy = params[2].split("=")[1];
392    }
393
394    response.write(createPolicyTest(policy, optionalEarlierPolicy));
395  }
396}
397