0

I want to intercept a request and return a local file as the response using a chrome extension. The user is going to provide the local file path.

Requirements

  • I want to do this only through the extension (ideally). No additional installations, no chrome apps, other 3rd party apps should be needed. I'm happy to provide whatever permissions are needed in the manifest, but this will ship, so it can't be in dev-mode / i.e. can't have dev-only APIs.
  • The files that the user can select aren't going to be from the extension package, I think the chrome.runtime.getURL allows reading from the relative URLs within the package, but it didn't work for exact paths for other files.
  • I'm aware that by setting up a server in either on localhost, or elsewhere and by redirecting to that URL; this could be achieved, but I'm not interested in that; I'm looking for an out of the box solution which will help me pass local files as responses.
  • Also - I'd be happy if there's a workaround - one that I thought was reading the contents of the file that user selected and streaming those contents from memory / or putting them into a temporary location that the file:// can work with, but couldn't find any way around this yet.

Current state

I'm using the snippet below to handle interception:

// API that I'm using
chrome.webRequest.onBeforeRequest.addListener(function(request){...})

Manifest looks like this:

{
   ...
   "background": {
        "scripts": ["background.js"],
        "persistent": true
    },
    "permissions": [
        "activeTab",
        "tabs",
        "http://*/*",
        "https://*/*",
        "file://*/*",
        "webRequest",
        "webRequestBlocking"
    ]
}

I've been able to intercept requests and redirect to other http(s) URLs - this works fine. I'm also receiving the user input for the file path just fine, using <input type="file"/> for this.

Redirecting the request path to be a file doesn't work though; for obvious security reasons. This is the bit that I'm stuck. Being a bit more descriptive below:

chrome.webRequest.onBeforeRequest.addListener(function(request){
   // works fine
   if (request.url === 'https://someurl') {
      return {redirectUrl : 'https://someotherurl'};
   }
   // doesn't work - and I'm looking for a solution for this scenario
   else if (request.url === 'https://someurl2') {
      return {redirectUrl: 'file://somefileondisk' };
   }
});

and this doesn't:

Community
  • 1
  • 1
Mavi Domates
  • 4,262
  • 2
  • 26
  • 45
  • I think that's a misunderstanding of what I was saying, I want to replace these for XHR requests - so if you're asking for an image as part of a page-load / I'm looking to hot-swap that image with something from the local disk – Mavi Domates Jun 14 '20 at 14:13
  • Ah, in that case this is working-as-intended in order to prevent local data exfiltration by web pages. I guess you can redirect to a data URI if the files are small, otherwise you'll have to create a `Blob`, although I don't think the page can read a blob created in an extension's background script so a data URI is probably the only solution. – wOxxOm Jun 14 '20 at 14:23
  • Oh - interesting. Is it possible to copy a file and write it to the extension's package location as a work-around (I'm assuming this is what you're referring when you say you'll have to create a blob) – Mavi Domates Jun 14 '20 at 14:37
  • No, a Blob is a standard DOM API. As for writing into the extension directory, you could do it in Chrome using a separate utility + nativeMessaging API but that would last only until the next update, and Chrome can even mark the extension as corrupted. – wOxxOm Jun 14 '20 at 14:39
  • I'm still a bit confused, because you're referring to the DOM APIs - the user may want to intercept an XHR and replace the response with a local json file - I don't think this is something to do with DOM / I'm guessing blobs won't work there. – Mavi Domates Jun 14 '20 at 14:57
  • I guess you can forget the Blob bit because I doubt it'll work in your case. Actually, there **is** a way to make them work but you'll have to add an extra step: intercept the XHR in [page context](/a/9517879) and re-export the Blob in your content script, which is rather complicated. Something for the future I guess. – wOxxOm Jun 14 '20 at 15:01
  • Ok - so if I'm understanding correctly, there's no way of doing this out of the box, it's likely that I'll have to setup a separate server where the user have to save their replacement response for the local files? – Mavi Domates Jun 14 '20 at 15:20

0 Answers0