def pac_context_for_url(url="https://www.actlab.org/", proxy_auth=None): """ This context manager provides a simple way to add rudimentary PAC functionality to code that cannot be modified to use :class:`PACSession`, but obeys the ``HTTP_PROXY`` and ``HTTPS_PROXY`` environment variables. Upon entering this context, PAC discovery occurs with default parameters. If a PAC is found, then it's asked for the proxy to use for the given URL. The proxy environment variables are then set accordingly. Note that this provides a very simplified PAC experience that's insufficient for some scenarios. :param url: Consult the PAC for the proxy to use for this URL. Default is "https://www.actlab.org/" :param requests.auth.HTTPProxyAuth proxy_auth: Username and password proxy authentication. """ prev_http_proxy, prev_https_proxy = os.environ.get( 'HTTP_PROXY'), os.environ.get('HTTPS_PROXY') pac = pypac.get_pac() if pac: resolver = pypac.ProxyResolver(pac, proxy_auth=proxy_auth) proxies = resolver.get_proxy_for_requests(url) # Cannot set None for environ. (#27) os.environ['HTTP_PROXY'] = proxies.get('http') or '' os.environ['HTTPS_PROXY'] = proxies.get('https') or '' yield if prev_http_proxy: os.environ['HTTP_PROXY'] = prev_http_proxy elif 'HTTP_PROXY' in os.environ: del os.environ['HTTP_PROXY'] if prev_https_proxy: os.environ['HTTPS_PROXY'] = prev_https_proxy elif 'HTTPS_PROXY' in os.environ: del os.environ['HTTPS_PROXY']
def __init__(self, pac_url: str = None, js: str = None, **kwargs: Any) -> None: super().__init__(**kwargs) if pac_url and "://" not in pac_url: pac_url = "http://" + pac_url self.pac_url = pac_url self._js = js self._pac_file = get_pac( url=pac_url, js=js, allowed_content_types=[ "application/octet-stream", "application/x-ns-proxy-autoconfig", "application/x-javascript-config", ], ) self._resolver = ProxyResolver(self._pac_file)
def __init__(self, pac_url: str = None, js: str = None, **kwargs: Any) -> None: super().__init__(**kwargs) if pac_url and "://" not in pac_url: pac_url = "http://" + pac_url self.pac_url = pac_url self._pac_file = get_pac( url=pac_url, js=js, allowed_content_types=[ "application/octet-stream", "application/x-ns-proxy-autoconfig", "application/x-javascript-config", ], ) self._resolver = ProxyResolver(self._pac_file)
def __init__(self, *, url: str = "", pac_url: str = "") -> None: args: Dict[str, Any] = {} if pac_url: # Load the PAC file as PyPAC won't do it for us if pac_url.startswith("file:"): with open(pac_url.replace("file://", "")) as pac: args["js"] = pac.read() else: args["url"] = pac_url args["allowed_content_types"] = [ "application/octet-stream", "application/x-ns-proxy-autoconfig", "application/x-javascript-config", ] self.pac_url = pac_url self._pac_file = get_pac(**args) self._resolver = ProxyResolver(self._pac_file)
def load_proxy(): # Return if proxies specified in Px config # Check if need to refresh if (State.proxy_mode == MODE_CONFIG or (State.proxy_refresh is not None and time.time() - State.proxy_refresh < State.config.getint("settings", "proxyreload"))): dprint("Skip proxy refresh") return # Reset proxy server list State.proxy_mode = MODE_NONE State.proxy_server = [] # First use pypac for WPAD or PAC config if "pypac" in sys.modules: State.pac = pypac.get_pac() # Fallback for file:/// URLs if State.pac is None: acu = pypac.windows.autoconfig_url_from_registry() if acu: acu = acu.replace("file:///", "") if ":" not in acu: acu = "c:\\" + acu if os.path.isfile(acu): dprint("Loading " + acu) with open(acu, "r") as f: State.pac = pypac.parser.PACFile(f.read()) # Fall back to any manual proxies defined in Internet Options if State.pac is None: parse_proxy(",".join([ urlparse.urlparse(i).netloc for i in set(urlrequest.getproxies().values()) ])) if State.proxy_server: State.proxy_mode = MODE_MANUAL else: State.proxy_mode = MODE_PAC dprint("Proxy mode = " + str(State.proxy_mode)) State.proxy_refresh = time.time()
def _get_proxy_from_pac(url: str, hostname: str) -> Optional[str]: """ Returns: proxy url to use "" if no proxy should be used `None` if no config was found """ # Hack to disable check on content-type (given server might not be well # configured, and `get_pac` silently fails on wrong content-type by returning None) # Also disable WPAD protocol to retrieve PAC from DNS given it produce annoying # WARNING logs get_pac_kwargs: dict = {"from_dns": False, "allowed_content_types": {""}} force_proxy_pac_url = os.environ.get("http_proxy_pac") or os.environ.get( "HTTP_PROXY_PAC") if force_proxy_pac_url: get_pac_kwargs["url"] = force_proxy_pac_url logger.debug( "Retrieving .PAC proxy config url from `HTTP_PROXY_PAC` env var", pac_url=force_proxy_pac_url, ) else: logger.debug("Retrieving .PAC proxy config url from system") try: pacfile = pypac.get_pac(**get_pac_kwargs) except Exception as exc: logger.warning("Error while retrieving .PAC proxy config", exc_info=exc) return None if not pacfile: return None try: proxies = pacfile.find_proxy_for_url(url, hostname) logger.debug("Found proxies info in .PAC proxy config", target_url=url, proxies=proxies) proxies = [p.strip() for p in proxies.split(";")] if len(proxies) > 1: logger.warning( "Found multiple proxies info in .PAC proxy config for target, only the first one is going to be used !", target_url=url, proxies=proxies, ) # We don't handle multiple proxies so keep the first correct one and pray ! for proxy in proxies: if proxy in ("DIRECT", ""): # PAC explicitly told us not to use a proxy return "" elif proxy: # Should be of style `PROXY 8.8.8.8:9999` proxy_type, proxy_netloc = proxy.strip().split() proxy_type = proxy_type.upper() if proxy_type in ("PROXY", "HTTP"): return f"http://{proxy_netloc}" elif proxy_type == "HTTPS": return f"https://{proxy_netloc}" else: logger.warning( "Unsupported proxy type requested by .PAC proxy config", proxy=proxy, target_url=url, ) else: return None except Exception as exc: logger.warning("Error while using .PAC proxy config", target_url=url, exc_info=exc) return None
def target_session(proxy): pac = get_pac(url=proxy, allowed_content_types=['text/plain']) return PACSession(pac)
import os import pypac # PyPAC découvrira automatiquement les paramètres du fichier PAC pac = pypac.get_pac(url='http://127.0.0.1:9000/localproxy.pac') # On récupère le proxy associé à Cloudant (idem, on aurait pu utiliser n'importe quelle autre URL) proxies = pac.find_proxy_for_url('https://rest.apisandbox.zuora.com', 'zuora.com') #proxies = pac.find_proxy_for_url('https://www.google.com', 'google.com') # Ce qui retourne quelque chose comme : 'PROXY 4.5.6.7:8080; PROXY 7.8.9.10:8080' # On prend la premier résultat : proxy = 'http://{}/'.format(proxies.split()[1].rstrip(';')) # On injecte les valeurs dans les variables d'environnement os.environ['HTTP_PROXY'] = os.environ['HTTPS_PROXY'] = proxy