static int s_encode_header_field()

in source/hpack.c [1327:1410]


static int s_encode_header_field(
    struct aws_hpack_context *context,
    const struct aws_http_header *header,
    struct aws_byte_buf *output) {

    AWS_PRECONDITION(context);
    AWS_PRECONDITION(header);
    AWS_PRECONDITION(output);

    size_t original_len = output->len;

    /* Search for header-field in tables */
    bool found_indexed_value;
    size_t header_index = aws_hpack_find_index(context, header, true, &found_indexed_value);

    if (header->compression != AWS_HTTP_HEADER_COMPRESSION_USE_CACHE) {
        /* If user doesn't want to use indexed value, then don't use it */
        found_indexed_value = false;
    }

    if (header_index && found_indexed_value) {
        /* Indexed header field */
        const enum aws_hpack_entry_type entry_type = AWS_HPACK_ENTRY_INDEXED_HEADER_FIELD;

        /* encode the one index (along with the entry type), and we're done! */
        uint8_t starting_bit_pattern = s_hpack_entry_starting_bit_pattern[entry_type];
        uint8_t num_prefix_bits = s_hpack_entry_num_prefix_bits[entry_type];
        if (aws_hpack_encode_integer(header_index, starting_bit_pattern, num_prefix_bits, output)) {
            goto error;
        }

        return AWS_OP_SUCCESS;
    }

    /* Else, Literal header field... */

    /* determine exactly which type of literal header-field to encode. */
    enum aws_hpack_entry_type literal_entry_type = AWS_HPACK_ENTRY_TYPE_COUNT;
    if (s_convert_http_compression_to_literal_entry_type(header->compression, &literal_entry_type)) {
        goto error;
    }

    /* the entry type makes up the first few bits of the next integer we encode */
    uint8_t starting_bit_pattern = s_hpack_entry_starting_bit_pattern[literal_entry_type];
    uint8_t num_prefix_bits = s_hpack_entry_num_prefix_bits[literal_entry_type];

    if (header_index) {
        /* Literal header field, indexed name */

        /* first encode the index of name */
        if (aws_hpack_encode_integer(header_index, starting_bit_pattern, num_prefix_bits, output)) {
            goto error;
        }
    } else {
        /* Literal header field, new name */

        /* first encode index of 0 to indicate that header-name is not indexed */
        if (aws_hpack_encode_integer(0, starting_bit_pattern, num_prefix_bits, output)) {
            goto error;
        }

        /* next encode header-name string */
        if (aws_hpack_encode_string(context, header->name, output)) {
            goto error;
        }
    }

    /* then encode header-value string, and we're done encoding! */
    if (aws_hpack_encode_string(context, header->value, output)) {
        goto error;
    }

    /* if "incremental indexing" type, insert header into the dynamic table. */
    if (AWS_HPACK_ENTRY_LITERAL_HEADER_FIELD_WITH_INCREMENTAL_INDEXING == literal_entry_type) {
        if (aws_hpack_insert_header(context, header)) {
            goto error;
        }
    }

    return AWS_OP_SUCCESS;
error:
    output->len = original_len;
    return AWS_OP_ERR;
}