Skip to content

Commit

Permalink
fix disconnection detection for more cases in .readline(); improve te…
Browse files Browse the repository at this point in the history
…st coverage
  • Loading branch information
maluke committed Aug 7, 2011
1 parent 50d389c commit 53b2238
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 19 deletions.
25 changes: 17 additions & 8 deletions tests/test_in_wsgiref.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from webob import Request, Response
import sys, logging, threading, random, urllib2, socket, cgi
from contextlib import contextmanager
from nose.tools import assert_raises
from nose.tools import assert_raises, eq_ as eq
from Queue import Queue, Empty

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -65,23 +65,32 @@ def _test_app_req_interrupt(env, sr):
sr('200 OK', [])
return []

def _req_req_cgi(req):
env = req.environ
#env = env.copy()
#env.setdefault('CONTENT_LENGTH', '0')
def _req_int_cgi(req):
assert req.body_file.read(0) == ''
#req.environ.setdefault('CONTENT_LENGTH', '0')
d = cgi.FieldStorage(
fp=req.body_file,
environ=env,
environ=req.environ,
)

def _req_int_readline(req):
try:
eq(req.body_file.readline(), 'a=b\n')
except IOError:
# too early to detect disconnect
raise AssertionError
req.body_file.readline()


_test_ops_req_interrupt = {
'/copy': lambda req: req.copy(),
'/read-body': lambda req: req.body,
'/read-post': lambda req: req.POST,
'/read-all': lambda req: req.body_file.read(),
'/read-too-much': lambda req: req.body_file.read(1<<30),
'/readline': _req_int_readline,
'/readlines': lambda req: req.body_file.readlines(),
'/read-cgi': _req_req_cgi,
'/read-cgi': _req_int_cgi,
'/make-seekable': lambda req: req.make_body_seekable()
}

Expand All @@ -101,7 +110,7 @@ def _send_interrupted_req(server, path='/'):
"content-length: 100000\r\n"
"\r\n"
)
_interrupted_req += 'z='+'x'*10000
_interrupted_req += 'a=b\nz='+'x'*10000



Expand Down
11 changes: 10 additions & 1 deletion tests/test_request_nose.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ def test_request_read_after_setting_body_file():
assert req.is_body_seekable
assert input.was_read

def test_request_readlines():
req = Request.blank('/', POST='a\n'*3)
req.is_body_seekable = False
eq(req.body_file.readlines(), ['a\n'] * 3)

def test_request_delete_with_body():
req = Request.blank('/', method='DELETE')
assert not req.is_body_readable
Expand Down Expand Up @@ -70,18 +75,22 @@ def read(self, size=-1):
return self.data


def test_request_wrong_clen():
def test_request_wrong_clen(is_seekable=False):
tlen = 1<<20
req = Request.blank('/', POST='x'*tlen)
eq(req.content_length, tlen)
req.body_file = _Helper_test_request_wrong_clen(req.body_file)
eq(req.content_length, None)
req.content_length = tlen + 100
req.is_body_seekable = is_seekable
eq(req.content_length, tlen+100)
# this raises AssertionError if the body reading
# trusts content_length too much
assert_raises(IOError, req.copy_body)

def test_request_wrong_clen_seekable():
test_request_wrong_clen(is_seekable=True)

class _Helper_test_request_wrong_clen(object):
def __init__(self, f):
self.f = f
Expand Down
11 changes: 1 addition & 10 deletions webob/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,7 @@ def readline(self, hint=None):
hint = self._normhint(hint)
r = self.file.readline(hint)
self.remaining -= len(r)
if not r:
if not r or not r.endswith('\n'):
self._check_disconnect()
return r

Expand All @@ -1301,15 +1301,6 @@ def readlines(self, hint=None):
self._check_disconnect()
return r

def __iter__(self):
return self

def next(self):
r = self.readline()
if not r:
raise StopIteration
return r

def _normhint(self, hint):
return min(hint, self.remaining) if hint else self.remaining

Expand Down

0 comments on commit 53b2238

Please sign in to comment.