Skip to content

Commit 89429eb

Browse files
authored
Proxy h2 (#402)
- add support for using proxy to setup http/2 connection - right now only supports talking h1 with proxy and create the http/2 connection from the tunneling proxy. - Turns out google doesn't like `:authority` with `host`, I am totally okay with what ever the real world want. :) ### TODO: The `AWS_TEST_HTTPS_H2_PROXY_URL` now has a proxy host that can talk http/2 with client. Used apache server with mod_proxy_http2. You can simply use that host for the proxy option and update the tls of proxy options to have h2 in the alpn string to create the h2 connection with proxy. However, I don't know what's the expected behavior for client to talk to a h2 proxy host. **`curl` doesn't seem supporting it.** So, put it as TODO, but still have the host here incase we want to implement it in the future.
1 parent 8f07568 commit 89429eb

File tree

8 files changed

+208
-75
lines changed

8 files changed

+208
-75
lines changed

codebuild/linux-integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ phases:
1616
build:
1717
commands:
1818
- echo Build started on `date`
19-
- aws s3 cp s3://aws-crt-test-stuff/setup_proxy_test_env.sh /tmp/setup_proxy_test_env.sh
19+
- aws s3 cp s3://aws-crt-test-stuff/setup_proxy_test_env_h2.sh /tmp/setup_proxy_test_env.sh
2020
- chmod a+xr /tmp/setup_proxy_test_env.sh
2121
- python3 -c "from urllib.request import urlretrieve; urlretrieve('$BUILDER_HOST/$BUILDER_SOURCE/$BUILDER_VERSION/builder.pyz', 'builder.pyz')"
2222
- python3 builder.pyz build -p aws-c-http --cmake-extra=-DENABLE_PROXY_INTEGRATION_TESTS=ON

include/aws/http/private/proxy_impl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <aws/http/http.h>
1010

11+
#include <aws/common/hash_table.h>
1112
#include <aws/http/connection.h>
1213
#include <aws/http/proxy.h>
1314
#include <aws/http/status_code.h>
@@ -103,8 +104,11 @@ struct aws_http_proxy_user_data {
103104
struct aws_socket_options original_socket_options;
104105
bool original_manual_window_management;
105106
size_t original_initial_window_size;
107+
bool prior_knowledge_http2;
106108
struct aws_http1_connection_options original_http1_options;
107-
109+
struct aws_http2_connection_options
110+
original_http2_options; /* the resource within options are allocated with userdata */
111+
struct aws_hash_table alpn_string_map;
108112
/*
109113
* setup/shutdown callbacks. We enforce via fatal assert that either the http callbacks are supplied or
110114
* the channel callbacks are supplied but never both.

source/connection.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ static void s_client_bootstrap_on_channel_shutdown(
887887
aws_http_client_bootstrap_destroy(http_bootstrap);
888888
}
889889

890-
static int s_validate_http_client_connection_options(const struct aws_http_client_connection_options *options) {
890+
int s_validate_http_client_connection_options(const struct aws_http_client_connection_options *options) {
891891
if (options->self_size == 0) {
892892
AWS_LOGF_ERROR(AWS_LS_HTTP_CONNECTION, "static: Invalid connection options, self size not initialized");
893893
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
@@ -926,6 +926,11 @@ static int s_validate_http_client_connection_options(const struct aws_http_clien
926926
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
927927
}
928928

929+
if (options->prior_knowledge_http2 && options->tls_options) {
930+
AWS_LOGF_ERROR(AWS_LS_HTTP_CONNECTION, "static: HTTP/2 prior knowledge only works with cleartext TCP.");
931+
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
932+
}
933+
929934
return AWS_OP_SUCCESS;
930935
}
931936

@@ -964,6 +969,15 @@ int aws_http_alpn_map_init_copy(
964969
struct aws_allocator *allocator,
965970
struct aws_hash_table *dest,
966971
struct aws_hash_table *src) {
972+
if (!src) {
973+
AWS_ZERO_STRUCT(*dest);
974+
return AWS_OP_SUCCESS;
975+
}
976+
if (!src->p_impl) {
977+
AWS_ZERO_STRUCT(*dest);
978+
return AWS_OP_SUCCESS;
979+
}
980+
967981
if (aws_http_alpn_map_init(allocator, dest)) {
968982
return AWS_OP_ERR;
969983
}
@@ -998,11 +1012,6 @@ int aws_http_client_connect_internal(
9981012

9991013
/* make copy of options, and add defaults for missing optional structs */
10001014
struct aws_http_client_connection_options options = *orig_options;
1001-
if (options.prior_knowledge_http2 && options.tls_options) {
1002-
AWS_LOGF_ERROR(AWS_LS_HTTP_CONNECTION, "static: HTTP/2 prior knowledge only works with cleartext TCP.");
1003-
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
1004-
}
1005-
10061015
struct aws_http1_connection_options default_http1_options;
10071016
AWS_ZERO_STRUCT(default_http1_options);
10081017
if (options.http1_options == NULL) {
@@ -1030,17 +1039,15 @@ int aws_http_client_connect_internal(
10301039

10311040
struct aws_http2_setting *setting_array = NULL;
10321041
struct aws_hash_table *alpn_string_map = NULL;
1033-
if (!aws_mem_acquire_many(
1034-
options.allocator,
1035-
3,
1036-
&http_bootstrap,
1037-
sizeof(struct aws_http_client_bootstrap),
1038-
&setting_array,
1039-
options.http2_options->num_initial_settings * sizeof(struct aws_http2_setting),
1040-
&alpn_string_map,
1041-
sizeof(struct aws_hash_table))) {
1042-
goto error;
1043-
}
1042+
aws_mem_acquire_many(
1043+
options.allocator,
1044+
3,
1045+
&http_bootstrap,
1046+
sizeof(struct aws_http_client_bootstrap),
1047+
&setting_array,
1048+
options.http2_options->num_initial_settings * sizeof(struct aws_http2_setting),
1049+
&alpn_string_map,
1050+
sizeof(struct aws_hash_table));
10441051

10451052
AWS_ZERO_STRUCT(*http_bootstrap);
10461053

0 commit comments

Comments
 (0)