85 lines
4.0 KiB
C
85 lines
4.0 KiB
C
/* SPDX-License-Identifier: GPL-3.0-only */
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/select.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
typedef int esp_err_t;
|
|
enum { ESP_OK, ESP_FAIL, ESP_ERR_INVALID_ARG, ESP_ERR_INVALID_STATE,
|
|
ESP_ERR_NO_MEM, ESP_ERR_TIMEOUT, ESP_ERR_NOT_SUPPORTED };
|
|
typedef void *httpd_handle_t;
|
|
typedef struct { int unused; } httpd_uri_t;
|
|
struct httpd_req_aux;
|
|
typedef struct { httpd_handle_t handle; struct httpd_req_aux *aux; } httpd_req_t;
|
|
struct sock_db {
|
|
int fd; uint64_t lru_counter; bool for_async_req, ws_handshake_done, ws_close;
|
|
size_t pending_len; int (*pending_fn)(httpd_handle_t, int);
|
|
};
|
|
struct httpd_req_aux { struct sock_db *sd; size_t remaining_len; };
|
|
struct httpd_data {
|
|
struct { unsigned max_open_sockets; } config;
|
|
struct { void *handle; } hd_td;
|
|
struct sock_db *hd_sd;
|
|
struct httpd_req_aux hd_req_aux;
|
|
httpd_req_t hd_req;
|
|
uint64_t lru_counter;
|
|
};
|
|
static bool owner;
|
|
static unsigned lock_depth, shutdown_calls, select_calls;
|
|
static int shutdown_error, select_error, tls_pending[FD_SETSIZE];
|
|
static int64_t now_us;
|
|
static void *httpd_os_thread_handle(void) { return owner ? (void *)1 : (void *)2; }
|
|
typedef int portMUX_TYPE;
|
|
#define portMUX_INITIALIZER_UNLOCKED 0
|
|
#define taskENTER_CRITICAL(lock) do { (void)(lock); assert(!lock_depth); ++lock_depth; } while (0)
|
|
#define taskEXIT_CRITICAL(lock) do { (void)(lock); assert(lock_depth == 1); --lock_depth; } while (0)
|
|
static int64_t esp_timer_get_time(void) { assert(!lock_depth); return now_us; }
|
|
static void (*delay_hook)(void);
|
|
static void vTaskDelay(int ticks) { assert(!lock_depth && ticks == 1); now_us += 100000; if (delay_hook) delay_hook(); }
|
|
typedef void *esp_timer_handle_t;
|
|
typedef struct { void (*callback)(void *); const char *name; bool skip_unhandled_events; } esp_timer_create_args_t;
|
|
static esp_err_t timer_create_error, timer_start_error, queue_error;
|
|
static unsigned timer_creates, timer_starts, timer_deletes, queue_calls;
|
|
static void (*timer_callback)(void *), (*queued_work)(void *);
|
|
static void *queued_arg;
|
|
static void (*queue_hook)(void);
|
|
static bool inline_work;
|
|
static esp_err_t esp_timer_create(const esp_timer_create_args_t *args, esp_timer_handle_t *timer) {
|
|
assert(!lock_depth && args->skip_unhandled_events); ++timer_creates;
|
|
if (timer_create_error) return timer_create_error;
|
|
timer_callback = args->callback; *timer = (void *)3; return ESP_OK;
|
|
}
|
|
static esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, int64_t period) {
|
|
assert(!lock_depth && timer && period == 1000000); ++timer_starts; return timer_start_error;
|
|
}
|
|
static esp_err_t esp_timer_delete(esp_timer_handle_t timer) { assert(!lock_depth && timer); ++timer_deletes; return ESP_OK; }
|
|
static esp_err_t httpd_queue_work(httpd_handle_t, void (*)(void *), void *);
|
|
typedef struct { int fd; bool get_error; } esp_tls_t;
|
|
enum { HTTPD_SSL_USER_CB_SESS_CREATE, HTTPD_SSL_USER_CB_SESS_CLOSE };
|
|
typedef struct { esp_tls_t *tls; unsigned user_cb_state; } esp_https_server_user_cb_arg_t;
|
|
static esp_err_t esp_tls_get_conn_sockfd(esp_tls_t *tls, int *fd) {
|
|
assert(owner && !lock_depth); *fd = tls->fd; return tls->get_error ? ESP_FAIL : ESP_OK;
|
|
}
|
|
static int test_select(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) {
|
|
assert(owner && !lock_depth && !w && !e && t && !t->tv_sec && !t->tv_usec);
|
|
++select_calls; return select_error ? -1 : select(n, r, w, e, t);
|
|
}
|
|
static int test_shutdown(int fd, int how) {
|
|
assert(owner && !lock_depth && how == SHUT_RDWR); ++shutdown_calls;
|
|
return shutdown_error ? -1 : shutdown(fd, how);
|
|
}
|
|
#define select test_select
|
|
#define shutdown test_shutdown
|
|
#define CONFIG_HTTPD_PURGE_BUF_LEN 32
|
|
#define ESP_LOGD(...) ((void)0)
|
|
#define ESP_LOG_BUFFER_HEX_LEVEL(...) ((void)0)
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
static esp_err_t httpd_req_new(struct httpd_data *, struct sock_db *);
|
|
static int httpd_req_recv(httpd_req_t *, char *, size_t);
|
|
static void httpd_req_cleanup(httpd_req_t *);
|