Permalink
Browse files

change content-range parsing to regexp

  • Loading branch information...
1 parent 3049deb commit fec7df05e64faf0976c373f29c9d04ed3f7320b2 @maluke maluke committed Sep 26, 2011
Showing with 25 additions and 87 deletions.
  1. +15 −53 tests/test_byterange.py
  2. +10 −34 webob/byterange.py
View
@@ -64,66 +64,28 @@ def test_contentrange_bad_input():
def test_contentrange_repr():
contentrange = ContentRange(0, 99, 100)
- assert_true(contentrange.__repr__(), '<ContentRange bytes 0-98/100>')
+ assert_true(repr(contentrange), '<ContentRange bytes 0-98/100>')
-def test_contentrange_str_length_none():
- contentrange = ContentRange(0, 99, 100)
- contentrange.length = None
+def test_contentrange_str():
+ contentrange = ContentRange(0, 99, None)
eq_(str(contentrange), 'bytes 0-98/*')
-
-def test_contentrange_str_start_none():
- contentrange = ContentRange(0, 99, 100)
- contentrange.start = None
- contentrange.stop = None
+ contentrange = ContentRange(None, None, 100)
eq_(str(contentrange), 'bytes */100')
def test_contentrange_iter():
contentrange = ContentRange(0, 99, 100)
assert_true(type(contentrange.__iter__()), iter)
-
-def test_cr_parse_ok():
- contentrange = ContentRange(0, 99, 100)
- assert_true(contentrange.parse('bytes 0-99/100').__class__, ContentRange)
-
-def test_cr_parse_none():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse(None), None)
-
-def test_cr_parse_no_bytes():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('0-99 100'), None)
-
-def test_cr_parse_missing_slash():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes 0-99 100'), None)
-
-def test_cr_parse_invalid_length():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes 0-99/xxx'), None)
-
-def test_cr_parse_no_range():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes 0 99/100'), None)
-
-def test_cr_parse_range_star():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes */100').__class__, ContentRange)
-
-def test_cr_parse_parse_problem_1():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes A-99/100'), None)
-
-def test_cr_parse_parse_problem_2():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes 0-B/100'), None)
-
-def test_cr_parse_content_invalid():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes 99-0/100'), None)
-
-def test_contentrange_str_length_start():
- contentrange = ContentRange(0, 99, 100)
- eq_(contentrange.parse('bytes 0 99/*'), None)
+ assert_true(ContentRange.parse('bytes 0-99/100').__class__, ContentRange)
+ eq_(ContentRange.parse(None), None)
+ eq_(ContentRange.parse('0-99 100'), None)
+ eq_(ContentRange.parse('bytes 0-99 100'), None)
+ eq_(ContentRange.parse('bytes 0-99/xxx'), None)
+ eq_(ContentRange.parse('bytes 0 99/100'), None)
+ eq_(ContentRange.parse('bytes */100').__class__, ContentRange)
+ eq_(ContentRange.parse('bytes A-99/100'), None)
+ eq_(ContentRange.parse('bytes 0-B/100'), None)
+ eq_(ContentRange.parse('bytes 99-0/100'), None)
+ eq_(ContentRange.parse('bytes 0 99/*'), None)
# _is_content_range_valid function
View
@@ -3,6 +3,7 @@
__all__ = ['Range', 'ContentRange']
_rx_range = re.compile('bytes=(\d*)-(\d*)')
+_rx_content_range = re.compile(r'bytes (?:(\d+)-(\d+)|[*])/(?:(\d+)|[*])')
class Range(object):
"""
@@ -129,42 +130,17 @@ def parse(cls, value):
"""
Parse the header. May return None if it cannot parse.
"""
- if value is None:
- return None
- value = value.strip()
- if not value.startswith('bytes '):
- # Unparseable
- return None
- value = value[len('bytes '):].strip()
- if '/' not in value:
- # Invalid, no length given
- return None
- range, length = value.split('/', 1)
- if length == '*':
- length = None
- elif length.isdigit():
- length = int(length)
- else:
- return None # invalid length
-
- if range == '*':
- return cls(None, None, length)
- elif '-' not in range:
- # Invalid, no range
+ m = _rx_content_range.match(value or '')
+ if not m:
return None
- else:
- start, stop = range.split('-', 1)
- try:
- start = int(start)
- stop = int(stop)
- stop += 1 # convert to non-inclusive
- except ValueError:
- # Parse problem
- return None
- if _is_content_range_valid(start, stop, length, response=True):
- return cls(start, stop, length)
+ s, e, l = m.groups()
+ if s:
+ s = int(s)
+ e = int(e) + 1
+ l = l and int(l)
+ if not _is_content_range_valid(s, e, l, response=True):
return None
-
+ return cls(s, e, l)
def _is_content_range_valid(start, stop, length, response=False):

0 comments on commit fec7df0

Please sign in to comment.