From 0900a2c2447eb5a6cc8b105b4331a638959dba5d Mon Sep 17 00:00:00 2001 From: Timur Alperovich Date: Tue, 6 Sep 2016 17:26:40 -0700 Subject: [PATCH] Fix error handling in proxy/controllers/base.py. There are a few issues going on in the controllers/base.py:_get_response_parts_iter(). One is that the "raise" statement that attempts to re-raise the GeneratorExit, may re-raise ValueError if that was the last exception caught. Secondly, the range may not actually be set in the backend_headers (need to investigate further, as that could actually be faulty tests, since learn_size_from_content_range should always set it). The patch changes the Range construction to throw a ValueError if None is passed in that case. Lastly, the range may be only half-defined, e.g. bytes=0-. In that case, the check of how many bytes are expected vs how many bytes have been sent does not make sense. Change-Id: Ida5adf3d33c736240b2c4bae5510b5289f03dee2 --- swift/common/swob.py | 2 ++ swift/proxy/controllers/base.py | 8 +++++--- test/unit/common/test_swob.py | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/swift/common/swob.py b/swift/common/swob.py index 1a8c6ea630..900767dbbe 100644 --- a/swift/common/swob.py +++ b/swift/common/swob.py @@ -467,6 +467,8 @@ class Range(object): :param headerval: value of the header as a str """ def __init__(self, headerval): + if not headerval: + raise ValueError('Invalid Range header: %r' % headerval) headerval = headerval.replace(' ', '') if not headerval.lower().startswith('bytes='): raise ValueError('Invalid Range header: %s' % headerval) diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index 36b98f484e..2bc1ef2718 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -1061,6 +1061,7 @@ class ResumingGetter(object): self.app.client_timeout) self.app.logger.increment('client_timeouts') except GeneratorExit: + exc_type, exc_value, exc_traceback = exc_info() warn = True try: req_range = Range(self.backend_headers['Range']) @@ -1068,11 +1069,12 @@ class ResumingGetter(object): req_range = None if req_range and len(req_range.ranges) == 1: begin, end = req_range.ranges[0] - if end - begin + 1 == self.bytes_used_from_backend: - warn = False + if end is not None and begin is not None: + if end - begin + 1 == self.bytes_used_from_backend: + warn = False if not req.environ.get('swift.non_client_disconnect') and warn: self.app.logger.warning(_('Client disconnected on read')) - raise + six.reraise(exc_type, exc_value, exc_traceback) except Exception: self.app.logger.exception(_('Trying to send to client')) raise diff --git a/test/unit/common/test_swob.py b/test/unit/common/test_swob.py index f1a11e1fcb..c4b1797c52 100644 --- a/test/unit/common/test_swob.py +++ b/test/unit/common/test_swob.py @@ -249,6 +249,7 @@ class TestRange(unittest.TestCase): 6. any combination of the above """ + _assert_invalid_range(None) _assert_invalid_range('nonbytes=foobar,10-2') _assert_invalid_range('bytes=5-3') _assert_invalid_range('bytes=-')