{"id":15472253,"url":"https://github.com/sethmlarson/socksio","last_synced_at":"2025-04-07T07:09:22.903Z","repository":{"id":35092806,"uuid":"205901200","full_name":"sethmlarson/socksio","owner":"sethmlarson","description":"Sans-I/O implementation of SOCKS4, SOCKS4A, and SOCKS5","archived":false,"fork":false,"pushed_at":"2024-03-01T03:06:33.000Z","size":65,"stargazers_count":53,"open_issues_count":6,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-31T06:05:29.060Z","etag":null,"topics":["python","sans-io","socks","socks-proxy","socks4","socks4a","socks5"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/socksio","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sethmlarson.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2019-09-02T17:01:33.000Z","updated_at":"2024-11-21T01:59:20.000Z","dependencies_parsed_at":"2024-03-01T04:24:34.061Z","dependency_job_id":"68eafa08-105e-419e-a257-59412f82bf05","html_url":"https://github.com/sethmlarson/socksio","commit_stats":{"total_commits":38,"total_committers":6,"mean_commits":6.333333333333333,"dds":0.3157894736842105,"last_synced_commit":"bad06ab5d8581797196ecf2eae1d8776c997567e"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethmlarson%2Fsocksio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethmlarson%2Fsocksio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethmlarson%2Fsocksio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethmlarson%2Fsocksio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sethmlarson","download_url":"https://codeload.github.com/sethmlarson/socksio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247608151,"owners_count":20965952,"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","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":["python","sans-io","socks","socks-proxy","socks4","socks4a","socks5"],"created_at":"2024-10-02T02:29:54.392Z","updated_at":"2025-04-07T07:09:22.885Z","avatar_url":"https://github.com/sethmlarson.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SOCKSIO\n\n[![Build Status](https://travis-ci.org/sethmlarson/socksio.svg?branch=master)](https://travis-ci.org/sethmlarson/socksio)\n[![codecov](https://codecov.io/gh/sethmlarson/socksio/branch/master/graph/badge.svg)](https://codecov.io/gh/sethmlarson/socksio)\n[![Supported Python Versions](https://img.shields.io/pypi/pyversions/socksio.svg)](https://pypi.org/project/socksio)\n[![PyPI](https://img.shields.io/pypi/v/socksio.svg)](https://pypi.org/project/socksio)\n\nClient-side sans-I/O SOCKS proxy implementation.\nSupports SOCKS4, SOCKS4A, and SOCKS5.\n\n`socksio` is a sans-I/O library similar to\n[`h11`](https://github.com/python-hyper/h11) or\n[`h2`](https://github.com/python-hyper/hyper-h2/), this means the library itself\ndoes not handle the actual sending of the bytes through the network, it only\ndeals with the implementation details of the SOCKS protocols so you can use\nit in any I/O library you want.\n\n## Current status: stable\n\nFeatures not yet implemented:\n\n- SOCKS5 GSS-API authentication.\n- SOCKS5 UDP associate requests.\n\n## Usage\n\nTL;DR check the [examples directory](https://github.com/sethmlarson/socksio/tree/master/examples).\n\nBeing sans-I/O means that in order to test `socksio` you need an I/O library.\nAnd the most basic I/O is, of course, the standard library's `socket` module.\n\nYou'll need to know ahead of time the type of SOCKS proxy you want to connect\nto. Assuming we have a SOCKS4 proxy running in our machine on port 8080, we\nwill first create a connection to it:\n\n```python\nimport socket\n\nsock = socket.create_connection((\"localhost\", 8080))\n```\n\n`socksio` exposes modules for SOCKS4, SOCKS4A and SOCKS5, each of them includes\na `Connection` class:\n\n```python\nfrom socksio import socks4\n\n# The SOCKS4 protocol requires a `user_id` to be supplied.\nconn = socks4.SOCKS4Connection(user_id=b\"socksio\")\n```\n\nSince `socksio` is a sans-I/O library, we will use the socket to send and\nreceive data to our SOCKS4 proxy. The raw data, however, will be created and\nparsed by our `SOCKS4Connection`.\n\nWe need to tell our connection we want to make a request to the proxy. We do\nthat by first creating a request object.\n\nIn SOCKS4 we only need to send a command along with an IP address and port.\n`socksio` exposes the different types of commands as enumerables and a\nconvenience `from_address` class method in the request classes to create a\nvalid request object:\n\n```python\n# SOCKS4 does not allow domain names, below is an IP for google.com\nrequest = socks4.SOCKS4Request.from_address(\n    socks4.SOCKS4Command.CONNECT, (\"216.58.204.78\", 80))\n```\n\n`from_address` methods are available on all request classes in `socksio`, they\naccept addresses as tuples of `(address, port)` as well as string `address:port`.\n\nNow we ask the connection to send our request:\n\n```python\nconn.send(request)\n```\n\nThe `SOCKS4Connection` will then compose the necessary `bytes` in the proper\nformat for us to send to our proxy:\n\n```python\ndata = conn.data_to_send()\nsock.sendall(data)\n```\n\nIf all goes well the proxy will have sent reply, we just need to read from the\nsocket and pass the data to the `SOCKS4Connection`:\n\n```python\ndata = sock.recv(1024)\nevent = conn.receive_data(data)\n```\n\nThe connection will parse the data and return an event from it, in this case, a\n`SOCKS4Reply` that includes attributes for the fields in the SOCKS reply:\n\n```python\nif event.reply_code != socks4.SOCKS4ReplyCode.REQUEST_GRANTED:\n    raise Exception(\n        \"Server could not connect to remote host: {}\".format(event.reply_code)\n    )\n```\n\nIf all went well the connection has been established correctly and we can\nstart sending our request directly to the proxy:\n\n```python\nsock.sendall(b\"GET / HTTP/1.1\\r\\nhost: google.com\\r\\n\\r\\n\")\ndata = receive_data(sock)\nprint(data)\n# b'HTTP/1.1 301 Moved Permanently\\r\\nLocation: http://www.google.com/...`\n```\n\nThe same methodology is used for all protocols, check out the\n[examples directory](https://github.com/sethmlarson/socksio/tree/master/examples/)\nfor more information.\n\n## Development\n\nInstall the test requirements with `pip install -r test-requirements.txt`.\n\nInstall the project in pseudo-editable mode with `flit install -s`.\n\nTests can be ran directly invoking `pytest`.\n\nThis project uses [`nox`](https://nox.thea.codes/en/stable/) to automate\ntesting and linting tasks. `nox` is installed as part of the test requirements.\nInvoking `nox` will run all sessions, but you may also run only some them, for\nexample `nox -s lint` will only run the linting session.\n\nIn order to test against a live proxy server a Docker setup is provided based\non the [`Dante`](https://www.inet.no/dante/) SOCKS server.\n\nA container will start `danted` listening on port 1080. The docker-compose.yml\nwill start the container and map the ports appropriately. To start the container\nin the background:\n\n```\ndocker-compose -f docker/docker-compose.yml up -d\n```\n\nTo stop it:\n\n```\ndocker-compose -f docker/docker-compose.yml down\n```\n\nAlternatively, remove the `-d` flag to run the containers in the foreground.\n\n## Reference documents\n\nEach implementation follows the documents as listed below:\n\n- SOCKS4: https://www.openssh.com/txt/socks4.protocol\n- SOCKS4A: https://www.openssh.com/txt/socks4a.protocol\n- SOCKS5: https://www.ietf.org/rfc/rfc1928.txt\n- SOCKS5 username/password authentication: https://www.ietf.org/rfc/rfc1929.txt\n- SOCKS5 GSS-API authentication: https://www.ietf.org/rfc/rfc1961.txt\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethmlarson%2Fsocksio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsethmlarson%2Fsocksio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethmlarson%2Fsocksio/lists"}