in source/http_headers.c [173:288]
static napi_value s_headers_constructor(napi_env env, const struct aws_napi_callback_info *cb_info) {
struct aws_allocator *alloc = aws_napi_get_allocator();
struct aws_http_headers *headers = aws_http_headers_new(alloc);
const struct aws_napi_argument *arg = NULL;
if (aws_napi_method_next_argument(napi_object, cb_info, &arg)) {
napi_value node_headers = arg->node;
bool is_array = false;
if (napi_is_array(env, node_headers, &is_array) || !is_array) {
napi_throw_type_error(env, NULL, "headers must be an array of arrays");
goto cleanup;
}
uint32_t num_headers = 0;
AWS_NAPI_CALL(env, napi_get_array_length(env, node_headers, &num_headers), {
napi_throw_error(env, NULL, "Could not get length of header array");
goto cleanup;
});
struct aws_byte_buf name_buf;
struct aws_byte_buf value_buf;
aws_byte_buf_init(&name_buf, alloc, 256);
aws_byte_buf_init(&value_buf, alloc, 256);
for (uint32_t idx = 0; idx < num_headers; ++idx) {
napi_value node_header = NULL;
AWS_NAPI_CALL(env, napi_get_element(env, node_headers, idx, &node_header), {
napi_throw_error(env, NULL, "Failed to extract headers");
goto header_parse_error;
});
AWS_NAPI_CALL(env, napi_is_array(env, node_header, &is_array), {
napi_throw_error(env, NULL, "Cannot determine if headers are an array");
goto header_parse_error;
});
if (!is_array) {
napi_throw_type_error(env, NULL, "headers must be an array of 2 element arrays");
goto header_parse_error;
}
uint32_t num_parts = 0;
AWS_NAPI_CALL(env, napi_get_array_length(env, node_header, &num_parts), {
napi_throw_error(env, NULL, "Could not get length of header parts");
goto header_parse_error;
});
if (num_parts != 2) {
napi_throw_error(env, NULL, "Could not get length of header parts or length was not 2");
goto header_parse_error;
}
napi_value node_name = NULL;
napi_value node = NULL;
AWS_NAPI_CALL(env, napi_get_element(env, node_header, 0, &node_name), {
napi_throw_error(env, NULL, "Could not extract header name");
goto header_parse_error;
});
AWS_NAPI_CALL(env, napi_get_element(env, node_header, 1, &node), {
napi_throw_error(env, NULL, "Could not extract header value");
goto header_parse_error;
});
/* extract the length of the name and value strings, ensure the buffers can hold them, and
then copy the values out. Should result in buffer re-use most of the time. */
size_t length = 0;
AWS_NAPI_CALL(env, napi_get_value_string_utf8(env, node_name, NULL, 0, &length), {
napi_throw_type_error(env, NULL, "HTTP header was not a string or length could not be extracted");
goto header_parse_error;
});
aws_byte_buf_reserve(&name_buf, length + 1);
AWS_NAPI_CALL(env, napi_get_value_string_utf8(env, node, NULL, 0, &length), {
napi_throw_type_error(env, NULL, "HTTP header was not a string or length could not be extracted");
goto header_parse_error;
});
aws_byte_buf_reserve(&value_buf, length + 1);
AWS_NAPI_CALL(
env,
napi_get_value_string_utf8(env, node_name, (char *)name_buf.buffer, name_buf.capacity, &name_buf.len),
{
napi_throw_error(env, NULL, "HTTP header name could not be extracted");
goto header_parse_error;
});
AWS_NAPI_CALL(
env,
napi_get_value_string_utf8(env, node, (char *)value_buf.buffer, value_buf.capacity, &value_buf.len),
{
napi_throw_error(env, NULL, "HTTP header value could not be extracted");
goto header_parse_error;
});
aws_http_headers_add(headers, aws_byte_cursor_from_buf(&name_buf), aws_byte_cursor_from_buf(&value_buf));
}
aws_byte_buf_clean_up(&name_buf);
aws_byte_buf_clean_up(&value_buf);
goto header_parse_success;
header_parse_error:
aws_byte_buf_clean_up(&name_buf);
aws_byte_buf_clean_up(&value_buf);
goto cleanup;
}
header_parse_success:;
napi_value node_this = cb_info->native_this;
AWS_NAPI_CALL(env, napi_wrap(env, node_this, headers, s_napi_http_headers_finalize, NULL, NULL), {
napi_throw_error(env, NULL, "Failed to wrap HttpHeaders");
goto cleanup;
});
return node_this;
cleanup:
if (headers) {
aws_http_headers_release(headers);
}
return NULL;
}