bakalarka/components/https_server/https_server.c
2020-03-20 18:01:25 +01:00

224 lines
6.6 KiB
C

/* Simple HTTP + SSL Server Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "esp_console.h"
#include "string.h"
#include "url_decoder.h"
#include <esp_https_server.h>
/* A simple example that demonstrates how to create GET and POST
* handlers and start an HTTPS server.
*/
struct csr{
char* var;
char* begin;
char* body;
char* end;
};
static const char *TAG = "server";
TaskHandle_t xHandleServer = NULL;
/* An HTTP GET handler */
static esp_err_t root_get_handler(httpd_req_t *req)
{
httpd_resp_set_type(req, "text/html");
httpd_resp_send(req, "<form action=\"/echo\" method=\"post\">\n"
" <label for=\"csr\">First name:</label><br>\n"
" <input type=\"text\" id=\"csr\" name=\"csr\" value=\"John\"><br>\n"
" <input type=\"submit\" value=\"Submit\">\n"
"</form>", -1); // -1 = use strlen()
return ESP_OK;
}
static esp_err_t echo_post_handler(httpd_req_t *req)
{
char buf[3000];
int ret, remaining = req->content_len;
memset(buf,'\0',sizeof(buf));
while (remaining > 0) {
/* Read the data for the request */
if ((ret = httpd_req_recv(req, buf,
MIN(remaining, sizeof(buf)))) <= 0) {
if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
/* Retry receiving if timeout occurred */
continue;
}
return ESP_FAIL;
}
/* Send back the same data */
//const char *url = "http%3A%2F%2ffoo+bar%2fabcd";
//char out[strlen(url) + 1];
//printf("length: %d\n", decode(buf, 0));
//puts(decode(buf, out) < 0 ? "bad string" : out);
/* Log data received */
ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
ESP_LOGI(TAG, "%.*s", ret, buf);
ESP_LOGI(TAG, "====================================");
const char *url = &buf[4];
char out[strlen(url) + 1];
printf("length: %d\n", decode(url, 0));
printf("%s\n",url);
printf("%s\n",decode(url, out) < 0 ? "bad string" : out);
httpd_resp_send_chunk(req, out, strlen(out));
remaining -= ret;
}
// End response
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
static const httpd_uri_t echo = {
.uri = "/echo",
.method = HTTP_POST,
.handler = echo_post_handler,
.user_ctx = NULL
};
static const httpd_uri_t root = {
.uri = "/",
.method = HTTP_GET,
.handler = root_get_handler
};
static httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
// Start the httpd server
ESP_LOGI(TAG, "Starting server");
httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();
conf.httpd.stack_size = 30000;
extern const unsigned char cacert_pem_start[] asm("_binary_cacert_pem_start");
extern const unsigned char cacert_pem_end[] asm("_binary_cacert_pem_end");
conf.cacert_pem = cacert_pem_start;
conf.cacert_len = cacert_pem_end - cacert_pem_start;
extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end");
conf.prvtkey_pem = prvtkey_pem_start;
conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
esp_err_t ret = httpd_ssl_start(&server, &conf);
if (ESP_OK != ret) {
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &root);
httpd_register_uri_handler(server, &echo);
return server;
}
static void stop_webserver(httpd_handle_t server)
{
// Stop the httpd server
httpd_ssl_stop(server);
}
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
stop_webserver(*server);
*server = NULL;
}
}
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
*server = start_webserver();
}
}
static void connect(void)
{
static httpd_handle_t server = NULL;
// ESP_ERROR_CHECK(nvs_flash_init());
// ESP_ERROR_CHECK(esp_netif_init());
// ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Register event handlers to start server when Wi-Fi or Ethernet is connected,
* and stop server when disconnection happens.
*/
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
//ESP_ERROR_CHECK(example_connect());
//start_webserver();
/*
for(;;){
vTaskDelay(40);
}
*/
}
static void server_off(){
vTaskDelete(xHandleServer);
}
void register_server(void)
{
const esp_console_cmd_t webserver_on = {
.command = "server_on",
.help = "HTTPS server",
.hint = NULL,
.func = &connect,
.argtable = NULL
};
const esp_console_cmd_t webserver_off = {
.command = "server_off",
.help = "HTTPS server",
.hint = NULL,
.func = &server_off,
.argtable = NULL
};
ESP_ERROR_CHECK(esp_console_cmd_register(&webserver_on));
ESP_ERROR_CHECK(esp_console_cmd_register(&webserver_off));
}