test_jarchannel.js (5218B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ 3 */ 4 5 /** 6 * Tests some basic jar channel functionality 7 */ 8 9 const { Constructor: ctor } = Components; 10 11 const { NetUtil } = ChromeUtils.importESModule( 12 "resource://gre/modules/NetUtil.sys.mjs" 13 ); 14 15 const ios = Services.io; 16 const dirSvc = Services.dirsvc; 17 const obs = Services.obs; 18 19 const nsIBinaryInputStream = ctor( 20 "@mozilla.org/binaryinputstream;1", 21 "nsIBinaryInputStream", 22 "setInputStream" 23 ); 24 25 const fileBase = "test_bug637286.zip"; 26 const file = do_get_file("data/" + fileBase); 27 const jarBase = "jar:" + ios.newFileURI(file).spec + "!"; 28 const tmpDir = dirSvc.get("TmpD", Ci.nsIFile); 29 30 function Listener(callback) { 31 this._callback = callback; 32 } 33 Listener.prototype = { 34 gotStartRequest: false, 35 available: -1, 36 gotStopRequest: false, 37 QueryInterface: ChromeUtils.generateQI(["nsIRequestObserver"]), 38 onDataAvailable(request, stream, offset, count) { 39 try { 40 this.available = stream.available(); 41 Assert.equal(this.available, count); 42 // Need to consume stream to avoid assertion 43 new nsIBinaryInputStream(stream).readBytes(count); 44 } catch (ex) { 45 do_throw(ex); 46 } 47 }, 48 onStartRequest() { 49 this.gotStartRequest = true; 50 }, 51 onStopRequest(request, status) { 52 this.gotStopRequest = true; 53 Assert.equal(status, 0); 54 if (this._callback) { 55 this._callback.call(null, this); 56 } 57 }, 58 }; 59 60 /** 61 * Basic reading test for asynchronously opened jar channel 62 */ 63 function testAsync() { 64 var uri = jarBase + "/inner40.zip"; 65 var chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); 66 Assert.less(chan.contentLength, 0); 67 chan.asyncOpen( 68 new Listener(function (l) { 69 Assert.greater(chan.contentLength, 0); 70 Assert.ok(l.gotStartRequest); 71 Assert.ok(l.gotStopRequest); 72 Assert.equal(l.available, chan.contentLength); 73 74 run_next_test(); 75 }) 76 ); 77 } 78 79 add_test(testAsync); 80 // Run same test again so we test the codepath for a zipcache hit 81 add_test(testAsync); 82 83 /** 84 * Basic test for nsIZipReader. 85 */ 86 function testZipEntry() { 87 var uri = jarBase + "/inner40.zip"; 88 var chan = NetUtil.newChannel({ 89 uri, 90 loadUsingSystemPrincipal: true, 91 }).QueryInterface(Ci.nsIJARChannel); 92 var entry = chan.zipEntry; 93 Assert.equal(entry.CRC32, 0x8b635486); 94 Assert.equal(entry.realSize, 184); 95 run_next_test(); 96 } 97 98 add_test(testZipEntry); 99 100 /** 101 * Basic reading test for synchronously opened jar channels 102 */ 103 add_test(function testSync() { 104 var uri = jarBase + "/inner40.zip"; 105 var chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); 106 var stream = chan.open(); 107 Assert.greater(chan.contentLength, 0); 108 Assert.equal(stream.available(), chan.contentLength); 109 stream.close(); 110 stream.close(); // should still not throw 111 112 run_next_test(); 113 }); 114 115 /** 116 * Basic reading test for synchronously opened, nested jar channels 117 */ 118 add_test(function testSyncNested() { 119 var uri = "jar:" + jarBase + "/inner40.zip!/foo"; 120 var chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); 121 var stream = chan.open(); 122 Assert.greater(chan.contentLength, 0); 123 Assert.equal(stream.available(), chan.contentLength); 124 stream.close(); 125 stream.close(); // should still not throw 126 127 run_next_test(); 128 }); 129 130 /** 131 * Basic reading test for asynchronously opened, nested jar channels 132 */ 133 add_test(function testAsyncNested() { 134 var uri = "jar:" + jarBase + "/inner40.zip!/foo"; 135 var chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); 136 chan.asyncOpen( 137 new Listener(function (l) { 138 Assert.greater(chan.contentLength, 0); 139 Assert.ok(l.gotStartRequest); 140 Assert.ok(l.gotStopRequest); 141 Assert.equal(l.available, chan.contentLength); 142 143 run_next_test(); 144 }) 145 ); 146 }); 147 148 /** 149 * Verify that file locks are released when closing a synchronously 150 * opened jar channel stream 151 */ 152 add_test(function testSyncCloseUnlocks() { 153 var copy = tmpDir.clone(); 154 copy.append(fileBase); 155 file.copyTo(copy.parent, copy.leafName); 156 var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip"; 157 var chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); 158 var stream = chan.open(); 159 Assert.greater(chan.contentLength, 0); 160 stream.close(); 161 162 // Drop any jar caches 163 obs.notifyObservers(null, "chrome-flush-caches"); 164 165 try { 166 copy.remove(false); 167 } catch (ex) { 168 do_throw(ex); 169 } 170 171 run_next_test(); 172 }); 173 174 /** 175 * Verify that file locks are released when closing an asynchronously 176 * opened jar channel stream 177 */ 178 add_test(function testAsyncCloseUnlocks() { 179 var copy = tmpDir.clone(); 180 copy.append(fileBase); 181 file.copyTo(copy.parent, copy.leafName); 182 183 var uri = "jar:" + ios.newFileURI(copy).spec + "!/inner40.zip"; 184 var chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); 185 186 chan.asyncOpen( 187 new Listener(function () { 188 Assert.greater(chan.contentLength, 0); 189 190 // Drop any jar caches 191 obs.notifyObservers(null, "chrome-flush-caches"); 192 193 try { 194 copy.remove(false); 195 } catch (ex) { 196 do_throw(ex); 197 } 198 199 run_next_test(); 200 }) 201 ); 202 }); 203 204 function run_test() { 205 return run_next_test(); 206 }