CORS tests: start staging for approved
authorOdin Hørthe Omdal <odinho@opera.com>
Fri, 01 Jun 2012 18:36:45 +0200
changeset 66 1d5c6bca565a
parent 65 3c5b991884a4
child 67 4dbb372543f8
CORS tests: start staging for approved
tests/cors/submitted/opera/staging/basic.htm
tests/cors/submitted/opera/staging/origin.htm
tests/cors/submitted/opera/staging/resources/cors-makeheader.php
tests/cors/submitted/opera/staging/status.htm
tests/cors/submitted/opera/staging/support.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/basic.htm	Fri Jun 01 18:36:45 2012 +0200
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Basic CORS</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=support.js></script>
+<div id=log></div>
+
+<script>
+
+function cors(desc, url) {
+    async_test(desc).step(function() {
+        console.log(url);
+        var client = new XMLHttpRequest();
+        client.open("GET", url + "resources/cors-makeheader.php?get_value=hest_er_best&origin=none");
+        client.onreadystatechange = this.step_func(function(e) {
+            // First request, test that it fails with no origin
+            if (client.readyState < 4) return;
+            if (!url)
+                assert_true(client.response.indexOf("hest_er_best") != -1, "Got response");
+            else
+                assert_false(!!client.response, "Got CORS-disallowed response");
+
+            client.open("GET", url + "resources/cors-makeheader.php?get_value=hest_er_best");
+            client.onreadystatechange = this.step_func(function(e) {
+                // Second request, test that it passes with the allowed-origin
+                if (client.readyState < 4) return;
+                assert_true(client.response.indexOf("hest_er_best") != -1, "Got CORS-allowed response");
+                this.done();
+            });
+            client.send();
+        });
+        client.send();
+    });
+}
+
+cors("Same domain basic usage", "");
+cors("Cross domain basic usage", CROSSDOMAIN);
+cors("Same domain different port", "http://" + location.hostname + ":" + PORT + dirname(location.pathname));
+cors("Cross domain different port", "http://" + SUBDOMAIN + "." + location.hostname + ":" + PORT + dirname(location.pathname));
+
+cors("Same domain different protocol", 'https://' + location.host + dirname(location.pathname));
+cors("Cross domain different protocol", CROSSDOMAIN.replace("http:", "https:"));
+cors("Same domain different protocol different port", "https://" + location.hostname + ":" + PORT_HTTPS + dirname(location.pathname));
+cors("Cross domain different protocol different port", "https://" + SUBDOMAIN + "." + location.hostname + ":" + PORT_HTTPS + dirname(location.pathname));
+
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/origin.htm	Fri Jun 01 18:36:45 2012 +0200
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Access-Control-Allow-Origin handling</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=support.js></script>
+
+<h1>Access-Control-Allow-Origin handling</h1>
+
+<div id=log></div>
+
+<script>
+
+/*
+ * Origin header
+ */
+function shouldPass(origin) {
+    test(function () {
+        var client = new XMLHttpRequest()
+        client.open('GET', CROSSDOMAIN
+                            + '/resources/cors-makeheader.php?origin='
+                            + encodeURIComponent(origin),
+                    false)
+        client.send()
+        r = JSON.parse(client.response)
+        var host = location.protocol + "//" + location.host
+        assert_equals(r['origin'], host, 'Request Origin: should be ' + host)
+    }, 'Allow origin: ' + origin.replace(/\t/g, "[tab]").replace(/ /g, '_'));
+}
+
+shouldPass('*');
+shouldPass(' *  ');
+shouldPass('	*');
+shouldPass(location.protocol + "//" + location.host);
+shouldPass(" "+location.protocol + "//" + location.host);
+shouldPass(" "+location.protocol + "//" + location.host + "   	 ");
+shouldPass("	"+location.protocol + "//" + location.host);
+
+
+function shouldFail(origin) {
+    test(function () {
+        var client = new XMLHttpRequest()
+        client.open('GET', CROSSDOMAIN
+                            + '/resources/cors-makeheader.php?origin='
+                            + encodeURIComponent(origin),
+                    false)
+        assert_throws(null, function() { client.send() }, 'send')
+    }, 'Disallow origin: ' + origin);
+}
+
+shouldFail(location.protocol + "//" + SUBDOMAIN + "." + location.host)
+shouldFail("//" + location.host)
+shouldFail("://" + location.host)
+shouldFail("ftp://" + location.host)
+shouldFail("http:://" + location.host)
+shouldFail("http:/" + location.host)
+shouldFail("http:" + location.host)
+shouldFail(location.host)
+shouldFail(location.protocol + "//" + location.host + "?")
+shouldFail(location.protocol + "//" + location.host + "/")
+shouldFail(location.protocol + "//" + location.host + " /")
+shouldFail(location.protocol + "//" + location.host + "#")
+shouldFail(location.protocol + "//" + location.host + "%23")
+shouldFail(location.protocol + "//" + location.host + ":80")
+shouldFail(location.protocol + "//" + location.host + ", *")
+shouldFail(location.protocol + "//" + location.host + "\0")
+shouldFail((location.protocol + "//" + location.host).toUpperCase())
+shouldFail(location.protocol.toUpperCase() + "//" + location.host)
+shouldFail("-")
+shouldFail("**")
+shouldFail("\0*")
+shouldFail("*\0")
+shouldFail("'*'")
+shouldFail('"*"')
+shouldFail("* *")
+shouldFail("*" + location.protocol + "//" + "*")
+shouldFail("*" + location.protocol + "//" + location.host)
+shouldFail("* " + location.protocol + "//" + location.host)
+shouldFail("*, " + location.protocol + "//" + location.host)
+shouldFail("\0" + location.protocol + "//" + location.host)
+shouldFail("null " + location.protocol + "//" + location.host)
+shouldFail('http://example.net')
+shouldFail('null')
+shouldFail('')
+shouldFail(location.href)
+shouldFail(dirname(location.href))
+shouldFail(CROSSDOMAIN)
+
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/resources/cors-makeheader.php	Fri Jun 01 18:36:45 2012 +0200
@@ -0,0 +1,50 @@
+<?php
+
+$origin = isset($_GET['origin']) ? $_GET['origin'] : $_SERVER['HTTP_ORIGIN'];
+
+if ($origin != 'none')
+    header("Access-Control-Allow-Origin: $origin");
+
+/* Preflight */
+if (isset($_GET['headers']))
+    header("Access-Control-Allow-Headers: {$_GET['headers']}");
+if (isset($_GET['credentials']))
+    header("Access-Control-Allow-Credentials: {$_GET['credentials']}");
+if (isset($_GET['methods']))
+    header("Access-Control-Allow-Methods: {$_GET['methods']}");
+
+$code = isset($_GET['code']) ? intval($_GET['code']) : null;
+if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS' and isset($_GET['preflight']))
+    $code = intval($_GET['preflight']);
+
+if (isset($_GET['location']))
+{
+    if ($code === null)
+    	$code = 302;
+
+    if ($code < 400 and $code > 299)
+    {
+        header("Location: {$_GET['location']}", true, $code);
+        die("Redirecting");
+    }
+}
+
+foreach ($_SERVER as $name => $value)
+{
+    if (substr($name, 0, 5) == 'HTTP_')
+    {
+        $name = strtolower(str_replace('_', '-', substr($name, 5)));
+        $headers[$name] = $value;
+    } else if ($name == "CONTENT_TYPE") {
+        $headers["content-type"] = $value;
+    } else if ($name == "CONTENT_LENGTH") {
+        $headers["content-length"] = $value;
+    }
+}
+
+$headers['get_value'] = isset($_GET['get_value']) ? $_GET['get_value'] : '';
+
+if ($code)
+    header("HTTP/1.1 {$code} StatusText");
+
+echo json_encode( $headers );
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/status.htm	Fri Jun 01 18:36:45 2012 +0200
@@ -0,0 +1,68 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CORS status</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+
+<h1>The returned status code in different scenarios</h1>
+
+<pre>
+   allowed  preflight  response  | status |
+   -------  ---------  --------  | ------ |
+ 1      no          x       400  |      0 |
+ 2      no        200         x  |      0 |
+ 3     yes          x       400  |    400 |
+ 4     yes        200       400  |    400 |
+ 5     yes        400         x  |      0 |
+</pre>
+
+<div id=log></div>
+
+<script>
+
+    var counter = 0
+
+    function testit(allow, preflight, response, status) {
+        var test = async_test(
+            (++counter) + '. ' +
+            (allow ? 'CORS allowed' : 'CORS disallowed') +
+            (preflight ? ', preflight status '+preflight : '') +
+            (response ? ', response status '+response : '') +
+            '.'
+        )
+
+        test.step(function() {
+            var client = new XMLHttpRequest()
+            client.open('GET', CROSSDOMAIN + 'resources/cors-makeheader.php?' + counter +
+                (allow ? '&headers=x-custom': '&origin=none') +
+                (response ? '&code='+response : '') +
+                (preflight ? '&preflight='+preflight : '')
+            )
+
+            if (preflight)
+                client.setRequestHeader('X-Custom', 'preflight')
+
+            client.onreadystatechange = test.step_func(function(){
+                if (client.readyState > client.OPENED)
+                    assert_equals(client.status, status, "status")
+
+                if (client.readyState == client.DONE)
+                {
+                    test.done()
+                }
+            })
+
+            client.send()
+
+        })
+    }
+
+    /*     allow  pref  resp  status */
+    testit(false, null, 400,  0)
+    testit(false, 200,  null, 0)
+    testit(true,  null, 400,  400)
+    testit(true,  200,  400,  400)
+    testit(true,  400,  null, 0)
+
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/support.js	Fri Jun 01 18:36:45 2012 +0200
@@ -0,0 +1,25 @@
+// For ignoring exception names (just for testing)
+/*
+_real_assert_throws = assert_throws;
+function assert_throws(d, func, desc) {
+    try {
+        func();
+    } catch(e) {
+        return true;
+    }
+    assert_unreached("Didn't throw!");
+}
+*/
+
+function dirname(path) {
+    return path.replace(/\/[^\/]*$/, '/')
+}
+
+/* This subdomain should point to this same location */
+var SUBDOMAIN = 'www1'
+var PORT = "8080"
+var PORT_HTTPS = "8443"
+
+/* Changes http://example.com/abc/def/cool.htm to http://www1.example.com/abc/def/ */
+var CROSSDOMAIN = dirname(location.href)
+    .replace('://', '://' + SUBDOMAIN + '.')