asyncproxy 1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
asyncproxy-1.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010-2025 Sippy Software, Inc. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification,
4
+ are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this
7
+ list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation and/or
11
+ other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
17
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,2 @@
1
+ include src/Symbol.map src/asp_iostats.h src/asp_sock.So src/asp_sock.c src/asp_sock.h src/asyncproxy.So src/asyncproxy.c src/asyncproxy.h
2
+ include README.md
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: asyncproxy
3
+ Version: 1.0
4
+ Summary: Background TCP proxy for async IO
5
+ Home-page: https://github.com/sippy/libasyncproxy.git
6
+ Author: Maksym Sobolyev
7
+ Author-email: sobomax@sippysoft.com
8
+ Classifier: License :: OSI Approved :: BSD License
9
+ Classifier: Operating System :: POSIX
10
+ Classifier: Programming Language :: C
11
+ Classifier: Programming Language :: Python
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: summary
22
+
23
+ # libasyncproxy
24
+
25
+ ## Introduction
26
+
27
+ The libasyncproxy is a fairy simple C library and a respective python wrapper,
28
+ which allows splicing two sockets, pipes and in general file descriptors to
29
+ relay bidirectional data in/out in a background using a worker thread (one per
30
+ connection at the moment).
31
+
32
+ Unlike system-wide facilities that might be offering similar functionality,
33
+ this library provides more control and flexibility. Allowing to connect
34
+ different kinds of underlying objects (i.e. plain file to a socket, device to
35
+ a pipe etc).
36
+
37
+ It also privides mechanism for the python code to supply a handler(s) to
38
+ monitor, record and/or alter the data being transmitted.
39
+
40
+ Last but not least, the C library can be used directly from a low-level code
41
+ for the same effect.
42
+
43
+ ## History
44
+
45
+ The code was created to allow Python code implementing application-layer proxy
46
+ to manage session routing and connection, while handling all transfers outside
47
+ of confinments of the slow Python and its GIL.
48
+
49
+ ## Interfaces
50
+
51
+ AsyncProxy: the lowest-level interface, dealing with raw sockets, wrapper for
52
+ libasyncproxy.
53
+
54
+ ForwarderFast: super-set of AsyncProxy with some utility methods.
55
+
56
+ Forwarder: same API and functionality as ForwarderFast, but without using
57
+ AsyncProxy C module (i.e. python thread doing i/o). Mostly for backward
58
+ compatibility when we need to break library API.
59
+
60
+ TCPProxy: set of high-level classes to accept and manage inbound connections
61
+ and initiate/tear-down outbound as needed, connecting them using forwarders
62
+ once established. Will use ForwarderFast if available, falling back to the
63
+ Forwarder if that fails to load or initialize.
64
+
65
+ ## Use Cases
66
+
67
+ We use this library to allow applications to be redirected to one of several
68
+ available DB replicas and re-routed instantly if the configuration changes.
69
+
70
+ ## Build and Install Python module from source code:
71
+
72
+ ```
73
+ git clone https://github.com/sippy/libasyncproxy.git
74
+ pip install libasyncproxy/
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ### asyncproxy -- `AsyncProxy2FD` Example
80
+
81
+ This example shows how to set up a bidirectional relay between two socket pairs using `AsyncProxy2FD`. Data sent on one end is forwarded to the other, and vice versa.
82
+
83
+ ```python
84
+ import socket
85
+ from asyncproxy.AsyncProxy import AsyncProxy2FD
86
+
87
+ # 1. Create two socket pairs:
88
+ # - (client_socket, proxy_in): client writes to `proxy_in`
89
+ # - (proxy_out, server_socket): proxy writes to `proxy_out`, server reads
90
+ client_socket, proxy_in = socket.socketpair()
91
+ proxy_out, server_socket = socket.socketpair()
92
+
93
+ # 2. Initialize and start the proxy:
94
+ proxy = AsyncProxy2FD(proxy_in.fileno(), proxy_out.fileno())
95
+ proxy.start()
96
+
97
+ # 3. Send from client → server:
98
+ client_msg = b"Hello from Client!"
99
+ client_socket.sendall(client_msg)
100
+ print("Client sent:", client_msg.decode())
101
+
102
+ server_recv = server_socket.recv(1024)
103
+ print("Server received:", server_recv.decode())
104
+
105
+ # 4. Send from server → client:
106
+ server_msg = b"Hello from Server!"
107
+ server_socket.sendall(server_msg)
108
+ print("Server sent:", server_msg.decode())
109
+
110
+ client_recv = client_socket.recv(1024)
111
+ print("Client received:", client_recv.decode())
112
+
113
+ # 5. Shutdown and cleanup:
114
+ proxy.join(shutdown=True)
115
+ for sock in (client_socket, proxy_in, proxy_out, server_socket):
116
+ sock.close()
117
+ ```
118
+
119
+ ### asyncproxy -- `TCPProxy` Example
120
+
121
+ This example shows how to set up a TCP proxy accepting connections on
122
+ `localhost:8080` and forwarding it to `www.google.com:80`.
123
+
124
+ ```python
125
+ import socket
126
+ from time import sleep
127
+ from asyncproxy.TCPProxy import TCPProxy
128
+
129
+ # 1. Initialize and start the proxy:
130
+ # - Listen on local port 8080
131
+ # - Forward all traffic to www.google.com:80
132
+ proxy = TCPProxy(port=8080, newhost='www.google.com', newport=80)
133
+ proxy.start()
134
+ print("TCPProxy running on:", proxy.sock.getsockname())
135
+
136
+ # 2. Connect via the proxy and send HTTP requests twice
137
+ for _ in (1, 2):
138
+ with socket.create_connection(('127.0.0.1', 8080)) as s:
139
+ print("Connected to www.google.com via TCPProxy.")
140
+ s.sendall(b"GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
141
+ resp = s.recv(256)
142
+ print("Response received from proxy:")
143
+ print(resp.decode('utf-8', errors='replace'))
144
+
145
+ # 3. Shutdown the proxy cleanly
146
+ proxy.shutdown()
147
+ ```
148
+
149
+ ### asyncproxy -- Advanced `AsyncProxy2FD` Example
150
+
151
+ This example shows how to subclass `AsyncProxy2FD` to inspect and modify data in transit using custom `in2out` and `out2in` hooks.
152
+
153
+ ```python
154
+ import socket
155
+ from ctypes import string_at, memmove
156
+ from asyncproxy.AsyncProxy import AsyncProxy2FD
157
+
158
+ class NosyProxy(AsyncProxy2FD):
159
+ def in2out(self, res_p):
160
+ # Unpack the struct
161
+ tr = res_p.contents
162
+ ptr, length = tr.buf, tr.len
163
+
164
+ # Read original bytes, transform, and write back
165
+ original = string_at(ptr, length)
166
+ length -= 1
167
+ transformed = original.upper()[:length]
168
+ memmove(ptr, transformed, length)
169
+ tr.len = length
170
+
171
+ print("in2out hook:", original, "→", transformed)
172
+
173
+ def out2in(self, res_p):
174
+ tr = res_p.contents
175
+ ptr, length = tr.buf, tr.len
176
+
177
+ original = string_at(ptr, length)
178
+ length -= 1
179
+ transformed = original[::-1][1:]
180
+ memmove(ptr, transformed, length)
181
+ tr.len = length
182
+
183
+ print("out2in hook:", original, "→", transformed)
184
+
185
+ # 1. Create two socket pairs for bidirectional flow
186
+ client_socket, proxy_in = socket.socketpair()
187
+ proxy_out, server_socket = socket.socketpair()
188
+
189
+ # 2. Initialize and start the custom proxy
190
+ proxy = NosyProxy(proxy_in.fileno(), proxy_out.fileno())
191
+ proxy.start()
192
+
193
+ # 3. Client → Server (uppercase transformation)
194
+ client_msg = b"Hello from Client!"
195
+ client_socket.sendall(client_msg)
196
+ print("Client sent:", client_msg.decode())
197
+
198
+ srv_recv = server_socket.recv(1024)
199
+ print("Server received:", srv_recv.decode())
200
+
201
+ # 4. Server → Client (reverse transformation)
202
+ server_msg = b"Hello from Server!"
203
+ server_socket.sendall(server_msg)
204
+ print("Server sent:", server_msg.decode())
205
+
206
+ cli_recv = client_socket.recv(1024)
207
+ print("Client received:", cli_recv.decode())
208
+
209
+ # 5. Shutdown and cleanup
210
+ proxy.join(shutdown=True)
211
+ for sock in (client_socket, proxy_in, proxy_out, server_socket):
212
+ sock.close()
213
+ ```
@@ -0,0 +1,191 @@
1
+ # libasyncproxy
2
+
3
+ ## Introduction
4
+
5
+ The libasyncproxy is a fairy simple C library and a respective python wrapper,
6
+ which allows splicing two sockets, pipes and in general file descriptors to
7
+ relay bidirectional data in/out in a background using a worker thread (one per
8
+ connection at the moment).
9
+
10
+ Unlike system-wide facilities that might be offering similar functionality,
11
+ this library provides more control and flexibility. Allowing to connect
12
+ different kinds of underlying objects (i.e. plain file to a socket, device to
13
+ a pipe etc).
14
+
15
+ It also privides mechanism for the python code to supply a handler(s) to
16
+ monitor, record and/or alter the data being transmitted.
17
+
18
+ Last but not least, the C library can be used directly from a low-level code
19
+ for the same effect.
20
+
21
+ ## History
22
+
23
+ The code was created to allow Python code implementing application-layer proxy
24
+ to manage session routing and connection, while handling all transfers outside
25
+ of confinments of the slow Python and its GIL.
26
+
27
+ ## Interfaces
28
+
29
+ AsyncProxy: the lowest-level interface, dealing with raw sockets, wrapper for
30
+ libasyncproxy.
31
+
32
+ ForwarderFast: super-set of AsyncProxy with some utility methods.
33
+
34
+ Forwarder: same API and functionality as ForwarderFast, but without using
35
+ AsyncProxy C module (i.e. python thread doing i/o). Mostly for backward
36
+ compatibility when we need to break library API.
37
+
38
+ TCPProxy: set of high-level classes to accept and manage inbound connections
39
+ and initiate/tear-down outbound as needed, connecting them using forwarders
40
+ once established. Will use ForwarderFast if available, falling back to the
41
+ Forwarder if that fails to load or initialize.
42
+
43
+ ## Use Cases
44
+
45
+ We use this library to allow applications to be redirected to one of several
46
+ available DB replicas and re-routed instantly if the configuration changes.
47
+
48
+ ## Build and Install Python module from source code:
49
+
50
+ ```
51
+ git clone https://github.com/sippy/libasyncproxy.git
52
+ pip install libasyncproxy/
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ### asyncproxy -- `AsyncProxy2FD` Example
58
+
59
+ This example shows how to set up a bidirectional relay between two socket pairs using `AsyncProxy2FD`. Data sent on one end is forwarded to the other, and vice versa.
60
+
61
+ ```python
62
+ import socket
63
+ from asyncproxy.AsyncProxy import AsyncProxy2FD
64
+
65
+ # 1. Create two socket pairs:
66
+ # - (client_socket, proxy_in): client writes to `proxy_in`
67
+ # - (proxy_out, server_socket): proxy writes to `proxy_out`, server reads
68
+ client_socket, proxy_in = socket.socketpair()
69
+ proxy_out, server_socket = socket.socketpair()
70
+
71
+ # 2. Initialize and start the proxy:
72
+ proxy = AsyncProxy2FD(proxy_in.fileno(), proxy_out.fileno())
73
+ proxy.start()
74
+
75
+ # 3. Send from client → server:
76
+ client_msg = b"Hello from Client!"
77
+ client_socket.sendall(client_msg)
78
+ print("Client sent:", client_msg.decode())
79
+
80
+ server_recv = server_socket.recv(1024)
81
+ print("Server received:", server_recv.decode())
82
+
83
+ # 4. Send from server → client:
84
+ server_msg = b"Hello from Server!"
85
+ server_socket.sendall(server_msg)
86
+ print("Server sent:", server_msg.decode())
87
+
88
+ client_recv = client_socket.recv(1024)
89
+ print("Client received:", client_recv.decode())
90
+
91
+ # 5. Shutdown and cleanup:
92
+ proxy.join(shutdown=True)
93
+ for sock in (client_socket, proxy_in, proxy_out, server_socket):
94
+ sock.close()
95
+ ```
96
+
97
+ ### asyncproxy -- `TCPProxy` Example
98
+
99
+ This example shows how to set up a TCP proxy accepting connections on
100
+ `localhost:8080` and forwarding it to `www.google.com:80`.
101
+
102
+ ```python
103
+ import socket
104
+ from time import sleep
105
+ from asyncproxy.TCPProxy import TCPProxy
106
+
107
+ # 1. Initialize and start the proxy:
108
+ # - Listen on local port 8080
109
+ # - Forward all traffic to www.google.com:80
110
+ proxy = TCPProxy(port=8080, newhost='www.google.com', newport=80)
111
+ proxy.start()
112
+ print("TCPProxy running on:", proxy.sock.getsockname())
113
+
114
+ # 2. Connect via the proxy and send HTTP requests twice
115
+ for _ in (1, 2):
116
+ with socket.create_connection(('127.0.0.1', 8080)) as s:
117
+ print("Connected to www.google.com via TCPProxy.")
118
+ s.sendall(b"GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
119
+ resp = s.recv(256)
120
+ print("Response received from proxy:")
121
+ print(resp.decode('utf-8', errors='replace'))
122
+
123
+ # 3. Shutdown the proxy cleanly
124
+ proxy.shutdown()
125
+ ```
126
+
127
+ ### asyncproxy -- Advanced `AsyncProxy2FD` Example
128
+
129
+ This example shows how to subclass `AsyncProxy2FD` to inspect and modify data in transit using custom `in2out` and `out2in` hooks.
130
+
131
+ ```python
132
+ import socket
133
+ from ctypes import string_at, memmove
134
+ from asyncproxy.AsyncProxy import AsyncProxy2FD
135
+
136
+ class NosyProxy(AsyncProxy2FD):
137
+ def in2out(self, res_p):
138
+ # Unpack the struct
139
+ tr = res_p.contents
140
+ ptr, length = tr.buf, tr.len
141
+
142
+ # Read original bytes, transform, and write back
143
+ original = string_at(ptr, length)
144
+ length -= 1
145
+ transformed = original.upper()[:length]
146
+ memmove(ptr, transformed, length)
147
+ tr.len = length
148
+
149
+ print("in2out hook:", original, "→", transformed)
150
+
151
+ def out2in(self, res_p):
152
+ tr = res_p.contents
153
+ ptr, length = tr.buf, tr.len
154
+
155
+ original = string_at(ptr, length)
156
+ length -= 1
157
+ transformed = original[::-1][1:]
158
+ memmove(ptr, transformed, length)
159
+ tr.len = length
160
+
161
+ print("out2in hook:", original, "→", transformed)
162
+
163
+ # 1. Create two socket pairs for bidirectional flow
164
+ client_socket, proxy_in = socket.socketpair()
165
+ proxy_out, server_socket = socket.socketpair()
166
+
167
+ # 2. Initialize and start the custom proxy
168
+ proxy = NosyProxy(proxy_in.fileno(), proxy_out.fileno())
169
+ proxy.start()
170
+
171
+ # 3. Client → Server (uppercase transformation)
172
+ client_msg = b"Hello from Client!"
173
+ client_socket.sendall(client_msg)
174
+ print("Client sent:", client_msg.decode())
175
+
176
+ srv_recv = server_socket.recv(1024)
177
+ print("Server received:", srv_recv.decode())
178
+
179
+ # 4. Server → Client (reverse transformation)
180
+ server_msg = b"Hello from Server!"
181
+ server_socket.sendall(server_msg)
182
+ print("Server sent:", server_msg.decode())
183
+
184
+ cli_recv = client_socket.recv(1024)
185
+ print("Client received:", cli_recv.decode())
186
+
187
+ # 5. Shutdown and cleanup
188
+ proxy.join(shutdown=True)
189
+ for sock in (client_socket, proxy_in, proxy_out, server_socket):
190
+ sock.close()
191
+ ```
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: asyncproxy
3
+ Version: 1.0
4
+ Summary: Background TCP proxy for async IO
5
+ Home-page: https://github.com/sippy/libasyncproxy.git
6
+ Author: Maksym Sobolyev
7
+ Author-email: sobomax@sippysoft.com
8
+ Classifier: License :: OSI Approved :: BSD License
9
+ Classifier: Operating System :: POSIX
10
+ Classifier: Programming Language :: C
11
+ Classifier: Programming Language :: Python
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license-file
21
+ Dynamic: summary
22
+
23
+ # libasyncproxy
24
+
25
+ ## Introduction
26
+
27
+ The libasyncproxy is a fairy simple C library and a respective python wrapper,
28
+ which allows splicing two sockets, pipes and in general file descriptors to
29
+ relay bidirectional data in/out in a background using a worker thread (one per
30
+ connection at the moment).
31
+
32
+ Unlike system-wide facilities that might be offering similar functionality,
33
+ this library provides more control and flexibility. Allowing to connect
34
+ different kinds of underlying objects (i.e. plain file to a socket, device to
35
+ a pipe etc).
36
+
37
+ It also privides mechanism for the python code to supply a handler(s) to
38
+ monitor, record and/or alter the data being transmitted.
39
+
40
+ Last but not least, the C library can be used directly from a low-level code
41
+ for the same effect.
42
+
43
+ ## History
44
+
45
+ The code was created to allow Python code implementing application-layer proxy
46
+ to manage session routing and connection, while handling all transfers outside
47
+ of confinments of the slow Python and its GIL.
48
+
49
+ ## Interfaces
50
+
51
+ AsyncProxy: the lowest-level interface, dealing with raw sockets, wrapper for
52
+ libasyncproxy.
53
+
54
+ ForwarderFast: super-set of AsyncProxy with some utility methods.
55
+
56
+ Forwarder: same API and functionality as ForwarderFast, but without using
57
+ AsyncProxy C module (i.e. python thread doing i/o). Mostly for backward
58
+ compatibility when we need to break library API.
59
+
60
+ TCPProxy: set of high-level classes to accept and manage inbound connections
61
+ and initiate/tear-down outbound as needed, connecting them using forwarders
62
+ once established. Will use ForwarderFast if available, falling back to the
63
+ Forwarder if that fails to load or initialize.
64
+
65
+ ## Use Cases
66
+
67
+ We use this library to allow applications to be redirected to one of several
68
+ available DB replicas and re-routed instantly if the configuration changes.
69
+
70
+ ## Build and Install Python module from source code:
71
+
72
+ ```
73
+ git clone https://github.com/sippy/libasyncproxy.git
74
+ pip install libasyncproxy/
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ### asyncproxy -- `AsyncProxy2FD` Example
80
+
81
+ This example shows how to set up a bidirectional relay between two socket pairs using `AsyncProxy2FD`. Data sent on one end is forwarded to the other, and vice versa.
82
+
83
+ ```python
84
+ import socket
85
+ from asyncproxy.AsyncProxy import AsyncProxy2FD
86
+
87
+ # 1. Create two socket pairs:
88
+ # - (client_socket, proxy_in): client writes to `proxy_in`
89
+ # - (proxy_out, server_socket): proxy writes to `proxy_out`, server reads
90
+ client_socket, proxy_in = socket.socketpair()
91
+ proxy_out, server_socket = socket.socketpair()
92
+
93
+ # 2. Initialize and start the proxy:
94
+ proxy = AsyncProxy2FD(proxy_in.fileno(), proxy_out.fileno())
95
+ proxy.start()
96
+
97
+ # 3. Send from client → server:
98
+ client_msg = b"Hello from Client!"
99
+ client_socket.sendall(client_msg)
100
+ print("Client sent:", client_msg.decode())
101
+
102
+ server_recv = server_socket.recv(1024)
103
+ print("Server received:", server_recv.decode())
104
+
105
+ # 4. Send from server → client:
106
+ server_msg = b"Hello from Server!"
107
+ server_socket.sendall(server_msg)
108
+ print("Server sent:", server_msg.decode())
109
+
110
+ client_recv = client_socket.recv(1024)
111
+ print("Client received:", client_recv.decode())
112
+
113
+ # 5. Shutdown and cleanup:
114
+ proxy.join(shutdown=True)
115
+ for sock in (client_socket, proxy_in, proxy_out, server_socket):
116
+ sock.close()
117
+ ```
118
+
119
+ ### asyncproxy -- `TCPProxy` Example
120
+
121
+ This example shows how to set up a TCP proxy accepting connections on
122
+ `localhost:8080` and forwarding it to `www.google.com:80`.
123
+
124
+ ```python
125
+ import socket
126
+ from time import sleep
127
+ from asyncproxy.TCPProxy import TCPProxy
128
+
129
+ # 1. Initialize and start the proxy:
130
+ # - Listen on local port 8080
131
+ # - Forward all traffic to www.google.com:80
132
+ proxy = TCPProxy(port=8080, newhost='www.google.com', newport=80)
133
+ proxy.start()
134
+ print("TCPProxy running on:", proxy.sock.getsockname())
135
+
136
+ # 2. Connect via the proxy and send HTTP requests twice
137
+ for _ in (1, 2):
138
+ with socket.create_connection(('127.0.0.1', 8080)) as s:
139
+ print("Connected to www.google.com via TCPProxy.")
140
+ s.sendall(b"GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
141
+ resp = s.recv(256)
142
+ print("Response received from proxy:")
143
+ print(resp.decode('utf-8', errors='replace'))
144
+
145
+ # 3. Shutdown the proxy cleanly
146
+ proxy.shutdown()
147
+ ```
148
+
149
+ ### asyncproxy -- Advanced `AsyncProxy2FD` Example
150
+
151
+ This example shows how to subclass `AsyncProxy2FD` to inspect and modify data in transit using custom `in2out` and `out2in` hooks.
152
+
153
+ ```python
154
+ import socket
155
+ from ctypes import string_at, memmove
156
+ from asyncproxy.AsyncProxy import AsyncProxy2FD
157
+
158
+ class NosyProxy(AsyncProxy2FD):
159
+ def in2out(self, res_p):
160
+ # Unpack the struct
161
+ tr = res_p.contents
162
+ ptr, length = tr.buf, tr.len
163
+
164
+ # Read original bytes, transform, and write back
165
+ original = string_at(ptr, length)
166
+ length -= 1
167
+ transformed = original.upper()[:length]
168
+ memmove(ptr, transformed, length)
169
+ tr.len = length
170
+
171
+ print("in2out hook:", original, "→", transformed)
172
+
173
+ def out2in(self, res_p):
174
+ tr = res_p.contents
175
+ ptr, length = tr.buf, tr.len
176
+
177
+ original = string_at(ptr, length)
178
+ length -= 1
179
+ transformed = original[::-1][1:]
180
+ memmove(ptr, transformed, length)
181
+ tr.len = length
182
+
183
+ print("out2in hook:", original, "→", transformed)
184
+
185
+ # 1. Create two socket pairs for bidirectional flow
186
+ client_socket, proxy_in = socket.socketpair()
187
+ proxy_out, server_socket = socket.socketpair()
188
+
189
+ # 2. Initialize and start the custom proxy
190
+ proxy = NosyProxy(proxy_in.fileno(), proxy_out.fileno())
191
+ proxy.start()
192
+
193
+ # 3. Client → Server (uppercase transformation)
194
+ client_msg = b"Hello from Client!"
195
+ client_socket.sendall(client_msg)
196
+ print("Client sent:", client_msg.decode())
197
+
198
+ srv_recv = server_socket.recv(1024)
199
+ print("Server received:", srv_recv.decode())
200
+
201
+ # 4. Server → Client (reverse transformation)
202
+ server_msg = b"Hello from Server!"
203
+ server_socket.sendall(server_msg)
204
+ print("Server sent:", server_msg.decode())
205
+
206
+ cli_recv = client_socket.recv(1024)
207
+ print("Client received:", cli_recv.decode())
208
+
209
+ # 5. Shutdown and cleanup
210
+ proxy.join(shutdown=True)
211
+ for sock in (client_socket, proxy_in, proxy_out, server_socket):
212
+ sock.close()
213
+ ```
@@ -0,0 +1,19 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ setup.py
5
+ asyncproxy.egg-info/PKG-INFO
6
+ asyncproxy.egg-info/SOURCES.txt
7
+ asyncproxy.egg-info/dependency_links.txt
8
+ asyncproxy.egg-info/top_level.txt
9
+ python/AsyncProxy.py
10
+ python/Forwarder.py
11
+ python/ForwarderFast.py
12
+ python/TCPProxy.py
13
+ python/env.py
14
+ src/Symbol.map
15
+ src/asp_iostats.h
16
+ src/asp_sock.c
17
+ src/asp_sock.h
18
+ src/asyncproxy.c
19
+ src/asyncproxy.h
@@ -0,0 +1,2 @@
1
+ _libasyncproxy
2
+ asyncproxy