0
0
Fork 0
wireless-proxy-esp32/project_components/web_server/web_server.c

131 lines
3.0 KiB
C

#include "web_server.h"
#include "web_uri_module.h"
#include <esp_http_server.h>
#include <esp_event.h>
#include <esp_system.h>
#include <esp_log.h>
#include <sys/unistd.h>
#define TAG "web server"
#define MAKE_U32(b0, b1, b2, b3) ((b0) | (b1) << 8 | (b2) << 16 | (b3) << 24)
#define URI_WS_STR MAKE_U32('/', 'w', 's', '\0')
#define URI_API_STR MAKE_U32('/', 'a', 'p', 'i')
static httpd_handle_t http_server = NULL;
/**
* 3 types of ref:
* - 1. "/"
* - 2. "/entry"
* - 3. "/dir/"
* 4 types of target
* - 1. "/.*"
* - 2. "/entry"
* - 2. "/dir/"
* - 3. "/dir/.*"
* */
static bool uri_match(const char *reference_uri, const char *uri_to_match, size_t match_upto)
{
const uint32_t *ptr32_ref = (const uint32_t *) reference_uri;
const uint32_t *ptr32_target = (const uint32_t *) uri_to_match;
size_t ref_length;
/* optimized for /ws quick access */
if (likely(match_upto == 3)) {
if (likely(*ptr32_ref == URI_WS_STR)) {
ESP_LOGI(TAG, "cmp ws");
return *ptr32_target == *ptr32_ref;
}
}
/* ref should be shorter than target */
ref_length = strlen(reference_uri);
if (ref_length > match_upto) {
ESP_LOGI(TAG, "no match length");
return false;
}
// strict matching "/entry" for ref = "/entry"
if (ref_length == match_upto) {
if (memcmp(reference_uri, uri_to_match, ref_length) == 0) {
ESP_LOGI(TAG, "strict match %s", reference_uri);
return true;
}
}
// if ref = /dir/ targets are /dir/ and /dir/*
if (reference_uri[ref_length - 1] == '/' && ref_length > 1) {
if (memcmp(reference_uri, uri_to_match, ref_length) == 0) {
ESP_LOGI(TAG, "match /dir/");
return true;
} else {
ESP_LOGI(TAG, "no match /dir/");
return false;
}
}
/* Fall back to root pages */
// match /* when ref if /
if (reference_uri[ref_length - 1] == '/') {
ESP_LOGI(TAG, "match /");
return true;
}
ESP_LOGI(TAG, "fall back false");
return false;
}
static int8_t opened_socket = 0;
static esp_err_t web_server_on_open(httpd_handle_t hd, int sockfd)
{
opened_socket++;
printf("%d open, now: %d\n", sockfd, opened_socket);
return ESP_OK;
}
static void web_server_on_close(httpd_handle_t hd, int sockfd)
{
opened_socket--;
printf("%d closed, now: %d\n", sockfd, opened_socket);
close(sockfd);
}
void start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
int err;
config.enable_so_linger = true;
config.linger_timeout = 0;
config.lru_purge_enable = true;
config.uri_match_fn = uri_match;
config.open_fn = web_server_on_open;
config.close_fn = web_server_on_close;
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if ((err = httpd_start(&server, &config) != ESP_OK)) {
ESP_LOGE(TAG, "Error starting server!");
ESP_ERROR_CHECK(err);
}
ESP_LOGI(TAG, "Registering URI handlers");
uri_module_init(server);
http_server = server;
}
static esp_err_t stop_webserver(httpd_handle_t server)
{
// Stop the httpd server
return httpd_stop(server);
}
int server_is_running()
{
return http_server != NULL;
}