CORS tests: Add a test on redirects, and one for origins when remote
authorOdin Hørthe Omdal <odinho@opera.com>
Tue, 06 Nov 2012 19:14:14 +0100
changeset 81 accf695c1223
parent 80 f80641f4740c
child 82 4a52799fb77d
CORS tests: Add a test on redirects, and one for origins when remote
tests/cors/submitted/opera/staging/MANIFEST
tests/cors/submitted/opera/staging/redirect-origin.htm
tests/cors/submitted/opera/staging/remote-origin.htm
tests/cors/submitted/opera/staging/support.js
--- a/tests/cors/submitted/opera/staging/MANIFEST	Sun Nov 04 17:35:08 2012 +0100
+++ b/tests/cors/submitted/opera/staging/MANIFEST	Tue Nov 06 19:14:14 2012 +0100
@@ -2,7 +2,9 @@
 credentials-flag.htm
 origin.htm
 preflight-cache.htm
+redirect-origin.htm
 redirect-preflight.htm
+remote_origin.htm
 request-headers.htm
 response-headers.htm
 simple-requests.htm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/redirect-origin.htm	Tue Nov 06 19:14:14 2012 +0100
@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CORS - redirect</title>
+<meta name=author title="Odin Hørthe Omdal" href="mailto:odiho@opera.com">
+
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=support.js></script>
+
+<h1>CORS redirect handling</h1>
+
+<div id=log></div>
+
+<script>
+
+    // Test count for cache busting and easy identifying of request in traffic analyzer
+    var num_test = 0,
+
+        origin         = location.protocol + "//" + location.host,
+        remote_origin  = origin.replace('://', '://' + SUBDOMAIN + '.'),
+
+        local   = dirname(location.href) + 'resources/cors-makeheader.php',
+        remote  = local.replace('://', '://' + SUBDOMAIN + '.'),
+        remote2 = local.replace('://', '://' + SUBDOMAIN2 + '.');
+
+
+    /*           First page           Redirect to          Expect what  */
+
+    // local -> remote
+
+    redir_test([ 'local',  '*'    ], [ 'remote', '*'    ], origin    );
+    redir_test([ 'local',  '*'    ], [ 'remote', origin ], origin    );
+    redir_test([ 'local',  '*'    ], [ 'remote', 'null' ], 'disallow');
+    redir_test([ 'local',  '*'    ], [ 'remote', 'none' ], 'disallow');
+
+    redir_test([ 'local',  origin ], [ 'remote', '*'    ], origin    );
+    redir_test([ 'local',  origin ], [ 'remote', origin ], origin    );
+    redir_test([ 'local',  origin ], [ 'remote', 'null' ], 'disallow');
+    redir_test([ 'local',  origin ], [ 'remote', 'none' ], 'disallow');
+
+    redir_test([ 'local',  'null' ], [ 'remote', '*'    ], origin    );
+    redir_test([ 'local',  'none' ], [ 'remote', '*'    ], origin    );
+
+
+    // remote -> local
+
+    redir_test([ 'remote',  '*'    ], [ 'local', '*'    ], 'null'    );
+    redir_test([ 'remote',  '*'    ], [ 'local', origin ], 'disallow');
+    redir_test([ 'remote',  '*'    ], [ 'local', 'null' ], 'null'    );
+    redir_test([ 'remote',  '*'    ], [ 'local', 'none' ], 'disallow');
+
+    redir_test([ 'remote',  origin ], [ 'local', '*'    ], 'null'    );
+    redir_test([ 'remote',  origin ], [ 'local', origin ], 'disallow');
+    redir_test([ 'remote',  origin ], [ 'local', 'null' ], 'null'    );
+    redir_test([ 'remote',  origin ], [ 'local', 'none' ], 'disallow');
+
+    redir_test([ 'remote',  'null' ], [ 'local', '*'    ], 'disallow');
+    redir_test([ 'remote',  'none' ], [ 'local', '*'    ], 'disallow');
+
+
+    // remote -> remote
+
+    redir_test([ 'remote',  '*'    ], [ 'remote', '*'    ], origin    );
+    redir_test([ 'remote',  '*'    ], [ 'remote', origin ], origin    );
+    redir_test([ 'remote',  '*'    ], [ 'remote', 'null' ], 'disallow');
+    redir_test([ 'remote',  '*'    ], [ 'remote', 'none' ], 'disallow');
+
+    redir_test([ 'remote',  origin ], [ 'remote', '*'    ], origin    );
+    redir_test([ 'remote',  origin ], [ 'remote', origin ], origin    );
+    redir_test([ 'remote',  origin ], [ 'remote', 'null' ], 'disallow');
+    redir_test([ 'remote',  origin ], [ 'remote', 'none' ], 'disallow');
+
+    redir_test([ 'remote',  'null' ], [ 'remote', '*'    ], 'disallow');
+    redir_test([ 'remote',  'none' ], [ 'remote', '*'    ], 'disallow');
+
+
+    // remote -> remote2
+
+    redir_test([ 'remote',  '*'    ], [ 'remote2', '*'    ], 'null'    );
+    redir_test([ 'remote',  '*'    ], [ 'remote2', origin ], 'disallow');
+    redir_test([ 'remote',  '*'    ], [ 'remote2', 'null' ], 'null'    );
+    redir_test([ 'remote',  '*'    ], [ 'remote2', 'none' ], 'disallow');
+
+    redir_test([ 'remote',  origin ], [ 'remote2', '*'    ], 'null'    );
+    redir_test([ 'remote',  origin ], [ 'remote2', origin ], 'disallow');
+    redir_test([ 'remote',  origin ], [ 'remote2', 'null' ], 'null');
+    redir_test([ 'remote',  origin ], [ 'remote2', 'none' ], 'disallow');
+
+    redir_test([ 'remote',  'null' ], [ 'remote2', '*'    ], 'disallow');
+    redir_test([ 'remote',  'none' ], [ 'remote2', '*'    ], 'disallow');
+
+
+    // Bonus weird edge checks
+
+    redir_test([ 'remote', '*'           ], [ 'remote',  remote_origin ], 'disallow');
+    redir_test([ 'remote', '*'           ], [ 'remote2', remote_origin ], 'disallow');
+    redir_test([ 'remote', remote_origin ], [ 'remote',  "*"           ], 'disallow');
+
+
+
+    /*
+     * The helpers
+     */
+
+    function redir_test(first, second, expect_origin) {
+        var first_url, second_url,
+            urls = { "remote": remote, "local": local, "remote2": remote2 };
+
+        first_url = urls[first[0]] + "?origin=" + first[1];
+        second_url = urls[second[0]] + "?origin=" + second[1];
+
+        if (expect_origin=="disallow") {
+            shouldFail(first[0]+" ("+first[1]+") to "
+                + second[0]+" ("+second[1]+"), expect to fail", [ first_url, second_url ]);
+        }
+        else {
+            shouldPass(first[0]+" ("+first[1]+") to "
+                + second[0]+" ("+second[1]+"), expect origin="+expect_origin, expect_origin, [ first_url, second_url ]);
+        }
+
+    }
+
+    function shouldPass(desc, expected_origin, urls) {
+        var test_id = num_test,
+            t = async_test(desc);
+
+        num_test++;
+
+        t.step(function() {
+            var final_url,
+                client = new XMLHttpRequest();
+
+            client.open('GET', buildURL(urls, test_id));
+
+            client.onreadystatechange = t.step_func(function() {
+                if (client.readyState != client.DONE)
+                    return;
+                assert_true(!!client.response, "Got response");
+                r = JSON.parse(client.response)
+                assert_equals(r['origin'], expected_origin, 'Origin Header')
+                assert_equals(r['get_value'], 'last', 'get_value')
+                t.done();
+            });
+            client.send(null)
+        });
+    }
+
+    function shouldFail(desc, urls) {
+        var test_id = num_test,
+            t = async_test(desc);
+
+        num_test++;
+
+        t.step(function() {
+            var client = new XMLHttpRequest();
+
+            client.open('GET', buildURL(urls, test_id));
+
+            client.onreadystatechange = t.step_func(function() {
+                if (client.readyState != client.DONE)
+                    return;
+                assert_false(!!client.response, "Got response");
+            });
+            client.onerror = t.step_func(function(e) {
+                t.done();
+            });
+
+            client.send(null)
+        });
+    }
+
+
+    function buildURL(urls, id) {
+        var tmp_url;
+
+        if (typeof(urls) == "string") {
+            return urls + "&" + id + "_0";
+        }
+
+        for (var i = urls.length; i--; ) {
+            if (!tmp_url)
+            {
+                tmp_url = urls[i] + "&get_value=last&" + id + "_" + i;
+                continue;
+            }
+            tmp_url = urls[i]
+                        + "&location="
+                        + encodeURIComponent(tmp_url)
+                        + "&" + id + "_" + i;
+        }
+
+        return tmp_url;
+    }
+
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/opera/staging/remote-origin.htm	Tue Nov 06 19:14:14 2012 +0100
@@ -0,0 +1,121 @@
+<!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>
+
+var remote_tests = [];
+var iframe = document.createElement("iframe")
+iframe.src = CROSSDOMAIN + 'remote_xhrer.htm';
+document.body.appendChild(iframe);
+
+function reverseOrigin(expect_pass, origin)
+{
+    var real_origin = origin.replace("<host>", REMOTE_HOST)
+                        .replace("<remote_origin>", location.protocol + "//" + location.host)
+                        .replace("<origin>", REMOTE_ORIGIN)
+                        .replace("<protocol>", REMOTE_PROTOCOL)
+                        .replace("<HOST>", REMOTE_HOST.toUpperCase())
+                        .replace("<ORIGIN>", REMOTE_ORIGIN.toUpperCase())
+                        .replace("<PROTOCOL>", REMOTE_PROTOCOL.toUpperCase());
+
+    var t = async_test((expect_pass ? 'Allow origin: ' : 'Disallow origin: ') + real_origin
+                            .replace(/\t/g, "[tab]")
+                            .replace(/ /g, '_'));
+    t.step(function() {
+        this.test_url = dirname(location.href)
+                            + 'resources/cors-makeheader.php?origin='
+                            + encodeURIComponent(real_origin);
+        iframe.contentWindow.postMessage({ url: this.test_url, origin: origin }, "*");
+    });
+
+    if (expect_pass)
+    {
+        t.callback = t.step_func(function(e) {
+            assert_equals(e.state, "load");
+            r = JSON.parse(e.response)
+            assert_equals(r['origin'], REMOTE_ORIGIN, 'Request Origin: should be ' + REMOTE_ORIGIN)
+            this.done();
+        });
+    }
+    else
+    {
+        t.callback = t.step_func(function(e) {
+            if (e.response) console.log(e.response);
+            assert_equals(e.state, "error");
+            assert_equals(e.response, "");
+            this.done();
+        });
+    }
+
+    remote_tests[origin] = t;
+}
+
+function shouldPass(origin) { reverseOrigin(true, origin); }
+function shouldFail(origin) { reverseOrigin(false, origin); }
+
+
+iframe.onload = function() {
+    shouldPass('*');
+    shouldPass(' *  ');
+    shouldPass('	*');
+    shouldPass("<origin>");
+    shouldPass(" <origin>");
+    shouldPass(" <origin>   	 ");
+    shouldPass("	<origin>");
+
+    shouldFail("<remote_origin>")
+    shouldFail("//" + "<host>")
+    shouldFail("://" + "<host>")
+    shouldFail("ftp://" + "<host>")
+    shouldFail("http:://" + "<host>")
+    shouldFail("http:/" + "<host>")
+    shouldFail("http:" + "<host>")
+    shouldFail("<host>")
+    shouldFail("<origin>" + "?")
+    shouldFail("<origin>" + "/")
+    shouldFail("<origin>" + " /")
+    shouldFail("<origin>" + "#")
+    shouldFail("<origin>" + "%23")
+    shouldFail("<origin>" + ":80")
+    shouldFail("<origin>" + ", *")
+    shouldFail("<origin>" + "\0")
+    shouldFail(("<ORIGIN>"))
+    shouldFail("<PROTOCOL>//<host>")
+    shouldFail("<protocol>//<HOST>")
+    shouldFail("-")
+    shouldFail("**")
+    shouldFail("\0*")
+    shouldFail("*\0")
+    shouldFail("'*'")
+    shouldFail('"*"')
+    shouldFail("* *")
+    shouldFail("*" + "<protocol>" + "//" + "*")
+    shouldFail("*" + "<origin>")
+    shouldFail("* " + "<origin>")
+    shouldFail("*, " + "<origin>")
+    shouldFail("\0" + "<origin>")
+    shouldFail("null " + "<origin>")
+    shouldFail('http://example.net')
+    shouldFail('null')
+    shouldFail('')
+    shouldFail(location.href)
+    shouldFail(dirname(location.href))
+    shouldFail(CROSSDOMAIN)
+}
+
+window.addEventListener("message", function(e) {
+    remote_tests[e.data.origin].callback(e.data);
+});
+
+add_completion_callback(function() {
+    iframe.parentElement.removeChild(iframe);
+});
+</script>
--- a/tests/cors/submitted/opera/staging/support.js	Sun Nov 04 17:35:08 2012 +0100
+++ b/tests/cors/submitted/opera/staging/support.js	Tue Nov 06 19:14:14 2012 +0100
@@ -22,5 +22,8 @@
 var PORTS = "83"
 
 /* Changes http://example.com/abc/def/cool.htm to http://www1.example.com/abc/def/ */
-var CROSSDOMAIN = dirname(location.href)
-    .replace('://', '://' + SUBDOMAIN + '.')
+var CROSSDOMAIN     = dirname(location.href)
+                        .replace('://', '://' + SUBDOMAIN + '.')
+var REMOTE_HOST     = SUBDOMAIN + "." + location.host
+var REMOTE_PROTOCOL = location.protocol
+var REMOTE_ORIGIN   = REMOTE_PROTOCOL + "//" + REMOTE_HOST