138451Smsmith/*	$OpenBSD: http.h,v 1.12 2021/03/24 20:59:53 benno Exp $	*/
238451Smsmith
338451Smsmith/*
438451Smsmith * Copyright (c) 2012 - 2015 Reyk Floeter <reyk@openbsd.org>
538451Smsmith *
638451Smsmith * Permission to use, copy, modify, and distribute this software for any
738451Smsmith * purpose with or without fee is hereby granted, provided that the above
838451Smsmith * copyright notice and this permission notice appear in all copies.
938451Smsmith *
1038451Smsmith * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1138451Smsmith * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1238451Smsmith * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1338451Smsmith * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1438451Smsmith * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1538451Smsmith * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1638451Smsmith * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1738451Smsmith */
1838451Smsmith
1938451Smsmith#ifndef HTTP_H
2038451Smsmith#define HTTP_H
2138451Smsmith
2238451Smsmith#include <sys/queue.h>
2338451Smsmith
2438451Smsmith#define HTTP_PORT	80
2538451Smsmith#define HTTPS_PORT	443
2638451Smsmith
2738451Smsmithenum httpmethod {
2838451Smsmith	HTTP_METHOD_NONE	= 0,
2938451Smsmith
3038451Smsmith	/* HTTP/1.1, RFC 7231 */
3138451Smsmith	HTTP_METHOD_GET,
3238451Smsmith	HTTP_METHOD_HEAD,
3338451Smsmith	HTTP_METHOD_POST,
3438451Smsmith	HTTP_METHOD_PUT,
3538451Smsmith	HTTP_METHOD_DELETE,
3638451Smsmith	HTTP_METHOD_OPTIONS,
3738451Smsmith	HTTP_METHOD_TRACE,
3838451Smsmith	HTTP_METHOD_CONNECT,
3938451Smsmith
4038451Smsmith	/* WebDAV, RFC 4918 */
4138451Smsmith	HTTP_METHOD_PROPFIND,
4284221Sdillon	HTTP_METHOD_PROPPATCH,
4384221Sdillon	HTTP_METHOD_MKCOL,
4484221Sdillon	HTTP_METHOD_COPY,
4538451Smsmith	HTTP_METHOD_MOVE,
4638451Smsmith	HTTP_METHOD_LOCK,
4738451Smsmith	HTTP_METHOD_UNLOCK,
4838451Smsmith
4938451Smsmith	/* WebDAV Versioning Extension, RFC 3253 */
5038451Smsmith	HTTP_METHOD_VERSION_CONTROL,
5138451Smsmith	HTTP_METHOD_REPORT,
5238451Smsmith	HTTP_METHOD_CHECKOUT,
5338451Smsmith	HTTP_METHOD_CHECKIN,
5438451Smsmith	HTTP_METHOD_UNCHECKOUT,
5538451Smsmith	HTTP_METHOD_MKWORKSPACE,
5638451Smsmith	HTTP_METHOD_UPDATE,
5738451Smsmith	HTTP_METHOD_LABEL,
5838451Smsmith	HTTP_METHOD_MERGE,
5938451Smsmith	HTTP_METHOD_BASELINE_CONTROL,
6038451Smsmith	HTTP_METHOD_MKACTIVITY,
6138451Smsmith
6238451Smsmith	/* WebDAV Ordered Collections, RFC 3648 */
6338451Smsmith	HTTP_METHOD_ORDERPATCH,
6438451Smsmith
6538451Smsmith	/* WebDAV Access Control, RFC 3744 */
6638451Smsmith	HTTP_METHOD_ACL,
6738451Smsmith
6838451Smsmith	/* WebDAV Redirect Reference Resources, RFC 4437 */
6938451Smsmith	HTTP_METHOD_MKREDIRECTREF,
7038451Smsmith	HTTP_METHOD_UPDATEREDIRECTREF,
7138451Smsmith
7238451Smsmith	/* WebDAV Search, RFC 5323 */
7338451Smsmith	HTTP_METHOD_SEARCH,
7438451Smsmith
7538451Smsmith	/* PATCH, RFC 5789 */
7638451Smsmith	HTTP_METHOD_PATCH,
7738451Smsmith
7838451Smsmith	/* Server response (internal value) */
7938451Smsmith	HTTP_METHOD_RESPONSE
8038451Smsmith};
8138451Smsmith
8238451Smsmithstruct http_method {
8338451Smsmith	enum httpmethod		 method_id;
8438451Smsmith	const char		*method_name;
8538451Smsmith};
8664527Sps#define HTTP_METHODS		{			\
8738451Smsmith	{ HTTP_METHOD_GET,		"GET" },	\
8864527Sps	{ HTTP_METHOD_HEAD,		"HEAD" },	\
8938451Smsmith	{ HTTP_METHOD_POST,		"POST" },	\
9038451Smsmith	{ HTTP_METHOD_PUT,		"PUT" },	\
9138451Smsmith	{ HTTP_METHOD_DELETE,		"DELETE" },	\
9238451Smsmith	{ HTTP_METHOD_OPTIONS,		"OPTIONS" },	\
9338451Smsmith	{ HTTP_METHOD_TRACE,		"TRACE" },	\
9438451Smsmith	{ HTTP_METHOD_CONNECT,		"CONNECT" },	\
9538451Smsmith	{ HTTP_METHOD_PROPFIND,		"PROPFIND" },	\
9638451Smsmith	{ HTTP_METHOD_PROPPATCH,	"PROPPATCH" },	\
9738451Smsmith	{ HTTP_METHOD_MKCOL,		"MKCOL" },	\
9838451Smsmith	{ HTTP_METHOD_COPY,		"COPY" },	\
9938451Smsmith	{ HTTP_METHOD_MOVE,		"MOVE" },	\
10038451Smsmith	{ HTTP_METHOD_LOCK,		"LOCK" },	\
10138451Smsmith	{ HTTP_METHOD_UNLOCK,		"UNLOCK" },	\
10238451Smsmith	{ HTTP_METHOD_VERSION_CONTROL,	"VERSION-CONTROL" }, \
10338451Smsmith	{ HTTP_METHOD_REPORT,		"REPORT" },	\
10438451Smsmith	{ HTTP_METHOD_CHECKOUT,		"CHECKOUT" },	\
10538451Smsmith	{ HTTP_METHOD_CHECKIN,		"CHECKIN" },	\
10638451Smsmith	{ HTTP_METHOD_UNCHECKOUT,	"UNCHECKOUT" },	\
10738451Smsmith	{ HTTP_METHOD_MKWORKSPACE,	"MKWORKSPACE" }, \
10838451Smsmith	{ HTTP_METHOD_UPDATE,		"UPDATE" },	\
10938451Smsmith	{ HTTP_METHOD_LABEL,		"LABEL" },	\
11038451Smsmith	{ HTTP_METHOD_MERGE,		"MERGE" },	\
11138451Smsmith	{ HTTP_METHOD_BASELINE_CONTROL,	"BASELINE-CONTROL" }, \
11238451Smsmith	{ HTTP_METHOD_MKACTIVITY,	"MKACTIVITY" },	\
11338451Smsmith	{ HTTP_METHOD_ORDERPATCH,	"ORDERPATCH" },	\
11438451Smsmith	{ HTTP_METHOD_ACL,		"ACL" },	\
11538451Smsmith	{ HTTP_METHOD_MKREDIRECTREF,	"MKREDIRECTREF" }, \
11638451Smsmith	{ HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" }, \
11738451Smsmith	{ HTTP_METHOD_SEARCH,		"SEARCH" },	\
11838451Smsmith	{ HTTP_METHOD_PATCH,		"PATCH" },	\
11938451Smsmith	{ HTTP_METHOD_NONE,		NULL }		\
12038451Smsmith}
12138451Smsmith
12238451Smsmithstruct http_error {
12338451Smsmith	int			 error_code;
12438451Smsmith	const char		*error_name;
12538451Smsmith};
12638451Smsmith
12738451Smsmith/*
12838451Smsmith * HTTP status codes based on IANA assignments (2014-06-11 version):
12938451Smsmith * https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
13038451Smsmith * plus legacy (306) and non-standard (420).
13164527Sps */
13264527Sps#define HTTP_ERRORS		{			\
13364527Sps	{ 100,	"Continue" },				\
13464527Sps	{ 101,	"Switching Protocols" },		\
13564527Sps	{ 102,	"Processing" },				\
13664527Sps	/* 103-199 unassigned */			\
13764527Sps	{ 200,	"OK" },					\
13864527Sps	{ 201,	"Created" },				\
13964527Sps	{ 202,	"Accepted" },				\
14064527Sps	{ 203,	"Non-Authoritative Information" },	\
14164527Sps	{ 204,	"No Content" },				\
14264527Sps	{ 205,	"Reset Content" },			\
14364527Sps	{ 206,	"Partial Content" },			\
14438451Smsmith	{ 207,	"Multi-Status" },			\
14538451Smsmith	{ 208,	"Already Reported" },			\
14638451Smsmith	/* 209-225 unassigned */			\
14738451Smsmith	{ 226,	"IM Used" },				\
14838451Smsmith	/* 227-299 unassigned */			\
14938451Smsmith	{ 300,	"Multiple Choices" },			\
15038451Smsmith	{ 301,	"Moved Permanently" },			\
15138451Smsmith	{ 302,	"Found" },				\
15238451Smsmith	{ 303,	"See Other" },				\
15338451Smsmith	{ 304,	"Not Modified" },			\
15438451Smsmith	{ 305,	"Use Proxy" },				\
15538451Smsmith	{ 306,	"Switch Proxy" },			\
15638451Smsmith	{ 307,	"Temporary Redirect" },			\
15738451Smsmith	{ 308,	"Permanent Redirect" },			\
15838451Smsmith	/* 309-399 unassigned */			\
15938451Smsmith	{ 400,	"Bad Request" },			\
16038451Smsmith	{ 401,	"Unauthorized" },			\
16138451Smsmith	{ 402,	"Payment Required" },			\
16238451Smsmith	{ 403,	"Forbidden" },				\
16338451Smsmith	{ 404,	"Not Found" },				\
16438451Smsmith	{ 405,	"Method Not Allowed" },			\
16538451Smsmith	{ 406,	"Not Acceptable" },			\
16638451Smsmith	{ 407,	"Proxy Authentication Required" },	\
16738451Smsmith	{ 408,	"Request Timeout" },			\
16838451Smsmith	{ 409,	"Conflict" },				\
16938451Smsmith	{ 410,	"Gone" },				\
17038451Smsmith	{ 411,	"Length Required" },			\
17138451Smsmith	{ 412,	"Precondition Failed" },		\
17238451Smsmith	{ 413,	"Payload Too Large" },			\
17338451Smsmith	{ 414,	"URI Too Long" },			\
17438451Smsmith	{ 415,	"Unsupported Media Type" },		\
17538451Smsmith	{ 416,	"Range Not Satisfiable" },		\
17638451Smsmith	{ 417,	"Expectation Failed" },			\
17738451Smsmith	{ 418,	"I'm a teapot" },			\
17838451Smsmith	/* 419-421 unassigned */			\
17938451Smsmith	{ 420,	"Enhance Your Calm" },			\
18064527Sps	{ 422,	"Unprocessable Entity" },		\
18164527Sps	{ 423,	"Locked" },				\
18264527Sps	{ 424,	"Failed Dependency" },			\
18364527Sps	/* 425 unassigned */				\
18464527Sps	{ 426,	"Upgrade Required" },			\
18564527Sps	/* 427 unassigned */				\
18664527Sps	{ 428,	"Precondition Required" },		\
18738451Smsmith	{ 429,	"Too Many Requests" },			\
18838451Smsmith	/* 430 unassigned */				\
18938451Smsmith	{ 431,	"Request Header Fields Too Large" },	\
19038451Smsmith	/* 432-450 unassigned */			\
19138451Smsmith	{ 451,	"Unavailable For Legal Reasons" },	\
19238451Smsmith	/* 452-499 unassigned */			\
19338451Smsmith	{ 500,	"Internal Server Error" },		\
19438451Smsmith	{ 501,	"Not Implemented" },			\
19538451Smsmith	{ 502,	"Bad Gateway" },			\
19638451Smsmith	{ 503,	"Service Unavailable" },		\
19738451Smsmith	{ 504,	"Gateway Timeout" },			\
19838451Smsmith	{ 505,	"HTTP Version Not Supported" },		\
19938451Smsmith	{ 506,	"Variant Also Negotiates" },		\
20038451Smsmith	{ 507,	"Insufficient Storage" },		\
20138451Smsmith	{ 508,	"Loop Detected" },			\
20238451Smsmith	/* 509 unassigned */				\
20338451Smsmith	{ 510,	"Not Extended" },			\
20438451Smsmith	{ 511,	"Network Authentication Required" },	\
20538451Smsmith	/* 512-599 unassigned */			\
20666134Sps	{ 0,	NULL }					\
20738451Smsmith}
20866134Sps
20938451Smsmithstruct http_mediatype {
21038451Smsmith	char		*media_name;
21138451Smsmith	char		*media_type;
21238451Smsmith	char		*media_subtype;
21338451Smsmith};
21438451Smsmith/*
21538451Smsmith * Some default media types based on (2014-08-04 version):
21638451Smsmith * https://www.iana.org/assignments/media-types/media-types.xhtml
21738451Smsmith */
21838451Smsmith#define MEDIA_TYPES		{			\
21938451Smsmith	{ "css",	"text",		"css" },	\
22038451Smsmith	{ "html",	"text",		"html" },	\
22138451Smsmith	{ "txt",	"text",		"plain" },	\
22238451Smsmith	{ "gif",	"image",	"gif" },	\
22338451Smsmith	{ "jpeg",	"image",	"jpeg" },	\
22438451Smsmith	{ "jpg",	"image",	"jpeg" },	\
22538451Smsmith	{ "png",	"image",	"png" },	\
22638451Smsmith	{ "svg",	"image",	"svg+xml" },	\
22738451Smsmith	{ "js",		"application",	"javascript" },	\
22838451Smsmith	{ NULL }					\
22938451Smsmith}
23038451Smsmith
23138451Smsmith/* Used during runtime */
23238451Smsmithstruct http_descriptor {
23338451Smsmith	struct kv		 http_pathquery;
23438451Smsmith	struct kv		 http_matchquery;
23538451Smsmith#define http_path		 http_pathquery.kv_key
23638451Smsmith#define http_query		 http_pathquery.kv_value
23738451Smsmith#define http_rescode		 http_pathquery.kv_key
23838451Smsmith#define http_resmesg		 http_pathquery.kv_value
23938451Smsmith#define query_key		 http_matchquery.kv_key
24038451Smsmith#define query_val		 http_matchquery.kv_value
24138451Smsmith
24238451Smsmith	char			*http_host;
24338451Smsmith	enum httpmethod		 http_method;
24438451Smsmith	int			 http_chunked;
24538451Smsmith	char			*http_version;
24638451Smsmith	unsigned int		 http_status;
24738451Smsmith
24838451Smsmith	/* Rewritten path remains NULL if not used */
24938451Smsmith	char			*http_path_alias;
25038451Smsmith
25138451Smsmith	/* A tree of headers and attached lists for repeated headers. */
25238451Smsmith	struct kv		*http_lastheader;
25338451Smsmith	struct kvtree		 http_headers;
25438451Smsmith};
25538451Smsmith
25638451Smsmithstruct http_method_node {
25738451Smsmith	enum httpmethod			hmn_method;
25838451Smsmith	SIMPLEQ_ENTRY(http_method_node)	hmn_entry;
25938451Smsmith};
26038451Smsmith
26138451Smsmithstruct http_session {
26238451Smsmith	SIMPLEQ_HEAD(, http_method_node) hs_methods;
26338451Smsmith};
26438451Smsmith
26538451Smsmith#endif /* HTTP_H */
26638451Smsmith