<!DOCTYPE HTML>
<html>
<head>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
  <title>Test for Cross Site XMLHttpRequest</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>        
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="gen.next()">
<p id="display">
<iframe id=loader></iframe>
</p>
<div id="content" style="display: none">
  
</div>
<pre id="test">
<script class="testbody" type="application/javascript">

let gen;
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("This test needs to generate artificial pauses, hence it uses timeouts.  There is no way around it, unfortunately. :(");

window.addEventListener("message", function(e) {
  gen.next(e.data);
});

gen = runTest();

function* runTest() {
  var loader = document.getElementById('loader');
  var loaderWindow = loader.contentWindow;
  loader.onload = function () { gen.next() };

  loader.src = "http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner.html";
  origin = "http://example.org";
  yield undefined;

  tests = [{ pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: 3600
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue",
                        "y-my-header": "second" },
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "hello" },
             allowHeaders: "y-my-header",
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "hello" },
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "hello" },
             allowHeaders: "y-my-header,x-my-header",
             cacheTime: 3600,
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue",
                        "y-my-header": "second" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "hello" },
             allowHeaders: "y-my-header,x-my-header",
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "hello" },
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue",
                        "y-my-header": "second" },
           },
           { newTest: "*******" },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: 2
           },
           { pause: 2.1 },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header, y-my-header",
             cacheTime: 3600
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "z-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: "\t  3600 \t ",
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: "3600 3",
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: "asdf",
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "first-header": "myValue" },
             allowHeaders: "first-header",
             cacheTime: 2,
           },
           { pass: 1,
             method: "GET",
             headers: { "second-header": "myValue" },
             allowHeaders: "second-header",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "GET",
             headers: { "third-header": "myValue" },
             allowHeaders: "third-header",
             cacheTime: 2,
           },
           { pause: 2.1 },
           { pass: 1,
             method: "GET",
             headers: { "second-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "first-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "first-header": "myValue" },
             allowHeaders: "first-header",
             cacheTime: 2,
           },
           { pass: 1,
             method: "GET",
             headers: { "second-header": "myValue" },
             allowHeaders: "second-header",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "GET",
             headers: { "third-header": "myValue" },
             allowHeaders: "third-header",
             cacheTime: 2,
           },
           { pause: 2.1 },
           { pass: 1,
             method: "GET",
             headers: { "second-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "third-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 0,
             method: "DELETE",
           },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE",
             cacheTime: 3600
           },
           { pass: 1,
             method: "DELETE",
           },
           { pass: 1,
             method: "DELETE",
           },
           { pass: 0,
             method: "PATCH",
           },
           { pass: 1,
             method: "PATCH",
             allowMethods: "PATCH",
           },
           { pass: 1,
             method: "PATCH",
           },
           { pass: 1,
             method: "PATCH",
             allowMethods: "PATCH",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "PATCH",
           },
           { pass: 0,
             method: "DELETE",
           },
           { pass: 0,
             method: "PUT",
           },
           { newTest: "*******" },
           { pass: 1,
             method: "PATCH",
             allowMethods: "PATCH",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "PATCH",
           },
           { newTest: "*******" },
           { pass: 0,
             method: "DELETE",
           },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE",
             cacheTime: 2
           },
           { pause: 2.1 },
           { pass: 0,
             method: "DELETE",
           },
           { newTest: "*******" },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE, PUT",
             cacheTime: 3600
           },
           { pass: 1,
             method: "DELETE",
           },
           { pass: 1,
             method: "PUT",
           },
           { pass: 0,
             method: "PATCH",
           },
           { newTest: "*******" },
           { pass: 1,
             method: "FIRST",
             allowMethods: "FIRST",
             cacheTime: 2,
           },
           { pass: 1,
             method: "SECOND",
             allowMethods: "SECOND",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "THIRD",
             allowMethods: "THIRD",
             cacheTime: 2,
           },
           { pause: 2.1 },
           { pass: 1,
             method: "SECOND",
           },
           { pass: 0,
             method: "FIRST",
           },
           { newTest: "*******" },
           { pass: 1,
             method: "FIRST",
             allowMethods: "FIRST",
             cacheTime: 2,
           },
           { pass: 1,
             method: "SECOND",
             allowMethods: "SECOND",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "THIRD",
             allowMethods: "THIRD",
             cacheTime: 2,
           },
           { pause: 2.1 },
           { pass: 1,
             method: "SECOND",
           },
           { pass: 0,
             method: "THIRD",
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "x-value" },
             allowHeaders: "x-my-header",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "x-value" }
           },
           { pass: 0,
             method: "GET",
             headers: { "y-my-header": "y-value" }
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "x-value" }
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "x-value" },
             allowHeaders: "x-my-header",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "x-value" },
           },
           { pass: 0,
             method: "PUT",
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "x-value" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "x-value" },
             allowHeaders: "x-my-header",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "x-value" },
           },
           { pass: 0,
             method: "GET",
             noOrigin: 1,
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "x-value" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "DELETE"
           },
           { pass: 0,
             method: "PUT"
           },
           { pass: 0,
             method: "DELETE"
           },
           { newTest: "*******" },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "DELETE"
           },
           { pass: 0,
             method: "DELETE",
             headers: { "my-header": "value" },
           },
           { pass: 0,
             method: "DELETE"
           },
           { newTest: "*******" },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE",
             cacheTime: 3600,
           },
           { pass: 1,
             method: "DELETE"
           },
           { pass: 0,
             method: "GET",
             noOrigin: 1,
           },
           { pass: 0,
             method: "DELETE"
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             withCred: true,
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: 3600
           },
           { pass: 1,
             method: "GET",
             withCred: true,
             headers: { "x-my-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             withCred: true,
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: 3600
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "myValue" },
             allowHeaders: "y-my-header",
             cacheTime: 2
           },
           { pass: 1,
             method: "GET",
             headers: { "y-my-header": "myValue" },
           },
           { pass: 1,
             method: "GET",
             withCred: true,
             headers: { "x-my-header": "myValue" },
           },
           { pause: 2.1 },
           { pass: 1,
             method: "GET",
             withCred: true,
             headers: { "x-my-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "x-my-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             headers: { "y-my-header": "myValue" },
           },
           { pass: 0,
             method: "GET",
             withCred: true,
             headers: { "y-my-header": "myValue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "DELETE",
             allowMethods: "DELETE",
             cacheTime: 3600
           },
           { pass: 0,
             method: "GET",
             headers: { "DELETE": "myvalue" },
           },
           { newTest: "*******" },
           { pass: 1,
             method: "GET",
             headers: { "x-my-header": "myValue" },
             allowHeaders: "x-my-header",
             cacheTime: 3600
           },
           { pass: 0,
             method: "3600",
             headers: { "x-my-header": "myvalue" },
           },
           ];

  for (let i = 0; i < 110; i++) {
    tests.push({ newTest: "*******" },
               { pass: 1,
                 method: "DELETE",
                 allowMethods: "DELETE",
                 cacheTime: 3600,
               });
  }

  baseURL = "http://mochi.test:8888/tests/dom/security/test/cors/" +
             "file_CrossSiteXHR_cache_server.sjs?";
  setStateURL = baseURL + "setState=";

  var unique = Date.now();
  for (test of tests) {
    if (test.newTest) {
      unique++;
      continue;
    }
    if (test.pause) {
      setTimeout(function() { gen.next() }, test.pause * 1000);
      yield undefined;
      continue;
    }

    req = {
      url: baseURL + "c=" + unique,
      method: test.method,
      headers: test.headers,
      withCred: test.withCred,
    };

    sec = { allowOrigin: test.noOrigin ? "" : origin,
            allowHeaders: test.allowHeaders,
            allowMethods: test.allowMethods,
            cacheTime: test.cacheTime,
            withCred: test.withCred };
    xhr = new XMLHttpRequest();
    xhr.open("POST", setStateURL + escape(JSON.stringify(sec)), true);
    xhr.onloadend = function() { gen.next(); }
    xhr.send();
    yield undefined;

    loaderWindow.postMessage(JSON.stringify(req), origin);

    res = JSON.parse(yield);

    testName = JSON.stringify(test) + " (index " + tests.indexOf(test) + ")";

    if (test.pass) {
      is(res.didFail, false,
        "shouldn't have failed in test for " + testName);
      is(res.status, 200, "wrong status in test for " + testName);
      is(res.responseXML, "<res>hello pass</res>",
         "wrong responseXML in test for " + testName);
      is(res.responseText, "<res>hello pass</res>\n",
         "wrong responseText in test for " + testName);
      is(res.events.join(","),
         "opening,rs1,sending,loadstart,rs2,rs3,rs4,load,loadend",
         "wrong events in test for " + testName);
    }
    else {
      is(res.didFail, true,
        "should have failed in test for " + testName);
      is(res.status, 0, "wrong status in test for " + testName);
      is(res.responseXML, null,
         "wrong responseXML in test for " + testName);
      is(res.responseText, "",
         "wrong responseText in test for " + testName);
      is(res.events.join(","),
         "opening,rs1,sending,loadstart,rs4,error,loadend",
         "wrong events in test for " + testName);
      is(res.progressEvents, 0,
         "wrong events in test for " + testName);
    }
  }

  SimpleTest.finish();
}

</script>
</pre>
</body>
</html>
