#!/usr/bin/python # export $targetport on $targethost upon $listenport, to the world import select, socket, SocketServer, string, sys, thread, time listenport= targethost= targetport= def annout(s): sys.stdout.write(s) sys.stdout.flush() def dout(s): #annout(s) pass def fromclient_callback(text, target_socket): #print text target_socket.send(text) # pass it along def fromserver_callback(text, client_socket): #print text client_socket.send(text) # pass it along def myhandle(request): request.setblocking(0) dout(' socket (') target_socket= socket.socket(socket.AF_INET, socket.SOCK_STREAM) dout(')') dout(' connect (') target_socket.connect((targethost, targetport)) dout(')') target_socket.setblocking(0) select_list= [request, target_socket] didone= 0 stallcount= 0 while 1: # Keep looping until one of the connections gets closed from other end if didone== 0: dout('.') time.sleep(1) stallcount+= 1 # needed to deal with persistent HTTP connection else: stallcount= 0 dout('[') [ready_to_read, ready_to_write, in_error]= select.select(select_list, [], [], 1000) dout('1') didone= 0 if request in ready_to_read: try: fromclient= request.recv(999999) dout('4') if len(fromclient)> 0: fromclient_callback(fromclient, target_socket) didone= 1 dout('5') except socket.error, msg: dout('\n'+ str(msg)+ '\n') in_error.append(request) # so we'll process as error below if target_socket in ready_to_read: try: fromserver= target_socket.recv(1024) dout('7(%i)'% len(fromserver)) if len(fromserver)> 0: fromserver_callback(fromserver, request) didone= 1 dout('8') except socket.error, msg: dout('\n'+ str(msg)+ '\n') in_error.append(target_socket) # so we'll process as error below if len(in_error)> 0 or stallcount> 10: dout(" Closing...") request.close() target_socket.close() return dout(']') class Handler(SocketServer.BaseRequestHandler): def handle(self): # Override of SocketServer.BaseRequestHandler.handle() (chost, cport)= self.client_address annout("\nHandle... from %s " % (chost)) accepting= 1 # HERE is where to put some filtering of service based on remote host if accepting==0: annout("...REJECTING\n") self.request.close() return myhandle(self.request) annout(" ...Handle from %s\n"% (chost)) # must be public name. '127.0.0.1' will only show up on loopback. # could use '' according to http://python.org/doc/current/lib/module-BaseHTTPServer.html server= SocketServer.ThreadingTCPServer(('',listenport), Handler) server.allow_reuse_address= 1 # dammit, won't take server.serve_forever()