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