diff options
Diffstat (limited to 'libmproxy/tcpserver.py')
-rw-r--r-- | libmproxy/tcpserver.py | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/libmproxy/tcpserver.py b/libmproxy/tcpserver.py new file mode 100644 index 00000000..bf7ed0b4 --- /dev/null +++ b/libmproxy/tcpserver.py @@ -0,0 +1,88 @@ +import select, socket, threading + +class BaseHandler: + rbufsize = -1 + wbufsize = 0 + def __init__(self, connection, client_address, server): + self.connection = connection + self.rfile = self.connection.makefile('rb', self.rbufsize) + self.wfile = self.connection.makefile('wb', self.wbufsize) + + self.client_address = client_address + self.server = server + self.handle() + self.finish() + + def finish(self): + try: + if not getattr(self.wfile, "closed", False): + self.wfile.flush() + self.connection.close() + self.wfile.close() + self.rfile.close() + except IOError: + pass + + def handle(self): + raise NotImplementedError + + +class TCPServer: + request_queue_size = 20 + def __init__(self, server_address): + self.server_address = server_address + self.__is_shut_down = threading.Event() + self.__shutdown_request = False + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.socket.bind(self.server_address) + self.server_address = self.socket.getsockname() + self.socket.listen(self.request_queue_size) + + def fileno(self): + return self.socket.fileno() + + def request_thread(self, request, client_address): + try: + self.handle_connection(request, client_address) + request.close() + except: + self.handle_error(request, client_address) + request.close() + + def serve_forever(self, poll_interval=0.5): + self.__is_shut_down.clear() + try: + while not self.__shutdown_request: + r, w, e = select.select([self], [], [], poll_interval) + if self in r: + try: + request, client_address = self.socket.accept() + except socket.error: + return + try: + t = threading.Thread(target = self.request_thread, + args = (request, client_address)) + t.setDaemon (1) + t.start() + except: + self.handle_error(request, client_address) + request.close() + finally: + self.__shutdown_request = False + self.__is_shut_down.set() + + def shutdown(self): + self.__shutdown_request = True + self.__is_shut_down.wait() + + def handle_error(self, request, client_address): + print '-'*40 + print 'Exception happened during processing of request from', + print client_address + import traceback + traceback.print_exc() # XXX But this goes to stderr! + print '-'*40 + + def handle_connection(self, request, client_address): + raise NotImplementedError |