Skip to content

Commit 69edc65

Browse files
authored
Proxy envrionment variable support (#333)
- Add support for setting up proxy from environment variable and integration test for proxy
1 parent 72c7241 commit 69edc65

File tree

13 files changed

+982
-398
lines changed

13 files changed

+982
-398
lines changed

.builder/action/aws-c-http-test.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
PROXY_SETUP=/tmp/setup_proxy_test_env.sh
2+
if [ -f "$PROXY_SETUP" ]; then
3+
source $PROXY_SETUP
4+
export AWS_PROXY_NO_VERIFY_PEER=on
5+
echo "setting proxy integration test envrionment"
6+
fi
7+
8+
cd ./build/aws-c-http/
9+
ctest --output-on-failure

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ if (POLICY CMP0069)
55
cmake_policy(SET CMP0069 NEW) # Enable LTO/IPO if available in the compiler, see AwsCFlags
66
endif()
77

8-
option(ENABLE_PROXY_INTEGRATION_TESTS "Whether to run the proxy integration tests that rely on a proxy server installed and running locally" OFF)
8+
option(ENABLE_PROXY_INTEGRATION_TESTS "Whether to run the proxy integration tests that rely on pre-configured proxy" OFF)
99

1010
if (DEFINED CMAKE_PREFIX_PATH)
1111
file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH)

builder.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
{ "name": "aws-c-auth" }
1515
],
1616
"test_steps": [
17-
"test",
17+
["bash", "{project_dir}/.builder/action/aws-c-http-test.sh"],
1818
["{python}", "{project_dir}/integration-testing/http_client_test.py", "{install_dir}/bin/elasticurl{exe}"]
1919
]
2020
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
version: 0.2
2+
#this build spec assumes the manylinux1 image for pypi
3+
#additional packages we installed: cmake 3.5, libcrypto 1.1.0j, gcc 4.8.4
4+
phases:
5+
install:
6+
commands:
7+
- add-apt-repository ppa:ubuntu-toolchain-r/test
8+
- apt-get update -y
9+
- apt-get install gcc-7 cmake ninja-build python3 -y
10+
pre_build:
11+
commands:
12+
- export CC=gcc-7
13+
- export BUILDER_VERSION=v0.8.27
14+
- export BUILDER_SOURCE=releases
15+
- export BUILDER_HOST=https://d19elf31gohf1l.cloudfront.net
16+
build:
17+
commands:
18+
- 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
20+
- chmod a+xr /tmp/setup_proxy_test_env.sh
21+
- python3 -c "from urllib.request import urlretrieve; urlretrieve('$BUILDER_HOST/$BUILDER_SOURCE/$BUILDER_VERSION/builder.pyz', 'builder.pyz')"
22+
- python3 builder.pyz build -p aws-c-http --cmake-extra=-DENABLE_PROXY_INTEGRATION_TESTS=ON
23+
post_build:
24+
commands:
25+
- echo Build completed on `date`

include/aws/http/connection.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <aws/http/http.h>
10+
#include <aws/http/proxy.h>
1011

1112
struct aws_client_bootstrap;
1213
struct aws_socket_options;
@@ -270,6 +271,13 @@ struct aws_http_client_connection_options {
270271
*/
271272
const struct aws_http_proxy_options *proxy_options;
272273

274+
/*
275+
* Optional.
276+
* Configuration for using proxy from environment variable.
277+
* Only works when proxy_options is not set.
278+
*/
279+
const struct proxy_env_var_settings *proxy_ev_settings;
280+
273281
/**
274282
* Optional
275283
* Configuration options related to connection health monitoring

include/aws/http/connection_manager.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <aws/http/http.h>
10+
#include <aws/http/proxy.h>
1011

1112
#include <aws/common/byte_buf.h>
1213

@@ -37,10 +38,18 @@ struct aws_http_connection_manager_options {
3738
size_t initial_window_size;
3839
const struct aws_socket_options *socket_options;
3940
const struct aws_tls_connection_options *tls_connection_options;
40-
const struct aws_http_proxy_options *proxy_options;
4141
const struct aws_http_connection_monitoring_options *monitoring_options;
4242
struct aws_byte_cursor host;
4343
uint16_t port;
44+
/* Proxy configuration for http connection */
45+
const struct aws_http_proxy_options *proxy_options;
46+
47+
/*
48+
* Optional.
49+
* Configuration for using proxy from environment variable.
50+
* Only works when proxy_options is not set.
51+
*/
52+
const struct proxy_env_var_settings *proxy_ev_settings;
4453

4554
/*
4655
* Maximum number of connections this manager is allowed to contain

include/aws/http/proxy.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ enum aws_http_proxy_authentication_type {
3131
AWS_HPAT_BASIC,
3232
};
3333

34+
enum aws_http_proxy_env_var_type {
35+
/**
36+
* Default.
37+
* Disable reading from environment variable for proxy.
38+
*/
39+
AWS_HPEV_DISABLE = 0,
40+
/**
41+
* Enable get proxy URL from environment variable, when the manual proxy options of connection manager is not set.
42+
* env HTTPS_PROXY/https_proxy will be checked when the main connection use tls.
43+
* env HTTP_PROXY/http_proxy will be checked when the main connection NOT use tls.
44+
* The lower case version has precedence.
45+
*/
46+
AWS_HPEV_ENABLE,
47+
};
48+
3449
/**
3550
* Supported proxy connection types
3651
*/
@@ -56,6 +71,27 @@ enum aws_http_proxy_connection_type {
5671
AWS_HPCT_HTTP_TUNNEL,
5772
};
5873

74+
/*
75+
* Configuration for using proxy from environment variable.
76+
* Zero out as default settings.
77+
*/
78+
struct proxy_env_var_settings {
79+
enum aws_http_proxy_env_var_type env_var_type;
80+
/*
81+
* Optional.
82+
* If not set:
83+
* If tls options are provided (for the main connection) use tunnel proxy type
84+
* If tls options are not provided (for the main connection) use forward proxy type
85+
*/
86+
enum aws_http_proxy_connection_type connection_type;
87+
/*
88+
* Optional.
89+
* If not set, a default tls option will be created. when https used for Local to proxy connection.
90+
* Must be distinct from the the tls_connection_options from aws_http_connection_manager_options
91+
*/
92+
const struct aws_tls_connection_options *tls_options;
93+
};
94+
5995
struct aws_http_proxy_strategy;
6096

6197
/**
@@ -457,6 +493,19 @@ struct aws_http_proxy_config *aws_http_proxy_config_new_tunneling_from_proxy_opt
457493
struct aws_allocator *allocator,
458494
const struct aws_http_proxy_options *options);
459495

496+
/**
497+
* Create a persistent proxy configuration from non-persistent proxy options.
498+
* Legacy connection type of proxy options will be rejected.
499+
*
500+
* @param allocator memory allocator to use
501+
* @param options http proxy options to source proxy configuration from
502+
* @return
503+
*/
504+
AWS_HTTP_API
505+
struct aws_http_proxy_config *aws_http_proxy_config_new_from_proxy_options(
506+
struct aws_allocator *allocator,
507+
const struct aws_http_proxy_options *options);
508+
460509
/**
461510
* Clones an existing proxy configuration. A refactor could remove this (do a "move" between the old and new user
462511
* data in the one spot it's used) but that should wait until we have better test cases for the logic where this

source/connection.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,12 @@ int aws_http_client_connect(const struct aws_http_client_connection_options *opt
11471147
if (options->proxy_options != NULL) {
11481148
return aws_http_client_connect_via_proxy(options);
11491149
} else {
1150-
return aws_http_client_connect_internal(options, NULL);
1150+
if (!options->proxy_ev_settings || options->proxy_ev_settings->env_var_type != AWS_HPEV_ENABLE) {
1151+
return aws_http_client_connect_internal(options, NULL);
1152+
} else {
1153+
/* Proxy through envrionment variable is enabled */
1154+
return aws_http_client_connect_via_proxy(options);
1155+
}
11511156
}
11521157
}
11531158

source/connection_manager.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <aws/io/logging.h>
1717
#include <aws/io/socket.h>
1818
#include <aws/io/tls_channel_handler.h>
19+
#include <aws/io/uri.h>
1920

2021
#include <aws/common/clock.h>
2122
#include <aws/common/hash_table.h>
@@ -209,6 +210,8 @@ struct aws_http_connection_manager {
209210
struct aws_http_proxy_config *proxy_config;
210211
struct aws_http_connection_monitoring_options monitoring_options;
211212
struct aws_string *host;
213+
struct proxy_env_var_settings proxy_ev_settings;
214+
struct aws_tls_connection_options *proxy_ev_tls_options;
212215
uint16_t port;
213216

214217
/*
@@ -632,7 +635,10 @@ static void s_aws_http_connection_manager_finish_destroy(struct aws_http_connect
632635
aws_tls_connection_options_clean_up(manager->tls_connection_options);
633636
aws_mem_release(manager->allocator, manager->tls_connection_options);
634637
}
635-
638+
if (manager->proxy_ev_tls_options) {
639+
aws_tls_connection_options_clean_up(manager->proxy_ev_tls_options);
640+
aws_mem_release(manager->allocator, manager->proxy_ev_tls_options);
641+
}
636642
if (manager->proxy_config) {
637643
aws_http_proxy_config_destroy(manager->proxy_config);
638644
}
@@ -806,7 +812,6 @@ struct aws_http_connection_manager *aws_http_connection_manager_new(
806812
goto on_error;
807813
}
808814
}
809-
810815
if (options->proxy_options) {
811816
manager->proxy_config = aws_http_proxy_config_new_from_manager_options(allocator, options);
812817
if (manager->proxy_config == NULL) {
@@ -830,7 +835,16 @@ struct aws_http_connection_manager *aws_http_connection_manager_new(
830835
manager->shutdown_complete_user_data = options->shutdown_complete_user_data;
831836
manager->enable_read_back_pressure = options->enable_read_back_pressure;
832837
manager->max_connection_idle_in_milliseconds = options->max_connection_idle_in_milliseconds;
833-
838+
if (options->proxy_ev_settings) {
839+
manager->proxy_ev_settings = *options->proxy_ev_settings;
840+
}
841+
if (manager->proxy_ev_settings.tls_options) {
842+
manager->proxy_ev_tls_options = aws_mem_calloc(allocator, 1, sizeof(struct aws_tls_connection_options));
843+
if (aws_tls_connection_options_copy(manager->proxy_ev_tls_options, manager->proxy_ev_settings.tls_options)) {
844+
goto on_error;
845+
}
846+
manager->proxy_ev_settings.tls_options = manager->proxy_ev_tls_options;
847+
}
834848
s_schedule_connection_culling(manager);
835849

836850
AWS_LOGF_INFO(AWS_LS_HTTP_CONNECTION_MANAGER, "id=%p: Successfully created", (void *)manager);
@@ -907,6 +921,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti
907921
options.on_setup = s_aws_http_connection_manager_on_connection_setup;
908922
options.on_shutdown = s_aws_http_connection_manager_on_connection_shutdown;
909923
options.manual_window_management = manager->enable_read_back_pressure;
924+
options.proxy_ev_settings = &manager->proxy_ev_settings;
910925

911926
if (aws_http_connection_monitoring_options_is_valid(&manager->monitoring_options)) {
912927
options.monitoring_options = &manager->monitoring_options;

0 commit comments

Comments
 (0)