static napi_value s_headers_constructor()

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;
}