Add support for a proxy host PAC url on the General Config/Advanced Settings page.

This commit is contained in:
JackDandy 2015-02-10 04:57:44 +00:00
parent 9f5b00d66c
commit c720c0b913
4 changed files with 83 additions and 13 deletions

View file

@ -23,6 +23,7 @@
* Change corrected spelling & better clarified various log messages
* Change minor PEP8 tweaks in sab.py
* Add api disabled error code for newznab providers
* Add support for a proxy host PAC url on the General Config/Advanced Settings page
[develop changelog]

View file

@ -551,7 +551,8 @@
<span class="component-title">Proxy host</span>
<span class="component-desc">
<input type="text" name="proxy_setting" value="$sickbeard.PROXY_SETTING" class="form-control input-sm input300" />
<div class="clear-left"><p>blank to disable or proxy to use when connecting to providers</p></div>
<p>blank to disable</p>
<div class="clear-left"><p>proxy address for connecting to providers (use 'PAC:Url' for PAC support)</p></div>
</label>
</div>

View file

@ -1236,6 +1236,60 @@ def _getTempDir():
return os.path.join(tempfile.gettempdir(), "SickGear-%s" % (uid))
def proxy_setting(proxy_setting, request_url, force=False):
"""
Returns a list of a) proxy_setting address value or a PAC is fetched and parsed if proxy_setting
starts with "PAC:" (case-insensitive) and b) True/False if "PAC" is found in the proxy_setting.
The PAC data parser is crude, javascript is not eval'd. The first "PROXY URL" found is extracted with a list
of "url_a_part.url_remaining", "url_b_part.url_remaining", "url_n_part.url_remaining" and so on.
Also, PAC data items are escaped for matching therefore regular expression items will not match a request_url.
If force is True or request_url contains a PAC parsed data item then the PAC proxy address is returned else False.
None is returned in the event of an error fetching PAC data.
"""
# check for "PAC" usage
match = re.search(r'^\s*PAC:\s*(.*)', proxy_setting, re.I)
if not match:
return proxy_setting, False
pac_url = match.group(1)
# prevent a recursive test with existing proxy setting when fetching PAC url
proxy_setting_backup = sickbeard.PROXY_SETTING
sickbeard.PROXY_SETTING = ''
resp = ''
try:
resp = getURL(pac_url)
except:
pass
sickbeard.PROXY_SETTING = proxy_setting_backup
if not resp:
return None, False
proxy_address = None
request_url_match = False
for pac_data in re.finditer(r"""(?:[^'"]*['"])([^\.]+\.[^'"]*)(?:['"])""", resp, re.I):
data = re.search(r"""PROXY\s+([^'"]+)""", pac_data.group(1), re.I)
if data:
if force:
return data.group(1), True
proxy_address = (proxy_address, data.group(1))[None is proxy_address]
elif re.search(re.escape(pac_data.group(1)), request_url, re.I):
request_url_match = True
if None is not proxy_address:
break
if None is proxy_address:
return None, True
return (False, proxy_address)[request_url_match], True
def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=None, json=False):
"""
Returns a byte-string retrieved from the url provider.
@ -1265,11 +1319,17 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
# request session proxies
if sickbeard.PROXY_SETTING:
logger.log("Using proxy for url: " + url, logger.DEBUG)
session.proxies = {
"http": sickbeard.PROXY_SETTING,
"https": sickbeard.PROXY_SETTING,
}
(proxy_address, pac_found) = proxy_setting(sickbeard.PROXY_SETTING, url)
msg = '%sproxy for url: %s' % (('', 'PAC parsed ')[pac_found], url)
if None is proxy_address:
logger.log('Proxy error, aborted the request using %s' % msg, logger.DEBUG)
return
elif proxy_address:
logger.log('Using %s' % msg, logger.DEBUG)
session.proxies = {
'http': proxy_address,
'https': proxy_address
}
# decide if we get or post data to server
if post_data:
@ -1316,11 +1376,17 @@ def download_file(url, filename, session=None):
# request session proxies
if sickbeard.PROXY_SETTING:
logger.log("Using proxy for url: " + url, logger.DEBUG)
session.proxies = {
"http": sickbeard.PROXY_SETTING,
"https": sickbeard.PROXY_SETTING,
}
(proxy_address, pac_found) = proxy_setting(sickbeard.PROXY_SETTING, url)
msg = '%sproxy for url: %s' % (('', 'PAC parsed ')[pac_found], url)
if None is proxy_address:
logger.log('Proxy error, aborted the request using %s' % msg, logger.DEBUG)
return
elif proxy_address:
logger.log('Using %s' % msg, logger.DEBUG)
session.proxies = {
'http': proxy_address,
'https': proxy_address
}
try:
resp = session.get(url)

View file

@ -19,7 +19,7 @@ import os
import sickbeard
from indexer_config import initConfig, indexerConfig
from sickbeard.helpers import proxy_setting
class indexerApi(object):
def __init__(self, indexerID=None):
@ -49,7 +49,9 @@ class indexerApi(object):
if sickbeard.CACHE_DIR:
indexerConfig[self.indexerID]['api_params']['cache'] = os.path.join(sickbeard.CACHE_DIR, 'indexers', self.name)
if sickbeard.PROXY_SETTING and sickbeard.PROXY_INDEXERS:
indexerConfig[self.indexerID]['api_params']['proxy'] = sickbeard.PROXY_SETTING
(proxy_address, pac_found) = proxy_setting(sickbeard.PROXY_SETTING, indexerConfig[self.indexerID]['base_url'], force=True)
if proxy_address:
indexerConfig[self.indexerID]['api_params']['proxy'] = proxy_address
return indexerConfig[self.indexerID]['api_params']