Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#!/usr/bin/env python3
import http.client
import socket
from struct import pack, unpack
class HTTPSocks5(http.client.HTTPConnection):
def setsocksproxy(self, host, port):
self.socks5host = host
self.socks5port = port
def connect(self):
if hasattr(self, "socks5host") and self.socks5host:
self.sock = self._create_connection(
(self.socks5host,self.socks5port), self.timeout, self.source_address)
error = ["succeeded", "general SOCKS server failure",\
"connection not allowed by ruleset", "Network unreachable",\
"Host unreachable", "Connection refused", "TTL expired",\
"Command not supported", "Address type not supported", "unassigned"]
data = pack('!3B',5,1,0) # lets connect to socks5 server
self.sock.send(data)
data = self.sock.recv(2)
auth = unpack('2B',data)[1] # do we need to authenticate
if auth != 255:
nport = pack('!H',self.port)
try:
if ":" in self.host: # we most likely have IPv6 here
data = pack('!4B',5,1,0,4)+\
socket.inet_pton(socket.AF_INET6,self.host)+nport
else: # IPv4
data = pack('!4B',5,1,0,1)+\
socket.inet_pton(socket.AF_INET,self.host)+nport
except socket.error: # or just a hostname to resolve by the SOCKS srv
data = pack('!5B',5,1,0,3,len(self.host))+\
bytearray(self.host,'UTF-8')+nport
self.sock.send(data)
data = self.sock.recv(256) # getting the status code
try:
code = unpack('BBB',data[:3])[1]
except:
raise("socks server sent a wrong replay")
if code != 0:
if code > 9:
code = 9
raise("socks server sent an error: %s" % (error[code],))
else:
raise("socks server requires authentication")
else:
self.sock = self._create_connection(
(self.host,self.port), self.timeout, self.source_address)
if __name__ == "__main__":
# example usage
c = HTTPSocks5("www.google.com", 80)
c.setsocksproxy("127.0.0.1", 1081)
c.request("GET", "/")
r = c.getresponse()
print("%s" % (r.read().decode('utf-8'),))
c.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment