Source code for selenium.webdriver.common.proxy

# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

"""The Proxy implementation."""


[docs] class ProxyTypeFactory: """Factory for proxy types."""
[docs] @staticmethod def make(ff_value, string): return {"ff_value": ff_value, "string": string}
[docs] class ProxyType: """Set of possible types of proxy. Each proxy type has 2 properties: 'ff_value' is value of Firefox profile preference, 'string' is id of proxy type. """ DIRECT = ProxyTypeFactory.make(0, "DIRECT") # Direct connection, no proxy (default on Windows). MANUAL = ProxyTypeFactory.make(1, "MANUAL") # Manual proxy settings (e.g., for httpProxy). PAC = ProxyTypeFactory.make(2, "PAC") # Proxy autoconfiguration from URL. RESERVED_1 = ProxyTypeFactory.make(3, "RESERVED1") # Never used. AUTODETECT = ProxyTypeFactory.make(4, "AUTODETECT") # Proxy autodetection (presumably with WPAD). SYSTEM = ProxyTypeFactory.make(5, "SYSTEM") # Use system settings (default on Linux). UNSPECIFIED = ProxyTypeFactory.make(6, "UNSPECIFIED") # Not initialized (for internal use).
[docs] @classmethod def load(cls, value): if isinstance(value, dict) and "string" in value: value = value["string"] value = str(value).upper() for attr in dir(cls): attr_value = getattr(cls, attr) if isinstance(attr_value, dict) and "string" in attr_value and attr_value["string"] == value: return attr_value raise Exception(f"No proxy type is found for {value}")
class _ProxyTypeDescriptor: def __init__(self, name, p_type): self.name = name self.p_type = p_type def __get__(self, obj, cls): return getattr(obj, self.name) def __set__(self, obj, value): if self.name == "autodetect" and not isinstance(value, bool): raise ValueError("Autodetect proxy value needs to be a boolean") getattr(obj, "_verify_proxy_type_compatibility")(self.p_type) setattr(obj, "proxyType", self.p_type) setattr(obj, self.name, value)
[docs] class Proxy: """Proxy configuration containing proxy type and necessary proxy settings.""" proxyType = ProxyType.UNSPECIFIED autodetect = False httpProxy = "" noProxy = "" proxyAutoconfigUrl = "" sslProxy = "" socksProxy = "" socksUsername = "" socksPassword = "" socksVersion = None # create descriptor type objects auto_detect = _ProxyTypeDescriptor("autodetect", ProxyType.AUTODETECT) """Proxy autodetection setting (boolean).""" http_proxy = _ProxyTypeDescriptor("httpProxy", ProxyType.MANUAL) """HTTP proxy address.""" no_proxy = _ProxyTypeDescriptor("noProxy", ProxyType.MANUAL) """Addresses to bypass proxy.""" proxy_autoconfig_url = _ProxyTypeDescriptor("proxyAutoconfigUrl", ProxyType.PAC) """Proxy autoconfiguration URL.""" ssl_proxy = _ProxyTypeDescriptor("sslProxy", ProxyType.MANUAL) """SSL proxy address.""" socks_proxy = _ProxyTypeDescriptor("socksProxy", ProxyType.MANUAL) """SOCKS proxy address.""" socks_username = _ProxyTypeDescriptor("socksUsername", ProxyType.MANUAL) """SOCKS proxy username.""" socks_password = _ProxyTypeDescriptor("socksPassword", ProxyType.MANUAL) """SOCKS proxy password.""" socks_version = _ProxyTypeDescriptor("socksVersion", ProxyType.MANUAL) """SOCKS proxy version.""" def __init__(self, raw: dict | None = None): """Creates a new Proxy. Args: raw: Raw proxy data. If None, default class values are used. """ if raw is None: return if not isinstance(raw, dict): raise TypeError(f"`raw` must be a dict, got {type(raw)}") if raw.get("proxyType"): self.proxy_type = ProxyType.load(raw["proxyType"]) if raw.get("httpProxy"): self.http_proxy = raw["httpProxy"] if raw.get("noProxy"): self.no_proxy = raw["noProxy"] if raw.get("proxyAutoconfigUrl"): self.proxy_autoconfig_url = raw["proxyAutoconfigUrl"] if raw.get("sslProxy"): self.sslProxy = raw["sslProxy"] if raw.get("autodetect"): self.auto_detect = raw["autodetect"] if raw.get("socksProxy"): self.socks_proxy = raw["socksProxy"] if raw.get("socksUsername"): self.socks_username = raw["socksUsername"] if raw.get("socksPassword"): self.socks_password = raw["socksPassword"] if raw.get("socksVersion"): self.socks_version = raw["socksVersion"] @property def proxy_type(self): """Returns proxy type as `ProxyType`.""" return self.proxyType @proxy_type.setter def proxy_type(self, value) -> None: """Sets proxy type. Args: value: The proxy type. """ self._verify_proxy_type_compatibility(value) self.proxyType = value def _verify_proxy_type_compatibility(self, compatible_proxy): if self.proxyType not in (ProxyType.UNSPECIFIED, compatible_proxy): raise ValueError( f"Specified proxy type ({compatible_proxy}) not compatible with current setting ({self.proxyType})" )
[docs] def to_capabilities(self): proxy_caps = {"proxyType": self.proxyType["string"].lower()} proxies = [ "autodetect", "httpProxy", "proxyAutoconfigUrl", "sslProxy", "noProxy", "socksProxy", "socksUsername", "socksPassword", "socksVersion", ] for proxy in proxies: attr_value = getattr(self, proxy) if attr_value: proxy_caps[proxy] = attr_value return proxy_caps
[docs] def to_bidi_dict(self) -> dict: """Convert proxy settings to BiDi format. Returns: Proxy configuration in BiDi format. """ proxy_type = self.proxyType["string"].lower() result = {"proxyType": proxy_type} if proxy_type == "manual": if self.httpProxy: result["httpProxy"] = self.httpProxy if self.sslProxy: result["sslProxy"] = self.sslProxy if self.socksProxy: result["socksProxy"] = self.socksProxy if self.socksVersion is not None: result["socksVersion"] = self.socksVersion if self.noProxy: # Convert comma-separated string to list if isinstance(self.noProxy, str): result["noProxy"] = [host.strip() for host in self.noProxy.split(",") if host.strip()] elif isinstance(self.noProxy, list): if not all(isinstance(h, str) for h in self.noProxy): raise TypeError("no_proxy list must contain only strings") result["noProxy"] = self.noProxy else: raise TypeError("no_proxy must be a comma-separated string or a list of strings") elif proxy_type == "pac": if self.proxyAutoconfigUrl: result["proxyAutoconfigUrl"] = self.proxyAutoconfigUrl return result