{"id":34099762,"url":"https://github.com/sippy/libasyncproxy","last_synced_at":"2025-12-30T06:44:33.070Z","repository":{"id":288699345,"uuid":"968931708","full_name":"sippy/libasyncproxy","owner":"sippy","description":"The C library and a respective python module, which allows splicing two sockets, pipes and in general file descriptors to relay bidirectional data in/out in background","archived":false,"fork":false,"pushed_at":"2025-10-24T22:22:41.000Z","size":72,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-24T23:22:04.650Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sippy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-19T02:37:03.000Z","updated_at":"2025-10-24T22:22:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"3fcb3177-e5a2-41ca-ae2f-d57867315b29","html_url":"https://github.com/sippy/libasyncproxy","commit_stats":null,"previous_names":["sippy/libasyncproxy"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/sippy/libasyncproxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sippy%2Flibasyncproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sippy%2Flibasyncproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sippy%2Flibasyncproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sippy%2Flibasyncproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sippy","download_url":"https://codeload.github.com/sippy/libasyncproxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sippy%2Flibasyncproxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27730945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-14T02:00:11.348Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-14T16:02:41.371Z","updated_at":"2025-12-14T16:02:42.352Z","avatar_url":"https://github.com/sippy.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build, Test \u0026 Publush](https://github.com/sippy/libasyncproxy/actions/workflows/build_and_test.yml/badge.svg)](https://github.com/sippy/libasyncproxy/actions/workflows/build_and_test.yml)\n\n# libasyncproxy\n\n## Introduction\n\nThe libasyncproxy is a fairy simple C library and a respective python wrapper,\nwhich allows splicing two sockets, pipes and in general file descriptors to\nrelay bidirectional data in/out in a background using a worker thread (one per\nconnection at the moment).\n\nUnlike system-wide facilities that might be offering similar functionality,\nthis library provides more control and flexibility. Allowing to connect\ndifferent kinds of underlying objects (i.e. plain file to a socket, device to\na pipe etc).\n\nIt also privides mechanism for the python code to supply a handler(s) to\nmonitor, record and/or alter the data being transmitted.\n\nLast but not least, the C library can be used directly from a low-level code\nfor the same effect.\n\n## History\n\nThe code was created to allow Python code implementing application-layer proxy\nto manage session routing and connection, while handling all transfers outside\nof confinments of the slow Python and its GIL.\n\n## Interfaces\n\nAsyncProxy: the lowest-level interface, dealing with raw sockets, wrapper for\nlibasyncproxy.\n\nForwarderFast: super-set of AsyncProxy with some utility methods.\n\nForwarder: same API and functionality as ForwarderFast, but without using\nAsyncProxy C module (i.e. python thread doing i/o). Mostly for backward\ncompatibility when we need to break library API.\n\nTCPProxy: set of high-level classes to accept and manage inbound connections\nand initiate/tear-down outbound as needed, connecting them using forwarders\nonce established. Will use ForwarderFast if available, falling back to the\nForwarder if that fails to load or initialize.\n\n## Use Cases\n\nWe use this library to allow applications to be redirected to one of several\navailable DB replicas and re-routed instantly if the configuration changes.\n\n## Install Python module from PyPy:\n\n```\npip install asyncproxy\n```\n\n## Build and Install Python module from source code:\n\n```\ngit clone https://github.com/sippy/libasyncproxy.git\npip install libasyncproxy/\n```\n\n## Usage\n\n### asyncproxy -- `AsyncProxy2FD` Example\n\nThis 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.\n\n```python\nimport socket\nfrom asyncproxy.AsyncProxy import AsyncProxy2FD\n\n# 1. Create two socket pairs:\n#    - (client_socket, proxy_in): client writes to `proxy_in`\n#    - (proxy_out, server_socket): proxy writes to `proxy_out`, server reads\nclient_socket, proxy_in     = socket.socketpair()\nproxy_out,    server_socket = socket.socketpair()\n\n# 2. Initialize and start the proxy:\nproxy = AsyncProxy2FD(proxy_in.fileno(), proxy_out.fileno())\nproxy.start()\n\n# 3. Send from client → server:\nclient_msg = b\"Hello from Client!\"\nclient_socket.sendall(client_msg)\nprint(\"Client sent:\", client_msg.decode())\n\nserver_recv = server_socket.recv(1024)\nprint(\"Server received:\", server_recv.decode())\n\n# 4. Send from server → client:\nserver_msg = b\"Hello from Server!\"\nserver_socket.sendall(server_msg)\nprint(\"Server sent:\", server_msg.decode())\n\nclient_recv = client_socket.recv(1024)\nprint(\"Client received:\", client_recv.decode())\n\n# 5. Shutdown and cleanup:\nproxy.join(shutdown=True)\nfor sock in (client_socket, proxy_in, proxy_out, server_socket):\n    sock.close()\n```\n\n### asyncproxy -- `TCPProxy` Example\n\nThis example shows how to set up a TCP proxy accepting connections on\n`localhost:8080` and forwarding it to `www.google.com:80`.\n\n```python\nimport socket\nfrom time import sleep\nfrom asyncproxy.TCPProxy import TCPProxy\n\n# 1. Initialize and start the proxy:\n#    - Listen on local port 8080\n#    - Forward all traffic to www.google.com:80\nproxy = TCPProxy(port=8080, newhost='www.google.com', newport=80)\nproxy.start()\nprint(\"TCPProxy running on:\", proxy.sock.getsockname())\n\n# 2. Connect via the proxy and send HTTP requests twice\nfor _ in (1, 2):\n    with socket.create_connection(('127.0.0.1', 8080)) as s:\n        print(\"Connected to www.google.com via TCPProxy.\")\n        s.sendall(b\"GET / HTTP/1.0\\r\\nHost: www.google.com\\r\\n\\r\\n\")\n        resp = s.recv(256)\n        print(\"Response received from proxy:\")\n        print(resp.decode('utf-8', errors='replace'))\n\n# 3. Shutdown the proxy cleanly\nproxy.shutdown()\n```\n\n### asyncproxy -- Advanced `AsyncProxy2FD` Example\n\nThis example shows how to subclass `AsyncProxy2FD` to inspect and modify data in transit using custom `in2out` and `out2in` hooks.\n\n```python\nimport socket\nfrom ctypes import string_at, memmove\nfrom asyncproxy.AsyncProxy import AsyncProxy2FD\n\nclass NosyProxy(AsyncProxy2FD):\n    def in2out(self, res_p):\n        # Unpack the struct\n        tr = res_p.contents\n        ptr, length = tr.buf, tr.len\n\n        # Read original bytes, transform, and write back\n        original    = string_at(ptr, length)\n        length     -= 1\n        transformed = original.upper()[:length]\n        memmove(ptr, transformed, length)\n        tr.len = length\n\n        print(\"in2out hook:\", original, \"→\", transformed)\n\n    def out2in(self, res_p):\n        tr = res_p.contents\n        ptr, length = tr.buf, tr.len\n\n        original    = string_at(ptr, length)\n        length     -= 1\n        transformed = original[::-1][1:]\n        memmove(ptr, transformed, length)\n        tr.len = length\n\n        print(\"out2in hook:\", original, \"→\", transformed)\n\n# 1. Create two socket pairs for bidirectional flow\nclient_socket, proxy_in       = socket.socketpair()\nproxy_out,    server_socket   = socket.socketpair()\n\n# 2. Initialize and start the custom proxy\nproxy = NosyProxy(proxy_in.fileno(), proxy_out.fileno())\nproxy.start()\n\n# 3. Client → Server (uppercase transformation)\nclient_msg = b\"Hello from Client!\"\nclient_socket.sendall(client_msg)\nprint(\"Client sent:\", client_msg.decode())\n\nsrv_recv = server_socket.recv(1024)\nprint(\"Server received:\", srv_recv.decode())\n\n# 4. Server → Client (reverse transformation)\nserver_msg = b\"Hello from Server!\"\nserver_socket.sendall(server_msg)\nprint(\"Server sent:\", server_msg.decode())\n\ncli_recv = client_socket.recv(1024)\nprint(\"Client received:\", cli_recv.decode())\n\n# 5. Shutdown and cleanup\nproxy.join(shutdown=True)\nfor sock in (client_socket, proxy_in, proxy_out, server_socket):\n    sock.close()\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsippy%2Flibasyncproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsippy%2Flibasyncproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsippy%2Flibasyncproxy/lists"}