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.
Files changed (47) hide show
  1. {simple_proxy-0.0.26/simple_proxy.egg-info → simple_proxy-0.0.28}/PKG-INFO +39 -36
  2. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/README.md +26 -20
  3. simple_proxy-0.0.28/pyproject.toml +67 -0
  4. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/__main__.py +14 -14
  5. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/run.py +4 -6
  6. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/proxyutils.py +1 -1
  7. simple_proxy-0.0.28/simple_proxy/version.py +10 -0
  8. {simple_proxy-0.0.26 → simple_proxy-0.0.28/simple_proxy.egg-info}/PKG-INFO +39 -36
  9. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy.egg-info/SOURCES.txt +1 -1
  10. simple_proxy-0.0.28/simple_proxy.egg-info/requires.txt +14 -0
  11. simple_proxy-0.0.28/simple_proxy.egg-info/top_level.txt +7 -0
  12. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_clients.py +6 -6
  13. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_osutils.py +9 -0
  14. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_proxy_channel_handler.py +12 -5
  15. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_run.py +39 -36
  16. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_socks5_proxy_channel_handler.py +1 -1
  17. simple_proxy-0.0.26/setup.py +0 -53
  18. simple_proxy-0.0.26/simple_proxy/version.py +0 -1
  19. simple_proxy-0.0.26/simple_proxy.egg-info/requires.txt +0 -4
  20. simple_proxy-0.0.26/simple_proxy.egg-info/top_level.txt +0 -1
  21. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/LICENSE +0 -0
  22. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/setup.cfg +0 -0
  23. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/__init__.py +0 -0
  24. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/clients.py +0 -0
  25. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/__init__.py +0 -0
  26. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/echo_channel_handler.py +0 -0
  27. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/http_proxy_channel_handler.py +0 -0
  28. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/proxy_channel_handler.py +0 -0
  29. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/shell_channel_handler.py +0 -0
  30. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/handler/socks5_proxy_channel_handler.py +0 -0
  31. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/__init__.py +0 -0
  32. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/certutils.py +0 -0
  33. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/logutils.py +0 -0
  34. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/netutils.py +0 -0
  35. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/osutils.py +0 -0
  36. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/stringutils.py +0 -0
  37. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy/utils/tlsutils.py +0 -0
  38. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy.egg-info/dependency_links.txt +0 -0
  39. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/simple_proxy.egg-info/entry_points.txt +0 -0
  40. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_certutils.py +0 -0
  41. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_echo_channel_handler.py +0 -0
  42. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_http_proxy_channel_handler.py +0 -0
  43. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_logutils.py +0 -0
  44. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_netutils.py +0 -0
  45. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_proxyutils.py +0 -0
  46. {simple_proxy-0.0.26 → simple_proxy-0.0.28}/tests/test_stringutils.py +0 -0
  47. {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.26
4
- Summary: A very simple NIO TCP proxy server
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: >=3.7, <4
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
- Dynamic: author
33
- Dynamic: author-email
34
- Dynamic: classifier
35
- Dynamic: description
36
- Dynamic: description-content-type
37
- Dynamic: home-page
38
- Dynamic: keywords
39
- Dynamic: license
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
+ [![CI](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml/badge.svg)](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
45
+ [![codecov](https://codecov.io/github/ruanhao/simple-proxy/graph/badge.svg?token=812EM2WL0L)](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, --local-server TEXT Local server address [default:
73
- localhost]
74
- -lp, --local-port INTEGER Local port [default: 8080]
75
- -g, --global Local port listening on all
76
- interfaces
77
- -r, --remote-server TEXT Remote server address [default:
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 Make local listen on secure port
83
+ -ss Listening on secure port
83
84
  TCP proxy configuration: Configuration for TCP proxy mode
84
- --read-delay-millis INTEGER Read delay in milliseconds
85
- [default: 0]
86
- --write-delay-millis INTEGER Write delay in milliseconds
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 [default:
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 proxy
120
- -e, --as-echo-server Run as Echo server
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
- --proxy-password TEXT Proxy password
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
+ [![CI](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml/badge.svg)](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/github/ruanhao/simple-proxy/graph/badge.svg?token=812EM2WL0L)](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, --local-server TEXT Local server address [default:
29
- localhost]
30
- -lp, --local-port INTEGER Local port [default: 8080]
31
- -g, --global Local port listening on all
32
- interfaces
33
- -r, --remote-server TEXT Remote server address [default:
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 Make local listen on secure port
42
+ -ss Listening on secure port
39
43
  TCP proxy configuration: Configuration for TCP proxy mode
40
- --read-delay-millis INTEGER Read delay in milliseconds
41
- [default: 0]
42
- --write-delay-millis INTEGER Write delay in milliseconds
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 [default:
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 proxy
76
- -e, --as-echo-server Run as Echo server
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
- --proxy-password TEXT Proxy password
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('--local-server', '-l', default='localhost', help='Local server address', show_default=True)
19
- @optgroup.option('--local-port', '-lp', type=int, default=8080, help='Local port', show_default=True)
20
- @optgroup.option('--global', '-g', 'using_global', is_flag=True, help='Local port listening on all interfaces')
21
- @optgroup.option('--remote-server', '-r', default='localhost', help='Remote server address', show_default=True)
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='Make local listen on secure port')
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 in milliseconds', default=0, show_default=True)
27
- @optgroup.option('--write-delay-millis', type=int, help='Write delay in milliseconds', default=0, show_default=True)
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 pool')
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 proxy')
53
- @optgroup.option('--as-echo-server', '-e', is_flag=True, help='Run as Echo server')
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
- httpd.socket = ssl.wrap_socket(httpd.socket,
94
- server_side=True,
95
- certfile=cf_mock,
96
- keyfile=kf_mock,
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(b'^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|TRACE|CONNECT)\s+http://[\w\.-]+(:\d+)?/',
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.26
4
- Summary: A very simple NIO TCP proxy server
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: >=3.7, <4
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
- Dynamic: author
33
- Dynamic: author-email
34
- Dynamic: classifier
35
- Dynamic: description
36
- Dynamic: description-content-type
37
- Dynamic: home-page
38
- Dynamic: keywords
39
- Dynamic: license
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
+ [![CI](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml/badge.svg)](https://github.com/ruanhao/simple-proxy/actions/workflows/ci.yml)
45
+ [![codecov](https://codecov.io/github/ruanhao/simple-proxy/graph/badge.svg?token=812EM2WL0L)](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, --local-server TEXT Local server address [default:
73
- localhost]
74
- -lp, --local-port INTEGER Local port [default: 8080]
75
- -g, --global Local port listening on all
76
- interfaces
77
- -r, --remote-server TEXT Remote server address [default:
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 Make local listen on secure port
83
+ -ss Listening on secure port
83
84
  TCP proxy configuration: Configuration for TCP proxy mode
84
- --read-delay-millis INTEGER Read delay in milliseconds
85
- [default: 0]
86
- --write-delay-millis INTEGER Write delay in milliseconds
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 [default:
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 proxy
120
- -e, --as-echo-server Run as Echo server
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
- --proxy-password TEXT Proxy password
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,7 +1,7 @@
1
1
  LICENSE
2
2
  README.md
3
+ pyproject.toml
3
4
  setup.cfg
4
- setup.py
5
5
  simple_proxy/__init__.py
6
6
  simple_proxy/__main__.py
7
7
  simple_proxy/clients.py
@@ -0,0 +1,14 @@
1
+ click-option-group
2
+ py-netty>=1.0.5
3
+ cryptography>=42.0.0
4
+ attrs>=22.1.0
5
+
6
+ [dev]
7
+ pip-chill
8
+
9
+ [test]
10
+ pytest>=7.4.0
11
+ pytest-cov>=4.1.0
12
+ pytest-asyncio>=0.21.0
13
+ pytest-mock>=3.11.1
14
+ coverage[toml]>=7.3.0
@@ -0,0 +1,7 @@
1
+ __tcpflow__
2
+ build
3
+ htmlcov
4
+ img
5
+ simple_proxy
6
+ test_dir
7
+ tests
@@ -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
- assert client_mocker.read.called_once_with(len(buffer))
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
- assert client_mocker.write.called_once_with(len(buffer))
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 >= 1000
128
- assert c1.wbps >= 1000
129
- assert TcpProxyClient.max_rx >= 1000
130
- assert TcpProxyClient.max_tx >= 1000
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) # channel active
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
- assert ctx0_mocker.close.called_once()
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 = False,
36
- alpn = True,
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 = False,
82
- alpn = True,
83
- read_delay_millis = 100,
84
- write_delay_millis = 200,
85
- workers = 4,
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 = False,
121
- alpn = True,
122
- read_delay_millis = 100,
123
- write_delay_millis = 200,
124
- workers = 4,
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 = False,
162
- alpn = True,
163
- read_delay_millis = 100,
164
- write_delay_millis = 200,
165
- workers = 4,
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 = False,
193
- alpn = True,
194
- read_delay_millis = 100,
195
- write_delay_millis = 200,
196
- workers = 4,
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 = True,
225
- alpn = True,
226
- read_delay_millis = 100,
227
- write_delay_millis = 200,
228
- workers = 4,
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 = False,
247
- alpn = True,
248
- read_delay_millis = 100,
249
- write_delay_millis = 200,
250
- workers = 4,
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')
@@ -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,4 +0,0 @@
1
- click-option-group
2
- py-netty>=1.0.5
3
- cryptography>=42.0.0
4
- attrs>=22.1.0
@@ -1 +0,0 @@
1
- simple_proxy
File without changes
File without changes