diff --git a/README.md b/README.md index 8fda91e..ebc273b 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,46 @@ -Simple HTTP server ------------------- +# Simple HTTP server This is a very minimal HTTP server I use in some of the projects. Absolutely not ready for any kind of production use. -How to use ----------- + +# How to use Really, please see above note. This directory is an ESP-IDF component. Clone it (or add it as a submodule) into the component directory of the project. -Documentation -------------- +# Documentation None yet, but I tried to make the comments in the header file helpful. -Example -------- +# Examples + +Examples functions at http server + +## GET Method Example + +`simple_GET_method_example()` function: -None yet. +* Add http_server.c and http_server.h as a component into your project. +* Server initialization added into the example function, simply call it and it should work! +* Receiving a GET request at /, http server response is a "Hello World, from ESP32!" html. +## POST Method Example +`simple_POST_method_example()` function: +* As well as GET example, simply add http_server as a componente into your ESP-IDF project. +* Server initialization added into the POST example function, simply call it and don't worry. +* Post to / a pair of key-value where the key is 'key' and value some value you want to test. The example will show value content. If needed, increade log verbosity at `make menuconfig` to show all parsed key-value pairs. -Debugging ---------- +# Debugging Increasing log level to "Verbose" should produce lots of output related to request handling. -License -------- +# License GPL, see [LICENSE](LICENSE) file. Mostly because this is a very early version. Will be relicensed as something more reasonable later. diff --git a/http_server.c b/http_server.c index 6f2f24c..1c788b0 100644 --- a/http_server.c +++ b/http_server.c @@ -111,6 +111,25 @@ static esp_err_t add_keyval_pair(http_header_list_t *list, const char* name, con static const char* TAG = "http_server"; +const static char index_html[] = "" + "\n" + "\n" + " \n" + " \n" + "HELLO ESP32\n" + "\n" + "\n" + "

Hello World, from ESP32!

\n" + "\n" + "\n"; + +const static char response_OK[] = + "OK!\n"; + + esp_err_t http_register_handler(http_server_t server, const char* uri_pattern, int method, int events, http_handler_fn_t callback, void* callback_arg) @@ -388,6 +407,7 @@ const char* http_request_get_arg_value(http_context_t ctx, const char* name) { http_header_t* it; SLIST_FOREACH(it, &ctx->request_args, list_entry) { + ESP_LOGD(TAG, "Key %s: %s", it->name, it->value); if (strcasecmp(name, it->name) == 0) { return it->value; } @@ -415,7 +435,7 @@ static void form_data_handler_cb(http_context_t http_ctx, void* ctx) const char* str; size_t len; http_request_get_data(http_ctx, &str, &len); - parse_urlencoded_args(ctx, str, len); + parse_urlencoded_args(http_ctx, str, len); } } @@ -817,3 +837,71 @@ esp_err_t http_server_stop(http_server_t server) free(server); return ESP_OK; } + +static void cb_GET_method(http_context_t http_ctx, void* ctx) +{ + size_t response_size = strlen(index_html); + http_response_begin(http_ctx, 200, "text/html", response_size); + http_buffer_t http_index_html = { .data = index_html }; + http_response_write(http_ctx, &http_index_html); + http_response_end(http_ctx); +} + +esp_err_t simple_GET_method_example(void) +{ + http_server_t server; + http_server_options_t http_options = HTTP_SERVER_OPTIONS_DEFAULT(); + esp_err_t res; + + res = http_server_start(&http_options, &server); + if (res != ESP_OK) { + return res; + } + + res = http_register_handler(server, "/", HTTP_GET, HTTP_HANDLE_RESPONSE, &cb_GET_method, NULL); + if (res != ESP_OK) { + return res; + } + + return res; +} + +static void cb_POST_method(http_context_t http_ctx, void* ctx) +{ + const char* post_data; + + ESP_LOGI(TAG, "Received data from POST method..."); + + /*Receiving key from POST*/ + post_data = http_request_get_arg_value(http_ctx, "key"); + if(post_data!=NULL){ + ESP_LOGI(TAG, "Received %d bytes corresponding to the 'key': %s", strlen(post_data), post_data); + }else{ + ESP_LOGI(TAG, "Received NULL from POST method"); + } + + size_t response_size = strlen(response_OK); + http_response_begin(http_ctx, 201, "text/plain", response_size); + http_buffer_t http_response_OK = { .data = response_OK }; + http_response_write(http_ctx, &http_response_OK); + http_response_end(http_ctx); +} + +esp_err_t simple_POST_method_example(void) +{ + http_server_t server; + http_server_options_t http_options = HTTP_SERVER_OPTIONS_DEFAULT(); + esp_err_t res; + + res = http_server_start(&http_options, &server); + if (res != ESP_OK) { + return res; + } + + res = http_register_form_handler(server, "/", HTTP_POST, HTTP_HANDLE_RESPONSE, &cb_POST_method, NULL); + if (res != ESP_OK) { + return res; + } + + return res; +} diff --git a/http_server.h b/http_server.h index 9c109d8..1ed846b 100644 --- a/http_server.h +++ b/http_server.h @@ -285,6 +285,24 @@ esp_err_t http_response_write(http_context_t http_ctx, const http_buffer_t* buff */ esp_err_t http_response_end(http_context_t http_ctx); +/** + * @brief Example of GET method. Responding a simple "Hello World" html. All initializations included. + * @param none + * @return + * - ESP_OK on success + * - other errors in the future? + */ +esp_err_t simple_GET_method_example(void); + +/** + * @brief Example of POST method. Send a application/x-www-form-urlencoded pair key-value where the key is 'key' and some value for it. The value is printed and the server responds a 201 code and a OK message. + * @param none + * @return + * - ESP_OK on success + * - other errors in the future? + */ +esp_err_t simple_POST_method_example(void); + #ifdef __cplusplus } #endif