<html>
<head>
<script>
if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.dumpChildFramesAsText();
    testRunner.setHandlesAuthenticationChallenges(true);
    testRunner.setAuthenticationUsername("first");
    testRunner.setAuthenticationPassword("first-pw");
    testRunner.waitUntilDone();
}

function firstFrameLoaded()
{
    if (window.testRunner) {
        testRunner.setAuthenticationUsername("second");
        testRunner.setAuthenticationPassword("second-pw");
    }
    var frame = document.createElement("iframe");
    frame.setAttribute("src", "http://127.0.0.1:8000/loading/resources/protected-resource.php");
    frame.setAttribute("onload", "setTimeout(secondFrameLoaded, 0)");
    document.body.appendChild(frame);
}

function secondFrameLoaded()
{
    if (window.testRunner) {
        testRunner.setAuthenticationUsername("third");
        testRunner.setAuthenticationPassword("third-pw");
    }
    var frame = document.createElement("iframe");
    frame.setAttribute("src", "http://127.0.0.1:8000/loading/resources/protected-resource.php");
    frame.setAttribute("onload", "setTimeout(thirdFrameLoaded, 0)");
    document.body.appendChild(frame);
}

function thirdFrameLoaded()
{
    if (window.testRunner) {
        testRunner.setAuthenticationUsername("fourth");
        testRunner.setAuthenticationPassword("fourth-pw");
    }
    var frame = document.createElement("iframe");
    frame.setAttribute("src", "http://127.0.0.1:8000/loading/resources/othersubresources/protected-resource.php");
    frame.setAttribute("onload", "setTimeout(fourthFrameLoaded, 0)");
    document.body.appendChild(frame);
}

function fourthFrameLoaded()
{
    if (window.testRunner)
        testRunner.notifyDone();
}

function makeIFrame() {
    var iframe = document.createElement("iframe");
    iframe.setAttribute("onload", "setTimeout(firstFrameLoaded, 0)");
    iframe.src="resources/subresources/protected-resource.php";
    document.body.appendChild(iframe);
}

</script>
</head>
<body onload="setTimeout(makeIFrame, 0)">
This test makes sure that once an HTTP Basic Auth. protected path is authenticated once, urls that emanate from that path automatically have their credentials sent without a challenge.<br>
The first frame's path is /loading/resources/subresources/protected-resource.php, and we should get a challenge for it.<br>
It will be authorized with first/first-pw.<br>
The second frame's path is /loading/resources/protected-resource.php, and we should get a challenge for it, because it does not share a common subpath of the previously authorized resource.<br>
It will be authorized with second/second-pw.<br>
The third frame's path is also /loading/resources/protected-resource.php, and we should *not* get a challenge for it because we authorized to this path for the second frame.<br>
It will be authorized with second/second-pw.<br>
The fourth frame's path is /loading/resources/othersubresources/protected-resource.php, and we should *not* get a challenge for it, because it has a common subpath with the previously authorized second and third frames.<br>
It will be authorized with second/second-pw.<br>
</body>
</html>
