<html>
<body>
<p>Test Range support in XMLHttpRequest</p>
<script>
    if (window.testRunner) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
    }

    var console_messages = document.createElement("ul");
    document.body.appendChild(console_messages);

    function log(message)
    {
        var item = document.createElement("li");
        item.appendChild(document.createTextNode(message));
        console_messages.appendChild(item);
    }

    function getRange(url, start, end, useUniqueUrls, fullResponse, done_callback) {
        log("getRange(" + url + ", " + start + ", " + end + ", " + useUniqueUrls + ")");
        var req = new XMLHttpRequest;

        if (useUniqueUrls)
          url = url + "?q=" + start + "-" + end;

        req.open("GET", url, true);
        req.setRequestHeader("Range", "bytes=" + start + "-" + (end - 1));
        req.responseType = 'arraybuffer';
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (req.status != 206)
                    log("Expected a 206 response, got " + req.status);

                var expected = fullResponse.subarray(start, end);
                var actual = new Uint8Array(req.response);
                log("Length : expected " + expected.length + " got " + actual.length);

                if (expected.length == actual.length) {
                    // Verify that all the data is what we expect.
                    for (var i = 0; i < expected.length; ++i) {
                        if (actual[i] != expected[i]) {
                            log("actual[" + i + "] != expected[" + i + "] (" + actual[i] + " != " + expected[i] + ")");
                        }
                    }
                }
                done_callback();
            }
        };
        req.send(null);
    }

    function runRangeTest(useUniqueUrls, done_callback) {
        // First fetch full resource.
        var url = "resources/reply.xml";
        var req = new XMLHttpRequest;
        req.open("GET", url, true);
        req.responseType = 'arraybuffer';
        req.onreadystatechange = function() {
              if (req.readyState == 4) {
                  var fullResponse = new Uint8Array(req.response);
                  var startOffset = fullResponse.length / 2;
                  var endOffset = startOffset + 2;

                  // Next fetch a subrange in the middle of the resource.
                  getRange(url, startOffset, endOffset, useUniqueUrls, fullResponse, function() {

                      // Fetch a different range near the middle of the resource.
                      getRange(url, startOffset + 1, endOffset + 2, useUniqueUrls, fullResponse, function() {
                          done_callback();
                      });
                  });
              }
          };
        req.send(null);
    }

    // First test range requests using the exact same URL.
    runRangeTest(false, function() {
        // Next test w/ a query parameter appended so that each XHR
        // has a unique URL.
        runRangeTest(true, function() {
            if (window.testRunner)
                testRunner.notifyDone();

        });
    });

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