<html>
<body>
<p>Test that a simple cross-origin request to a server that responds (but does not permit cross-origin requests) is indistinguishable from one that does not exist. Should say PASS:</p>
<pre id='console'></pre>
<script type="text/javascript">
    if (window.testRunner) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
    }

    function log(message)
    {
        document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
    }

    var xhr;
    var logExisting;
    var logMissing;

    function doneExisting()
    {
        if (xhr.responseText.length)
            alert("FAIL: Response is not empty, " + xhr.responseText);

        logExisting = document.getElementById('console').innerHTML;
        document.getElementById('console').innerHTML = "";

        xhr = new XMLHttpRequest;
        xhr.onreadystatechange = function() { log("onreadystatechange " + xhr.readyState) }
        xhr.onload = function() { log("onload") }
        xhr.onloadstart = function() { log("onloadstart") }
        xhr.onprogress = function() { log("onprogress") }
        xhr.onerror = function() { log("onerror"); setTimeout(doneMissing, 100); }
        xhr.upload.onabort = function() { log("upload.onabort") }
        xhr.upload.onerror = function() { log("upload.onerror") }
        xhr.upload.onload = function() { log("upload.onload") }
        xhr.upload.onloadstart = function() { log("upload.onloadstart") }
        xhr.upload.onprogress = function() { log("upload.onprogress") }
        xhr.open("POST", "http://localhost:7/", true); // A port that will likely refuse the connection.
        xhr.setRequestHeader("Content-Type", "text/plain");
        xhr.send("Text");
    }

    function doneMissing()
    {
        if (xhr.responseText.length)
            alert("FAIL: Response is not empty, " + xhr.responseText);

        logMissing = document.getElementById('console').innerHTML;
        document.getElementById('console').innerHTML = "";
        
        if (logMissing == logExisting)
            log("PASS");
        else {
            log("FAIL. Responding server:");
            document.getElementById('console').innerHTML += logExisting;
            log("Non-existent server:");
            document.getElementById('console').innerHTML += logMissing;
        }
        if (window.testRunner)
            testRunner.notifyDone();
    }

    xhr = new XMLHttpRequest;
    xhr.onreadystatechange = function() { log("onreadystatechange " + xhr.readyState) }
    xhr.onload = function() { log("onload") }
    xhr.onloadstart = function() { log("onloadstart") }
    xhr.onprogress = function() { log("onprogress") }
    xhr.onerror = function() { log("onerror"); setTimeout(doneExisting, 100); }
    xhr.upload.onabort = function() { log("upload.onabort") }
    xhr.upload.onerror = function() { log("upload.onerror") }
    xhr.upload.onload = function() { log("upload.onload") }
    xhr.upload.onloadstart = function() { log("upload.onloadstart") }
    xhr.upload.onprogress = function() { log("upload.onprogress") }
    xhr.open("POST", "http://localhost:8000/xmlhttprequest/resources/reply.xml", true);
    xhr.setRequestHeader("Content-Type", "text/plain");
    xhr.send("Text");

</script>
</body>
</html>
