Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/selenium/webdriver/common/proxy.py
1864 views
1
# Licensed to the Software Freedom Conservancy (SFC) under one
2
# or more contributor license agreements. See the NOTICE file
3
# distributed with this work for additional information
4
# regarding copyright ownership. The SFC licenses this file
5
# to you under the Apache License, Version 2.0 (the
6
# "License"); you may not use this file except in compliance
7
# with the License. You may obtain a copy of the License at
8
#
9
# http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing,
12
# software distributed under the License is distributed on an
13
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
# KIND, either express or implied. See the License for the
15
# specific language governing permissions and limitations
16
# under the License.
17
18
"""The Proxy implementation."""
19
20
import warnings
21
22
23
class ProxyTypeFactory:
24
"""Factory for proxy types."""
25
26
@staticmethod
27
def make(ff_value, string):
28
return {"ff_value": ff_value, "string": string}
29
30
31
class ProxyType:
32
"""Set of possible types of proxy.
33
34
Each proxy type has 2 properties: 'ff_value' is value of Firefox
35
profile preference, 'string' is id of proxy type.
36
"""
37
38
DIRECT = ProxyTypeFactory.make(0, "DIRECT") # Direct connection, no proxy (default on Windows).
39
MANUAL = ProxyTypeFactory.make(1, "MANUAL") # Manual proxy settings (e.g., for httpProxy).
40
PAC = ProxyTypeFactory.make(2, "PAC") # Proxy autoconfiguration from URL.
41
RESERVED_1 = ProxyTypeFactory.make(3, "RESERVED1") # Never used.
42
AUTODETECT = ProxyTypeFactory.make(4, "AUTODETECT") # Proxy autodetection (presumably with WPAD).
43
SYSTEM = ProxyTypeFactory.make(5, "SYSTEM") # Use system settings (default on Linux).
44
UNSPECIFIED = ProxyTypeFactory.make(6, "UNSPECIFIED") # Not initialized (for internal use).
45
46
@classmethod
47
def load(cls, value):
48
if isinstance(value, dict) and "string" in value:
49
value = value["string"]
50
value = str(value).upper()
51
for attr in dir(cls):
52
attr_value = getattr(cls, attr)
53
if isinstance(attr_value, dict) and "string" in attr_value and attr_value["string"] == value:
54
return attr_value
55
raise Exception(f"No proxy type is found for {value}")
56
57
58
class _ProxyTypeDescriptor:
59
def __init__(self, name, p_type):
60
self.name = name
61
self.p_type = p_type
62
63
def __get__(self, obj, cls):
64
return getattr(obj, self.name)
65
66
def __set__(self, obj, value):
67
if self.name == "autodetect" and not isinstance(value, bool):
68
raise ValueError("Autodetect proxy value needs to be a boolean")
69
if self.name == "ftpProxy":
70
# TODO: Remove ftpProxy in future version and remove deprecation warning
71
# https://github.com/SeleniumHQ/selenium/issues/15905
72
warnings.warn(
73
"ftpProxy is deprecated and will be removed in the future",
74
DeprecationWarning,
75
stacklevel=2,
76
)
77
getattr(obj, "_verify_proxy_type_compatibility")(self.p_type)
78
setattr(obj, "proxyType", self.p_type)
79
setattr(obj, self.name, value)
80
81
82
class Proxy:
83
"""Proxy contains information about proxy type and necessary proxy
84
settings."""
85
86
proxyType = ProxyType.UNSPECIFIED
87
autodetect = False
88
ftpProxy = "" # TODO: Remove ftpProxy in future version and remove deprecation warning
89
httpProxy = ""
90
noProxy = ""
91
proxyAutoconfigUrl = ""
92
sslProxy = ""
93
socksProxy = ""
94
socksUsername = ""
95
socksPassword = ""
96
socksVersion = None
97
98
# create descriptor type objects
99
auto_detect = _ProxyTypeDescriptor("autodetect", ProxyType.AUTODETECT)
100
"""Gets and Sets `auto_detect`
101
102
Usage:
103
------
104
- Get
105
- `self.auto_detect`
106
- Set
107
- `self.auto_detect` = `value`
108
109
Parameters:
110
-----------
111
`value`: `str`
112
"""
113
114
# TODO: Remove ftpProxy in future version and remove deprecation warning
115
ftp_proxy = _ProxyTypeDescriptor("ftpProxy", ProxyType.MANUAL)
116
"""Gets and Sets `ftp_proxy`
117
118
Usage:
119
------
120
- Get
121
- `self.ftp_proxy`
122
- Set
123
- `self.ftp_proxy` = `value`
124
125
Parameters:
126
-----------
127
`value`: `str`
128
"""
129
130
http_proxy = _ProxyTypeDescriptor("httpProxy", ProxyType.MANUAL)
131
"""Gets and Sets `http_proxy`
132
133
Usage:
134
------
135
- Get
136
- `self.http_proxy`
137
- Set
138
- `self.http_proxy` = `value`
139
140
Parameters:
141
-----------
142
`value`: `str`
143
"""
144
145
no_proxy = _ProxyTypeDescriptor("noProxy", ProxyType.MANUAL)
146
"""Gets and Sets `no_proxy`
147
148
Usage:
149
------
150
- Get
151
- `self.no_proxy`
152
- Set
153
- `self.no_proxy` = `value`
154
155
Parameters:
156
-----------
157
`value`: `str`
158
"""
159
160
proxy_autoconfig_url = _ProxyTypeDescriptor("proxyAutoconfigUrl", ProxyType.PAC)
161
"""Gets and Sets `proxy_autoconfig_url`
162
163
Usage:
164
------
165
- Get
166
- `self.proxy_autoconfig_url`
167
- Set
168
- `self.proxy_autoconfig_url` = `value`
169
170
Parameters:
171
-----------
172
`value`: `str`
173
"""
174
175
ssl_proxy = _ProxyTypeDescriptor("sslProxy", ProxyType.MANUAL)
176
"""Gets and Sets `ssl_proxy`
177
178
Usage:
179
------
180
- Get
181
- `self.ssl_proxy`
182
- Set
183
- `self.ssl_proxy` = `value`
184
185
Parameters:
186
-----------
187
`value`: `str`
188
"""
189
190
socks_proxy = _ProxyTypeDescriptor("socksProxy", ProxyType.MANUAL)
191
"""Gets and Sets `socks_proxy`
192
193
Usage:
194
------
195
- Get
196
- `self.sock_proxy`
197
- Set
198
- `self.socks_proxy` = `value`
199
200
Parameters:
201
-----------
202
`value`: `str`
203
"""
204
205
socks_username = _ProxyTypeDescriptor("socksUsername", ProxyType.MANUAL)
206
"""Gets and Sets `socks_password`
207
208
Usage:
209
------
210
- Get
211
- `self.socks_password`
212
- Set
213
- `self.socks_password` = `value`
214
215
Parameters:
216
-----------
217
`value`: `str`
218
"""
219
220
socks_password = _ProxyTypeDescriptor("socksPassword", ProxyType.MANUAL)
221
"""Gets and Sets `socks_password`
222
223
Usage:
224
------
225
- Get
226
- `self.socks_password`
227
- Set
228
- `self.socks_password` = `value`
229
230
Parameters:
231
-----------
232
`value`: `str`
233
"""
234
235
socks_version = _ProxyTypeDescriptor("socksVersion", ProxyType.MANUAL)
236
"""Gets and Sets `socks_version`
237
238
Usage:
239
------
240
- Get
241
- `self.socks_version`
242
- Set
243
- `self.socks_version` = `value`
244
245
Parameters:
246
-----------
247
`value`: `str`
248
"""
249
250
def __init__(self, raw=None):
251
"""Creates a new Proxy.
252
253
:Args:
254
- raw: raw proxy data. If None, default class values are used.
255
"""
256
if raw:
257
if "proxyType" in raw and raw["proxyType"]:
258
self.proxy_type = ProxyType.load(raw["proxyType"])
259
# TODO: Remove ftpProxy in future version and remove deprecation warning
260
# https://github.com/SeleniumHQ/selenium/issues/15905
261
if "ftpProxy" in raw and raw["ftpProxy"]:
262
warnings.warn(
263
"ftpProxy is deprecated and will be removed in the future",
264
DeprecationWarning,
265
stacklevel=2,
266
)
267
self.ftp_proxy = raw["ftpProxy"]
268
if "httpProxy" in raw and raw["httpProxy"]:
269
self.http_proxy = raw["httpProxy"]
270
if "noProxy" in raw and raw["noProxy"]:
271
self.no_proxy = raw["noProxy"]
272
if "proxyAutoconfigUrl" in raw and raw["proxyAutoconfigUrl"]:
273
self.proxy_autoconfig_url = raw["proxyAutoconfigUrl"]
274
if "sslProxy" in raw and raw["sslProxy"]:
275
self.sslProxy = raw["sslProxy"]
276
if "autodetect" in raw and raw["autodetect"]:
277
self.auto_detect = raw["autodetect"]
278
if "socksProxy" in raw and raw["socksProxy"]:
279
self.socks_proxy = raw["socksProxy"]
280
if "socksUsername" in raw and raw["socksUsername"]:
281
self.socks_username = raw["socksUsername"]
282
if "socksPassword" in raw and raw["socksPassword"]:
283
self.socks_password = raw["socksPassword"]
284
if "socksVersion" in raw and raw["socksVersion"]:
285
self.socks_version = raw["socksVersion"]
286
287
@property
288
def proxy_type(self):
289
"""Returns proxy type as `ProxyType`."""
290
return self.proxyType
291
292
@proxy_type.setter
293
def proxy_type(self, value) -> None:
294
"""Sets proxy type.
295
296
:Args:
297
- value: The proxy type.
298
"""
299
self._verify_proxy_type_compatibility(value)
300
self.proxyType = value
301
302
def _verify_proxy_type_compatibility(self, compatible_proxy):
303
if self.proxyType not in (ProxyType.UNSPECIFIED, compatible_proxy):
304
raise ValueError(
305
f"Specified proxy type ({compatible_proxy}) not compatible with current setting ({self.proxyType})"
306
)
307
308
def to_capabilities(self):
309
proxy_caps = {"proxyType": self.proxyType["string"].lower()}
310
# TODO: Remove ftpProxy in future version and remove deprecation warning
311
proxies = [
312
"autodetect",
313
"ftpProxy",
314
"httpProxy",
315
"proxyAutoconfigUrl",
316
"sslProxy",
317
"noProxy",
318
"socksProxy",
319
"socksUsername",
320
"socksPassword",
321
"socksVersion",
322
]
323
for proxy in proxies:
324
attr_value = getattr(self, proxy)
325
if attr_value:
326
proxy_caps[proxy] = attr_value
327
return proxy_caps
328
329
def to_bidi_dict(self):
330
"""Convert proxy settings to BiDi format.
331
332
Returns:
333
-------
334
dict: Proxy configuration in BiDi format.
335
"""
336
proxy_type = self.proxyType["string"].lower()
337
result = {"proxyType": proxy_type}
338
339
if proxy_type == "manual":
340
if self.httpProxy:
341
result["httpProxy"] = self.httpProxy
342
if self.sslProxy:
343
result["sslProxy"] = self.sslProxy
344
if self.socksProxy:
345
result["socksProxy"] = self.socksProxy
346
if self.socksVersion is not None:
347
result["socksVersion"] = self.socksVersion
348
if self.noProxy:
349
# Convert comma-separated string to list
350
if isinstance(self.noProxy, str):
351
result["noProxy"] = [host.strip() for host in self.noProxy.split(",") if host.strip()]
352
elif isinstance(self.noProxy, list):
353
if not all(isinstance(h, str) for h in self.noProxy):
354
raise TypeError("no_proxy list must contain only strings")
355
result["noProxy"] = self.noProxy
356
else:
357
raise TypeError("no_proxy must be a comma-separated string or a list of strings")
358
359
elif proxy_type == "pac":
360
if self.proxyAutoconfigUrl:
361
result["proxyAutoconfigUrl"] = self.proxyAutoconfigUrl
362
363
return result
364
365