Usage¶
TL;DR check the examples directory.
Being sans-I/O means that in order to test socksio you need an I/O
library. And the most basic I/O is, of course, the standard library’s
socket module.
You’ll need to know ahead of time the type of SOCKS proxy you want to connect to. Assuming we have a SOCKS4 proxy running in our machine on port 8080, we will first create a connection to it:
import socket
sock = socket.create_connection(("localhost", 8080))
socksio exposes modules for SOCKS4, SOCKS4A and SOCKS5, each of them
includes a Connection class:
from socksio import socks4
# The SOCKS4 protocol requires a `user_id` to be supplied.
conn = socks4.SOCKS4Connection(user_id=b"socksio")
Since socksio is a sans-I/O library, we will use the socket to send
and receive data to our SOCKS4 proxy. The raw data, however, will be
created and parsed by our SOCKS4Connection.
We need to tell our connection we want to make a request to the proxy. We do that by first creating a request object.
In SOCKS4 we only need to send a command along with an IP address and
port. socksio exposes the different types of commands as enumerables
and a convenience from_address()
class method in the request classes to create a valid request object:
# SOCKS4 does not allow domain names, below is an IP for google.com
request = socks4.SOCKS4Request.from_address(
socks4.SOCKS4Command.CONNECT, ("216.58.204.78", 80))
from_address methods are available on all request classes in
socksio, they accept addresses as tuples of (address, port) as
well as string address:port.
Now we ask the connection to send our request:
conn.send(request)
The SOCKS4Connection will then compose the
necessary bytes in the proper format for us to send to our proxy:
data = conn.data_to_send()
sock.sendall(data)
If all goes well the proxy will have sent reply, we just need to read
from the socket and pass the data to the
SOCKS4Connection:
data = sock.recv(1024)
event = conn.receive_data(data)
The connection will parse the data and return an event from it, in this
case, a SOCKS4Reply that includes attributes for
the fields in the SOCKS reply:
if event.reply_code != socks4.SOCKS4ReplyCode.REQUEST_GRANTED:
raise Exception(
"Server could not connect to remote host: {}".format(event.reply_code)
)
If all went well the connection has been established correctly and we can start sending our request directly to the proxy:
sock.sendall(b"GET / HTTP/1.1\r\nhost: google.com\r\n\r\n")
data = receive_data(sock)
print(data)
# b'HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/...`
The same methodology is used for all protocols, check out the examples directory for more information.