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