Skip to content

Commit 1670150

Browse files
authored
Retry RequestTimeout error by S3. (#457)
1 parent 45eee8d commit 1670150

6 files changed

Lines changed: 70 additions & 0 deletions

File tree

include/aws/s3/s3.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum aws_s3_errors {
4848
AWS_ERROR_S3_REQUEST_HAS_COMPLETED,
4949
AWS_ERROR_S3_RECV_FILE_ALREADY_EXISTS,
5050
AWS_ERROR_S3_RECV_FILE_NOT_FOUND,
51+
AWS_ERROR_S3_REQUEST_TIMEOUT,
5152

5253
AWS_ERROR_S3_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_S3_PACKAGE_ID)
5354
};

source/s3.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static struct aws_error_info s_errors[] = {
5151
AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_REQUEST_HAS_COMPLETED, "Request has already completed, action cannot be performed."),
5252
AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_RECV_FILE_ALREADY_EXISTS, "File already exists, cannot create as new."),
5353
AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_RECV_FILE_NOT_FOUND, "The receive file doesn't exist, cannot create as configuration required."),
54+
AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_REQUEST_TIMEOUT, "RequestTimeout error received from S3."),
5455
};
5556
/* clang-format on */
5657

source/s3_util.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,11 @@ int aws_s3_crt_error_code_from_recoverable_server_error_code_string(struct aws_b
687687
if (aws_byte_cursor_eq_c_str_ignore_case(&error_code_string, "RequestTimeTooSkewed")) {
688688
return AWS_ERROR_S3_REQUEST_TIME_TOO_SKEWED;
689689
}
690+
691+
if (aws_byte_cursor_eq_c_str_ignore_case(&error_code_string, "RequestTimeout")) {
692+
return AWS_ERROR_S3_REQUEST_TIMEOUT;
693+
}
694+
690695
return AWS_ERROR_UNKNOWN;
691696
}
692697

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ if(ENABLE_MOCK_SERVER_TESTS)
339339
add_net_test_case(s3express_client_sanity_test_mock_server)
340340
add_net_test_case(s3express_client_sanity_override_test_mock_server)
341341
add_net_test_case(request_time_too_skewed_mock_server)
342+
add_net_test_case(request_timeout_error_mock_server)
342343
endif()
343344

344345
add_net_test_case(s3express_provider_long_running_session_refresh)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
{
3+
"status": 400,
4+
"headers": {"x-amz-request-id": "12345"},
5+
"body": [
6+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
7+
"",
8+
"<Error>",
9+
"<Code>RequestTimeout</Code>",
10+
"<Message>Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed.</Message>",
11+
"<RequestId>1234</RequestId>",
12+
"<HostId>asdf</HostId>",
13+
"</Error>"
14+
]
15+
}

tests/s3_mock_server_tests.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,3 +1078,50 @@ TEST_CASE(request_time_too_skewed_mock_server) {
10781078

10791079
return AWS_OP_SUCCESS;
10801080
}
1081+
1082+
TEST_CASE(request_timeout_error_mock_server) {
1083+
(void)ctx;
1084+
1085+
struct aws_s3_tester tester;
1086+
ASSERT_SUCCESS(aws_s3_tester_init(allocator, &tester));
1087+
struct aws_s3_tester_client_options client_options = {
1088+
.part_size = MB_TO_BYTES(5),
1089+
.tls_usage = AWS_S3_TLS_DISABLED,
1090+
};
1091+
1092+
struct aws_s3_client *client = NULL;
1093+
ASSERT_SUCCESS(aws_s3_tester_client_new(&tester, &client_options, &client));
1094+
1095+
struct aws_byte_cursor object_path = aws_byte_cursor_from_c_str("/request_timeout");
1096+
struct aws_s3_meta_request_test_results out_results;
1097+
aws_s3_meta_request_test_results_init(&out_results, allocator);
1098+
1099+
struct aws_s3_tester_meta_request_options put_options = {
1100+
.allocator = allocator,
1101+
.meta_request_type = AWS_S3_META_REQUEST_TYPE_PUT_OBJECT,
1102+
.client = client,
1103+
.checksum_algorithm = AWS_SCA_CRC32,
1104+
.validate_get_response_checksum = false,
1105+
.put_options =
1106+
{
1107+
.object_size_mb = 10,
1108+
.object_path_override = object_path,
1109+
},
1110+
.mock_server = true,
1111+
.validate_type = AWS_S3_TESTER_VALIDATE_TYPE_EXPECT_FAILURE,
1112+
};
1113+
1114+
ASSERT_SUCCESS(aws_s3_tester_send_meta_request_with_options(&tester, &put_options, &out_results));
1115+
1116+
ASSERT_UINT_EQUALS(AWS_ERROR_S3_REQUEST_TIMEOUT, out_results.finished_error_code);
1117+
1118+
/* The default retry will max out after 5 times. So, in total, it will be 6 requests, first one and 5 retries. */
1119+
size_t result_num = aws_array_list_length(&out_results.synced_data.metrics);
1120+
ASSERT_UINT_EQUALS(6, result_num);
1121+
1122+
aws_s3_meta_request_test_results_clean_up(&out_results);
1123+
aws_s3_client_release(client);
1124+
aws_s3_tester_clean_up(&tester);
1125+
1126+
return AWS_OP_SUCCESS;
1127+
}

0 commit comments

Comments
 (0)