1*53e8df0dSbenno /* $OpenBSD: http.h,v 1.12 2021/03/24 20:59:53 benno Exp $ */ 2cb8b0e56Sreyk 3cb8b0e56Sreyk /* 496e6e983Sreyk * Copyright (c) 2012 - 2015 Reyk Floeter <reyk@openbsd.org> 5cb8b0e56Sreyk * 6cb8b0e56Sreyk * Permission to use, copy, modify, and distribute this software for any 7cb8b0e56Sreyk * purpose with or without fee is hereby granted, provided that the above 8cb8b0e56Sreyk * copyright notice and this permission notice appear in all copies. 9cb8b0e56Sreyk * 10cb8b0e56Sreyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11cb8b0e56Sreyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12cb8b0e56Sreyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13cb8b0e56Sreyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14cb8b0e56Sreyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15cb8b0e56Sreyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16cb8b0e56Sreyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17cb8b0e56Sreyk */ 18cb8b0e56Sreyk 19a3e464c5Sreyk #ifndef HTTP_H 20a3e464c5Sreyk #define HTTP_H 21cb8b0e56Sreyk 22*53e8df0dSbenno #include <sys/queue.h> 23*53e8df0dSbenno 24c9447d50Sreyk #define HTTP_PORT 80 25c9447d50Sreyk #define HTTPS_PORT 443 26c9447d50Sreyk 27cb8b0e56Sreyk enum httpmethod { 28cb8b0e56Sreyk HTTP_METHOD_NONE = 0, 29cb8b0e56Sreyk 30c9447d50Sreyk /* HTTP/1.1, RFC 7231 */ 31cb8b0e56Sreyk HTTP_METHOD_GET, 32cb8b0e56Sreyk HTTP_METHOD_HEAD, 33cb8b0e56Sreyk HTTP_METHOD_POST, 34cb8b0e56Sreyk HTTP_METHOD_PUT, 35cb8b0e56Sreyk HTTP_METHOD_DELETE, 36cb8b0e56Sreyk HTTP_METHOD_OPTIONS, 37cb8b0e56Sreyk HTTP_METHOD_TRACE, 38cb8b0e56Sreyk HTTP_METHOD_CONNECT, 39cb8b0e56Sreyk 40cb8b0e56Sreyk /* WebDAV, RFC 4918 */ 41cb8b0e56Sreyk HTTP_METHOD_PROPFIND, 42cb8b0e56Sreyk HTTP_METHOD_PROPPATCH, 43cb8b0e56Sreyk HTTP_METHOD_MKCOL, 44cb8b0e56Sreyk HTTP_METHOD_COPY, 45cb8b0e56Sreyk HTTP_METHOD_MOVE, 46cb8b0e56Sreyk HTTP_METHOD_LOCK, 47cb8b0e56Sreyk HTTP_METHOD_UNLOCK, 48cb8b0e56Sreyk 4996e6e983Sreyk /* WebDAV Versioning Extension, RFC 3253 */ 5096e6e983Sreyk HTTP_METHOD_VERSION_CONTROL, 5196e6e983Sreyk HTTP_METHOD_REPORT, 5296e6e983Sreyk HTTP_METHOD_CHECKOUT, 5396e6e983Sreyk HTTP_METHOD_CHECKIN, 5496e6e983Sreyk HTTP_METHOD_UNCHECKOUT, 5596e6e983Sreyk HTTP_METHOD_MKWORKSPACE, 5696e6e983Sreyk HTTP_METHOD_UPDATE, 5796e6e983Sreyk HTTP_METHOD_LABEL, 5896e6e983Sreyk HTTP_METHOD_MERGE, 5996e6e983Sreyk HTTP_METHOD_BASELINE_CONTROL, 6096e6e983Sreyk HTTP_METHOD_MKACTIVITY, 6196e6e983Sreyk 6296e6e983Sreyk /* WebDAV Ordered Collections, RFC 3648 */ 6396e6e983Sreyk HTTP_METHOD_ORDERPATCH, 6496e6e983Sreyk 6596e6e983Sreyk /* WebDAV Access Control, RFC 3744 */ 6696e6e983Sreyk HTTP_METHOD_ACL, 6796e6e983Sreyk 6896e6e983Sreyk /* WebDAV Redirect Reference Resources, RFC 4437 */ 6996e6e983Sreyk HTTP_METHOD_MKREDIRECTREF, 7096e6e983Sreyk HTTP_METHOD_UPDATEREDIRECTREF, 7196e6e983Sreyk 7296e6e983Sreyk /* WebDAV Search, RFC 5323 */ 7396e6e983Sreyk HTTP_METHOD_SEARCH, 7496e6e983Sreyk 75cb8b0e56Sreyk /* PATCH, RFC 5789 */ 76cb8b0e56Sreyk HTTP_METHOD_PATCH, 77cb8b0e56Sreyk 78cb8b0e56Sreyk /* Server response (internal value) */ 79cb8b0e56Sreyk HTTP_METHOD_RESPONSE 80cb8b0e56Sreyk }; 81cb8b0e56Sreyk 82cb8b0e56Sreyk struct http_method { 83cb8b0e56Sreyk enum httpmethod method_id; 84cb8b0e56Sreyk const char *method_name; 85cb8b0e56Sreyk }; 86cb8b0e56Sreyk #define HTTP_METHODS { \ 87cb8b0e56Sreyk { HTTP_METHOD_GET, "GET" }, \ 88cb8b0e56Sreyk { HTTP_METHOD_HEAD, "HEAD" }, \ 89cb8b0e56Sreyk { HTTP_METHOD_POST, "POST" }, \ 90cb8b0e56Sreyk { HTTP_METHOD_PUT, "PUT" }, \ 91cb8b0e56Sreyk { HTTP_METHOD_DELETE, "DELETE" }, \ 92cb8b0e56Sreyk { HTTP_METHOD_OPTIONS, "OPTIONS" }, \ 93cb8b0e56Sreyk { HTTP_METHOD_TRACE, "TRACE" }, \ 94cb8b0e56Sreyk { HTTP_METHOD_CONNECT, "CONNECT" }, \ 95cb8b0e56Sreyk { HTTP_METHOD_PROPFIND, "PROPFIND" }, \ 96cb8b0e56Sreyk { HTTP_METHOD_PROPPATCH, "PROPPATCH" }, \ 97cb8b0e56Sreyk { HTTP_METHOD_MKCOL, "MKCOL" }, \ 98cb8b0e56Sreyk { HTTP_METHOD_COPY, "COPY" }, \ 99cb8b0e56Sreyk { HTTP_METHOD_MOVE, "MOVE" }, \ 100cb8b0e56Sreyk { HTTP_METHOD_LOCK, "LOCK" }, \ 101cb8b0e56Sreyk { HTTP_METHOD_UNLOCK, "UNLOCK" }, \ 10296e6e983Sreyk { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" }, \ 10396e6e983Sreyk { HTTP_METHOD_REPORT, "REPORT" }, \ 10496e6e983Sreyk { HTTP_METHOD_CHECKOUT, "CHECKOUT" }, \ 10596e6e983Sreyk { HTTP_METHOD_CHECKIN, "CHECKIN" }, \ 10696e6e983Sreyk { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" }, \ 10796e6e983Sreyk { HTTP_METHOD_MKWORKSPACE, "MKWORKSPACE" }, \ 10896e6e983Sreyk { HTTP_METHOD_UPDATE, "UPDATE" }, \ 10996e6e983Sreyk { HTTP_METHOD_LABEL, "LABEL" }, \ 11096e6e983Sreyk { HTTP_METHOD_MERGE, "MERGE" }, \ 11196e6e983Sreyk { HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" }, \ 11296e6e983Sreyk { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" }, \ 11396e6e983Sreyk { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" }, \ 11496e6e983Sreyk { HTTP_METHOD_ACL, "ACL" }, \ 11596e6e983Sreyk { HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" }, \ 11696e6e983Sreyk { HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" }, \ 11796e6e983Sreyk { HTTP_METHOD_SEARCH, "SEARCH" }, \ 118cb8b0e56Sreyk { HTTP_METHOD_PATCH, "PATCH" }, \ 119cb8b0e56Sreyk { HTTP_METHOD_NONE, NULL } \ 120cb8b0e56Sreyk } 121cb8b0e56Sreyk 122543ef491Sreyk struct http_error { 123543ef491Sreyk int error_code; 124543ef491Sreyk const char *error_name; 125543ef491Sreyk }; 126c9447d50Sreyk 127c9447d50Sreyk /* 128c9447d50Sreyk * HTTP status codes based on IANA assignments (2014-06-11 version): 129c9447d50Sreyk * https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml 130c9447d50Sreyk * plus legacy (306) and non-standard (420). 131c9447d50Sreyk */ 132543ef491Sreyk #define HTTP_ERRORS { \ 133543ef491Sreyk { 100, "Continue" }, \ 134543ef491Sreyk { 101, "Switching Protocols" }, \ 135c9447d50Sreyk { 102, "Processing" }, \ 136c9447d50Sreyk /* 103-199 unassigned */ \ 137543ef491Sreyk { 200, "OK" }, \ 138543ef491Sreyk { 201, "Created" }, \ 139543ef491Sreyk { 202, "Accepted" }, \ 140c9447d50Sreyk { 203, "Non-Authoritative Information" }, \ 141543ef491Sreyk { 204, "No Content" }, \ 142543ef491Sreyk { 205, "Reset Content" }, \ 143543ef491Sreyk { 206, "Partial Content" }, \ 144c9447d50Sreyk { 207, "Multi-Status" }, \ 145c9447d50Sreyk { 208, "Already Reported" }, \ 146c9447d50Sreyk /* 209-225 unassigned */ \ 147c9447d50Sreyk { 226, "IM Used" }, \ 148c9447d50Sreyk /* 227-299 unassigned */ \ 149543ef491Sreyk { 300, "Multiple Choices" }, \ 150543ef491Sreyk { 301, "Moved Permanently" }, \ 151c9447d50Sreyk { 302, "Found" }, \ 152543ef491Sreyk { 303, "See Other" }, \ 153543ef491Sreyk { 304, "Not Modified" }, \ 154c9447d50Sreyk { 305, "Use Proxy" }, \ 155c9447d50Sreyk { 306, "Switch Proxy" }, \ 156543ef491Sreyk { 307, "Temporary Redirect" }, \ 157c9447d50Sreyk { 308, "Permanent Redirect" }, \ 158c9447d50Sreyk /* 309-399 unassigned */ \ 159543ef491Sreyk { 400, "Bad Request" }, \ 160543ef491Sreyk { 401, "Unauthorized" }, \ 161543ef491Sreyk { 402, "Payment Required" }, \ 162543ef491Sreyk { 403, "Forbidden" }, \ 163543ef491Sreyk { 404, "Not Found" }, \ 164543ef491Sreyk { 405, "Method Not Allowed" }, \ 165543ef491Sreyk { 406, "Not Acceptable" }, \ 166543ef491Sreyk { 407, "Proxy Authentication Required" }, \ 167543ef491Sreyk { 408, "Request Timeout" }, \ 168543ef491Sreyk { 409, "Conflict" }, \ 169543ef491Sreyk { 410, "Gone" }, \ 170543ef491Sreyk { 411, "Length Required" }, \ 171543ef491Sreyk { 412, "Precondition Failed" }, \ 172c9447d50Sreyk { 413, "Payload Too Large" }, \ 173c9447d50Sreyk { 414, "URI Too Long" }, \ 174543ef491Sreyk { 415, "Unsupported Media Type" }, \ 175c9447d50Sreyk { 416, "Range Not Satisfiable" }, \ 176543ef491Sreyk { 417, "Expectation Failed" }, \ 17796e6e983Sreyk { 418, "I'm a teapot" }, \ 17896e6e983Sreyk /* 419-421 unassigned */ \ 179c9447d50Sreyk { 420, "Enhance Your Calm" }, \ 180c9447d50Sreyk { 422, "Unprocessable Entity" }, \ 181c9447d50Sreyk { 423, "Locked" }, \ 182c9447d50Sreyk { 424, "Failed Dependency" }, \ 183c9447d50Sreyk /* 425 unassigned */ \ 184c9447d50Sreyk { 426, "Upgrade Required" }, \ 185c9447d50Sreyk /* 427 unassigned */ \ 186c9447d50Sreyk { 428, "Precondition Required" }, \ 187c9447d50Sreyk { 429, "Too Many Requests" }, \ 188c9447d50Sreyk /* 430 unassigned */ \ 189c9447d50Sreyk { 431, "Request Header Fields Too Large" }, \ 19096e6e983Sreyk /* 432-450 unassigned */ \ 19196e6e983Sreyk { 451, "Unavailable For Legal Reasons" }, \ 19296e6e983Sreyk /* 452-499 unassigned */ \ 193543ef491Sreyk { 500, "Internal Server Error" }, \ 194543ef491Sreyk { 501, "Not Implemented" }, \ 195543ef491Sreyk { 502, "Bad Gateway" }, \ 196543ef491Sreyk { 503, "Service Unavailable" }, \ 197543ef491Sreyk { 504, "Gateway Timeout" }, \ 198543ef491Sreyk { 505, "HTTP Version Not Supported" }, \ 199c9447d50Sreyk { 506, "Variant Also Negotiates" }, \ 200c9447d50Sreyk { 507, "Insufficient Storage" }, \ 201c9447d50Sreyk { 508, "Loop Detected" }, \ 202c9447d50Sreyk /* 509 unassigned */ \ 203c9447d50Sreyk { 510, "Not Extended" }, \ 204c9447d50Sreyk { 511, "Network Authentication Required" }, \ 205c9447d50Sreyk /* 512-599 unassigned */ \ 206543ef491Sreyk { 0, NULL } \ 207543ef491Sreyk } 208543ef491Sreyk 209fb419eefSreyk struct http_mediatype { 210fb419eefSreyk char *media_name; 211fb419eefSreyk char *media_type; 212fb419eefSreyk char *media_subtype; 213fb419eefSreyk }; 214c9447d50Sreyk /* 215c9447d50Sreyk * Some default media types based on (2014-08-04 version): 216c9447d50Sreyk * https://www.iana.org/assignments/media-types/media-types.xhtml 217c9447d50Sreyk */ 218fb419eefSreyk #define MEDIA_TYPES { \ 219fb419eefSreyk { "css", "text", "css" }, \ 220fb419eefSreyk { "html", "text", "html" }, \ 221fb419eefSreyk { "txt", "text", "plain" }, \ 222fb419eefSreyk { "gif", "image", "gif" }, \ 223fb419eefSreyk { "jpeg", "image", "jpeg" }, \ 224fb419eefSreyk { "jpg", "image", "jpeg" }, \ 225fb419eefSreyk { "png", "image", "png" }, \ 22696e6e983Sreyk { "svg", "image", "svg+xml" }, \ 227fb419eefSreyk { "js", "application", "javascript" }, \ 228fb419eefSreyk { NULL } \ 229fb419eefSreyk } 230fb419eefSreyk 231cb8b0e56Sreyk /* Used during runtime */ 232cb8b0e56Sreyk struct http_descriptor { 233cb8b0e56Sreyk struct kv http_pathquery; 234cb8b0e56Sreyk struct kv http_matchquery; 235cb8b0e56Sreyk #define http_path http_pathquery.kv_key 236cb8b0e56Sreyk #define http_query http_pathquery.kv_value 237cb8b0e56Sreyk #define http_rescode http_pathquery.kv_key 238cb8b0e56Sreyk #define http_resmesg http_pathquery.kv_value 239cb8b0e56Sreyk #define query_key http_matchquery.kv_key 240cb8b0e56Sreyk #define query_val http_matchquery.kv_value 241cb8b0e56Sreyk 24296e6e983Sreyk char *http_host; 243cb8b0e56Sreyk enum httpmethod http_method; 244cb8b0e56Sreyk int http_chunked; 245c9447d50Sreyk char *http_version; 246055a638bSbenno unsigned int http_status; 247c9447d50Sreyk 24896e6e983Sreyk /* Rewritten path remains NULL if not used */ 24996e6e983Sreyk char *http_path_alias; 25096e6e983Sreyk 251c307a266Sreyk /* A tree of headers and attached lists for repeated headers. */ 252c307a266Sreyk struct kv *http_lastheader; 253c9447d50Sreyk struct kvtree http_headers; 254cb8b0e56Sreyk }; 255cb8b0e56Sreyk 256*53e8df0dSbenno struct http_method_node { 257*53e8df0dSbenno enum httpmethod hmn_method; 258*53e8df0dSbenno SIMPLEQ_ENTRY(http_method_node) hmn_entry; 259*53e8df0dSbenno }; 260*53e8df0dSbenno 261*53e8df0dSbenno struct http_session { 262*53e8df0dSbenno SIMPLEQ_HEAD(, http_method_node) hs_methods; 263*53e8df0dSbenno }; 264*53e8df0dSbenno 265a3e464c5Sreyk #endif /* HTTP_H */ 266