Skip to content

Commit

Permalink
Bring back request_type -> operation_name function
Browse files Browse the repository at this point in the history
  • Loading branch information
graebm committed Nov 22, 2023
1 parent 570975e commit e03689e
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 15 deletions.
3 changes: 1 addition & 2 deletions include/aws/s3/private/s3_default_meta_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct aws_s3_meta_request_default {

size_t content_length;

/* Actual type for the single request (AWS_S3_REQUEST_TYPE_DEFAULT if unknown) */
/* Actual type for the single request (may be AWS_S3_REQUEST_TYPE_UNKNOWN) */
enum aws_s3_request_type request_type;

/* S3 operation name for the single request (NULL if unknown) */
Expand Down Expand Up @@ -48,7 +48,6 @@ struct aws_s3_meta_request *aws_s3_meta_request_default_new(
struct aws_allocator *allocator,
struct aws_s3_client *client,
enum aws_s3_request_type request_type,
const char *operation_name_override,
uint64_t content_length,
bool should_compute_content_md5,
const struct aws_s3_meta_request_options *options);
Expand Down
2 changes: 1 addition & 1 deletion include/aws/s3/private/s3_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ struct aws_s3_request {
/* TODO: this should be a union type to make it clear that this could be one of two enums for puts, and gets. */
int request_tag;

/* Actual S3 type for the single request (AWS_S3_REQUEST_TYPE_DEFAULT if unknown) */
/* Actual S3 type for the single request (may be AWS_S3_REQUEST_TYPE_UNKNOWN) */
enum aws_s3_request_type request_type;

/* S3 operation name for the single request (e.g. "CompleteMultipartUpload") (NULL if unknown) */
Expand Down
33 changes: 29 additions & 4 deletions include/aws/s3/s3_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,25 +85,39 @@ enum aws_s3_meta_request_type {
};

/**
* The type of S3 request made. Used by metrics.
* The type of a single S3 HTTP request. Used by metrics.
* A meta-request can make multiple S3 HTTP requests under the hood.
*
* For example, AWS_S3_META_REQUEST_TYPE_PUT_OBJECT for a large file will
* do multipart upload, resulting in 3+ HTTP requests:
* AWS_S3_REQUEST_TYPE_CREATE_MULTIPART_UPLOAD, one or more AWS_S3_REQUEST_TYPE_UPLOAD_PART,
* and finally AWS_S3_REQUEST_TYPE_COMPLETE_MULTIPART_UPLOAD.
*
* aws_s3_request_type_operation_name() returns the S3 operation name
* for types that map (e.g. AWS_S3_REQUEST_TYPE_HEAD_OBJECT -> "HeadObject"),
* or empty string for types that don't map (e.g. AWS_S3_REQUEST_TYPE_UNKNOWN -> "").
*/
enum aws_s3_request_type {
/* Same as the original HTTP request passed to aws_s3_meta_request_options */
AWS_S3_REQUEST_TYPE_DEFAULT,
/* The actual type of the single S3 HTTP request is unknown */
AWS_S3_REQUEST_TYPE_UNKNOWN,

/* S3 APIs */
AWS_S3_REQUEST_TYPE_HEAD_OBJECT,
AWS_S3_REQUEST_TYPE_GET_OBJECT,
AWS_S3_REQUEST_TYPE_LIST_PARTS,
AWS_S3_REQUEST_TYPE_PUT_OBJECT,
AWS_S3_REQUEST_TYPE_CREATE_MULTIPART_UPLOAD,
AWS_S3_REQUEST_TYPE_UPLOAD_PART,
AWS_S3_REQUEST_TYPE_ABORT_MULTIPART_UPLOAD,
AWS_S3_REQUEST_TYPE_COMPLETE_MULTIPART_UPLOAD,
AWS_S3_REQUEST_TYPE_UPLOAD_PART_COPY,
AWS_S3_REQUEST_TYPE_COPY_OBJECT,
AWS_S3_REQUEST_TYPE_PUT_OBJECT,

/* Max enum value */
AWS_S3_REQUEST_TYPE_MAX,

/** @deprecated Use AWS_S3_REQUEST_TYPE_UNKNOWN if the actual S3 HTTP request type is unknown */
AWS_S3_REQUEST_TYPE_DEFAULT = AWS_S3_REQUEST_TYPE_UNKNOWN,
};

/**
Expand Down Expand Up @@ -845,6 +859,17 @@ void aws_s3_init_default_signing_config(
const struct aws_byte_cursor region,
struct aws_credentials_provider *credentials_provider);

/**
* Return operation name for aws_s3_request_type,
* or empty string if the type doesn't map to an actual operation.
* For example:
* AWS_S3_REQUEST_TYPE_HEAD_OBJECT -> "HeadObject"
* AWS_S3_REQUEST_TYPE_UNKNOWN -> ""
* AWS_S3_REQUEST_TYPE_MAX -> ""
*/
AWS_S3_API
const char *aws_s3_request_type_operation_name(enum aws_s3_request_type type);

/**
* Add a reference, keeping this object alive.
* The reference must be released when you are done with it, or it's memory will never be cleaned up.
Expand Down
5 changes: 1 addition & 4 deletions source/s3_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,6 @@ static struct aws_s3_meta_request *s_s3_client_meta_request_factory_default(
client->allocator,
client,
AWS_S3_REQUEST_TYPE_GET_OBJECT,
"GetObject",
content_length,
false /*should_compute_content_md5*/,
options);
Expand Down Expand Up @@ -1100,7 +1099,6 @@ static struct aws_s3_meta_request *s_s3_client_meta_request_factory_default(
client->allocator,
client,
AWS_S3_REQUEST_TYPE_PUT_OBJECT,
"PutObject",
content_length,
client->compute_content_md5 == AWS_MR_CONTENT_MD5_ENABLED &&
!aws_http_headers_has(initial_message_headers, g_content_md5_header_name),
Expand Down Expand Up @@ -1150,8 +1148,7 @@ static struct aws_s3_meta_request *s_s3_client_meta_request_factory_default(
return aws_s3_meta_request_default_new(
client->allocator,
client,
AWS_S3_REQUEST_TYPE_DEFAULT,
NULL /*operation_name_override*/,
AWS_S3_REQUEST_TYPE_UNKNOWN,
content_length,
false /*should_compute_content_md5*/,
options);
Expand Down
13 changes: 9 additions & 4 deletions source/s3_default_meta_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ struct aws_s3_meta_request *aws_s3_meta_request_default_new(
struct aws_allocator *allocator,
struct aws_s3_client *client,
enum aws_s3_request_type request_type,
const char *operation_name_override,
uint64_t content_length,
bool should_compute_content_md5,
const struct aws_s3_meta_request_options *options) {
Expand Down Expand Up @@ -108,8 +107,14 @@ struct aws_s3_meta_request *aws_s3_meta_request_default_new(
meta_request_default->content_length = (size_t)content_length;
meta_request_default->request_type = request_type;

if (operation_name_override != NULL) {
meta_request_default->operation_name = aws_string_new_from_c_str(allocator, operation_name_override);
/* Try to get operation name.
* When internal aws-c-s3 code creates a default meta-request,
* a valid request_type is always passed in, and we can get its operation name.
* When external users create a default meta-request, they may have provided
* operation name in the options. */
const char *operation_name = aws_s3_request_type_operation_name(request_type);
if (operation_name[0] != '\0') {
meta_request_default->operation_name = aws_string_new_from_c_str(allocator, operation_name);
} else if (options->operation_name.len != 0) {
meta_request_default->operation_name = aws_string_new_from_cursor(allocator, &options->operation_name);
}
Expand Down Expand Up @@ -161,7 +166,7 @@ static bool s_s3_meta_request_default_update(
request = aws_s3_request_new(
meta_request,
0 /*request_tag*/,
AWS_S3_REQUEST_TYPE_DEFAULT,
meta_request_default->request_type,
meta_request_default->operation_name ? aws_string_c_str(meta_request_default->operation_name)
: NULL,
1 /*part_number*/,
Expand Down
27 changes: 27 additions & 0 deletions source/s3_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,33 @@ const struct aws_byte_cursor g_user_agent_header_product_name =
const uint32_t g_s3_max_num_upload_parts = 10000;
const size_t g_s3_min_upload_part_size = MB_TO_BYTES(5);

const char *aws_s3_request_type_operation_name(enum aws_s3_request_type type) {
switch (type) {
case AWS_S3_REQUEST_TYPE_HEAD_OBJECT:
return "HeadObject";
case AWS_S3_REQUEST_TYPE_GET_OBJECT:
return "GetObject";
case AWS_S3_REQUEST_TYPE_LIST_PARTS:
return "ListParts";
case AWS_S3_REQUEST_TYPE_CREATE_MULTIPART_UPLOAD:
return "CreateMultipartUpload";
case AWS_S3_REQUEST_TYPE_UPLOAD_PART:
return "UploadPart";
case AWS_S3_REQUEST_TYPE_ABORT_MULTIPART_UPLOAD:
return "AbortMultipartUpload";
case AWS_S3_REQUEST_TYPE_COMPLETE_MULTIPART_UPLOAD:
return "CompleteMultipartUpload";
case AWS_S3_REQUEST_TYPE_UPLOAD_PART_COPY:
return "UploadPartCopy";
case AWS_S3_REQUEST_TYPE_COPY_OBJECT:
return "CopyObject";
case AWS_S3_REQUEST_TYPE_PUT_OBJECT:
return "PutObject";
default:
return "";
}
}

void copy_http_headers(const struct aws_http_headers *src, struct aws_http_headers *dest) {
AWS_PRECONDITION(src);
AWS_PRECONDITION(dest);
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ add_net_test_case(test_s3_not_satisfiable_range)
add_net_test_case(test_s3_bad_endpoint)
add_net_test_case(test_s3_different_endpoints)

add_test_case(test_s3_request_type_operation_name)
add_test_case(test_s3_replace_quote_entities)
add_test_case(test_s3_strip_quotes)
add_test_case(test_s3_parse_content_range_response_header)
Expand Down
24 changes: 24 additions & 0 deletions tests/s3_util_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@
#include <inttypes.h>
#include <stdio.h>

AWS_TEST_CASE(test_s3_request_type_operation_name, s_test_s3_request_type_operation_name)
static int s_test_s3_request_type_operation_name(struct aws_allocator *allocator, void *ctx) {
(void)allocator;
(void)ctx;

/* sanity check */
ASSERT_STR_EQUALS("HeadObject", aws_s3_request_type_operation_name(AWS_S3_REQUEST_TYPE_HEAD_OBJECT));

/* check that all valid enums give back valid strings */
for (enum aws_s3_request_type type = AWS_S3_REQUEST_TYPE_UNKNOWN + 1; type < AWS_S3_REQUEST_TYPE_MAX; ++type) {
const char *operation_name = aws_s3_request_type_operation_name(type);
ASSERT_NOT_NULL(operation_name);
ASSERT_TRUE(strlen(operation_name) > 1);
}

/* check that invalid enums give back empty strings */
ASSERT_NOT_NULL(aws_s3_request_type_operation_name(AWS_S3_REQUEST_TYPE_UNKNOWN));
ASSERT_STR_EQUALS("", aws_s3_request_type_operation_name(AWS_S3_REQUEST_TYPE_UNKNOWN));
ASSERT_STR_EQUALS("", aws_s3_request_type_operation_name(AWS_S3_REQUEST_TYPE_MAX));
ASSERT_STR_EQUALS("", aws_s3_request_type_operation_name(-1));

return 0;
}

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

0 comments on commit e03689e

Please sign in to comment.