1*f4ea8fe2Sjob /* $OpenBSD: http.h,v 1.17 2024/03/24 10:53:27 job Exp $ */ 2b7b6a941Sreyk 3b7b6a941Sreyk /* 405c2c945Sreyk * Copyright (c) 2012 - 2015 Reyk Floeter <reyk@openbsd.org> 5b7b6a941Sreyk * 6b7b6a941Sreyk * Permission to use, copy, modify, and distribute this software for any 7b7b6a941Sreyk * purpose with or without fee is hereby granted, provided that the above 8b7b6a941Sreyk * copyright notice and this permission notice appear in all copies. 9b7b6a941Sreyk * 10b7b6a941Sreyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11b7b6a941Sreyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12b7b6a941Sreyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13b7b6a941Sreyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14b7b6a941Sreyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15b7b6a941Sreyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16b7b6a941Sreyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17b7b6a941Sreyk */ 18b7b6a941Sreyk 19a3e464c5Sreyk #ifndef HTTP_H 20a3e464c5Sreyk #define HTTP_H 21b7b6a941Sreyk 226af43371Sreyk #define HTTP_PORT 80 236af43371Sreyk #define HTTPS_PORT 443 246af43371Sreyk 25b7b6a941Sreyk enum httpmethod { 26b7b6a941Sreyk HTTP_METHOD_NONE = 0, 27b7b6a941Sreyk 2806ea06a1Sdoug /* HTTP/1.1, RFC 7231 */ 29b7b6a941Sreyk HTTP_METHOD_GET, 30b7b6a941Sreyk HTTP_METHOD_HEAD, 31b7b6a941Sreyk HTTP_METHOD_POST, 32b7b6a941Sreyk HTTP_METHOD_PUT, 33b7b6a941Sreyk HTTP_METHOD_DELETE, 34b7b6a941Sreyk HTTP_METHOD_OPTIONS, 35b7b6a941Sreyk HTTP_METHOD_TRACE, 36b7b6a941Sreyk HTTP_METHOD_CONNECT, 37b7b6a941Sreyk 38b7b6a941Sreyk /* WebDAV, RFC 4918 */ 39b7b6a941Sreyk HTTP_METHOD_PROPFIND, 40b7b6a941Sreyk HTTP_METHOD_PROPPATCH, 41b7b6a941Sreyk HTTP_METHOD_MKCOL, 42b7b6a941Sreyk HTTP_METHOD_COPY, 43b7b6a941Sreyk HTTP_METHOD_MOVE, 44b7b6a941Sreyk HTTP_METHOD_LOCK, 45b7b6a941Sreyk HTTP_METHOD_UNLOCK, 46b7b6a941Sreyk 47f0c872b4Sreyk /* WebDAV Versioning Extension, RFC 3253 */ 48f0c872b4Sreyk HTTP_METHOD_VERSION_CONTROL, 49f0c872b4Sreyk HTTP_METHOD_REPORT, 50f0c872b4Sreyk HTTP_METHOD_CHECKOUT, 51f0c872b4Sreyk HTTP_METHOD_CHECKIN, 52f0c872b4Sreyk HTTP_METHOD_UNCHECKOUT, 53f0c872b4Sreyk HTTP_METHOD_MKWORKSPACE, 54f0c872b4Sreyk HTTP_METHOD_UPDATE, 55f0c872b4Sreyk HTTP_METHOD_LABEL, 56f0c872b4Sreyk HTTP_METHOD_MERGE, 57f0c872b4Sreyk HTTP_METHOD_BASELINE_CONTROL, 58f0c872b4Sreyk HTTP_METHOD_MKACTIVITY, 59f0c872b4Sreyk 60f0c872b4Sreyk /* WebDAV Ordered Collections, RFC 3648 */ 61f0c872b4Sreyk HTTP_METHOD_ORDERPATCH, 62f0c872b4Sreyk 63f0c872b4Sreyk /* WebDAV Access Control, RFC 3744 */ 64f0c872b4Sreyk HTTP_METHOD_ACL, 65f0c872b4Sreyk 66f0c872b4Sreyk /* WebDAV Redirect Reference Resources, RFC 4437 */ 67f0c872b4Sreyk HTTP_METHOD_MKREDIRECTREF, 68f0c872b4Sreyk HTTP_METHOD_UPDATEREDIRECTREF, 69f0c872b4Sreyk 70f0c872b4Sreyk /* WebDAV Search, RFC 5323 */ 71f0c872b4Sreyk HTTP_METHOD_SEARCH, 72f0c872b4Sreyk 73b7b6a941Sreyk /* PATCH, RFC 5789 */ 74b7b6a941Sreyk HTTP_METHOD_PATCH, 75b7b6a941Sreyk 76b7b6a941Sreyk /* Server response (internal value) */ 77b7b6a941Sreyk HTTP_METHOD_RESPONSE 78b7b6a941Sreyk }; 79b7b6a941Sreyk 80b7b6a941Sreyk struct http_method { 81b7b6a941Sreyk enum httpmethod method_id; 82b7b6a941Sreyk const char *method_name; 83b7b6a941Sreyk }; 84b7b6a941Sreyk #define HTTP_METHODS { \ 85b7b6a941Sreyk { HTTP_METHOD_GET, "GET" }, \ 86b7b6a941Sreyk { HTTP_METHOD_HEAD, "HEAD" }, \ 87b7b6a941Sreyk { HTTP_METHOD_POST, "POST" }, \ 88b7b6a941Sreyk { HTTP_METHOD_PUT, "PUT" }, \ 89b7b6a941Sreyk { HTTP_METHOD_DELETE, "DELETE" }, \ 90b7b6a941Sreyk { HTTP_METHOD_OPTIONS, "OPTIONS" }, \ 91b7b6a941Sreyk { HTTP_METHOD_TRACE, "TRACE" }, \ 92b7b6a941Sreyk { HTTP_METHOD_CONNECT, "CONNECT" }, \ 93b7b6a941Sreyk { HTTP_METHOD_PROPFIND, "PROPFIND" }, \ 94b7b6a941Sreyk { HTTP_METHOD_PROPPATCH, "PROPPATCH" }, \ 95b7b6a941Sreyk { HTTP_METHOD_MKCOL, "MKCOL" }, \ 96b7b6a941Sreyk { HTTP_METHOD_COPY, "COPY" }, \ 97b7b6a941Sreyk { HTTP_METHOD_MOVE, "MOVE" }, \ 98b7b6a941Sreyk { HTTP_METHOD_LOCK, "LOCK" }, \ 99b7b6a941Sreyk { HTTP_METHOD_UNLOCK, "UNLOCK" }, \ 100f0c872b4Sreyk { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" }, \ 101f0c872b4Sreyk { HTTP_METHOD_REPORT, "REPORT" }, \ 102f0c872b4Sreyk { HTTP_METHOD_CHECKOUT, "CHECKOUT" }, \ 103f0c872b4Sreyk { HTTP_METHOD_CHECKIN, "CHECKIN" }, \ 104f0c872b4Sreyk { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" }, \ 105f0c872b4Sreyk { HTTP_METHOD_MKWORKSPACE, "MKWORKSPACE" }, \ 106f0c872b4Sreyk { HTTP_METHOD_UPDATE, "UPDATE" }, \ 107f0c872b4Sreyk { HTTP_METHOD_LABEL, "LABEL" }, \ 108f0c872b4Sreyk { HTTP_METHOD_MERGE, "MERGE" }, \ 109f0c872b4Sreyk { HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" }, \ 110f0c872b4Sreyk { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" }, \ 111f0c872b4Sreyk { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" }, \ 112f0c872b4Sreyk { HTTP_METHOD_ACL, "ACL" }, \ 113f0c872b4Sreyk { HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" }, \ 114f0c872b4Sreyk { HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" }, \ 115f0c872b4Sreyk { HTTP_METHOD_SEARCH, "SEARCH" }, \ 116b7b6a941Sreyk { HTTP_METHOD_PATCH, "PATCH" }, \ 117b7b6a941Sreyk { HTTP_METHOD_NONE, NULL } \ 118b7b6a941Sreyk } 119b7b6a941Sreyk 120b7b6a941Sreyk struct http_error { 121b7b6a941Sreyk int error_code; 122b7b6a941Sreyk const char *error_name; 123b7b6a941Sreyk }; 12406ea06a1Sdoug 12506ea06a1Sdoug /* 12606ea06a1Sdoug * HTTP status codes based on IANA assignments (2014-06-11 version): 12706ea06a1Sdoug * https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml 12806ea06a1Sdoug * plus legacy (306) and non-standard (420). 12906ea06a1Sdoug */ 130b7b6a941Sreyk #define HTTP_ERRORS { \ 131b7b6a941Sreyk { 100, "Continue" }, \ 132b7b6a941Sreyk { 101, "Switching Protocols" }, \ 13306ea06a1Sdoug { 102, "Processing" }, \ 134*f4ea8fe2Sjob { 103, "Early Hints" }, \ 135*f4ea8fe2Sjob /* 104-199 unassigned */ \ 136b7b6a941Sreyk { 200, "OK" }, \ 137b7b6a941Sreyk { 201, "Created" }, \ 138b7b6a941Sreyk { 202, "Accepted" }, \ 13906ea06a1Sdoug { 203, "Non-Authoritative Information" }, \ 140b7b6a941Sreyk { 204, "No Content" }, \ 141b7b6a941Sreyk { 205, "Reset Content" }, \ 142b7b6a941Sreyk { 206, "Partial Content" }, \ 14306ea06a1Sdoug { 207, "Multi-Status" }, \ 14406ea06a1Sdoug { 208, "Already Reported" }, \ 14506ea06a1Sdoug /* 209-225 unassigned */ \ 14606ea06a1Sdoug { 226, "IM Used" }, \ 14706ea06a1Sdoug /* 227-299 unassigned */ \ 148b7b6a941Sreyk { 300, "Multiple Choices" }, \ 149b7b6a941Sreyk { 301, "Moved Permanently" }, \ 15006ea06a1Sdoug { 302, "Found" }, \ 151b7b6a941Sreyk { 303, "See Other" }, \ 152b7b6a941Sreyk { 304, "Not Modified" }, \ 15306ea06a1Sdoug { 305, "Use Proxy" }, \ 15406ea06a1Sdoug { 306, "Switch Proxy" }, \ 155b7b6a941Sreyk { 307, "Temporary Redirect" }, \ 15606ea06a1Sdoug { 308, "Permanent Redirect" }, \ 15706ea06a1Sdoug /* 309-399 unassigned */ \ 158b7b6a941Sreyk { 400, "Bad Request" }, \ 159b7b6a941Sreyk { 401, "Unauthorized" }, \ 160b7b6a941Sreyk { 402, "Payment Required" }, \ 161b7b6a941Sreyk { 403, "Forbidden" }, \ 162b7b6a941Sreyk { 404, "Not Found" }, \ 163b7b6a941Sreyk { 405, "Method Not Allowed" }, \ 164b7b6a941Sreyk { 406, "Not Acceptable" }, \ 165b7b6a941Sreyk { 407, "Proxy Authentication Required" }, \ 166b7b6a941Sreyk { 408, "Request Timeout" }, \ 167b7b6a941Sreyk { 409, "Conflict" }, \ 168b7b6a941Sreyk { 410, "Gone" }, \ 169b7b6a941Sreyk { 411, "Length Required" }, \ 170b7b6a941Sreyk { 412, "Precondition Failed" }, \ 17106ea06a1Sdoug { 413, "Payload Too Large" }, \ 17206ea06a1Sdoug { 414, "URI Too Long" }, \ 173b7b6a941Sreyk { 415, "Unsupported Media Type" }, \ 17406ea06a1Sdoug { 416, "Range Not Satisfiable" }, \ 175b7b6a941Sreyk { 417, "Expectation Failed" }, \ 176c05a8c45Sflorian { 418, "I'm a teapot" }, \ 177c05a8c45Sflorian /* 419-421 unassigned */ \ 17806ea06a1Sdoug { 420, "Enhance Your Calm" }, \ 179*f4ea8fe2Sjob { 422, "Unprocessable Content" }, \ 18006ea06a1Sdoug { 423, "Locked" }, \ 18106ea06a1Sdoug { 424, "Failed Dependency" }, \ 182*f4ea8fe2Sjob { 425, "Too Early" }, \ 18306ea06a1Sdoug { 426, "Upgrade Required" }, \ 18406ea06a1Sdoug /* 427 unassigned */ \ 18506ea06a1Sdoug { 428, "Precondition Required" }, \ 18606ea06a1Sdoug { 429, "Too Many Requests" }, \ 18706ea06a1Sdoug /* 430 unassigned */ \ 18806ea06a1Sdoug { 431, "Request Header Fields Too Large" }, \ 189c05a8c45Sflorian /* 432-450 unassigned */ \ 190c05a8c45Sflorian { 451, "Unavailable For Legal Reasons" }, \ 191c05a8c45Sflorian /* 452-499 unassigned */ \ 192b7b6a941Sreyk { 500, "Internal Server Error" }, \ 193b7b6a941Sreyk { 501, "Not Implemented" }, \ 194b7b6a941Sreyk { 502, "Bad Gateway" }, \ 195b7b6a941Sreyk { 503, "Service Unavailable" }, \ 196b7b6a941Sreyk { 504, "Gateway Timeout" }, \ 197b7b6a941Sreyk { 505, "HTTP Version Not Supported" }, \ 19806ea06a1Sdoug { 506, "Variant Also Negotiates" }, \ 19906ea06a1Sdoug { 507, "Insufficient Storage" }, \ 20006ea06a1Sdoug { 508, "Loop Detected" }, \ 20106ea06a1Sdoug /* 509 unassigned */ \ 20206ea06a1Sdoug { 510, "Not Extended" }, \ 20306ea06a1Sdoug { 511, "Network Authentication Required" }, \ 20406ea06a1Sdoug /* 512-599 unassigned */ \ 205b7b6a941Sreyk { 0, NULL } \ 206b7b6a941Sreyk } 207b7b6a941Sreyk 2089b9ff8ecSreyk struct http_mediatype { 2099b9ff8ecSreyk char *media_name; 2109b9ff8ecSreyk char *media_type; 2119b9ff8ecSreyk char *media_subtype; 2129b9ff8ecSreyk }; 21306ea06a1Sdoug /* 21406ea06a1Sdoug * Some default media types based on (2014-08-04 version): 21506ea06a1Sdoug * https://www.iana.org/assignments/media-types/media-types.xhtml 21606ea06a1Sdoug */ 2179b9ff8ecSreyk #define MEDIA_TYPES { \ 2189b9ff8ecSreyk { "css", "text", "css" }, \ 2199b9ff8ecSreyk { "html", "text", "html" }, \ 2209b9ff8ecSreyk { "txt", "text", "plain" }, \ 2219b9ff8ecSreyk { "gif", "image", "gif" }, \ 2229b9ff8ecSreyk { "jpeg", "image", "jpeg" }, \ 2239b9ff8ecSreyk { "jpg", "image", "jpeg" }, \ 2249b9ff8ecSreyk { "png", "image", "png" }, \ 225d8578b6bSreyk { "svg", "image", "svg+xml" }, \ 2269b9ff8ecSreyk { "js", "application", "javascript" }, \ 2279b9ff8ecSreyk { NULL } \ 2289b9ff8ecSreyk } 2299b9ff8ecSreyk 230b7b6a941Sreyk /* Used during runtime */ 231b7b6a941Sreyk struct http_descriptor { 232b7b6a941Sreyk struct kv http_pathquery; 233fb419eefSreyk struct kv http_matchquery; 234b7b6a941Sreyk #define http_path http_pathquery.kv_key 235b7b6a941Sreyk #define http_query http_pathquery.kv_value 236b7b6a941Sreyk #define http_rescode http_pathquery.kv_key 237b7b6a941Sreyk #define http_resmesg http_pathquery.kv_value 238fb419eefSreyk #define query_key http_matchquery.kv_key 239fb419eefSreyk #define query_val http_matchquery.kv_value 240b7b6a941Sreyk 24147dc2a9dSreyk char *http_host; 242b7b6a941Sreyk enum httpmethod http_method; 243b7b6a941Sreyk int http_chunked; 2446af43371Sreyk char *http_version; 245a9aa5d33Sbenno unsigned int http_status; 246b7b6a941Sreyk 247a23b6848Stb /* Rewritten path and query remain NULL if not used */ 248de6550b1Sreyk char *http_path_alias; 249a23b6848Stb char *http_query_alias; 25016a88448Syasuoka char *http_path_orig; 251de6550b1Sreyk 252b7b6a941Sreyk /* A tree of headers and attached lists for repeated headers. */ 253b7b6a941Sreyk struct kv *http_lastheader; 2546af43371Sreyk struct kvtree http_headers; 255b7b6a941Sreyk }; 256b7b6a941Sreyk 257a3e464c5Sreyk #endif /* HTTP_H */ 258