mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-27 10:26:23 +00:00
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
|
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
|