Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | // This file tests nsIContentSniffer, introduced in bug 324985 |
michael@0 | 2 | |
michael@0 | 3 | Cu.import("resource://testing-common/httpd.js"); |
michael@0 | 4 | |
michael@0 | 5 | const unknownType = "application/x-unknown-content-type"; |
michael@0 | 6 | const sniffedType = "application/x-sniffed"; |
michael@0 | 7 | |
michael@0 | 8 | const snifferCID = Components.ID("{4c93d2db-8a56-48d7-b261-9cf2a8d998eb}"); |
michael@0 | 9 | const snifferContract = "@mozilla.org/network/unittest/contentsniffer;1"; |
michael@0 | 10 | const categoryName = "net-content-sniffers"; |
michael@0 | 11 | |
michael@0 | 12 | var sniffing_enabled = true; |
michael@0 | 13 | |
michael@0 | 14 | /** |
michael@0 | 15 | * This object is both a factory and an nsIContentSniffer implementation (so, it |
michael@0 | 16 | * is de-facto a service) |
michael@0 | 17 | */ |
michael@0 | 18 | var sniffer = { |
michael@0 | 19 | QueryInterface: function sniffer_qi(iid) { |
michael@0 | 20 | if (iid.equals(Components.interfaces.nsISupports) || |
michael@0 | 21 | iid.equals(Components.interfaces.nsIFactory) || |
michael@0 | 22 | iid.equals(Components.interfaces.nsIContentSniffer)) |
michael@0 | 23 | return this; |
michael@0 | 24 | throw Components.results.NS_ERROR_NO_INTERFACE; |
michael@0 | 25 | }, |
michael@0 | 26 | createInstance: function sniffer_ci(outer, iid) { |
michael@0 | 27 | if (outer) |
michael@0 | 28 | throw Components.results.NS_ERROR_NO_AGGREGATION; |
michael@0 | 29 | return this.QueryInterface(iid); |
michael@0 | 30 | }, |
michael@0 | 31 | lockFactory: function sniffer_lockf(lock) { |
michael@0 | 32 | throw Components.results.NS_ERROR_NOT_IMPLEMENTED; |
michael@0 | 33 | }, |
michael@0 | 34 | |
michael@0 | 35 | getMIMETypeFromContent: function (request, data, length) { |
michael@0 | 36 | return sniffedType; |
michael@0 | 37 | } |
michael@0 | 38 | }; |
michael@0 | 39 | |
michael@0 | 40 | var listener = { |
michael@0 | 41 | onStartRequest: function test_onStartR(request, ctx) { |
michael@0 | 42 | try { |
michael@0 | 43 | var chan = request.QueryInterface(Components.interfaces.nsIChannel); |
michael@0 | 44 | if (chan.contentType == unknownType) |
michael@0 | 45 | do_throw("Type should not be unknown!"); |
michael@0 | 46 | if (sniffing_enabled && this._iteration > 2 && |
michael@0 | 47 | chan.contentType != sniffedType) { |
michael@0 | 48 | do_throw("Expecting <" + sniffedType +"> but got <" + |
michael@0 | 49 | chan.contentType + "> for " + chan.URI.spec); |
michael@0 | 50 | } else if (!sniffing_enabled && chan.contentType == sniffedType) { |
michael@0 | 51 | do_throw("Sniffing not enabled but sniffer called for " + chan.URI.spec); |
michael@0 | 52 | } |
michael@0 | 53 | } catch (e) { |
michael@0 | 54 | do_throw("Unexpected exception: " + e); |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | throw Components.results.NS_ERROR_ABORT; |
michael@0 | 58 | }, |
michael@0 | 59 | |
michael@0 | 60 | onDataAvailable: function test_ODA() { |
michael@0 | 61 | throw Components.results.NS_ERROR_UNEXPECTED; |
michael@0 | 62 | }, |
michael@0 | 63 | |
michael@0 | 64 | onStopRequest: function test_onStopR(request, ctx, status) { |
michael@0 | 65 | run_test_iteration(this._iteration); |
michael@0 | 66 | do_test_finished(); |
michael@0 | 67 | }, |
michael@0 | 68 | |
michael@0 | 69 | _iteration: 1 |
michael@0 | 70 | }; |
michael@0 | 71 | |
michael@0 | 72 | function makeChan(url) { |
michael@0 | 73 | var ios = Components.classes["@mozilla.org/network/io-service;1"] |
michael@0 | 74 | .getService(Components.interfaces.nsIIOService); |
michael@0 | 75 | var chan = ios.newChannel(url, null, null); |
michael@0 | 76 | if (sniffing_enabled) |
michael@0 | 77 | chan.loadFlags |= Components.interfaces.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS; |
michael@0 | 78 | |
michael@0 | 79 | return chan; |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | var httpserv = null; |
michael@0 | 83 | var urls = null; |
michael@0 | 84 | |
michael@0 | 85 | function run_test() { |
michael@0 | 86 | httpserv = new HttpServer(); |
michael@0 | 87 | httpserv.start(-1); |
michael@0 | 88 | |
michael@0 | 89 | urls = [ |
michael@0 | 90 | // NOTE: First URL here runs without our content sniffer |
michael@0 | 91 | "data:" + unknownType + ", Some text", |
michael@0 | 92 | "data:" + unknownType + ", Text", // Make sure sniffing works even if we |
michael@0 | 93 | // used the unknown content sniffer too |
michael@0 | 94 | "data:text/plain, Some more text", |
michael@0 | 95 | "http://localhost:" + httpserv.identity.primaryPort |
michael@0 | 96 | ]; |
michael@0 | 97 | |
michael@0 | 98 | Components.manager.nsIComponentRegistrar.registerFactory(snifferCID, |
michael@0 | 99 | "Unit test content sniffer", snifferContract, sniffer); |
michael@0 | 100 | |
michael@0 | 101 | run_test_iteration(1); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | function run_test_iteration(index) { |
michael@0 | 105 | if (index > urls.length) { |
michael@0 | 106 | if (sniffing_enabled) { |
michael@0 | 107 | sniffing_enabled = false; |
michael@0 | 108 | index = listener._iteration = 1; |
michael@0 | 109 | } else { |
michael@0 | 110 | do_test_pending(); |
michael@0 | 111 | httpserv.stop(do_test_finished); |
michael@0 | 112 | return; // we're done |
michael@0 | 113 | } |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | if (sniffing_enabled && index == 2) { |
michael@0 | 117 | // Register our sniffer only here |
michael@0 | 118 | // This also makes sure that dynamic registration is working |
michael@0 | 119 | var catMan = Components.classes["@mozilla.org/categorymanager;1"] |
michael@0 | 120 | .getService(Components.interfaces.nsICategoryManager); |
michael@0 | 121 | catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test", |
michael@0 | 122 | snifferContract, false, true); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | var chan = makeChan(urls[index - 1]); |
michael@0 | 126 | |
michael@0 | 127 | listener._iteration++; |
michael@0 | 128 | chan.asyncOpen(listener, null); |
michael@0 | 129 | |
michael@0 | 130 | do_test_pending(); |
michael@0 | 131 | } |
michael@0 | 132 |