in source/http_connection_manager.c [56:208]
napi_value aws_napi_http_connection_manager_new(napi_env env, napi_callback_info info) {
napi_value result = NULL;
napi_value node_args[9];
size_t num_args = AWS_ARRAY_SIZE(node_args);
napi_value *arg = &node_args[0];
AWS_NAPI_CALL(env, napi_get_cb_info(env, info, &num_args, node_args, NULL, NULL), {
napi_throw_error(env, NULL, "Unable to get callback info");
return NULL;
});
if (num_args != AWS_ARRAY_SIZE(node_args)) {
napi_throw_error(env, NULL, "http_connection_manager_new takes exactly 8 arguments");
return NULL;
}
struct aws_allocator *allocator = aws_napi_get_allocator();
struct aws_http_connection_manager_options options;
AWS_ZERO_STRUCT(options);
struct aws_byte_buf host_buf;
AWS_ZERO_STRUCT(host_buf);
struct aws_tls_connection_options tls_connection_options;
AWS_ZERO_STRUCT(tls_connection_options);
napi_value node_bootstrap = *arg++;
struct client_bootstrap_binding *client_bootstrap_binding = NULL;
napi_get_value_external(env, node_bootstrap, (void **)&client_bootstrap_binding);
if (client_bootstrap_binding != NULL) {
options.bootstrap = aws_napi_get_client_bootstrap(client_bootstrap_binding);
} else {
options.bootstrap = aws_napi_get_default_client_bootstrap();
}
napi_value node_host = *arg++;
if (aws_byte_buf_init_from_napi(&host_buf, env, node_host)) {
napi_throw_type_error(env, NULL, "host must be a string");
return NULL;
}
options.host = aws_byte_cursor_from_buf(&host_buf);
struct http_connection_manager_binding *binding =
aws_mem_calloc(allocator, 1, sizeof(struct http_connection_manager_binding));
AWS_FATAL_ASSERT(binding);
binding->allocator = allocator;
binding->env = env;
napi_value node_port = *arg++;
uint32_t port = 0;
if (napi_get_value_uint32(env, node_port, &port) || port > UINT16_MAX) {
napi_throw_type_error(env, NULL, "port must be a number between 0 and 65535");
goto cleanup;
}
options.port = (uint16_t)port;
napi_value node_max_conns = *arg++;
uint32_t max_connections = 0;
AWS_NAPI_CALL(env, napi_get_value_uint32(env, node_max_conns, &max_connections), {
napi_throw_type_error(env, NULL, "max_connections must be a number");
goto cleanup;
});
options.max_connections = (size_t)max_connections;
napi_value node_window_size = *arg++;
uint32_t window_size = 16 * 1024;
AWS_NAPI_CALL(env, napi_get_value_uint32(env, node_window_size, &window_size), {
napi_throw_type_error(env, NULL, "initial_window_size must be a number");
goto cleanup;
});
options.initial_window_size = (size_t)window_size;
napi_value node_socket_options = *arg++;
const struct aws_socket_options *socket_options = NULL;
if (!aws_napi_is_null_or_undefined(env, node_socket_options)) {
AWS_NAPI_CALL(env, napi_get_value_external(env, node_socket_options, (void **)&socket_options), {
napi_throw_type_error(env, NULL, "socket_options must be undefined or a valid SocketOptions");
goto cleanup;
});
}
options.socket_options = socket_options;
napi_value node_tls_opts = *arg++;
struct aws_tls_connection_options *tls_opts = NULL;
if (!aws_napi_is_null_or_undefined(env, node_tls_opts)) {
AWS_NAPI_CALL(env, napi_get_value_external(env, node_tls_opts, (void **)&tls_opts), {
napi_throw_type_error(env, NULL, "tls_opts must be undefined or a valid TlsConnectionOptions");
goto cleanup;
});
}
options.tls_connection_options = tls_opts;
napi_value node_proxy_options = *arg++;
struct aws_http_proxy_options *proxy_options = NULL;
if (!aws_napi_is_null_or_undefined(env, node_proxy_options)) {
struct http_proxy_options_binding *proxy_binding = NULL;
AWS_NAPI_CALL(env, napi_get_value_external(env, node_proxy_options, (void **)&proxy_binding), {
napi_throw_type_error(env, NULL, "tls_opts must be undefined or a valid TlsConnectionOptions");
goto cleanup;
});
proxy_options = aws_napi_get_http_proxy_options(proxy_binding);
}
/* proxy_options are copied internally, no need to go nuts on copies */
options.proxy_options = proxy_options;
napi_value node_on_shutdown = *arg++;
if (!aws_napi_is_null_or_undefined(env, node_on_shutdown)) {
AWS_NAPI_CALL(
env,
aws_napi_create_threadsafe_function(
env,
node_on_shutdown,
"aws_http_connection_manager_on_shutdown",
s_http_connection_manager_shutdown_call,
binding,
&binding->on_shutdown),
{
napi_throw_type_error(env, NULL, "on_shutdown must be a valid callback or undefined");
goto cleanup;
});
}
options.shutdown_complete_callback = s_http_connection_manager_shutdown_complete;
options.shutdown_complete_user_data = binding;
binding->manager = aws_http_connection_manager_new(allocator, &options);
if (!binding->manager) {
aws_napi_throw_last_error(env);
goto cleanup;
}
napi_value node_external = NULL;
AWS_NAPI_CALL(env, napi_create_external(env, binding, s_http_connection_manager_finalize, NULL, &node_external), {
napi_throw_error(env, NULL, "Unable to create node external");
goto external_failed;
});
AWS_NAPI_CALL(env, napi_create_reference(env, node_external, 1, &binding->node_external), {
napi_throw_error(env, NULL, "Unable to create reference to node external");
goto external_failed;
});
/* success, set the return value */
result = node_external;
goto done;
external_failed:
aws_http_connection_manager_release(binding->manager);
cleanup:
done:
aws_tls_connection_options_clean_up(&tls_connection_options);
aws_byte_buf_clean_up(&host_buf);
return result;
}