Skip to content

Commit b652af1

Browse files
Proxyv2 (#306)
* Move all public proxy types to proxy.h * Add support for proxy strategies - polymorphic policies for proxy connection and authentication. Existing auth configuration still works (by injecting the appropriate strategy internally) but is deprecated. * Add backwards-compatible support for explicitly requesting tunneling vs. forwarding proxy connections. * Add support for synchronous ntlm and kerberos proxy authentication via callbacks to gather necessary tokens Co-authored-by: Abhishek Jain <61713632+ajainaus@users.noreply.github.com>
1 parent 7dc97ea commit b652af1

File tree

14 files changed

+3891
-418
lines changed

14 files changed

+3891
-418
lines changed

include/aws/http/connection.h

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -121,54 +121,6 @@ struct aws_http_connection_monitoring_options {
121121
uint32_t allowable_throughput_failure_interval_seconds;
122122
};
123123

124-
/**
125-
* Supported proxy authentication modes
126-
*/
127-
enum aws_http_proxy_authentication_type {
128-
AWS_HPAT_NONE = 0,
129-
AWS_HPAT_BASIC,
130-
};
131-
132-
/**
133-
* Options for http proxy server usage
134-
*/
135-
struct aws_http_proxy_options {
136-
137-
/**
138-
* Proxy host to connect to, in lieu of actual target
139-
*/
140-
struct aws_byte_cursor host;
141-
142-
/**
143-
* Port to make the proxy connection to
144-
*/
145-
uint16_t port;
146-
147-
/**
148-
* Optional.
149-
* TLS configuration for the Local <-> Proxy connection
150-
* Must be distinct from the the TLS options in the parent aws_http_connection_options struct
151-
*/
152-
const struct aws_tls_connection_options *tls_options;
153-
154-
/**
155-
* What type of proxy authentication to use, if any
156-
*/
157-
enum aws_http_proxy_authentication_type auth_type;
158-
159-
/**
160-
* Optional
161-
* User name to use for authentication, basic only
162-
*/
163-
struct aws_byte_cursor auth_username;
164-
165-
/**
166-
* Optional
167-
* Password to use for authentication, basic only
168-
*/
169-
struct aws_byte_cursor auth_password;
170-
};
171-
172124
/**
173125
* Options specific to HTTP/1.x connections.
174126
* Initialize with AWS_HTTP1_CONNECTION_OPTIONS_INIT to set default values.
@@ -482,6 +434,12 @@ enum aws_http_version aws_http_connection_get_version(const struct aws_http_conn
482434
AWS_HTTP_API
483435
struct aws_channel *aws_http_connection_get_channel(struct aws_http_connection *connection);
484436

437+
/**
438+
* Checks http proxy options for correctness
439+
*/
440+
AWS_HTTP_API
441+
int aws_http_options_validate_proxy_configuration(const struct aws_http_client_connection_options *options);
442+
485443
/**
486444
* Send a SETTINGS frame (HTTP/2 only).
487445
* SETTINGS will be applied locally when SETTINGS ACK is received from peer.

include/aws/http/http.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ enum aws_http_errors {
3636
AWS_ERROR_HTTP_CONNECTION_MANAGER_INVALID_STATE_FOR_ACQUIRE,
3737
AWS_ERROR_HTTP_CONNECTION_MANAGER_VENDED_CONNECTION_UNDERFLOW,
3838
AWS_ERROR_HTTP_SERVER_CLOSED,
39-
AWS_ERROR_HTTP_PROXY_TLS_CONNECT_FAILED,
39+
AWS_ERROR_HTTP_PROXY_CONNECT_FAILED,
4040
AWS_ERROR_HTTP_CONNECTION_MANAGER_SHUTTING_DOWN,
4141
AWS_ERROR_HTTP_CHANNEL_THROUGHPUT_FAILURE,
4242
AWS_ERROR_HTTP_PROTOCOL_ERROR,
@@ -46,6 +46,9 @@ enum aws_http_errors {
4646
AWS_ERROR_HTTP_RST_STREAM_SENT,
4747
AWS_ERROR_HTTP_STREAM_NOT_ACTIVATED,
4848
AWS_ERROR_HTTP_STREAM_HAS_COMPLETED,
49+
AWS_ERROR_HTTP_PROXY_STRATEGY_NTLM_CHALLENGE_TOKEN_MISSING,
50+
AWS_ERROR_HTTP_PROXY_STRATEGY_TOKEN_RETRIEVAL_FAILURE,
51+
AWS_ERROR_HTTP_PROXY_CONNECT_FAILED_RETRYABLE,
4952

5053
AWS_ERROR_HTTP_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_HTTP_PACKAGE_ID)
5154
};
@@ -79,6 +82,7 @@ enum aws_http_log_subject {
7982
AWS_LS_HTTP_CONNECTION_MANAGER,
8083
AWS_LS_HTTP_WEBSOCKET,
8184
AWS_LS_HTTP_WEBSOCKET_SETUP,
85+
AWS_LS_HTTP_PROXY_NEGOTIATION,
8286
};
8387

8488
enum aws_http_version {

include/aws/http/private/proxy_impl.h

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,20 @@
99
#include <aws/http/http.h>
1010

1111
#include <aws/http/connection.h>
12+
#include <aws/http/proxy.h>
13+
#include <aws/http/status_code.h>
14+
#include <aws/io/socket.h>
1215

16+
struct aws_http_connection_manager_options;
1317
struct aws_http_message;
1418
struct aws_channel_slot;
1519
struct aws_string;
1620
struct aws_tls_connection_options;
21+
struct aws_http_proxy_negotiator;
22+
struct aws_http_proxy_strategy;
23+
struct aws_http_proxy_strategy_tunneling_sequence_options;
24+
struct aws_http_proxy_strategy_tunneling_kerberos_options;
25+
struct aws_http_proxy_strategy_tunneling_ntlm_options;
1726

1827
/*
1928
* (Successful) State transitions for proxy connections
@@ -37,17 +46,15 @@ struct aws_http_proxy_config {
3746

3847
struct aws_allocator *allocator;
3948

49+
enum aws_http_proxy_connection_type connection_type;
50+
4051
struct aws_byte_buf host;
4152

4253
uint16_t port;
4354

4455
struct aws_tls_connection_options *tls_options;
4556

46-
enum aws_http_proxy_authentication_type auth_type;
47-
48-
struct aws_byte_buf auth_username;
49-
50-
struct aws_byte_buf auth_password;
57+
struct aws_http_proxy_strategy *proxy_strategy;
5158
};
5259

5360
/*
@@ -61,19 +68,31 @@ struct aws_http_proxy_config {
6168
struct aws_http_proxy_user_data {
6269
struct aws_allocator *allocator;
6370

71+
/*
72+
* dynamic proxy connection resolution state
73+
*/
6474
enum aws_proxy_bootstrap_state state;
6575
int error_code;
76+
enum aws_http_status_code connect_status_code;
6677
struct aws_http_connection *connection;
6778
struct aws_http_message *connect_request;
6879
struct aws_http_stream *connect_stream;
80+
struct aws_http_proxy_negotiator *proxy_negotiator;
6981

82+
/*
83+
* Cached original connect options
84+
*/
7085
struct aws_string *original_host;
7186
uint16_t original_port;
7287
aws_http_on_client_connection_setup_fn *original_on_setup;
7388
aws_http_on_client_connection_shutdown_fn *original_on_shutdown;
7489
void *original_user_data;
7590

7691
struct aws_tls_connection_options *tls_options;
92+
struct aws_client_bootstrap *bootstrap;
93+
struct aws_socket_options socket_options;
94+
bool manual_window_management;
95+
size_t initial_window_size;
7796

7897
struct aws_http_proxy_config *proxy_config;
7998
};
@@ -103,18 +122,81 @@ int aws_http_rewrite_uri_for_proxy_request(
103122
AWS_HTTP_API
104123
void aws_http_proxy_system_set_vtable(struct aws_http_proxy_system_vtable *vtable);
105124

125+
/**
126+
* Checks if tunneling proxy negotiation should continue to try and connect
127+
* @param proxy_negotiator negotiator to query
128+
* @return true if another connect request should be attempted, false otherwise
129+
*/
130+
AWS_HTTP_API
131+
enum aws_http_proxy_negotiation_retry_directive aws_http_proxy_negotiator_get_retry_directive(
132+
struct aws_http_proxy_negotiator *proxy_negotiator);
133+
134+
/**
135+
* Constructor for a tunnel-only proxy strategy that applies no changes to outbound CONNECT requests. Intended to be
136+
* the first link in an adaptive sequence for a tunneling proxy: first try a basic CONNECT, then based on the response,
137+
* later links are allowed to make attempts.
138+
*
139+
* @param allocator memory allocator to use
140+
* @return a new proxy strategy if successfully constructed, otherwise NULL
141+
*/
142+
AWS_HTTP_API
143+
struct aws_http_proxy_strategy *aws_http_proxy_strategy_new_tunneling_one_time_identity(
144+
struct aws_allocator *allocator);
145+
146+
/**
147+
* Constructor for a forwarding-only proxy strategy that does nothing. Exists so that all proxy logic uses a
148+
* strategy.
149+
*
150+
* @param allocator memory allocator to use
151+
* @return a new proxy strategy if successfully constructed, otherwise NULL
152+
*/
153+
AWS_HTTP_API
154+
struct aws_http_proxy_strategy *aws_http_proxy_strategy_new_forwarding_identity(struct aws_allocator *allocator);
155+
156+
/**
157+
* Constructor for a tunneling proxy strategy that contains a set of sub-strategies which are tried
158+
* sequentially in order. Each strategy has the choice to either proceed on a fresh connection or
159+
* reuse the current one.
160+
*
161+
* @param allocator memory allocator to use
162+
* @param config sequence configuration options
163+
* @return a new proxy strategy if successfully constructed, otherwise NULL
164+
*/
106165
AWS_HTTP_API
107-
struct aws_http_proxy_config *aws_http_proxy_config_new(
166+
struct aws_http_proxy_strategy *aws_http_proxy_strategy_new_tunneling_sequence(
108167
struct aws_allocator *allocator,
109-
const struct aws_http_proxy_options *options);
168+
struct aws_http_proxy_strategy_tunneling_sequence_options *config);
110169

170+
/**
171+
* A constructor for a proxy strategy that performs kerberos authentication by adding the appropriate
172+
* header and header value to CONNECT requests.
173+
*
174+
* Currently only supports synchronous fetch of kerberos token values.
175+
*
176+
* @param allocator memory allocator to use
177+
* @param config kerberos authentication configuration info
178+
* @return a new proxy strategy if successfully constructed, otherwise NULL
179+
*/
111180
AWS_HTTP_API
112-
void aws_http_proxy_config_destroy(struct aws_http_proxy_config *config);
181+
struct aws_http_proxy_strategy *aws_http_proxy_strategy_new_tunneling_kerberos(
182+
struct aws_allocator *allocator,
183+
struct aws_http_proxy_strategy_tunneling_kerberos_options *config);
113184

185+
/**
186+
* Constructor for an NTLM proxy strategy. Because ntlm is a challenge-response authentication protocol, this
187+
* strategy will only succeed in a chain in a non-leading position. The strategy extracts the challenge from the
188+
* proxy's response to a previous CONNECT request in the chain.
189+
*
190+
* Currently only supports synchronous fetch of token values.
191+
*
192+
* @param allocator memory allocator to use
193+
* @param config configuration options for the strategy
194+
* @return a new proxy strategy if successfully constructed, otherwise NULL
195+
*/
114196
AWS_HTTP_API
115-
void aws_http_proxy_options_init_from_config(
116-
struct aws_http_proxy_options *options,
117-
const struct aws_http_proxy_config *config);
197+
struct aws_http_proxy_strategy *aws_http_proxy_strategy_new_tunneling_ntlm(
198+
struct aws_allocator *allocator,
199+
struct aws_http_proxy_strategy_tunneling_ntlm_options *config);
118200

119201
AWS_EXTERN_C_END
120202

0 commit comments

Comments
 (0)