You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
358 lines
11 KiB
Python
358 lines
11 KiB
Python
![]()
2 years ago
|
# 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.
|
||
|
"""
|
||
|
|
||
|
|
||
|
class ProxyTypeFactory:
|
||
|
"""
|
||
|
Factory for proxy types.
|
||
|
"""
|
||
|
|
||
|
@staticmethod
|
||
|
def make(ff_value, string):
|
||
|
return {"ff_value": ff_value, "string": string}
|
||
|
|
||
|
|
||
|
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).
|
||
|
|
||
|
@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 Proxy:
|
||
|
"""
|
||
|
Proxy contains information about proxy type and necessary proxy settings.
|
||
|
"""
|
||
|
|
||
|
proxyType = ProxyType.UNSPECIFIED
|
||
|
autodetect = False
|
||
|
ftpProxy = ""
|
||
|
httpProxy = ""
|
||
|
noProxy = ""
|
||
|
proxyAutoconfigUrl = ""
|
||
|
sslProxy = ""
|
||
|
socksProxy = ""
|
||
|
socksUsername = ""
|
||
|
socksPassword = ""
|
||
|
socksVersion = None
|
||
|
|
||
|
def __init__(self, raw=None):
|
||
|
"""
|
||
|
Creates a new Proxy.
|
||
|
|
||
|
:Args:
|
||
|
- raw: raw proxy data. If None, default class values are used.
|
||
|
"""
|
||
|
if raw:
|
||
|
if "proxyType" in raw and raw["proxyType"]:
|
||
|
self.proxy_type = ProxyType.load(raw["proxyType"])
|
||
|
if "ftpProxy" in raw and raw["ftpProxy"]:
|
||
|
self.ftp_proxy = raw["ftpProxy"]
|
||
|
if "httpProxy" in raw and raw["httpProxy"]:
|
||
|
self.http_proxy = raw["httpProxy"]
|
||
|
if "noProxy" in raw and raw["noProxy"]:
|
||
|
self.no_proxy = raw["noProxy"]
|
||
|
if "proxyAutoconfigUrl" in raw and raw["proxyAutoconfigUrl"]:
|
||
|
self.proxy_autoconfig_url = raw["proxyAutoconfigUrl"]
|
||
|
if "sslProxy" in raw and raw["sslProxy"]:
|
||
|
self.sslProxy = raw["sslProxy"]
|
||
|
if "autodetect" in raw and raw["autodetect"]:
|
||
|
self.auto_detect = raw["autodetect"]
|
||
|
if "socksProxy" in raw and raw["socksProxy"]:
|
||
|
self.socks_proxy = raw["socksProxy"]
|
||
|
if "socksUsername" in raw and raw["socksUsername"]:
|
||
|
self.socks_username = raw["socksUsername"]
|
||
|
if "socksPassword" in raw and raw["socksPassword"]:
|
||
|
self.socks_password = raw["socksPassword"]
|
||
|
if "socksVersion" in raw and raw["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
|
||
|
|
||
|
@property
|
||
|
def auto_detect(self):
|
||
|
"""
|
||
|
Returns autodetect setting.
|
||
|
"""
|
||
|
return self.autodetect
|
||
|
|
||
|
@auto_detect.setter
|
||
|
def auto_detect(self, value) -> None:
|
||
|
"""
|
||
|
Sets autodetect setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The autodetect value.
|
||
|
"""
|
||
|
if isinstance(value, bool):
|
||
|
if self.autodetect is not value:
|
||
|
self._verify_proxy_type_compatibility(ProxyType.AUTODETECT)
|
||
|
self.proxyType = ProxyType.AUTODETECT
|
||
|
self.autodetect = value
|
||
|
else:
|
||
|
raise ValueError("Autodetect proxy value needs to be a boolean")
|
||
|
|
||
|
@property
|
||
|
def ftp_proxy(self):
|
||
|
"""
|
||
|
Returns ftp proxy setting.
|
||
|
"""
|
||
|
return self.ftpProxy
|
||
|
|
||
|
@ftp_proxy.setter
|
||
|
def ftp_proxy(self, value) -> None:
|
||
|
"""
|
||
|
Sets ftp proxy setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The ftp proxy value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.ftpProxy = value
|
||
|
|
||
|
@property
|
||
|
def http_proxy(self):
|
||
|
"""
|
||
|
Returns http proxy setting.
|
||
|
"""
|
||
|
return self.httpProxy
|
||
|
|
||
|
@http_proxy.setter
|
||
|
def http_proxy(self, value) -> None:
|
||
|
"""
|
||
|
Sets http proxy setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The http proxy value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.httpProxy = value
|
||
|
|
||
|
@property
|
||
|
def no_proxy(self):
|
||
|
"""
|
||
|
Returns noproxy setting.
|
||
|
"""
|
||
|
return self.noProxy
|
||
|
|
||
|
@no_proxy.setter
|
||
|
def no_proxy(self, value) -> None:
|
||
|
"""
|
||
|
Sets noproxy setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The noproxy value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.noProxy = value
|
||
|
|
||
|
@property
|
||
|
def proxy_autoconfig_url(self):
|
||
|
"""
|
||
|
Returns proxy autoconfig url setting.
|
||
|
"""
|
||
|
return self.proxyAutoconfigUrl
|
||
|
|
||
|
@proxy_autoconfig_url.setter
|
||
|
def proxy_autoconfig_url(self, value) -> None:
|
||
|
"""
|
||
|
Sets proxy autoconfig url setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The proxy autoconfig url value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.PAC)
|
||
|
self.proxyType = ProxyType.PAC
|
||
|
self.proxyAutoconfigUrl = value
|
||
|
|
||
|
@property
|
||
|
def ssl_proxy(self):
|
||
|
"""
|
||
|
Returns https proxy setting.
|
||
|
"""
|
||
|
return self.sslProxy
|
||
|
|
||
|
@ssl_proxy.setter
|
||
|
def ssl_proxy(self, value) -> None:
|
||
|
"""
|
||
|
Sets https proxy setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The https proxy value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.sslProxy = value
|
||
|
|
||
|
@property
|
||
|
def socks_proxy(self):
|
||
|
"""
|
||
|
Returns socks proxy setting.
|
||
|
"""
|
||
|
return self.socksProxy
|
||
|
|
||
|
@socks_proxy.setter
|
||
|
def socks_proxy(self, value) -> None:
|
||
|
"""
|
||
|
Sets socks proxy setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The socks proxy value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.socksProxy = value
|
||
|
|
||
|
@property
|
||
|
def socks_username(self):
|
||
|
"""
|
||
|
Returns socks proxy username setting.
|
||
|
"""
|
||
|
return self.socksUsername
|
||
|
|
||
|
@socks_username.setter
|
||
|
def socks_username(self, value) -> None:
|
||
|
"""
|
||
|
Sets socks proxy username setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The socks proxy username value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.socksUsername = value
|
||
|
|
||
|
@property
|
||
|
def socks_password(self):
|
||
|
"""
|
||
|
Returns socks proxy password setting.
|
||
|
"""
|
||
|
return self.socksPassword
|
||
|
|
||
|
@socks_password.setter
|
||
|
def socks_password(self, value) -> None:
|
||
|
"""
|
||
|
Sets socks proxy password setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The socks proxy password value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.socksPassword = value
|
||
|
|
||
|
@property
|
||
|
def socks_version(self):
|
||
|
"""
|
||
|
Returns socks proxy version setting.
|
||
|
"""
|
||
|
return self.socksVersion
|
||
|
|
||
|
@socks_version.setter
|
||
|
def socks_version(self, value) -> None:
|
||
|
"""
|
||
|
Sets socks proxy version setting.
|
||
|
|
||
|
:Args:
|
||
|
- value: The socks proxy version value.
|
||
|
"""
|
||
|
self._verify_proxy_type_compatibility(ProxyType.MANUAL)
|
||
|
self.proxyType = ProxyType.MANUAL
|
||
|
self.socksVersion = value
|
||
|
|
||
|
def _verify_proxy_type_compatibility(self, compatible_proxy):
|
||
|
if self.proxyType not in (ProxyType.UNSPECIFIED, compatible_proxy):
|
||
|
raise Exception(
|
||
|
f"Specified proxy type ({compatible_proxy}) not compatible with current setting ({self.proxyType})"
|
||
|
)
|
||
|
|
||
|
def add_to_capabilities(self, capabilities):
|
||
|
"""
|
||
|
Adds proxy information as capability in specified capabilities.
|
||
|
|
||
|
:Args:
|
||
|
- capabilities: The capabilities to which proxy will be added.
|
||
|
"""
|
||
|
proxy_caps = {}
|
||
|
proxy_caps["proxyType"] = self.proxyType["string"]
|
||
|
if self.autodetect:
|
||
|
proxy_caps["autodetect"] = self.autodetect
|
||
|
if self.ftpProxy:
|
||
|
proxy_caps["ftpProxy"] = self.ftpProxy
|
||
|
if self.httpProxy:
|
||
|
proxy_caps["httpProxy"] = self.httpProxy
|
||
|
if self.proxyAutoconfigUrl:
|
||
|
proxy_caps["proxyAutoconfigUrl"] = self.proxyAutoconfigUrl
|
||
|
if self.sslProxy:
|
||
|
proxy_caps["sslProxy"] = self.sslProxy
|
||
|
if self.noProxy:
|
||
|
proxy_caps["noProxy"] = self.noProxy
|
||
|
if self.socksProxy:
|
||
|
proxy_caps["socksProxy"] = self.socksProxy
|
||
|
if self.socksUsername:
|
||
|
proxy_caps["socksUsername"] = self.socksUsername
|
||
|
if self.socksPassword:
|
||
|
proxy_caps["socksPassword"] = self.socksPassword
|
||
|
if self.socksVersion:
|
||
|
proxy_caps["socksVersion"] = self.socksVersion
|
||
|
capabilities["proxy"] = proxy_caps
|