codekingpro/portable-devtools
115k
1#!/usr/bin/env python2"""3SocksiPy + urllib2 handler4 5version: 0.36author: e<e@tr0ll.in>7 8This module provides a Handler which you can use with urllib2 to allow it to tunnel your connection through a socks.sockssocket socket, with out monkey patching the original socket...9"""10import socket11import ssl12 13try:14 import urllib215 import httplib16except ImportError: # Python 317 import urllib.request as urllib218 import http.client as httplib19 20import socks # $ pip install PySocks21 22def merge_dict(a, b):23 d = a.copy()24 d.update(b)25 return d26 27def is_ip(s):28 try:29 if ':' in s:30 socket.inet_pton(socket.AF_INET6, s)31 elif '.' in s:32 socket.inet_aton(s)33 else:34 return False35 except:36 return False37 else:38 return True39 40socks4_no_rdns = set()41 42class SocksiPyConnection(httplib.HTTPConnection):43 def __init__(self, proxytype, proxyaddr, proxyport=None, rdns=True, username=None, password=None, *args, **kwargs):44 self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)45 httplib.HTTPConnection.__init__(self, *args, **kwargs)46 47 def connect(self):48 (proxytype, proxyaddr, proxyport, rdns, username, password) = self.proxyargs49 rdns = rdns and proxyaddr not in socks4_no_rdns50 while True:51 try:52 sock = socks.create_connection(53 (self.host, self.port), self.timeout, None,54 proxytype, proxyaddr, proxyport, rdns, username, password,55 ((socket.IPPROTO_TCP, socket.TCP_NODELAY, 1),))56 break57 except socks.SOCKS4Error as e:58 if rdns and "0x5b" in str(e) and not is_ip(self.host):59 # Maybe a SOCKS4 server that doesn't support remote resolving60 # Let's try again61 rdns = False62 socks4_no_rdns.add(proxyaddr)63 else:64 raise65 self.sock = sock66 67class SocksiPyConnectionS(httplib.HTTPSConnection):68 def __init__(self, proxytype, proxyaddr, proxyport=None, rdns=True, username=None, password=None, *args, **kwargs):69 self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)70 httplib.HTTPSConnection.__init__(self, *args, **kwargs)71 72 def connect(self):73 SocksiPyConnection.connect(self)74 self.sock = self._context.wrap_socket(self.sock, server_hostname=self.host)75 if not self._context.check_hostname and self._check_hostname:76 try:77 ssl.match_hostname(self.sock.getpeercert(), self.host)78 except Exception:79 self.sock.shutdown(socket.SHUT_RDWR)80 self.sock.close()81 raise82 83class SocksiPyHandler(urllib2.HTTPHandler, urllib2.HTTPSHandler):84 def __init__(self, *args, **kwargs):85 self.args = args86 self.kw = kwargs87 urllib2.HTTPHandler.__init__(self)88 89 def http_open(self, req):90 def build(host, port=None, timeout=0, **kwargs):91 kw = merge_dict(self.kw, kwargs)92 conn = SocksiPyConnection(*self.args, host=host, port=port, timeout=timeout, **kw)93 return conn94 return self.do_open(build, req)95 96 def https_open(self, req):97 def build(host, port=None, timeout=0, **kwargs):98 kw = merge_dict(self.kw, kwargs)99 conn = SocksiPyConnectionS(*self.args, host=host, port=port, timeout=timeout, **kw)100 return conn101 return self.do_open(build, req)102 103if __name__ == "__main__":104 import sys105 try:106 port = int(sys.argv[1])107 except (ValueError, IndexError):108 port = 9050109 opener = urllib2.build_opener(SocksiPyHandler(socks.PROXY_TYPE_SOCKS5, "localhost", port))110 print("HTTP: " + opener.open("http://httpbin.org/ip").read().decode())111 print("HTTPS: " + opener.open("https://httpbin.org/ip").read().decode())112 