192 lines
4.5 KiB
C
192 lines
4.5 KiB
C
/**
|
|
* sesimos - secure, simple, modern web server
|
|
* @brief HTTP implementation (header file)
|
|
* @file src/lib/http.h
|
|
* @author Lorenz Stechauner
|
|
* @date 2020-12-09
|
|
*/
|
|
|
|
#ifndef SESIMOS_HTTP_H
|
|
#define SESIMOS_HTTP_H
|
|
|
|
#include "sock.h"
|
|
|
|
#define HTTP_PRESERVE 0
|
|
#define HTTP_LOWER 1
|
|
#define HTTP_CAMEL 2
|
|
|
|
#define HTTP_REMOVE_ONE 0
|
|
#define HTTP_REMOVE_ALL 1
|
|
#define HTTP_REMOVE_LAST 2
|
|
|
|
#define HTTP_FIELD_NORMAL 0
|
|
#define HTTP_FIELD_EX_VALUE 1
|
|
#define HTTP_FIELD_EX_NAME 2
|
|
|
|
#define HTTP_MERGE_FIELDS 1
|
|
|
|
#define HTTP_1XX_STR "\x1B[1;32m"
|
|
#define HTTP_2XX_STR "\x1B[1;32m"
|
|
#define HTTP_3XX_STR "\x1B[1;33m"
|
|
#define HTTP_4XX_STR "\x1B[1;31m"
|
|
#define HTTP_5XX_STR "\x1B[1;31m"
|
|
|
|
#define HTTP_COLOR_SUCCESS "#008000"
|
|
#define HTTP_COLOR_INFO "#606060"
|
|
#define HTTP_COLOR_WARNING "#E0C000"
|
|
#define HTTP_COLOR_ERROR "#C00000"
|
|
|
|
#define CLIENT_MAX_HEADER_SIZE 8192
|
|
#define HTTP_INIT_HEADER_FIELD_NUM 16
|
|
|
|
#define HTTP_TYPE_INFORMATIONAL 1
|
|
#define HTTP_TYPE_SUCCESS 2
|
|
#define HTTP_TYPE_REDIRECTION 3
|
|
#define HTTP_TYPE_CLIENT_ERROR 4
|
|
#define HTTP_TYPE_SERVER_ERROR 5
|
|
|
|
#define HTTP_ERROR_GENERAL 1
|
|
#define HTTP_ERROR_SYSCALL 2
|
|
#define HTTP_ERROR_TOO_MANY_HEADER_FIELDS 3
|
|
#define HTTP_ERROR_EOH_NOT_FOUND 4
|
|
#define HTTP_ERROR_HEADER_MALFORMED 5
|
|
#define HTTP_ERROR_INVALID_VERSION 6
|
|
#define HTTP_ERROR_URI_TOO_LONG 7
|
|
|
|
#ifndef SERVER_STR
|
|
# define SERVER_STR "sesimos"
|
|
#endif
|
|
|
|
#ifndef SERVER_STR_HTML
|
|
# define SERVER_STR_HTML "sesimos web server"
|
|
#endif
|
|
|
|
typedef unsigned short status_code_t;
|
|
|
|
typedef struct {
|
|
status_code_t code:10;
|
|
unsigned char type:3;
|
|
char msg[64];
|
|
} http_status;
|
|
|
|
typedef struct {
|
|
status_code_t code:10;
|
|
const char *msg;
|
|
} http_status_msg;
|
|
|
|
typedef struct {
|
|
char mode[8];
|
|
char color[8];
|
|
const char *icon;
|
|
const char *doc;
|
|
} http_doc_info;
|
|
|
|
typedef struct {
|
|
char type;
|
|
union {
|
|
struct {
|
|
char name[32];
|
|
char value[32];
|
|
} normal;
|
|
struct {
|
|
char name[64 - sizeof(char *)];
|
|
char *value;
|
|
} ex_value;
|
|
struct {
|
|
char *name;
|
|
char *value;
|
|
} ex_name;
|
|
};
|
|
} http_field;
|
|
|
|
typedef struct {
|
|
int last_field_num;
|
|
http_field *fields;
|
|
} http_hdr;
|
|
|
|
typedef struct {
|
|
char method[16];
|
|
char *uri;
|
|
char version[4];
|
|
http_hdr hdr;
|
|
} http_req;
|
|
|
|
typedef struct {
|
|
const http_status *status;
|
|
char version[4];
|
|
http_hdr hdr;
|
|
} http_res;
|
|
|
|
typedef enum {
|
|
NONE, INTERNAL, CLIENT_REQ, SERVER_REQ, SERVER, SERVER_RES, CLIENT_RES
|
|
} http_error_origin;
|
|
|
|
typedef struct {
|
|
status_code_t status;
|
|
http_error_origin origin;
|
|
const char* ws_key;
|
|
} http_status_ctx;
|
|
|
|
extern const http_status http_statuses[];
|
|
extern const http_status_msg http_status_messages[];
|
|
extern const int http_statuses_size;
|
|
extern const int http_status_messages_size;
|
|
|
|
extern const char http_error_doc[], http_warning_doc[], http_success_doc[], http_info_doc[];
|
|
|
|
const char *http_error_str(int err);
|
|
|
|
void http_to_camel_case(char *str, int mode);
|
|
|
|
const char *http_field_get_name(const http_field *field);
|
|
|
|
const char *http_field_get_value(const http_field *field);
|
|
|
|
int http_init_hdr(http_hdr *hdr);
|
|
|
|
void http_free_field(http_field *f);
|
|
|
|
void http_free_hdr(http_hdr *hdr);
|
|
|
|
void http_free_req(http_req *req);
|
|
|
|
void http_free_res(http_res *res);
|
|
|
|
int http_parse_request(char *buf, http_req *req);
|
|
|
|
int http_receive_request(sock *client, http_req *req);
|
|
|
|
int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr, int flags);
|
|
|
|
const char *http_get_header_field(const http_hdr *hdr, const char *field_name);
|
|
|
|
int http_get_header_field_num(const http_hdr *hdr, const char *field_name);
|
|
|
|
int http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);
|
|
|
|
int http_add_header_field_len(http_hdr *hdr, const char *name, unsigned long name_len, const char *value, unsigned long value_len);
|
|
|
|
void http_append_to_header_field(http_field *field, const char *value, unsigned long len);
|
|
|
|
void http_remove_header_field(http_hdr *hdr, const char *field_name, int mode);
|
|
|
|
int http_send_response(sock *client, http_res *res);
|
|
|
|
int http_send_request(sock *server, http_req *req);
|
|
|
|
const http_status *http_get_status(status_code_t status_code);
|
|
|
|
const http_status_msg *http_get_error_msg(status_code_t status_code);
|
|
|
|
const char *http_get_status_color(status_code_t status_code);
|
|
|
|
char *http_format_date(time_t time, char *buf, size_t size);
|
|
|
|
char *http_get_date(char *buf, size_t size);
|
|
|
|
const http_doc_info *http_get_status_info(status_code_t status_code);
|
|
|
|
int http_get_compression(const http_req *req, const http_res *res);
|
|
|
|
#endif //SESIMOS_HTTP_H
|