summaryrefslogtreecommitdiffstats
path: root/image/test/unit/test_private_channel.js
diff options
context:
space:
mode:
Diffstat (limited to 'image/test/unit/test_private_channel.js')
-rw-r--r--image/test/unit/test_private_channel.js166
1 files changed, 166 insertions, 0 deletions
diff --git a/image/test/unit/test_private_channel.js b/image/test/unit/test_private_channel.js
new file mode 100644
index 0000000000..9ed702baf1
--- /dev/null
+++ b/image/test/unit/test_private_channel.js
@@ -0,0 +1,166 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+
+const ReferrerInfo = Components.Constructor(
+ "@mozilla.org/referrer-info;1",
+ "nsIReferrerInfo",
+ "init"
+);
+
+var server = new HttpServer();
+server.registerPathHandler("/image.png", imageHandler);
+server.start(-1);
+
+/* import-globals-from image_load_helpers.js */
+load("image_load_helpers.js");
+
+var gHits = 0;
+
+var gIoService = Services.io;
+var gPublicLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+ Ci.imgILoader
+);
+var gPrivateLoader = Cc["@mozilla.org/image/loader;1"].createInstance(
+ Ci.imgILoader
+);
+gPrivateLoader.QueryInterface(Ci.imgICache).respectPrivacyNotifications();
+
+var nonPrivateLoadContext = Cu.createLoadContext();
+var privateLoadContext = Cu.createPrivateLoadContext();
+
+function imageHandler(metadata, response) {
+ gHits++;
+ response.setHeader("Cache-Control", "max-age=10000", false);
+ response.setStatusLine(metadata.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "image/png", false);
+ var body = atob(
+ "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
+ );
+ response.bodyOutputStream.write(body, body.length);
+}
+
+var requests = [];
+var listeners = [];
+
+var gImgPath = "http://localhost:" + server.identity.primaryPort + "/image.png";
+
+function setup_chan(path, isPrivate, callback) {
+ var uri = NetUtil.newURI(gImgPath);
+ var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL;
+ var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {
+ privateBrowsingId: isPrivate ? 1 : 0,
+ });
+ var chan = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE,
+ });
+ chan.notificationCallbacks = isPrivate
+ ? privateLoadContext
+ : nonPrivateLoadContext;
+ var channelListener = new ChannelListener();
+ chan.asyncOpen(channelListener);
+
+ var listener = new ImageListener(null, callback);
+ var outlistener = {};
+ var loader = isPrivate ? gPrivateLoader : gPublicLoader;
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ listeners.push(outer);
+ requests.push(
+ loader.loadImageWithChannelXPCOM(chan, outer, null, outlistener)
+ );
+ channelListener.outputListener = outlistener.value;
+ listener.synchronous = false;
+}
+
+function loadImage(isPrivate, callback) {
+ var listener = new ImageListener(null, callback);
+ var outer = Cc["@mozilla.org/image/tools;1"]
+ .getService(Ci.imgITools)
+ .createScriptedObserver(listener);
+ var uri = gIoService.newURI(gImgPath);
+ var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(
+ Ci.nsILoadGroup
+ );
+ loadGroup.notificationCallbacks = isPrivate
+ ? privateLoadContext
+ : nonPrivateLoadContext;
+ var loader = isPrivate ? gPrivateLoader : gPublicLoader;
+ var referrerInfo = new ReferrerInfo(
+ Ci.nsIReferrerInfo.NO_REFERRER_WHEN_DOWNGRADE,
+ true,
+ null
+ );
+ requests.push(
+ loader.loadImageXPCOM(
+ uri,
+ null,
+ referrerInfo,
+ null,
+ loadGroup,
+ outer,
+ null,
+ 0,
+ null
+ )
+ );
+ listener.synchronous = false;
+}
+
+function run_loadImage_tests() {
+ function observer() {
+ Services.obs.removeObserver(observer, "cacheservice:empty-cache");
+ gHits = 0;
+ loadImage(false, function() {
+ loadImage(false, function() {
+ loadImage(true, function() {
+ loadImage(true, function() {
+ Assert.equal(gHits, 2);
+ server.stop(do_test_finished);
+ });
+ });
+ });
+ });
+ }
+
+ for (let loader of [gPublicLoader, gPrivateLoader]) {
+ loader.QueryInterface(Ci.imgICache).clearCache(true);
+ loader.QueryInterface(Ci.imgICache).clearCache(false);
+ }
+ Services.obs.addObserver(observer, "cacheservice:empty-cache");
+ let cs = Services.cache2;
+ cs.clear();
+}
+
+function cleanup() {
+ for (var i = 0; i < requests.length; ++i) {
+ requests[i].cancelAndForgetObserver(0);
+ }
+}
+
+function run_test() {
+ registerCleanupFunction(cleanup);
+
+ do_test_pending();
+
+ Services.prefs.setBoolPref("network.http.rcwn.enabled", false);
+
+ // We create a public channel that loads an image, then an identical
+ // one that should cause a cache read. We then create a private channel
+ // and load the same image, and do that a second time to ensure a cache
+ // read. In total, we should cause two separate http responses to occur,
+ // since the private channels shouldn't be able to use the public cache.
+ setup_chan("/image.png", false, function() {
+ setup_chan("/image.png", false, function() {
+ setup_chan("/image.png", true, function() {
+ setup_chan("/image.png", true, function() {
+ Assert.equal(gHits, 2);
+ run_loadImage_tests();
+ });
+ });
+ });
+ });
+}