#ifndef HTTP #define HTTP #include #include #include #include #include "picohttpparser.h" #define HTTP_MAX_ALLOWED_HEADERS 16 #define HTTP_MAX_REGEX_GROUPS 4 extern const char *http_response_type_names[5][32]; extern const char *http_header_names[]; typedef enum http_request_method { http_get = 0, http_post = 1, http_put = 2, http_patch = 3, http_delete = 4 } http_request_method; extern const char *request_method_names[]; extern const size_t request_method_names_len; typedef enum http_body_type { http_body_buf = 0, http_body_file = 1 } http_body_type; /* * Struct representing the specific type of request */ typedef struct http_request { size_t len; int minor_version; http_request_method method; const char *path; size_t path_len; const char *query; size_t query_len; http_body_type body_type; union { char *buf; FILE *file; } body; size_t body_len; size_t body_received; char *body_file_name; regmatch_t regex_groups[HTTP_MAX_REGEX_GROUPS]; struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS]; size_t num_headers; } http_request; typedef enum http_parse_error { http_parse_error_ok = 0, http_parse_error_incomplete = 1, http_parse_error_invalid = 2, http_parse_error_unknown_method = 3 } http_parse_error; /* void http_route(event_loop_conn *conn); */ typedef enum http_response_type { // 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, http_not_found = 404, http_method_not_allowed = 405, 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 } http_response_type; typedef enum http_header { http_header_connection = 0, http_header_location = 1 } http_header; typedef struct http_response_header { http_header type; const char *value; bool owned; } http_response_header; typedef struct http_response { http_response_type status; const char *head; size_t head_len; size_t head_written; http_body_type body_type; union { char *buf; FILE *file; } body; size_t body_len; size_t body_written; // If false, the body won't be freed bool owns_body; http_response_header headers[4]; size_t header_count; } http_response; #endif