SpriteHTTPD - embedded HTTP server with read-only filesystem and templating, originally developed for ESP8266, now stand-alone and POSIX compatible.
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.
 
 
spritehttpd/lib/include/httpd.h

204 lines
7.6 KiB

#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "httpd-platform.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 "esp8266-httpd " 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
//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
/**
* CGI handler state / return value
*/
typedef enum {
HTTPD_CGI_MORE = 0,
HTTPD_CGI_DONE = 1,
HTTPD_CGI_NOTFOUND = 2,
HTTPD_CGI_AUTHENTICATED = 3,
} httpd_cgi_state;
/**
* HTTP method (verb) used for the request
*/
typedef enum {
HTTPD_METHOD_GET = 1,
HTTPD_METHOD_POST = 2,
HTTPD_METHOD_OPTIONS = 3,
HTTPD_METHOD_PUT = 4,
HTTPD_METHOD_DELETE = 5,
HTTPD_METHOD_PATCH = 6,
HTTPD_METHOD_HEAD = 7,
} httpd_method;
/**
* Transfer mode
*/
typedef enum {
HTTPD_TRANSFER_CLOSE = 0,
HTTPD_TRANSFER_CHUNKED = 1,
HTTPD_TRANSFER_NONE = 2,
} httpd_transfer_opt;
typedef struct HttpdPriv HttpdPriv;
typedef struct HttpdConnData HttpdConnData;
typedef struct HttpdPostData HttpdPostData;
// Private static connection pool
extern HttpdConnData *s_connData[HTTPD_MAX_CONNECTIONS];
typedef httpd_cgi_state (* cgiSendCallback)(HttpdConnData *connData);
typedef httpd_cgi_state (* cgiRecvHandler)(HttpdConnData *connData, char *data, int len);
struct httpd_options {
uint16_t port;
};
//A struct describing a http connection. This gets passed to cgi functions.
struct HttpdConnData {
ConnTypePtr conn; // The TCP connection. Exact type depends on the platform.
httpd_method requestType; // One of the HTTPD_METHOD_* values
char *url; // The URL requested, without hostname or GET arguments
char *getArgs; // The GET arguments for this request, if any.
const void *cgiArg; // Argument to the CGI function, as stated as the 3rd argument of
// the builtInUrls entry that referred to the CGI function.
const void *cgiArg2; // 4th argument of the builtInUrls entries, used to pass template file to the tpl handler.
void *cgiData; // Opaque data pointer for the CGI function
char *hostName; // Host name field of request
HttpdPriv *priv; // Opaque pointer to data for internal httpd housekeeping
cgiSendCallback cgi; // CGI function pointer
cgiRecvHandler recvHdl; // Handler for data received after headers, if any
HttpdPostData *post; // POST data structure
int remote_port; // Remote TCP port
uint8_t remote_ip[4]; // IP address of client
uint8_t slot; // Slot ID
};
//A struct describing the POST data sent inside the http connection. This is used by the CGI functions
struct HttpdPostData {
int len; // POST Content-Length
int buffSize; // The maximum length of the post buffer
int buffLen; // The amount of bytes in the current post buffer
int received; // The total amount of bytes received so far
char *buff; // Actual POST data buffer
char *multipartBoundary; //Text of the multipart boundary, if any
};
//A struct describing an url. This is the main struct that's used to send different URL requests to
//different routines.
typedef struct {
const char *url;
cgiSendCallback cgiCb;
const void *cgiArg;
const void *cgiArg2;
} HttpdBuiltInUrl;
// 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_AUTH(path, passwdFunc) ROUTE_CGI_ARG((path), authBasic, (AuthGetUserPw)(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)
#define ROUTE_END() {NULL, NULL, NULL, NULL}
const char *httpdGetVersion(void);
httpd_cgi_state cgiRedirect(HttpdConnData *connData);
httpd_cgi_state cgiRedirectToHostname(HttpdConnData *connData);
httpd_cgi_state cgiRedirectApClientToHostname(HttpdConnData *connData);
void httpdRedirect(HttpdConnData *conn, const char *newUrl);
int httpdUrlDecode(const char *val, int valLen, char *ret, int retLen);
int httpdFindArg(const char *line, const char *arg, char *buff, int buffLen);
httpd_thread_handle_t *httpdInit(const HttpdBuiltInUrl *fixedUrls, struct httpd_options *options);
void httpdJoin(httpd_thread_handle_t *handle);
const char *httpdGetMimetype(const char *url);
const char *httpdMethodName(httpd_method m);
void httdSetTransferMode(HttpdConnData *conn, int mode);
void httpdStartResponse(HttpdConnData *conn, int code);
void httpdHeader(HttpdConnData *conn, const char *field, const char *val);
void httpdEndHeaders(HttpdConnData *conn);
int httpdGetHeader(HttpdConnData *conn, const char *header, char *ret, int retLen);
int httpdSend(HttpdConnData *conn, const char *data, int len);
int httpdSend_js(HttpdConnData *conn, const char *data, int len);
int httpdSend_html(HttpdConnData *conn, const char *data, int len);
bool httpdFlushSendBuffer(HttpdConnData *conn);
void httpdContinue(HttpdConnData *conn);
void httpdConnSendStart(HttpdConnData *conn);
void httpdConnSendFinish(HttpdConnData *conn);
void httpdAddCacheHeaders(HttpdConnData *connData, const char *mime);
int httpGetBacklogSize(const HttpdConnData *connData);
void httdResponseOptions(HttpdConnData *conn, int cors);
//Platform dependent code should call these.
void httpdSentCb(ConnTypePtr conn, const char *remIp, int remPort);
void httpdRecvCb(ConnTypePtr conn, const char *remIp, int remPort, char *data, unsigned short len);
void httpdDisconCb(ConnTypePtr conn, const char *remIp, int remPort);
int httpdConnectCb(ConnTypePtr conn, const char *remIp, int remPort);
void httpdSetName(const char *name);