|
|
@@ -2,9 +2,7 @@ OmegaTarget = require('omega-target')
|
|
|
OmegaPac = OmegaTarget.OmegaPac
|
|
|
Promise = OmegaTarget.Promise
|
|
|
querystring = require('querystring')
|
|
|
-chromeApiPromisify = require('./chrome_api').chromeApiPromisify
|
|
|
parseExternalProfile = require('./parse_external_profile')
|
|
|
-ProxyAuth = require('./proxy_auth')
|
|
|
WebRequestMonitor = require('./web_request_monitor')
|
|
|
ChromePort = require('./chrome_port')
|
|
|
fetchUrl = require('./fetch_url')
|
|
|
@@ -73,202 +71,6 @@ class ChromeOptions extends OmegaTarget.Options
|
|
|
chrome.browserAction.setBadgeText?(text: '')
|
|
|
return
|
|
|
|
|
|
- _formatBypassItem: (condition) ->
|
|
|
- str = OmegaPac.Conditions.str(condition)
|
|
|
- i = str.indexOf(' ')
|
|
|
- return str.substr(i + 1)
|
|
|
- _fixedProfileConfig: (profile) ->
|
|
|
- config = {}
|
|
|
- config['mode'] = 'fixed_servers'
|
|
|
- rules = {}
|
|
|
- protocols = ['proxyForHttp', 'proxyForHttps', 'proxyForFtp']
|
|
|
- protocolProxySet = false
|
|
|
- for protocol in protocols when profile[protocol]?
|
|
|
- rules[protocol] = profile[protocol]
|
|
|
- protocolProxySet = true
|
|
|
-
|
|
|
- if profile.fallbackProxy
|
|
|
- if profile.fallbackProxy.scheme == 'http'
|
|
|
- # Chromium does not allow HTTP proxies in 'fallbackProxy'.
|
|
|
- if not protocolProxySet
|
|
|
- # Use 'singleProxy' if no proxy is configured for other protocols.
|
|
|
- rules['singleProxy'] = profile.fallbackProxy
|
|
|
- else
|
|
|
- # Try to set the proxies of all possible protocols.
|
|
|
- for protocol in protocols
|
|
|
- rules[protocol] ?= JSON.parse(JSON.stringify(profile.fallbackProxy))
|
|
|
- else
|
|
|
- rules['fallbackProxy'] = profile.fallbackProxy
|
|
|
- else if not protocolProxySet
|
|
|
- config['mode'] = 'direct'
|
|
|
-
|
|
|
- if config['mode'] != 'direct'
|
|
|
- rules['bypassList'] = bypassList = []
|
|
|
- for condition in profile.bypassList
|
|
|
- bypassList.push(@_formatBypassItem(condition))
|
|
|
- config['rules'] = rules
|
|
|
- return config
|
|
|
-
|
|
|
- _proxyChangeWatchers: null
|
|
|
- _proxyChangeListener: null
|
|
|
- watchProxyChange: (callback) ->
|
|
|
- @_proxyChangeWatchers = []
|
|
|
- if not @_proxyChangeListener?
|
|
|
- @_proxyChangeListener = (details) =>
|
|
|
- for watcher in @_proxyChangeWatchers
|
|
|
- watcher(details)
|
|
|
- if chrome?.proxy?.settings?.onChange?
|
|
|
- chrome.proxy.settings.onChange.addListener @_proxyChangeListener
|
|
|
- @_proxyChangeWatchers.push(callback)
|
|
|
- applyProfileProxy: (profile, meta) ->
|
|
|
- if browser?.proxy?.register? or browser?.proxy?.registerProxyScript?
|
|
|
- return @applyProfileProxyScript(profile, meta)
|
|
|
- else if chrome?.proxy?.settings?
|
|
|
- return @applyProfileProxySettings(profile, meta)
|
|
|
- else
|
|
|
- ex = new Error('Your browser does not support proxy settings!')
|
|
|
- return Promise.reject ex
|
|
|
- applyProfileProxySettings: (profile, meta) ->
|
|
|
- meta ?= profile
|
|
|
- if profile.profileType == 'SystemProfile'
|
|
|
- # Clear proxy settings, returning proxy control to Chromium.
|
|
|
- return chromeApiPromisify(chrome.proxy.settings, 'clear')({}).then =>
|
|
|
- chrome.proxy.settings.get {}, @_proxyChangeListener
|
|
|
- return
|
|
|
- config = {}
|
|
|
- if profile.profileType == 'DirectProfile'
|
|
|
- config['mode'] = 'direct'
|
|
|
- else if profile.profileType == 'PacProfile'
|
|
|
- config['mode'] = 'pac_script'
|
|
|
-
|
|
|
- config['pacScript'] =
|
|
|
- if !profile.pacScript || OmegaPac.Profiles.isFileUrl(profile.pacUrl)
|
|
|
- url: profile.pacUrl
|
|
|
- mandatory: true
|
|
|
- else
|
|
|
- data: OmegaPac.PacGenerator.ascii(profile.pacScript)
|
|
|
- mandatory: true
|
|
|
- else if profile.profileType == 'FixedProfile'
|
|
|
- config = @_fixedProfileConfig(profile)
|
|
|
- else
|
|
|
- config['mode'] = 'pac_script'
|
|
|
- config['pacScript'] =
|
|
|
- data: null
|
|
|
- mandatory: true
|
|
|
- setPacScript = @pacForProfile(profile).then (script) ->
|
|
|
- profileName = OmegaPac.PacGenerator.ascii(JSON.stringify(meta.name))
|
|
|
- profileName = profileName.replace(/\*/g, '\\u002a')
|
|
|
- profileName = profileName.replace(/\\/g, '\\u002f')
|
|
|
- prefix = "/*OmegaProfile*#{profileName}*#{meta.revision}*/"
|
|
|
- config['pacScript'].data = prefix + script
|
|
|
- return
|
|
|
- setPacScript ?= Promise.resolve()
|
|
|
- setPacScript.then(=>
|
|
|
- @_proxyAuth ?= new ProxyAuth(this)
|
|
|
- @_proxyAuth.listen()
|
|
|
- @_proxyAuth.setProxies(@_watchingProfiles)
|
|
|
- chromeApiPromisify(chrome.proxy.settings, 'set')({value: config})
|
|
|
- ).then =>
|
|
|
- chrome.proxy.settings.get {}, @_proxyChangeListener
|
|
|
- return
|
|
|
-
|
|
|
- _proxyScriptUrl: 'js/omega_webext_proxy_script.min.js'
|
|
|
- _proxyScriptDisabled: false
|
|
|
- applyProfileProxyScript: (profile, state) ->
|
|
|
- state = state ? {}
|
|
|
- state.currentProfileName = profile.name
|
|
|
- if profile.name == ''
|
|
|
- state.tempProfile = @_tempProfile
|
|
|
- if profile.profileType == 'SystemProfile'
|
|
|
- # MOZ: SystemProfile cannot be done now due to lack of "PASS" support.
|
|
|
- # https://bugzilla.mozilla.org/show_bug.cgi?id=1319634
|
|
|
- # In the mean time, let's just unregister the script.
|
|
|
- if browser.proxy.unregister?
|
|
|
- browser.proxy.unregister()
|
|
|
- else
|
|
|
- # Some older browers may not ship with .unregister API.
|
|
|
- # In that case, let's just set an invalid script to unregister it.
|
|
|
- browser.proxy.registerProxyScript('js/omega_invalid_proxy_script.js')
|
|
|
- @_proxyScriptDisabled = true
|
|
|
- else
|
|
|
- @_proxyScriptState = state
|
|
|
- Promise.all([
|
|
|
- browser.runtime.getBrowserInfo(),
|
|
|
- @_initWebextProxyScript(),
|
|
|
- ]).then ([info]) =>
|
|
|
- if info.vendor == 'Mozilla' and info.buildID < '20170918220054'
|
|
|
- # MOZ: Legacy proxy support expects PAC-like string return type.
|
|
|
- # TODO(catus): Remove support for string return type.
|
|
|
- @log.error(
|
|
|
- 'Your browser is outdated! SOCKS5 DNS/Auth unsupported! ' +
|
|
|
- "Please update your browser ASAP! (Current Build #{info.buildID})")
|
|
|
- @_proxyScriptState.useLegacyStringReturn = true
|
|
|
- @_proxyScriptStateChanged()
|
|
|
- @_proxyAuth ?= new ProxyAuth(this)
|
|
|
- @_proxyAuth.listen()
|
|
|
- @_proxyAuth.setProxies(@_watchingProfiles)
|
|
|
- return Promise.resolve()
|
|
|
-
|
|
|
- _proxyScriptInitialized: false
|
|
|
- _proxyScriptState: {}
|
|
|
- _initWebextProxyScript: ->
|
|
|
- if not @_proxyScriptInitialized
|
|
|
- browser.proxy.onProxyError.addListener (err) =>
|
|
|
- if err?.message?
|
|
|
- if err.message.indexOf('Invalid Proxy Rule: DIRECT') >= 0
|
|
|
- # DIRECT cannot be parsed in Mozilla earlier due to a bug. Even
|
|
|
- # though it throws, it actually falls back to direct connection
|
|
|
- # so it works.
|
|
|
- # https://bugzilla.mozilla.org/show_bug.cgi?id=1355198
|
|
|
- return
|
|
|
- if err.message.indexOf('Return type must be a string') >= 0
|
|
|
- # MOZ: Legacy proxy support expects PAC-like string return type.
|
|
|
- # TODO(catus): Remove support for string return type.
|
|
|
- #
|
|
|
- @log.error(
|
|
|
- 'Your browser is outdated! SOCKS5 DNS/Auth unsupported! ' +
|
|
|
- 'Please update your browser ASAP!')
|
|
|
- @_proxyScriptState.useLegacyStringReturn = true
|
|
|
- @_proxyScriptStateChanged()
|
|
|
- return
|
|
|
- @log.error(err)
|
|
|
- browser.runtime.onMessage.addListener (message) =>
|
|
|
- return unless message.event == 'proxyScriptLog'
|
|
|
- if message.level == 'error'
|
|
|
- @log.error(message)
|
|
|
- else if message.level == 'warn'
|
|
|
- @log.error(message)
|
|
|
- else
|
|
|
- @log.log(message)
|
|
|
-
|
|
|
- if not @_proxyScriptInitialized or @_proxyScriptDisabled
|
|
|
- promise = new Promise (resolve) ->
|
|
|
- onMessage = (message) ->
|
|
|
- return unless message.event == 'proxyScriptLoaded'
|
|
|
- resolve()
|
|
|
- browser.runtime.onMessage.removeListener onMessage
|
|
|
- return
|
|
|
- browser.runtime.onMessage.addListener onMessage
|
|
|
- # The API has been renamed to .register but for some old browsers' sake:
|
|
|
- if browser.proxy.register?
|
|
|
- browser.proxy.register(@_proxyScriptUrl)
|
|
|
- else
|
|
|
- browser.proxy.registerProxyScript(@_proxyScriptUrl)
|
|
|
- @_proxyScriptDisabled = false
|
|
|
- else
|
|
|
- promise = Promise.resolve()
|
|
|
- @_proxyScriptInitialized = true
|
|
|
- return promise
|
|
|
-
|
|
|
- _proxyScriptStateChanged: ->
|
|
|
- browser.runtime.sendMessage({
|
|
|
- event: 'proxyScriptStateChanged'
|
|
|
- state: @_proxyScriptState
|
|
|
- options: @_options
|
|
|
- }, {
|
|
|
- toProxyScript: true
|
|
|
- })
|
|
|
-
|
|
|
_quickSwitchInit: false
|
|
|
_quickSwitchHandlerReady: false
|
|
|
_quickSwitchCanEnable: false
|
|
|
@@ -478,4 +280,3 @@ class ChromeOptions extends OmegaTarget.Options
|
|
|
}
|
|
|
|
|
|
module.exports = ChromeOptions
|
|
|
-
|