1
votes

I'm setting up a Chrome Extension (version 40) for myself and my work colleagues.

One of it's functions is to automatically redirect requests that are received within the browser to our staging server IP address. This allows us to avoid editing host files to switch between staging and production as is currently done. Every minute counts..

Anyway the following script that I set up works perfectly when using the proxy config for HTTP requests. But when trying to run it on sites that request the url using https it fails with the following error.

net::ERR_TUNNEL_CONNECTION_FAILED

Here's the main gist of the code that I've set up so far.

PAC File: https://awesomeurl.com/proxy.pac

function FindProxyForURL(url, host) {
  var domains = ["url1", "url2", "url3", "url4"], // fake company urls
      base = ".awesomecompany.com",
      ii;

  // our local URLs from the domains below example.com don"t need a proxy:

  for(ii=0; ii<domains.length; ii++) {
    if(shExpMatch(host, domains[ii] + base)) {
      return "PROXY 11.111.111.111"; // Fake IP Address
    }
  }
  return "DIRECT";
}

And here's the script that generates the Chrome settings. Persistence is done elsewhere.

/**
 * Checks which value has been selected and generates the proxy config that will
 * be used for the the chrome settings and persisted.
 *
 * @param {string} mode The mode requested by the user
 * @return {ProxyConfig} the proxy configuration reprensented by the user's selections
 * @public
 *
 */
function generateProxyConfig(mode) {
  switch(mode) {
    case proxyValues.NORMAL:
      return { mode: 'system' }

    case 'production':
      return {
        mode: 'pac_script',
        pacScript: {
          url: 'https://awesomeurl.com/proxy.pac',
          mandatory: true
        }
      }
  }
}

function applyChanges ( mode, cb ) {
  config = generateProxyConfig( mode );

  chrome.proxy.settings.set({
    value: config,
    scope: 'regular'
  }, cb );
}

applyChanges('production', function() {console.log('Why doesn't this work for https') })

The only resource I found that was even remotely relevant was this one. It seems to imply that for iOS the PAC file can't be used to redirect HTTPS traffic due to security implications.

I guess I want to see if this is the same with Chrome. Please provide any known potential workarounds.

1
You could bypass the use of a proxy completely by using webRequest API to redirect requests in-flight.Xan
I had looked at that - but I couldn't figure out how to switch out the IP Address in onBeforeRequest. This only seems to be available from onResponseStarted which is too late.ifiokjr

1 Answers

1
votes

Okay - this is a potential solution to the question, just not a very elegant one.

I was able to use the webRequest API as suggested by Xan.

Firstly I added the following permissions to the manifest.json file.

"permissions": [
    "tabs",
    "activeTab",
    "http://*/*",
    "https://*/*",
    "proxy", 
    "webRequest", // new
    "webRequestBlocking" // new
  ],

Then in a new file that runs as soon as the script is loaded. I was able to use the following.

// Let's play around with redirecting all https requests to http
'use strict';

console.info('awesome is here')
var domains = ["url1", "url2", "url3", "url4"], 
    base = ".awesomecompany.com";

chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    console.log(details);
    return {redirectUrl: details.url.replace('https', 'http')};
  }, {urls: domains.map(function(domain) {var url = 'https://' + domain + base + '/*'; return url;})},["blocking"]
);

So basically I'm redirecting all the URLs to http and it's working.

This kind of hack makes me feel very bad inside - but I've already spent too much time hunting for solutions.