This code shows an implementation of tunneling. Though this code uses ssl as an example. It would not be hard to modify it to work for other situations as well.
The reason I use ssl as an example is because the standard python libraries do not support tunneling ssl through a proxy. Import pytunnel and give it a function w/the code you want to tunnel and your off.
For the latest code try: http://ftp.gnu.org/pub/savannah/cvs/pytunnel-cvs-latest.tar.gz
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | import threading,socket,traceback,sys,httplib,pprint,select,base64,time
 
def recv_all(the_socket,timeout=''):
    #setup to use non-blocking sockets
    #assume proxy network connection is worse than locahost
    #if no data arrives it assumes transaction is done
    #recv() returns a string; it's an upper bound on len(sock.recv())
    the_socket.setblocking(0)
    total_data=[];data=''
    begin=time.time()
    if not timeout:
        timeout=1
    while 1:
        #if you got some data, then break after wait sec
        if total_data and time.time()-begin>timeout:
            break
        #if you got no data at all, wait a little longer
        elif time.time()-begin>timeout*2:
            break
        wait=0
        try:
            data=the_socket.recv(4096)
            if data:
                total_data.append(data)
                begin=time.time()
                data='';wait=0
            else:
                time.sleep(0.1)
        except:
            pass
        #When a recv returns 0 bytes, other side has closed
    result=''.join(total_data)
    return result
 
class thread_it ( threading.Thread ) :
    done=0
    def __init__(self,tid='',proxy='',server='',tunnel_client='',\
                 port=0,ip='',timeout=0,slow=0):
        threading.Thread.__init__(self)
        self.tid=tid
        self.proxy=proxy
        self.port=port
        self.server=server
        self.tunnel_client=tunnel_client
        self.ip=ip;self._port=port
        self.data={} #store data here to get later
        self.timeout=timeout
    def run ( self ): #overridden from threading library
        try:
            if self.proxy and self.server:
                ins=[self.server,self.proxy]
                ous=[];data={};adrs={}
                new_socket=0
                while not thread_it.done:
                    if not new_socket:
                        new_socket,address=self.server.accept()
                    else:
                        self.proxy.sendall(
                                  recv_all(new_socket,timeout=self.timeout))
                        new_socket.sendall(
                                  recv_all(self.proxy,timeout=self.timeout))
            elif self.tunnel_client:
                self.tunnel_client(self.ip,self.port)
                thread_it.done=1
        except Exception,error:
            print traceback.print_exc(sys.exc_info()),error
            thread_it.done=1
class build:
    def __init__(self,host='',port=443,proxy_host='',proxy_port=80,
                 proxy_user='',proxy_pass='',proxy_type='',timeout=0):
        #initialize variables
                                                                                
        self._port=port;self.host=host;self._phost=proxy_host;self._puser=proxy_user
        self._pport=proxy_port;self._ppass=proxy_pass;self._ptype=proxy_type
        self.ip='127.0.0.1';self.timeout=timeout
        #setup variables
        self._server,self.server_port=self.get_server()
    def get_proxy(self):
        if not self._ptype:
            proxy=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            proxy.connect((self._phost,self._pport))
            proxy_authorization=''
            if self._puser:
                proxy_authorization='Proxy-authorization: Basic '+\
                base64.encodestring(self._puser+':'+self._ppass).strip()+'\r\n'
            proxy_connect='CONNECT %s:%sHTTP/1.0\r\n'%(self.host,self._port)
            user_agent='User-Agent: pytunnel\r\n'
            proxy_pieces=proxy_connect+proxy_authorization+user_agent+'\r\n'
            proxy.sendall(proxy_pieces+'\r\n')
            response=recv_all(proxy,timeout=0.5)
            status=response.split()[1]
            if int(status)/100 !=2:
                print 'error',response
                raise status
            return proxy
    def get_server(self):
        port=2222
        server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #localhost = only visible to this machine
        server.bind(('localhost',port))
        server.listen(5)
        return server,port
    def run(self,func):
        Threads=[]
        Threads.append( thread_it(tid=0,proxy=self.get_proxy(),\
                                  server=self._server,timeout=self.timeout))
        Threads.append( thread_it(tid=1,tunnel_client=func,ip=self.ip,\
                                  port=self.server_port,timeout=0.5))
 
        for Thread in Threads: #now go thru list and start threads running
            Thread.start() #call the run function
                print 'error',response
                raise status
            return proxy
    def get_server(self):
        port=2222
        server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #localhost = only visible to this machine
        server.bind(('localhost',port))
        server.listen(5)
        return server,port
    def run(self,func):
        Threads=[]
        Threads.append( thread_it(tid=0,proxy=self.get_proxy(),\
                                  server=self._server,timeout=self.timeout))
        Threads.append( thread_it(tid=1,tunnel_client=func,ip=self.ip,\
                                  port=self.server_port,timeout=0.5))
 
        for Thread in Threads: #now go thru list and start threads running
            Thread.start() #call the run function
        for Thread in Threads: #make main thread wait for all in list to 
            Thread.join()
 | 
import pytunnel,httplib
def tunnel_this(ip,port): conn = httplib.HTTPSConnection(ip,port=port) conn.putrequest('GET', '/') conn.endheaders() response = conn.getresponse() print response.read()
tunnel=pytunnel.build(host='login.yahoo.com',proxy_host='h1', proxy_user='u',proxy_pass='p') tunnel.run(tunnel_this)
Note: Python versions 2.4 and earlier do support non-blocking sockets for ssl I/O. For this example, you may have issues if the proxy server uses non-blocking sockets.

 Download
Download Copy to clipboard
Copy to clipboard
At the moment it looks outdated:
link given does not work
example code is broken at line 112
Could someone fix it?