-
-
Notifications
You must be signed in to change notification settings - Fork 589
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Core acceptor pool doc, cleanup and standalone example (#393)
* Better document acceptor module and add a TCP Echo Server example * autopep8 formating * Rename ThreadlessWork --> Work class * Make initialize, is_inactive and shutdown as optional interface methods. Also introduce Readables & Writables custom types. * Move websocket code into its own module * Add websocket client example * Cleanup websocket client
- Loading branch information
1 parent
9be6c29
commit c884338
Showing
27 changed files
with
467 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Proxy.py Library Examples | ||
|
||
This directory contains examples that demonstrate `proxy.py` core library capabilities. | ||
|
||
Looking for `proxy.py` plugin examples? Check [proxy/plugin](https://github.com/abhinavsingh/proxy.py/tree/develop/proxy/plugin) directory. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
proxy.py | ||
~~~~~~~~ | ||
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on | ||
Network monitoring, controls & Application development, testing, debugging. | ||
:copyright: (c) 2013-present by Abhinav Singh and contributors. | ||
:license: BSD, see LICENSE for more details. | ||
""" | ||
import time | ||
import socket | ||
import selectors | ||
|
||
from typing import Dict | ||
|
||
from proxy.core.acceptor import AcceptorPool, Work | ||
from proxy.common.flags import Flags | ||
from proxy.common.types import Readables, Writables | ||
|
||
|
||
class EchoServerHandler(Work): | ||
"""EchoServerHandler implements Work interface. | ||
An instance of EchoServerHandler is created for each client | ||
connection. EchoServerHandler lifecycle is controlled by | ||
Threadless core using asyncio. Implementation must provide | ||
get_events and handle_events method. Optionally, also implement | ||
intialize, is_inactive and shutdown method. | ||
""" | ||
|
||
def get_events(self) -> Dict[socket.socket, int]: | ||
# We always want to read from client | ||
# Register for EVENT_READ events | ||
events = {self.client.connection: selectors.EVENT_READ} | ||
# If there is pending buffer for client | ||
# also register for EVENT_WRITE events | ||
if self.client.has_buffer(): | ||
events[self.client.connection] |= selectors.EVENT_WRITE | ||
return events | ||
|
||
def handle_events( | ||
self, | ||
readables: Readables, | ||
writables: Writables) -> bool: | ||
"""Return True to shutdown work.""" | ||
if self.client.connection in readables: | ||
data = self.client.recv() | ||
if data is None: | ||
# Client closed connection, signal shutdown | ||
return True | ||
# Queue data back to client | ||
self.client.queue(data) | ||
|
||
if self.client.connection in writables: | ||
self.client.flush() | ||
|
||
return False | ||
|
||
|
||
def main() -> None: | ||
# This example requires `threadless=True` | ||
pool = AcceptorPool( | ||
flags=Flags(num_workers=1, threadless=True), | ||
work_klass=EchoServerHandler) | ||
try: | ||
pool.setup() | ||
while True: | ||
time.sleep(1) | ||
finally: | ||
pool.shutdown() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
proxy.py | ||
~~~~~~~~ | ||
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on | ||
Network monitoring, controls & Application development, testing, debugging. | ||
:copyright: (c) 2013-present by Abhinav Singh and contributors. | ||
:license: BSD, see LICENSE for more details. | ||
""" | ||
import time | ||
from proxy.http.websocket import WebsocketClient, WebsocketFrame, websocketOpcodes | ||
|
||
|
||
# globals | ||
client: WebsocketClient | ||
last_dispatch_time: float | ||
static_frame = memoryview(WebsocketFrame.text(b'hello')) | ||
num_echos = 10 | ||
|
||
|
||
def on_message(frame: WebsocketFrame) -> None: | ||
"""WebsocketClient on_message callback.""" | ||
global client, num_echos, last_dispatch_time | ||
print('Received %r after %d millisec' % (frame.data, (time.time() - last_dispatch_time) * 1000)) | ||
assert(frame.data == b'hello' and frame.opcode == websocketOpcodes.TEXT_FRAME) | ||
if num_echos > 0: | ||
client.queue(static_frame) | ||
last_dispatch_time = time.time() | ||
num_echos -= 1 | ||
else: | ||
client.close() | ||
|
||
|
||
if __name__ == '__main__': | ||
# Constructor establishes socket connection | ||
client = WebsocketClient(b'echo.websocket.org', 80, b'/', on_message=on_message) | ||
# Perform handshake | ||
client.handshake() | ||
# Queue some data for client | ||
client.queue(static_frame) | ||
last_dispatch_time = time.time() | ||
# Start event loop | ||
client.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.