aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
authorThomas Kriechbaumer <Kriechi@users.noreply.github.com>2016-02-01 20:25:28 +0100
committerThomas Kriechbaumer <Kriechi@users.noreply.github.com>2016-02-01 20:25:28 +0100
commit1e203401261ab6b24ae193f81dc4256854de13d8 (patch)
tree8fec43b4223a831a817fdbd5a25a6f80b572f379 /netlib
parentd253ebc142d80708a1bdc065d3db05d1394e3819 (diff)
parent931b5459e92ec237914d7cca9034c5a348033bdb (diff)
downloadmitmproxy-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')
-rw-r--r--netlib/tcp.py30
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)