pyproxytools 0.4.6__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyproxytools-0.5.0/MANIFEST.in +2 -0
- {pyproxytools-0.4.6/pyproxytools.egg-info → pyproxytools-0.5.0}/PKG-INFO +14 -7
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/README.md +6 -1
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproject.toml +22 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/__init__.py +1 -1
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/handlers/http.py +8 -27
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/handlers/https.py +6 -18
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/modules/filter.py +6 -17
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/monitoring/__init__.py +21 -2
- pyproxytools-0.5.0/pyproxy/monitoring/messages.pot +235 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/monitoring/routes.py +61 -19
- pyproxytools-0.5.0/pyproxy/monitoring/translations/en/LC_MESSAGES/messages.mo +0 -0
- pyproxytools-0.5.0/pyproxy/monitoring/translations/en/LC_MESSAGES/messages.po +248 -0
- pyproxytools-0.5.0/pyproxy/monitoring/translations/fr/LC_MESSAGES/messages.mo +0 -0
- pyproxytools-0.5.0/pyproxy/monitoring/translations/fr/LC_MESSAGES/messages.po +248 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/pyproxy.py +9 -23
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/server.py +7 -25
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/utils/args.py +10 -30
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/utils/crypto.py +1 -3
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/utils/logger.py +1 -3
- {pyproxytools-0.4.6 → pyproxytools-0.5.0/pyproxytools.egg-info}/PKG-INFO +14 -7
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxytools.egg-info/SOURCES.txt +6 -4
- pyproxytools-0.5.0/pyproxytools.egg-info/requires.txt +8 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxytools.egg-info/top_level.txt +0 -1
- pyproxytools-0.5.0/requirements.txt +8 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/setup.py +3 -1
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/modules/test_filter.py +2 -6
- pyproxytools-0.4.6/benchmark/benchmark.py +0 -165
- pyproxytools-0.4.6/benchmark/utils/html.py +0 -179
- pyproxytools-0.4.6/benchmark/utils/req.py +0 -43
- pyproxytools-0.4.6/pyproxytools.egg-info/requires.txt +0 -7
- pyproxytools-0.4.6/requirements.txt +0 -7
- pyproxytools-0.4.6/tests/utils/__init__.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/LICENSE +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/__main__.py +0 -0
- {pyproxytools-0.4.6/benchmark/utils → pyproxytools-0.5.0/pyproxy/handlers}/__init__.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/handlers/client.py +0 -0
- {pyproxytools-0.4.6/pyproxy/handlers → pyproxytools-0.5.0/pyproxy/modules}/__init__.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/modules/cancel_inspect.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/modules/custom_header.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/modules/shortcuts.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/monitoring/auth.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/monitoring/monitor.py +0 -0
- {pyproxytools-0.4.6/pyproxy/modules → pyproxytools-0.5.0/pyproxy/utils}/__init__.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/utils/config.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxy/utils/http_req.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxytools.egg-info/dependency_links.txt +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/pyproxytools.egg-info/entry_points.txt +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/setup.cfg +0 -0
- {pyproxytools-0.4.6/pyproxy/utils → pyproxytools-0.5.0/tests/modules}/__init__.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/modules/test_cancel_inspect.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/modules/test_custom_header.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/modules/test_shortcuts.py +0 -0
- {pyproxytools-0.4.6/tests/modules → pyproxytools-0.5.0/tests/utils}/__init__.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/utils/test_crypto.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/utils/test_http_req.py +0 -0
- {pyproxytools-0.4.6 → pyproxytools-0.5.0}/tests/utils/test_logger.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyproxytools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Lightweight and fast python web proxy
|
|
5
5
|
Author: pyproxytools
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
19
|
Classifier: Topic :: Internet
|
|
19
20
|
Classifier: Topic :: Software Development :: Libraries
|
|
20
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -22,12 +23,13 @@ Classifier: Topic :: Utilities
|
|
|
22
23
|
Classifier: Typing :: Typed
|
|
23
24
|
Description-Content-Type: text/markdown
|
|
24
25
|
License-File: LICENSE
|
|
25
|
-
Requires-Dist: rich-argparse>=1.7.
|
|
26
|
-
Requires-Dist: pyOpenSSL>=25.
|
|
27
|
-
Requires-Dist: requests>=2.
|
|
28
|
-
Requires-Dist: Flask>=3.1.
|
|
26
|
+
Requires-Dist: rich-argparse>=1.7.1
|
|
27
|
+
Requires-Dist: pyOpenSSL>=25.3.0
|
|
28
|
+
Requires-Dist: requests>=2.32.5
|
|
29
|
+
Requires-Dist: Flask>=3.1.2
|
|
29
30
|
Requires-Dist: Flask-HTTPAuth>=4.8.0
|
|
30
|
-
Requires-Dist:
|
|
31
|
+
Requires-Dist: Flask-Babel>=4.0.0
|
|
32
|
+
Requires-Dist: psutil>=7.1.0
|
|
31
33
|
Requires-Dist: colorlog>=6.9.0
|
|
32
34
|
Dynamic: license-file
|
|
33
35
|
|
|
@@ -118,7 +120,7 @@ If you encounter any problems, or if you want to use the program in a particular
|
|
|
118
120
|
|
|
119
121
|
## 🏎️ **Benchmark**
|
|
120
122
|
|
|
121
|
-
If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark
|
|
123
|
+
If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark repository](https://github.com/pyproxytools/pyproxy-benchmark) for detailed instructions on how to run the benchmarking tests and generate reports.
|
|
122
124
|
|
|
123
125
|
## 📄 **License**
|
|
124
126
|
|
|
@@ -138,4 +140,9 @@ If you want to deploy **pyproxy** automatically to remote servers (via source or
|
|
|
138
140
|
|
|
139
141
|
👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
|
|
140
142
|
|
|
143
|
+
## 🧩 **Python SDK for Administration and Monitoring**
|
|
144
|
+
|
|
145
|
+
A dedicated Python SDK is available to interact programmatically with the **pyproxy** administration and monitoring interface: [**pyproxy-sdk-py**](https://github.com/pyproxytools/pyproxy-sdk-py).
|
|
146
|
+
This SDK provides a simple and consistent API to manage your proxy configuration remotely — allowing you to add or delete domains, manage URLs, create and remove clients, and perform other administrative tasks. It is designed to integrate easily into automation scripts, dashboards, or backend systems that need to control and monitor pyproxy instances.
|
|
147
|
+
|
|
141
148
|
---
|
|
@@ -85,7 +85,7 @@ If you encounter any problems, or if you want to use the program in a particular
|
|
|
85
85
|
|
|
86
86
|
## 🏎️ **Benchmark**
|
|
87
87
|
|
|
88
|
-
If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark
|
|
88
|
+
If you're interested in benchmarking the performance of the proxy or comparing request times with and without a proxy, please refer to the [Benchmark repository](https://github.com/pyproxytools/pyproxy-benchmark) for detailed instructions on how to run the benchmarking tests and generate reports.
|
|
89
89
|
|
|
90
90
|
## 📄 **License**
|
|
91
91
|
|
|
@@ -105,4 +105,9 @@ If you want to deploy **pyproxy** automatically to remote servers (via source or
|
|
|
105
105
|
|
|
106
106
|
👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
|
|
107
107
|
|
|
108
|
+
## 🧩 **Python SDK for Administration and Monitoring**
|
|
109
|
+
|
|
110
|
+
A dedicated Python SDK is available to interact programmatically with the **pyproxy** administration and monitoring interface: [**pyproxy-sdk-py**](https://github.com/pyproxytools/pyproxy-sdk-py).
|
|
111
|
+
This SDK provides a simple and consistent API to manage your proxy configuration remotely — allowing you to add or delete domains, manage URLs, create and remove clients, and perform other administrative tasks. It is designed to integrate easily into automation scripts, dashboards, or backend systems that need to control and monitor pyproxy instances.
|
|
112
|
+
|
|
108
113
|
---
|
|
@@ -17,6 +17,7 @@ classifiers = [
|
|
|
17
17
|
"Programming Language :: Python :: 3.10",
|
|
18
18
|
"Programming Language :: Python :: 3.11",
|
|
19
19
|
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
20
21
|
"Topic :: Internet",
|
|
21
22
|
"Topic :: Software Development :: Libraries",
|
|
22
23
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
@@ -35,6 +36,27 @@ find = {}
|
|
|
35
36
|
[tool.setuptools.dynamic]
|
|
36
37
|
dependencies = { file = "requirements.txt" }
|
|
37
38
|
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
line-length = 100
|
|
41
|
+
src = ["pyproxy", "tests"]
|
|
42
|
+
exclude = [
|
|
43
|
+
".git",
|
|
44
|
+
"__pycache__",
|
|
45
|
+
"build",
|
|
46
|
+
"dist",
|
|
47
|
+
"venv",
|
|
48
|
+
"setup.py",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[tool.ruff.lint]
|
|
52
|
+
select = ["E", "F", "W", "S"]
|
|
53
|
+
|
|
54
|
+
[tool.ruff.format]
|
|
55
|
+
quote-style = "double"
|
|
56
|
+
indent-style = "space"
|
|
57
|
+
line-ending = "auto"
|
|
58
|
+
skip-magic-trailing-comma = false
|
|
59
|
+
|
|
38
60
|
[project.scripts]
|
|
39
61
|
pyproxy = "pyproxy.pyproxy:main"
|
|
40
62
|
|
|
@@ -62,9 +62,7 @@ class HttpHandler:
|
|
|
62
62
|
new_headers = self.custom_header_result_queue.get(timeout=5)
|
|
63
63
|
headers.update(new_headers)
|
|
64
64
|
except Exception:
|
|
65
|
-
self.console_logger.warning(
|
|
66
|
-
"Timeout while getting custom headers for %s", url
|
|
67
|
-
)
|
|
65
|
+
self.console_logger.warning("Timeout while getting custom headers for %s", url)
|
|
68
66
|
return headers
|
|
69
67
|
|
|
70
68
|
def _rebuild_http_request(self, request_line, headers, body=""):
|
|
@@ -86,9 +84,7 @@ class HttpHandler:
|
|
|
86
84
|
try:
|
|
87
85
|
return self.shortcuts_result_queue.get(timeout=5)
|
|
88
86
|
except Exception:
|
|
89
|
-
self.console_logger.warning(
|
|
90
|
-
"Timeout while getting shortcut for %s", url
|
|
91
|
-
)
|
|
87
|
+
self.console_logger.warning("Timeout while getting shortcut for %s", url)
|
|
92
88
|
return None
|
|
93
89
|
|
|
94
90
|
def _is_blocked(self, url: str) -> bool:
|
|
@@ -150,10 +146,7 @@ class HttpHandler:
|
|
|
150
146
|
shortcut_url = self._apply_shortcut(url)
|
|
151
147
|
if shortcut_url:
|
|
152
148
|
response = (
|
|
153
|
-
f"HTTP/1.1 302 Found\r\n"
|
|
154
|
-
f"Location: {shortcut_url}\r\n"
|
|
155
|
-
f"Content-Length: 0\r\n"
|
|
156
|
-
"\r\n"
|
|
149
|
+
f"HTTP/1.1 302 Found\r\nLocation: {shortcut_url}\r\nContent-Length: 0\r\n\r\n"
|
|
157
150
|
)
|
|
158
151
|
|
|
159
152
|
client_socket.sendall(response.encode())
|
|
@@ -170,16 +163,10 @@ class HttpHandler:
|
|
|
170
163
|
request_lines = request_text.split("\r\n")
|
|
171
164
|
headers = self._get_modified_headers(url, request_text)
|
|
172
165
|
request_line = request_lines[0]
|
|
173
|
-
body = (
|
|
174
|
-
request_text.split("\r\n\r\n", 1)[1]
|
|
175
|
-
if "\r\n\r\n" in request_text
|
|
176
|
-
else ""
|
|
177
|
-
)
|
|
166
|
+
body = request_text.split("\r\n\r\n", 1)[1] if "\r\n\r\n" in request_text else ""
|
|
178
167
|
modified_request = self._rebuild_http_request(request_line, headers, body)
|
|
179
168
|
|
|
180
|
-
self.forward_request_to_server(
|
|
181
|
-
client_socket, modified_request, url, first_line
|
|
182
|
-
)
|
|
169
|
+
self.forward_request_to_server(client_socket, modified_request, url, first_line)
|
|
183
170
|
|
|
184
171
|
else:
|
|
185
172
|
self.forward_request_to_server(client_socket, request, url, first_line)
|
|
@@ -199,9 +186,7 @@ class HttpHandler:
|
|
|
199
186
|
else:
|
|
200
187
|
parsed_url = urlparse(url)
|
|
201
188
|
server_host = parsed_url.hostname
|
|
202
|
-
server_port = parsed_url.port or (
|
|
203
|
-
443 if parsed_url.scheme == "https" else 80
|
|
204
|
-
)
|
|
189
|
+
server_port = parsed_url.port or (443 if parsed_url.scheme == "https" else 80)
|
|
205
190
|
|
|
206
191
|
try:
|
|
207
192
|
ip_address = socket.gethostbyname(server_host)
|
|
@@ -233,17 +218,13 @@ class HttpHandler:
|
|
|
233
218
|
response = server_socket.recv(4096)
|
|
234
219
|
if response:
|
|
235
220
|
client_socket.send(response)
|
|
236
|
-
self.active_connections[thread_id]["bytes_received"] += len(
|
|
237
|
-
response
|
|
238
|
-
)
|
|
221
|
+
self.active_connections[thread_id]["bytes_received"] += len(response)
|
|
239
222
|
else:
|
|
240
223
|
break
|
|
241
224
|
except socket.timeout:
|
|
242
225
|
break
|
|
243
226
|
except (socket.timeout, socket.gaierror, ConnectionRefusedError, OSError) as e:
|
|
244
|
-
self.console_logger.error(
|
|
245
|
-
"Error connecting to the server %s : %s", server_host, e
|
|
246
|
-
)
|
|
227
|
+
self.console_logger.error("Error connecting to the server %s : %s", server_host, e)
|
|
247
228
|
response = (
|
|
248
229
|
f"HTTP/1.1 502 Bad Gateway\r\n"
|
|
249
230
|
f"Content-Length: {len('Bad Gateway')} \r\n"
|
|
@@ -271,12 +271,8 @@ class HttpsHandler:
|
|
|
271
271
|
|
|
272
272
|
tls_version = ssl_client_socket.version() or "unknown"
|
|
273
273
|
|
|
274
|
-
server_socket = self._establish_server_connection(
|
|
275
|
-
|
|
276
|
-
)
|
|
277
|
-
ssl_server_socket = self._wrap_server_socket_with_ssl(
|
|
278
|
-
server_socket, server_host
|
|
279
|
-
)
|
|
274
|
+
server_socket = self._establish_server_connection(server_host, server_port)
|
|
275
|
+
ssl_server_socket = self._wrap_server_socket_with_ssl(server_socket, server_host)
|
|
280
276
|
|
|
281
277
|
first_request, full_url, is_blocked = self._process_first_ssl_request(
|
|
282
278
|
ssl_client_socket, server_host, first_line
|
|
@@ -324,9 +320,7 @@ class HttpsHandler:
|
|
|
324
320
|
|
|
325
321
|
else:
|
|
326
322
|
try:
|
|
327
|
-
server_socket = self._establish_server_connection(
|
|
328
|
-
server_host, server_port
|
|
329
|
-
)
|
|
323
|
+
server_socket = self._establish_server_connection(server_host, server_port)
|
|
330
324
|
client_socket.sendall(b"HTTP/1.1 200 Connection Established\r\n\r\n")
|
|
331
325
|
|
|
332
326
|
client_ip = client_socket.getpeername()[0]
|
|
@@ -355,9 +349,7 @@ class HttpsHandler:
|
|
|
355
349
|
ConnectionRefusedError,
|
|
356
350
|
OSError,
|
|
357
351
|
) as e:
|
|
358
|
-
self.console_logger.error(
|
|
359
|
-
"Error connecting to the server %s: %s", server_host, e
|
|
360
|
-
)
|
|
352
|
+
self.console_logger.error("Error connecting to the server %s: %s", server_host, e)
|
|
361
353
|
response = (
|
|
362
354
|
f"HTTP/1.1 502 Bad Gateway\r\n"
|
|
363
355
|
f"Content-Length: {len('Bad Gateway')} \r\n"
|
|
@@ -401,9 +393,7 @@ class HttpsHandler:
|
|
|
401
393
|
client_socket.close()
|
|
402
394
|
server_socket.close()
|
|
403
395
|
bytes_sent = self.active_connections[thread_id]["bytes_sent"]
|
|
404
|
-
bytes_received = self.active_connections[thread_id][
|
|
405
|
-
"bytes_received"
|
|
406
|
-
]
|
|
396
|
+
bytes_received = self.active_connections[thread_id]["bytes_received"]
|
|
407
397
|
self.active_connections.pop(threading.get_ident(), None)
|
|
408
398
|
return bytes_sent, bytes_received
|
|
409
399
|
if sock is client_socket:
|
|
@@ -411,9 +401,7 @@ class HttpsHandler:
|
|
|
411
401
|
self.active_connections[thread_id]["bytes_sent"] += len(data)
|
|
412
402
|
else:
|
|
413
403
|
client_socket.sendall(data)
|
|
414
|
-
self.active_connections[thread_id]["bytes_received"] += len(
|
|
415
|
-
data
|
|
416
|
-
)
|
|
404
|
+
self.active_connections[thread_id]["bytes_received"] += len(data)
|
|
417
405
|
except (socket.error, OSError):
|
|
418
406
|
client_socket.close()
|
|
419
407
|
server_socket.close()
|
|
@@ -18,9 +18,7 @@ from urllib.parse import urlparse
|
|
|
18
18
|
import requests
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def load_blacklist(
|
|
22
|
-
blocked_sites_path: str, blocked_url_path: str, filter_mode: str
|
|
23
|
-
) -> set:
|
|
21
|
+
def load_blacklist(blocked_sites_path: str, blocked_url_path: str, filter_mode: str) -> set:
|
|
24
22
|
"""
|
|
25
23
|
Loads blocked FQDNs or URLs from a file or URL into a set for fast lookup.
|
|
26
24
|
|
|
@@ -50,9 +48,7 @@ def load_blacklist(
|
|
|
50
48
|
for line in response.text.splitlines():
|
|
51
49
|
data.add(line.strip())
|
|
52
50
|
except requests.exceptions.RequestException as e:
|
|
53
|
-
raise requests.exceptions.RequestException(
|
|
54
|
-
f"Failed to load data from {url}: {e}"
|
|
55
|
-
)
|
|
51
|
+
raise requests.exceptions.RequestException(f"Failed to load data from {url}: {e}")
|
|
56
52
|
return data
|
|
57
53
|
|
|
58
54
|
if filter_mode == "local":
|
|
@@ -88,12 +84,8 @@ def filter_process(
|
|
|
88
84
|
manager = multiprocessing.Manager()
|
|
89
85
|
blocked_data = manager.dict(
|
|
90
86
|
{
|
|
91
|
-
"sites": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[
|
|
92
|
-
|
|
93
|
-
],
|
|
94
|
-
"urls": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[
|
|
95
|
-
1
|
|
96
|
-
],
|
|
87
|
+
"sites": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[0],
|
|
88
|
+
"urls": load_blacklist(blocked_sites_path, blocked_url_path, filter_mode)[1],
|
|
97
89
|
}
|
|
98
90
|
)
|
|
99
91
|
|
|
@@ -136,13 +128,10 @@ def filter_process(
|
|
|
136
128
|
full_url = server_host
|
|
137
129
|
|
|
138
130
|
if "*" in blocked_data["sites"] or any(
|
|
139
|
-
server_host.startswith(blocked_host)
|
|
140
|
-
for blocked_host in blocked_data["sites"]
|
|
131
|
+
server_host.startswith(blocked_host) for blocked_host in blocked_data["sites"]
|
|
141
132
|
):
|
|
142
133
|
result_queue.put((server_host, "Blocked"))
|
|
143
|
-
elif any(
|
|
144
|
-
full_url.startswith(blocked_url) for blocked_url in blocked_data["urls"]
|
|
145
|
-
):
|
|
134
|
+
elif any(full_url.startswith(blocked_url) for blocked_url in blocked_data["urls"]):
|
|
146
135
|
result_queue.put((full_url, "Blocked"))
|
|
147
136
|
else:
|
|
148
137
|
result_queue.put((server_host, "Allowed"))
|
|
@@ -7,7 +7,8 @@ server using Flask to provide monitoring endpoints.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
|
-
from flask import Flask
|
|
10
|
+
from flask import Flask, request
|
|
11
|
+
from flask_babel import Babel
|
|
11
12
|
from .monitor import ProxyMonitor
|
|
12
13
|
from .auth import create_basic_auth
|
|
13
14
|
from .routes import register_routes
|
|
@@ -30,9 +31,27 @@ def start_flask_server(proxy_server, flask_port, flask_pass, debug) -> None:
|
|
|
30
31
|
auth = create_basic_auth(flask_pass)
|
|
31
32
|
|
|
32
33
|
app = Flask(__name__, static_folder="static")
|
|
34
|
+
app.config["BABEL_DEFAULT_LOCALE"] = "en"
|
|
35
|
+
app.config["BABEL_SUPPORTED_LOCALES"] = ["fr", "en"]
|
|
36
|
+
app.config["BABEL_DEFAULT_TIMEZONE"] = "Europe/London"
|
|
37
|
+
|
|
38
|
+
def select_locale():
|
|
39
|
+
lang = request.args.get("lang")
|
|
40
|
+
if lang in app.config["BABEL_SUPPORTED_LOCALES"]:
|
|
41
|
+
return lang
|
|
42
|
+
return request.accept_languages.best_match(app.config["BABEL_SUPPORTED_LOCALES"])
|
|
43
|
+
|
|
44
|
+
Babel(app, locale_selector=select_locale)
|
|
45
|
+
|
|
46
|
+
@app.context_processor
|
|
47
|
+
def inject_globals():
|
|
48
|
+
from flask_babel import get_locale
|
|
49
|
+
|
|
50
|
+
return {"get_locale": get_locale}
|
|
51
|
+
|
|
33
52
|
if not debug:
|
|
34
53
|
log = logging.getLogger("werkzeug")
|
|
35
54
|
log.setLevel(logging.ERROR)
|
|
36
55
|
|
|
37
56
|
register_routes(app, auth, proxy_server, ProxyMonitor)
|
|
38
|
-
app.run(host="0.0.0.0", port=flask_port) #
|
|
57
|
+
app.run(host="0.0.0.0", port=flask_port) # noqa: S104
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Translations template for PROJECT.
|
|
2
|
+
# Copyright (C) 2025 ORGANIZATION
|
|
3
|
+
# This file is distributed under the same license as the PROJECT project.
|
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PROJECT VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
|
11
|
+
"POT-Creation-Date: 2025-10-12 16:04+0200\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
15
|
+
"MIME-Version: 1.0\n"
|
|
16
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
17
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
18
|
+
"Generated-By: Babel 2.17.0\n"
|
|
19
|
+
|
|
20
|
+
#: routes.py:34 templates/index.html:19
|
|
21
|
+
msgid "Next refresh in:"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#: routes.py:35 templates/index.html:31 templates/index.html:36
|
|
25
|
+
msgid "Loading..."
|
|
26
|
+
msgstr ""
|
|
27
|
+
|
|
28
|
+
#: routes.py:36
|
|
29
|
+
msgid "Main Process"
|
|
30
|
+
msgstr ""
|
|
31
|
+
|
|
32
|
+
#: routes.py:37
|
|
33
|
+
msgid "Subprocesses"
|
|
34
|
+
msgstr ""
|
|
35
|
+
|
|
36
|
+
#: routes.py:38 templates/index.html:23
|
|
37
|
+
msgid "Status"
|
|
38
|
+
msgstr ""
|
|
39
|
+
|
|
40
|
+
#: routes.py:39
|
|
41
|
+
msgid "Configuration"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#: routes.py:40 templates/index.html:41
|
|
45
|
+
msgid "Active Connections"
|
|
46
|
+
msgstr ""
|
|
47
|
+
|
|
48
|
+
#: routes.py:41 templates/index.html:42
|
|
49
|
+
msgid "Search client or target..."
|
|
50
|
+
msgstr ""
|
|
51
|
+
|
|
52
|
+
#: routes.py:42
|
|
53
|
+
msgid "Blocked sites"
|
|
54
|
+
msgstr ""
|
|
55
|
+
|
|
56
|
+
#: routes.py:43
|
|
57
|
+
msgid "Blocked URLs"
|
|
58
|
+
msgstr ""
|
|
59
|
+
|
|
60
|
+
#: routes.py:44 templates/index.html:62
|
|
61
|
+
msgid "Add"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#: routes.py:45 templates/index.html:51
|
|
65
|
+
msgid "Add a domain or URL to block"
|
|
66
|
+
msgstr ""
|
|
67
|
+
|
|
68
|
+
#: routes.py:46 templates/index.html:55
|
|
69
|
+
msgid "Domain"
|
|
70
|
+
msgstr ""
|
|
71
|
+
|
|
72
|
+
#: routes.py:47 templates/index.html:56
|
|
73
|
+
msgid "URL"
|
|
74
|
+
msgstr ""
|
|
75
|
+
|
|
76
|
+
#: routes.py:48 templates/index.html:59
|
|
77
|
+
msgid "Value :"
|
|
78
|
+
msgstr ""
|
|
79
|
+
|
|
80
|
+
#: routes.py:49 templates/index.html:26 templates/index.html:49
|
|
81
|
+
msgid "Filtering"
|
|
82
|
+
msgstr ""
|
|
83
|
+
|
|
84
|
+
#: routes.py:50
|
|
85
|
+
msgid "No active connections."
|
|
86
|
+
msgstr ""
|
|
87
|
+
|
|
88
|
+
#: routes.py:51
|
|
89
|
+
msgid "No blocked sites."
|
|
90
|
+
msgstr ""
|
|
91
|
+
|
|
92
|
+
#: routes.py:52
|
|
93
|
+
msgid "No URLs blocked."
|
|
94
|
+
msgstr ""
|
|
95
|
+
|
|
96
|
+
#: routes.py:53
|
|
97
|
+
msgid "Error while deleting :"
|
|
98
|
+
msgstr ""
|
|
99
|
+
|
|
100
|
+
#: routes.py:54
|
|
101
|
+
msgid "Error adding :"
|
|
102
|
+
msgstr ""
|
|
103
|
+
|
|
104
|
+
#: routes.py:55
|
|
105
|
+
msgid "Please enter a value to block."
|
|
106
|
+
msgstr ""
|
|
107
|
+
|
|
108
|
+
#: routes.py:56 routes.py:84
|
|
109
|
+
msgid "Network error"
|
|
110
|
+
msgstr ""
|
|
111
|
+
|
|
112
|
+
#: routes.py:57
|
|
113
|
+
msgid "Error loading data:"
|
|
114
|
+
msgstr ""
|
|
115
|
+
|
|
116
|
+
#: routes.py:58
|
|
117
|
+
msgid "Name:"
|
|
118
|
+
msgstr ""
|
|
119
|
+
|
|
120
|
+
#: routes.py:59
|
|
121
|
+
msgid "PID:"
|
|
122
|
+
msgstr ""
|
|
123
|
+
|
|
124
|
+
#: routes.py:60
|
|
125
|
+
msgid "Status:"
|
|
126
|
+
msgstr ""
|
|
127
|
+
|
|
128
|
+
#: routes.py:61
|
|
129
|
+
msgid "Start Time:"
|
|
130
|
+
msgstr ""
|
|
131
|
+
|
|
132
|
+
#: routes.py:62
|
|
133
|
+
msgid "Client"
|
|
134
|
+
msgstr ""
|
|
135
|
+
|
|
136
|
+
#: routes.py:63
|
|
137
|
+
msgid "Target"
|
|
138
|
+
msgstr ""
|
|
139
|
+
|
|
140
|
+
#: routes.py:64
|
|
141
|
+
msgid "Sent"
|
|
142
|
+
msgstr ""
|
|
143
|
+
|
|
144
|
+
#: routes.py:65
|
|
145
|
+
msgid "Received"
|
|
146
|
+
msgstr ""
|
|
147
|
+
|
|
148
|
+
#: routes.py:66
|
|
149
|
+
msgid "bytes"
|
|
150
|
+
msgstr ""
|
|
151
|
+
|
|
152
|
+
#: routes.py:67
|
|
153
|
+
msgid "Port:"
|
|
154
|
+
msgstr ""
|
|
155
|
+
|
|
156
|
+
#: routes.py:68
|
|
157
|
+
msgid "Flask Port:"
|
|
158
|
+
msgstr ""
|
|
159
|
+
|
|
160
|
+
#: routes.py:69
|
|
161
|
+
msgid "HTML 403:"
|
|
162
|
+
msgstr ""
|
|
163
|
+
|
|
164
|
+
#: routes.py:70
|
|
165
|
+
msgid "Filter Configuration"
|
|
166
|
+
msgstr ""
|
|
167
|
+
|
|
168
|
+
#: routes.py:71
|
|
169
|
+
msgid "Blocked Sites File:"
|
|
170
|
+
msgstr ""
|
|
171
|
+
|
|
172
|
+
#: routes.py:72
|
|
173
|
+
msgid "Blocked URL File:"
|
|
174
|
+
msgstr ""
|
|
175
|
+
|
|
176
|
+
#: routes.py:73
|
|
177
|
+
msgid "Filter Mode:"
|
|
178
|
+
msgstr ""
|
|
179
|
+
|
|
180
|
+
#: routes.py:74
|
|
181
|
+
msgid "Logger Configuration"
|
|
182
|
+
msgstr ""
|
|
183
|
+
|
|
184
|
+
#: routes.py:75
|
|
185
|
+
msgid "Access Log:"
|
|
186
|
+
msgstr ""
|
|
187
|
+
|
|
188
|
+
#: routes.py:76
|
|
189
|
+
msgid "Block Log:"
|
|
190
|
+
msgstr ""
|
|
191
|
+
|
|
192
|
+
#: routes.py:77
|
|
193
|
+
msgid "SSL Inspection"
|
|
194
|
+
msgstr ""
|
|
195
|
+
|
|
196
|
+
#: routes.py:78
|
|
197
|
+
msgid "Inspect CA Cert:"
|
|
198
|
+
msgstr ""
|
|
199
|
+
|
|
200
|
+
#: routes.py:79
|
|
201
|
+
msgid "Inspect CA Key:"
|
|
202
|
+
msgstr ""
|
|
203
|
+
|
|
204
|
+
#: routes.py:80
|
|
205
|
+
msgid "Inspect certs folder:"
|
|
206
|
+
msgstr ""
|
|
207
|
+
|
|
208
|
+
#: routes.py:81
|
|
209
|
+
msgid "Cancel inspect:"
|
|
210
|
+
msgstr ""
|
|
211
|
+
|
|
212
|
+
#: routes.py:82
|
|
213
|
+
msgid "Action"
|
|
214
|
+
msgstr ""
|
|
215
|
+
|
|
216
|
+
#: routes.py:83
|
|
217
|
+
msgid "Unblock"
|
|
218
|
+
msgstr ""
|
|
219
|
+
|
|
220
|
+
#: templates/index.html:24
|
|
221
|
+
msgid "Settings"
|
|
222
|
+
msgstr ""
|
|
223
|
+
|
|
224
|
+
#: templates/index.html:25
|
|
225
|
+
msgid "Connections"
|
|
226
|
+
msgstr ""
|
|
227
|
+
|
|
228
|
+
#: templates/index.html:60
|
|
229
|
+
msgid "e.g.: example.com or http://example.com/page"
|
|
230
|
+
msgstr ""
|
|
231
|
+
|
|
232
|
+
#: templates/index.html:65
|
|
233
|
+
msgid "Search domain or URLs..."
|
|
234
|
+
msgstr ""
|
|
235
|
+
|