michael@0: Cu.import("resource://testing-common/httpd.js"); michael@0: michael@0: var httpserv = null; michael@0: var test_nr = 0; michael@0: var observers_called = ""; michael@0: var handlers_called = ""; michael@0: var buffer = ""; michael@0: michael@0: var observer = { michael@0: QueryInterface: function (aIID) { michael@0: if (aIID.equals(Ci.nsISupports) || michael@0: aIID.equals(Ci.nsIObserver)) michael@0: return this; michael@0: throw Cr.NS_ERROR_NO_INTERFACE; michael@0: }, michael@0: michael@0: observe: function(subject, topic, data) { michael@0: if (observers_called.length) michael@0: observers_called += ","; michael@0: michael@0: observers_called += topic; michael@0: } michael@0: }; michael@0: michael@0: var listener = { michael@0: onStartRequest: function (request, ctx) { michael@0: buffer = ""; michael@0: }, michael@0: michael@0: onDataAvailable: function (request, ctx, stream, offset, count) { michael@0: buffer = buffer.concat(read_stream(stream, count)); michael@0: }, michael@0: michael@0: onStopRequest: function (request, ctx, status) { michael@0: do_check_eq(status, Cr.NS_OK); michael@0: do_check_eq(buffer, "0123456789"); michael@0: do_check_eq(observers_called, results[test_nr]); michael@0: test_nr++; michael@0: do_timeout(0, do_test); michael@0: } michael@0: }; michael@0: michael@0: function run_test() { michael@0: httpserv = new HttpServer(); michael@0: httpserv.registerPathHandler("/bug482601/nocache", bug482601_nocache); michael@0: httpserv.registerPathHandler("/bug482601/partial", bug482601_partial); michael@0: httpserv.registerPathHandler("/bug482601/cached", bug482601_cached); michael@0: httpserv.registerPathHandler("/bug482601/only_from_cache", bug482601_only_from_cache); michael@0: httpserv.start(-1); michael@0: michael@0: var obs = Cc["@mozilla.org/observer-service;1"].getService(); michael@0: obs = obs.QueryInterface(Ci.nsIObserverService); michael@0: obs.addObserver(observer, "http-on-examine-response", false); michael@0: obs.addObserver(observer, "http-on-examine-merged-response", false); michael@0: obs.addObserver(observer, "http-on-examine-cached-response", false); michael@0: michael@0: do_timeout(0, do_test); michael@0: do_test_pending(); michael@0: } michael@0: michael@0: function do_test() { michael@0: if (test_nr < tests.length) { michael@0: tests[test_nr](); michael@0: } michael@0: else { michael@0: do_check_eq(handlers_called, "nocache,partial,cached"); michael@0: httpserv.stop(do_test_finished); michael@0: } michael@0: } michael@0: michael@0: var tests = [test_nocache, michael@0: test_partial, michael@0: test_cached, michael@0: test_only_from_cache]; michael@0: michael@0: var results = ["http-on-examine-response", michael@0: "http-on-examine-response,http-on-examine-merged-response", michael@0: "http-on-examine-response,http-on-examine-merged-response", michael@0: "http-on-examine-cached-response"]; michael@0: michael@0: function makeChan(url) { michael@0: var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); michael@0: var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel); michael@0: return chan; michael@0: } michael@0: michael@0: function storeCache(aCacheEntry, aResponseHeads, aContent) { michael@0: aCacheEntry.setMetaDataElement("request-method", "GET"); michael@0: aCacheEntry.setMetaDataElement("response-head", aResponseHeads); michael@0: aCacheEntry.setMetaDataElement("charset", "ISO-8859-1"); michael@0: michael@0: var oStream = aCacheEntry.openOutputStream(0); michael@0: var written = oStream.write(aContent, aContent.length); michael@0: if (written != aContent.length) { michael@0: do_throw("oStream.write has not written all data!\n" + michael@0: " Expected: " + written + "\n" + michael@0: " Actual: " + aContent.length + "\n"); michael@0: } michael@0: oStream.close(); michael@0: aCacheEntry.close(); michael@0: } michael@0: michael@0: function test_nocache() { michael@0: observers_called = ""; michael@0: michael@0: var chan = makeChan("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/nocache"); michael@0: chan.asyncOpen(listener, null); michael@0: } michael@0: michael@0: function test_partial() { michael@0: asyncOpenCacheEntry("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/partial", michael@0: "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null, michael@0: test_partial2); michael@0: } michael@0: michael@0: function test_partial2(status, entry) { michael@0: do_check_eq(status, Cr.NS_OK); michael@0: storeCache(entry, michael@0: "HTTP/1.1 200 OK\r\n" + michael@0: "Date: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + michael@0: "Server: httpd.js\r\n" + michael@0: "Last-Modified: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + michael@0: "Accept-Ranges: bytes\r\n" + michael@0: "Content-Length: 10\r\n" + michael@0: "Content-Type: text/plain\r\n", michael@0: "0123"); michael@0: michael@0: observers_called = ""; michael@0: michael@0: var chan = makeChan("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/partial"); michael@0: chan.asyncOpen(listener, null); michael@0: } michael@0: michael@0: function test_cached() { michael@0: asyncOpenCacheEntry("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/cached", michael@0: "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null, michael@0: test_cached2); michael@0: } michael@0: michael@0: function test_cached2(status, entry) { michael@0: do_check_eq(status, Cr.NS_OK); michael@0: storeCache(entry, michael@0: "HTTP/1.1 200 OK\r\n" + michael@0: "Date: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + michael@0: "Server: httpd.js\r\n" + michael@0: "Last-Modified: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + michael@0: "Accept-Ranges: bytes\r\n" + michael@0: "Content-Length: 10\r\n" + michael@0: "Content-Type: text/plain\r\n", michael@0: "0123456789"); michael@0: michael@0: observers_called = ""; michael@0: michael@0: var chan = makeChan("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/cached"); michael@0: chan.loadFlags = Ci.nsIRequest.VALIDATE_ALWAYS; michael@0: chan.asyncOpen(listener, null); michael@0: } michael@0: michael@0: function test_only_from_cache() { michael@0: asyncOpenCacheEntry("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/only_from_cache", michael@0: "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null, michael@0: test_only_from_cache2); michael@0: } michael@0: michael@0: function test_only_from_cache2(status, entry) { michael@0: do_check_eq(status, Cr.NS_OK); michael@0: storeCache(entry, michael@0: "HTTP/1.1 200 OK\r\n" + michael@0: "Date: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + michael@0: "Server: httpd.js\r\n" + michael@0: "Last-Modified: Thu, 1 Jan 2009 00:00:00 GMT\r\n" + michael@0: "Accept-Ranges: bytes\r\n" + michael@0: "Content-Length: 10\r\n" + michael@0: "Content-Type: text/plain\r\n", michael@0: "0123456789"); michael@0: michael@0: observers_called = ""; michael@0: michael@0: var chan = makeChan("http://localhost:" + httpserv.identity.primaryPort + michael@0: "/bug482601/only_from_cache"); michael@0: chan.loadFlags = Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE; michael@0: chan.asyncOpen(listener, null); michael@0: } michael@0: michael@0: michael@0: // PATHS michael@0: michael@0: // /bug482601/nocache michael@0: function bug482601_nocache(metadata, response) { michael@0: response.setHeader("Content-Type", "text/plain", false); michael@0: var body = "0123456789"; michael@0: response.bodyOutputStream.write(body, body.length); michael@0: handlers_called += "nocache"; michael@0: } michael@0: michael@0: // /bug482601/partial michael@0: function bug482601_partial(metadata, response) { michael@0: do_check_true(metadata.hasHeader("If-Range")); michael@0: do_check_eq(metadata.getHeader("If-Range"), michael@0: "Thu, 1 Jan 2009 00:00:00 GMT"); michael@0: do_check_true(metadata.hasHeader("Range")); michael@0: do_check_eq(metadata.getHeader("Range"), "bytes=4-"); michael@0: michael@0: response.setStatusLine(metadata.httpVersion, 206, "Partial Content"); michael@0: response.setHeader("Content-Range", "bytes 4-9/10", false); michael@0: response.setHeader("Content-Type", "text/plain", false); michael@0: response.setHeader("Last-Modified", "Thu, 1 Jan 2009 00:00:00 GMT"); michael@0: michael@0: var body = "456789"; michael@0: response.bodyOutputStream.write(body, body.length); michael@0: handlers_called += ",partial"; michael@0: } michael@0: michael@0: // /bug482601/cached michael@0: function bug482601_cached(metadata, response) { michael@0: do_check_true(metadata.hasHeader("If-Modified-Since")); michael@0: do_check_eq(metadata.getHeader("If-Modified-Since"), michael@0: "Thu, 1 Jan 2009 00:00:00 GMT"); michael@0: michael@0: response.setStatusLine(metadata.httpVersion, 304, "Not Modified"); michael@0: handlers_called += ",cached"; michael@0: } michael@0: michael@0: // /bug482601/only_from_cache michael@0: function bug482601_only_from_cache(metadata, response) { michael@0: do_throw("This should not be reached"); michael@0: }