477 lines
15 KiB
C
477 lines
15 KiB
C
#ifndef HTTP_INCLUDED
|
|
#define HTTP_INCLUDED
|
|
|
|
#ifndef HTTP_PARSE
|
|
#define HTTP_PARSE 1
|
|
#endif
|
|
|
|
#ifndef HTTP_ENGINE
|
|
#define HTTP_ENGINE 1
|
|
#endif
|
|
|
|
#ifndef HTTP_PROXY_ENGINE
|
|
#define HTTP_PROXY_ENGINE 1
|
|
#endif
|
|
|
|
#ifndef HTTP_CLIENT
|
|
#define HTTP_CLIENT 1
|
|
#endif
|
|
|
|
#ifndef HTTP_SERVER
|
|
#define HTTP_SERVER 1
|
|
#endif
|
|
|
|
#ifndef HTTP_PROXY
|
|
#define HTTP_PROXY 1
|
|
#endif
|
|
|
|
#ifndef HTTP_ROUTER
|
|
#define HTTP_ROUTER 1
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// UTILITIES
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
#define HTTP_STR(X) ((HTTP_String) {(X), sizeof(X)-1})
|
|
#define HTTP_CEIL(X, Y) (((X) + (Y) - 1) / (Y))
|
|
|
|
typedef struct {
|
|
char *ptr;
|
|
long len;
|
|
} HTTP_String;
|
|
|
|
int http_streq (HTTP_String s1, HTTP_String s2);
|
|
int http_streqcase (HTTP_String s1, HTTP_String s2);
|
|
HTTP_String http_trim (HTTP_String s);
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP PARSER
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_PARSE
|
|
|
|
#define HTTP_MAX_HEADERS 32
|
|
|
|
typedef struct {
|
|
unsigned int data;
|
|
} HTTP_IPv4;
|
|
|
|
typedef struct {
|
|
unsigned short data[8];
|
|
} HTTP_IPv6;
|
|
|
|
typedef enum {
|
|
HTTP_HOST_MODE_VOID = 0,
|
|
HTTP_HOST_MODE_NAME,
|
|
HTTP_HOST_MODE_IPV4,
|
|
HTTP_HOST_MODE_IPV6,
|
|
} HTTP_HostMode;
|
|
|
|
typedef struct {
|
|
HTTP_HostMode mode;
|
|
HTTP_String text;
|
|
union {
|
|
HTTP_String name;
|
|
HTTP_IPv4 ipv4;
|
|
HTTP_IPv6 ipv6;
|
|
};
|
|
} HTTP_Host;
|
|
|
|
typedef struct {
|
|
HTTP_String userinfo;
|
|
HTTP_Host host;
|
|
int port;
|
|
} HTTP_Authority;
|
|
|
|
// ZII
|
|
typedef struct {
|
|
HTTP_String scheme;
|
|
HTTP_Authority authority;
|
|
HTTP_String path;
|
|
HTTP_String query;
|
|
HTTP_String fragment;
|
|
} HTTP_URL;
|
|
|
|
typedef enum {
|
|
HTTP_METHOD_GET,
|
|
HTTP_METHOD_HEAD,
|
|
HTTP_METHOD_POST,
|
|
HTTP_METHOD_PUT,
|
|
HTTP_METHOD_DELETE,
|
|
HTTP_METHOD_CONNECT,
|
|
HTTP_METHOD_OPTIONS,
|
|
HTTP_METHOD_TRACE,
|
|
HTTP_METHOD_PATCH,
|
|
} HTTP_Method;
|
|
|
|
typedef struct {
|
|
HTTP_String name;
|
|
HTTP_String value;
|
|
} HTTP_Header;
|
|
|
|
typedef struct {
|
|
HTTP_Method method;
|
|
HTTP_URL url;
|
|
int minor;
|
|
int num_headers;
|
|
HTTP_Header headers[HTTP_MAX_HEADERS];
|
|
HTTP_String body;
|
|
} HTTP_Request;
|
|
|
|
typedef struct {
|
|
int minor;
|
|
int status;
|
|
HTTP_String reason;
|
|
int num_headers;
|
|
HTTP_Header headers[HTTP_MAX_HEADERS];
|
|
HTTP_String body;
|
|
} HTTP_Response;
|
|
|
|
int http_parse_ipv4 (char *src, int len, HTTP_IPv4 *ipv4);
|
|
int http_parse_ipv6 (char *src, int len, HTTP_IPv6 *ipv6);
|
|
int http_parse_url (char *src, int len, HTTP_URL *url);
|
|
int http_parse_request (char *src, int len, HTTP_Request *req);
|
|
int http_parse_response (char *src, int len, HTTP_Response *res);
|
|
|
|
HTTP_String http_getbodyparam (HTTP_Request *req, HTTP_String name);
|
|
HTTP_String http_getcookie (HTTP_Request *req, HTTP_String name);
|
|
|
|
#endif // HTTP_PARSE
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP BYTE QUEUE
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_ENGINE
|
|
|
|
typedef enum {
|
|
HTTP_MEMFUNC_MALLOC,
|
|
HTTP_MEMFUNC_FREE,
|
|
} HTTP_MemoryFuncTag;
|
|
|
|
typedef void*(*HTTP_MemoryFunc)(HTTP_MemoryFuncTag tag,
|
|
void *ptr, int len, void *data);
|
|
|
|
typedef struct {
|
|
|
|
HTTP_MemoryFunc memfunc;
|
|
void *memfuncdata;
|
|
|
|
unsigned long long curs;
|
|
|
|
char* data;
|
|
unsigned int head;
|
|
unsigned int size;
|
|
unsigned int used;
|
|
unsigned int limit;
|
|
|
|
char* read_target;
|
|
unsigned int read_target_size;
|
|
|
|
int flags;
|
|
} HTTP_ByteQueue;
|
|
|
|
typedef unsigned long long HTTP_ByteQueueOffset;
|
|
|
|
#endif // HTTP_ENGINE
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP ENGINE
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_ENGINE
|
|
|
|
#define HTTP_ENGINE_STATEBIT_CLIENT (1 << 0)
|
|
#define HTTP_ENGINE_STATEBIT_CLOSED (1 << 1)
|
|
#define HTTP_ENGINE_STATEBIT_RECV_BUF (1 << 2)
|
|
#define HTTP_ENGINE_STATEBIT_RECV_ACK (1 << 3)
|
|
#define HTTP_ENGINE_STATEBIT_SEND_BUF (1 << 4)
|
|
#define HTTP_ENGINE_STATEBIT_SEND_ACK (1 << 5)
|
|
#define HTTP_ENGINE_STATEBIT_REQUEST (1 << 6)
|
|
#define HTTP_ENGINE_STATEBIT_RESPONSE (1 << 7)
|
|
#define HTTP_ENGINE_STATEBIT_PREP (1 << 8)
|
|
#define HTTP_ENGINE_STATEBIT_PREP_HEADER (1 << 9)
|
|
#define HTTP_ENGINE_STATEBIT_PREP_BODY_BUF (1 << 10)
|
|
#define HTTP_ENGINE_STATEBIT_PREP_BODY_ACK (1 << 11)
|
|
#define HTTP_ENGINE_STATEBIT_PREP_ERROR (1 << 12)
|
|
#define HTTP_ENGINE_STATEBIT_PREP_URL (1 << 13)
|
|
#define HTTP_ENGINE_STATEBIT_PREP_STATUS (1 << 14)
|
|
#define HTTP_ENGINE_STATEBIT_CLOSING (1 << 15)
|
|
|
|
typedef enum {
|
|
HTTP_ENGINE_STATE_NONE = 0,
|
|
HTTP_ENGINE_STATE_CLIENT_PREP_URL = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_URL,
|
|
HTTP_ENGINE_STATE_CLIENT_PREP_HEADER = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_HEADER,
|
|
HTTP_ENGINE_STATE_CLIENT_PREP_BODY_BUF = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_BODY_BUF,
|
|
HTTP_ENGINE_STATE_CLIENT_PREP_BODY_ACK = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_BODY_ACK,
|
|
HTTP_ENGINE_STATE_CLIENT_PREP_ERROR = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_ERROR,
|
|
HTTP_ENGINE_STATE_CLIENT_SEND_BUF = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_SEND_BUF,
|
|
HTTP_ENGINE_STATE_CLIENT_SEND_ACK = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_SEND_ACK,
|
|
HTTP_ENGINE_STATE_CLIENT_RECV_BUF = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_RECV_BUF,
|
|
HTTP_ENGINE_STATE_CLIENT_RECV_ACK = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_RECV_ACK,
|
|
HTTP_ENGINE_STATE_CLIENT_READY = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_RESPONSE,
|
|
HTTP_ENGINE_STATE_CLIENT_CLOSED = HTTP_ENGINE_STATEBIT_CLIENT | HTTP_ENGINE_STATEBIT_CLOSED,
|
|
HTTP_ENGINE_STATE_SERVER_RECV_BUF = HTTP_ENGINE_STATEBIT_RECV_BUF,
|
|
HTTP_ENGINE_STATE_SERVER_RECV_ACK = HTTP_ENGINE_STATEBIT_RECV_ACK,
|
|
HTTP_ENGINE_STATE_SERVER_PREP_STATUS = HTTP_ENGINE_STATEBIT_REQUEST | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_STATUS,
|
|
HTTP_ENGINE_STATE_SERVER_PREP_HEADER = HTTP_ENGINE_STATEBIT_REQUEST | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_HEADER,
|
|
HTTP_ENGINE_STATE_SERVER_PREP_BODY_BUF = HTTP_ENGINE_STATEBIT_REQUEST | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_BODY_BUF,
|
|
HTTP_ENGINE_STATE_SERVER_PREP_BODY_ACK = HTTP_ENGINE_STATEBIT_REQUEST | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_BODY_ACK,
|
|
HTTP_ENGINE_STATE_SERVER_PREP_ERROR = HTTP_ENGINE_STATEBIT_REQUEST | HTTP_ENGINE_STATEBIT_PREP | HTTP_ENGINE_STATEBIT_PREP_ERROR,
|
|
HTTP_ENGINE_STATE_SERVER_SEND_BUF = HTTP_ENGINE_STATEBIT_SEND_BUF,
|
|
HTTP_ENGINE_STATE_SERVER_SEND_ACK = HTTP_ENGINE_STATEBIT_SEND_ACK,
|
|
HTTP_ENGINE_STATE_SERVER_CLOSED = HTTP_ENGINE_STATEBIT_CLIENT,
|
|
} HTTP_EngineState;
|
|
|
|
typedef struct {
|
|
HTTP_EngineState state;
|
|
HTTP_ByteQueue input;
|
|
HTTP_ByteQueue output;
|
|
int numexch;
|
|
int reqsize;
|
|
int closing;
|
|
int keepalive;
|
|
HTTP_ByteQueueOffset response_offset;
|
|
HTTP_ByteQueueOffset content_length_offset;
|
|
HTTP_ByteQueueOffset content_length_value_offset;
|
|
union {
|
|
HTTP_Request req;
|
|
HTTP_Response res;
|
|
} result;
|
|
} HTTP_Engine;
|
|
|
|
void http_engine_init (HTTP_Engine *eng, int client, HTTP_MemoryFunc memfunc, void *memfuncdata);
|
|
void http_engine_free (HTTP_Engine *eng);
|
|
|
|
void http_engine_close (HTTP_Engine *eng);
|
|
HTTP_EngineState http_engine_state (HTTP_Engine *eng);
|
|
|
|
char* http_engine_recvbuf (HTTP_Engine *eng, int *cap);
|
|
void http_engine_recvack (HTTP_Engine *eng, int num);
|
|
char* http_engine_sendbuf (HTTP_Engine *eng, int *len);
|
|
void http_engine_sendack (HTTP_Engine *eng, int num);
|
|
|
|
HTTP_Request* http_engine_getreq (HTTP_Engine *eng);
|
|
HTTP_Response* http_engine_getres (HTTP_Engine *eng);
|
|
|
|
void http_engine_url (HTTP_Engine *eng, HTTP_Method method, char *url, int minor);
|
|
void http_engine_status (HTTP_Engine *eng, int status);
|
|
void http_engine_header (HTTP_Engine *eng, const char *src, int len);
|
|
void http_engine_body (HTTP_Engine *eng, void *src, int len);
|
|
void http_engine_bodycap (HTTP_Engine *eng, int mincap);
|
|
char* http_engine_bodybuf (HTTP_Engine *eng, int *cap);
|
|
void http_engine_bodyack (HTTP_Engine *eng, int num);
|
|
void http_engine_done (HTTP_Engine *eng);
|
|
void http_engine_undo (HTTP_Engine *eng);
|
|
|
|
#endif // HTTP_ENGINE
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP PROXY ENGINE
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_PROXY_ENGINE
|
|
|
|
typedef struct {
|
|
HTTP_Engine in;
|
|
HTTP_Engine out;
|
|
} HTTP_ProxyEngine;
|
|
|
|
typedef enum {
|
|
HTTP_PROXY_ENGINE_STATE_NONE,
|
|
HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_BUF,
|
|
HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_ACK,
|
|
HTTP_PROXY_ENGINE_STATE_SERVER_SEND_BUF,
|
|
HTTP_PROXY_ENGINE_STATE_SERVER_SEND_ACK,
|
|
HTTP_PROXY_ENGINE_STATE_SERVER_RECV_BUF,
|
|
HTTP_PROXY_ENGINE_STATE_SERVER_RECV_ACK,
|
|
HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_BUF,
|
|
HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_ACK,
|
|
HTTP_PROXY_ENGINE_STATE_CLOSED,
|
|
} HTTP_ProxyEngineState;
|
|
|
|
void http_proxyengine_init(HTTP_ProxyEngine *eng, HTTP_MemoryFunc memfunc, void *memfuncdata);
|
|
void http_proxyengine_free(HTTP_ProxyEngine *eng);
|
|
HTTP_ProxyEngineState http_proxyengine_state(HTTP_ProxyEngine *eng);
|
|
void http_proxyengine_close(HTTP_ProxyEngine *eng);
|
|
char* http_proxyengine_serverrecvbuf(HTTP_ProxyEngine *eng, int *cap);
|
|
void http_proxyengine_serverrecvack(HTTP_ProxyEngine *eng, int num);
|
|
char* http_proxyengine_serversendbuf(HTTP_ProxyEngine *eng, int *len);
|
|
void http_proxyengine_serversendack(HTTP_ProxyEngine *eng, int num);
|
|
char* http_proxyengine_clientrecvbuf(HTTP_ProxyEngine *eng, int *cap);
|
|
void http_proxyengine_clientrecvack(HTTP_ProxyEngine *eng, int num);
|
|
char* http_proxyengine_clientsendbuf(HTTP_ProxyEngine *eng, int *len);
|
|
void http_proxyengine_clientsendack(HTTP_ProxyEngine *eng, int num);
|
|
|
|
#endif // HTTP_PROXY_ENGINE
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP CLIENT AND SERVER
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_CLIENT || HTTP_SERVER || HTTP_PROXY
|
|
|
|
typedef unsigned long long HTTP_Socket;
|
|
|
|
#endif // HTTP_CLIENT || HTTP_SERVER
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP CLIENT
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_CLIENT
|
|
|
|
#define HTTP_CLIENT_TLS 0
|
|
|
|
#define HTTP_CLIENT_WAIT_LIMIT (1<<9)
|
|
|
|
typedef struct { _Alignas(void*) char data[32]; } HTTP_TLSContext;
|
|
typedef struct { _Alignas(void*) char data[32]; } HTTP_TLSClientContext;
|
|
|
|
typedef enum {
|
|
HTTP_STATE_CLIENT_IDLE,
|
|
HTTP_STATE_CLIENT_CONNECT,
|
|
HTTP_STATE_CLIENT_TLS_HANDSHAKE_RECV,
|
|
HTTP_STATE_CLIENT_TLS_HANDSHAKE_SEND,
|
|
HTTP_STATE_CLIENT_RECV,
|
|
HTTP_STATE_CLIENT_SEND,
|
|
HTTP_STATE_CLIENT_CLOSED,
|
|
HTTP_STATE_CLIENT_READY,
|
|
} HTTP_ClientState;
|
|
|
|
enum {
|
|
HTTP_CLIENT_OK = 0,
|
|
HTTP_CLIENT_ERROR_INVURL = -1,
|
|
HTTP_CLIENT_ERROR_NOSYS = -2,
|
|
HTTP_CLIENT_ERROR_INVPROTO = -3,
|
|
HTTP_CLIENT_ERROR_FSOCK = -4,
|
|
HTTP_CLIENT_ERROR_FCONNECT = -5,
|
|
HTTP_CLIENT_ERROR_DNS = -6,
|
|
HTTP_CLIENT_ERROR_FSSLNEW = -7,
|
|
HTTP_CLIENT_ERROR_FRECV = -8,
|
|
HTTP_CLIENT_ERROR_FSSLREAD = -9,
|
|
HTTP_CLIENT_ERROR_FSEND = -10,
|
|
HTTP_CLIENT_ERROR_FSSLWRITE = -11,
|
|
HTTP_CLIENT_ERROR_FGETSOCKOPT = -12,
|
|
HTTP_CLIENT_ERROR_FSSLCONNECT = -13,
|
|
};
|
|
|
|
typedef struct {
|
|
int secure;
|
|
int code;
|
|
HTTP_Socket fd;
|
|
HTTP_Engine eng;
|
|
HTTP_ClientState state;
|
|
HTTP_TLSClientContext tls;
|
|
} HTTP_Client;
|
|
|
|
void http_tls_global_init(void);
|
|
void http_tls_global_free(void);
|
|
|
|
int http_tls_init(HTTP_TLSContext *tls);
|
|
void http_tls_free(HTTP_TLSContext *tls);
|
|
|
|
void http_client_init(HTTP_Client *client);
|
|
void http_client_free(HTTP_Client *client);
|
|
|
|
void http_client_startreq(
|
|
HTTP_Client *client, HTTP_Method method,
|
|
const char *url, HTTP_String *headers,
|
|
int num_headers, char *body, int body_len,
|
|
HTTP_TLSContext *tls);
|
|
|
|
int http_client_waitany(HTTP_Client **clients, int num_clients, int timeout);
|
|
int http_client_waitall(HTTP_Client **clients, int num_clients, int timeout);
|
|
|
|
int http_client_result(HTTP_Client *client, HTTP_Response **res);
|
|
const char *http_client_strerror(int code);
|
|
|
|
#endif // HTTP_CLIENT
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP SERVER
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_SERVER
|
|
|
|
#define HTTP_MAX_CLIENTS_PER_SERVER (1<<9)
|
|
|
|
typedef unsigned long long HTTP_BitsetWord;
|
|
typedef struct {
|
|
HTTP_BitsetWord data[HTTP_CEIL(HTTP_MAX_CLIENTS_PER_SERVER,
|
|
sizeof(HTTP_BitsetWord))];
|
|
} HTTP_Bitset;
|
|
|
|
typedef struct {
|
|
int head;
|
|
int count;
|
|
int items[HTTP_MAX_CLIENTS_PER_SERVER];
|
|
HTTP_Bitset set;
|
|
} HTTP_IntQueue;
|
|
|
|
typedef struct {
|
|
void *ptr;
|
|
int idx;
|
|
int gen;
|
|
} HTTP_ResponseHandle;
|
|
|
|
typedef struct {
|
|
HTTP_Socket fd;
|
|
HTTP_Engine eng;
|
|
unsigned short gen;
|
|
} HTTP_ServerConnection;
|
|
|
|
typedef struct {
|
|
HTTP_Socket listen_fd;
|
|
HTTP_IntQueue ready;
|
|
int num_conns;
|
|
HTTP_ServerConnection conns[HTTP_MAX_CLIENTS_PER_SERVER];
|
|
} HTTP_Server;
|
|
|
|
int http_server_init(HTTP_Server *server,
|
|
const char *addr, int port);
|
|
|
|
void http_server_free(HTTP_Server *server);
|
|
|
|
int http_server_wait(HTTP_Server *server, HTTP_Request **req,
|
|
HTTP_ResponseHandle *res, int timeout);
|
|
|
|
void http_response_status(HTTP_ResponseHandle res, int status);
|
|
void http_response_header(HTTP_ResponseHandle res, const char *fmt, ...);
|
|
void http_response_body(HTTP_ResponseHandle res, char *src, int len);
|
|
void http_response_done(HTTP_ResponseHandle res);
|
|
void http_response_undo(HTTP_ResponseHandle res);
|
|
|
|
#endif // HTTP_SERVER
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP PROXY
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_PROXY
|
|
|
|
#define HTTP_MAX_CONNS_PER_PROXY (1<<10)
|
|
|
|
typedef struct {
|
|
HTTP_Socket client_sock;
|
|
HTTP_Socket server_sock;
|
|
HTTP_ProxyEngine eng;
|
|
} HTTP_ProxyConnection;
|
|
|
|
typedef struct {
|
|
HTTP_Socket listen_sock;
|
|
int num_conns;
|
|
HTTP_ProxyConnection conns[HTTP_MAX_CONNS_PER_PROXY];
|
|
} HTTP_Proxy;
|
|
|
|
int http_proxy_init(HTTP_Proxy *proxy, const char *addr, int port);
|
|
void http_proxy_free(HTTP_Proxy *proxy);
|
|
int http_proxy_wait(HTTP_Proxy *proxy, int timeout);
|
|
|
|
#endif // HTTP_PROXY
|
|
/////////////////////////////////////////////////////////////////////
|
|
// HTTP ROUTER
|
|
/////////////////////////////////////////////////////////////////////
|
|
#if HTTP_ROUTER
|
|
|
|
typedef struct HTTP_Router HTTP_Router;
|
|
typedef void (*HTTP_RouterFunc)(HTTP_Request*, HTTP_ResponseHandle, void*);;
|
|
|
|
HTTP_Router* http_router_init (void);
|
|
void http_router_free (HTTP_Router *router);
|
|
void http_router_resolve (HTTP_Router *router, HTTP_Request *req, HTTP_ResponseHandle res);
|
|
void http_router_dir (HTTP_Router *router, HTTP_String endpoint, HTTP_String path);
|
|
void http_router_func (HTTP_Router *router, HTTP_Method method, HTTP_String endpoint, HTTP_RouterFunc func, void*);
|
|
int http_serve (const char *addr, int port, HTTP_Router *router);
|
|
|
|
#endif // HTTP_ROUTER
|
|
/////////////////////////////////////////////////////////////////////
|
|
// THE END
|
|
/////////////////////////////////////////////////////////////////////
|
|
#endif // HTTP_INCLUDED
|