2023-05-25 12:01:20 +02:00
|
|
|
#ifndef HTTP
|
|
|
|
#define HTTP
|
|
|
|
|
2023-05-29 16:55:16 +02:00
|
|
|
#include <regex.h>
|
2023-05-29 11:36:57 +02:00
|
|
|
#include <stdbool.h>
|
2023-05-25 12:01:20 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2023-05-25 22:58:00 +02:00
|
|
|
#include "picohttpparser.h"
|
|
|
|
|
2023-05-29 11:36:57 +02:00
|
|
|
#define HTTP_MAX_ALLOWED_HEADERS 16
|
2023-05-29 16:55:16 +02:00
|
|
|
#define HTTP_MAX_REGEX_GROUPS 4
|
2023-05-25 22:58:00 +02:00
|
|
|
|
2023-05-28 10:23:32 +02:00
|
|
|
extern const char *http_response_type_names[5][32];
|
2023-05-29 15:34:46 +02:00
|
|
|
extern const char *http_header_names[];
|
2023-05-25 12:01:20 +02:00
|
|
|
|
2023-05-27 15:38:06 +02:00
|
|
|
typedef enum http_request_method {
|
2023-05-29 12:43:50 +02:00
|
|
|
http_get = 0,
|
|
|
|
http_post = 1,
|
|
|
|
http_put = 2,
|
|
|
|
http_patch = 3,
|
|
|
|
http_delete = 4
|
2023-05-27 15:38:06 +02:00
|
|
|
} http_request_method;
|
|
|
|
|
2023-05-28 09:09:46 +02:00
|
|
|
extern const char *request_method_names[];
|
|
|
|
extern const size_t request_method_names_len;
|
|
|
|
|
2023-05-27 15:38:06 +02:00
|
|
|
/*
|
|
|
|
* Struct representing the specific type of request
|
|
|
|
*/
|
|
|
|
typedef struct http_request {
|
|
|
|
size_t len;
|
|
|
|
int minor_version;
|
2023-05-28 09:09:46 +02:00
|
|
|
http_request_method method;
|
2023-05-27 15:38:06 +02:00
|
|
|
const char *path;
|
|
|
|
size_t path_len;
|
2023-05-27 17:14:49 +02:00
|
|
|
const char *query;
|
|
|
|
size_t query_len;
|
2023-05-29 16:55:16 +02:00
|
|
|
regmatch_t regex_groups[HTTP_MAX_REGEX_GROUPS];
|
2023-05-27 15:38:06 +02:00
|
|
|
struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
|
|
|
|
} http_request;
|
|
|
|
|
2023-05-25 12:01:20 +02:00
|
|
|
typedef enum http_parse_error {
|
|
|
|
http_parse_error_ok = 0,
|
|
|
|
http_parse_error_incomplete = 1,
|
|
|
|
http_parse_error_invalid = 2,
|
2023-05-28 09:09:46 +02:00
|
|
|
http_parse_error_unknown_method = 3
|
2023-05-25 12:01:20 +02:00
|
|
|
} http_parse_error;
|
|
|
|
|
2023-05-27 15:38:06 +02:00
|
|
|
/* void http_route(event_loop_conn *conn); */
|
2023-05-25 22:58:00 +02:00
|
|
|
|
2023-05-26 22:41:01 +02:00
|
|
|
typedef enum http_response_type {
|
2023-05-28 10:23:32 +02:00
|
|
|
// 1xx
|
|
|
|
http_continue = 100,
|
|
|
|
http_switching_protocols = 101,
|
|
|
|
http_processing = 102,
|
|
|
|
http_early_hints = 103,
|
|
|
|
// 2xx
|
|
|
|
http_ok = 200,
|
|
|
|
http_created = 201,
|
|
|
|
http_accepted = 202,
|
|
|
|
http_non_authoritative_information = 203,
|
|
|
|
http_no_content = 204,
|
|
|
|
http_reset_content = 205,
|
|
|
|
http_partial_content = 206,
|
|
|
|
http_multi_status = 207,
|
|
|
|
http_already_reported = 208,
|
|
|
|
// 3xx
|
|
|
|
http_multiple_choices = 300,
|
|
|
|
http_moved_permanently = 301,
|
|
|
|
http_found = 302,
|
|
|
|
http_see_other = 303,
|
|
|
|
http_not_modified = 304,
|
|
|
|
http_temporary_redirect = 307,
|
|
|
|
http_permanent_redirect = 308,
|
|
|
|
// 4xx
|
|
|
|
http_bad_request = 400,
|
|
|
|
http_unauthorized = 401,
|
|
|
|
http_payment_required = 402,
|
|
|
|
http_forbidden = 403,
|
2023-05-26 22:41:01 +02:00
|
|
|
http_not_found = 404,
|
2023-05-28 09:09:46 +02:00
|
|
|
http_method_not_allowed = 405,
|
2023-05-28 10:23:32 +02:00
|
|
|
http_not_acceptable = 406,
|
|
|
|
http_proxy_authentication_required = 407,
|
|
|
|
http_request_timeout = 408,
|
|
|
|
http_conflict = 409,
|
|
|
|
http_gone = 410,
|
|
|
|
http_length_required = 411,
|
|
|
|
http_precondition_failed = 412,
|
|
|
|
http_content_too_large = 413,
|
|
|
|
http_uri_too_long = 414,
|
|
|
|
http_unsupported_media_type = 415,
|
|
|
|
http_range_not_satisfiable = 416,
|
|
|
|
http_expection_failed = 417,
|
|
|
|
http_im_a_teapot = 418,
|
|
|
|
http_misdirected_request = 421,
|
|
|
|
http_unprocessable_content = 422,
|
|
|
|
http_locked = 423,
|
|
|
|
http_failed_dependency = 424,
|
|
|
|
http_too_early = 425,
|
|
|
|
http_upgrade_required = 426,
|
|
|
|
http_precondition_required = 428,
|
|
|
|
http_too_many_requests = 429,
|
|
|
|
http_request_header_fields_too_large = 431,
|
|
|
|
// 5xx
|
|
|
|
http_internal_server_error = 500,
|
|
|
|
http_method_not_implemented = 501,
|
|
|
|
http_bad_gateway = 502,
|
|
|
|
http_service_unavailable = 503,
|
|
|
|
http_gateway_timeout = 504,
|
|
|
|
http_http_version_not_supported = 505,
|
|
|
|
http_variant_also_negotiates = 506,
|
|
|
|
http_insufficient_storage = 507,
|
|
|
|
http_loop_detected = 508,
|
|
|
|
http_not_extended = 510,
|
|
|
|
http_network_authentication_required = 511
|
2023-05-26 22:41:01 +02:00
|
|
|
} http_response_type;
|
|
|
|
|
2023-05-29 15:34:46 +02:00
|
|
|
typedef enum http_header {
|
|
|
|
http_header_connection = 0,
|
2023-05-29 18:15:48 +02:00
|
|
|
http_header_location = 1
|
2023-05-29 15:34:46 +02:00
|
|
|
} http_header;
|
|
|
|
|
|
|
|
typedef struct http_response_header {
|
|
|
|
http_header type;
|
|
|
|
const char *value;
|
|
|
|
bool owned;
|
|
|
|
} http_response_header;
|
|
|
|
|
2023-05-29 17:53:57 +02:00
|
|
|
typedef enum http_response_body_type {
|
|
|
|
http_response_body_buf = 0,
|
|
|
|
http_response_body_file = 1
|
|
|
|
} http_response_body_type;
|
|
|
|
|
2023-05-28 18:24:22 +02:00
|
|
|
typedef struct http_response {
|
|
|
|
http_response_type type;
|
2023-05-29 11:36:57 +02:00
|
|
|
const char *head;
|
|
|
|
size_t head_len;
|
|
|
|
size_t head_written;
|
2023-05-29 17:53:57 +02:00
|
|
|
http_response_body_type body_type;
|
|
|
|
void *body;
|
2023-05-28 18:24:22 +02:00
|
|
|
size_t body_len;
|
|
|
|
size_t body_written;
|
2023-05-29 11:36:57 +02:00
|
|
|
// If false, the body won't be freed
|
|
|
|
bool owns_body;
|
2023-05-29 15:34:46 +02:00
|
|
|
http_response_header headers[4];
|
|
|
|
size_t header_count;
|
2023-05-28 18:24:22 +02:00
|
|
|
} http_response;
|
|
|
|
|
2023-05-25 12:01:20 +02:00
|
|
|
#endif
|