test_alt-data_cross_process.js (4092B)
1 /** 2 * Test for the "alternative data stream" stored withing a cache entry. 3 * 4 * - we load a URL with preference for an alt data (check what we get is the raw data, 5 * since there was nothing previously cached) 6 * - we store the alt data along the channel (to the cache entry) 7 * - we flush the HTTP cache 8 * - we reload the same URL using a new channel, again prefering the alt data be loaded 9 * - this time the alt data must arive 10 */ 11 12 "use strict"; 13 14 const { HttpServer } = ChromeUtils.importESModule( 15 "resource://testing-common/httpd.sys.mjs" 16 ); 17 18 ChromeUtils.defineLazyGetter(this, "URL", function () { 19 return "http://localhost:" + httpServer.identity.primaryPort + "/content"; 20 }); 21 22 var httpServer = null; 23 24 function make_channel(url) { 25 return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true }); 26 } 27 28 function inChildProcess() { 29 return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; 30 } 31 32 const responseContent = "response body"; 33 const responseContent2 = "response body 2"; 34 const altContent = "!@#$%^&*()"; 35 const altContentType = "text/binary"; 36 37 var servedNotModified = false; 38 var shouldPassRevalidation = true; 39 40 var cache_storage = null; 41 42 function contentHandler(metadata, response) { 43 response.setHeader("Content-Type", "text/plain"); 44 response.setHeader("Cache-Control", "no-cache"); 45 response.setHeader("ETag", "test-etag1"); 46 47 let etag; 48 try { 49 etag = metadata.getHeader("If-None-Match"); 50 } catch (ex) { 51 etag = ""; 52 } 53 54 if (etag == "test-etag1" && shouldPassRevalidation) { 55 response.setStatusLine(metadata.httpVersion, 304, "Not Modified"); 56 servedNotModified = true; 57 } else { 58 var content = shouldPassRevalidation ? responseContent : responseContent2; 59 response.bodyOutputStream.write(content, content.length); 60 } 61 } 62 63 function check_has_alt_data_in_index(aHasAltData, callback) { 64 if (inChildProcess()) { 65 callback(); 66 return; 67 } 68 69 syncWithCacheIOThread(() => { 70 var hasAltData = {}; 71 cache_storage.getCacheIndexEntryAttrs(createURI(URL), "", hasAltData, {}); 72 Assert.equal(hasAltData.value, aHasAltData); 73 callback(); 74 }, true); 75 } 76 77 // This file is loaded as part of test_alt-data_cross_process_wrap.js. 78 // eslint-disable-next-line no-unused-vars 79 function run_test() { 80 httpServer = new HttpServer(); 81 httpServer.registerPathHandler("/content", contentHandler); 82 httpServer.start(-1); 83 do_test_pending(); 84 85 asyncOpen(); 86 } 87 88 function asyncOpen() { 89 var chan = make_channel(URL); 90 91 var cc = chan.QueryInterface(Ci.nsICacheInfoChannel); 92 cc.preferAlternativeDataType( 93 altContentType, 94 "", 95 Ci.nsICacheInfoChannel.ASYNC 96 ); 97 98 chan.asyncOpen(new ChannelListener(readServerContent, null)); 99 } 100 101 function readServerContent(request, buffer) { 102 var cc = request.QueryInterface(Ci.nsICacheInfoChannel); 103 104 Assert.equal(buffer, responseContent); 105 Assert.equal(cc.alternativeDataType, ""); 106 check_has_alt_data_in_index(false, () => { 107 executeSoon(() => { 108 var os = cc.openAlternativeOutputStream( 109 altContentType, 110 altContent.length 111 ); 112 os.write(altContent, altContent.length); 113 os.close(); 114 115 executeSoon(flushAndOpenAltChannel); 116 }); 117 }); 118 } 119 120 function flushAndOpenAltChannel() { 121 // We need to do a GC pass to ensure the cache entry has been freed. 122 gc(); 123 do_send_remote_message("flush"); 124 do_await_remote_message("flushed").then(() => { 125 openAltChannel(); 126 }); 127 } 128 129 function openAltChannel() { 130 var chan = make_channel(URL); 131 var cc = chan.QueryInterface(Ci.nsICacheInfoChannel); 132 cc.preferAlternativeDataType( 133 altContentType, 134 "", 135 Ci.nsICacheInfoChannel.ASYNC 136 ); 137 138 chan.asyncOpen(new ChannelListener(readAltContent, null)); 139 } 140 141 function readAltContent(request, buffer) { 142 var cc = request.QueryInterface(Ci.nsICacheInfoChannel); 143 144 Assert.equal(servedNotModified, true); 145 Assert.equal(cc.alternativeDataType, altContentType); 146 Assert.equal(buffer, altContent); 147 148 // FINISH 149 do_send_remote_message("done"); 150 do_await_remote_message("finish").then(() => { 151 httpServer.stop(do_test_finished); 152 }); 153 }