Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose additional configuration options for Http connection manager #204

Merged
merged 34 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d8fcb1c
Exposes proxy options
waahm7 Aug 22, 2022
89cca7e
lint fix
waahm7 Aug 22, 2022
4feb631
Fix comments
waahm7 Aug 22, 2022
cbf8f52
Move proxy option to meta request options
waahm7 Aug 24, 2022
4685e9d
remove proxy options from client
waahm7 Aug 24, 2022
2c2fddb
Expose proxy_ev_settings
waahm7 Aug 25, 2022
4cabcb3
fix test
waahm7 Aug 25, 2022
b4c1c15
Fix struct
waahm7 Aug 25, 2022
701b721
Expose keep alive & connect timeout
waahm7 Aug 25, 2022
78b7939
Adds proxy config in S3 Client
waahm7 Aug 28, 2022
f0ce0c1
Adds proxy environment, connect_timeout, and tcp keep alive options t…
waahm7 Aug 28, 2022
3487405
Deep copy proxy ev setting and destroy.
waahm7 Aug 28, 2022
756ac86
Fix const proxy environment tls config
waahm7 Aug 28, 2022
c711e75
Fix todos
waahm7 Aug 28, 2022
6951cc8
updates comment
waahm7 Aug 29, 2022
5232a37
Fix proxy ev settings allocation and clean up
waahm7 Aug 29, 2022
4fca7d3
Fix memory management issues
waahm7 Aug 29, 2022
15b1c90
Minor improvement
waahm7 Aug 29, 2022
fc91d20
Updates include proxy.h
waahm7 Aug 29, 2022
3e2e323
Fix comment
waahm7 Aug 29, 2022
7784a72
improve comment
waahm7 Aug 29, 2022
9134dd9
Expose monitoring options
waahm7 Aug 29, 2022
866e11b
Adds test for monitoring options and proxy ev settings
waahm7 Aug 29, 2022
0e199e8
Adds test for monitoring options and proxy ev setting override
waahm7 Aug 29, 2022
752d47b
Update proxy ev setting test
waahm7 Aug 29, 2022
072f0da
Adds tcp keep alive override test
waahm7 Aug 29, 2022
2341407
lint fix
waahm7 Aug 29, 2022
58caf03
Use Keep Alive pointer
waahm7 Aug 29, 2022
014494c
Fix tests
waahm7 Aug 29, 2022
5635f1d
Fix lint
waahm7 Aug 29, 2022
22e3ac5
Removes hard coded default value
waahm7 Aug 30, 2022
acbd85c
Updates comment
waahm7 Aug 30, 2022
0913ce7
Update keep alive comment
waahm7 Aug 30, 2022
fee5621
Merge branch 'main' into expose-proxy-config
waahm7 Sep 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions include/aws/s3/private/s3_client_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include <aws/common/mutex.h>
#include <aws/common/ref_count.h>
#include <aws/common/task_scheduler.h>
#include <aws/http/connection.h>
#include <aws/http/connection_manager.h>
#include <aws/http/proxy.h>
waahm7 marked this conversation as resolved.
Show resolved Hide resolved

/* TODO automate this value in the future to prevent it from becoming out-of-sync. */
#define AWS_S3_CLIENT_VERSION "0.1.x"
Expand Down Expand Up @@ -58,6 +60,40 @@ struct aws_s3_endpoint_options {

/* HTTP port override. If zero, determine port based on TLS context */
uint16_t port;

/**
* Optional.
* Proxy configuration for http connection.
waahm7 marked this conversation as resolved.
Show resolved Hide resolved
*/
struct aws_http_proxy_config *proxy_config;

/**
* Optional.
* Configuration for fetching proxy configuration from environment.
* By Default proxy_ev_settings.aws_http_proxy_env_var_type is set to AWS_HPEV_ENABLE which means read proxy
* configuration from environment.
* Only works when proxy_config is not set. If both are set, configuration from proxy_config is used.
*/
struct proxy_env_var_settings *proxy_ev_settings;

/**
* Optional.
* If set to 0, default value is used.
*/
uint32_t connect_timeout_ms;
waahm7 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Optional.
* Set keepalive to periodically transmit messages for detecting a disconnected peer.
*/
struct aws_s3_tcp_keep_alive_options *tcp_keep_alive_options;

/**
* Optional.
* Configuration options for connection monitoring.
* If the transfer speed falls below the specified minimum_throughput_bytes_per_second, the operation is aborted.
*/
struct aws_http_connection_monitoring_options *monitoring_options;
};

struct aws_s3_endpoint {
Expand Down Expand Up @@ -179,6 +215,43 @@ struct aws_s3_client {
/* Retry strategy used for scheduling request retries. */
struct aws_retry_strategy *retry_strategy;

/**
* Optional.
* Proxy configuration for http connection.
*/
struct aws_http_proxy_config *proxy_config;

/**
* Optional.
* Configuration for fetching proxy configuration from environment.
* By Default proxy_ev_settings.aws_http_proxy_env_var_type is set to AWS_HPEV_ENABLE which means read proxy
* configuration from environment.
* Only works when proxy_config is not set. If both are set, configuration from proxy_config is used.
*/
struct proxy_env_var_settings *proxy_ev_settings;

/**
* Optional.
* If set to 0, default value is used.
*/
uint32_t connect_timeout_ms;

/**
* Optional.
* Set keepalive to periodically transmit messages for detecting a disconnected peer.
*/
struct aws_s3_tcp_keep_alive_options *tcp_keep_alive_options;

/**
* Optional.
* Configuration options for connection monitoring.
* If the transfer speed falls below the specified minimum_throughput_bytes_per_second, the operation is aborted.
*/
struct aws_http_connection_monitoring_options *monitoring_options;

/* tls options from proxy environment settings. */
struct aws_tls_connection_options *proxy_ev_tls_options;

/* Shutdown callbacks to notify when the client is completely cleaned up. */
aws_s3_client_shutdown_complete_callback_fn *shutdown_callback;
void *shutdown_callback_user_data;
Expand Down
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 @@ -51,7 +51,7 @@ struct aws_s3_prepare_request_payload {
};

struct aws_s3_meta_request_vtable {
/* Update the meta request. out_request is required to be non-null. Returns true if there is there is any work in
/* Update the meta request. out_request is required to be non-null. Returns true if there is any work in
* progress, false if there is not. */
bool (*update)(struct aws_s3_meta_request *meta_request, uint32_t flags, struct aws_s3_request **out_request);

Expand Down
50 changes: 48 additions & 2 deletions include/aws/s3/s3_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
* SPDX-License-Identifier: Apache-2.0.
*/

#include <aws/auth/signing_config.h>
#include <aws/io/retry_strategy.h>
#include <aws/s3/s3.h>

#include <aws/auth/signing_config.h>

struct aws_allocator;

struct aws_http_stream;
Expand Down Expand Up @@ -150,6 +149,19 @@ enum aws_s3_checksum_algorithm {
AWS_SCA_COUNT,
};

/* Keepalive properties are TCP only.
* If interval or timeout are zero, then default values are used.
*/
struct aws_s3_tcp_keep_alive_options {
waahm7 marked this conversation as resolved.
Show resolved Hide resolved

uint16_t keep_alive_interval_sec;
uint16_t keep_alive_timeout_sec;

/* If set, sets the number of keep alive probes allowed to fail before the connection is considered
* lost. If zero OS defaults are used. On Windows, this option is meaningless until Windows 10 1703.*/
uint16_t keep_alive_max_failed_probes;
};

/* Options for a new client. */
struct aws_s3_client_config {

Expand Down Expand Up @@ -200,6 +212,40 @@ struct aws_s3_client_config {
/* Callback and associated user data for when the client has completed its shutdown process. */
aws_s3_client_shutdown_complete_callback_fn *shutdown_callback;
void *shutdown_callback_user_data;

/**
* Optional.
* Proxy configuration for http connection.
*/
struct aws_http_proxy_options *proxy_options;
waahm7 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Optional.
* Configuration for fetching proxy configuration from environment.
* By Default proxy_ev_settings.aws_http_proxy_env_var_type is set to AWS_HPEV_ENABLE which means read proxy
* configuration from environment.
* Only works when proxy_options is not set. If both are set, configuration from proxy_options is used.
*/
struct proxy_env_var_settings *proxy_ev_settings;

/**
* Optional.
* If set to 0, default value is used.
*/
uint32_t connect_timeout_ms;

/**
* Optional.
* Set keepalive to periodically transmit messages for detecting a disconnected peer.
*/
struct aws_s3_tcp_keep_alive_options *tcp_keep_alive_options;

/**
* Optional.
* Configuration options for connection monitoring.
* If the transfer speed falls below the specified minimum_throughput_bytes_per_second, the operation is aborted.
*/
struct aws_http_connection_monitoring_options *monitoring_options;
};

/* Options for a new meta request, ie, file transfer that will be handled by the high performance client. */
Expand Down
2 changes: 1 addition & 1 deletion source/s3_auto_ranged_get.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static bool s_s3_auto_ranged_get_update(
{
aws_s3_meta_request_lock_synced_data(meta_request);

/* If nothing has set the the "finish result" then this meta request is still in progress and we can potentially
/* If nothing has set the "finish result" then this meta request is still in progress, and we can potentially
* send additional requests. */
if (!aws_s3_meta_request_has_finish_result_synced(meta_request)) {

Expand Down
63 changes: 61 additions & 2 deletions source/s3_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,37 @@ struct aws_s3_client *aws_s3_client_new(
*((size_t *)&client_config->max_part_size) = client_config->part_size;
}

if (client_config->proxy_options) {
client->proxy_config = aws_http_proxy_config_new_from_proxy_options(allocator, client_config->proxy_options);
if (client->proxy_config == NULL) {
goto on_error;
}
}
Comment on lines +307 to +312
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am unable to write a test for the proxy_config override. As the struct proxy_config implementation detail is private in the aws-c-http repo, I can't access its members to assert.

client->connect_timeout_ms = client_config->connect_timeout_ms;
if (client_config->proxy_ev_settings) {
client->proxy_ev_settings = aws_mem_calloc(allocator, 1, sizeof(struct proxy_env_var_settings));
*client->proxy_ev_settings = *client_config->proxy_ev_settings;

if (client_config->proxy_ev_settings->tls_options) {
client->proxy_ev_tls_options = aws_mem_calloc(allocator, 1, sizeof(struct aws_tls_connection_options));
if (aws_tls_connection_options_copy(client->proxy_ev_tls_options, client->proxy_ev_settings->tls_options)) {
goto on_error;
}
client->proxy_ev_settings->tls_options = client->proxy_ev_tls_options;
}
Comment on lines +318 to +324
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way to deep copy proxy_ev_settings->tls_options? The problem is that in proxy_ev_settings, tls_options is declared as const. So if I just use that directly instead of using client->proxy_ev_tls_options, I get a bunch of warnings about passing const tls_options to other functions which expect a non-const object like aws_mem_release.

}

if (client_config->tcp_keep_alive_options) {
client->tcp_keep_alive_options = aws_mem_calloc(allocator, 1, sizeof(struct aws_s3_tcp_keep_alive_options));
*client->tcp_keep_alive_options = *client_config->tcp_keep_alive_options;
}

if (client_config->monitoring_options) {
client->monitoring_options =
aws_mem_calloc(allocator, 1, sizeof(struct aws_http_connection_monitoring_options));
*client->monitoring_options = *client_config->monitoring_options;
}

if (client_config->tls_mode == AWS_MR_TLS_ENABLED) {
client->tls_connection_options =
aws_mem_calloc(client->allocator, 1, sizeof(struct aws_tls_connection_options));
Expand Down Expand Up @@ -421,6 +452,18 @@ struct aws_s3_client *aws_s3_client_new(
aws_mem_release(client->allocator, client->tls_connection_options);
client->tls_connection_options = NULL;
}
if (client->proxy_config) {
aws_http_proxy_config_destroy(client->proxy_config);
}
if (client->proxy_ev_tls_options) {
aws_tls_connection_options_clean_up(client->proxy_ev_tls_options);
aws_mem_release(client->allocator, client->proxy_ev_tls_options);
client->proxy_ev_settings->tls_options = NULL;
}
aws_mem_release(client->allocator, client->proxy_ev_settings);
aws_mem_release(client->allocator, client->monitoring_options);
aws_mem_release(client->allocator, client->tcp_keep_alive_options);

aws_event_loop_group_release(client->client_bootstrap->event_loop_group);
aws_client_bootstrap_release(client->client_bootstrap);
aws_mutex_clean_up(&client->synced_data.lock);
Expand Down Expand Up @@ -495,6 +538,19 @@ static void s_s3_client_finish_destroy_default(struct aws_s3_client *client) {
client->tls_connection_options = NULL;
}

if (client->proxy_config) {
aws_http_proxy_config_destroy(client->proxy_config);
}

if (client->proxy_ev_tls_options) {
aws_tls_connection_options_clean_up(client->proxy_ev_tls_options);
aws_mem_release(client->allocator, client->proxy_ev_tls_options);
client->proxy_ev_settings->tls_options = NULL;
}
aws_mem_release(client->allocator, client->proxy_ev_settings);
aws_mem_release(client->allocator, client->monitoring_options);
aws_mem_release(client->allocator, client->tcp_keep_alive_options);

aws_mutex_clean_up(&client->synced_data.lock);

AWS_ASSERT(aws_linked_list_empty(&client->synced_data.pending_meta_request_work));
Expand Down Expand Up @@ -667,7 +723,6 @@ struct aws_s3_meta_request *aws_s3_client_make_meta_request(
struct aws_hash_element *endpoint_hash_element = NULL;

int was_created = 0;

if (aws_hash_table_create(
&client->synced_data.endpoints, endpoint_host_name, &endpoint_hash_element, &was_created)) {
error_occurred = true;
Expand All @@ -684,7 +739,11 @@ struct aws_s3_meta_request *aws_s3_client_make_meta_request(
.user_data = client,
.max_connections = aws_s3_client_get_max_active_connections(client, NULL),
.port = port,
};
.proxy_config = client->proxy_config,
.proxy_ev_settings = client->proxy_ev_settings,
.connect_timeout_ms = client->connect_timeout_ms,
.tcp_keep_alive_options = client->tcp_keep_alive_options,
.monitoring_options = client->monitoring_options};

endpoint = aws_s3_endpoint_new(client->allocator, &endpoint_options);

Expand Down
51 changes: 42 additions & 9 deletions source/s3_endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <aws/common/system_info.h>
#include <aws/http/connection.h>
#include <aws/http/connection_manager.h>
#include <aws/http/proxy.h>
#include <aws/http/request_response.h>
#include <aws/io/channel_bootstrap.h>
#include <aws/io/event_loop.h>
Expand Down Expand Up @@ -51,7 +50,12 @@ static struct aws_http_connection_manager *s_s3_endpoint_create_http_connection_
struct aws_client_bootstrap *client_bootstrap,
const struct aws_tls_connection_options *tls_connection_options,
uint32_t max_connections,
uint16_t port);
uint16_t port,
const struct aws_http_proxy_config *proxy_config,
const struct proxy_env_var_settings *proxy_ev_settings,
uint32_t connect_timeout_ms,
const struct aws_s3_tcp_keep_alive_options *tcp_keep_alive_options,
const struct aws_http_connection_monitoring_options *monitoring_options);

static void s_s3_endpoint_http_connection_manager_shutdown_callback(void *user_data);

Expand Down Expand Up @@ -98,7 +102,12 @@ struct aws_s3_endpoint *aws_s3_endpoint_new(
options->client_bootstrap,
options->tls_connection_options,
options->max_connections,
options->port);
options->port,
options->proxy_config,
options->proxy_ev_settings,
options->connect_timeout_ms,
options->tcp_keep_alive_options,
options->monitoring_options);

if (endpoint->http_connection_manager == NULL) {
goto error_cleanup;
Expand All @@ -124,7 +133,13 @@ static struct aws_http_connection_manager *s_s3_endpoint_create_http_connection_
struct aws_client_bootstrap *client_bootstrap,
const struct aws_tls_connection_options *tls_connection_options,
uint32_t max_connections,
uint16_t port) {
uint16_t port,
const struct aws_http_proxy_config *proxy_config,
const struct proxy_env_var_settings *proxy_ev_settings,
uint32_t connect_timeout_ms,
const struct aws_s3_tcp_keep_alive_options *tcp_keep_alive_options,
const struct aws_http_connection_monitoring_options *monitoring_options) {

AWS_PRECONDITION(endpoint);
AWS_PRECONDITION(client_bootstrap);
AWS_PRECONDITION(host_name);
Expand All @@ -136,11 +151,20 @@ static struct aws_http_connection_manager *s_s3_endpoint_create_http_connection_
AWS_ZERO_STRUCT(socket_options);
socket_options.type = AWS_SOCKET_STREAM;
socket_options.domain = AWS_SOCKET_IPV4;
socket_options.connect_timeout_ms = s_connection_timeout_ms;
struct proxy_env_var_settings proxy_ev_settings;
AWS_ZERO_STRUCT(proxy_ev_settings);
socket_options.connect_timeout_ms = connect_timeout_ms == 0 ? s_connection_timeout_ms : connect_timeout_ms;
if (tcp_keep_alive_options != NULL) {
socket_options.keepalive = true;
socket_options.keep_alive_interval_sec = tcp_keep_alive_options->keep_alive_interval_sec;
socket_options.keep_alive_timeout_sec = tcp_keep_alive_options->keep_alive_timeout_sec;
socket_options.keep_alive_max_failed_probes = tcp_keep_alive_options->keep_alive_max_failed_probes;
}
struct proxy_env_var_settings proxy_ev_settings_default;
/* Turn on envrionment variable for proxy by default */
proxy_ev_settings.env_var_type = AWS_HPEV_ENABLE;
if (proxy_ev_settings == NULL) {
AWS_ZERO_STRUCT(proxy_ev_settings_default);
proxy_ev_settings_default.env_var_type = AWS_HPEV_ENABLE;
proxy_ev_settings = &proxy_ev_settings_default;
}

struct aws_http_connection_manager_options manager_options;
AWS_ZERO_STRUCT(manager_options);
Expand All @@ -151,7 +175,16 @@ static struct aws_http_connection_manager *s_s3_endpoint_create_http_connection_
manager_options.max_connections = max_connections;
manager_options.shutdown_complete_callback = s_s3_endpoint_http_connection_manager_shutdown_callback;
manager_options.shutdown_complete_user_data = endpoint;
manager_options.proxy_ev_settings = &proxy_ev_settings;
manager_options.proxy_ev_settings = proxy_ev_settings;
if (monitoring_options != NULL) {
manager_options.monitoring_options = monitoring_options;
}

struct aws_http_proxy_options proxy_options;
if (proxy_config != NULL) {
aws_http_proxy_options_init_from_config(&proxy_options, proxy_config);
manager_options.proxy_options = &proxy_options;
}

struct aws_tls_connection_options *manager_tls_options = NULL;

Expand Down
Loading