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