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.js143
1 files changed, 143 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 000000000..960d6d69b
--- /dev/null
+++ b/image/test/unit/test_private_channel.js
@@ -0,0 +1,143 @@
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://testing-common/httpd.js");
+
+var server = new HttpServer();
+server.registerPathHandler('/image.png', imageHandler);
+server.start(-1);
+
+load('image_load_helpers.js');
+
+var gHits = 0;
+
+var gIoService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+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();
+
+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 = "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
+ response.bodyOutputStream.write(body, body.length);
+}
+
+var requests = [];
+var listeners = [];
+
+function NotificationCallbacks(isPrivate) {
+ this.originAttributes.privateBrowsingId = isPrivate ? 1 : 0;
+ this.usePrivateBrowsing = isPrivate;
+}
+
+NotificationCallbacks.prototype = {
+ QueryInterface: function (iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsILoadContext))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+ getInterface: function(iid) {
+ if (iid.equals(Ci.nsILoadContext))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+ originAttributes: {
+ privateBrowsingId: 0
+ }
+};
+
+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_DATA_IS_NULL;
+ var principal = Services.scriptSecurityManager
+ .createCodebasePrincipal(uri, {privateBrowsingId: isPrivate ? 1 : 0});
+ var chan = NetUtil.newChannel({uri: uri, loadingPrincipal: principal,
+ securityFlags: securityFlags,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE});
+ chan.notificationCallbacks = new NotificationCallbacks(isPrivate);
+ var channelListener = new ChannelListener();
+ chan.asyncOpen2(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, null, null);
+ var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup);
+ loadGroup.notificationCallbacks = new NotificationCallbacks(isPrivate);
+ var loader = isPrivate ? gPrivateLoader : gPublicLoader;
+ requests.push(loader.loadImageXPCOM(uri, null, null, "default", 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() {
+ do_check_eq(gHits, 2);
+ server.stop(do_test_finished);
+ });
+ });
+ });
+ });
+ }
+
+ Services.obs.addObserver(observer, "cacheservice:empty-cache", false);
+ let cs = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
+ .getService(Ci.nsICacheStorageService);
+ cs.clear();
+}
+
+function cleanup()
+{
+ for (var i = 0; i < requests.length; ++i) {
+ requests[i].cancelAndForgetObserver(0);
+ }
+}
+
+function run_test() {
+ do_register_cleanup(cleanup);
+
+ do_test_pending();
+
+ // 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() {
+ do_check_eq(gHits, 2);
+ run_loadImage_tests();
+ });
+ });
+ });
+ });
+}