📄 connection.py
字号:
from proxy4_base import *class Connection(asyncore.dispatcher): RECV_BUFSIZE = 65536 #SEND_BUFSIZE = 1460 SEND_BUFSIZE = 8192 def __init__(self, socket=None): self.connected = 0 self.socket = None asyncore.dispatcher.__init__(self, socket) self.recv_buffer = '' self.send_buffer = '' self.close_pending = 0 def log(self, msg): pass def fileno(self): return self._fileno def close(self): if self.connected: self.connected = 0 asyncore.dispatcher.close(self) def writable(self): return self.send_buffer != '' def write(self, data): # Add buffering to the connection if self.send_buffer != '': self.send_buffer = self.send_buffer + data else: self.send_buffer = data def read(self, bytes=None): "Read up to LEN bytes from the internal buffer" if bytes is None or len(self.recv_buffer) <= bytes: data = self.recv_buffer self.recv_buffer = '' else: data = self.recv_buffer[:bytes] self.recv_buffer = self.recv_buffer[bytes:] return data def send(self, data): n = asyncore.dispatcher.send(self, data) #print 'send:', self, `data[:n]` return n def handle_connect(self): message(None, 'connect', None, None, self) def handle_read(self): if not self.connected: # It's been closed (presumably recently) return try: data = self.recv(self.RECV_BUFSIZE) if not data: # It's been closed, and handle_close has been called return message(None, 'read', len(data), '<=', self) #print 'read:', `data` except socket.error, err: message(1, 'read error', None, None, self, err) self.handle_error(socket.error, err) return if self.recv_buffer != '': self.recv_buffer = self.recv_buffer + data else: self.recv_buffer = data self.process_read() def handle_write(self): assert self.connected try: what_to_write = self.send_buffer if len(what_to_write) > self.SEND_BUFSIZE: what_to_write = self.send_buffer[:self.SEND_BUFSIZE] n = self.send(what_to_write) message(None, 'write', n, '=>', self) except socket.error, err: message(1, 'write error', None, None, self, err) self.handle_error(socket.error, err) return if n < len(self.send_buffer): self.send_buffer = self.send_buffer[n:] else: self.send_buffer = '' if not self.send_buffer and self.close_pending: self.close_pending = 0 self.close() def close(self): message(None, 'close', None, None, self) return asyncore.dispatcher.close(self) def delayed_close(self): "Close whenever the data has been sent" assert self.connected if self.send_buffer: # We can't close yet because there's still data to send message(None, 'close ready', None, None, self) self.close_pending = 1 else: self.close() def handle_close(self): if self.connected: self.delayed_close() def handle_error(self, type, value, tb=None): message(1, 'error', None, None, self, type, value) import traceback if tb: traceback.print_tb(tb) if self.connected: self.close() self.del_channel()# asyncore problem -- the __getattr__ thingie is trouble. Below# I delete it.# asyncore problem -- we can't separately register for reading/writing# (less efficient: it calls writable(), readable() a LOT)# (however, for the proxy it may not be a big deal) I'd like to# assume everything is readable, at least. Is that the case?# asyncore problem -- suppose we get an error while connecting.# it calls handle_read_event, and then the recv() gives an exception.# the problem now is that we can't just close(), because asyncore's# loop will call handle_write_event, which will then assume the# connection is reopened (!!!) and then we get another exception# while trying to write .. argh. NOTE: I just started using my# own poll loop to avoid this problem. :P# EVIL HACKS to asyncore# We shouldn't need this method.. it's only trouble!try: del asyncore.dispatcher.__getattr__except TypeError: pass # Py1.5.1 doesn't allow thisold_compact_traceback = asyncore.compact_tracebackdef new_compact_traceback(a,b,c): x,y = old_compact_traceback(a,b,c) return x, color(3, str(y))asyncore.compact_traceback = new_compact_traceback
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -