/** * Helper script for mixed content testing. It opens a new top-level window * from a secure origin and '?runtest' query. That tells us to run the test * body, function runTest(). Then we wait for call of finish(). On its first * call it loads helper page 'backward.html' that immediately navigates * back to the test secure test. This checks the bfcache. We got second call * to onload and this time we call afterNavigationTest() function to let the * test check security state after re-navigation back. Then we again wait for * finish() call, that this time finishes completelly the test. */ // Tells the framework if to load the test in an insecure page (http://) var loadAsInsecure = false; // Set true to bypass the navigation forward/back test var bypassNavigationTest = false; // Set true to do forward/back navigation over an http:// page, test state leaks var navigateToInsecure = false; // Open the test in two separate windows, test requests sharing among windows var openTwoWindows = false; // Override the name of the test page to load, useful e.g. to prevent load // of images or other content before the test starts; this is actually // a 'redirect' to a different test page. var testPage = ""; // Assign a function to this variable to have a clean up at the end var testCleanUp = null; // Internal variables var _windowCount = 0; window.onload = function onLoad() { if (location.search == "?runtest") { try { if (history.length == 1) runTest(); else afterNavigationTest(); } catch (ex) { ok(false, "Exception thrown during test: " + ex); finish(); } } else { window.addEventListener("message", onMessageReceived, false); var secureTestLocation; if (loadAsInsecure) secureTestLocation = "http://example.com"; else secureTestLocation = "https://example.com"; secureTestLocation += location.pathname if (testPage != "") { array = secureTestLocation.split("/"); array.pop(); array.push(testPage); secureTestLocation = array.join("/"); } secureTestLocation += "?runtest"; if (openTwoWindows) { _windowCount = 2; window.open(secureTestLocation, "_new1", ""); window.open(secureTestLocation, "_new2", ""); } else { _windowCount = 1; window.open(secureTestLocation); } } } function onMessageReceived(event) { switch (event.data) { // Indication of all test parts finish (from any of the frames) case "done": if (--_windowCount == 0) { if (testCleanUp) testCleanUp(); SimpleTest.finish(); } break; // Any other message indicates error or succes message of a test default: var failureRegExp = new RegExp("^FAILURE"); var todoRegExp = new RegExp("^TODO"); if (event.data.match(todoRegExp)) SimpleTest.todo(false, event.data); else SimpleTest.ok(!event.data.match(failureRegExp), event.data); break; } } function postMsg(message) { opener.postMessage(message, "http://mochi.test:8888"); } function finish() { if (history.length == 1 && !bypassNavigationTest) { window.setTimeout(function() { window.location.assign(navigateToInsecure ? "http://example.com/tests/security/ssl/mixedcontent/backward.html" : "https://example.com/tests/security/ssl/mixedcontent/backward.html"); }, 0); } else { postMsg("done"); window.close(); } } function ok(a, message) { if (!a) postMsg("FAILURE: " + message); else postMsg(message); } function is(a, b, message) { if (a != b) postMsg("FAILURE: " + message + ", expected "+b+" got "+a); else postMsg(message + ", expected "+b+" got "+a); } function todo(a, message) { if (a) postMsg("FAILURE: TODO works? " + message); else postMsg("TODO: " + message); } function todoSecurityState(expectedState, message) { isSecurityState(expectedState, message, todo); } function isSecurityState(expectedState, message, test) { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); if (!test) test = ok; // Quit nasty but working :) var ui = window .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell) .securityUI; var isInsecure = !ui || (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_INSECURE); var isBroken = ui && (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_BROKEN); var isEV = ui && (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL); var gotState; if (isInsecure) gotState = "insecure"; else if (isBroken) gotState = "broken"; else if (isEV) gotState = "EV"; else gotState = "secure"; test(gotState == expectedState, (message || "") + ", " + "expected " + expectedState + " got " + gotState); switch (expectedState) { case "insecure": test(isInsecure && !isBroken && !isEV, "for 'insecure' excpected flags [1,0,0], " + (message || "")); break; case "broken": test(ui && !isInsecure && isBroken && !isEV, "for 'broken' expected flags [0,1,0], " + (message || "")); break; case "secure": test(ui && !isInsecure && !isBroken && !isEV, "for 'secure' expected flags [0,0,0], " + (message || "")); break; case "EV": test(ui && !isInsecure && !isBroken && isEV, "for 'EV' expected flags [0,0,1], " + (message || "")); break; default: throw "Invalid isSecurityState state"; } } function waitForSecurityState(expectedState, callback) { var roundsLeft = 200; // Wait for 20 seconds (=200*100ms) var interval = window.setInterval(function() { isSecurityState(expectedState, "", function(isok) {if (isok) {roundsLeft = 0;}}); if (!roundsLeft--) { window.clearInterval(interval); callback(); } }, 100); }