Skip to content

Commit

Permalink
Populate error payload for HeadObject request failure (#364)
Browse files Browse the repository at this point in the history
  • Loading branch information
waahm7 authored Oct 27, 2023
1 parent 684484e commit d68aa80
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 7 deletions.
2 changes: 1 addition & 1 deletion include/aws/s3/private/s3_meta_request_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ AWS_S3_API
void aws_s3_meta_request_result_setup(
struct aws_s3_meta_request *meta_request,
struct aws_s3_meta_request_result *result,
struct aws_s3_request *request,
struct aws_s3_request *failed_request,
int response_status,
int error_code);

Expand Down
24 changes: 18 additions & 6 deletions source/s3_meta_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1764,21 +1764,33 @@ bool aws_s3_meta_request_body_has_no_more_data(const struct aws_s3_meta_request
void aws_s3_meta_request_result_setup(
struct aws_s3_meta_request *meta_request,
struct aws_s3_meta_request_result *result,
struct aws_s3_request *request,
struct aws_s3_request *failed_request,
int response_status,
int error_code) {

if (request != NULL) {
if (request->send_data.response_headers != NULL) {
result->error_response_headers = request->send_data.response_headers;
if (failed_request != NULL) {
if (failed_request->send_data.response_headers != NULL) {
result->error_response_headers = failed_request->send_data.response_headers;
aws_http_headers_acquire(result->error_response_headers);
}

if (request->send_data.response_body.capacity > 0) {
if (failed_request->send_data.response_body.capacity > 0) {
result->error_response_body = aws_mem_calloc(meta_request->allocator, 1, sizeof(struct aws_byte_buf));

aws_byte_buf_init_copy(
result->error_response_body, meta_request->allocator, &request->send_data.response_body);
result->error_response_body, meta_request->allocator, &failed_request->send_data.response_body);
} else if (
failed_request->request_tag == AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_HEAD_OBJECT &&
error_code == AWS_ERROR_S3_INVALID_RESPONSE_STATUS) {
/* S3 does not send an error explanation in the body if the HEAD_OBJECT request fails.
* Populate the error_response with aws_http_status_text to have something reasonable instead of
* empty error_response_body
*/
result->error_response_body = aws_mem_calloc(meta_request->allocator, 1, sizeof(struct aws_byte_buf));
aws_byte_buf_init_copy_from_cursor(
result->error_response_body,
meta_request->allocator,
aws_byte_cursor_from_c_str(aws_http_status_text(response_status)));
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ add_net_test_case(test_s3_meta_request_default)
add_net_test_case(test_s3_put_object_fail_headers_callback)
add_net_test_case(test_s3_put_object_fail_body_callback)
add_net_test_case(test_s3_get_object_fail_headers_callback)
add_net_test_case(test_s3_get_object_fail_key_does_not_exist)
add_net_test_case(test_s3_get_object_fail_body_callback)
add_net_test_case(test_s3_default_fail_headers_callback)
add_net_test_case(test_s3_default_invoke_headers_callback_on_error)
Expand Down
27 changes: 27 additions & 0 deletions tests/s3_data_plane_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -4225,6 +4225,33 @@ static int s_test_s3_get_object_fail_headers_callback(struct aws_allocator *allo
return 0;
}

AWS_TEST_CASE(test_s3_get_object_fail_key_does_not_exist, s_test_s3_get_object_fail_key_does_not_exist)
static int s_test_s3_get_object_fail_key_does_not_exist(struct aws_allocator *allocator, void *ctx) {
(void)ctx;

struct aws_s3_meta_request_test_results meta_request_test_results;
aws_s3_meta_request_test_results_init(&meta_request_test_results, allocator);

struct aws_s3_tester_meta_request_options options = {
.allocator = allocator,
.meta_request_type = AWS_S3_META_REQUEST_TYPE_GET_OBJECT,
.validate_type = AWS_S3_TESTER_VALIDATE_TYPE_EXPECT_FAILURE,
.validate_get_response_checksum = true,
.get_options =
{
.object_path = aws_byte_cursor_from_c_str("/does_not_exist"),
},
};

ASSERT_SUCCESS(aws_s3_tester_send_meta_request_with_options(NULL, &options, &meta_request_test_results));
ASSERT_INT_EQUALS(meta_request_test_results.finished_error_code, AWS_ERROR_S3_INVALID_RESPONSE_STATUS);
ASSERT_CURSOR_VALUE_CSTRING_EQUALS(
aws_byte_cursor_from_buf(&meta_request_test_results.error_response_body), "Not Found");
aws_s3_meta_request_test_results_clean_up(&meta_request_test_results);

return 0;
}

AWS_TEST_CASE(test_s3_get_object_fail_body_callback, s_test_s3_get_object_fail_body_callback)
static int s_test_s3_get_object_fail_body_callback(struct aws_allocator *allocator, void *ctx) {
(void)ctx;
Expand Down

0 comments on commit d68aa80

Please sign in to comment.