summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2019-09-09 00:50:58 -0700
committerChris Dent <cdent@anticdent.org>2019-09-09 08:50:58 +0100
commit7e2f7e78697a0a9126cdbc69bbea699c00b7c121 (patch)
tree4059366257bbbc3a9f39ba0f58229ac09359ae94
parent3a1642dce3a9a5b3f7805ab9f7a4792a494a8db7 (diff)
downloadpaste-git-7e2f7e78697a0a9126cdbc69bbea699c00b7c121.tar.gz
LimitedLengthFile: Handle io.UnsupportedOperation from socket.tell(). (#35)
On Python 3, socket.makefile() returns an object with a tell() method, but one that always raises io.UnsupportedOperation.
-rwxr-xr-xpaste/httpserver.py9
-rw-r--r--tests/test_httpserver.py21
2 files changed, 27 insertions, 3 deletions
diff --git a/paste/httpserver.py b/paste/httpserver.py
index 063c180..7709c60 100755
--- a/paste/httpserver.py
+++ b/paste/httpserver.py
@@ -20,6 +20,7 @@ if pyOpenSSL is installed, it also provides SSL capabilities.
from __future__ import print_function
import atexit
import traceback
+import io
import socket, sys, threading
import posixpath
import six
@@ -523,9 +524,11 @@ class LimitedLengthFile(object):
def tell(self):
if hasattr(self.file, 'tell'):
- return self.file.tell()
- else:
- return self._consumed
+ try:
+ return self.file.tell()
+ except io.UnsupportedOperation:
+ pass
+ return self._consumed
class ThreadPool(object):
"""
diff --git a/tests/test_httpserver.py b/tests/test_httpserver.py
index 20a4320..512f06d 100644
--- a/tests/test_httpserver.py
+++ b/tests/test_httpserver.py
@@ -1,5 +1,8 @@
import email
import io
+import socket
+
+import six
from paste.httpserver import LimitedLengthFile, WSGIHandler
from six.moves import StringIO
@@ -49,5 +52,23 @@ def test_environ_with_multiple_values():
def test_limited_length_file():
backing = io.BytesIO(b'0123456789')
f = LimitedLengthFile(backing, 9)
+ assert f.tell() == 0
assert f.read() == b'012345678'
+ assert f.tell() == 9
assert f.read() == b''
+
+def test_limited_length_file_tell_on_socket():
+ backing_read, backing_write = socket.socketpair()
+ if six.PY2:
+ # On Python 2, socketpair() returns an internal socket type rather than
+ # the public one.
+ backing_read = socket.socket(_sock=backing_read)
+ f = LimitedLengthFile(backing_read.makefile('rb'), 10)
+ backing_write.send(b'0123456789')
+ backing_write.close()
+ assert f.tell() == 0
+ assert f.read(1) == b'0'
+ assert f.tell() == 1
+ assert f.read() == b'123456789'
+ assert f.tell() == 10
+ backing_read.close()