Skip to content

Commit 35a9067

Browse files
authored
combine 2 callbacks into 1 (#25)
- `on_request()` instead of distinct `on_method()` and `on_uri()` - rename `on_code()` -> `on_response()`
1 parent 7ba3b4a commit 35a9067

File tree

5 files changed

+80
-102
lines changed

5 files changed

+80
-102
lines changed

include/aws/http/private/decode.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,25 @@ typedef bool(aws_http_decoder_on_header_fn)(const struct aws_http_decoded_header
4949
*/
5050
typedef bool(aws_http_decoder_on_body_fn)(const struct aws_byte_cursor *data, bool finished, void *user_data);
5151

52-
typedef void(aws_http_decoder_on_uri_fn)(struct aws_byte_cursor *uri, void *user_data);
53-
typedef void(aws_http_decoder_on_response_code_fn)(int code, void *user_data);
54-
55-
typedef void(aws_http_decoder_on_method_fn)(
56-
enum aws_http_method method,
57-
const struct aws_byte_cursor *method_data,
52+
typedef void(aws_http_decoder_on_request_fn)(
53+
enum aws_http_method method_enum,
54+
const struct aws_byte_cursor *method_str,
55+
const struct aws_byte_cursor *uri,
5856
void *user_data);
5957

58+
typedef void(aws_http_decoder_on_response_fn)(int status_code, void *user_data);
59+
6060
typedef void(aws_http_decoder_done_fn)(void *user_data);
6161

6262
struct aws_http_decoder_vtable {
6363
aws_http_decoder_on_header_fn *on_header;
6464
aws_http_decoder_on_body_fn *on_body;
6565

6666
/* Only needed for requests, can be NULL for responses. */
67-
aws_http_decoder_on_uri_fn *on_uri;
68-
aws_http_decoder_on_method_fn *on_method;
67+
aws_http_decoder_on_request_fn *on_request;
6968

7069
/* Only needed for responses, can be NULL for requests. */
71-
aws_http_decoder_on_response_code_fn *on_code;
70+
aws_http_decoder_on_response_fn *on_response;
7271

7372
aws_http_decoder_done_fn *on_done;
7473
};

source/connection_h1.c

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <aws/http/private/connection_impl.h>
1717

18+
#include <aws/common/math.h>
1819
#include <aws/common/mutex.h>
1920
#include <aws/common/string.h>
2021
#include <aws/http/private/decode.h>
@@ -60,9 +61,12 @@ static void s_handler_destroy(struct aws_channel_handler *handler);
6061
static struct aws_http_stream *s_new_client_request_stream(const struct aws_http_request_options *options);
6162
static void s_stream_destroy(struct aws_http_stream *stream_base);
6263
static void s_stream_update_window(struct aws_http_stream *stream, size_t increment_size);
63-
static void s_decoder_on_method(enum aws_http_method method, const struct aws_byte_cursor *method_str, void *user_data);
64-
static void s_decoder_on_uri(struct aws_byte_cursor *uri, void *user_data);
65-
static void s_decoder_on_response_code(int status_code, void *user_data);
64+
static void s_decoder_on_request(
65+
enum aws_http_method method_enum,
66+
const struct aws_byte_cursor *method_str,
67+
const struct aws_byte_cursor *uri,
68+
void *user_data);
69+
static void s_decoder_on_response(int status_code, void *user_data);
6670
static bool s_decoder_on_header(const struct aws_http_decoded_header *header, void *user_data);
6771
static bool s_decoder_on_body(const struct aws_byte_cursor *data, bool finished, void *user_data);
6872
static void s_decoder_on_done(void *user_data);
@@ -88,9 +92,8 @@ static const struct aws_http_stream_vtable s_stream_vtable = {
8892
};
8993

9094
static const struct aws_http_decoder_vtable s_decoder_vtable = {
91-
.on_method = s_decoder_on_method,
92-
.on_uri = s_decoder_on_uri,
93-
.on_code = s_decoder_on_response_code,
95+
.on_request = s_decoder_on_request,
96+
.on_response = s_decoder_on_response,
9497
.on_header = s_decoder_on_header,
9598
.on_body = s_decoder_on_body,
9699
.on_done = s_decoder_on_done,
@@ -838,52 +841,50 @@ static void s_outgoing_stream_task(struct aws_channel_task *task, void *arg, enu
838841
s_shutdown_connection(connection, aws_last_error());
839842
}
840843

841-
static void s_decoder_on_method(
842-
enum aws_http_method method,
844+
static void s_decoder_on_request(
845+
enum aws_http_method method_enum,
843846
const struct aws_byte_cursor *method_str,
847+
const struct aws_byte_cursor *uri,
844848
void *user_data) {
845849

846-
(void)method;
847-
848850
struct h1_connection *connection = user_data;
849851
struct h1_stream *incoming_stream = connection->thread_data.incoming_stream;
850852

851-
AWS_LOGF_TRACE(
852-
AWS_LS_HTTP_STREAM,
853-
"id=%p: Incoming request method: " PRInSTR,
854-
(void *)&incoming_stream->base,
855-
AWS_BYTE_CURSOR_PRI(*method_str));
856-
857853
assert(incoming_stream->base.incoming_request_method_str.len == 0);
858-
/* TODO: combine decoder on_uri & on_method callbacks so we can allocate buffer all at once
859-
incoming_stream->base.incoming_request_method = method;
860-
incoming_stream->base.incoming_request_method_str = aws_byte_cursor_from_c_str(aws_http_method_to_str(method));
861-
*/
862-
}
863-
864-
static void s_decoder_on_uri(struct aws_byte_cursor *uri, void *user_data) {
865-
struct h1_connection *connection = user_data;
866-
struct h1_stream *incoming_stream = connection->thread_data.incoming_stream;
867-
868-
assert(!incoming_stream->base.incoming_request_uri.ptr);
854+
assert(incoming_stream->base.incoming_request_uri.len == 0);
869855

870856
AWS_LOGF_TRACE(
871857
AWS_LS_HTTP_STREAM,
872-
"id=%p: Incoming request uri: " PRInSTR,
858+
"id=%p: Incoming request: method=" PRInSTR " uri=" PRInSTR,
873859
(void *)&incoming_stream->base,
860+
AWS_BYTE_CURSOR_PRI(*method_str),
874861
AWS_BYTE_CURSOR_PRI(*uri));
875862

876-
/* TODO: combine decoder on_uri & on_method callbacks so we can allocate buffer all at once */
877-
878863
/* TODO: Limit on lengths of incoming data https://httpwg.org/specs/rfc7230.html#attack.protocol.element.length */
879864

880-
int err = aws_byte_buf_init(&incoming_stream->incoming_storage_buf, incoming_stream->base.alloc, uri->len);
865+
/* Copy strings to internal buffer */
866+
struct aws_byte_buf *storage_buf = &incoming_stream->incoming_storage_buf;
867+
assert(storage_buf->capacity == 0);
868+
869+
size_t storage_size = 0;
870+
int err = aws_add_size_checked(uri->len, method_str->len, &storage_size);
881871
if (err) {
882872
goto error;
883873
}
884874

885-
aws_byte_buf_write(&incoming_stream->incoming_storage_buf, uri->ptr, uri->len);
886-
incoming_stream->base.incoming_request_uri = aws_byte_cursor_from_buf(&incoming_stream->incoming_storage_buf);
875+
err = aws_byte_buf_init(storage_buf, incoming_stream->base.alloc, storage_size);
876+
if (err) {
877+
goto error;
878+
}
879+
880+
aws_byte_buf_write_from_whole_cursor(storage_buf, *method_str);
881+
incoming_stream->base.incoming_request_method_str = aws_byte_cursor_from_buf(storage_buf);
882+
883+
aws_byte_buf_write_from_whole_cursor(storage_buf, *uri);
884+
incoming_stream->base.incoming_request_uri = aws_byte_cursor_from_buf(storage_buf);
885+
aws_byte_cursor_advance(&incoming_stream->base.incoming_request_method_str, storage_buf->len - uri->len);
886+
887+
incoming_stream->base.incoming_request_method = method_enum;
887888

888889
return;
889890
error:
@@ -895,7 +896,7 @@ static void s_decoder_on_uri(struct aws_byte_cursor *uri, void *user_data) {
895896
s_shutdown_connection(connection, aws_last_error());
896897
}
897898

898-
static void s_decoder_on_response_code(int status_code, void *user_data) {
899+
static void s_decoder_on_response(int status_code, void *user_data) {
899900
struct h1_connection *connection = user_data;
900901

901902
AWS_LOGF_TRACE(

source/decode.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -475,12 +475,8 @@ static int s_linestate_request(struct aws_http_decoder *decoder, struct aws_byte
475475
return aws_raise_error(AWS_ERROR_HTTP_PARSE);
476476
}
477477

478-
if (decoder->vtable.on_method) {
479-
decoder->vtable.on_method(aws_http_str_to_method(method), &method, decoder->user_data);
480-
}
481-
482-
if (decoder->vtable.on_uri) {
483-
decoder->vtable.on_uri(&uri, decoder->user_data);
478+
if (decoder->vtable.on_request) {
479+
decoder->vtable.on_request(aws_http_str_to_method(method), &method, &uri, decoder->user_data);
484480
}
485481

486482
s_set_line_state(decoder, s_linestate_header);
@@ -515,8 +511,8 @@ static int s_linestate_response(struct aws_http_decoder *decoder, struct aws_byt
515511
return aws_raise_error(AWS_ERROR_HTTP_PARSE);
516512
}
517513

518-
if (decoder->vtable.on_code) {
519-
decoder->vtable.on_code((int)code_val, decoder->user_data);
514+
if (decoder->vtable.on_response) {
515+
decoder->vtable.on_response((int)code_val, decoder->user_data);
520516
}
521517

522518
s_set_line_state(decoder, s_linestate_header);

tests/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ file(GLOB TEST_HDRS "*.h")
55
file(GLOB TEST_SRC "*.c")
66
file(GLOB TESTS ${TEST_HDRS} ${TEST_SRC})
77

8-
add_test_case(http_test_get_method)
8+
add_test_case(http_test_get_request)
99
add_test_case(http_test_request_bad_version)
1010
add_test_case(http_test_response_bad_version)
11-
add_test_case(http_test_get_uri)
1211
add_test_case(http_test_get_status_code)
1312
add_test_case(http_test_overflow_scratch_space)
1413
add_test_case(http_test_receive_request_headers)

tests/test_decode.c

Lines changed: 32 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -49,50 +49,54 @@ static bool s_on_body_stub(const struct aws_byte_cursor *data, bool finished, vo
4949
return true;
5050
}
5151

52-
static void s_on_uri(struct aws_byte_cursor *uri, void *user_data) {
53-
struct aws_byte_cursor *ptr = (struct aws_byte_cursor *)user_data;
54-
if (ptr) {
55-
size_t len = ptr->len < uri->len ? ptr->len : uri->len;
56-
memcpy(ptr->ptr, uri->ptr, len);
57-
ptr->len = len;
58-
}
59-
}
60-
61-
static void s_on_uri_stub(struct aws_byte_cursor *uri, void *user_data) {
62-
(void)uri;
63-
(void)user_data;
64-
}
65-
66-
static void s_on_code(int code, void *user_data) {
52+
static void s_on_response(int code, void *user_data) {
6753
int *ptr = (int *)user_data;
6854
if (ptr) {
6955
*ptr = code;
7056
}
7157
}
7258

73-
static void s_on_code_stub(int code, void *user_data) {
59+
static void s_on_response_stub(int code, void *user_data) {
7460
(void)code;
7561
(void)user_data;
7662
}
7763

7864
struct request_data {
7965
enum aws_http_method method_enum;
8066
struct aws_byte_cursor method_str;
67+
struct aws_byte_cursor uri;
8168
uint8_t buffer[1024];
8269
};
8370

84-
static void s_on_method(enum aws_http_method method, const struct aws_byte_cursor *method_str, void *user_data) {
71+
static void s_on_request(
72+
enum aws_http_method method_enum,
73+
const struct aws_byte_cursor *method_str,
74+
const struct aws_byte_cursor *uri,
75+
void *user_data) {
76+
8577
struct request_data *request_data = (struct request_data *)user_data;
78+
assert(sizeof(request_data->buffer) >= uri->len + method_str->len);
8679
if (request_data) {
87-
request_data->method_enum = method;
80+
request_data->method_enum = method_enum;
81+
8882
memcpy(request_data->buffer, method_str->ptr, method_str->len);
8983
request_data->method_str = aws_byte_cursor_from_array(request_data->buffer, method_str->len);
84+
85+
uint8_t *uri_dst = request_data->buffer + method_str->len;
86+
memcpy(uri_dst, uri->ptr, uri->len);
87+
request_data->uri = aws_byte_cursor_from_array(uri_dst, uri->len);
9088
}
9189
}
9290

93-
static void s_on_method_stub(enum aws_http_method method, const struct aws_byte_cursor *method_str, void *user_data) {
94-
(void)method;
91+
static void s_on_request_stub(
92+
enum aws_http_method method_enum,
93+
const struct aws_byte_cursor *method_str,
94+
const struct aws_byte_cursor *uri,
95+
void *user_data) {
96+
97+
(void)method_enum;
9598
(void)method_str;
99+
(void)uri;
96100
(void)user_data;
97101
}
98102

@@ -115,14 +119,13 @@ static void s_common_test_setup(
115119
params->user_data = user_data;
116120
params->vtable.on_header = s_on_header_stub;
117121
params->vtable.on_body = s_on_body_stub;
118-
params->vtable.on_uri = s_on_uri_stub;
119-
params->vtable.on_code = s_on_code_stub;
120-
params->vtable.on_method = s_on_method_stub;
122+
params->vtable.on_request = s_on_request_stub;
123+
params->vtable.on_response = s_on_response_stub;
121124
params->vtable.on_done = s_on_done;
122125
}
123126

124-
AWS_TEST_CASE(http_test_get_method, s_http_test_get_method);
125-
static int s_http_test_get_method(struct aws_allocator *allocator, void *ctx) {
127+
AWS_TEST_CASE(http_test_get_request, s_http_test_get_request);
128+
static int s_http_test_get_request(struct aws_allocator *allocator, void *ctx) {
126129
(void)ctx;
127130

128131
struct request_data request_data;
@@ -131,7 +134,7 @@ static int s_http_test_get_method(struct aws_allocator *allocator, void *ctx) {
131134

132135
struct aws_http_decoder_params params;
133136
s_common_test_setup(allocator, 1024, &params, s_request, &request_data);
134-
params.vtable.on_method = s_on_method;
137+
params.vtable.on_request = s_on_request;
135138
struct aws_http_decoder *decoder = aws_http_decoder_new(&params);
136139

137140
size_t len = strlen(msg);
@@ -140,6 +143,8 @@ static int s_http_test_get_method(struct aws_allocator *allocator, void *ctx) {
140143

141144
ASSERT_TRUE(aws_byte_cursor_eq_c_str(&request_data.method_str, "HEAD"));
142145

146+
ASSERT_TRUE(aws_byte_cursor_eq_c_str(&request_data.uri, "/"));
147+
143148
aws_http_decoder_destroy(decoder);
144149
aws_http_library_clean_up();
145150
return AWS_OP_SUCCESS;
@@ -179,28 +184,6 @@ static int s_http_test_response_bad_version(struct aws_allocator *allocator, voi
179184
return AWS_OP_SUCCESS;
180185
}
181186

182-
AWS_TEST_CASE(http_test_get_uri, s_http_test_get_uri);
183-
static int s_http_test_get_uri(struct aws_allocator *allocator, void *ctx) {
184-
(void)ctx;
185-
186-
uint8_t buf[128];
187-
struct aws_byte_cursor uri_data = aws_byte_cursor_from_array(buf, 128);
188-
189-
const char *msg = s_typical_request;
190-
struct aws_http_decoder_params params;
191-
s_common_test_setup(allocator, 1024, &params, s_request, &uri_data);
192-
params.vtable.on_uri = s_on_uri;
193-
struct aws_http_decoder *decoder = aws_http_decoder_new(&params);
194-
195-
size_t len = strlen(msg);
196-
ASSERT_SUCCESS(aws_http_decode(decoder, msg, len, NULL));
197-
ASSERT_TRUE(aws_byte_cursor_eq_c_str(&uri_data, "/"));
198-
199-
aws_http_decoder_destroy(decoder);
200-
aws_http_library_clean_up();
201-
return AWS_OP_SUCCESS;
202-
}
203-
204187
AWS_TEST_CASE(http_test_get_status_code, s_http_test_get_status_code);
205188
static int s_http_test_get_status_code(struct aws_allocator *allocator, void *ctx) {
206189
(void)ctx;
@@ -210,7 +193,7 @@ static int s_http_test_get_status_code(struct aws_allocator *allocator, void *ct
210193
const char *msg = s_typical_response;
211194
struct aws_http_decoder_params params;
212195
s_common_test_setup(allocator, 1024, &params, s_response, &code);
213-
params.vtable.on_code = s_on_code;
196+
params.vtable.on_response = s_on_response;
214197
struct aws_http_decoder *decoder = aws_http_decoder_new(&params);
215198

216199
size_t len = strlen(msg);

0 commit comments

Comments
 (0)