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