1 #ifndef AWS_HTTP_CONNECTION_IMPL_H
2 #define AWS_HTTP_CONNECTION_IMPL_H
3 
4 /**
5  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
6  * SPDX-License-Identifier: Apache-2.0.
7  */
8 
9 #include <aws/http/connection.h>
10 
11 #include <aws/http/private/http_impl.h>
12 #include <aws/http/server.h>
13 
14 #include <aws/common/atomics.h>
15 #include <aws/io/channel.h>
16 #include <aws/io/channel_bootstrap.h>
17 
18 struct aws_http_message;
19 struct aws_http_make_request_options;
20 struct aws_http_request_handler_options;
21 struct aws_http_stream;
22 
23 typedef int aws_client_bootstrap_new_socket_channel_fn(struct aws_socket_channel_bootstrap_options *options);
24 
25 struct aws_http_connection_system_vtable {
26     aws_client_bootstrap_new_socket_channel_fn *new_socket_channel;
27 };
28 
29 struct aws_http_connection_vtable {
30     struct aws_channel_handler_vtable channel_handler_vtable;
31 
32     /* This is a callback I wish was in aws_channel_handler_vtable. */
33     void (*on_channel_handler_installed)(struct aws_channel_handler *handler, struct aws_channel_slot *slot);
34 
35     struct aws_http_stream *(*make_request)(
36         struct aws_http_connection *client_connection,
37         const struct aws_http_make_request_options *options);
38 
39     struct aws_http_stream *(*new_server_request_handler_stream)(
40         const struct aws_http_request_handler_options *options);
41     int (*stream_send_response)(struct aws_http_stream *stream, struct aws_http_message *response);
42     void (*close)(struct aws_http_connection *connection);
43     bool (*is_open)(const struct aws_http_connection *connection);
44     bool (*new_requests_allowed)(const struct aws_http_connection *connection);
45 
46     /* HTTP/2 specific functions */
47     void (*update_window)(struct aws_http_connection *connection, uint32_t increment_size);
48     int (*change_settings)(
49         struct aws_http_connection *http2_connection,
50         const struct aws_http2_setting *settings_array,
51         size_t num_settings,
52         aws_http2_on_change_settings_complete_fn *on_completed,
53         void *user_data);
54     int (*send_ping)(
55         struct aws_http_connection *http2_connection,
56         const struct aws_byte_cursor *optional_opaque_data,
57         aws_http2_on_ping_complete_fn *on_completed,
58         void *user_data);
59     int (*send_goaway)(
60         struct aws_http_connection *http2_connection,
61         uint32_t http2_error,
62         bool allow_more_streams,
63         const struct aws_byte_cursor *optional_debug_data);
64     int (*get_sent_goaway)(
65         struct aws_http_connection *http2_connection,
66         uint32_t *out_http2_error,
67         uint32_t *out_last_stream_id);
68     int (*get_received_goaway)(
69         struct aws_http_connection *http2_connection,
70         uint32_t *out_http2_error,
71         uint32_t *out_last_stream_id);
72     void (*get_local_settings)(
73         const struct aws_http_connection *http2_connection,
74         struct aws_http2_setting out_settings[AWS_HTTP2_SETTINGS_COUNT]);
75     void (*get_remote_settings)(
76         const struct aws_http_connection *http2_connection,
77         struct aws_http2_setting out_settings[AWS_HTTP2_SETTINGS_COUNT]);
78 };
79 
80 typedef int(aws_http_proxy_request_transform_fn)(struct aws_http_message *request, void *user_data);
81 
82 /**
83  * Base class for connections.
84  * There are specific implementations for each HTTP version.
85  */
86 struct aws_http_connection {
87     const struct aws_http_connection_vtable *vtable;
88     struct aws_channel_handler channel_handler;
89     struct aws_channel_slot *channel_slot;
90     struct aws_allocator *alloc;
91     enum aws_http_version http_version;
92 
93     aws_http_proxy_request_transform_fn *proxy_request_transform;
94     void *user_data;
95 
96     /* Connection starts with 1 hold for the user.
97      * aws_http_streams will also acquire holds on their connection for the duration of their lifetime */
98     struct aws_atomic_var refcount;
99 
100     /* Starts at either 1 or 2, increments by two with each new stream */
101     uint32_t next_stream_id;
102 
103     union {
104         struct aws_http_connection_client_data {
105             uint8_t delete_me; /* exists to prevent "empty struct" errors */
106         } client;
107 
108         struct aws_http_connection_server_data {
109             aws_http_on_incoming_request_fn *on_incoming_request;
110             aws_http_on_server_connection_shutdown_fn *on_shutdown;
111         } server;
112     } client_or_server_data;
113 
114     /* On client connections, `client_data` points to client_or_server_data.client and `server_data` is null.
115      * Opposite is true on server connections */
116     struct aws_http_connection_client_data *client_data;
117     struct aws_http_connection_server_data *server_data;
118 
119     bool manual_window_management;
120 };
121 
122 /* Gets a client connection up and running.
123  * Responsible for firing on_setup and on_shutdown callbacks. */
124 struct aws_http_client_bootstrap {
125     struct aws_allocator *alloc;
126     bool is_using_tls;
127     bool manual_window_management;
128     bool prior_knowledge_http2;
129     size_t initial_window_size;
130     struct aws_http_connection_monitoring_options monitoring_options;
131     void *user_data;
132     aws_http_on_client_connection_setup_fn *on_setup;
133     aws_http_on_client_connection_shutdown_fn *on_shutdown;
134     aws_http_proxy_request_transform_fn *proxy_request_transform;
135 
136     struct aws_http1_connection_options http1_options;
137     struct aws_http2_connection_options http2_options; /* allocated with bootstrap */
138     struct aws_hash_table *alpn_string_map;            /* allocated with bootstrap */
139     struct aws_http_connection *connection;
140 };
141 
142 AWS_EXTERN_C_BEGIN
143 AWS_HTTP_API
144 void aws_http_client_bootstrap_destroy(struct aws_http_client_bootstrap *bootstrap);
145 
146 AWS_HTTP_API
147 void aws_http_connection_set_system_vtable(const struct aws_http_connection_system_vtable *system_vtable);
148 
149 AWS_HTTP_API
150 int aws_http_client_connect_internal(
151     const struct aws_http_client_connection_options *options,
152     aws_http_proxy_request_transform_fn *proxy_request_transform);
153 
154 /**
155  * Internal API for adding a reference to a connection
156  */
157 AWS_HTTP_API
158 void aws_http_connection_acquire(struct aws_http_connection *connection);
159 
160 /**
161  * Allow tests to fake stats data
162  */
163 AWS_HTTP_API
164 struct aws_crt_statistics_http1_channel *aws_h1_connection_get_statistics(struct aws_http_connection *connection);
165 
166 /**
167  * Gets the next available stream id within the connection.  Valid for creating both h1 and h2 streams.
168  *
169  * This function is not thread-safe.
170  *
171  * Returns 0 if there was an error.
172  */
173 AWS_HTTP_API
174 uint32_t aws_http_connection_get_next_stream_id(struct aws_http_connection *connection);
175 
176 /**
177  * Layers an http channel handler/connection onto a channel.  Moved from internal to private so that the proxy
178  * logic could apply a new http connection/handler after tunneling proxy negotiation (into http) is finished.
179  * This is a synchronous operation.
180  *
181  * @param alloc memory allocator to use
182  * @param channel channel to apply the http handler/connection to
183  * @param is_server should the handler behave like an http server
184  * @param is_using_tls is tls is being used (do an alpn check of the to-the-left channel handler)
185  * @param manual_window_management is manual window management enabled
186  * @param prior_knowledge_http2 prior knowledge about http2 connection to be used
187  * @param initial_window_size what should the initial window size be
188  * @param alpn_string_map the customized ALPN string map from `struct aws_string *` to `enum aws_http_version`.
189  * @param http1_options http1 options
190  * @param http2_options http2 options
191  * @return a new http connection or NULL on failure
192  */
193 AWS_HTTP_API
194 struct aws_http_connection *aws_http_connection_new_channel_handler(
195     struct aws_allocator *alloc,
196     struct aws_channel *channel,
197     bool is_server,
198     bool is_using_tls,
199     bool manual_window_management,
200     bool prior_knowledge_http2,
201     size_t initial_window_size,
202     const struct aws_hash_table *alpn_string_map,
203     const struct aws_http1_connection_options *http1_options,
204     const struct aws_http2_connection_options *http2_options);
205 
206 AWS_EXTERN_C_END
207 
208 #endif /* AWS_HTTP_CONNECTION_IMPL_H */
209