From 71a6ee16332ce3fb9a1deffdd2f86cb22513a389 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Sat, 14 Mar 2020 16:32:48 -0400 Subject: [PATCH] chore: cleanup http namespace --- runtime/include/http_api.h | 41 +++--- runtime/include/http_parser_settings.h | 176 ++++++++++++++++++++++++ runtime/src/http.c | 180 ++----------------------- runtime/src/runtime.c | 7 +- runtime/src/sandbox.c | 4 +- 5 files changed, 213 insertions(+), 195 deletions(-) create mode 100644 runtime/include/http_parser_settings.h diff --git a/runtime/include/http_api.h b/runtime/include/http_api.h index 2961920..bed34fb 100644 --- a/runtime/include/http_api.h +++ b/runtime/include/http_api.h @@ -6,7 +6,7 @@ /*************************************************** * General HTTP Request Functions * **************************************************/ -int http_request_body_get_sb(struct sandbox *sandbox, char **body); +int sandbox__get_http_request_body(struct sandbox *sandbox, char **body); /** * Gets the HTTP Request body from the current sandbox @@ -14,18 +14,18 @@ int http_request_body_get_sb(struct sandbox *sandbox, char **body); * @returns the length of the http_request's body **/ static inline int -http_request_body_get(char **body) +current_sandbox__get_http_request_body(char **body) { - return http_request_body_get_sb(get_current_sandbox(), body); + return sandbox__get_http_request_body(get_current_sandbox(), body); } /*************************************************** * General HTTP Response Functions * **************************************************/ -int http_response_header_set_sb(struct sandbox *sandbox, char *h, int length); -int http_response_body_set_sb(struct sandbox *sandbox, char *body, int length); -int http_response_status_set_sb(struct sandbox *sandbox, char *status, int length); -int http_response_vector_sb(struct sandbox *sandbox); +int sandbox__set_http_response_header(struct sandbox *sandbox, char *h, int length); +int sandbox__set_http_response_body(struct sandbox *sandbox, char *body, int length); +int sandbox__set_http_response_status(struct sandbox *sandbox, char *status, int length); +int sandbox__vectorize_http_response(struct sandbox *sandbox); /** * Set an HTTP Response Header on the current sandbox @@ -34,9 +34,9 @@ int http_response_vector_sb(struct sandbox *sandbox); * @returns 0 (abends program in case of error) **/ static inline int -http_response_header_set(char *header, int length) +current_sandbox__set_http_response_header(char *header, int length) { - return http_response_header_set_sb(get_current_sandbox(), header, length); + return sandbox__set_http_response_header(get_current_sandbox(), header, length); } /** @@ -46,9 +46,9 @@ http_response_header_set(char *header, int length) * @returns 0 (abends program in case of error) **/ static inline int -http_response_body_set(char *body, int length) +current_sandbox__set_http_response_body(char *body, int length) { - return http_response_body_set_sb(get_current_sandbox(), body, length); + return sandbox__set_http_response_body(get_current_sandbox(), body, length); } /** @@ -58,9 +58,9 @@ http_response_body_set(char *body, int length) * @returns 0 (abends program in case of error) **/ static inline int -http_response_status_set(char *status, int length) +current_sandbox__set_http_response_status(char *status, int length) { - return http_response_status_set_sb(get_current_sandbox(), status, length); + return sandbox__set_http_response_status(get_current_sandbox(), status, length); } /** @@ -68,16 +68,19 @@ http_response_status_set(char *status, int length) * @returns the number of buffers used to store the HTTP Response **/ static inline int -http_response_vector(void) +current_sandbox__vectorize_http_response(void) { - return http_response_vector_sb(get_current_sandbox()); + return sandbox__vectorize_http_response(get_current_sandbox()); } /*********************************************************************** * http-parser Setup and Excute * **********************************************************************/ -void http_init(void); -int http_request_parse_sb(struct sandbox *sandbox, size_t l); +// void global__http_parser_settings__initialize_and_register_callbacks(void); + +extern http_parser_settings global__http_parser_settings; + +int sandbox__parse_http_request(struct sandbox *sandbox, size_t l); /** * Parse the current sandbox's request_response_data up to length @@ -85,9 +88,9 @@ int http_request_parse_sb(struct sandbox *sandbox, size_t l); * @returns 0 **/ static inline int -http_request_parse(size_t length) +current_sandbox__parse_http_request(size_t length) { - return http_request_parse_sb(get_current_sandbox(), length); + return sandbox__parse_http_request(get_current_sandbox(), length); } #endif /* SRFT_HTTP_API_H */ diff --git a/runtime/include/http_parser_settings.h b/runtime/include/http_parser_settings.h new file mode 100644 index 0000000..22c0b60 --- /dev/null +++ b/runtime/include/http_parser_settings.h @@ -0,0 +1,176 @@ +#ifndef SRFT_HTTP_PARSER_SETTINGS_H +#define SRFT_HTTP_PARSER_SETTINGS_H + +#include +#include +#include +#include + +/*********************************************************************** + * http-parser Callbacks in lifecycle order * + **********************************************************************/ + +/** + * http-parser data callback called when a URL is called + * Sanity check to make sure that the path matches the name of the module + * TODO: Why does this not fail this assertion? To execute fibonacci, I just request localhost:10000, not localhost:10000/fibonacci + * @param parser + * @param at the start of the URL + * @param length the length of the URL + * @returns 0 + **/ +static inline int +http_parser_settings__on_url(http_parser *parser, const char *at, size_t length) +{ + struct sandbox *sandbox = (struct sandbox *) parser->data; + + assert(strncmp(sandbox->module->name, (at + 1), length - 1) == 0); + return 0; +} + +/** + * http-parser callback called when parsing of a new message begins + * Sets the HTTP Request's message_begin and last_was_value flags to true + * @param parser + **/ +static inline int +http_parser_settings__on_message_begin(http_parser *parser) +{ + struct sandbox * sandbox = (struct sandbox *) parser->data; + struct http_request *http_request = &sandbox->http_request; + + http_request->message_begin = 1; + http_request->last_was_value = 1; // should always start with a header.. + return 0; +} + +/** + * http-parser callback called when a header field is parsed + * Sets the key value of the latest header + * on a new header if last_was_value is true + * updating an existing header if last_was_value is false + * TODO: Is this logic correct? What is the relationship between fields and values? Is overwrite the correct logic if on_header executes twice in a row? + * @param parser + * @param at start address of the header field + * @param length length of the header field + * @returns 0 + **/ +static inline int +http_parser_settings__on_header_field(http_parser *parser, const char *at, size_t length) +{ + struct sandbox * sandbox = (struct sandbox *) parser->data; + struct http_request *http_request = &sandbox->http_request; + + if (http_request->last_was_value) http_request->header_count++; + assert(http_request->header_count <= HTTP_HEADERS_MAX); + assert(length < HTTP_HEADER_MAXSZ); + + http_request->last_was_value = 0; + http_request->headers[http_request->header_count - 1].key = (char *)at; // it is from the sandbox's request_response_data, should persist. + + return 0; +} + +/** + * http-parser callback called when a header value is parsed + * Writes the value to the latest header and sets last_was_value to true + * @param parser + * @param at start address of the header value + * @param length length of the header value + * @returns 0 + **/ +static inline int +http_parser_settings__on_header_value(http_parser *parser, const char *at, size_t length) +{ + struct sandbox * sandbox = (struct sandbox *) parser->data; + struct http_request *http_request = &sandbox->http_request; + + http_request->last_was_value = 1; + assert(http_request->header_count <= HTTP_HEADERS_MAX); + assert(length < HTTP_HEADERVAL_MAXSZ); + + http_request->headers[http_request->header_count - 1].value = (char *)at; // it is from the sandbox's request_response_data, should persist. + + return 0; +} + +/** + * http-parser callback called when header parsing is complete + * Just sets the HTTP Request's header_end flag to true + * @param parser + **/ +static inline int +http_parser_settings__on_header_end(http_parser *parser) +{ + struct sandbox * sandbox = (struct sandbox *) parser->data; + struct http_request *http_request = &sandbox->http_request; + + http_request->header_end = 1; + return 0; +} + +/** + * http-parser callback called for HTTP Bodies + * Assigns the parsed data to the http_request body of the sandbox struct + * @param parser + * @param at + * @param length + * @returns 0 + **/ +static inline int +http_parser_settings__on_body(http_parser *parser, const char *at, size_t length) +{ + struct sandbox * sandbox = (struct sandbox *) parser->data; + struct http_request *http_request = &sandbox->http_request; + + assert(http_request->body_length + length <= sandbox->module->max_request_size); + if (!http_request->body) + http_request->body = (char *)at; + else + assert(http_request->body + http_request->body_length == at); + + http_request->body_length += length; + + return 0; +} + +/** + * Sets the HTTP Request's message_end flag to true + * @param parser + **/ +static inline int +http_parser_settings__on_msg_end(http_parser *parser) +{ + struct sandbox * sandbox = (struct sandbox *) parser->data; + struct http_request *http_request = &sandbox->http_request; + + http_request->message_end = 1; + return 0; +} + +/*********************************************************************** + * http-parser Setup and Excute * + **********************************************************************/ + +/** + * The settings global with the Callback Functions for HTTP Events + */ +void +http_parser_settings__register_callbacks(http_parser_settings *settings) +{ + settings->on_url = http_parser_settings__on_url; + settings->on_message_begin = http_parser_settings__on_message_begin; + settings->on_header_field = http_parser_settings__on_header_field; + settings->on_header_value = http_parser_settings__on_header_value; + settings->on_headers_complete = http_parser_settings__on_header_end; + settings->on_body = http_parser_settings__on_body; + settings->on_message_complete = http_parser_settings__on_msg_end; +} + +void +http_parser_settings__initialize(http_parser_settings *settings) +{ + http_parser_settings_init(settings); +} + +#endif /* SRFT_HTTP_PARSER_SETTINGS_H */ diff --git a/runtime/src/http.c b/runtime/src/http.c index 2dab6bb..e91dfa8 100644 --- a/runtime/src/http.c +++ b/runtime/src/http.c @@ -3,8 +3,6 @@ #include #include -http_parser_settings settings; - /*************************************************** * General HTTP Request Functions * **************************************************/ @@ -16,7 +14,7 @@ http_parser_settings settings; * @returns the length of the http_request's body **/ int -http_request_body_get_sb(struct sandbox *sandbox, char **body) +sandbox__get_http_request_body(struct sandbox *sandbox, char **body) { struct http_request *http_request = &sandbox->http_request; @@ -36,7 +34,7 @@ http_request_body_get_sb(struct sandbox *sandbox, char **body) * @returns 0 (abends program in case of error) **/ int -http_response_header_set_sb(struct sandbox *sandbox, char *header, int length) +sandbox__set_http_response_header(struct sandbox *sandbox, char *header, int length) { // by now, request_response_data should only be containing response! struct http_response *http_response = &sandbox->http_response; @@ -57,7 +55,7 @@ http_response_header_set_sb(struct sandbox *sandbox, char *header, int length) * @returns 0 (abends program in case of error) **/ int -http_response_body_set_sb(struct sandbox *sandbox, char *body, int length) +sandbox__set_http_response_body(struct sandbox *sandbox, char *body, int length) { struct http_response *http_response = &sandbox->http_response; @@ -76,7 +74,7 @@ http_response_body_set_sb(struct sandbox *sandbox, char *body, int length) * @returns 0 (abends program in case of error) **/ int -http_response_status_set_sb(struct sandbox *sandbox, char *status, int length) +sandbox__set_http_response_status(struct sandbox *sandbox, char *status, int length) { struct http_response *http_response = &sandbox->http_response; @@ -92,7 +90,7 @@ http_response_status_set_sb(struct sandbox *sandbox, char *status, int length) * @returns the number of buffers used to store the HTTP Response **/ int -http_response_vector_sb(struct sandbox *sandbox) +sandbox__vectorize_http_response(struct sandbox *sandbox) { int buffer_count = 0; struct http_response *http_response = &sandbox->http_response; @@ -137,181 +135,19 @@ http_response_vector_sb(struct sandbox *sandbox) return buffer_count; } -/*********************************************************************** - * http-parser Callbacks in lifecycle order * - **********************************************************************/ - -/** - * http-parser data callback called when a URL is called - * Sanity check to make sure that the path matches the name of the module - * TODO: Why does this not fail this assertion? To execute fibonacci, I just request localhost:10000, not localhost:10000/fibonacci - * @param parser - * @param at the start of the URL - * @param length the length of the URL - * @returns 0 - **/ -static inline int -http_on_url(http_parser *parser, const char *at, size_t length) -{ - struct sandbox *sandbox = parser->data; - - assert(strncmp(sandbox->module->name, (at + 1), length - 1) == 0); - return 0; -} - -/** - * http-parser callback called when parsing of a new message begins - * Sets the HTTP Request's message_begin and last_was_value flags to true - * @param parser - **/ -static inline int -http_on_msg_begin(http_parser *parser) -{ - struct sandbox * sandbox = parser->data; - struct http_request *http_request = &sandbox->http_request; - - http_request->message_begin = 1; - http_request->last_was_value = 1; // should always start with a header.. - return 0; -} - -/** - * http-parser callback called when a header field is parsed - * Sets the key value of the latest header - * on a new header if last_was_value is true - * updating an existing header if last_was_value is false - * TODO: Is this logic correct? What is the relationship between fields and values? Is overwrite the correct logic if on_header executes twice in a row? - * @param parser - * @param at start address of the header field - * @param length length of the header field - * @returns 0 - **/ -static inline int -http_on_header_field(http_parser *parser, const char *at, size_t length) -{ - struct sandbox * sandbox = parser->data; - struct http_request *http_request = &sandbox->http_request; - - if (http_request->last_was_value) http_request->header_count++; - assert(http_request->header_count <= HTTP_HEADERS_MAX); - assert(length < HTTP_HEADER_MAXSZ); - - http_request->last_was_value = 0; - http_request->headers[http_request->header_count - 1].key = (char *)at; // it is from the sandbox's request_response_data, should persist. - - return 0; -} - -/** - * http-parser callback called when a header value is parsed - * Writes the value to the latest header and sets last_was_value to true - * @param parser - * @param at start address of the header value - * @param length length of the header value - * @returns 0 - **/ -static inline int -http_on_header_value(http_parser *parser, const char *at, size_t length) -{ - struct sandbox * sandbox = parser->data; - struct http_request *http_request = &sandbox->http_request; - - http_request->last_was_value = 1; - assert(http_request->header_count <= HTTP_HEADERS_MAX); - assert(length < HTTP_HEADERVAL_MAXSZ); - - http_request->headers[http_request->header_count - 1].value = (char *)at; // it is from the sandbox's request_response_data, should persist. - - return 0; -} - -/** - * http-parser callback called when header parsing is complete - * Just sets the HTTP Request's header_end flag to true - * @param parser - **/ -static inline int -http_on_header_end(http_parser *parser) -{ - struct sandbox * sandbox = parser->data; - struct http_request *http_request = &sandbox->http_request; - - http_request->header_end = 1; - return 0; -} - -/** - * http-parser callback called for HTTP Bodies - * Assigns the parsed data to the http_request body of the sandbox struct - * @param parser - * @param at - * @param length - * @returns 0 - **/ -static inline int -http_on_body(http_parser *parser, const char *at, size_t length) -{ - struct sandbox * sandbox = parser->data; - struct http_request *http_request = &sandbox->http_request; - - assert(http_request->body_length + length <= sandbox->module->max_request_size); - if (!http_request->body) - http_request->body = (char *)at; - else - assert(http_request->body + http_request->body_length == at); - - http_request->body_length += length; - - return 0; -} - -/** - * Sets the HTTP Request's message_end flag to true - * @param parser - **/ -static inline int -http_on_msg_end(http_parser *parser) -{ - struct sandbox * sandbox = parser->data; - struct http_request *http_request = &sandbox->http_request; - - http_request->message_end = 1; - return 0; -} - -/*********************************************************************** - * http-parser Setup and Excute * - **********************************************************************/ - -/** - * The settings global with the Callback Functions for HTTP Events - */ -void -http_init(void) -{ - http_parser_settings_init(&settings); - settings.on_url = http_on_url; - settings.on_message_begin = http_on_msg_begin; - settings.on_header_field = http_on_header_field; - settings.on_header_value = http_on_header_value; - settings.on_headers_complete = http_on_header_end; - settings.on_body = http_on_body; - settings.on_message_complete = http_on_msg_end; -} - /** * Run the http-parser on the sandbox's request_response_data using the configured settings global * @param sandbox the sandbox containing the req_resp data that we want to parse * @param length The size of the request_response_data that we want to parse * @returns 0 * - * Global State: settings + * Globals: global__http_parser_settings **/ int -http_request_parse_sb(struct sandbox *sandbox, size_t length) +sandbox__parse_http_request(struct sandbox *sandbox, size_t length) { // Why is our start address sandbox->request_response_data + sandbox->request_response_data_length? // it's like a cursor to keep track of what we've read so far - http_parser_execute(&sandbox->http_parser, &settings, sandbox->request_response_data + sandbox->request_response_data_length, length); + http_parser_execute(&sandbox->http_parser, &global__http_parser_settings, sandbox->request_response_data + sandbox->request_response_data_length, length); return 0; } diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index f3a43b7..8fb5087 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -11,6 +11,7 @@ #include #include +#include "http_parser_settings.h" #include "sandbox_request.h" /*************************** @@ -20,6 +21,7 @@ struct deque_sandbox *global_deque; pthread_mutex_t global_deque_mutex = PTHREAD_MUTEX_INITIALIZER; int epoll_file_descriptor; +http_parser_settings global__http_parser_settings; /****************************************** * Shared Process / Listener Thread Logic * @@ -44,8 +46,9 @@ initialize_runtime(void) softint_mask(SIGUSR1); softint_mask(SIGALRM); - // Initialize http-parser - http_init(); + // Initialize http_parser_settings global + http_parser_settings__initialize(&global__http_parser_settings); + http_parser_settings__register_callbacks(&global__http_parser_settings); } /******************************** diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index e926c31..95c2b32 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -27,7 +27,7 @@ on_libuv_read_parse_http_request(uv_stream_t *stream, ssize_t number_read, const // Parse the chunks libuv has read on our behalf until we've parse to message end if (number_read > 0) { - if (http_request_parse_sb(sandbox, number_read) != 0) return; + if (sandbox__parse_http_request(sandbox, number_read) != 0) return; sandbox->request_response_data_length += number_read; struct http_request *rh = &sandbox->http_request; if (!rh->message_end) return; @@ -181,7 +181,7 @@ receive_and_parse_current_sandbox_client_request(void) return r; } while (r > 0) { - if (http_request_parse(r) != 0) return -1; + if (current_sandbox__parse_http_request(r) != 0) return -1; curr->request_response_data_length += r; struct http_request *rh = &curr->http_request; if (rh->message_end) break;