Path: blob/trunk/py/selenium/webdriver/remote/client_config.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.1617import base6418import os19import socket20from enum import Enum21from typing import Optional22from urllib import parse2324import certifi2526from selenium.webdriver.common.proxy import Proxy, ProxyType272829class AuthType(Enum):30BASIC = "Basic"31BEARER = "Bearer"32X_API_KEY = "X-API-Key"333435class _ClientConfigDescriptor:36def __init__(self, name):37self.name = name3839def __get__(self, obj, cls):40return obj.__dict__[self.name]4142def __set__(self, obj, value) -> None:43obj.__dict__[self.name] = value444546class ClientConfig:47remote_server_addr = _ClientConfigDescriptor("_remote_server_addr")48"""Gets and Sets Remote Server."""49keep_alive = _ClientConfigDescriptor("_keep_alive")50"""Gets and Sets Keep Alive value."""51proxy = _ClientConfigDescriptor("_proxy")52"""Gets and Sets the proxy used for communicating to the driver/server."""53ignore_certificates = _ClientConfigDescriptor("_ignore_certificates")54"""Gets and Sets the ignore certificate check value."""55init_args_for_pool_manager = _ClientConfigDescriptor("_init_args_for_pool_manager")56"""Gets and Sets the ignore certificate check."""57timeout = _ClientConfigDescriptor("_timeout")58"""Gets and Sets the timeout (in seconds) used for communicating to the59driver/server."""60ca_certs = _ClientConfigDescriptor("_ca_certs")61"""Gets and Sets the path to bundle of CA certificates."""62username = _ClientConfigDescriptor("_username")63"""Gets and Sets the username used for basic authentication to the64remote."""65password = _ClientConfigDescriptor("_password")66"""Gets and Sets the password used for basic authentication to the67remote."""68auth_type = _ClientConfigDescriptor("_auth_type")69"""Gets and Sets the type of authentication to the remote server."""70token = _ClientConfigDescriptor("_token")71"""Gets and Sets the token used for authentication to the remote server."""72user_agent = _ClientConfigDescriptor("_user_agent")73"""Gets and Sets user agent to be added to the request headers."""74extra_headers = _ClientConfigDescriptor("_extra_headers")75"""Gets and Sets extra headers to be added to the request."""7677def __init__(78self,79remote_server_addr: str,80keep_alive: Optional[bool] = True,81proxy: Optional[Proxy] = Proxy(raw={"proxyType": ProxyType.SYSTEM}),82ignore_certificates: Optional[bool] = False,83init_args_for_pool_manager: Optional[dict] = None,84timeout: Optional[int] = None,85ca_certs: Optional[str] = None,86username: Optional[str] = None,87password: Optional[str] = None,88auth_type: Optional[AuthType] = AuthType.BASIC,89token: Optional[str] = None,90user_agent: Optional[str] = None,91extra_headers: Optional[dict] = None,92) -> None:93self.remote_server_addr = remote_server_addr94self.keep_alive = keep_alive95self.proxy = proxy96self.ignore_certificates = ignore_certificates97self.init_args_for_pool_manager = init_args_for_pool_manager or {}98self.timeout = socket.getdefaulttimeout() if timeout is None else timeout99self.username = username100self.password = password101self.auth_type = auth_type102self.token = token103self.user_agent = user_agent104self.extra_headers = extra_headers105106self.ca_certs = (107(os.getenv("REQUESTS_CA_BUNDLE") if "REQUESTS_CA_BUNDLE" in os.environ else certifi.where())108if ca_certs is None109else ca_certs110)111112def reset_timeout(self) -> None:113"""Resets the timeout to the default value of socket."""114self._timeout = socket.getdefaulttimeout()115116def get_proxy_url(self) -> Optional[str]:117"""Returns the proxy URL to use for the connection."""118proxy_type = self.proxy.proxy_type119remote_add = parse.urlparse(self.remote_server_addr)120if proxy_type is ProxyType.DIRECT:121return None122if proxy_type is ProxyType.SYSTEM:123_no_proxy = os.environ.get("no_proxy", os.environ.get("NO_PROXY"))124if _no_proxy:125for entry in map(str.strip, _no_proxy.split(",")):126if entry == "*":127return None128n_url = parse.urlparse(entry)129if n_url.netloc and remote_add.netloc == n_url.netloc:130return None131if n_url.path in remote_add.netloc:132return None133return os.environ.get(134"https_proxy" if self.remote_server_addr.startswith("https://") else "http_proxy",135os.environ.get("HTTPS_PROXY" if self.remote_server_addr.startswith("https://") else "HTTP_PROXY"),136)137if proxy_type is ProxyType.MANUAL:138return self.proxy.sslProxy if self.remote_server_addr.startswith("https://") else self.proxy.http_proxy139return None140141def get_auth_header(self) -> Optional[dict]:142"""Returns the authorization to add to the request headers."""143if self.auth_type is AuthType.BASIC and self.username and self.password:144credentials = f"{self.username}:{self.password}"145encoded_credentials = base64.b64encode(credentials.encode("utf-8")).decode("utf-8")146return {"Authorization": f"{AuthType.BASIC.value} {encoded_credentials}"}147if self.auth_type is AuthType.BEARER and self.token:148return {"Authorization": f"{AuthType.BEARER.value} {self.token}"}149if self.auth_type is AuthType.X_API_KEY and self.token:150return {f"{AuthType.X_API_KEY.value}": f"{self.token}"}151return None152153154