diff options
Diffstat (limited to 'image/test/unit/test_private_channel.js')
-rw-r--r-- | image/test/unit/test_private_channel.js | 167 |
1 files changed, 167 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..46bae8c3aa --- /dev/null +++ b/image/test/unit/test_private_channel.js @@ -0,0 +1,167 @@ +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +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(); + }); + }); + }); + }); +} |