in source/connection.c [419:545]
static void s_server_bootstrap_on_accept_channel_setup(
struct aws_server_bootstrap *bootstrap,
int error_code,
struct aws_channel *channel,
void *user_data) {
(void)bootstrap;
AWS_ASSERT(user_data);
struct aws_http_server *server = user_data;
bool user_cb_invoked = false;
struct aws_http_connection *connection = NULL;
if (error_code) {
AWS_LOGF_ERROR(
AWS_LS_HTTP_SERVER,
"%p: Incoming connection failed with error code %d (%s)",
(void *)server,
error_code,
aws_error_name(error_code));
goto error;
}
/* Create connection */
/* TODO: expose http1/2 options to server API */
struct aws_http1_connection_options http1_options;
AWS_ZERO_STRUCT(http1_options);
struct aws_http2_connection_options http2_options;
AWS_ZERO_STRUCT(http2_options);
connection = aws_http_connection_new_channel_handler(
server->alloc,
channel,
true,
server->is_using_tls,
server->manual_window_management,
false, /* prior_knowledge_http2 */
server->initial_window_size,
NULL, /* alpn_string_map */
&http1_options,
&http2_options,
NULL /* connection_user_data */);
if (!connection) {
AWS_LOGF_ERROR(
AWS_LS_HTTP_SERVER,
"%p: Failed to create connection object, error %d (%s).",
(void *)server,
aws_last_error(),
aws_error_name(aws_last_error()));
goto error;
}
int put_err = 0;
/* BEGIN CRITICAL SECTION */
s_server_lock_synced_data(server);
if (server->synced_data.is_shutting_down) {
error_code = AWS_ERROR_HTTP_CONNECTION_CLOSED;
}
if (!error_code) {
put_err = aws_hash_table_put(&server->synced_data.channel_to_connection_map, channel, connection, NULL);
}
s_server_unlock_synced_data(server);
/* END CRITICAL SECTION */
if (error_code) {
AWS_LOGF_ERROR(
AWS_ERROR_HTTP_SERVER_CLOSED,
"id=%p: Incoming connection failed. The server is shutting down.",
(void *)server);
goto error;
}
if (put_err) {
AWS_LOGF_ERROR(
AWS_LS_HTTP_SERVER,
"%p: %s:%d: Failed to store connection object, error %d (%s).",
(void *)server,
server->socket->local_endpoint.address,
server->socket->local_endpoint.port,
aws_last_error(),
aws_error_name(aws_last_error()));
goto error;
}
/* Tell user of successful connection. */
AWS_LOGF_INFO(
AWS_LS_HTTP_CONNECTION,
"id=%p: " PRInSTR " server connection established at %p %s:%d.",
(void *)connection,
AWS_BYTE_CURSOR_PRI(aws_http_version_to_str(connection->http_version)),
(void *)server,
server->socket->local_endpoint.address,
server->socket->local_endpoint.port);
server->on_incoming_connection(server, connection, AWS_ERROR_SUCCESS, server->user_data);
user_cb_invoked = true;
/* If user failed to configure the server during callback, shut down the channel. */
if (!connection->server_data->on_incoming_request) {
AWS_LOGF_ERROR(
AWS_LS_HTTP_CONNECTION,
"id=%p: Caller failed to invoke aws_http_connection_configure_server() during on_incoming_connection "
"callback, closing connection.",
(void *)connection);
aws_raise_error(AWS_ERROR_HTTP_REACTION_REQUIRED);
goto error;
}
return;
error:
if (!error_code) {
error_code = aws_last_error();
}
if (!user_cb_invoked) {
server->on_incoming_connection(server, NULL, error_code, server->user_data);
}
if (channel) {
aws_channel_shutdown(channel, error_code);
}
if (connection) {
/* release the ref count for the user side */
aws_http_connection_release(connection);
}
}