Blob


1 /* $OpenBSD: http.h,v 1.14 2026/06/03 20:00:34 kirill Exp $ */
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 */
19 #ifndef HTTP_H
20 #define HTTP_H
22 #include <sys/queue.h>
24 #define HTTP_PORT 80
25 #define HTTPS_PORT 443
27 enum httpmethod {
28 HTTP_METHOD_NONE = 0,
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,
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,
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,
62 /* WebDAV Ordered Collections, RFC 3648 */
63 HTTP_METHOD_ORDERPATCH,
65 /* WebDAV Access Control, RFC 3744 */
66 HTTP_METHOD_ACL,
68 /* WebDAV Redirect Reference Resources, RFC 4437 */
69 HTTP_METHOD_MKREDIRECTREF,
70 HTTP_METHOD_UPDATEREDIRECTREF,
72 /* WebDAV Search, RFC 5323 */
73 HTTP_METHOD_SEARCH,
75 /* WebDAV Calendaring Extensions, RFC 4791 */
76 HTTP_METHOD_MKCALENDAR,
78 /* PATCH, RFC 5789 */
79 HTTP_METHOD_PATCH,
81 /* Server response (internal value) */
82 HTTP_METHOD_RESPONSE
83 };
85 struct http_method {
86 enum httpmethod method_id;
87 const char *method_name;
88 };
89 #define HTTP_METHODS { \
90 { HTTP_METHOD_GET, "GET" }, \
91 { HTTP_METHOD_HEAD, "HEAD" }, \
92 { HTTP_METHOD_POST, "POST" }, \
93 { HTTP_METHOD_PUT, "PUT" }, \
94 { HTTP_METHOD_DELETE, "DELETE" }, \
95 { HTTP_METHOD_OPTIONS, "OPTIONS" }, \
96 { HTTP_METHOD_TRACE, "TRACE" }, \
97 { HTTP_METHOD_CONNECT, "CONNECT" }, \
98 { HTTP_METHOD_PROPFIND, "PROPFIND" }, \
99 { HTTP_METHOD_PROPPATCH, "PROPPATCH" }, \
100 { HTTP_METHOD_MKCOL, "MKCOL" }, \
101 { HTTP_METHOD_COPY, "COPY" }, \
102 { HTTP_METHOD_MOVE, "MOVE" }, \
103 { HTTP_METHOD_LOCK, "LOCK" }, \
104 { HTTP_METHOD_UNLOCK, "UNLOCK" }, \
105 { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" }, \
106 { HTTP_METHOD_REPORT, "REPORT" }, \
107 { HTTP_METHOD_CHECKOUT, "CHECKOUT" }, \
108 { HTTP_METHOD_CHECKIN, "CHECKIN" }, \
109 { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" }, \
110 { HTTP_METHOD_MKWORKSPACE, "MKWORKSPACE" }, \
111 { HTTP_METHOD_UPDATE, "UPDATE" }, \
112 { HTTP_METHOD_LABEL, "LABEL" }, \
113 { HTTP_METHOD_MERGE, "MERGE" }, \
114 { HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" }, \
115 { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" }, \
116 { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" }, \
117 { HTTP_METHOD_ACL, "ACL" }, \
118 { HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" }, \
119 { HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" }, \
120 { HTTP_METHOD_SEARCH, "SEARCH" }, \
121 { HTTP_METHOD_MKCALENDAR, "MKCALENDAR" }, \
122 { HTTP_METHOD_PATCH, "PATCH" }, \
123 { HTTP_METHOD_NONE, NULL } \
126 struct http_error {
127 int error_code;
128 const char *error_name;
129 };
131 /*
132 * HTTP status codes based on IANA assignments (2014-06-11 version):
133 * https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
134 * plus legacy (306) and non-standard (420).
135 */
136 #define HTTP_ERRORS { \
137 { 100, "Continue" }, \
138 { 101, "Switching Protocols" }, \
139 { 102, "Processing" }, \
140 /* 103-199 unassigned */ \
141 { 200, "OK" }, \
142 { 201, "Created" }, \
143 { 202, "Accepted" }, \
144 { 203, "Non-Authoritative Information" }, \
145 { 204, "No Content" }, \
146 { 205, "Reset Content" }, \
147 { 206, "Partial Content" }, \
148 { 207, "Multi-Status" }, \
149 { 208, "Already Reported" }, \
150 /* 209-225 unassigned */ \
151 { 226, "IM Used" }, \
152 /* 227-299 unassigned */ \
153 { 300, "Multiple Choices" }, \
154 { 301, "Moved Permanently" }, \
155 { 302, "Found" }, \
156 { 303, "See Other" }, \
157 { 304, "Not Modified" }, \
158 { 305, "Use Proxy" }, \
159 { 306, "Switch Proxy" }, \
160 { 307, "Temporary Redirect" }, \
161 { 308, "Permanent Redirect" }, \
162 /* 309-399 unassigned */ \
163 { 400, "Bad Request" }, \
164 { 401, "Unauthorized" }, \
165 { 402, "Payment Required" }, \
166 { 403, "Forbidden" }, \
167 { 404, "Not Found" }, \
168 { 405, "Method Not Allowed" }, \
169 { 406, "Not Acceptable" }, \
170 { 407, "Proxy Authentication Required" }, \
171 { 408, "Request Timeout" }, \
172 { 409, "Conflict" }, \
173 { 410, "Gone" }, \
174 { 411, "Length Required" }, \
175 { 412, "Precondition Failed" }, \
176 { 413, "Payload Too Large" }, \
177 { 414, "URI Too Long" }, \
178 { 415, "Unsupported Media Type" }, \
179 { 416, "Range Not Satisfiable" }, \
180 { 417, "Expectation Failed" }, \
181 { 418, "I'm a teapot" }, \
182 /* 419-421 unassigned */ \
183 { 420, "Enhance Your Calm" }, \
184 { 422, "Unprocessable Entity" }, \
185 { 423, "Locked" }, \
186 { 424, "Failed Dependency" }, \
187 /* 425 unassigned */ \
188 { 426, "Upgrade Required" }, \
189 /* 427 unassigned */ \
190 { 428, "Precondition Required" }, \
191 { 429, "Too Many Requests" }, \
192 /* 430 unassigned */ \
193 { 431, "Request Header Fields Too Large" }, \
194 /* 432-450 unassigned */ \
195 { 451, "Unavailable For Legal Reasons" }, \
196 /* 452-499 unassigned */ \
197 { 500, "Internal Server Error" }, \
198 { 501, "Not Implemented" }, \
199 { 502, "Bad Gateway" }, \
200 { 503, "Service Unavailable" }, \
201 { 504, "Gateway Timeout" }, \
202 { 505, "HTTP Version Not Supported" }, \
203 { 506, "Variant Also Negotiates" }, \
204 { 507, "Insufficient Storage" }, \
205 { 508, "Loop Detected" }, \
206 /* 509 unassigned */ \
207 { 510, "Not Extended" }, \
208 { 511, "Network Authentication Required" }, \
209 /* 512-599 unassigned */ \
210 { 0, NULL } \
213 struct http_mediatype {
214 char *media_name;
215 char *media_type;
216 char *media_subtype;
217 };
218 /*
219 * Some default media types based on (2014-08-04 version):
220 * https://www.iana.org/assignments/media-types/media-types.xhtml
221 */
222 #define MEDIA_TYPES { \
223 { "css", "text", "css" }, \
224 { "html", "text", "html" }, \
225 { "txt", "text", "plain" }, \
226 { "gif", "image", "gif" }, \
227 { "jpeg", "image", "jpeg" }, \
228 { "jpg", "image", "jpeg" }, \
229 { "png", "image", "png" }, \
230 { "svg", "image", "svg+xml" }, \
231 { "js", "application", "javascript" }, \
232 { NULL } \
235 /* Used during runtime */
236 struct http_descriptor {
237 struct kv http_pathquery;
238 struct kv http_matchquery;
239 #define http_path http_pathquery.kv_key
240 #define http_query http_pathquery.kv_value
241 #define http_rescode http_pathquery.kv_key
242 #define http_resmesg http_pathquery.kv_value
243 #define query_key http_matchquery.kv_key
244 #define query_val http_matchquery.kv_value
246 char *http_host;
247 enum httpmethod http_method;
248 int http_chunked;
249 struct kv *http_cl;
250 char *http_version;
251 unsigned int http_status;
253 /* Rewritten path remains NULL if not used */
254 char *http_path_alias;
256 /* A tree of headers and attached lists for repeated headers. */
257 struct kv *http_lastheader;
258 struct kvtree http_headers;
259 };
261 struct http_method_node {
262 enum httpmethod hmn_method;
263 SIMPLEQ_ENTRY(http_method_node) hmn_entry;
264 };
266 struct http_session {
267 SIMPLEQ_HEAD(, http_method_node) hs_methods;
268 };
270 #endif /* HTTP_H */