Skip to content

Commit 48508f6

Browse files
committed
Fix corner case on empty file and add testcase
1 parent 42c69ab commit 48508f6

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

Lib/http/server.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,13 @@ def send_head(self):
783783
# `end` here means suffix length
784784
start = max(0, fs.st_size - end)
785785
end = fs.st_size - 1
786-
if start >= fs.st_size:
786+
elif end is None or end >= fs.st_size:
787+
end = fs.st_size - 1
788+
789+
if start == 0 and end >= fs.st_size - 1:
790+
# Send entire file
791+
self._range = None
792+
elif start >= fs.st_size:
787793
# 416 REQUESTED_RANGE_NOT_SATISFIABLE means that
788794
# none of the range values overlap the extent of
789795
# the resource
@@ -792,10 +798,11 @@ def send_head(self):
792798
self.send_error(HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE,
793799
extra_headers=headers)
794800
return None
795-
if end is None or end >= fs.st_size:
796-
end = fs.st_size - 1
801+
802+
if self._range:
797803
self.send_response(HTTPStatus.PARTIAL_CONTENT)
798-
self.send_header("Content-Range", f"bytes {start}-{end}/{fs.st_size}")
804+
self.send_header("Content-Range",
805+
f"bytes {start}-{end}/{fs.st_size}")
799806
self.send_header("Content-Length", str(end - start + 1))
800807

801808
# Update range to be sent to be used later in copyfile

Lib/test/test_httpservers.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,14 +588,29 @@ def test_range_get(self):
588588

589589
response = self.request(route, headers={'Range': 'bytes=--'})
590590
self.check_status_and_reason(response, HTTPStatus.OK, data=self.data)
591-
591+
592592
response = self.request(route, headers={'Range': 'bytes='})
593593
self.check_status_and_reason(response, HTTPStatus.OK, data=self.data)
594594

595595
# multipart ranges (not supported currently)
596596
response = self.request(route, headers={'Range': 'bytes=1-2, 4-7'})
597597
self.check_status_and_reason(response, HTTPStatus.OK, data=self.data)
598598

599+
# empty file
600+
with open(os.path.join(self.tempdir_name, 'empty'), 'wb'):
601+
pass
602+
empty_path = self.base_url + '/empty'
603+
604+
response = self.request(empty_path, headers={'Range': 'bytes=0-512'})
605+
self.check_status_and_reason(response, HTTPStatus.OK, data=b'')
606+
607+
response = self.request(empty_path, headers={'Range': 'bytes=-512'})
608+
self.check_status_and_reason(response, HTTPStatus.OK, data=b'')
609+
610+
response = self.request(empty_path, headers={'Range': 'bytes=1-2'})
611+
self.assertEqual(response.getheader('content-range'), 'bytes */0')
612+
self.check_status_and_reason(response, HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
613+
599614
def test_head(self):
600615
response = self.request(
601616
self.base_url + '/test', method='HEAD')

0 commit comments

Comments
 (0)