Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/aws/http/private/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ AWS_HTTP_API int aws_http_decode(
size_t data_bytes,
size_t *bytes_read);

AWS_HTTP_API void aws_http_decoder_set_logging_id(struct aws_http_decoder *decoder, void *id);

/* RFC-7230 section 4.2 Message Format */
#define AWS_HTTP_TRANSFER_ENCODING_CHUNKED (1 << 0)
#define AWS_HTTP_TRANSFER_ENCODING_GZIP (1 << 1)
Expand Down
3 changes: 3 additions & 0 deletions source/connection_h1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,9 @@ static int s_handler_process_read_message(
}

/* Decoder will invoke the internal s_decoder_X callbacks, which in turn invoke user callbacks */
aws_http_decoder_set_logging_id(
connection->thread_data.incoming_stream_decoder, connection->thread_data.incoming_stream);

size_t decoded_len = 0;
err = aws_http_decode(
connection->thread_data.incoming_stream_decoder, message_cursor.ptr, message_cursor.len, &decoded_len);
Expand Down
329 changes: 258 additions & 71 deletions source/decode.c

Large diffs are not rendered by default.

35 changes: 23 additions & 12 deletions source/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,20 @@ static struct aws_log_subject_info_list s_log_subject_list = {
* Key is aws_byte_cursor* (pointing into cursor from array) and comparisons are case-insensitive.
* Value is the array index cast to a void*.
*/
static void s_init_case_insensitive_hash_table(
static void s_init_str_to_enum_hash_table(
struct aws_hash_table *table,
struct aws_allocator *alloc,
struct aws_byte_cursor *str_array,
int start_index,
int end_index) {
int end_index,
bool ignore_case) {

int err = aws_hash_table_init(
table,
alloc,
end_index - start_index,
aws_hash_byte_cursor_ptr_ignore_case,
(aws_hash_callback_eq_fn *)aws_byte_cursor_eq_ignore_case,
ignore_case ? aws_hash_byte_cursor_ptr_ignore_case : aws_hash_byte_cursor_ptr,
(aws_hash_callback_eq_fn *)(ignore_case ? aws_byte_cursor_eq_ignore_case : aws_byte_cursor_eq),
NULL,
NULL);
AWS_FATAL_ASSERT(!err);
Expand All @@ -108,10 +109,10 @@ static void s_init_case_insensitive_hash_table(
}

/**
* Given key, get value from table initialized by s_init_case_insensitive_hash_table().
* Given key, get value from table initialized by s_init_str_to_enum_hash_table().
* Returns -1 if key not found.
*/
static int s_find_in_case_insensitive_hash_table(const struct aws_hash_table *table, struct aws_byte_cursor *key) {
static int s_find_in_str_to_enum_hash_table(const struct aws_hash_table *table, struct aws_byte_cursor *key) {
struct aws_hash_element *elem;
aws_hash_table_find(table, key, &elem);
if (elem) {
Expand All @@ -127,16 +128,21 @@ static struct aws_byte_cursor s_method_enum_to_str[AWS_HTTP_METHOD_COUNT]; /* fo
static void s_methods_init(struct aws_allocator *alloc) {
s_method_enum_to_str[AWS_HTTP_METHOD_HEAD] = aws_byte_cursor_from_c_str("HEAD");

s_init_case_insensitive_hash_table(
&s_method_str_to_enum, alloc, s_method_enum_to_str, AWS_HTTP_METHOD_UNKNOWN + 1, AWS_HTTP_METHOD_COUNT);
s_init_str_to_enum_hash_table(
&s_method_str_to_enum,
alloc,
s_method_enum_to_str,
AWS_HTTP_METHOD_UNKNOWN + 1,
AWS_HTTP_METHOD_COUNT,
false /* DO NOT ignore case of method */);
}

static void s_methods_clean_up(void) {
aws_hash_table_clean_up(&s_method_str_to_enum);
}

enum aws_http_method aws_http_str_to_method(struct aws_byte_cursor cursor) {
int method = s_find_in_case_insensitive_hash_table(&s_method_str_to_enum, &cursor);
int method = s_find_in_str_to_enum_hash_table(&s_method_str_to_enum, &cursor);
if (method >= 0) {
return (enum aws_http_method)method;
}
Expand Down Expand Up @@ -173,16 +179,21 @@ static void s_headers_init(struct aws_allocator *alloc) {
s_header_enum_to_str[AWS_HTTP_HEADER_CONTENT_LENGTH] = aws_byte_cursor_from_c_str("content-length");
s_header_enum_to_str[AWS_HTTP_HEADER_EXPECT] = aws_byte_cursor_from_c_str("expect");

s_init_case_insensitive_hash_table(
&s_header_str_to_enum, alloc, s_header_enum_to_str, AWS_HTTP_HEADER_UNKNOWN + 1, AWS_HTTP_HEADER_COUNT);
s_init_str_to_enum_hash_table(
&s_header_str_to_enum,
alloc,
s_header_enum_to_str,
AWS_HTTP_HEADER_UNKNOWN + 1,
AWS_HTTP_HEADER_COUNT,
true /* ignore case */);
}

static void s_headers_clean_up(void) {
aws_hash_table_clean_up(&s_header_str_to_enum);
}

enum aws_http_header_name aws_http_str_to_header_name(struct aws_byte_cursor cursor) {
int header = s_find_in_case_insensitive_hash_table(&s_header_str_to_enum, &cursor);
int header = s_find_in_str_to_enum_hash_table(&s_header_str_to_enum, &cursor);
if (header >= 0) {
return (enum aws_http_header_name)header;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ add_test_case(http_test_body_chunked)
add_test_case(http_decode_trailers)
add_test_case(http_decode_one_byte_at_a_time)
add_test_case(http_decode_messages_at_random_intervals)
add_test_case(http_decode_bad_messages_and_assert_failure)
add_test_case(http_decode_bad_requests_and_assert_failure)
add_test_case(http_decode_bad_responses_and_assert_failure)
add_test_case(http_test_extraneous_buffer_data_ensure_not_processed)
add_test_case(http_test_ignore_transfer_extensions)
add_test_case(http_test_ignore_chunk_extensions)
add_test_case(server_new_destroy)
# add_test_case(connection_setup_shutdown) TODO: diagnose occasional failures
Expand Down
Loading