Skip to content

Commit 68904f3

Browse files
authored
Fix bug when Range: bytes=0-0 (#278)
This is a valid way to request the first byte. There was a bug where, if some internal range_start and range_end variables were both 0, it was assumed that meant they were unset, because the object was 0 bytes. Fix by adding separate bool to indicate whether the object is empty.
1 parent 7b5c7f0 commit 68904f3

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

include/aws/s3/private/s3_auto_ranged_get.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ struct aws_s3_auto_ranged_get {
2020
enum aws_s3_checksum_algorithm validation_algorithm;
2121
/* Members to only be used when the mutex in the base type is locked. */
2222
struct {
23-
/* The starting byte of the data that we will be retrieved from the object.*/
23+
/* The starting byte of the data that we will be retrieved from the object.
24+
* (ignore this if object_range_empty) */
2425
uint64_t object_range_start;
2526

26-
/* The last byte of the data that will be retrieved from the object.*/
27+
/* The last byte of the data that will be retrieved from the object.
28+
* (ignore this if object_range_empty) */
2729
uint64_t object_range_end;
2830

2931
/* The total number of parts that are being used in downloading the object range. Note that "part" here
@@ -37,6 +39,10 @@ struct aws_s3_auto_ranged_get {
3739
uint32_t num_parts_checksum_validated;
3840

3941
uint32_t object_range_known : 1;
42+
43+
/* True if object_range_known, and it's found to be empty.
44+
* If this is true, ignore object_range_start and object_range_end */
45+
uint32_t object_range_empty : 1;
4046
uint32_t head_object_sent : 1;
4147
uint32_t head_object_completed : 1;
4248
uint32_t get_without_range_sent : 1;

source/s3_auto_ranged_get.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ static bool s_s3_auto_ranged_get_update(
196196
}
197197

198198
/* If the object range is known and that range is empty, then we have an empty file to request. */
199-
if (auto_ranged_get->synced_data.object_range_start == 0 &&
200-
auto_ranged_get->synced_data.object_range_end == 0) {
199+
if (auto_ranged_get->synced_data.object_range_empty != 0) {
201200
if (auto_ranged_get->synced_data.get_without_range_sent) {
202201
if (auto_ranged_get->synced_data.get_without_range_completed) {
203202
goto no_work_remaining;
@@ -653,6 +652,7 @@ static void s_s3_auto_ranged_get_request_finished(
653652
AWS_ASSERT(!auto_ranged_get->synced_data.object_range_known);
654653

655654
auto_ranged_get->synced_data.object_range_known = true;
655+
auto_ranged_get->synced_data.object_range_empty = (total_content_length == 0);
656656
auto_ranged_get->synced_data.object_range_start = object_range_start;
657657
auto_ranged_get->synced_data.object_range_end = object_range_end;
658658
auto_ranged_get->synced_data.total_num_parts =

tests/s3_data_plane_tests.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4295,6 +4295,9 @@ static int s_test_s3_range_requests(struct aws_allocator *allocator, void *ctx)
42954295
// Single byte range.
42964296
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("bytes=8-8"),
42974297

4298+
// Single byte range (first byte).
4299+
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("bytes=0-0"),
4300+
42984301
// First 8K. 8K < client's 16K part size.
42994302
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("bytes=0-8191"),
43004303

0 commit comments

Comments
 (0)