pyproxytools 0.4.3__tar.gz → 0.4.5__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.
Files changed (51) hide show
  1. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/LICENSE +1 -1
  2. {pyproxytools-0.4.3/pyproxytools.egg-info → pyproxytools-0.4.5}/PKG-INFO +18 -18
  3. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/README.md +14 -14
  4. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproject.toml +3 -3
  5. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/__init__.py +1 -1
  6. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/handlers/client.py +19 -18
  7. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/handlers/http.py +15 -6
  8. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/handlers/https.py +25 -6
  9. pyproxytools-0.4.5/pyproxy/monitoring/__init__.py +38 -0
  10. pyproxytools-0.4.5/pyproxy/monitoring/auth.py +31 -0
  11. pyproxytools-0.4.5/pyproxy/monitoring/monitor.py +196 -0
  12. pyproxytools-0.4.5/pyproxy/monitoring/routes.py +78 -0
  13. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/server.py +1 -1
  14. {pyproxytools-0.4.3 → pyproxytools-0.4.5/pyproxytools.egg-info}/PKG-INFO +18 -18
  15. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxytools.egg-info/SOURCES.txt +3 -1
  16. pyproxytools-0.4.3/pyproxy/monitoring/web.py +0 -279
  17. pyproxytools-0.4.3/tests/utils/__init__.py +0 -0
  18. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/benchmark/benchmark.py +0 -0
  19. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/benchmark/utils/__init__.py +0 -0
  20. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/benchmark/utils/html.py +0 -0
  21. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/benchmark/utils/req.py +0 -0
  22. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/__main__.py +0 -0
  23. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/handlers/__init__.py +0 -0
  24. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/modules/__init__.py +0 -0
  25. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/modules/cancel_inspect.py +0 -0
  26. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/modules/custom_header.py +0 -0
  27. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/modules/filter.py +0 -0
  28. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/modules/shortcuts.py +0 -0
  29. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/pyproxy.py +0 -0
  30. {pyproxytools-0.4.3/pyproxy/monitoring → pyproxytools-0.4.5/pyproxy/utils}/__init__.py +0 -0
  31. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/utils/args.py +0 -0
  32. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/utils/config.py +0 -0
  33. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/utils/crypto.py +0 -0
  34. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/utils/http_req.py +0 -0
  35. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxy/utils/logger.py +0 -0
  36. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxytools.egg-info/dependency_links.txt +0 -0
  37. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxytools.egg-info/entry_points.txt +0 -0
  38. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxytools.egg-info/requires.txt +0 -0
  39. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/pyproxytools.egg-info/top_level.txt +0 -0
  40. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/requirements.txt +0 -0
  41. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/setup.cfg +0 -0
  42. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/setup.py +0 -0
  43. {pyproxytools-0.4.3/pyproxy/utils → pyproxytools-0.4.5/tests/modules}/__init__.py +0 -0
  44. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/modules/test_cancel_inspect.py +0 -0
  45. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/modules/test_custom_header.py +0 -0
  46. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/modules/test_filter.py +0 -0
  47. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/modules/test_shortcuts.py +0 -0
  48. {pyproxytools-0.4.3/tests/modules → pyproxytools-0.4.5/tests/utils}/__init__.py +0 -0
  49. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/utils/test_crypto.py +0 -0
  50. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/utils/test_http_req.py +0 -0
  51. {pyproxytools-0.4.3 → pyproxytools-0.4.5}/tests/utils/test_logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 6C656C65
3
+ Copyright (c) 2025 pyproxytools
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyproxytools
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: Lightweight and fast python web proxy
5
- Author: 6C656C65
5
+ Author: pyproxytools
6
6
  License-Expression: MIT
7
- Project-URL: Documentation, https://github.com/6C656C65/pyproxy/wiki
8
- Project-URL: Issue tracker, https://github.com/6C656C65/pyproxy/issues
7
+ Project-URL: Documentation, https://github.com/pyproxytools/pyproxy/wiki
8
+ Project-URL: Issue tracker, https://github.com/pyproxytools/pyproxy/issues
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Intended Audience :: Developers
11
11
  Classifier: Natural Language :: English
@@ -39,14 +39,14 @@ Dynamic: license-file
39
39
  **pyproxy** is a lightweight, fast, and customizable Python-based web proxy server designed to handle both HTTP and HTTPS traffic efficiently. It can be used for various purposes, including web scraping, traffic monitoring, and content filtering.
40
40
 
41
41
  <p align="center">
42
- <img src="https://img.shields.io/github/license/6C656C65/pyproxy?style=for-the-badge">
43
- <img src="https://img.shields.io/github/issues/6C656C65/pyproxy?style=for-the-badge">
44
- <img src="https://img.shields.io/github/issues-closed/6C656C65/pyproxy?style=for-the-badge">
42
+ <img src="https://img.shields.io/github/license/pyproxytools/pyproxy?style=for-the-badge">
43
+ <img src="https://img.shields.io/github/issues/pyproxytools/pyproxy?style=for-the-badge">
44
+ <img src="https://img.shields.io/github/issues-closed/pyproxytools/pyproxy?style=for-the-badge">
45
45
  <br>
46
- <img src="https://img.shields.io/github/forks/6C656C65/pyproxy?style=for-the-badge">
47
- <img src="https://img.shields.io/github/stars/6C656C65/pyproxy?style=for-the-badge">
48
- <img src="https://img.shields.io/github/commit-activity/w/6C656C65/pyproxy?style=for-the-badge">
49
- <img src="https://img.shields.io/github/contributors/6C656C65/pyproxy?style=for-the-badge">
46
+ <img src="https://img.shields.io/github/forks/pyproxytools/pyproxy?style=for-the-badge">
47
+ <img src="https://img.shields.io/github/stars/pyproxytools/pyproxy?style=for-the-badge">
48
+ <img src="https://img.shields.io/github/commit-activity/w/pyproxytools/pyproxy?style=for-the-badge">
49
+ <img src="https://img.shields.io/github/contributors/pyproxytools/pyproxy?style=for-the-badge">
50
50
  <br>
51
51
  <img src="https://img.shields.io/pypi/v/pyproxytools?style=for-the-badge">
52
52
  <img src="https://img.shields.io/pypi/pyversions/pyproxytools?style=for-the-badge">
@@ -81,21 +81,21 @@ pip install pyproxytools
81
81
 
82
82
  ### Install from source
83
83
  ```bash
84
- git clone https://github.com/6C656C65/pyproxy.git
84
+ git clone https://github.com/pyproxytools/pyproxy.git
85
85
  cd pyproxy
86
86
  pip install -r requirements.txt
87
87
  ```
88
88
 
89
89
  ### Install with Docker
90
90
  ```bash
91
- docker pull ghcr.io/6c656c65/pyproxy:latest
92
- docker run -d ghcr.io/6c656c65/pyproxy:latest
91
+ docker pull ghcr.io/pyproxytools/pyproxy:latest
92
+ docker run -d ghcr.io/pyproxytools/pyproxy:latest
93
93
  ```
94
94
  You can use slim images by adding `-slim` to the end of the tags
95
95
 
96
96
  ### Install with Compose
97
97
  ```bash
98
- wget https://raw.githubusercontent.com/6C656C65/pyproxy/main/docker-compose.yml
98
+ wget https://raw.githubusercontent.com/pyproxytools/pyproxy/main/docker-compose.yml
99
99
  docker-compose up -d
100
100
  ```
101
101
 
@@ -109,7 +109,7 @@ The proxy will be available at: `0.0.0.0:8080`.
109
109
  The access log will be available at `./logs/access.log`.
110
110
 
111
111
  ## 📚 **Documentation**
112
- If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/6C656C65/pyproxy/wiki).
112
+ If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/pyproxytools/pyproxy/wiki).
113
113
 
114
114
  ## 🔧 **To do**
115
115
 
@@ -130,12 +130,12 @@ Contributions are welcome and appreciated! If you'd like to improve this project
130
130
 
131
131
  ## 📦 Deployment with Ansible
132
132
 
133
- If you want to deploy **pyproxy** automatically to remote servers (via source or Docker), an official [Ansible role](https://github.com/6C656C65/pyproxy_ansible) is available:
133
+ If you want to deploy **pyproxy** automatically to remote servers (via source or Docker), an official [Ansible role](https://github.com/pyproxytools/pyproxy-ansible) is available:
134
134
 
135
135
  * 🔧 Install from source or run as a Docker container
136
136
  * 📁 Supports customization of ports, versions, and paths
137
137
  * 🚀 Easily integrable into your infrastructure or CI/CD pipelines
138
138
 
139
- 👉 Check out the [ansible-role-pyproxy](https://github.com/6C656C65/pyproxy_ansible) repository for more details and usage instructions.
139
+ 👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
140
140
 
141
141
  ---
@@ -6,14 +6,14 @@
6
6
  **pyproxy** is a lightweight, fast, and customizable Python-based web proxy server designed to handle both HTTP and HTTPS traffic efficiently. It can be used for various purposes, including web scraping, traffic monitoring, and content filtering.
7
7
 
8
8
  <p align="center">
9
- <img src="https://img.shields.io/github/license/6C656C65/pyproxy?style=for-the-badge">
10
- <img src="https://img.shields.io/github/issues/6C656C65/pyproxy?style=for-the-badge">
11
- <img src="https://img.shields.io/github/issues-closed/6C656C65/pyproxy?style=for-the-badge">
9
+ <img src="https://img.shields.io/github/license/pyproxytools/pyproxy?style=for-the-badge">
10
+ <img src="https://img.shields.io/github/issues/pyproxytools/pyproxy?style=for-the-badge">
11
+ <img src="https://img.shields.io/github/issues-closed/pyproxytools/pyproxy?style=for-the-badge">
12
12
  <br>
13
- <img src="https://img.shields.io/github/forks/6C656C65/pyproxy?style=for-the-badge">
14
- <img src="https://img.shields.io/github/stars/6C656C65/pyproxy?style=for-the-badge">
15
- <img src="https://img.shields.io/github/commit-activity/w/6C656C65/pyproxy?style=for-the-badge">
16
- <img src="https://img.shields.io/github/contributors/6C656C65/pyproxy?style=for-the-badge">
13
+ <img src="https://img.shields.io/github/forks/pyproxytools/pyproxy?style=for-the-badge">
14
+ <img src="https://img.shields.io/github/stars/pyproxytools/pyproxy?style=for-the-badge">
15
+ <img src="https://img.shields.io/github/commit-activity/w/pyproxytools/pyproxy?style=for-the-badge">
16
+ <img src="https://img.shields.io/github/contributors/pyproxytools/pyproxy?style=for-the-badge">
17
17
  <br>
18
18
  <img src="https://img.shields.io/pypi/v/pyproxytools?style=for-the-badge">
19
19
  <img src="https://img.shields.io/pypi/pyversions/pyproxytools?style=for-the-badge">
@@ -48,21 +48,21 @@ pip install pyproxytools
48
48
 
49
49
  ### Install from source
50
50
  ```bash
51
- git clone https://github.com/6C656C65/pyproxy.git
51
+ git clone https://github.com/pyproxytools/pyproxy.git
52
52
  cd pyproxy
53
53
  pip install -r requirements.txt
54
54
  ```
55
55
 
56
56
  ### Install with Docker
57
57
  ```bash
58
- docker pull ghcr.io/6c656c65/pyproxy:latest
59
- docker run -d ghcr.io/6c656c65/pyproxy:latest
58
+ docker pull ghcr.io/pyproxytools/pyproxy:latest
59
+ docker run -d ghcr.io/pyproxytools/pyproxy:latest
60
60
  ```
61
61
  You can use slim images by adding `-slim` to the end of the tags
62
62
 
63
63
  ### Install with Compose
64
64
  ```bash
65
- wget https://raw.githubusercontent.com/6C656C65/pyproxy/main/docker-compose.yml
65
+ wget https://raw.githubusercontent.com/pyproxytools/pyproxy/main/docker-compose.yml
66
66
  docker-compose up -d
67
67
  ```
68
68
 
@@ -76,7 +76,7 @@ The proxy will be available at: `0.0.0.0:8080`.
76
76
  The access log will be available at `./logs/access.log`.
77
77
 
78
78
  ## 📚 **Documentation**
79
- If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/6C656C65/pyproxy/wiki).
79
+ If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/pyproxytools/pyproxy/wiki).
80
80
 
81
81
  ## 🔧 **To do**
82
82
 
@@ -97,12 +97,12 @@ Contributions are welcome and appreciated! If you'd like to improve this project
97
97
 
98
98
  ## 📦 Deployment with Ansible
99
99
 
100
- If you want to deploy **pyproxy** automatically to remote servers (via source or Docker), an official [Ansible role](https://github.com/6C656C65/pyproxy_ansible) is available:
100
+ If you want to deploy **pyproxy** automatically to remote servers (via source or Docker), an official [Ansible role](https://github.com/pyproxytools/pyproxy-ansible) is available:
101
101
 
102
102
  * 🔧 Install from source or run as a Docker container
103
103
  * 📁 Supports customization of ports, versions, and paths
104
104
  * 🚀 Easily integrable into your infrastructure or CI/CD pipelines
105
105
 
106
- 👉 Check out the [ansible-role-pyproxy](https://github.com/6C656C65/pyproxy_ansible) repository for more details and usage instructions.
106
+ 👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
107
107
 
108
108
  ---
@@ -6,7 +6,7 @@ license = "MIT"
6
6
  license-files = [
7
7
  "LICENSE",
8
8
  ]
9
- authors = [{name = "6C656C65"}]
9
+ authors = [{name = "pyproxytools"}]
10
10
  classifiers = [
11
11
  "Development Status :: 5 - Production/Stable",
12
12
  "Intended Audience :: Developers",
@@ -26,8 +26,8 @@ classifiers = [
26
26
  dynamic = ["version", "dependencies"]
27
27
 
28
28
  [project.urls]
29
- Documentation = "https://github.com/6C656C65/pyproxy/wiki"
30
- "Issue tracker" = "https://github.com/6C656C65/pyproxy/issues"
29
+ Documentation = "https://github.com/pyproxytools/pyproxy/wiki"
30
+ "Issue tracker" = "https://github.com/pyproxytools/pyproxy/issues"
31
31
 
32
32
  [tool.setuptools.packages]
33
33
  find = {}
@@ -5,7 +5,7 @@ that holds the current version number of the application.
5
5
 
6
6
  import os
7
7
 
8
- __version__ = "0.4.3"
8
+ __version__ = "0.4.5"
9
9
 
10
10
  if os.path.isdir("pyproxy/monitoring"):
11
11
  __slim__ = False
@@ -90,24 +90,25 @@ class ProxyHandlers:
90
90
  Args:
91
91
  client_socket (socket): The socket object for the client connection.
92
92
  """
93
- request = client_socket.recv(4096)
93
+ try:
94
+ client_socket.settimeout(10)
95
+ request = client_socket.recv(4096)
94
96
 
95
- if not request:
96
- self.console_logger.debug("No request received, closing connection.")
97
+ if not request:
98
+ return
99
+
100
+ first_line = request.decode(errors="ignore").split("\n")[0]
101
+ if first_line.startswith("CONNECT"):
102
+ https_handler = self._create_handler(
103
+ HttpsHandler,
104
+ ssl_config=self.ssl_config,
105
+ cancel_inspect_queue=self.cancel_inspect_queue,
106
+ cancel_inspect_result_queue=self.cancel_inspect_result_queue,
107
+ )
108
+ https_handler.handle_https_connection(client_socket, first_line)
109
+ else:
110
+ http_handler = self._create_handler(HttpHandler)
111
+ http_handler.handle_http_request(client_socket, request)
112
+ finally:
97
113
  client_socket.close()
98
114
  self.active_connections.pop(threading.get_ident(), None)
99
- return
100
-
101
- first_line = request.decode(errors="ignore").split("\n")[0]
102
-
103
- if first_line.startswith("CONNECT"):
104
- https_handler = self._create_handler(
105
- HttpsHandler,
106
- ssl_config=self.ssl_config,
107
- cancel_inspect_queue=self.cancel_inspect_queue,
108
- cancel_inspect_result_queue=self.cancel_inspect_result_queue,
109
- )
110
- https_handler.handle_https_connection(client_socket, first_line)
111
- else:
112
- http_handler = self._create_handler(HttpHandler)
113
- http_handler.handle_http_request(client_socket, request)
@@ -202,15 +202,24 @@ class HttpHandler:
202
202
  server_port = parsed_url.port or (
203
203
  443 if parsed_url.scheme == "https" else 80
204
204
  )
205
+
206
+ try:
207
+ ip_address = socket.gethostbyname(server_host)
208
+ except socket.gaierror:
209
+ ip_address = server_host
210
+
205
211
  thread_id = threading.get_ident()
206
212
 
207
213
  if thread_id in self.active_connections:
208
- self.active_connections[thread_id] = {
209
- "target_ip": server_host,
210
- "target_port": server_port,
211
- "bytes_sent": 0,
212
- "bytes_received": 0,
213
- }
214
+ self.active_connections[thread_id].update(
215
+ {
216
+ "target_ip": ip_address,
217
+ "target_domain": server_host,
218
+ "target_port": server_port,
219
+ "bytes_sent": 0,
220
+ "bytes_received": 0,
221
+ }
222
+ )
214
223
 
215
224
  try:
216
225
  server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -206,6 +206,21 @@ class HttpsHandler:
206
206
  if self._is_blocked(f"{server_host}{path}"):
207
207
  return None, full_url, True
208
208
 
209
+ if not self.logger_config.no_logging_access:
210
+ method, domain_port, protocol = first_line.split(" ")
211
+ domain, port = domain_port.split(":")
212
+ self.logger_config.access_logger.info(
213
+ "",
214
+ extra={
215
+ "ip_src": ssl_client_socket.getpeername()[0],
216
+ "url": full_url,
217
+ "method": method,
218
+ "domain": server_host,
219
+ "port": port,
220
+ "protocol": protocol,
221
+ },
222
+ )
223
+
209
224
  return first_request, full_url, False
210
225
  except Exception as e:
211
226
  self.logger_config.error_logger.error(f"SSL request processing error : {e}")
@@ -231,10 +246,13 @@ class HttpsHandler:
231
246
  not_inspect = self._should_skip_inspection(server_host)
232
247
 
233
248
  thread_id = threading.get_ident()
234
- self.active_connections[thread_id] = {
235
- "bytes_sent": 0,
236
- "bytes_received": 0,
237
- }
249
+ self.active_connections[thread_id].update(
250
+ {
251
+ "target_domain": server_host,
252
+ "bytes_sent": 0,
253
+ "bytes_received": 0,
254
+ }
255
+ )
238
256
 
239
257
  if self.ssl_config.ssl_inspect and not not_inspect:
240
258
  try:
@@ -317,13 +335,13 @@ class HttpsHandler:
317
335
  )
318
336
 
319
337
  if not self.logger_config.no_logging_access:
320
- _, _, protocol = first_line.split(" ")
338
+ method, _, protocol = first_line.split(" ")
321
339
  self.logger_config.access_logger.info(
322
340
  "",
323
341
  extra={
324
342
  "ip_src": client_ip,
325
343
  "url": target,
326
- "method": "CONNECT",
344
+ "method": method,
327
345
  "domain": server_host,
328
346
  "port": server_port,
329
347
  "protocol": protocol,
@@ -397,6 +415,7 @@ class HttpsHandler:
397
415
  data
398
416
  )
399
417
  except (socket.error, OSError):
418
+ self.logger_config.console_logger("error")
400
419
  client_socket.close()
401
420
  server_socket.close()
402
421
  self.active_connections.pop(threading.get_ident(), None)
@@ -0,0 +1,38 @@
1
+ """
2
+ pyproxy.monitoring.__init__.py
3
+
4
+ Provides a monitoring system for the ProxyServer, exposing information about
5
+ processes, threads, active connections, and subprocesses. Implements an HTTP
6
+ server using Flask to provide monitoring endpoints.
7
+ """
8
+
9
+ import logging
10
+ from flask import Flask
11
+ from .monitor import ProxyMonitor
12
+ from .auth import create_basic_auth
13
+ from .routes import register_routes
14
+
15
+
16
+ def start_flask_server(proxy_server, flask_port, flask_pass, debug) -> None:
17
+ """
18
+ Launches a Flask HTTP server to monitor the ProxyServer.
19
+
20
+ The server exposes endpoints that provide status information about
21
+ the proxy server, including process details, thread information,
22
+ subprocess statuses, and active connections.
23
+
24
+ Args:
25
+ proxy_server (ProxyServer): The ProxyServer instance to monitor.
26
+ flask_port (int): The port number on which the Flask server will listen.
27
+ flask_pass (str): The password used for basic HTTP authentication.
28
+ debug (bool): Flag to enable or disable Flask debug mode.
29
+ """
30
+ auth = create_basic_auth(flask_pass)
31
+
32
+ app = Flask(__name__, static_folder="static")
33
+ if not debug:
34
+ log = logging.getLogger("werkzeug")
35
+ log.setLevel(logging.ERROR)
36
+
37
+ register_routes(app, auth, proxy_server, ProxyMonitor)
38
+ app.run(host="0.0.0.0", port=flask_port) # nosec
@@ -0,0 +1,31 @@
1
+ """
2
+ pyproxy.monitoring.auth.py
3
+
4
+ Provides HTTP Basic Authentication setup for the monitoring Flask server,
5
+ using a single hardcoded user 'admin' with a hashed password.
6
+ """
7
+
8
+ from flask_httpauth import HTTPBasicAuth
9
+ from werkzeug.security import check_password_hash, generate_password_hash
10
+
11
+
12
+ def create_basic_auth(password: str):
13
+ """
14
+ Creates and configures an HTTPBasicAuth instance with a single user.
15
+
16
+ Args:
17
+ password (str): The password for the 'admin' user.
18
+
19
+ Returns:
20
+ HTTPBasicAuth: Configured HTTPBasicAuth instance for use in Flask.
21
+ """
22
+ auth = HTTPBasicAuth()
23
+ users = {"admin": generate_password_hash(password)}
24
+
25
+ @auth.verify_password
26
+ def verify_password(username, passwd):
27
+ if username in users and check_password_hash(users.get(username), passwd):
28
+ return username
29
+ return None
30
+
31
+ return auth
@@ -0,0 +1,196 @@
1
+ """
2
+ pyproxy.monitoring.monitor
3
+
4
+ This module defines the ProxyMonitor class, which provides monitoring capabilities
5
+ for the ProxyServer. It collects and exposes real-time information about the
6
+ main process, threads, subprocesses, and active client connections using `psutil`,
7
+ `threading`, and `multiprocessing` libraries.
8
+ """
9
+
10
+ import os
11
+ import threading
12
+ import multiprocessing
13
+ from datetime import datetime
14
+ from typing import List, Dict, Union
15
+ import psutil
16
+
17
+
18
+ class ProxyMonitor:
19
+ """
20
+ Monitors the status of the ProxyServer, including details about
21
+ the main process, threads, subprocesses, and active client connections.
22
+
23
+ Args:
24
+ proxy_server (ProxyServer): The instance of the ProxyServer to monitor.
25
+ """
26
+
27
+ def __init__(self, proxy_server):
28
+ self.proxy_server = proxy_server
29
+
30
+ def get_process_info(
31
+ self,
32
+ ) -> Dict[str, Union[int, str, List[Dict[str, Union[int, str]]]]]:
33
+ """
34
+ Retrieves overall process information for the ProxyServer,
35
+ including the PID, name, status, and details about threads,
36
+ subprocesses, and active connections.
37
+
38
+ Returns:
39
+ dict: A dictionary containing the process information.
40
+ """
41
+ process_info = {
42
+ "pid": os.getpid(),
43
+ "name": "ProxyServer",
44
+ "status": "running",
45
+ "start_time": datetime.fromtimestamp(
46
+ psutil.Process(os.getpid()).create_time()
47
+ ).strftime("%Y-%m-%d %H:%M:%S"),
48
+ "threads": self.get_threads_info(),
49
+ "subprocesses": self.get_subprocesses_info(),
50
+ "active_connections": self.get_active_connections(),
51
+ }
52
+ return process_info
53
+
54
+ def get_threads_info(self) -> List[Dict[str, Union[int, str]]]:
55
+ """
56
+ Retrieves information about the threads running in the ProxyServer.
57
+
58
+ Returns:
59
+ list: A list of dictionaries, each containing information
60
+ about a thread.
61
+ """
62
+ threads_info = []
63
+ for thread in threading.enumerate():
64
+ threads_info.append(
65
+ {
66
+ "thread_id": thread.ident,
67
+ "name": thread.name,
68
+ "status": self.get_thread_status(thread),
69
+ }
70
+ )
71
+ return threads_info
72
+
73
+ def get_thread_status(self, thread: threading.Thread) -> str:
74
+ """
75
+ Gets the status of a given thread.
76
+
77
+ Args:
78
+ thread (threading.Thread): The thread whose status is to be retrieved.
79
+
80
+ Returns:
81
+ str: The status of the thread ('running', 'terminated', or 'unknown').
82
+ """
83
+ try:
84
+ if thread.is_alive():
85
+ return "running"
86
+ return "terminated"
87
+ except AttributeError:
88
+ return "unknown"
89
+
90
+ def get_subprocesses_info(
91
+ self,
92
+ ) -> Dict[str, Dict[str, Union[str, List[Dict[str, Union[int, str]]]]]]:
93
+ """
94
+ Retrieves the status of the ProxyServer's subprocesses, including
95
+ filtering, shortcuts, cancel inspection, and custom header processes.
96
+
97
+ Returns:
98
+ dict: A dictionary containing subprocess statuses.
99
+ """
100
+ subprocesses_info = {}
101
+
102
+ subprocesses = {
103
+ "filter": self.proxy_server.filter_proc,
104
+ "shortcuts": self.proxy_server.shortcuts_proc,
105
+ "cancel_inspect": self.proxy_server.cancel_inspect_proc,
106
+ "custom_header": self.proxy_server.custom_header_proc,
107
+ }
108
+
109
+ for name, process in subprocesses.items():
110
+ if process is not None and process.is_alive():
111
+ subprocesses_info[name] = self.get_subprocess_status(process, name)
112
+ return subprocesses_info
113
+
114
+ def get_subprocess_status(
115
+ self, process: multiprocessing.Process, name: str
116
+ ) -> Dict[str, Union[str, None, List[Dict[str, Union[int, str]]]]]:
117
+ """
118
+ Retrieves the status of a subprocess.
119
+
120
+ Args:
121
+ process (multiprocessing.Process): The subprocess to check.
122
+ name (str): The name of the subprocess.
123
+
124
+ Returns:
125
+ dict: A dictionary containing the subprocess status.
126
+ """
127
+ if process is None:
128
+ return {"status": "not started", "name": name, "threads": []}
129
+ try:
130
+ status = "running" if process.is_alive() else "terminated"
131
+ threads_info = self.get_subprocess_threads_info(process)
132
+ except AttributeError:
133
+ status = "terminated"
134
+ threads_info = []
135
+ return {
136
+ "pid": process.pid if hasattr(process, "pid") else None,
137
+ "status": status,
138
+ "name": name,
139
+ "threads": threads_info,
140
+ }
141
+
142
+ def get_subprocess_threads_info(
143
+ self, process: multiprocessing.Process
144
+ ) -> List[Dict[str, Union[int, str]]]:
145
+ """
146
+ Retrieves the threads associated with a subprocess.
147
+
148
+ Args:
149
+ process (multiprocessing.Process): The subprocess to check.
150
+
151
+ Returns:
152
+ list: A list of dictionaries containing thread information.
153
+ """
154
+ threads_info = []
155
+ try:
156
+ for proc_thread in psutil.Process(process.pid).threads():
157
+ threads_info.append(
158
+ {
159
+ "thread_id": proc_thread.id,
160
+ "name": f"Thread-{proc_thread.id}",
161
+ "status": self.get_thread_status_by_pid(proc_thread.id),
162
+ }
163
+ )
164
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
165
+ pass
166
+ return threads_info
167
+
168
+ def get_thread_status_by_pid(self, thread_id: int) -> str:
169
+ """
170
+ Attempts to retrieve the status of a thread by its PID.
171
+
172
+ Args:
173
+ thread_id (int): The thread's ID.
174
+
175
+ Returns:
176
+ str: The status of the thread ('running' or 'terminated').
177
+ """
178
+ try:
179
+ process = psutil.Process(thread_id)
180
+ if process.is_running():
181
+ return "running"
182
+ return "terminated"
183
+ except psutil.NoSuchProcess:
184
+ return "terminated"
185
+
186
+ def get_active_connections(self) -> List[Dict[str, Union[int, Dict]]]:
187
+ """
188
+ Retrieves information about the active client connections to the ProxyServer.
189
+
190
+ Returns:
191
+ list: A list of dictionaries containing information about active connections.
192
+ """
193
+ return [
194
+ {"thread_id": thread_id, **conn}
195
+ for thread_id, conn in self.proxy_server.active_connections.items()
196
+ ]
@@ -0,0 +1,78 @@
1
+ """
2
+ pyproxy.monitoring.routes.py
3
+
4
+ Defines and registers monitoring-related routes for the Flask application,
5
+ including endpoints for system information, configuration, and a secured
6
+ HTML-based index page.
7
+ """
8
+
9
+ from flask import jsonify, render_template
10
+
11
+
12
+ def register_routes(app, auth, proxy_server, ProxyMonitor):
13
+ """
14
+ Registers the monitoring routes to the Flask app, secured with HTTP Basic Auth.
15
+
16
+ Args:
17
+ app (Flask): The Flask application instance.
18
+ auth (HTTPBasicAuth): The HTTP Basic Auth instance used to secure routes.
19
+ proxy_server (ProxyServer): The running ProxyServer instance to monitor.
20
+ ProxyMonitor (class): The monitoring class used to gather runtime information.
21
+ """
22
+
23
+ @app.route("/")
24
+ @auth.login_required
25
+ def index():
26
+ """
27
+ Serves the main index HTML page for the monitoring dashboard.
28
+
29
+ Returns:
30
+ Response: Rendered HTML page.
31
+ """
32
+ return render_template("index.html")
33
+
34
+ @app.route("/monitoring", methods=["GET"])
35
+ @auth.login_required
36
+ def monitoring():
37
+ """
38
+ Provides real-time monitoring information about the ProxyServer,
39
+ including process, thread, and connection status.
40
+
41
+ Returns:
42
+ Response: JSON object containing monitoring data.
43
+ """
44
+ monitor = ProxyMonitor(proxy_server)
45
+ return jsonify(monitor.get_process_info())
46
+
47
+ @app.route("/config", methods=["GET"])
48
+ @auth.login_required
49
+ def config():
50
+ """
51
+ Returns the current configuration of the ProxyServer, including
52
+ host, port, debug mode, and optional components like logger, filter,
53
+ and SSL configuration.
54
+
55
+ Returns:
56
+ Response: JSON object containing configuration data.
57
+ """
58
+ config_data = {
59
+ "host": proxy_server.host_port[0],
60
+ "port": proxy_server.host_port[1],
61
+ "debug": proxy_server.debug,
62
+ "html_403": proxy_server.html_403,
63
+ "logger_config": (
64
+ proxy_server.logger_config.to_dict()
65
+ if proxy_server.logger_config
66
+ else None
67
+ ),
68
+ "filter_config": (
69
+ proxy_server.filter_config.to_dict()
70
+ if proxy_server.filter_config
71
+ else None
72
+ ),
73
+ "ssl_config": (
74
+ proxy_server.ssl_config.to_dict() if proxy_server.ssl_config else None
75
+ ),
76
+ "flask_port": proxy_server.monitoring_config.flask_port,
77
+ }
78
+ return jsonify(config_data)
@@ -27,7 +27,7 @@ if not __slim__:
27
27
  if not __slim__:
28
28
  from pyproxy.modules.custom_header import custom_header_process
29
29
  if not __slim__:
30
- from pyproxy.monitoring.web import start_flask_server
30
+ from pyproxy.monitoring import start_flask_server
31
31
 
32
32
 
33
33
  class ProxyServer:
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyproxytools
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: Lightweight and fast python web proxy
5
- Author: 6C656C65
5
+ Author: pyproxytools
6
6
  License-Expression: MIT
7
- Project-URL: Documentation, https://github.com/6C656C65/pyproxy/wiki
8
- Project-URL: Issue tracker, https://github.com/6C656C65/pyproxy/issues
7
+ Project-URL: Documentation, https://github.com/pyproxytools/pyproxy/wiki
8
+ Project-URL: Issue tracker, https://github.com/pyproxytools/pyproxy/issues
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Intended Audience :: Developers
11
11
  Classifier: Natural Language :: English
@@ -39,14 +39,14 @@ Dynamic: license-file
39
39
  **pyproxy** is a lightweight, fast, and customizable Python-based web proxy server designed to handle both HTTP and HTTPS traffic efficiently. It can be used for various purposes, including web scraping, traffic monitoring, and content filtering.
40
40
 
41
41
  <p align="center">
42
- <img src="https://img.shields.io/github/license/6C656C65/pyproxy?style=for-the-badge">
43
- <img src="https://img.shields.io/github/issues/6C656C65/pyproxy?style=for-the-badge">
44
- <img src="https://img.shields.io/github/issues-closed/6C656C65/pyproxy?style=for-the-badge">
42
+ <img src="https://img.shields.io/github/license/pyproxytools/pyproxy?style=for-the-badge">
43
+ <img src="https://img.shields.io/github/issues/pyproxytools/pyproxy?style=for-the-badge">
44
+ <img src="https://img.shields.io/github/issues-closed/pyproxytools/pyproxy?style=for-the-badge">
45
45
  <br>
46
- <img src="https://img.shields.io/github/forks/6C656C65/pyproxy?style=for-the-badge">
47
- <img src="https://img.shields.io/github/stars/6C656C65/pyproxy?style=for-the-badge">
48
- <img src="https://img.shields.io/github/commit-activity/w/6C656C65/pyproxy?style=for-the-badge">
49
- <img src="https://img.shields.io/github/contributors/6C656C65/pyproxy?style=for-the-badge">
46
+ <img src="https://img.shields.io/github/forks/pyproxytools/pyproxy?style=for-the-badge">
47
+ <img src="https://img.shields.io/github/stars/pyproxytools/pyproxy?style=for-the-badge">
48
+ <img src="https://img.shields.io/github/commit-activity/w/pyproxytools/pyproxy?style=for-the-badge">
49
+ <img src="https://img.shields.io/github/contributors/pyproxytools/pyproxy?style=for-the-badge">
50
50
  <br>
51
51
  <img src="https://img.shields.io/pypi/v/pyproxytools?style=for-the-badge">
52
52
  <img src="https://img.shields.io/pypi/pyversions/pyproxytools?style=for-the-badge">
@@ -81,21 +81,21 @@ pip install pyproxytools
81
81
 
82
82
  ### Install from source
83
83
  ```bash
84
- git clone https://github.com/6C656C65/pyproxy.git
84
+ git clone https://github.com/pyproxytools/pyproxy.git
85
85
  cd pyproxy
86
86
  pip install -r requirements.txt
87
87
  ```
88
88
 
89
89
  ### Install with Docker
90
90
  ```bash
91
- docker pull ghcr.io/6c656c65/pyproxy:latest
92
- docker run -d ghcr.io/6c656c65/pyproxy:latest
91
+ docker pull ghcr.io/pyproxytools/pyproxy:latest
92
+ docker run -d ghcr.io/pyproxytools/pyproxy:latest
93
93
  ```
94
94
  You can use slim images by adding `-slim` to the end of the tags
95
95
 
96
96
  ### Install with Compose
97
97
  ```bash
98
- wget https://raw.githubusercontent.com/6C656C65/pyproxy/main/docker-compose.yml
98
+ wget https://raw.githubusercontent.com/pyproxytools/pyproxy/main/docker-compose.yml
99
99
  docker-compose up -d
100
100
  ```
101
101
 
@@ -109,7 +109,7 @@ The proxy will be available at: `0.0.0.0:8080`.
109
109
  The access log will be available at `./logs/access.log`.
110
110
 
111
111
  ## 📚 **Documentation**
112
- If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/6C656C65/pyproxy/wiki).
112
+ If you encounter any problems, or if you want to use the program in a particular way, I advise you to read the [documentation](https://github.com/pyproxytools/pyproxy/wiki).
113
113
 
114
114
  ## 🔧 **To do**
115
115
 
@@ -130,12 +130,12 @@ Contributions are welcome and appreciated! If you'd like to improve this project
130
130
 
131
131
  ## 📦 Deployment with Ansible
132
132
 
133
- If you want to deploy **pyproxy** automatically to remote servers (via source or Docker), an official [Ansible role](https://github.com/6C656C65/pyproxy_ansible) is available:
133
+ If you want to deploy **pyproxy** automatically to remote servers (via source or Docker), an official [Ansible role](https://github.com/pyproxytools/pyproxy-ansible) is available:
134
134
 
135
135
  * 🔧 Install from source or run as a Docker container
136
136
  * 📁 Supports customization of ports, versions, and paths
137
137
  * 🚀 Easily integrable into your infrastructure or CI/CD pipelines
138
138
 
139
- 👉 Check out the [ansible-role-pyproxy](https://github.com/6C656C65/pyproxy_ansible) repository for more details and usage instructions.
139
+ 👉 Check out the [pyproxy-ansible](https://github.com/pyproxytools/pyproxy-ansible) repository for more details and usage instructions.
140
140
 
141
141
  ---
@@ -21,7 +21,9 @@ pyproxy/modules/custom_header.py
21
21
  pyproxy/modules/filter.py
22
22
  pyproxy/modules/shortcuts.py
23
23
  pyproxy/monitoring/__init__.py
24
- pyproxy/monitoring/web.py
24
+ pyproxy/monitoring/auth.py
25
+ pyproxy/monitoring/monitor.py
26
+ pyproxy/monitoring/routes.py
25
27
  pyproxy/utils/__init__.py
26
28
  pyproxy/utils/args.py
27
29
  pyproxy/utils/config.py
@@ -1,279 +0,0 @@
1
- """
2
- pyproxy.monitoring.web.py
3
-
4
- This module defines a monitoring system for the ProxyServer that provides
5
- information about the server's processes, threads, active connections, and
6
- subprocesses. It includes an HTTP server implemented with Flask to expose
7
- monitoring endpoints for the proxy server.
8
- """
9
-
10
- import os
11
- import threading
12
- import multiprocessing
13
- import logging
14
- from datetime import datetime
15
- from typing import List, Dict, Union
16
- from flask import Flask, jsonify, render_template
17
- from flask_httpauth import HTTPBasicAuth
18
- from werkzeug.security import check_password_hash, generate_password_hash
19
- import psutil
20
-
21
-
22
- def start_flask_server(proxy_server, flask_port, flask_pass, debug) -> None:
23
- """
24
- Starts the Flask server for monitoring the ProxyServer. It creates and
25
- runs an HTTP server that exposes the proxy server's status, including
26
- process and thread details, subprocess statuses, and active connections.
27
-
28
- Args:
29
- proxy_server (ProxyServer): The ProxyServer instance to monitor.
30
-
31
- The server will expose two routes:
32
- - '/' : Renders a simple index page.
33
- - '/monitoring' : Returns a JSON response with the monitoring data.
34
- """
35
-
36
- class ProxyMonitor:
37
- """
38
- Monitors the status of the ProxyServer, including process, thread,
39
- and subprocess information, as well as active client connections.
40
-
41
- Args:
42
- proxy_server (ProxyServer): The ProxyServer instance to monitor.
43
- """
44
-
45
- def __init__(self, proxy_server):
46
- self.proxy_server = proxy_server
47
-
48
- def get_process_info(
49
- self,
50
- ) -> Dict[str, Union[int, str, List[Dict[str, Union[int, str]]]]]:
51
- """
52
- Retrieves overall process information for the ProxyServer,
53
- including the PID, name, status, and details about threads,
54
- subprocesses, and active connections.
55
-
56
- Returns:
57
- dict: A dictionary containing the process information.
58
- """
59
- process_info = {
60
- "pid": os.getpid(),
61
- "name": "ProxyServer",
62
- "status": "running",
63
- "start_time": datetime.fromtimestamp(
64
- psutil.Process(os.getpid()).create_time()
65
- ).strftime("%Y-%m-%d %H:%M:%S"),
66
- "threads": self.get_threads_info(),
67
- "subprocesses": self.get_subprocesses_info(),
68
- "active_connections": self.get_active_connections(),
69
- }
70
- return process_info
71
-
72
- def get_threads_info(self) -> List[Dict[str, Union[int, str]]]:
73
- """
74
- Retrieves information about the threads running in the ProxyServer.
75
-
76
- Returns:
77
- list: A list of dictionaries, each containing information
78
- about a thread.
79
- """
80
- threads_info = []
81
- for thread in threading.enumerate():
82
- threads_info.append(
83
- {
84
- "thread_id": thread.ident,
85
- "name": thread.name,
86
- "status": self.get_thread_status(thread),
87
- }
88
- )
89
- return threads_info
90
-
91
- def get_thread_status(self, thread: threading.Thread) -> str:
92
- """
93
- Gets the status of a given thread.
94
-
95
- Args:
96
- thread (threading.Thread): The thread whose status is to be retrieved.
97
-
98
- Returns:
99
- str: The status of the thread ('running', 'terminated', or 'unknown').
100
- """
101
- try:
102
- if thread.is_alive():
103
- return "running"
104
- return "terminated"
105
- except AttributeError:
106
- return "unknown"
107
-
108
- def get_subprocesses_info(
109
- self,
110
- ) -> Dict[str, Dict[str, Union[str, List[Dict[str, Union[int, str]]]]]]:
111
- """
112
- Retrieves the status of the ProxyServer's subprocesses, including
113
- filtering, shortcuts, cancel inspection, and custom header processes.
114
-
115
- Returns:
116
- dict: A dictionary containing subprocess statuses.
117
- """
118
- subprocesses_info = {}
119
-
120
- subprocesses = {
121
- "filter": self.proxy_server.filter_proc,
122
- "shortcuts": self.proxy_server.shortcuts_proc,
123
- "cancel_inspect": self.proxy_server.cancel_inspect_proc,
124
- "custom_header": self.proxy_server.custom_header_proc,
125
- }
126
-
127
- for name, process in subprocesses.items():
128
- if process is not None and process.is_alive():
129
- subprocesses_info[name] = self.get_subprocess_status(process, name)
130
- return subprocesses_info
131
-
132
- def get_subprocess_status(
133
- self, process: multiprocessing.Process, name: str
134
- ) -> Dict[str, Union[str, None, List[Dict[str, Union[int, str]]]]]:
135
- """
136
- Retrieves the status of a subprocess.
137
-
138
- Args:
139
- process (multiprocessing.Process): The subprocess to check.
140
- name (str): The name of the subprocess.
141
-
142
- Returns:
143
- dict: A dictionary containing the subprocess status.
144
- """
145
- if process is None:
146
- return {"status": "not started", "name": name, "threads": []}
147
- try:
148
- status = "running" if process.is_alive() else "terminated"
149
- threads_info = self.get_subprocess_threads_info(process)
150
- except AttributeError:
151
- status = "terminated"
152
- threads_info = []
153
- return {
154
- "pid": process.pid if hasattr(process, "pid") else None,
155
- "status": status,
156
- "name": name,
157
- "threads": threads_info,
158
- }
159
-
160
- def get_subprocess_threads_info(
161
- self, process: multiprocessing.Process
162
- ) -> List[Dict[str, Union[int, str]]]:
163
- """
164
- Retrieves the threads associated with a subprocess.
165
-
166
- Args:
167
- process (multiprocessing.Process): The subprocess to check.
168
-
169
- Returns:
170
- list: A list of dictionaries containing thread information.
171
- """
172
- threads_info = []
173
- try:
174
- for proc_thread in psutil.Process(process.pid).threads():
175
- threads_info.append(
176
- {
177
- "thread_id": proc_thread.id,
178
- "name": f"Thread-{proc_thread.id}",
179
- "status": self.get_thread_status_by_pid(proc_thread.id),
180
- }
181
- )
182
- except (psutil.NoSuchProcess, psutil.AccessDenied):
183
- pass
184
- return threads_info
185
-
186
- def get_thread_status_by_pid(self, thread_id: int) -> str:
187
- """
188
- Attempts to retrieve the status of a thread by its PID.
189
-
190
- Args:
191
- thread_id (int): The thread's ID.
192
-
193
- Returns:
194
- str: The status of the thread ('running' or 'terminated').
195
- """
196
- try:
197
- process = psutil.Process(thread_id)
198
- if process.is_running():
199
- return "running"
200
- return "terminated"
201
- except psutil.NoSuchProcess:
202
- return "terminated"
203
-
204
- def get_active_connections(self) -> List[Dict[str, Union[int, Dict]]]:
205
- """
206
- Retrieves information about the active client connections to the ProxyServer.
207
-
208
- Returns:
209
- list: A list of dictionaries containing information about active connections.
210
- """
211
- return [
212
- {"thread_id": thread_id, **conn}
213
- for thread_id, conn in self.proxy_server.active_connections.items()
214
- ]
215
-
216
- auth = HTTPBasicAuth()
217
-
218
- users = {"admin": generate_password_hash(flask_pass)}
219
-
220
- @auth.verify_password
221
- def verify_password(username, password):
222
- if username in users and check_password_hash(users.get(username), password):
223
- return username
224
- return None
225
-
226
- app = Flask(__name__, static_folder="static")
227
- if not debug:
228
- log = logging.getLogger("werkzeug")
229
- log.setLevel(logging.ERROR)
230
-
231
- @app.route("/")
232
- @auth.login_required
233
- def index():
234
- """
235
- Renders the index page for the Flask application.
236
-
237
- Returns:
238
- str: The rendered HTML content of the index page.
239
- """
240
- return render_template("index.html")
241
-
242
- @app.route("/monitoring", methods=["GET"])
243
- @auth.login_required
244
- def monitoring():
245
- """
246
- Returns the monitoring data for the ProxyServer in JSON format.
247
-
248
- Returns:
249
- Response: A JSON response containing the server's process information.
250
- """
251
- monitor = ProxyMonitor(proxy_server)
252
- return jsonify(monitor.get_process_info())
253
-
254
- @app.route("/config", methods=["GET"])
255
- @auth.login_required
256
- def config():
257
- config_data = {
258
- "host": proxy_server.host_port[0],
259
- "port": proxy_server.host_port[1],
260
- "debug": proxy_server.debug,
261
- "html_403": proxy_server.html_403,
262
- "logger_config": (
263
- proxy_server.logger_config.to_dict()
264
- if proxy_server.logger_config
265
- else None
266
- ),
267
- "filter_config": (
268
- proxy_server.filter_config.to_dict()
269
- if proxy_server.filter_config
270
- else None
271
- ),
272
- "ssl_config": (
273
- proxy_server.ssl_config.to_dict() if proxy_server.ssl_config else None
274
- ),
275
- "flask_port": proxy_server.flask_port,
276
- }
277
- return jsonify(config_data)
278
-
279
- app.run(host="0.0.0.0", port=flask_port) # nosec
File without changes
File without changes
File without changes