Skip to content

Commit

Permalink
UserAgent Updates (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
waahm7 authored Mar 22, 2024
1 parent e91577e commit efeb625
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 19 deletions.
2 changes: 1 addition & 1 deletion include/aws/s3/private/s3_platform_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ bool aws_s3_is_running_on_ec2_nitro(struct aws_s3_platform_info_loader *loader);
* @return byte_cursor containing the instance type. If this is empty, the instance type could not be determined.
*/
AWS_S3_API
struct aws_byte_cursor aws_s3_get_ec2_instance_type(struct aws_s3_platform_info_loader *loader);
struct aws_byte_cursor aws_s3_get_ec2_instance_type(struct aws_s3_platform_info_loader *loader, bool cached_only);

AWS_EXTERN_C_END

Expand Down
6 changes: 6 additions & 0 deletions include/aws/s3/private/s3_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ extern const struct aws_byte_cursor g_user_agent_header_name;
AWS_S3_API
extern const struct aws_byte_cursor g_user_agent_header_product_name;

AWS_S3_API
extern const struct aws_byte_cursor g_user_agent_header_platform;

AWS_S3_API
extern const struct aws_byte_cursor g_user_agent_header_unknown;

AWS_S3_API
extern const struct aws_byte_cursor g_acl_header_name;

Expand Down
7 changes: 7 additions & 0 deletions include/aws/s3/s3.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ void aws_s3_library_clean_up(void);
AWS_S3_API
const struct aws_s3_platform_info *aws_s3_get_current_platform_info(void);

/*
* Returns the ec2 instance_type for current platform if possible
* NOTE: THIS API IS EXPERIMENTAL AND UNSTABLE
*/
AWS_S3_API
struct aws_byte_cursor aws_s3_get_current_platform_ec2_intance_type(bool cached_only);

/*
* Retrieves a list of EC2 instance types with recommended configuration.
* Returns aws_array_list<aws_byte_cursor>. The caller is responsible for cleaning up the array list.
Expand Down
4 changes: 4 additions & 0 deletions source/s3.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ const struct aws_s3_platform_info *aws_s3_get_current_platform_info(void) {
return aws_s3_get_platform_info_for_current_environment(s_loader);
}

struct aws_byte_cursor aws_s3_get_current_platform_ec2_intance_type(bool cached_only) {
return aws_s3_get_ec2_instance_type(s_loader, cached_only);
}

struct aws_array_list aws_s3_get_platforms_with_recommended_config(void) {
return aws_s3_get_recommended_platforms(s_loader);
}
Expand Down
12 changes: 10 additions & 2 deletions source/s3_platform_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ struct aws_string *s_query_imds_for_instance_type(struct aws_allocator *allocato
return callback_info.instance_type;
}

struct aws_byte_cursor aws_s3_get_ec2_instance_type(struct aws_s3_platform_info_loader *loader) {
struct aws_byte_cursor aws_s3_get_ec2_instance_type(struct aws_s3_platform_info_loader *loader, bool cached_only) {
aws_mutex_lock(&loader->lock_data.lock);
struct aws_byte_cursor return_cur;
AWS_ZERO_STRUCT(return_cur);
Expand All @@ -499,6 +499,14 @@ struct aws_byte_cursor aws_s3_get_ec2_instance_type(struct aws_s3_platform_info_
aws_string_bytes(loader->lock_data.detected_instance_type));
goto return_instance_and_unlock;
}
if (cached_only) {
AWS_LOGF_TRACE(
AWS_LS_S3_CLIENT,
"id=%p: Instance type has not been cached. Returning without trying to determine instance type since "
"cached_only is set.",
(void *)loader);
goto return_instance_and_unlock;
}

AWS_LOGF_TRACE(
AWS_LS_S3_CLIENT,
Expand Down Expand Up @@ -556,7 +564,7 @@ struct aws_byte_cursor aws_s3_get_ec2_instance_type(struct aws_s3_platform_info_
const struct aws_s3_platform_info *aws_s3_get_platform_info_for_current_environment(
struct aws_s3_platform_info_loader *loader) {
/* getting the instance type will set it on the loader the first time if it can */
aws_s3_get_ec2_instance_type(loader);
aws_s3_get_ec2_instance_type(loader, false /*cached_only*/);
/* will never be mutated after the above call. */
return &loader->lock_data.current_env_platform_info;
}
Expand Down
23 changes: 16 additions & 7 deletions source/s3_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "aws/s3/private/s3_util.h"
#include "aws/s3/private/s3_client_impl.h"
#include "aws/s3/private/s3_meta_request_impl.h"
#include "aws/s3/private/s3_platform_info.h"
#include "aws/s3/private/s3_request.h"
#include <aws/auth/credentials.h>
#include <aws/common/clock.h>
Expand Down Expand Up @@ -66,6 +67,8 @@ const struct aws_byte_cursor g_delete_method = AWS_BYTE_CUR_INIT_FROM_STRING_LIT
const struct aws_byte_cursor g_user_agent_header_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("User-Agent");
const struct aws_byte_cursor g_user_agent_header_product_name =
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("CRTS3NativeClient");
const struct aws_byte_cursor g_user_agent_header_platform = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("platform");
const struct aws_byte_cursor g_user_agent_header_unknown = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("unknown");

const uint32_t g_s3_max_num_upload_parts = 10000;
const size_t g_s3_min_upload_part_size = MB_TO_BYTES(5);
Expand Down Expand Up @@ -352,9 +355,13 @@ void aws_s3_add_user_agent_header(struct aws_allocator *allocator, struct aws_ht

const struct aws_byte_cursor space_delimiter = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" ");
const struct aws_byte_cursor forward_slash = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/");

const size_t user_agent_product_version_length =
g_user_agent_header_product_name.len + forward_slash.len + g_s3_client_version.len;
struct aws_byte_cursor platform_cursor = aws_s3_get_current_platform_ec2_intance_type(true /* cached_only */);
if (!platform_cursor.len) {
platform_cursor = g_user_agent_header_unknown;
}
const size_t user_agent_length = g_user_agent_header_product_name.len + forward_slash.len +
g_s3_client_version.len + space_delimiter.len + g_user_agent_header_platform.len +
forward_slash.len + platform_cursor.len;

struct aws_http_headers *headers = aws_http_message_get_headers(message);
AWS_ASSERT(headers != NULL);
Expand All @@ -369,9 +376,7 @@ void aws_s3_add_user_agent_header(struct aws_allocator *allocator, struct aws_ht
/* If the header was found, then create a buffer with the total size we'll need, and append the current user
* agent header with a trailing space. */
aws_byte_buf_init(
&user_agent_buffer,
allocator,
current_user_agent_header.len + space_delimiter.len + user_agent_product_version_length);
&user_agent_buffer, allocator, current_user_agent_header.len + space_delimiter.len + user_agent_length);

aws_byte_buf_append_dynamic(&user_agent_buffer, &current_user_agent_header);

Expand All @@ -382,14 +387,18 @@ void aws_s3_add_user_agent_header(struct aws_allocator *allocator, struct aws_ht

/* If the header was not found, then create a buffer with just the size of the user agent string that is about
* to be appended to the buffer. */
aws_byte_buf_init(&user_agent_buffer, allocator, user_agent_product_version_length);
aws_byte_buf_init(&user_agent_buffer, allocator, user_agent_length);
}

/* Append the client's user-agent string. */
{
aws_byte_buf_append_dynamic(&user_agent_buffer, &g_user_agent_header_product_name);
aws_byte_buf_append_dynamic(&user_agent_buffer, &forward_slash);
aws_byte_buf_append_dynamic(&user_agent_buffer, &g_s3_client_version);
aws_byte_buf_append_dynamic(&user_agent_buffer, &space_delimiter);
aws_byte_buf_append_dynamic(&user_agent_buffer, &g_user_agent_header_platform);
aws_byte_buf_append_dynamic(&user_agent_buffer, &forward_slash);
aws_byte_buf_append_dynamic(&user_agent_buffer, &platform_cursor);
}

/* Apply the updated header. */
Expand Down
22 changes: 13 additions & 9 deletions tests/s3_data_plane_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -5253,12 +5253,16 @@ static int s_get_expected_user_agent(struct aws_allocator *allocator, struct aws
AWS_ASSERT(dest);

const struct aws_byte_cursor forward_slash = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/");
const struct aws_byte_cursor single_space = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" ");

ASSERT_SUCCESS(aws_byte_buf_init(dest, allocator, 32));
ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &g_user_agent_header_product_name));
ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &forward_slash));
ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &g_s3_client_version));

ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &single_space));
ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &g_user_agent_header_platform));
ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &forward_slash));
ASSERT_SUCCESS(aws_byte_buf_append_dynamic(dest, &g_user_agent_header_unknown));
return AWS_OP_SUCCESS;
}

Expand All @@ -5270,7 +5274,6 @@ static int s_test_add_user_agent_header(struct aws_allocator *allocator, void *c
AWS_ZERO_STRUCT(tester);
ASSERT_SUCCESS(aws_s3_tester_init(allocator, &tester));

const struct aws_byte_cursor forward_slash = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/");
const struct aws_byte_cursor single_space = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" ");

struct aws_byte_buf expected_user_agent_value_buf;
Expand All @@ -5290,8 +5293,8 @@ static int s_test_add_user_agent_header(struct aws_allocator *allocator, void *c

ASSERT_TRUE(headers != NULL);
ASSERT_SUCCESS(aws_http_headers_get(headers, g_user_agent_header_name, &user_agent_value));
ASSERT_TRUE(aws_byte_cursor_eq(&user_agent_value, &expected_user_agent_value));

ASSERT_BIN_ARRAYS_EQUALS(
user_agent_value.ptr, user_agent_value.len, expected_user_agent_value.ptr, expected_user_agent_value.len);
aws_http_message_release(message);
}

Expand All @@ -5303,10 +5306,7 @@ static int s_test_add_user_agent_header(struct aws_allocator *allocator, void *c
aws_byte_buf_init(&total_expected_user_agent_value_buf, allocator, 64);
aws_byte_buf_append_dynamic(&total_expected_user_agent_value_buf, &dummy_agent_header_value);
aws_byte_buf_append_dynamic(&total_expected_user_agent_value_buf, &single_space);

aws_byte_buf_append_dynamic(&total_expected_user_agent_value_buf, &g_user_agent_header_product_name);
aws_byte_buf_append_dynamic(&total_expected_user_agent_value_buf, &forward_slash);
aws_byte_buf_append_dynamic(&total_expected_user_agent_value_buf, &g_s3_client_version);
aws_byte_buf_append_dynamic(&total_expected_user_agent_value_buf, &expected_user_agent_value);

struct aws_byte_cursor total_expected_user_agent_value =
aws_byte_cursor_from_buf(&total_expected_user_agent_value_buf);
Expand All @@ -5323,7 +5323,11 @@ static int s_test_add_user_agent_header(struct aws_allocator *allocator, void *c
struct aws_byte_cursor user_agent_value;
AWS_ZERO_STRUCT(user_agent_value);
ASSERT_SUCCESS(aws_http_headers_get(headers, g_user_agent_header_name, &user_agent_value));
ASSERT_TRUE(aws_byte_cursor_eq(&user_agent_value, &total_expected_user_agent_value));
ASSERT_BIN_ARRAYS_EQUALS(
user_agent_value.ptr,
user_agent_value.len,
total_expected_user_agent_value.ptr,
total_expected_user_agent_value.len);
}

aws_byte_buf_clean_up(&total_expected_user_agent_value_buf);
Expand Down

0 comments on commit efeb625

Please sign in to comment.