simple-proxy 0.0.26__tar.gz → 0.0.28__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.
- {simple_proxy-0.0.26/simple_proxy.egg-info → simple_proxy-0.0.28}/PKG-INFO +39 -36
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/README.md +26 -20
- simple_proxy-0.0.28/pyproject.toml +67 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/__main__.py +14 -14
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/run.py +4 -6
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/proxyutils.py +1 -1
- simple_proxy-0.0.28/simple_proxy/version.py +10 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28/simple_proxy.egg-info}/PKG-INFO +39 -36
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy.egg-info/SOURCES.txt +1 -1
- simple_proxy-0.0.28/simple_proxy.egg-info/requires.txt +14 -0
- simple_proxy-0.0.28/simple_proxy.egg-info/top_level.txt +7 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_clients.py +6 -6
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_osutils.py +9 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_proxy_channel_handler.py +12 -5
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_run.py +39 -36
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_socks5_proxy_channel_handler.py +1 -1
- simple_proxy-0.0.26/setup.py +0 -53
- simple_proxy-0.0.26/simple_proxy/version.py +0 -1
- simple_proxy-0.0.26/simple_proxy.egg-info/requires.txt +0 -4
- simple_proxy-0.0.26/simple_proxy.egg-info/top_level.txt +0 -1
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/LICENSE +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/setup.cfg +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/__init__.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/clients.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/__init__.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/echo_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/http_proxy_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/proxy_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/shell_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/socks5_proxy_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/__init__.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/certutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/logutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/netutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/osutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/stringutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/tlsutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy.egg-info/dependency_links.txt +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy.egg-info/entry_points.txt +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_certutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_echo_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_http_proxy_channel_handler.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_logutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_netutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_proxyutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_stringutils.py +0 -0
- {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_tlsutils.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple_proxy
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: A
|
|
3
|
+
Version: 0.0.28
|
|
4
|
+
Summary: A simple NIO proxy tool
|
|
5
5
|
Home-page: https://github.com/ruanhao/simple-proxy
|
|
6
|
-
Author: Hao Ruan
|
|
7
|
-
Author-email: ruanhao1116@gmail.com
|
|
6
|
+
Author-email: Hao Ruan <ruanhao1116@gmail.com>
|
|
8
7
|
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/ruanhao/simple-proxy
|
|
9
9
|
Keywords: network,tcp,non-blocking,proxy
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -22,28 +22,30 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
23
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
24
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
-
Requires-Python:
|
|
25
|
+
Requires-Python: <4,>=3.7
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: click-option-group
|
|
29
29
|
Requires-Dist: py-netty>=1.0.5
|
|
30
30
|
Requires-Dist: cryptography>=42.0.0
|
|
31
31
|
Requires-Dist: attrs>=22.1.0
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pip-chill; extra == "dev"
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: pytest>=7.4.0; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-mock>=3.11.1; extra == "test"
|
|
39
|
+
Requires-Dist: coverage[toml]>=7.3.0; extra == "test"
|
|
40
40
|
Dynamic: license-file
|
|
41
|
-
Dynamic: requires-dist
|
|
42
|
-
Dynamic: requires-python
|
|
43
|
-
Dynamic: summary
|
|
44
41
|
|
|
45
42
|
# simple-proxy :rocket:
|
|
46
43
|
|
|
44
|
+
[](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
|
|
45
|
+
[](https://codecov.io/github/ruanhao/simple-proxy)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
47
49
|
A very simple TCP proxy tool empowered by nio tcp framework [py-netty](https://pypi.org/project/py-netty/)
|
|
48
50
|
|
|
49
51
|
There is a simple traffic control mechenism between 2 segments of TCP connection:
|
|
@@ -69,23 +71,20 @@ Usage: simple-proxy [OPTIONS]
|
|
|
69
71
|
Options:
|
|
70
72
|
Common configuration: Configuration for local/remote
|
|
71
73
|
endpoints
|
|
72
|
-
-l, --
|
|
73
|
-
localhost]
|
|
74
|
-
-lp, --
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-r, --remote-
|
|
78
|
-
localhost]
|
|
74
|
+
-l, --listening-host TEXT Listening server address
|
|
75
|
+
[default: localhost]
|
|
76
|
+
-lp, --listening-port INTEGER
|
|
77
|
+
Listening port [default: 8080]
|
|
78
|
+
-g, --global Listening on all interfaces
|
|
79
|
+
-r, --remote-host TEXT Remote host [default: localhost]
|
|
79
80
|
-rp, --remote-port INTEGER Remote port [default: 80]
|
|
80
81
|
-s, --tls Denote remote is listening on
|
|
81
82
|
secure port
|
|
82
|
-
-ss
|
|
83
|
+
-ss Listening on secure port
|
|
83
84
|
TCP proxy configuration: Configuration for TCP proxy mode
|
|
84
|
-
--read-delay-millis INTEGER Read delay
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
[default: 0]
|
|
88
|
-
Thread configuration: Configuration for thread pool
|
|
85
|
+
--read-delay-millis INTEGER Read delay(ms) [default: 0]
|
|
86
|
+
--write-delay-millis INTEGER Write delay(ms) [default: 0]
|
|
87
|
+
Thread configuration: Configuration for thread
|
|
89
88
|
--workers INTEGER Number of worker threads
|
|
90
89
|
[default: 1]
|
|
91
90
|
--proxy-workers INTEGER Number of proxy threads [default:
|
|
@@ -104,8 +103,8 @@ Options:
|
|
|
104
103
|
-m, --monitor Print speed info to console for
|
|
105
104
|
established connection
|
|
106
105
|
-mi, --monitor-interval INTEGER
|
|
107
|
-
Speed monitor interval
|
|
108
|
-
3]
|
|
106
|
+
Speed monitor interval(seconds)
|
|
107
|
+
[default: 3]
|
|
109
108
|
TLS Disguise configuration: Configuration for protection
|
|
110
109
|
against unwanted inspection
|
|
111
110
|
-dti, --disguise-tls-ip TEXT Disguised upstream TLS IP
|
|
@@ -116,18 +115,22 @@ Options:
|
|
|
116
115
|
without specifying external one
|
|
117
116
|
-wl, --white-list TEXT IP White list for legal incoming
|
|
118
117
|
TLS connections (comma separated)
|
|
119
|
-
Proxy configuration: Configuration for
|
|
120
|
-
|
|
118
|
+
Proxy configuration: Configuration for application
|
|
119
|
+
proxies
|
|
120
|
+
-e, --echo-proxy Run as Echo server
|
|
121
121
|
--shell-proxy Run as shell proxy server
|
|
122
122
|
--http-proxy Run as HTTP proxy server
|
|
123
123
|
--socks5-proxy Run as SOCKS5 proxy server
|
|
124
|
-
--proxy-username TEXT Proxy username
|
|
125
|
-
|
|
124
|
+
--proxy-username TEXT Proxy username for HTTP/SOCKS5
|
|
125
|
+
proxy
|
|
126
|
+
--proxy-password TEXT Proxy password for HTTP/SOCKS5
|
|
127
|
+
proxy
|
|
126
128
|
-t, --proxy-transform <TEXT INTEGER TEXT INTEGER>...
|
|
127
129
|
List of target
|
|
128
130
|
transformations(origin_host,
|
|
129
131
|
origin_port, transformed_host,
|
|
130
|
-
transformed_port)
|
|
132
|
+
transformed_port) for HTTP/SOCKS5
|
|
133
|
+
proxy
|
|
131
134
|
Misc configuration:
|
|
132
135
|
-v, --verbose
|
|
133
136
|
--log-file PATH Log file
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# simple-proxy :rocket:
|
|
2
2
|
|
|
3
|
+
[](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/github/ruanhao/simple-proxy)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
3
8
|
A very simple TCP proxy tool empowered by nio tcp framework [py-netty](https://pypi.org/project/py-netty/)
|
|
4
9
|
|
|
5
10
|
There is a simple traffic control mechenism between 2 segments of TCP connection:
|
|
@@ -25,23 +30,20 @@ Usage: simple-proxy [OPTIONS]
|
|
|
25
30
|
Options:
|
|
26
31
|
Common configuration: Configuration for local/remote
|
|
27
32
|
endpoints
|
|
28
|
-
-l, --
|
|
29
|
-
localhost]
|
|
30
|
-
-lp, --
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-r, --remote-
|
|
34
|
-
localhost]
|
|
33
|
+
-l, --listening-host TEXT Listening server address
|
|
34
|
+
[default: localhost]
|
|
35
|
+
-lp, --listening-port INTEGER
|
|
36
|
+
Listening port [default: 8080]
|
|
37
|
+
-g, --global Listening on all interfaces
|
|
38
|
+
-r, --remote-host TEXT Remote host [default: localhost]
|
|
35
39
|
-rp, --remote-port INTEGER Remote port [default: 80]
|
|
36
40
|
-s, --tls Denote remote is listening on
|
|
37
41
|
secure port
|
|
38
|
-
-ss
|
|
42
|
+
-ss Listening on secure port
|
|
39
43
|
TCP proxy configuration: Configuration for TCP proxy mode
|
|
40
|
-
--read-delay-millis INTEGER Read delay
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
[default: 0]
|
|
44
|
-
Thread configuration: Configuration for thread pool
|
|
44
|
+
--read-delay-millis INTEGER Read delay(ms) [default: 0]
|
|
45
|
+
--write-delay-millis INTEGER Write delay(ms) [default: 0]
|
|
46
|
+
Thread configuration: Configuration for thread
|
|
45
47
|
--workers INTEGER Number of worker threads
|
|
46
48
|
[default: 1]
|
|
47
49
|
--proxy-workers INTEGER Number of proxy threads [default:
|
|
@@ -60,8 +62,8 @@ Options:
|
|
|
60
62
|
-m, --monitor Print speed info to console for
|
|
61
63
|
established connection
|
|
62
64
|
-mi, --monitor-interval INTEGER
|
|
63
|
-
Speed monitor interval
|
|
64
|
-
3]
|
|
65
|
+
Speed monitor interval(seconds)
|
|
66
|
+
[default: 3]
|
|
65
67
|
TLS Disguise configuration: Configuration for protection
|
|
66
68
|
against unwanted inspection
|
|
67
69
|
-dti, --disguise-tls-ip TEXT Disguised upstream TLS IP
|
|
@@ -72,18 +74,22 @@ Options:
|
|
|
72
74
|
without specifying external one
|
|
73
75
|
-wl, --white-list TEXT IP White list for legal incoming
|
|
74
76
|
TLS connections (comma separated)
|
|
75
|
-
Proxy configuration: Configuration for
|
|
76
|
-
|
|
77
|
+
Proxy configuration: Configuration for application
|
|
78
|
+
proxies
|
|
79
|
+
-e, --echo-proxy Run as Echo server
|
|
77
80
|
--shell-proxy Run as shell proxy server
|
|
78
81
|
--http-proxy Run as HTTP proxy server
|
|
79
82
|
--socks5-proxy Run as SOCKS5 proxy server
|
|
80
|
-
--proxy-username TEXT Proxy username
|
|
81
|
-
|
|
83
|
+
--proxy-username TEXT Proxy username for HTTP/SOCKS5
|
|
84
|
+
proxy
|
|
85
|
+
--proxy-password TEXT Proxy password for HTTP/SOCKS5
|
|
86
|
+
proxy
|
|
82
87
|
-t, --proxy-transform <TEXT INTEGER TEXT INTEGER>...
|
|
83
88
|
List of target
|
|
84
89
|
transformations(origin_host,
|
|
85
90
|
origin_port, transformed_host,
|
|
86
|
-
transformed_port)
|
|
91
|
+
transformed_port) for HTTP/SOCKS5
|
|
92
|
+
proxy
|
|
87
93
|
Misc configuration:
|
|
88
94
|
-v, --verbose
|
|
89
95
|
--log-file PATH Log file
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "simple_proxy"
|
|
8
|
+
version = "0.0.28"
|
|
9
|
+
description = "A simple NIO proxy tool"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.7, <4"
|
|
12
|
+
license = { text = "MIT" }
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Hao Ruan", email = "ruanhao1116@gmail.com" },
|
|
15
|
+
]
|
|
16
|
+
keywords = ["network", "tcp", "non-blocking", "proxy"]
|
|
17
|
+
|
|
18
|
+
dependencies = [
|
|
19
|
+
"click-option-group",
|
|
20
|
+
"py-netty>=1.0.5",
|
|
21
|
+
"cryptography>=42.0.0",
|
|
22
|
+
"attrs>=22.1.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Natural Language :: English",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
"Programming Language :: Python",
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"Programming Language :: Python :: 3.7",
|
|
33
|
+
"Programming Language :: Python :: 3.8",
|
|
34
|
+
"Programming Language :: Python :: 3.9",
|
|
35
|
+
"Programming Language :: Python :: 3.10",
|
|
36
|
+
"Programming Language :: Python :: 3.11",
|
|
37
|
+
"Programming Language :: Python :: 3.12",
|
|
38
|
+
"Programming Language :: Python :: 3.13",
|
|
39
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
40
|
+
"Topic :: Software Development :: Libraries",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://github.com/ruanhao/simple-proxy"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
simple-proxy = "simple_proxy.__main__:_run"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
[tool.setuptools]
|
|
52
|
+
packages = { find = {} }
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.package-data]
|
|
55
|
+
simple_proxy = ["*"]
|
|
56
|
+
|
|
57
|
+
[project.optional-dependencies]
|
|
58
|
+
dev = [
|
|
59
|
+
"pip-chill" # used to generate requirements-chill.txt
|
|
60
|
+
]
|
|
61
|
+
test = [
|
|
62
|
+
"pytest>=7.4.0",
|
|
63
|
+
"pytest-cov>=4.1.0",
|
|
64
|
+
"pytest-asyncio>=0.21.0",
|
|
65
|
+
"pytest-mock>=3.11.1",
|
|
66
|
+
"coverage[toml]>=7.3.0"
|
|
67
|
+
]
|
|
@@ -15,18 +15,18 @@ logger = logging.getLogger(__name__)
|
|
|
15
15
|
max_content_width=shutil.get_terminal_size().columns - 10,
|
|
16
16
|
))
|
|
17
17
|
@optgroup.group('Common configuration', help='Configuration for local/remote endpoints')
|
|
18
|
-
@optgroup.option('--
|
|
19
|
-
@optgroup.option('--
|
|
20
|
-
@optgroup.option('--global', '-g', 'using_global', is_flag=True, help='
|
|
21
|
-
@optgroup.option('--remote-
|
|
18
|
+
@optgroup.option('--listening-host', '-l', 'local_server', default='localhost', help='Listening server address', show_default=True)
|
|
19
|
+
@optgroup.option('--listening-port', '-lp', 'local_port', type=int, default=8080, help='Listening port', show_default=True)
|
|
20
|
+
@optgroup.option('--global', '-g', 'using_global', is_flag=True, help='Listening on all interfaces')
|
|
21
|
+
@optgroup.option('--remote-host', '-r', 'remote_server', default='localhost', help='Remote host', show_default=True)
|
|
22
22
|
@optgroup.option('--remote-port', '-rp', type=int, default=80, help='Remote port', show_default=True)
|
|
23
23
|
@optgroup.option('--tls', '-s', is_flag=True, help='Denote remote is listening on secure port')
|
|
24
|
-
@optgroup.option('-ss', is_flag=True, help='
|
|
24
|
+
@optgroup.option('-ss', is_flag=True, help='Listening on secure port')
|
|
25
25
|
@optgroup.group('TCP proxy configuration', help='Configuration for TCP proxy mode')
|
|
26
|
-
@optgroup.option('--read-delay-millis', type=int, help='Read delay
|
|
27
|
-
@optgroup.option('--write-delay-millis', type=int, help='Write delay
|
|
26
|
+
@optgroup.option('--read-delay-millis', type=int, help='Read delay(ms)', default=0, show_default=True)
|
|
27
|
+
@optgroup.option('--write-delay-millis', type=int, help='Write delay(ms)', default=0, show_default=True)
|
|
28
28
|
#
|
|
29
|
-
@optgroup.group('Thread configuration', help='Configuration for thread
|
|
29
|
+
@optgroup.group('Thread configuration', help='Configuration for thread')
|
|
30
30
|
@optgroup.option('--workers', type=int, default=1, help='Number of worker threads', show_default=True)
|
|
31
31
|
@optgroup.option('--proxy-workers', type=int, default=1, help='Number of proxy threads', show_default=True)
|
|
32
32
|
#
|
|
@@ -41,7 +41,7 @@ logger = logging.getLogger(__name__)
|
|
|
41
41
|
#
|
|
42
42
|
@optgroup.group('Traffic monitor configuration', help='Configuration for traffic monitor')
|
|
43
43
|
@optgroup.option('--monitor', '-m', is_flag=True, help='Print speed info to console for established connection')
|
|
44
|
-
@optgroup.option('--monitor-interval', '-mi', type=int, default=3, help='Speed monitor interval', show_default=True)
|
|
44
|
+
@optgroup.option('--monitor-interval', '-mi', type=int, default=3, help='Speed monitor interval(seconds)', show_default=True)
|
|
45
45
|
#
|
|
46
46
|
@optgroup.group('TLS Disguise configuration', help='Configuration for protection against unwanted inspection')
|
|
47
47
|
@optgroup.option('--disguise-tls-ip', '-dti', help='Disguised upstream TLS IP')
|
|
@@ -49,14 +49,14 @@ logger = logging.getLogger(__name__)
|
|
|
49
49
|
@optgroup.option('--run-disguise-tls-server', is_flag=True, help='Run builtin disguise TLS server without specifying external one')
|
|
50
50
|
@optgroup.option('--white-list', '-wl', help='IP White list for legal incoming TLS connections (comma separated)')
|
|
51
51
|
#
|
|
52
|
-
@optgroup.group('Proxy configuration', help='Configuration for
|
|
53
|
-
@optgroup.option('--
|
|
52
|
+
@optgroup.group('Proxy configuration', help='Configuration for application proxies')
|
|
53
|
+
@optgroup.option('--echo-proxy', '-e', 'as_echo_server', is_flag=True, help='Run as Echo server')
|
|
54
54
|
@optgroup.option('--shell-proxy', is_flag=True, help='Run as shell proxy server')
|
|
55
55
|
@optgroup.option('--http-proxy', is_flag=True, help='Run as HTTP proxy server')
|
|
56
56
|
@optgroup.option('--socks5-proxy', is_flag=True, help='Run as SOCKS5 proxy server')
|
|
57
|
-
@optgroup.option('--proxy-username', help='Proxy username')
|
|
58
|
-
@optgroup.option('--proxy-password', help='Proxy password')
|
|
59
|
-
@optgroup.option('--proxy-transform', '-t', type=(str, int, str, int), multiple=True, help='List of target transformations(origin_host, origin_port, transformed_host, transformed_port)')
|
|
57
|
+
@optgroup.option('--proxy-username', help='Proxy username for HTTP/SOCKS5 proxy')
|
|
58
|
+
@optgroup.option('--proxy-password', help='Proxy password for HTTP/SOCKS5 proxy')
|
|
59
|
+
@optgroup.option('--proxy-transform', '-t', type=(str, int, str, int), multiple=True, help='List of target transformations(origin_host, origin_port, transformed_host, transformed_port) for HTTP/SOCKS5 proxy')
|
|
60
60
|
#
|
|
61
61
|
@optgroup.group('Misc configuration')
|
|
62
62
|
@optgroup.option('-v', '--verbose', count=True)
|
|
@@ -90,12 +90,10 @@ def run_proxy(
|
|
|
90
90
|
server_address = (disguise_tls_ip, disguise_tls_port)
|
|
91
91
|
kf_mock, cf_mock = create_temp_key_cert()
|
|
92
92
|
httpd = http.server.HTTPServer(server_address, MyHttpHandler) # noqa
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
ssl_version=ssl.PROTOCOL_TLS)
|
|
98
|
-
pstderr(f"Builin disguise TLS server started listening(https://localhost:{disguise_tls_port}) ...")
|
|
93
|
+
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
|
94
|
+
context.load_cert_chain(certfile=cf_mock, keyfile=kf_mock)
|
|
95
|
+
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
|
|
96
|
+
pstderr(f"Builtin disguise TLS server started listening(https://localhost:{disguise_tls_port}) ...")
|
|
99
97
|
submit_daemon_thread(httpd.serve_forever)
|
|
100
98
|
|
|
101
99
|
client_eventloop_group = EventLoopGroup(proxy_workers, 'Client')
|
|
@@ -48,6 +48,6 @@ def trim_proxy_info(request_headers_bytes: bytes) -> bytes:
|
|
|
48
48
|
trimmed = request_headers_bytes
|
|
49
49
|
trimmed = re.sub(b'Proxy-.*\r\n', b'', trimmed, flags=re.IGNORECASE)
|
|
50
50
|
# remove host in url line
|
|
51
|
-
trimmed = re.sub(
|
|
51
|
+
trimmed = re.sub(br'^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|TRACE|CONNECT)\s+http://[\w\.-]+(:\d+)?/',
|
|
52
52
|
lambda m: m.group(1) + b' /', trimmed, flags=re.IGNORECASE | re.MULTILINE)
|
|
53
53
|
return trimmed
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
try:
|
|
2
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
3
|
+
except ImportError:
|
|
4
|
+
# Python < 3.8
|
|
5
|
+
from importlib_metadata import version, PackageNotFoundError
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
__version__ = version("simple_proxy")
|
|
9
|
+
except PackageNotFoundError:
|
|
10
|
+
__version__ = "0.0.0-dev"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple_proxy
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: A
|
|
3
|
+
Version: 0.0.28
|
|
4
|
+
Summary: A simple NIO proxy tool
|
|
5
5
|
Home-page: https://github.com/ruanhao/simple-proxy
|
|
6
|
-
Author: Hao Ruan
|
|
7
|
-
Author-email: ruanhao1116@gmail.com
|
|
6
|
+
Author-email: Hao Ruan <ruanhao1116@gmail.com>
|
|
8
7
|
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/ruanhao/simple-proxy
|
|
9
9
|
Keywords: network,tcp,non-blocking,proxy
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -22,28 +22,30 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
23
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
24
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
-
Requires-Python:
|
|
25
|
+
Requires-Python: <4,>=3.7
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: click-option-group
|
|
29
29
|
Requires-Dist: py-netty>=1.0.5
|
|
30
30
|
Requires-Dist: cryptography>=42.0.0
|
|
31
31
|
Requires-Dist: attrs>=22.1.0
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pip-chill; extra == "dev"
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: pytest>=7.4.0; extra == "test"
|
|
36
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-mock>=3.11.1; extra == "test"
|
|
39
|
+
Requires-Dist: coverage[toml]>=7.3.0; extra == "test"
|
|
40
40
|
Dynamic: license-file
|
|
41
|
-
Dynamic: requires-dist
|
|
42
|
-
Dynamic: requires-python
|
|
43
|
-
Dynamic: summary
|
|
44
41
|
|
|
45
42
|
# simple-proxy :rocket:
|
|
46
43
|
|
|
44
|
+
[](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
|
|
45
|
+
[](https://codecov.io/github/ruanhao/simple-proxy)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
47
49
|
A very simple TCP proxy tool empowered by nio tcp framework [py-netty](https://pypi.org/project/py-netty/)
|
|
48
50
|
|
|
49
51
|
There is a simple traffic control mechenism between 2 segments of TCP connection:
|
|
@@ -69,23 +71,20 @@ Usage: simple-proxy [OPTIONS]
|
|
|
69
71
|
Options:
|
|
70
72
|
Common configuration: Configuration for local/remote
|
|
71
73
|
endpoints
|
|
72
|
-
-l, --
|
|
73
|
-
localhost]
|
|
74
|
-
-lp, --
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-r, --remote-
|
|
78
|
-
localhost]
|
|
74
|
+
-l, --listening-host TEXT Listening server address
|
|
75
|
+
[default: localhost]
|
|
76
|
+
-lp, --listening-port INTEGER
|
|
77
|
+
Listening port [default: 8080]
|
|
78
|
+
-g, --global Listening on all interfaces
|
|
79
|
+
-r, --remote-host TEXT Remote host [default: localhost]
|
|
79
80
|
-rp, --remote-port INTEGER Remote port [default: 80]
|
|
80
81
|
-s, --tls Denote remote is listening on
|
|
81
82
|
secure port
|
|
82
|
-
-ss
|
|
83
|
+
-ss Listening on secure port
|
|
83
84
|
TCP proxy configuration: Configuration for TCP proxy mode
|
|
84
|
-
--read-delay-millis INTEGER Read delay
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
[default: 0]
|
|
88
|
-
Thread configuration: Configuration for thread pool
|
|
85
|
+
--read-delay-millis INTEGER Read delay(ms) [default: 0]
|
|
86
|
+
--write-delay-millis INTEGER Write delay(ms) [default: 0]
|
|
87
|
+
Thread configuration: Configuration for thread
|
|
89
88
|
--workers INTEGER Number of worker threads
|
|
90
89
|
[default: 1]
|
|
91
90
|
--proxy-workers INTEGER Number of proxy threads [default:
|
|
@@ -104,8 +103,8 @@ Options:
|
|
|
104
103
|
-m, --monitor Print speed info to console for
|
|
105
104
|
established connection
|
|
106
105
|
-mi, --monitor-interval INTEGER
|
|
107
|
-
Speed monitor interval
|
|
108
|
-
3]
|
|
106
|
+
Speed monitor interval(seconds)
|
|
107
|
+
[default: 3]
|
|
109
108
|
TLS Disguise configuration: Configuration for protection
|
|
110
109
|
against unwanted inspection
|
|
111
110
|
-dti, --disguise-tls-ip TEXT Disguised upstream TLS IP
|
|
@@ -116,18 +115,22 @@ Options:
|
|
|
116
115
|
without specifying external one
|
|
117
116
|
-wl, --white-list TEXT IP White list for legal incoming
|
|
118
117
|
TLS connections (comma separated)
|
|
119
|
-
Proxy configuration: Configuration for
|
|
120
|
-
|
|
118
|
+
Proxy configuration: Configuration for application
|
|
119
|
+
proxies
|
|
120
|
+
-e, --echo-proxy Run as Echo server
|
|
121
121
|
--shell-proxy Run as shell proxy server
|
|
122
122
|
--http-proxy Run as HTTP proxy server
|
|
123
123
|
--socks5-proxy Run as SOCKS5 proxy server
|
|
124
|
-
--proxy-username TEXT Proxy username
|
|
125
|
-
|
|
124
|
+
--proxy-username TEXT Proxy username for HTTP/SOCKS5
|
|
125
|
+
proxy
|
|
126
|
+
--proxy-password TEXT Proxy password for HTTP/SOCKS5
|
|
127
|
+
proxy
|
|
126
128
|
-t, --proxy-transform <TEXT INTEGER TEXT INTEGER>...
|
|
127
129
|
List of target
|
|
128
130
|
transformations(origin_host,
|
|
129
131
|
origin_port, transformed_host,
|
|
130
|
-
transformed_port)
|
|
132
|
+
transformed_port) for HTTP/SOCKS5
|
|
133
|
+
proxy
|
|
131
134
|
Misc configuration:
|
|
132
135
|
-v, --verbose
|
|
133
136
|
--log-file PATH Log file
|
|
@@ -76,14 +76,14 @@ def test_handle_data_case_client_rw(mocker):
|
|
|
76
76
|
client_mocker = mocker.MagicMock()
|
|
77
77
|
get_clients()[('127.0.0.1', 12345)] = client_mocker
|
|
78
78
|
assert handle_data(buffer, True, src, dst, False, False) == buffer
|
|
79
|
-
|
|
79
|
+
client_mocker.read.assert_called_once_with(len(buffer))
|
|
80
80
|
assert not client_mocker.write.called
|
|
81
81
|
|
|
82
82
|
# write case
|
|
83
83
|
client_mocker = mocker.MagicMock()
|
|
84
84
|
get_clients()[('8.8.8.8', 54321)] = client_mocker
|
|
85
85
|
assert handle_data(buffer, False, src, dst, False, False) == buffer
|
|
86
|
-
|
|
86
|
+
client_mocker.write.assert_called_once_with(len(buffer))
|
|
87
87
|
assert not client_mocker.read.called
|
|
88
88
|
|
|
89
89
|
def test_handle_data_case_log_data(mocker):
|
|
@@ -124,10 +124,10 @@ def test_tcp_proxy_client():
|
|
|
124
124
|
time.sleep(1.1)
|
|
125
125
|
c1.read(1100)
|
|
126
126
|
c1.write(1200)
|
|
127
|
-
assert c1.rbps >=
|
|
128
|
-
assert c1.wbps >=
|
|
129
|
-
assert TcpProxyClient.max_rx >=
|
|
130
|
-
assert TcpProxyClient.max_tx >=
|
|
127
|
+
assert c1.rbps >= 900
|
|
128
|
+
assert c1.wbps >= 900
|
|
129
|
+
assert TcpProxyClient.max_rx >= 900
|
|
130
|
+
assert TcpProxyClient.max_tx >= 900
|
|
131
131
|
assert c1.cumulative_read_time == 0
|
|
132
132
|
assert c1.cumulative_read_bytes == 0
|
|
133
133
|
assert c1.cumulative_write_time == 0
|
|
@@ -4,6 +4,14 @@ import time
|
|
|
4
4
|
import logging
|
|
5
5
|
import threading
|
|
6
6
|
|
|
7
|
+
|
|
8
|
+
class TestOS:
|
|
9
|
+
|
|
10
|
+
def test_os(self):
|
|
11
|
+
print("test os")
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
7
15
|
def test_from_cwd():
|
|
8
16
|
ts_str = str(int(time.time()))
|
|
9
17
|
test_path = from_cwd('test_dir', ts_str, 'test_file.txt')
|
|
@@ -14,6 +22,7 @@ def test_from_cwd():
|
|
|
14
22
|
def test_submit_daemon_thread(caplog):
|
|
15
23
|
result = []
|
|
16
24
|
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
17
26
|
def sample_function(x, y):
|
|
18
27
|
time.sleep(0.1)
|
|
19
28
|
result.append(x + y)
|
|
@@ -6,6 +6,7 @@ from simple_proxy.clients import get_clients
|
|
|
6
6
|
|
|
7
7
|
raddr = ('127.0.0.1', 8080)
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
def test_exception_caught(mocker):
|
|
10
11
|
handler = ProxyChannelHandler("1.2.3.4", 9090, EventLoopGroup())
|
|
11
12
|
ctx_mocker = mocker.MagicMock()
|
|
@@ -26,6 +27,7 @@ def test_channel_active(mocker):
|
|
|
26
27
|
handler.channel_active(ctx_mocker)
|
|
27
28
|
assert raddr in get_clients()
|
|
28
29
|
|
|
30
|
+
|
|
29
31
|
def test_create_client_case_already_exists(mocker):
|
|
30
32
|
handler = ProxyChannelHandler(
|
|
31
33
|
"1.2.3.4", 9090, EventLoopGroup(),
|
|
@@ -33,6 +35,7 @@ def test_create_client_case_already_exists(mocker):
|
|
|
33
35
|
handler._client = mocker.MagicMock()
|
|
34
36
|
handler._create_client(None, None) # no exception should be raised
|
|
35
37
|
|
|
38
|
+
|
|
36
39
|
def test_create_client_case_disguise_and_wait_for_traffic(mocker):
|
|
37
40
|
handler = ProxyChannelHandler(
|
|
38
41
|
"1.2.3.4", 9090, EventLoopGroup(),
|
|
@@ -41,6 +44,7 @@ def test_create_client_case_disguise_and_wait_for_traffic(mocker):
|
|
|
41
44
|
handler._client = mocker.MagicMock()
|
|
42
45
|
handler._create_client(None, None) # no exception should be raised
|
|
43
46
|
|
|
47
|
+
|
|
44
48
|
def test_create_client_case_non_whitelist_with_disguise(mocker):
|
|
45
49
|
handler = ProxyChannelHandler(
|
|
46
50
|
"1.2.3.4", 9090, EventLoopGroup(),
|
|
@@ -59,6 +63,7 @@ def test_create_client_case_non_whitelist_with_disguise(mocker):
|
|
|
59
63
|
assert BoostrapMocker().connect.call_args[0] == ("4.3.2.1", 443, True)
|
|
60
64
|
assert handler._client is client_mocker
|
|
61
65
|
|
|
66
|
+
|
|
62
67
|
def test_create_client_case_non_whitelist_with_disguise_but_not_tls(mocker):
|
|
63
68
|
handler = ProxyChannelHandler(
|
|
64
69
|
"1.2.3.4", 9090, EventLoopGroup(),
|
|
@@ -160,10 +165,11 @@ def test_create_client_case_no_wl_and_disguise_configured(mocker):
|
|
|
160
165
|
)
|
|
161
166
|
BoostrapMocker.return_value.connect.return_value.sync.return_value.channel.return_value = client_mocker
|
|
162
167
|
|
|
163
|
-
handler._create_client(ctx_mocker, None)
|
|
168
|
+
handler._create_client(ctx_mocker, None) # channel active
|
|
164
169
|
assert handler._client is client_mocker
|
|
165
170
|
assert BoostrapMocker().connect.call_args[0] == ("1.2.3.4", 9090, True)
|
|
166
171
|
|
|
172
|
+
|
|
167
173
|
def test_channel_inactive(mocker):
|
|
168
174
|
handler = ProxyChannelHandler("1.2.3.4", 8080, EventLoopGroup())
|
|
169
175
|
ctx_mocker = mocker.MagicMock()
|
|
@@ -209,6 +215,7 @@ def test_channel_read_case_no_delay(mocker):
|
|
|
209
215
|
assert time.time() - now < 0.5 # no delay
|
|
210
216
|
client_mocker.write.assert_called_once_with(b'test data')
|
|
211
217
|
|
|
218
|
+
|
|
212
219
|
def test_channel_read_case_write_delay(mocker):
|
|
213
220
|
handler = ProxyChannelHandler(
|
|
214
221
|
"1.2.3.4", 8080, EventLoopGroup(),
|
|
@@ -244,15 +251,14 @@ def _get_client_channel_handler(mocker, ctx0_mocker, read_delay_millis=0):
|
|
|
244
251
|
return BoostrapMocker.call_args[1]['handler_initializer']
|
|
245
252
|
|
|
246
253
|
|
|
247
|
-
|
|
248
|
-
|
|
249
254
|
def test_client_channel_inactive(mocker):
|
|
250
255
|
ctx0_mocker = mocker.MagicMock()
|
|
251
256
|
ctx0_mocker.channel.return_value.socket.return_value.getpeername.return_value = ("10.1.0.1", 12345)
|
|
252
257
|
handler_cls = _get_client_channel_handler(mocker, ctx0_mocker)
|
|
253
258
|
ctx_mocker = mocker.MagicMock()
|
|
254
259
|
handler_cls().channel_inactive(ctx_mocker)
|
|
255
|
-
|
|
260
|
+
ctx0_mocker.close.assert_called_once()
|
|
261
|
+
|
|
256
262
|
|
|
257
263
|
def test_client_channel_writability_changed(mocker):
|
|
258
264
|
ctx0_mocker = mocker.MagicMock()
|
|
@@ -286,6 +292,7 @@ def test_client_channel_read_case_no_delay(mocker):
|
|
|
286
292
|
assert time.time() - now < 0.5 # no delay
|
|
287
293
|
ctx0_mocker.write.assert_called_once_with(b'test data')
|
|
288
294
|
|
|
295
|
+
|
|
289
296
|
def test_client_channel_read_case_delay(mocker):
|
|
290
297
|
ctx0_mocker = mocker.MagicMock()
|
|
291
298
|
ctx0_mocker.channel.return_value.socket.return_value.getpeername.return_value = ("10.1.0.1", 12345)
|
|
@@ -298,4 +305,4 @@ def test_client_channel_read_case_delay(mocker):
|
|
|
298
305
|
handler = handler_cls()
|
|
299
306
|
handler.channel_read(ctx_mocker, b'test data')
|
|
300
307
|
assert time.time() - now >= 1
|
|
301
|
-
ctx0_mocker.write.assert_called_once_with(b'test data')
|
|
308
|
+
ctx0_mocker.write.assert_called_once_with(b'test data')
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
from fastmcp.contrib.bulk_tool_caller.example import echo_tool
|
|
2
|
-
|
|
3
1
|
from simple_proxy.run import run_proxy
|
|
4
2
|
import pytest
|
|
5
3
|
from simple_proxy.handler.shell_channel_handler import ShellChannelHandler
|
|
6
4
|
|
|
5
|
+
|
|
7
6
|
def test_run_proxy_case_tls_mode_with_both_disguise_ip_and_server():
|
|
8
7
|
with pytest.raises(SystemExit):
|
|
9
8
|
run_proxy(
|
|
@@ -19,6 +18,7 @@ def test_run_proxy_case_tls_mode_with_both_disguise_ip_and_server():
|
|
|
19
18
|
run_disguise_tls_server=True,
|
|
20
19
|
)
|
|
21
20
|
|
|
21
|
+
|
|
22
22
|
def test_run_proxy_case_tcp_proxy(mocker):
|
|
23
23
|
ServerBoostrapMocker = mocker.patch('simple_proxy.run.ServerBootstrap')
|
|
24
24
|
run_proxy(
|
|
@@ -32,8 +32,8 @@ def test_run_proxy_case_tcp_proxy(mocker):
|
|
|
32
32
|
monitor_interval=3,
|
|
33
33
|
disguise_tls_ip="1.2.3.4",
|
|
34
34
|
disguise_tls_port=443,
|
|
35
|
-
run_disguise_tls_server
|
|
36
|
-
alpn
|
|
35
|
+
run_disguise_tls_server=False,
|
|
36
|
+
alpn=True,
|
|
37
37
|
read_delay_millis=100,
|
|
38
38
|
write_delay_millis=200,
|
|
39
39
|
workers=2,
|
|
@@ -64,7 +64,6 @@ def test_run_proxy_case_tcp_proxy(mocker):
|
|
|
64
64
|
assert ServerBoostrapMocker.return_value.bind.call_args[1]['port'] == 8081
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
|
|
68
67
|
def test_run_proxy_case_http_proxy(mocker):
|
|
69
68
|
ServerBoostrapMocker = mocker.patch('simple_proxy.run.ServerBootstrap')
|
|
70
69
|
run_proxy(
|
|
@@ -78,11 +77,11 @@ def test_run_proxy_case_http_proxy(mocker):
|
|
|
78
77
|
monitor_interval=3,
|
|
79
78
|
disguise_tls_ip=None,
|
|
80
79
|
disguise_tls_port=443,
|
|
81
|
-
run_disguise_tls_server
|
|
82
|
-
alpn
|
|
83
|
-
read_delay_millis
|
|
84
|
-
write_delay_millis
|
|
85
|
-
workers
|
|
80
|
+
run_disguise_tls_server=False,
|
|
81
|
+
alpn=True,
|
|
82
|
+
read_delay_millis=100,
|
|
83
|
+
write_delay_millis=200,
|
|
84
|
+
workers=4,
|
|
86
85
|
http_proxy=True,
|
|
87
86
|
proxy_transform=(('example.com', 80, 'transformed.com', 8080),),
|
|
88
87
|
proxy_workers=2,
|
|
@@ -104,6 +103,7 @@ def test_run_proxy_case_http_proxy(mocker):
|
|
|
104
103
|
assert http_proxy_channel_handler._proxy_username == "cisco"
|
|
105
104
|
assert http_proxy_channel_handler._proxy_password == "juniper"
|
|
106
105
|
|
|
106
|
+
|
|
107
107
|
def test_run_proxy_case_socks5_proxy(mocker):
|
|
108
108
|
ServerBoostrapMocker = mocker.patch('simple_proxy.run.ServerBootstrap')
|
|
109
109
|
run_proxy(
|
|
@@ -117,11 +117,11 @@ def test_run_proxy_case_socks5_proxy(mocker):
|
|
|
117
117
|
monitor_interval=3,
|
|
118
118
|
disguise_tls_ip=None,
|
|
119
119
|
disguise_tls_port=443,
|
|
120
|
-
run_disguise_tls_server
|
|
121
|
-
alpn
|
|
122
|
-
read_delay_millis
|
|
123
|
-
write_delay_millis
|
|
124
|
-
workers
|
|
120
|
+
run_disguise_tls_server=False,
|
|
121
|
+
alpn=True,
|
|
122
|
+
read_delay_millis=100,
|
|
123
|
+
write_delay_millis=200,
|
|
124
|
+
workers=4,
|
|
125
125
|
socks5_proxy=True,
|
|
126
126
|
proxy_transform=(('example.com', 80, 'transformed.com', 8080),),
|
|
127
127
|
proxy_workers=2,
|
|
@@ -145,6 +145,7 @@ def test_run_proxy_case_socks5_proxy(mocker):
|
|
|
145
145
|
assert ServerBoostrapMocker.return_value.bind.call_args[1]['address'] == '127.0.0.2'
|
|
146
146
|
assert ServerBoostrapMocker.return_value.bind.call_args[1]['port'] == 8081
|
|
147
147
|
|
|
148
|
+
|
|
148
149
|
def test_run_proxy_case_shell_proxy(mocker):
|
|
149
150
|
ServerBoostrapMocker = mocker.patch('simple_proxy.run.ServerBootstrap')
|
|
150
151
|
run_proxy(
|
|
@@ -158,11 +159,11 @@ def test_run_proxy_case_shell_proxy(mocker):
|
|
|
158
159
|
monitor_interval=3,
|
|
159
160
|
disguise_tls_ip=None,
|
|
160
161
|
disguise_tls_port=443,
|
|
161
|
-
run_disguise_tls_server
|
|
162
|
-
alpn
|
|
163
|
-
read_delay_millis
|
|
164
|
-
write_delay_millis
|
|
165
|
-
workers
|
|
162
|
+
run_disguise_tls_server=False,
|
|
163
|
+
alpn=True,
|
|
164
|
+
read_delay_millis=100,
|
|
165
|
+
write_delay_millis=200,
|
|
166
|
+
workers=4,
|
|
166
167
|
shell_proxy=True,
|
|
167
168
|
)
|
|
168
169
|
kwargs = ServerBoostrapMocker.call_args[1]
|
|
@@ -189,11 +190,11 @@ def test_run_proxy_case_echo_server(mocker):
|
|
|
189
190
|
monitor_interval=3,
|
|
190
191
|
disguise_tls_ip=None,
|
|
191
192
|
disguise_tls_port=443,
|
|
192
|
-
run_disguise_tls_server
|
|
193
|
-
alpn
|
|
194
|
-
read_delay_millis
|
|
195
|
-
write_delay_millis
|
|
196
|
-
workers
|
|
193
|
+
run_disguise_tls_server=False,
|
|
194
|
+
alpn=True,
|
|
195
|
+
read_delay_millis=100,
|
|
196
|
+
write_delay_millis=200,
|
|
197
|
+
workers=4,
|
|
197
198
|
as_echo_server=True,
|
|
198
199
|
proxy_workers=8,
|
|
199
200
|
)
|
|
@@ -207,6 +208,7 @@ def test_run_proxy_case_echo_server(mocker):
|
|
|
207
208
|
assert echo_channel_handler._client_eventloop_group.num == 8
|
|
208
209
|
assert echo_channel_handler._tls is True
|
|
209
210
|
|
|
211
|
+
|
|
210
212
|
def test_run_disguise_tls_server(mocker):
|
|
211
213
|
mocker.patch('simple_proxy.run.ServerBootstrap')
|
|
212
214
|
submit_daemon_thread_mocker = mocker.patch('simple_proxy.run.submit_daemon_thread')
|
|
@@ -221,14 +223,15 @@ def test_run_disguise_tls_server(mocker):
|
|
|
221
223
|
monitor_interval=3,
|
|
222
224
|
disguise_tls_ip=None,
|
|
223
225
|
disguise_tls_port=443,
|
|
224
|
-
run_disguise_tls_server
|
|
225
|
-
alpn
|
|
226
|
-
read_delay_millis
|
|
227
|
-
write_delay_millis
|
|
228
|
-
workers
|
|
226
|
+
run_disguise_tls_server=True,
|
|
227
|
+
alpn=True,
|
|
228
|
+
read_delay_millis=100,
|
|
229
|
+
write_delay_millis=200,
|
|
230
|
+
workers=4,
|
|
229
231
|
)
|
|
230
232
|
submit_daemon_thread_mocker.assert_called_once()
|
|
231
233
|
|
|
234
|
+
|
|
232
235
|
def test_run_monitor(mocker):
|
|
233
236
|
mocker.patch('simple_proxy.run.ServerBootstrap')
|
|
234
237
|
spawn_clients_monitor_mocker = mocker.patch('simple_proxy.run.spawn_clients_monitor')
|
|
@@ -243,10 +246,10 @@ def test_run_monitor(mocker):
|
|
|
243
246
|
monitor_interval=30,
|
|
244
247
|
disguise_tls_ip=None,
|
|
245
248
|
disguise_tls_port=443,
|
|
246
|
-
run_disguise_tls_server
|
|
247
|
-
alpn
|
|
248
|
-
read_delay_millis
|
|
249
|
-
write_delay_millis
|
|
250
|
-
workers
|
|
249
|
+
run_disguise_tls_server=False,
|
|
250
|
+
alpn=True,
|
|
251
|
+
read_delay_millis=100,
|
|
252
|
+
write_delay_millis=200,
|
|
253
|
+
workers=4,
|
|
251
254
|
)
|
|
252
|
-
spawn_clients_monitor_mocker.assert_called_once_with(30)
|
|
255
|
+
spawn_clients_monitor_mocker.assert_called_once_with(30)
|
|
@@ -212,7 +212,7 @@ def test_channel_read_case_authenticate_with_wrong_password(mocker):
|
|
|
212
212
|
handler.channel_read(ctx, b'\x05\x01\x02')
|
|
213
213
|
ctx.write.assert_called_with(b'\x05\x02') # USERNAME/PASSWORD authentication
|
|
214
214
|
|
|
215
|
-
with pytest.raises(ValueError, match="Authentication failed: cisco/\*\*\*\*\*\*\*\*"):
|
|
215
|
+
with pytest.raises(ValueError, match=r"Authentication failed: cisco/\*\*\*\*\*\*\*\*"):
|
|
216
216
|
handler.channel_read(ctx, b'\x01\x05') # Version 1
|
|
217
217
|
handler.channel_read(ctx, b'cis')
|
|
218
218
|
handler.channel_read(ctx, b'co')
|
simple_proxy-0.0.26/setup.py
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# setup.py
|
|
2
|
-
from setuptools import setup, find_packages
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
this_directory = Path(__file__).parent
|
|
6
|
-
long_description = (this_directory / "README.md").read_text()
|
|
7
|
-
# install_requires = (this_directory / 'requirements.txt').read_text().splitlines()
|
|
8
|
-
|
|
9
|
-
__version__ = None
|
|
10
|
-
|
|
11
|
-
exec(open("simple_proxy/version.py").read())
|
|
12
|
-
|
|
13
|
-
config = {
|
|
14
|
-
'name': 'simple_proxy',
|
|
15
|
-
'url': 'https://github.com/ruanhao/simple-proxy',
|
|
16
|
-
'license': 'MIT',
|
|
17
|
-
"long_description": long_description,
|
|
18
|
-
"long_description_content_type": 'text/markdown',
|
|
19
|
-
'description': 'A very simple NIO TCP proxy server',
|
|
20
|
-
'author' : 'Hao Ruan',
|
|
21
|
-
'author_email': 'ruanhao1116@gmail.com',
|
|
22
|
-
'keywords': ['network', 'tcp', 'non-blocking', 'proxy'],
|
|
23
|
-
'version': __version__,
|
|
24
|
-
'packages': find_packages(),
|
|
25
|
-
'install_requires': ['click-option-group', 'py-netty>=1.0.5', 'cryptography>=42.0.0', 'attrs>=22.1.0'],
|
|
26
|
-
'python_requires': ">=3.7, <4",
|
|
27
|
-
'setup_requires': ['wheel'],
|
|
28
|
-
'package_data': {'simple_proxy': ['*']},
|
|
29
|
-
'entry_points': {
|
|
30
|
-
'console_scripts': [
|
|
31
|
-
'simple-proxy = simple_proxy.__main__:_run',
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
'classifiers': [
|
|
35
|
-
"Intended Audience :: Developers",
|
|
36
|
-
'License :: OSI Approved :: MIT License',
|
|
37
|
-
"Natural Language :: English",
|
|
38
|
-
"Operating System :: OS Independent",
|
|
39
|
-
"Programming Language :: Python",
|
|
40
|
-
"Programming Language :: Python :: 3",
|
|
41
|
-
"Programming Language :: Python :: 3.7",
|
|
42
|
-
"Programming Language :: Python :: 3.8",
|
|
43
|
-
"Programming Language :: Python :: 3.9",
|
|
44
|
-
"Programming Language :: Python :: 3.10",
|
|
45
|
-
"Programming Language :: Python :: 3.11",
|
|
46
|
-
"Programming Language :: Python :: 3.12",
|
|
47
|
-
"Programming Language :: Python :: 3.13",
|
|
48
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
49
|
-
"Topic :: Software Development :: Libraries",
|
|
50
|
-
],
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
setup(**config)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.26"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
simple_proxy
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/http_proxy_channel_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/socks5_proxy_channel_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|