You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
10 KiB
371 lines
10 KiB
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <sys/types.h> /* needed for ssize_t */
|
|
#include "httpd-platform.h"
|
|
#include "httpd-types.h"
|
|
|
|
#ifndef GIT_HASH
|
|
#define GIT_HASH "unknown"
|
|
#endif
|
|
|
|
// we must not use this macro outside the library, as the git hash is not defined there
|
|
#define HTTPDVER "0.4+MightyPork/libesphttpd#" GIT_HASH
|
|
|
|
// default servername
|
|
#ifndef HTTPD_SERVERNAME
|
|
#define HTTPD_SERVERNAME "SpriteHTTPD " HTTPDVER
|
|
#endif
|
|
|
|
//Max length of request head. This is statically allocated for each connection.
|
|
#ifndef HTTPD_MAX_HEAD_LEN
|
|
#define HTTPD_MAX_HEAD_LEN 1024
|
|
#endif
|
|
|
|
//Max post buffer len. This is dynamically malloc'ed if needed.
|
|
#ifndef HTTPD_MAX_POST_LEN
|
|
#define HTTPD_MAX_POST_LEN 2048
|
|
#endif
|
|
|
|
//Max send buffer len. This is allocated on the stack.
|
|
#ifndef HTTPD_MAX_SENDBUFF_LEN
|
|
#define HTTPD_MAX_SENDBUFF_LEN 2048
|
|
#endif
|
|
|
|
//Receive buffer
|
|
#ifndef HTTPD_RECV_BUF_LEN
|
|
#define HTTPD_RECV_BUF_LEN 2048
|
|
#endif
|
|
|
|
//If some data can't be sent because the underlaying socket doesn't accept the data (like the nonos
|
|
//layer is prone to do), we put it in a backlog that is dynamically malloc'ed. This defines the max
|
|
//size of the backlog.
|
|
#ifndef HTTPD_MAX_BACKLOG_SIZE
|
|
#define HTTPD_MAX_BACKLOG_SIZE (4*1024)
|
|
#endif
|
|
|
|
//Max len of CORS token. This is allocated in each connection
|
|
#ifndef HTTPD_MAX_CORS_TOKEN_LEN
|
|
#define HTTPD_MAX_CORS_TOKEN_LEN 256
|
|
#endif
|
|
|
|
#ifndef HTTPD_MAX_CONNECTIONS
|
|
#define HTTPD_MAX_CONNECTIONS 4
|
|
#endif
|
|
|
|
// macros for defining HttpdBuiltInUrl's
|
|
|
|
/** Route with a CGI handler and two arguments */
|
|
#define ROUTE_CGI_ARG2(path, handler, arg1, arg2) {(path), (handler), (void *)(arg1), (void *)(arg2)}
|
|
|
|
/** Route with a CGI handler and one arguments */
|
|
#define ROUTE_CGI_ARG(path, handler, arg1) ROUTE_CGI_ARG2((path), (handler), (arg1), NULL)
|
|
|
|
/** Route with an argument-less CGI handler */
|
|
#define ROUTE_CGI(path, handler) ROUTE_CGI_ARG2((path), (handler), NULL, NULL)
|
|
|
|
/** Static file route (file loaded from espfs) */
|
|
#define ROUTE_FILE(path, filepath) ROUTE_CGI_ARG((path), cgiEspFsHook, (const char*)(filepath))
|
|
|
|
/** Static file as a template with a replacer function */
|
|
#define ROUTE_TPL(path, replacer) ROUTE_CGI_ARG((path), cgiEspFsTemplate, (TplCallback)(replacer))
|
|
|
|
/** Static file as a template with a replacer function, taking additional argument connData->cgiArg2 */
|
|
#define ROUTE_TPL_FILE(path, replacer, filepath) ROUTE_CGI_ARG2((path), cgiEspFsTemplate, (TplCallback)(replacer), (filepath))
|
|
|
|
/** Redirect to some URL */
|
|
#define ROUTE_REDIRECT(path, target) ROUTE_CGI_ARG((path), cgiRedirect, (const char*)(target))
|
|
|
|
/** Following routes are basic-auth protected */
|
|
#define ROUTE_BASIC_AUTH(path, passwdFunc) ROUTE_CGI_ARG((path), cgiAuthBasic, (HttpdBasicAuthCb)(passwdFunc))
|
|
|
|
/** Following routes are basic-auth protected */
|
|
#define ROUTE_BEARER_AUTH(path, passwdFunc) ROUTE_CGI_ARG((path), cgiAuthBearer, (HttpdBearerAuthCb)(passwdFunc))
|
|
|
|
/** Websocket endpoint */
|
|
#define ROUTE_WS(path, callback) ROUTE_CGI_ARG((path), cgiWebsocket, (WsConnectedCb)(callback))
|
|
|
|
/** Catch-all filesystem route */
|
|
#define ROUTE_FILESYSTEM() ROUTE_CGI("*", cgiEspFsHook)
|
|
|
|
/** Marker for the end of the route list */
|
|
#define ROUTE_END() {NULL, NULL, NULL, NULL}
|
|
|
|
/**
|
|
* Get the server version string
|
|
*
|
|
* @return version
|
|
*/
|
|
const char *httpdGetVersion(void);
|
|
|
|
/**
|
|
* Use this as a cgi function to redirect one url to another.
|
|
*/
|
|
httpd_cgi_state cgiRedirect(HttpdConnData *connData);
|
|
|
|
/**
|
|
* This CGI function redirects to a fixed url of http://[hostname]/ if hostname field of request isn't
|
|
* already that hostname. Use this in combination with a DNS server that redirects everything to the
|
|
* ESP in order to load a HTML page as soon as a phone, tablet etc connects to the ESP. Watch out:
|
|
* this will also redirect connections when the ESP is in STA mode, potentially to a hostname that is not
|
|
* in the 'official' DNS and so will fail.
|
|
*
|
|
* @param conn - connection
|
|
*/
|
|
httpd_cgi_state cgiRedirectToHostname(HttpdConnData *connData);
|
|
|
|
/**
|
|
* Redirect to the given URL.
|
|
*
|
|
* Sets the status code to 302, adds the Location header and a simple redirect text body.
|
|
*
|
|
* @param conn - connection
|
|
* @param newUrl - URL to redirect to
|
|
*/
|
|
void httpdRedirect(HttpdConnData *conn, const char *newUrl);
|
|
|
|
/**
|
|
* Start the HTTP server
|
|
*
|
|
* @param fixedUrls - array of defined URLs
|
|
* @param options - server options
|
|
* @return server thread handle or NULL on error
|
|
*/
|
|
httpd_thread_handle_t *httpdStart(const HttpdBuiltInUrl *fixedUrls, struct httpd_options *options);
|
|
|
|
/**
|
|
* Shutdown the server & wait for the thread to end.
|
|
*
|
|
* @param handle
|
|
*/
|
|
void httpdShutdown(httpd_thread_handle_t *handle);
|
|
|
|
/**
|
|
* Join the server thread.
|
|
* This is mainly useful in the posix build to block while the server runs.
|
|
*
|
|
* @param handle
|
|
*/
|
|
void httpdJoin(httpd_thread_handle_t *handle);
|
|
|
|
/**
|
|
* Set transfer mode for the current connection
|
|
*
|
|
* @param conn
|
|
* @param mode - transfer mode
|
|
*/
|
|
void httdSetTransferMode(HttpdConnData *conn, httpd_transfer_opt mode);
|
|
|
|
/**
|
|
* Start a HTTP response. Sends the HTTP line and common headers.
|
|
* More headers can be added before starting the message body.
|
|
*
|
|
* @param conn
|
|
* @param code - HTTP status code
|
|
*/
|
|
void httpdStartResponse(HttpdConnData *conn, int code);
|
|
|
|
/**
|
|
* Add a HTTP header
|
|
*
|
|
* @param conn
|
|
* @param field - name
|
|
* @param val - value
|
|
*/
|
|
void httpdHeader(HttpdConnData *conn, const char *field, const char *val);
|
|
|
|
/**
|
|
* End headers, start sending body
|
|
*
|
|
* @param conn
|
|
*/
|
|
void httpdEndHeaders(HttpdConnData *conn);
|
|
|
|
/**
|
|
* Read value of a request header
|
|
*
|
|
* @param conn
|
|
* @param header - name
|
|
* @param[out] buff - buffer for the header value, will be zero terminated
|
|
* @param buffLen - capacity of the buffer
|
|
* @return 1 = OK
|
|
*/
|
|
int httpdGetHeader(HttpdConnData *conn, const char *header, char *buff, size_t buffLen);
|
|
|
|
/**
|
|
* Send binary data
|
|
*
|
|
* @param conn
|
|
* @param data - data to send
|
|
* @param len - num bytes. -1 to use strlen.
|
|
* @return 1 = OK
|
|
*/
|
|
int httpdSend(HttpdConnData *conn, const uint8_t *data, size_t len);
|
|
|
|
/**
|
|
* Send a string. The length is measured using strlen.
|
|
*
|
|
* @param conn
|
|
* @param data - string
|
|
* @return 1 = OK
|
|
*/
|
|
static inline int httpdSendStr(HttpdConnData *conn, const char *data)
|
|
{
|
|
return httpdSend(conn, (const uint8_t *) data, strlen(data));
|
|
}
|
|
|
|
/**
|
|
* Send a string with custom length. This is a slight optimization over httpdSendStr when the length is known.
|
|
*
|
|
* @param conn
|
|
* @param data - string
|
|
* @param len - num bytes
|
|
* @return 1 = OK
|
|
*/
|
|
static inline int httpdSendStrN(HttpdConnData *conn, const char *data, size_t len)
|
|
{
|
|
return httpdSend(conn, (const uint8_t *) data, len);
|
|
}
|
|
|
|
// TODO convert to a general escaped send function
|
|
/**
|
|
* Send text with JSON escaping
|
|
*
|
|
* @param conn
|
|
* @param data - string
|
|
* @param len - string length, -1 to use strlen()
|
|
* @return 1 = OK
|
|
*/
|
|
int httpdSend_js(HttpdConnData *conn, const char *data, ssize_t len);
|
|
|
|
/**
|
|
* Send text with HTML escaping. Escapes quotes and angle brackets.
|
|
*
|
|
* @param conn
|
|
* @param data - string
|
|
* @param len - string length, -1 to use strlen()
|
|
* @return 1 = OK
|
|
*/
|
|
int httpdSend_html(HttpdConnData *conn, const char *data, ssize_t len);
|
|
|
|
/**
|
|
* Function to send any data in conn->priv->sendBuff. Do not use in CGIs unless you know what you
|
|
* are doing! Also, if you do set conn->cgi to NULL to indicate the connection is closed, do it BEFORE
|
|
* calling this.
|
|
* Returns false if data could not be sent nor put in backlog.
|
|
*
|
|
* @param conn
|
|
* @return 1 = OK
|
|
*/
|
|
bool httpdFlushSendBuffer(HttpdConnData *conn);
|
|
|
|
/**
|
|
* Can be called after a CGI function has returned HTTPD_CGI_MORE to
|
|
* resume handling an open connection asynchronously
|
|
*
|
|
* @param conn
|
|
*/
|
|
void httpdContinue(HttpdConnData *conn);
|
|
|
|
/**
|
|
* Make a connection 'live' so we can do all the things a cgi can do to it.
|
|
*
|
|
* @param conn
|
|
*/
|
|
void httpdConnSendStart(HttpdConnData *conn);
|
|
|
|
/**
|
|
* Finish the live-ness of a connection. Always call this after httpdConnStart
|
|
*
|
|
* @param conn
|
|
*/
|
|
void httpdConnSendFinish(HttpdConnData *conn);
|
|
|
|
/**
|
|
* Add sensible cache control headers to avoid needless asset reloading.
|
|
*
|
|
* @param connData
|
|
* @param mime - mime type string
|
|
*/
|
|
void httpdAddCacheHeaders(HttpdConnData *connData, const char *mime);
|
|
|
|
/**
|
|
* Get current HTTP backlog size
|
|
*
|
|
* @param connData
|
|
* @return bytes
|
|
*/
|
|
size_t httpGetBacklogSize(const HttpdConnData *connData);
|
|
|
|
/**
|
|
* Set HTTP response options
|
|
*
|
|
* @param conn
|
|
* @param cors 0 = don't add CORS header
|
|
*/
|
|
void httdResponseOptions(HttpdConnData *conn, int cors);
|
|
|
|
//Platform dependent code should call these.
|
|
|
|
/**
|
|
* Callback called when the data on a socket has been successfully sent.
|
|
*
|
|
* @param conn
|
|
* @param remIp - remote IP (4 bytes)
|
|
* @param remPort - remote port
|
|
*/
|
|
void httpdSentCb(ConnTypePtr conn, const char *remIp, int remPort);
|
|
|
|
/**
|
|
* Callback called when there's data available on a socket.
|
|
*
|
|
* @param conn
|
|
* @param remIp - remote IP (4 bytes)
|
|
* @param remPort - remote port
|
|
* @param data - data received. This is a mutable buffer
|
|
* @param len - data len
|
|
*/
|
|
void httpdRecvCb(ConnTypePtr conn, const char *remIp, int remPort, uint8_t *data, unsigned short len);
|
|
|
|
/**
|
|
* The platform layer should ALWAYS call this function, regardless if the connection is closed by the server
|
|
* or by the client.
|
|
*
|
|
* @param conn
|
|
* @param remIp - remote IP (4 bytes)
|
|
* @param remPort - remote port
|
|
*/
|
|
void httpdDisconCb(ConnTypePtr conn, const char *remIp, int remPort);
|
|
|
|
/**
|
|
* Connect callback - a client connected
|
|
*
|
|
* @param conn
|
|
* @param remIp - remote IP (4 bytes)
|
|
* @param remPort - remote port
|
|
* @return 1 = OK, 0 = client couldn't be served
|
|
*/
|
|
int httpdConnectCb(ConnTypePtr conn, const char *remIp, int remPort);
|
|
|
|
/**
|
|
* Set server name (Should not be on stack - the pointer must live as long as the server! Const is preferable.)
|
|
*
|
|
* @param name - new server name
|
|
*/
|
|
void httpdSetName(const char *name);
|
|
|
|
/**
|
|
* Low level function to close & release a connection
|
|
*
|
|
* @param conn
|
|
*/
|
|
void httpdConnRelease(ConnTypePtr conn);
|
|
|
|
/**
|
|
* Close and retire all sockets.
|
|
* Called during httpd shutdown.
|
|
*/
|
|
void httpdInternalCloseAllSockets();
|
|
|