netwerk/test/unit/test_bug248970_cache.js

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

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 Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 // names for cache devices
michael@0 6 const kDiskDevice = "disk";
michael@0 7 const kMemoryDevice = "memory";
michael@0 8 const kOfflineDevice = "appcache";
michael@0 9
michael@0 10 const kCacheA = "http://cache/A";
michael@0 11 const kCacheA2 = "http://cache/A2";
michael@0 12 const kCacheB = "http://cache/B";
michael@0 13 const kCacheC = "http://cache/C";
michael@0 14 const kTestContent = "test content";
michael@0 15
michael@0 16 function make_input_stream_scriptable(input) {
michael@0 17 var wrapper = Cc["@mozilla.org/scriptableinputstream;1"].
michael@0 18 createInstance(Ci.nsIScriptableInputStream);
michael@0 19 wrapper.init(input);
michael@0 20 return wrapper;
michael@0 21 }
michael@0 22
michael@0 23 const entries = [
michael@0 24 // key content device should exist after leaving PB
michael@0 25 [kCacheA, kTestContent, kMemoryDevice, true],
michael@0 26 [kCacheA2, kTestContent, kDiskDevice, false],
michael@0 27 [kCacheB, kTestContent, kDiskDevice, true],
michael@0 28 [kCacheC, kTestContent, kOfflineDevice, true]
michael@0 29 ]
michael@0 30
michael@0 31 var store_idx;
michael@0 32 var store_cb = null;
michael@0 33 var appCache = null;
michael@0 34
michael@0 35 function store_entries(cb)
michael@0 36 {
michael@0 37 if (cb) {
michael@0 38 store_cb = cb;
michael@0 39 store_idx = 0;
michael@0 40 }
michael@0 41
michael@0 42 if (store_idx == entries.length) {
michael@0 43 do_execute_soon(store_cb);
michael@0 44 return;
michael@0 45 }
michael@0 46
michael@0 47 asyncOpenCacheEntry(entries[store_idx][0],
michael@0 48 entries[store_idx][2],
michael@0 49 Ci.nsICacheStorage.OPEN_TRUNCATE,
michael@0 50 LoadContextInfo.custom(!entries[store_idx][3]),
michael@0 51 store_data,
michael@0 52 appCache);
michael@0 53 }
michael@0 54
michael@0 55 var store_data = function(status, entry) {
michael@0 56 do_check_eq(status, Cr.NS_OK);
michael@0 57 var os = entry.openOutputStream(0);
michael@0 58
michael@0 59 var written = os.write(entries[store_idx][1], entries[store_idx][1].length);
michael@0 60 if (written != entries[store_idx][1].length) {
michael@0 61 do_throw("os.write has not written all data!\n" +
michael@0 62 " Expected: " + entries[store_idx][1].length + "\n" +
michael@0 63 " Actual: " + written + "\n");
michael@0 64 }
michael@0 65 os.close();
michael@0 66 entry.close();
michael@0 67 store_idx++;
michael@0 68 do_execute_soon(store_entries);
michael@0 69 };
michael@0 70
michael@0 71 var check_idx;
michael@0 72 var check_cb = null;
michael@0 73 var check_pb_exited;
michael@0 74 function check_entries(cb, pbExited)
michael@0 75 {
michael@0 76 if (cb) {
michael@0 77 check_cb = cb;
michael@0 78 check_idx = 0;
michael@0 79 check_pb_exited = pbExited;
michael@0 80 }
michael@0 81
michael@0 82 if (check_idx == entries.length) {
michael@0 83 do_execute_soon(check_cb);
michael@0 84 return;
michael@0 85 }
michael@0 86
michael@0 87 asyncOpenCacheEntry(entries[check_idx][0],
michael@0 88 entries[check_idx][2],
michael@0 89 Ci.nsICacheStorage.OPEN_READONLY,
michael@0 90 LoadContextInfo.custom(!entries[check_idx][3]),
michael@0 91 check_data,
michael@0 92 appCache);
michael@0 93 }
michael@0 94
michael@0 95 var check_data = function (status, entry) {
michael@0 96 var cont = function() {
michael@0 97 check_idx++;
michael@0 98 do_execute_soon(check_entries);
michael@0 99 }
michael@0 100
michael@0 101 if (!check_pb_exited || entries[check_idx][3]) {
michael@0 102 do_check_eq(status, Cr.NS_OK);
michael@0 103 var is = entry.openInputStream(0);
michael@0 104 pumpReadStream(is, function(read) {
michael@0 105 entry.close();
michael@0 106 do_check_eq(read, entries[check_idx][1]);
michael@0 107 cont();
michael@0 108 });
michael@0 109 } else {
michael@0 110 do_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
michael@0 111 cont();
michael@0 112 }
michael@0 113 };
michael@0 114
michael@0 115 function run_test() {
michael@0 116 // Simulate a profile dir for xpcshell
michael@0 117 do_get_profile();
michael@0 118
michael@0 119 appCache = Cc["@mozilla.org/network/application-cache-service;1"].
michael@0 120 getService(Ci.nsIApplicationCacheService).
michael@0 121 getApplicationCache("fake-client-id|fake-group-id");
michael@0 122
michael@0 123 // Start off with an empty cache
michael@0 124 evict_cache_entries();
michael@0 125
michael@0 126 // Store cache-A, cache-A2, cache-B and cache-C
michael@0 127 store_entries(run_test2);
michael@0 128
michael@0 129 do_test_pending();
michael@0 130 }
michael@0 131
michael@0 132 function run_test2() {
michael@0 133 // Check if cache-A, cache-A2, cache-B and cache-C are available
michael@0 134 check_entries(run_test3, false);
michael@0 135 }
michael@0 136
michael@0 137 function run_test3() {
michael@0 138 // Simulate all private browsing instances being closed
michael@0 139 var obsvc = Cc["@mozilla.org/observer-service;1"].
michael@0 140 getService(Ci.nsIObserverService);
michael@0 141 obsvc.notifyObservers(null, "last-pb-context-exited", null);
michael@0 142
michael@0 143 // Make sure the memory device is not empty
michael@0 144 get_device_entry_count(kMemoryDevice, null, function(count) {
michael@0 145 do_check_eq(count, 1);
michael@0 146 // Check if cache-A is gone, and cache-B and cache-C are still available
michael@0 147 check_entries(do_test_finished, true);
michael@0 148 });
michael@0 149 }

mercurial