Path: blob/trunk/py/selenium/webdriver/common/proxy.py
1864 views
# Licensed to the Software Freedom Conservancy (SFC) under one1# or more contributor license agreements. See the NOTICE file2# distributed with this work for additional information3# regarding copyright ownership. The SFC licenses this file4# to you under the Apache License, Version 2.0 (the5# "License"); you may not use this file except in compliance6# with the License. You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing,11# software distributed under the License is distributed on an12# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13# KIND, either express or implied. See the License for the14# specific language governing permissions and limitations15# under the License.1617"""The Proxy implementation."""1819import warnings202122class ProxyTypeFactory:23"""Factory for proxy types."""2425@staticmethod26def make(ff_value, string):27return {"ff_value": ff_value, "string": string}282930class ProxyType:31"""Set of possible types of proxy.3233Each proxy type has 2 properties: 'ff_value' is value of Firefox34profile preference, 'string' is id of proxy type.35"""3637DIRECT = ProxyTypeFactory.make(0, "DIRECT") # Direct connection, no proxy (default on Windows).38MANUAL = ProxyTypeFactory.make(1, "MANUAL") # Manual proxy settings (e.g., for httpProxy).39PAC = ProxyTypeFactory.make(2, "PAC") # Proxy autoconfiguration from URL.40RESERVED_1 = ProxyTypeFactory.make(3, "RESERVED1") # Never used.41AUTODETECT = ProxyTypeFactory.make(4, "AUTODETECT") # Proxy autodetection (presumably with WPAD).42SYSTEM = ProxyTypeFactory.make(5, "SYSTEM") # Use system settings (default on Linux).43UNSPECIFIED = ProxyTypeFactory.make(6, "UNSPECIFIED") # Not initialized (for internal use).4445@classmethod46def load(cls, value):47if isinstance(value, dict) and "string" in value:48value = value["string"]49value = str(value).upper()50for attr in dir(cls):51attr_value = getattr(cls, attr)52if isinstance(attr_value, dict) and "string" in attr_value and attr_value["string"] == value:53return attr_value54raise Exception(f"No proxy type is found for {value}")555657class _ProxyTypeDescriptor:58def __init__(self, name, p_type):59self.name = name60self.p_type = p_type6162def __get__(self, obj, cls):63return getattr(obj, self.name)6465def __set__(self, obj, value):66if self.name == "autodetect" and not isinstance(value, bool):67raise ValueError("Autodetect proxy value needs to be a boolean")68if self.name == "ftpProxy":69# TODO: Remove ftpProxy in future version and remove deprecation warning70# https://github.com/SeleniumHQ/selenium/issues/1590571warnings.warn(72"ftpProxy is deprecated and will be removed in the future",73DeprecationWarning,74stacklevel=2,75)76getattr(obj, "_verify_proxy_type_compatibility")(self.p_type)77setattr(obj, "proxyType", self.p_type)78setattr(obj, self.name, value)798081class Proxy:82"""Proxy contains information about proxy type and necessary proxy83settings."""8485proxyType = ProxyType.UNSPECIFIED86autodetect = False87ftpProxy = "" # TODO: Remove ftpProxy in future version and remove deprecation warning88httpProxy = ""89noProxy = ""90proxyAutoconfigUrl = ""91sslProxy = ""92socksProxy = ""93socksUsername = ""94socksPassword = ""95socksVersion = None9697# create descriptor type objects98auto_detect = _ProxyTypeDescriptor("autodetect", ProxyType.AUTODETECT)99"""Gets and Sets `auto_detect`100101Usage:102------103- Get104- `self.auto_detect`105- Set106- `self.auto_detect` = `value`107108Parameters:109-----------110`value`: `str`111"""112113# TODO: Remove ftpProxy in future version and remove deprecation warning114ftp_proxy = _ProxyTypeDescriptor("ftpProxy", ProxyType.MANUAL)115"""Gets and Sets `ftp_proxy`116117Usage:118------119- Get120- `self.ftp_proxy`121- Set122- `self.ftp_proxy` = `value`123124Parameters:125-----------126`value`: `str`127"""128129http_proxy = _ProxyTypeDescriptor("httpProxy", ProxyType.MANUAL)130"""Gets and Sets `http_proxy`131132Usage:133------134- Get135- `self.http_proxy`136- Set137- `self.http_proxy` = `value`138139Parameters:140-----------141`value`: `str`142"""143144no_proxy = _ProxyTypeDescriptor("noProxy", ProxyType.MANUAL)145"""Gets and Sets `no_proxy`146147Usage:148------149- Get150- `self.no_proxy`151- Set152- `self.no_proxy` = `value`153154Parameters:155-----------156`value`: `str`157"""158159proxy_autoconfig_url = _ProxyTypeDescriptor("proxyAutoconfigUrl", ProxyType.PAC)160"""Gets and Sets `proxy_autoconfig_url`161162Usage:163------164- Get165- `self.proxy_autoconfig_url`166- Set167- `self.proxy_autoconfig_url` = `value`168169Parameters:170-----------171`value`: `str`172"""173174ssl_proxy = _ProxyTypeDescriptor("sslProxy", ProxyType.MANUAL)175"""Gets and Sets `ssl_proxy`176177Usage:178------179- Get180- `self.ssl_proxy`181- Set182- `self.ssl_proxy` = `value`183184Parameters:185-----------186`value`: `str`187"""188189socks_proxy = _ProxyTypeDescriptor("socksProxy", ProxyType.MANUAL)190"""Gets and Sets `socks_proxy`191192Usage:193------194- Get195- `self.sock_proxy`196- Set197- `self.socks_proxy` = `value`198199Parameters:200-----------201`value`: `str`202"""203204socks_username = _ProxyTypeDescriptor("socksUsername", ProxyType.MANUAL)205"""Gets and Sets `socks_password`206207Usage:208------209- Get210- `self.socks_password`211- Set212- `self.socks_password` = `value`213214Parameters:215-----------216`value`: `str`217"""218219socks_password = _ProxyTypeDescriptor("socksPassword", ProxyType.MANUAL)220"""Gets and Sets `socks_password`221222Usage:223------224- Get225- `self.socks_password`226- Set227- `self.socks_password` = `value`228229Parameters:230-----------231`value`: `str`232"""233234socks_version = _ProxyTypeDescriptor("socksVersion", ProxyType.MANUAL)235"""Gets and Sets `socks_version`236237Usage:238------239- Get240- `self.socks_version`241- Set242- `self.socks_version` = `value`243244Parameters:245-----------246`value`: `str`247"""248249def __init__(self, raw=None):250"""Creates a new Proxy.251252:Args:253- raw: raw proxy data. If None, default class values are used.254"""255if raw:256if "proxyType" in raw and raw["proxyType"]:257self.proxy_type = ProxyType.load(raw["proxyType"])258# TODO: Remove ftpProxy in future version and remove deprecation warning259# https://github.com/SeleniumHQ/selenium/issues/15905260if "ftpProxy" in raw and raw["ftpProxy"]:261warnings.warn(262"ftpProxy is deprecated and will be removed in the future",263DeprecationWarning,264stacklevel=2,265)266self.ftp_proxy = raw["ftpProxy"]267if "httpProxy" in raw and raw["httpProxy"]:268self.http_proxy = raw["httpProxy"]269if "noProxy" in raw and raw["noProxy"]:270self.no_proxy = raw["noProxy"]271if "proxyAutoconfigUrl" in raw and raw["proxyAutoconfigUrl"]:272self.proxy_autoconfig_url = raw["proxyAutoconfigUrl"]273if "sslProxy" in raw and raw["sslProxy"]:274self.sslProxy = raw["sslProxy"]275if "autodetect" in raw and raw["autodetect"]:276self.auto_detect = raw["autodetect"]277if "socksProxy" in raw and raw["socksProxy"]:278self.socks_proxy = raw["socksProxy"]279if "socksUsername" in raw and raw["socksUsername"]:280self.socks_username = raw["socksUsername"]281if "socksPassword" in raw and raw["socksPassword"]:282self.socks_password = raw["socksPassword"]283if "socksVersion" in raw and raw["socksVersion"]:284self.socks_version = raw["socksVersion"]285286@property287def proxy_type(self):288"""Returns proxy type as `ProxyType`."""289return self.proxyType290291@proxy_type.setter292def proxy_type(self, value) -> None:293"""Sets proxy type.294295:Args:296- value: The proxy type.297"""298self._verify_proxy_type_compatibility(value)299self.proxyType = value300301def _verify_proxy_type_compatibility(self, compatible_proxy):302if self.proxyType not in (ProxyType.UNSPECIFIED, compatible_proxy):303raise ValueError(304f"Specified proxy type ({compatible_proxy}) not compatible with current setting ({self.proxyType})"305)306307def to_capabilities(self):308proxy_caps = {"proxyType": self.proxyType["string"].lower()}309# TODO: Remove ftpProxy in future version and remove deprecation warning310proxies = [311"autodetect",312"ftpProxy",313"httpProxy",314"proxyAutoconfigUrl",315"sslProxy",316"noProxy",317"socksProxy",318"socksUsername",319"socksPassword",320"socksVersion",321]322for proxy in proxies:323attr_value = getattr(self, proxy)324if attr_value:325proxy_caps[proxy] = attr_value326return proxy_caps327328def to_bidi_dict(self):329"""Convert proxy settings to BiDi format.330331Returns:332-------333dict: Proxy configuration in BiDi format.334"""335proxy_type = self.proxyType["string"].lower()336result = {"proxyType": proxy_type}337338if proxy_type == "manual":339if self.httpProxy:340result["httpProxy"] = self.httpProxy341if self.sslProxy:342result["sslProxy"] = self.sslProxy343if self.socksProxy:344result["socksProxy"] = self.socksProxy345if self.socksVersion is not None:346result["socksVersion"] = self.socksVersion347if self.noProxy:348# Convert comma-separated string to list349if isinstance(self.noProxy, str):350result["noProxy"] = [host.strip() for host in self.noProxy.split(",") if host.strip()]351elif isinstance(self.noProxy, list):352if not all(isinstance(h, str) for h in self.noProxy):353raise TypeError("no_proxy list must contain only strings")354result["noProxy"] = self.noProxy355else:356raise TypeError("no_proxy must be a comma-separated string or a list of strings")357358elif proxy_type == "pac":359if self.proxyAutoconfigUrl:360result["proxyAutoconfigUrl"] = self.proxyAutoconfigUrl361362return result363364365