From 0d47e593c685313571aaa00cb7341b458123c82f Mon Sep 17 00:00:00 2001
From: Christoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Date: Wed, 19 Nov 2014 16:03:30 -0800
Subject: [PATCH 2/2] Bug 1080987 - navigator.sendBeacon() needs to sent origin
 header - test. r=sicking, a=bkerensa

---
 .../beacon/beacon-originheader-handler.sjs         | 41 ++++++++++++++
 dom/tests/mochitest/beacon/mochitest.ini           |  2 +
 .../mochitest/beacon/test_beaconOriginHeader.html  | 64 ++++++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 dom/tests/mochitest/beacon/beacon-originheader-handler.sjs
 create mode 100644 dom/tests/mochitest/beacon/test_beaconOriginHeader.html

diff --git a/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs b/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs
new file mode 100644
index 0000000..baed22c
--- /dev/null
+++ b/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs
@@ -0,0 +1,41 @@
+/*
+ * TestSever customized specifically for the needs of:
+ * Bug 1080987 - navigator.sendBeacon() needs to sent origin header
+ */
+
+function handleRequest(request, response)
+{
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "text/plain", false);
+
+  // case XHR-REQUEST: the xhr-request tries to query the
+  // stored header from the beacon request.
+  if (request.queryString == "queryheader") {
+    var header = getState("originHeader");
+    // if the beacon already stored the header - return.
+    if (header) {
+      response.write(header);
+      setState("originHeader", "");
+      return;
+    }
+    // otherwise wait for the beacon request
+    response.processAsync();
+    setObjectState("xhr-response", response);
+    return;
+  }
+
+  // case BEACON-REQUEST: get the beacon header and
+  // store the header on the server.
+  var header = request.getHeader("origin");
+  setState("originHeader", header);
+
+  // if there is an xhr-request waiting, return the header now.
+  getObjectState("xhr-response", function(xhrResponse) {
+    if (!xhrResponse) {
+      return;
+    }
+    setState("originHeader", "");
+    xhrResponse.write(header);
+    xhrResponse.finish();
+  });
+}
diff --git a/dom/tests/mochitest/beacon/mochitest.ini b/dom/tests/mochitest/beacon/mochitest.ini
index f65276e..6681fa4 100644
--- a/dom/tests/mochitest/beacon/mochitest.ini
+++ b/dom/tests/mochitest/beacon/mochitest.ini
@@ -2,8 +2,10 @@
 skip-if = buildapp == 'b2g' || e10s
 support-files = beacon-frame.html
                 beacon-handler.sjs
+                beacon-originheader-handler.sjs
 
 [test_beacon.html]
 [test_beaconFrame.html]
 [test_beaconPreflight.html]
 [test_beaconContentPolicy.html]
+[test_beaconOriginHeader.html]
diff --git a/dom/tests/mochitest/beacon/test_beaconOriginHeader.html b/dom/tests/mochitest/beacon/test_beaconOriginHeader.html
new file mode 100644
index 0000000..b5684a9
--- /dev/null
+++ b/dom/tests/mochitest/beacon/test_beaconOriginHeader.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 1080987 - navigator.sendBeacon() needs to sent origin header</title>
+  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="visibility: hidden">
+    <iframe style="width:100%;" id="testframe"></iframe>
+  </div>
+
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const BEACON_URL = "http://example.com/tests/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs";
+const ORIGIN_HEADER = "http://mochi.test:8888";
+
+/* Description of the test:
+ *   We call sendBeacon() cross origin and make sure that the
+ *   origin header is actually set in the request.
+ *
+ * Since sendBeacon() does not expect any response, we are storing the
+ * header on the server (*.sjs) and use an XMLHttpRequest to actually
+ * retrieve the header back from the server. We assert that the header
+ * is indeed correct. Since sendBeacon() and also the XMLHttpRequest()
+ * are performed in an asynchronous fashion, there is no guarantee that
+ * the sendBeacon() is actually executed before the XMLHttpRequest().
+ * Hence the xhr-response might be processed asynchronously.
+ */
+
+SpecialPowers.pushPrefEnv({'set': [["beacon.enabled", true]]}, runTest);
+
+function queryHeaderFromServer() {
+  var xhr = new XMLHttpRequest();
+  xhr.open("GET", "beacon-originheader-handler.sjs?queryheader", true);
+  xhr.onload = function() {
+    is(xhr.responseText, ORIGIN_HEADER, "SendBeacon sends right origin header");
+    SimpleTest.finish();
+  };
+  xhr.onerror = function() {
+    ok(false, "xhr request returned error");
+    SimpleTest.finish();
+  };
+  xhr.send();
+}
+
+function runTest() {
+  // generate data and send beacon
+  var formData = new FormData();
+  formData.append('name', 'value');
+  navigator.sendBeacon(BEACON_URL, formData);
+
+  // start quering the result from the server
+  queryHeaderFromServer();
+}
+
+</script>
+</pre>
+</body>
+</html>
-- 
2.1.2

