add webserver components, some webserver fices and improvements in templating, add real time history chart
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
#ifndef HTTPD_UTILS_CAPTIVE_H
|
||||
#define HTTPD_UTILS_CAPTIVE_H
|
||||
|
||||
#include <esp_http_server.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
/**
|
||||
* Redirect if needed when a captive portal capture is detected
|
||||
*
|
||||
* @param r
|
||||
* @return ESP_OK on redirect, ESP_ERR_NOT_FOUND if not needed, other error on failure
|
||||
*/
|
||||
esp_err_t httpd_captive_redirect(httpd_req_t *r);
|
||||
|
||||
/**
|
||||
* Get URL to redirect to. WEAK.
|
||||
*
|
||||
* @param r
|
||||
* @param buf
|
||||
* @param maxlen
|
||||
* @return http(s)://foo.bar/
|
||||
*/
|
||||
esp_err_t httpd_captive_redirect_get_url(httpd_req_t *r, char *buf, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Get captive portal domain. WEAK.
|
||||
*
|
||||
* @return foo.bar
|
||||
*/
|
||||
const char * httpd_captive_redirect_get_domain();
|
||||
|
||||
#endif //HTTPD_UTILS_CAPTIVE_H
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef HTTPD_FDIPV4_H
|
||||
#define HTTPD_FDIPV4_H
|
||||
|
||||
/**
|
||||
* Get IP address for a FD
|
||||
*
|
||||
* @param fd
|
||||
* @param[out] ipv4
|
||||
* @return success
|
||||
*/
|
||||
esp_err_t fd_to_ipv4(int fd, in_addr_t *ipv4);
|
||||
|
||||
#endif //HTTPD_FDIPV4_H
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef HTTPD_UTILS_REDIRECT_H
|
||||
#define HTTPD_UTILS_REDIRECT_H
|
||||
|
||||
#include <esp_http_server.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
/**
|
||||
* Redirect to other URI - sends a HTTP response from the http server
|
||||
*
|
||||
* @param r - request
|
||||
* @param uri - target uri
|
||||
* @return success
|
||||
*/
|
||||
esp_err_t httpd_redirect_to(httpd_req_t *r, const char *uri);
|
||||
|
||||
#endif // HTTPD_UTILS_REDIRECT_H
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Session store system main include file
|
||||
*
|
||||
* Created on 2019/07/13.
|
||||
*/
|
||||
|
||||
#ifndef HTTPD_UTILS_SESSION_H
|
||||
#define HTTPD_UTILS_SESSION_H
|
||||
|
||||
#include "session_kvmap.h"
|
||||
#include "session_store.h"
|
||||
|
||||
// Customary keys
|
||||
|
||||
/** Session key for OK flash message */
|
||||
#define SESS_FLASH_OK "flash_ok"
|
||||
/** Session key for error flash message */
|
||||
#define SESS_FLASH_ERR "flash_err"
|
||||
/** Session key for a "logged in" flag. Value is 1 if logged in. */
|
||||
#define SESS_AUTHED "authed"
|
||||
|
||||
// ..
|
||||
|
||||
/**
|
||||
* Redirect to /login form if unauthed,
|
||||
* but also retrieve the session key-value store for further use
|
||||
*/
|
||||
#define HTTP_GET_AUTHED_SESSION(kvstore, r) do { \
|
||||
kvstore = httpd_req_find_session_and((r), SESS_GET_DATA); \
|
||||
if (NULL == kvstore || NULL == sess_kv_map_get(kvstore, SESS_AUTHED)) { \
|
||||
return httpd_redirect_to((r), "/login"); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Start or resume a session without checking for authed status.
|
||||
* When started, the session cookie is added to the response immediately.
|
||||
*
|
||||
* @param[out] kvstore - a place to store the allocated or retrieved session kvmap
|
||||
* @param[in] r - request
|
||||
* @return success
|
||||
*/
|
||||
esp_err_t HTTP_GET_SESSION(sess_kv_map_t **kvstore, httpd_req_t *r);
|
||||
|
||||
/**
|
||||
* Redirect to the login form if unauthed.
|
||||
* This is the same as `HTTP_GET_AUTHED_SESSION`, except the kvstore variable is
|
||||
* not needed in the uri handler calling this, so it is declared internally.
|
||||
*/
|
||||
#define HTTP_REDIRECT_IF_UNAUTHED(r) do { \
|
||||
sess_kv_map_t *_kvstore; \
|
||||
HTTP_GET_AUTHED_SESSION(_kvstore, r); \
|
||||
} while(0)
|
||||
|
||||
#endif // HTTPD_UTILS_SESSION_H
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Simple key-value map for session data storage.
|
||||
* Takes care of dynamic allocation and cleanup.
|
||||
*
|
||||
* Created on 2019/01/28.
|
||||
*/
|
||||
|
||||
#ifndef SESSION_KVMAP_H
|
||||
#define SESSION_KVMAP_H
|
||||
|
||||
/**
|
||||
* Prototype for a free() func to clean up session-held objects
|
||||
*/
|
||||
typedef void (*sess_kv_free_func_t)(void *obj);
|
||||
|
||||
typedef struct sess_kv_map sess_kv_map_t;
|
||||
|
||||
#define SESS_KVMAP_KEY_LEN 16
|
||||
|
||||
/**
|
||||
* Allocate a new session key-value store
|
||||
*
|
||||
* @return the store, NULL on error
|
||||
*/
|
||||
sess_kv_map_t *sess_kv_map_alloc(void);
|
||||
|
||||
/**
|
||||
* Free the session kv store.
|
||||
*
|
||||
* @param head - store head
|
||||
*/
|
||||
void sess_kv_map_free(void *head);
|
||||
|
||||
/**
|
||||
* Get a value from the session kv store.
|
||||
*
|
||||
* @param head - store head
|
||||
* @param key - key to get a value for
|
||||
* @return the value, or NULL if not found
|
||||
*/
|
||||
void *sess_kv_map_get(sess_kv_map_t *head, const char *key);
|
||||
|
||||
/**
|
||||
* Get and remove a value from the session store.
|
||||
*
|
||||
* The free function is not called in this case and the recipient is
|
||||
* responsible for cleaning it up correctly.
|
||||
*
|
||||
* @param head - store head
|
||||
* @param key - key to get a value for
|
||||
* @return the value, or NULL if not found
|
||||
*/
|
||||
void * sess_kv_map_take(sess_kv_map_t *head, const char *key);
|
||||
|
||||
/**
|
||||
* Remove an entry from the session by its key name.
|
||||
* The slot is not free'd yet, but is made available for reuse.
|
||||
*
|
||||
* @param head - store head
|
||||
* @param key - key to remove
|
||||
* @return success
|
||||
*/
|
||||
esp_err_t sess_kv_map_remove(sess_kv_map_t *head, const char *key);
|
||||
|
||||
/**
|
||||
* Set a key value. If there is an old value stored, it will be freed by its free function and replaced by the new one.
|
||||
* Otherwise a new slot is allocated for it, or a previously released one is reused.
|
||||
*
|
||||
* @param head - store head
|
||||
* @param key - key to assign to
|
||||
* @param value - new value
|
||||
* @param free_fn - value free func
|
||||
* @return success
|
||||
*/
|
||||
esp_err_t sess_kv_map_set(sess_kv_map_t *head, const char *key, void *value, sess_kv_free_func_t free_fn);
|
||||
|
||||
#endif //SESSION_KVMAP_H
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Cookie-based session store
|
||||
*/
|
||||
|
||||
#ifndef SESSION_STORE_H
|
||||
#define SESSION_STORE_H
|
||||
|
||||
#include "esp_http_server.h"
|
||||
|
||||
#define SESSION_EXPIRY_TIME_S 60*30
|
||||
#define SESSION_COOKIE_NAME "SESSID"
|
||||
|
||||
/** function that frees a session data object */
|
||||
typedef void (*sess_data_free_fn_t)(void *);
|
||||
|
||||
enum session_find_action {
|
||||
SESS_DROP, SESS_GET_DATA
|
||||
};
|
||||
|
||||
/**
|
||||
* Find session and either get data, or drop it.
|
||||
*
|
||||
* @param cookie
|
||||
* @param action
|
||||
* @return
|
||||
*/
|
||||
void *session_find_and(const char *cookie, enum session_find_action action);
|
||||
|
||||
/**
|
||||
* Initialize the session store.
|
||||
* Safely empty it if initialized
|
||||
*/
|
||||
void session_store_init(void);
|
||||
|
||||
// placeholder for when no data is stored
|
||||
#define SESSION_DUMMY ((void *) 1)
|
||||
|
||||
/**
|
||||
* Create a new session. Data must not be NULL, because it wouldn't be possible
|
||||
* to distinguish between NULL value and session not found in return values.
|
||||
* It can be e.g. 1 if no data storage is needed.
|
||||
*
|
||||
* @param data - data object to attach to the session
|
||||
* @param free_fn - function that disposes of the data when the session expires
|
||||
* @return NULL on error, or the new session ID. This is a live pointer into the session structure,
|
||||
* must be copied if stored, as it can become invalid at any time
|
||||
*/
|
||||
const char *session_new(void *data, sess_data_free_fn_t free_fn);
|
||||
|
||||
/**
|
||||
* Find a session by it's ID (from a cookie)
|
||||
*
|
||||
* @param cookie - session ID string
|
||||
* @return session data (void*), or NULL
|
||||
*/
|
||||
void *session_find(const char *cookie);
|
||||
|
||||
/**
|
||||
* Loop through all sessions and drop these that expired.
|
||||
*/
|
||||
void session_drop_expired(void);
|
||||
|
||||
/**
|
||||
* Drop a session by its ID. Does nothing if not found.
|
||||
*
|
||||
* @param cookie - session ID string
|
||||
*/
|
||||
void session_drop(const char *cookie);
|
||||
|
||||
/**
|
||||
* Parse the Cookie header from a request, and do something with the corresponding session.
|
||||
*
|
||||
* To also delete the cookie, use req_delete_session_cookie(r)
|
||||
*
|
||||
* @param r - request
|
||||
* @param action - what to do with the session
|
||||
* @return session data, NULL if removed or not found
|
||||
*/
|
||||
void *httpd_req_find_session_and(httpd_req_t *r, enum session_find_action action);
|
||||
|
||||
/**
|
||||
* Add a header that deletes the session cookie
|
||||
*
|
||||
* @param r - request
|
||||
*/
|
||||
void httpd_resp_delete_session_cookie(httpd_req_t *r);
|
||||
|
||||
/**
|
||||
* Add a header that sets the session cookie.
|
||||
*
|
||||
* This must be called after creating a session (e.g. user logged in) to make it persistent.
|
||||
*
|
||||
* @attention NOT RE-ENTRANT, CAN'T BE USED AGAIN UNTIL THE REQUEST IT WAS CALLED FOR IS DISPATCHED.
|
||||
*
|
||||
* @param r - request
|
||||
* @param cookie - cookie ID
|
||||
*/
|
||||
void httpd_resp_set_session_cookie(httpd_req_t *r, const char *cookie);
|
||||
|
||||
#endif //SESSION_STORE_H
|
||||
Reference in New Issue
Block a user