diff options
Diffstat (limited to 'netwerk/test/unit/test_resumable_truncate.js')
-rw-r--r-- | netwerk/test/unit/test_resumable_truncate.js | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_resumable_truncate.js b/netwerk/test/unit/test_resumable_truncate.js new file mode 100644 index 000000000..c23a91b71 --- /dev/null +++ b/netwerk/test/unit/test_resumable_truncate.js @@ -0,0 +1,88 @@ +Cu.import("resource://testing-common/httpd.js"); +Cu.import("resource://gre/modules/NetUtil.jsm"); + +var httpserver = null; + +function make_channel(url, callback, ctx) { + return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true}); +} + +const responseBody = "response body"; + +function cachedHandler(metadata, response) { + var body = responseBody; + if (metadata.hasHeader("Range")) { + var matches = metadata.getHeader("Range").match(/^\s*bytes=(\d+)?-(\d+)?\s*$/); + var from = (matches[1] === undefined) ? 0 : matches[1]; + var to = (matches[2] === undefined) ? responseBody.length - 1 : matches[2]; + if (from >= responseBody.length) { + response.setStatusLine(metadata.httpVersion, 416, "Start pos too high"); + response.setHeader("Content-Range", "*/" + responseBody.length, false); + return; + } + body = responseBody.slice(from, to + 1); + // always respond to successful range requests with 206 + response.setStatusLine(metadata.httpVersion, 206, "Partial Content"); + response.setHeader("Content-Range", from + "-" + to + "/" + responseBody.length, false); + } + + response.setHeader("Content-Type", "text/plain", false); + response.setHeader("ETag", "Just testing"); + response.setHeader("Accept-Ranges", "bytes"); + + response.bodyOutputStream.write(body, body.length); +} + +function Canceler(continueFn) { + this.continueFn = continueFn; +} + +Canceler.prototype = { + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIStreamListener) || + iid.equals(Ci.nsIRequestObserver) || + iid.equals(Ci.nsISupports)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + onStartRequest: function(request, context) { + }, + + onDataAvailable: function(request, context, stream, offset, count) { + request.QueryInterface(Ci.nsIChannel) + .cancel(Components.results.NS_BINDING_ABORTED); + }, + + onStopRequest: function(request, context, status) { + do_check_eq(status, Components.results.NS_BINDING_ABORTED); + this.continueFn(); + } +}; + +function finish_test() { + httpserver.stop(do_test_finished); +} + +function start_cache_read() { + var chan = make_channel("http://localhost:" + + httpserver.identity.primaryPort + "/cached/test.gz"); + chan.asyncOpen2(new ChannelListener(finish_test, null)); +} + +function start_canceler() { + var chan = make_channel("http://localhost:" + + httpserver.identity.primaryPort + "/cached/test.gz"); + chan.asyncOpen2(new Canceler(start_cache_read)); +} + +function run_test() { + httpserver = new HttpServer(); + httpserver.registerPathHandler("/cached/test.gz", cachedHandler); + httpserver.start(-1); + + var chan = make_channel("http://localhost:" + + httpserver.identity.primaryPort + "/cached/test.gz"); + chan.asyncOpen2(new ChannelListener(start_canceler, null)); + do_test_pending(); +} |