summaryrefslogtreecommitdiff
path: root/redis/connection.py
diff options
context:
space:
mode:
authorandy <andy@andymccurdy.com>2011-10-24 15:31:39 -0700
committerandy <andy@andymccurdy.com>2011-10-24 15:31:39 -0700
commit88d69301e5ba420a60ff2a3d57dec7f9b3225a86 (patch)
tree7ff157aa8a2d815deddab7171aa2d379503563ce /redis/connection.py
parent4e18978b8eb4c8d70e26ba8a2c9209454495023b (diff)
downloadredis-py-88d69301e5ba420a60ff2a3d57dec7f9b3225a86.tar.gz
Limit the maximum bytes read from the PythonParser. Fix for #205.
Diffstat (limited to 'redis/connection.py')
-rw-r--r--redis/connection.py26
1 files changed, 24 insertions, 2 deletions
diff --git a/redis/connection.py b/redis/connection.py
index 5a82221..fc95af6 100644
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -1,10 +1,17 @@
-import errno
import socket
from itertools import chain, imap
from redis.exceptions import ConnectionError, ResponseError, InvalidResponse
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+
+
class PythonParser(object):
"Plain Python parsing class"
+ MAX_READ_LENGTH = 1000000
+
def __init__(self):
self._fp = None
@@ -31,7 +38,22 @@ class PythonParser(object):
"""
try:
if length is not None:
- return self._fp.read(length+2)[:-2]
+ bytes_left = length + 2 # read the line ending
+ if length > self.MAX_READ_LENGTH:
+ # apparently reading more than 1MB or so from a windows
+ # socket can cause MemoryErrors. See:
+ # https://github.com/andymccurdy/redis-py/issues/205
+ # read smaller chunks at a time to work around this
+ buf = StringIO()
+ while bytes_left > 0:
+ read_len = min(bytes_left, self.MAX_READ_LENGTH)
+ buf.write(self._fp.read(read_len))
+ bytes_left -= read_len
+ buf.seek(0)
+ return buf.read(length)
+ return self._fp.read(bytes_left)[:-2]
+
+ # no length, read a full line
return self._fp.readline()[:-2]
except (socket.error, socket.timeout), e:
raise ConnectionError("Error while reading from socket: %s" % \