Added a /range-request endpoint

This endpoint conforms to RFC7233.
http://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7233.html

It is functionally very similar to /stream-bytes, but it also
allows specifying a "Range" header, which allows the client
to ask for a specific portion of the resource.

I didn't add this functionality to /stream-bytes so as not
to break compatibility with any clients that expect range
requests to fail on that endpoint. Perhaps I'm just being
overly cautious.
This commit is contained in:
David Shirley
2015-01-02 13:22:42 -08:00
parent 6b7676ba80
commit e73f34e335
5 changed files with 200 additions and 2 deletions
+84
View File
@@ -335,5 +335,89 @@ class HttpbinTestCase(unittest.TestCase):
response.headers.get('Location'), 'http://localhost/get'
)
def test_request_range(self):
response1 = self.app.get('/range-request/1234')
self.assertEqual(response1.status_code, 200)
self.assertEqual(response1.headers.get('ETag'), 'range-request1234')
self.assertEqual(response1.headers.get('Content-range'), 'bytes 0-1233/1234')
self.assertEqual(response1.headers.get('Accept-ranges'), 'bytes')
self.assertEqual(len(response1.get_data()), 1234)
response2 = self.app.get('/range-request/1234')
self.assertEqual(response2.status_code, 200)
self.assertEqual(response2.headers.get('ETag'), 'range-request1234')
self.assertEqual(response1.get_data(), response2.get_data())
def test_request_range_with_parameters(self):
response = self.app.get(
'/range-request/100?duration=1.5&chunk_size=5',
headers={ 'Range': 'bytes=10-24' }
)
self.assertEqual(response.status_code, 206)
self.assertEqual(response.headers.get('ETag'), 'range-request100')
self.assertEqual(response.headers.get('Content-range'), 'bytes 10-24/100')
self.assertEqual(response.headers.get('Accept-ranges'), 'bytes')
self.assertEqual(response.get_data(), 'klmnopqrstuvwxy')
def test_request_range_first_15_bytes(self):
response = self.app.get(
'/range-request/1000',
headers={ 'Range': 'bytes=0-15' }
)
self.assertEqual(response.status_code, 206)
self.assertEqual(response.headers.get('ETag'), 'range-request1000')
self.assertEqual(response.get_data(), 'abcdefghijklmnop')
self.assertEqual(response.headers.get('Content-range'), 'bytes 0-15/1000')
def test_request_range_open_ended_last_6_bytes(self):
response = self.app.get(
'/range-request/26',
headers={ 'Range': 'bytes=20-' }
)
self.assertEqual(response.status_code, 206)
self.assertEqual(response.headers.get('ETag'), 'range-request26')
self.assertEqual(response.get_data(), 'uvwxyz')
self.assertEqual(response.headers.get('Content-range'), 'bytes 20-25/26')
def test_request_range_suffix(self):
response = self.app.get(
'/range-request/26',
headers={ 'Range': 'bytes=-5' }
)
self.assertEqual(response.status_code, 206)
self.assertEqual(response.headers.get('ETag'), 'range-request26')
self.assertEqual(response.get_data(), 'vwxyz')
self.assertEqual(response.headers.get('Content-range'), 'bytes 21-25/26')
def test_request_out_of_bounds(self):
response = self.app.get(
'/range-request/26',
headers={ 'Range': 'bytes=10-5',
}
)
self.assertEqual(response.status_code, 416)
self.assertEqual(response.headers.get('ETag'), 'range-request26')
self.assertEqual(len(response.get_data()), 0)
self.assertEqual(response.headers.get('Content-range'), 'bytes */26')
response = self.app.get(
'/range-request/26',
headers={ 'Range': 'bytes=32-40',
}
)
self.assertEqual(response.status_code, 416)
response = self.app.get(
'/range-request/26',
headers={ 'Range': 'bytes=0-40',
}
)
self.assertEqual(response.status_code, 416)
if __name__ == '__main__':
unittest.main()