<!DOCTYPE HTML> <html> <head> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <title>Test for Cross Site XMLHttpRequest</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body onload="initTest()"> <p id="display"> <iframe id=loader></iframe> </p> <div id="content" style="display: none"> </div> <pre id="test"> <script class="testbody" type="application/javascript;version=1.8"> const runPreflightTests = 1; const runCookieTests = 1; const runRedirectTests = 1; var gen; function initTest() { SimpleTest.waitForExplicitFinish(); // Allow all cookies, then do the actual test initialization SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, initTestCallback); } function initTestCallback() { window.addEventListener("message", function(e) { gen.send(e.data); }, false); gen = runTest(); gen.next() } function runTest() { var loader = document.getElementById('loader'); var loaderWindow = loader.contentWindow; loader.onload = function () { gen.next() }; // Test preflight-less requests basePath = "/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?" baseURL = "http://mochi.test:8888" + basePath; // Test preflighted requests loader.src = "http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner.html"; origin = "http://example.org"; yield undefined; tests = [// Plain request { pass: 1, method: "GET", noAllowPreflight: 1, }, // undefined username { pass: 1, method: "GET", noAllowPreflight: 1, username: undefined }, // undefined username and password { pass: 1, method: "GET", noAllowPreflight: 1, username: undefined, password: undefined }, // nonempty username { pass: 0, method: "GET", noAllowPreflight: 1, username: "user", }, // nonempty password // XXXbz this passes for now, because we ignore passwords // without usernames in most cases. { pass: 1, method: "GET", noAllowPreflight: 1, password: "password", }, // Default allowed headers { pass: 1, method: "GET", headers: { "Content-Type": "text/plain", "Accept": "foo/bar", "Accept-Language": "sv-SE" }, noAllowPreflight: 1, }, { pass: 0, method: "GET", headers: { "Content-Type": "foo/bar", "Accept": "foo/bar", "Accept-Language": "sv-SE" }, noAllowPreflight: 1, }, { pass: 0, method: "GET", headers: { "Content-Type": "foo/bar, text/plain" }, noAllowPreflight: 1, }, { pass: 0, method: "GET", headers: { "Content-Type": "foo/bar, text/plain, garbage" }, noAllowPreflight: 1, }, // Custom headers { pass: 1, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "X-My-Header", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header": "secondValue" }, allowHeaders: "x-my-header, long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header-long-header", }, { pass: 1, method: "GET", headers: { "x-my%-header": "myValue" }, allowHeaders: "x-my%-header", }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue" }, }, { pass: 0, method: "GET", headers: { "x-my-header": "" }, }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "", }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "y-my-header", }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header y-my-header", }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header, y-my-header z", }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header, y-my-he(ader", }, { pass: 0, method: "GET", headers: { "myheader": "" }, allowMethods: "myheader", }, { pass: 1, method: "GET", headers: { "User-Agent": "myValue" }, allowHeaders: "User-Agent", }, { pass: 0, method: "GET", headers: { "User-Agent": "myValue" }, }, // Multiple custom headers { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "second-header": "secondValue", "third-header": "thirdValue" }, allowHeaders: "x-my-header, second-header, third-header", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "second-header": "secondValue", "third-header": "thirdValue" }, allowHeaders: "x-my-header,second-header,third-header", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "second-header": "secondValue", "third-header": "thirdValue" }, allowHeaders: "x-my-header ,second-header ,third-header", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "second-header": "secondValue", "third-header": "thirdValue" }, allowHeaders: "x-my-header , second-header , third-header", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "second-header": "secondValue" }, allowHeaders: ", x-my-header, , ,, second-header, , ", }, { pass: 1, method: "GET", headers: { "x-my-header": "myValue", "second-header": "secondValue" }, allowHeaders: "x-my-header, second-header, unused-header", }, { pass: 0, method: "GET", headers: { "x-my-header": "myValue", "y-my-header": "secondValue" }, allowHeaders: "x-my-header", }, { pass: 0, method: "GET", headers: { "x-my-header": "", "y-my-header": "" }, allowHeaders: "x-my-header", }, // HEAD requests { pass: 1, method: "HEAD", noAllowPreflight: 1, }, // HEAD with safe headers { pass: 1, method: "HEAD", headers: { "Content-Type": "text/plain", "Accept": "foo/bar", "Accept-Language": "sv-SE" }, noAllowPreflight: 1, }, { pass: 0, method: "HEAD", headers: { "Content-Type": "foo/bar", "Accept": "foo/bar", "Accept-Language": "sv-SE" }, noAllowPreflight: 1, }, { pass: 0, method: "HEAD", headers: { "Content-Type": "foo/bar, text/plain" }, noAllowPreflight: 1, }, { pass: 0, method: "HEAD", headers: { "Content-Type": "foo/bar, text/plain, garbage" }, noAllowPreflight: 1, }, // HEAD with custom headers { pass: 1, method: "HEAD", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 0, method: "HEAD", headers: { "x-my-header": "myValue" }, }, { pass: 0, method: "HEAD", headers: { "x-my-header": "myValue" }, allowHeaders: "", }, { pass: 0, method: "HEAD", headers: { "x-my-header": "myValue" }, allowHeaders: "y-my-header", }, { pass: 0, method: "HEAD", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header y-my-header", }, // POST tests { pass: 1, method: "POST", body: "hi there", noAllowPreflight: 1, }, { pass: 1, method: "POST", }, { pass: 1, method: "POST", noAllowPreflight: 1, }, // POST with standard headers { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain" }, noAllowPreflight: 1, }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "multipart/form-data" }, noAllowPreflight: 1, }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "application/x-www-form-urlencoded" }, noAllowPreflight: 1, }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar" }, }, { pass: 0, method: "POST", headers: { "Content-Type": "foo/bar" }, }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "Accept": "foo/bar", "Accept-Language": "sv-SE" }, noAllowPreflight: 1, }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar, text/plain" }, noAllowPreflight: 1, }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar, text/plain, garbage" }, noAllowPreflight: 1, }, // POST with custom headers { pass: 1, method: "POST", body: "hi there", headers: { "Accept": "foo/bar", "Accept-Language": "sv-SE", "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 1, method: "POST", headers: { "Content-Type": "text/plain", "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar", "x-my-header": "myValue" }, allowHeaders: "x-my-header, content-type", }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar" }, noAllowPreflight: 1, }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar", "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 1, method: "POST", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header", }, { pass: 1, method: "POST", body: "hi there", headers: { "x-my-header": "myValue" }, allowHeaders: "x-my-header, $_%", }, // Other methods { pass: 1, method: "DELETE", allowMethods: "DELETE", }, { pass: 0, method: "DELETE", allowHeaders: "DELETE", }, { pass: 0, method: "DELETE", }, { pass: 0, method: "DELETE", allowMethods: "", }, { pass: 1, method: "DELETE", allowMethods: "POST, PUT, DELETE", }, { pass: 1, method: "DELETE", allowMethods: "POST, DELETE, PUT", }, { pass: 1, method: "DELETE", allowMethods: "DELETE, POST, PUT", }, { pass: 1, method: "DELETE", allowMethods: "POST ,PUT ,DELETE", }, { pass: 1, method: "DELETE", allowMethods: "POST,PUT,DELETE", }, { pass: 1, method: "DELETE", allowMethods: "POST , PUT , DELETE", }, { pass: 1, method: "DELETE", allowMethods: " ,, PUT ,, , , DELETE , ,", }, { pass: 0, method: "DELETE", allowMethods: "PUT", }, { pass: 0, method: "DELETE", allowMethods: "DELETEZ", }, { pass: 0, method: "DELETE", allowMethods: "DELETE PUT", }, { pass: 0, method: "DELETE", allowMethods: "DELETE, PUT Z", }, { pass: 0, method: "DELETE", allowMethods: "DELETE, PU(T", }, { pass: 0, method: "DELETE", allowMethods: "PUT DELETE", }, { pass: 0, method: "DELETE", allowMethods: "PUT Z, DELETE", }, { pass: 0, method: "DELETE", allowMethods: "PU(T, DELETE", }, { pass: 0, method: "MYMETHOD", allowMethods: "myMethod", }, { pass: 0, method: "PUT", allowMethods: "put", }, // Progress events { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain" }, uploadProgress: "progress", }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain" }, uploadProgress: "progress", noAllowPreflight: 1, }, // Status messages { pass: 1, method: "GET", noAllowPreflight: 1, status: 404, statusMessage: "nothin' here", }, { pass: 1, method: "GET", noAllowPreflight: 1, status: 401, statusMessage: "no can do", }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "foo/bar" }, allowHeaders: "content-type", status: 500, statusMessage: "server boo", }, { pass: 1, method: "GET", noAllowPreflight: 1, status: 200, statusMessage: "Yes!!", }, { pass: 0, method: "GET", headers: { "x-my-header": "header value" }, allowHeaders: "x-my-header", preflightStatus: 400 }, { pass: 1, method: "GET", headers: { "x-my-header": "header value" }, allowHeaders: "x-my-header", preflightStatus: 200 }, { pass: 1, method: "GET", headers: { "x-my-header": "header value" }, allowHeaders: "x-my-header", preflightStatus: 204 }, // exposed headers { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header" }, exposeHeaders: "x-my-header", expectedResponseHeaders: ["x-my-header"], }, { pass: 0, method: "GET", origin: "http://invalid", responseHeaders: { "x-my-header": "x header" }, exposeHeaders: "x-my-header", expectedResponseHeaders: [], }, { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header" }, expectedResponseHeaders: [], }, { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header" }, exposeHeaders: "x-my-header y", expectedResponseHeaders: [], }, { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header" }, exposeHeaders: "y x-my-header", expectedResponseHeaders: [], }, { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header" }, exposeHeaders: "x-my-header, y-my-header z", expectedResponseHeaders: [], }, { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header" }, exposeHeaders: "x-my-header, y-my-hea(er", expectedResponseHeaders: [], }, { pass: 1, method: "GET", responseHeaders: { "x-my-header": "x header", "y-my-header": "y header" }, exposeHeaders: " , ,,y-my-header,z-my-header, ", expectedResponseHeaders: ["y-my-header"], }, { pass: 1, method: "GET", responseHeaders: { "Cache-Control": "cacheControl header", "Content-Language": "contentLanguage header", "Expires":"expires header", "Last-Modified":"lastModified header", "Pragma":"pragma header", "Unexpected":"unexpected header" }, expectedResponseHeaders: ["Cache-Control","Content-Language","Content-Type","Expires","Last-Modified","Pragma"], }, // Check that sending a body in the OPTIONS response works { pass: 1, method: "DELETE", allowMethods: "DELETE", preflightBody: "I'm a preflight response body", }, ]; if (!runPreflightTests) { tests = []; } for (test of tests) { var req = { url: baseURL + "allowOrigin=" + escape(test.origin || origin), method: test.method, headers: test.headers, uploadProgress: test.uploadProgress, body: test.body, responseHeaders: test.responseHeaders, }; if (test.pass) { req.url += "&origin=" + escape(origin) + "&requestMethod=" + test.method; } if ("username" in test) { req.username = test.username; } if ("password" in test) { req.password = test.password; } if (test.noAllowPreflight) req.url += "&noAllowPreflight"; if (test.pass && "headers" in test) { function isUnsafeHeader(name) { lName = name.toLowerCase(); return lName != "accept" && lName != "accept-language" && (lName != "content-type" || ["text/plain", "multipart/form-data", "application/x-www-form-urlencoded"] .indexOf(test.headers[name].toLowerCase()) == -1); } req.url += "&headers=" + escape(test.headers.toSource()); reqHeaders = escape(Object.keys(test.headers) .filter(isUnsafeHeader) .map(String.toLowerCase) .sort() .join(",")); req.url += reqHeaders ? "&requestHeaders=" + reqHeaders : ""; } if ("allowHeaders" in test) req.url += "&allowHeaders=" + escape(test.allowHeaders); if ("allowMethods" in test) req.url += "&allowMethods=" + escape(test.allowMethods); if (test.body) req.url += "&body=" + escape(test.body); if (test.status) { req.url += "&status=" + test.status; req.url += "&statusMessage=" + escape(test.statusMessage); } if (test.preflightStatus) req.url += "&preflightStatus=" + test.preflightStatus; if (test.responseHeaders) req.url += "&responseHeaders=" + escape(test.responseHeaders.toSource()); if (test.exposeHeaders) req.url += "&exposeHeaders=" + escape(test.exposeHeaders); if (test.preflightBody) req.url += "&preflightBody=" + escape(test.preflightBody); loaderWindow.postMessage(req.toSource(), origin); res = eval(yield); if (test.pass) { is(res.didFail, false, "shouldn't have failed in test for " + test.toSource()); if (test.status) { is(res.status, test.status, "wrong status in test for " + test.toSource()); is(res.statusText, test.statusMessage, "wrong status text for " + test.toSource()); } else { is(res.status, 200, "wrong status in test for " + test.toSource()); is(res.statusText, "OK", "wrong status text for " + test.toSource()); } if (test.method !== "HEAD") { is(res.responseXML, "<res>hello pass</res>", "wrong responseXML in test for " + test.toSource()); is(res.responseText, "<res>hello pass</res>\n", "wrong responseText in test for " + test.toSource()); is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs3,rs4,load,loadend", "wrong responseText in test for " + test.toSource()); } else { is(res.responseXML, null, "wrong responseXML in test for " + test.toSource()); is(res.responseText, "", "wrong responseText in test for " + test.toSource()); is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs4,load,loadend", "wrong responseText in test for " + test.toSource()); } if (test.responseHeaders) { for (header in test.responseHeaders) { if (test.expectedResponseHeaders.indexOf(header) == -1) { is(res.responseHeaders[header], null, "|xhr.getResponseHeader()|wrong response header (" + header + ") in test for " + test.toSource()); is(res.allResponseHeaders[header], undefined, "|xhr.getAllResponseHeaderss()|wrong response header (" + header + ") in test for " + test.toSource()); } else { is(res.responseHeaders[header], test.responseHeaders[header], "|xhr.getResponseHeader()|wrong response header (" + header + ") in test for " + test.toSource()); is(res.allResponseHeaders[header.toLowerCase()], test.responseHeaders[header], "|xhr.getAllResponseHeaderss()|wrong response header (" + header + ") in test for " + test.toSource()); } } } } else { is(res.didFail, true, "should have failed in test for " + test.toSource()); is(res.status, 0, "wrong status in test for " + test.toSource()); is(res.statusText, "", "wrong status text for " + test.toSource()); is(res.responseXML, null, "wrong responseXML in test for " + test.toSource()); is(res.responseText, "", "wrong responseText in test for " + test.toSource()); if (!res.sendThrew) { if (test.username) { is(res.events.join(","), "opening,rs1,sending,loadstart,rs4,error,loadend", "wrong events in test for " + test.toSource()); } else { is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs4,error,loadend", "wrong events in test for " + test.toSource()); } } is(res.progressEvents, 0, "wrong events in test for " + test.toSource()); if (test.responseHeaders) { for (header in test.responseHeaders) { is(res.responseHeaders[header], null, "wrong response header (" + header + ") in test for " + test.toSource()); } } } } // Test cookie behavior tests = [{ pass: 1, method: "GET", withCred: 1, allowCred: 1, }, { pass: 0, method: "GET", withCred: 1, allowCred: 0, }, { pass: 0, method: "GET", withCred: 1, allowCred: 1, origin: "*", }, { pass: 1, method: "GET", withCred: 0, allowCred: 1, origin: "*", }, { pass: 1, method: "GET", setCookie: "a=1", withCred: 1, allowCred: 1, }, { pass: 1, method: "GET", cookie: "a=1", withCred: 1, allowCred: 1, }, { pass: 1, method: "GET", noCookie: 1, withCred: 0, allowCred: 1, }, { pass: 0, method: "GET", noCookie: 1, withCred: 1, allowCred: 1, }, { pass: 1, method: "GET", setCookie: "a=2", withCred: 0, allowCred: 1, }, { pass: 1, method: "GET", cookie: "a=1", withCred: 1, allowCred: 1, }, { pass: 1, method: "GET", setCookie: "a=2", withCred: 1, allowCred: 1, }, { pass: 1, method: "GET", cookie: "a=2", withCred: 1, allowCred: 1, }, ]; if (!runCookieTests) { tests = []; } for (test of tests) { req = { url: baseURL + "allowOrigin=" + escape(test.origin || origin), method: test.method, headers: test.headers, withCred: test.withCred, }; if (test.allowCred) req.url += "&allowCred"; if (test.setCookie) req.url += "&setCookie=" + escape(test.setCookie); if (test.cookie) req.url += "&cookie=" + escape(test.cookie); if (test.noCookie) req.url += "&noCookie"; if ("allowHeaders" in test) req.url += "&allowHeaders=" + escape(test.allowHeaders); if ("allowMethods" in test) req.url += "&allowMethods=" + escape(test.allowMethods); loaderWindow.postMessage(req.toSource(), origin); res = eval(yield); if (test.pass) { is(res.didFail, false, "shouldn't have failed in test for " + test.toSource()); is(res.status, 200, "wrong status in test for " + test.toSource()); is(res.statusText, "OK", "wrong status text for " + test.toSource()); is(res.responseXML, "<res>hello pass</res>", "wrong responseXML in test for " + test.toSource()); is(res.responseText, "<res>hello pass</res>\n", "wrong responseText in test for " + test.toSource()); is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs3,rs4,load,loadend", "wrong responseText in test for " + test.toSource()); } else { is(res.didFail, true, "should have failed in test for " + test.toSource()); is(res.status, 0, "wrong status in test for " + test.toSource()); is(res.statusText, "", "wrong status text for " + test.toSource()); is(res.responseXML, null, "wrong responseXML in test for " + test.toSource()); is(res.responseText, "", "wrong responseText in test for " + test.toSource()); is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs4,error,loadend", "wrong events in test for " + test.toSource()); is(res.progressEvents, 0, "wrong events in test for " + test.toSource()); } } // Make sure to clear cookies to avoid affecting other tests document.cookie = "a=; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT" is(document.cookie, "", "No cookies should be left over"); // Test redirects is(loader.src, "http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner.html"); is(origin, "http://example.org"); tests = [{ pass: 1, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://example.org", allowOrigin: origin }, ], }, { pass: 1, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://example.org", allowOrigin: "*" }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://example.org", }, ], }, { pass: 1, method: "GET", hops: [{ server: "http://example.org", }, { server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.org", }, { server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin }, { server: "http://example.org", }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://test2.example.org:8000", allowOrigin: origin }, { server: "http://sub2.xn--lt-uia.example.org", allowOrigin: origin }, { server: "http://sub1.test1.example.org", allowOrigin: origin }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://test2.example.org:8000", allowOrigin: origin }, { server: "http://sub2.xn--lt-uia.example.org", allowOrigin: "*" }, { server: "http://sub1.test1.example.org", allowOrigin: "*" }, ], }, { pass: 1, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://test2.example.org:8000", allowOrigin: "*" }, { server: "http://sub2.xn--lt-uia.example.org", allowOrigin: "*" }, { server: "http://sub1.test1.example.org", allowOrigin: "*" }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://test2.example.org:8000", allowOrigin: origin }, { server: "http://sub2.xn--lt-uia.example.org", allowOrigin: "x" }, { server: "http://sub1.test1.example.org", allowOrigin: origin }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://test2.example.org:8000", allowOrigin: origin }, { server: "http://sub2.xn--lt-uia.example.org", allowOrigin: "*" }, { server: "http://sub1.test1.example.org", allowOrigin: origin }, ], }, { pass: 0, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin }, { server: "http://test2.example.org:8000", allowOrigin: origin }, { server: "http://sub2.xn--lt-uia.example.org", allowOrigin: "*" }, { server: "http://sub1.test1.example.org", }, ], }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain" }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, }, ], }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowHeaders: "my-header", }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowHeaders: "my-header", }, { server: "http://sub1.test1.example.org", allowOrigin: origin, allowHeaders: "my-header", }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowHeaders: "my-header", }, { server: "http://example.com", allowOrigin: origin, allowHeaders: "my-header", }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowHeaders: "my-header", }, { server: "http://example.org", allowOrigin: origin, allowHeaders: "my-header", }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, noAllowPreflight: 1, }, ], }, { pass: 1, method: "DELETE", hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowMethods: "DELETE", }, ], }, { pass: 0, method: "DELETE", hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowMethods: "DELETE", }, { server: "http://sub1.test1.example.org", allowOrigin: origin, allowMethods: "DELETE", }, ], }, { pass: 0, method: "DELETE", hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowMethods: "DELETE", }, { server: "http://example.com", allowOrigin: origin, allowMethods: "DELETE", }, ], }, { pass: 0, method: "DELETE", hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowMethods: "DELETE", }, { server: "http://example.org", allowOrigin: origin, allowMethods: "DELETE", }, ], }, { pass: 0, method: "DELETE", hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, allowMethods: "DELETE", noAllowPreflight: 1, }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.com", allowOrigin: origin, }, { server: "http://sub1.test1.example.org", allowOrigin: origin, }, ], }, { pass: 0, method: "DELETE", hops: [{ server: "http://example.com", allowOrigin: origin, }, { server: "http://sub1.test1.example.org", allowOrigin: origin, }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.com", }, { server: "http://sub1.test1.example.org", allowOrigin: origin, allowHeaders: "my-header", }, ], }, { pass: 1, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain" }, hops: [{ server: "http://example.org", }, { server: "http://example.com", allowOrigin: origin, }, ], }, { pass: 0, method: "POST", body: "hi there", headers: { "Content-Type": "text/plain", "my-header": "myValue", }, hops: [{ server: "http://example.com", allowOrigin: origin, allowHeaders: "my-header", }, { server: "http://example.org", allowOrigin: origin, allowHeaders: "my-header", }, ], }, // test redirects with different credentials settings { // Initialize by setting a cookies for same- and cross- origins. pass: 1, method: "GET", hops: [{ server: origin, setCookie: escape("a=1"), }, { server: "http://example.com", allowOrigin: origin, allowCred: 1, setCookie: escape("a=2"), }, ], withCred: 1, }, { pass: 1, method: "GET", hops: [{ server: origin, cookie: escape("a=1"), }, { server: origin, cookie: escape("a=1"), }, { server: "http://example.com", allowOrigin: origin, noCookie: 1, }, ], withCred: 0, }, { pass: 1, method: "GET", hops: [{ server: origin, cookie: escape("a=1"), }, { server: origin, cookie: escape("a=1"), }, { server: "http://example.com", allowOrigin: origin, allowCred: 1, cookie: escape("a=2"), }, ], withCred: 1, }, // expected fail because allow-credentials CORS header is not set { pass: 0, method: "GET", hops: [{ server: origin, cookie: escape("a=1"), }, { server: origin, cookie: escape("a=1"), }, { server: "http://example.com", allowOrigin: origin, cookie: escape("a=2"), }, ], withCred: 1, }, { pass: 1, method: "GET", hops: [{ server: origin, cookie: escape("a=1"), }, { server: origin, cookie: escape("a=1"), }, { server: "http://example.com", allowOrigin: '*', noCookie: 1, }, ], withCred: 0, }, { pass: 0, method: "GET", hops: [{ server: origin, cookie: escape("a=1"), }, { server: origin, cookie: escape("a=1"), }, { server: "http://example.com", allowOrigin: '*', allowCred: 1, cookie: escape("a=2"), }, ], withCred: 1, }, ]; if (!runRedirectTests) { tests = []; } for (test of tests) { req = { url: test.hops[0].server + basePath + "hop=1&hops=" + escape(test.hops.toSource()), method: test.method, headers: test.headers, body: test.body, withCred: test.withCred, }; if (test.pass) { if (test.body) req.url += "&body=" + escape(test.body); } loaderWindow.postMessage(req.toSource(), origin); res = eval(yield); if (test.pass) { is(res.didFail, false, "shouldn't have failed in test for " + test.toSource()); is(res.status, 200, "wrong status in test for " + test.toSource()); is(res.statusText, "OK", "wrong status text for " + test.toSource()); is(res.responseXML, "<res>hello pass</res>", "wrong responseXML in test for " + test.toSource()); is(res.responseText, "<res>hello pass</res>\n", "wrong responseText in test for " + test.toSource()); is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs3,rs4,load,loadend", "wrong responseText in test for " + test.toSource()); } else { is(res.didFail, true, "should have failed in test for " + test.toSource()); is(res.status, 0, "wrong status in test for " + test.toSource()); is(res.statusText, "", "wrong status text for " + test.toSource()); is(res.responseXML, null, "wrong responseXML in test for " + test.toSource()); is(res.responseText, "", "wrong responseText in test for " + test.toSource()); is(res.events.join(","), "opening,rs1,sending,loadstart,rs2,rs4,error,loadend", "wrong events in test for " + test.toSource()); is(res.progressEvents, 0, "wrong progressevents in test for " + test.toSource()); } } SimpleTest.finish(); yield undefined; } </script> </pre> </body> </html>