NetworkOverride.sys.mjs (2380B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /** 6 * This modules focuses on redirecting requests to a particular local file. 7 */ 8 9 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; 10 11 import { NetUtil } from "resource://gre/modules/NetUtil.sys.mjs"; 12 13 const lazy = {}; 14 15 ChromeUtils.defineESModuleGetters(lazy, { 16 FileUtils: "resource://gre/modules/FileUtils.sys.mjs", 17 }); 18 19 XPCOMUtils.defineLazyServiceGetter( 20 lazy, 21 "mimeService", 22 "@mozilla.org/mime;1", 23 Ci.nsIMIMEService 24 ); 25 26 function readFile(file) { 27 const fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( 28 Ci.nsIFileInputStream 29 ); 30 fstream.init(file, -1, 0, 0); 31 const data = NetUtil.readInputStreamToString(fstream, fstream.available()); 32 fstream.close(); 33 return data; 34 } 35 36 /** 37 * Given an in-flight channel, we will force to replace the content of this request 38 * with the content of a local file. 39 * 40 * @param {nsIHttpChannel} channel 41 * The request to replace content for. 42 * @param {string} path 43 * The absolute path to the local file to read content from. 44 */ 45 function overrideChannelWithFilePath(channel, path) { 46 // For JS it isn't important, but for HTML we ought to set the right content type on the data URI. 47 let mimeType = ""; 48 try { 49 // getTypeFromURI will throw if there is no extension at the end of the URI 50 mimeType = lazy.mimeService.getTypeFromURI(channel.URI); 51 } catch (e) {} 52 53 // Create a new response. 54 const replacedHttpResponse = Cc[ 55 "@mozilla.org/network/replaced-http-response;1" 56 ].createInstance(Ci.nsIReplacedHttpResponse); 57 58 replacedHttpResponse.responseStatus = 200; 59 replacedHttpResponse.responseStatusText = "OK"; 60 const file = lazy.FileUtils.File(path); 61 replacedHttpResponse.responseBody = readFile(file); 62 if (mimeType) { 63 replacedHttpResponse.setResponseHeader("Content-Type", mimeType, false); 64 } 65 66 // Allow all cross origin requests for overrides. 67 replacedHttpResponse.setResponseHeader( 68 "Access-Control-Allow-Origin", 69 "*", 70 false 71 ); 72 73 channel 74 .QueryInterface(Ci.nsIHttpChannelInternal) 75 .setResponseOverride(replacedHttpResponse); 76 } 77 78 export const NetworkOverride = { 79 overrideChannelWithFilePath, 80 };