diff options
author | Thomas Kriechbaumer <Kriechi@users.noreply.github.com> | 2016-02-01 20:25:28 +0100 |
---|---|---|
committer | Thomas Kriechbaumer <Kriechi@users.noreply.github.com> | 2016-02-01 20:25:28 +0100 |
commit | 1e203401261ab6b24ae193f81dc4256854de13d8 (patch) | |
tree | 8fec43b4223a831a817fdbd5a25a6f80b572f379 /netlib/tcp.py | |
parent | d253ebc142d80708a1bdc065d3db05d1394e3819 (diff) | |
parent | 931b5459e92ec237914d7cca9034c5a348033bdb (diff) | |
download | mitmproxy-1e203401261ab6b24ae193f81dc4256854de13d8.tar.gz mitmproxy-1e203401261ab6b24ae193f81dc4256854de13d8.tar.bz2 mitmproxy-1e203401261ab6b24ae193f81dc4256854de13d8.zip |
Merge pull request #118 from mitmproxy/py3-peek
Fix Reader.peek() on Python 3
Diffstat (limited to 'netlib/tcp.py')
-rw-r--r-- | netlib/tcp.py | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/netlib/tcp.py b/netlib/tcp.py index 8902b9dc..682db29a 100644 --- a/netlib/tcp.py +++ b/netlib/tcp.py @@ -25,6 +25,10 @@ from netlib.exceptions import InvalidCertificateException, TcpReadIncomplete, Tl version_check.check_pyopenssl_version() +if six.PY2: + socket_fileobject = socket._fileobject +else: + socket_fileobject = socket.SocketIO EINTR = 4 @@ -268,9 +272,9 @@ class Reader(_FileLike): Raises: TcpException if there was an error with the socket TlsException if there was an error with pyOpenSSL. - NotImplementedError if the underlying file object is not a (pyOpenSSL) socket + NotImplementedError if the underlying file object is not a [pyOpenSSL] socket """ - if isinstance(self.o, socket._fileobject): + if isinstance(self.o, socket_fileobject): try: return self.o._sock.recv(length, socket.MSG_PEEK) except socket.error as e: @@ -420,11 +424,26 @@ class _Connection(object): rbufsize = -1 wbufsize = -1 + def _makefile(self): + """ + Set up .rfile and .wfile attributes from .connection + """ + # Ideally, we would use the Buffered IO in Python 3 by default. + # Unfortunately, the implementation of .peek() is broken for n>1 bytes, + # as it may just return what's left in the buffer and not all the bytes we want. + # As a workaround, we just use unbuffered sockets directly. + # https://mail.python.org/pipermail/python-dev/2009-June/089986.html + if six.PY2: + self.rfile = Reader(self.connection.makefile('rb', self.rbufsize)) + self.wfile = Writer(self.connection.makefile('wb', self.wbufsize)) + else: + self.rfile = Reader(socket.SocketIO(self.connection, "rb")) + self.wfile = Writer(socket.SocketIO(self.connection, "wb")) + def __init__(self, connection): if connection: self.connection = connection - self.rfile = Reader(self.connection.makefile('rb', self.rbufsize)) - self.wfile = Writer(self.connection.makefile('wb', self.wbufsize)) + self._makefile() else: self.connection = None self.rfile = None @@ -663,13 +682,12 @@ class TCPClient(_Connection): connection.connect(self.address()) if not self.source_address: self.source_address = Address(connection.getsockname()) - self.rfile = Reader(connection.makefile('rb', self.rbufsize)) - self.wfile = Writer(connection.makefile('wb', self.wbufsize)) except (socket.error, IOError) as err: raise TcpException( 'Error connecting to "%s": %s' % (self.address.host, err)) self.connection = connection + self._makefile() def settimeout(self, n): self.connection.settimeout(n) |