<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<body>
<p>Test for <a href="http://bugs.webkit.org/show_bug.cgi?id=34653">bug 34653</a>:
XMLHttpRequest should force to send content-type as charset equals UTF-8.</p>
<div id=result1>FAIL: script didn't run to completion.</div>
<div id=result2>FAIL: script didn't run to completion.</div>
<div id=result3>FAIL: script didn't run to completion.</div>
<div id=result4>FAIL: script didn't run to completion.</div>
<script>

    function test1() {
        // Test when content-type is not set.
        req = new XMLHttpRequest;
        req.open("POST", "print-content-type.cgi", false);

        req.send("");

        document.getElementById("result1").firstChild.data = "Test1 (setRequestHeader was not called):";
        if (req.responseText == "text/plain;charset=UTF-8\n")
            document.getElementById("result1").firstChild.data += " SUCCESS";
        else
            document.getElementById("result1").firstChild.data += " FAILURE: '" + req.responseText + "'";
    }

    function test2() {
        // Test when content-type is set without charset.
        req = new XMLHttpRequest;
        req.open("POST", "print-content-type.cgi", false);

        req.setRequestHeader("Content-Type", "application/xml");
        req.send("");

        document.getElementById("result2").firstChild.data = "Test2 (setRequestHeader was called without a charset):";
        if (req.responseText == "application/xml\n")
            document.getElementById("result2").firstChild.data += " SUCCESS";
        else
            document.getElementById("result2").firstChild.data += " FAILURE: '" + req.responseText + "'";
    }

    function test3() {
        // Test when content-type is set with non-UTF-8 charset.
        req = new XMLHttpRequest;
        req.open("POST", "print-content-type.cgi", false);

        req.setRequestHeader("Content-Type", "application/xml; charset=KOI8-R");
        req.send("");

        document.getElementById("result3").firstChild.data = "Test3 (setRequestHeader was called with a non-UTF8 charset):";
        if (req.responseText == "application/xml;charset=UTF-8\n")
            document.getElementById("result3").firstChild.data += " SUCCESS";
        else
            document.getElementById("result3").firstChild.data += " FAILURE: '" + req.responseText + "'";
    }

    function test4() {
        // Test when content-type is set with multiple charsets and other attributes.
        req = new XMLHttpRequest;
        req.open("POST", "print-content-type.cgi", false);

        req.setRequestHeader("Content-Type", "application/xml; charset=KOI8-R; charset=UTF-8; charset=iso-8859-1; KOI8-R");
        req.send("");

        document.getElementById("result4").firstChild.data = "Test4 (setRequestHeader was called with multiple charsets and other attributes):";
        if (req.responseText == "application/xml;charset=UTF-8\n")
            document.getElementById("result4").firstChild.data += " SUCCESS";
        else
            document.getElementById("result4").firstChild.data += " FAILURE: '" + req.responseText + "'";
    }

    if (window.testRunner)
        testRunner.dumpAsText();

    test1();
    test2();
    test3();
    test4();

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