xref: /openbsd-src/usr.sbin/httpd/httpd.h (revision efa8f74bcb87f92d7e457fb53b963083fef00c4e)
1*efa8f74bSjsg /*	$OpenBSD: httpd.h,v 1.165 2024/10/08 05:28:11 jsg Exp $	*/
2b7b6a941Sreyk 
3b7b6a941Sreyk /*
405c2c945Sreyk  * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
5b7b6a941Sreyk  * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
6b7b6a941Sreyk  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7b7b6a941Sreyk  *
8b7b6a941Sreyk  * Permission to use, copy, modify, and distribute this software for any
9b7b6a941Sreyk  * purpose with or without fee is hereby granted, provided that the above
10b7b6a941Sreyk  * copyright notice and this permission notice appear in all copies.
11b7b6a941Sreyk  *
12b7b6a941Sreyk  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13b7b6a941Sreyk  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14b7b6a941Sreyk  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15b7b6a941Sreyk  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16b7b6a941Sreyk  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17b7b6a941Sreyk  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18b7b6a941Sreyk  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19b7b6a941Sreyk  */
20b7b6a941Sreyk 
21b7b6a941Sreyk #ifndef _HTTPD_H
22b7b6a941Sreyk #define _HTTPD_H
23b7b6a941Sreyk 
2486f952e4Sreyk #include <sys/types.h>
2586f952e4Sreyk #include <sys/socket.h>
2686f952e4Sreyk #include <sys/queue.h>
27b7b6a941Sreyk #include <sys/tree.h>
2886f952e4Sreyk #include <sys/time.h>
29b7b6a941Sreyk 
3086f952e4Sreyk #include <net/if.h>
3112e5c931Sguenther #include <netinet/in.h>
3286f952e4Sreyk 
3386f952e4Sreyk #include <stdarg.h>
34b7b6a941Sreyk #include <limits.h>
3586f952e4Sreyk #include <event.h>
36b7b6a941Sreyk #include <imsg.h>
370e3bc1d9Sjsing #include <tls.h>
38ba87bb65Sreyk #include <vis.h>
39b7b6a941Sreyk 
4059355b5aSreyk #include "patterns.h"
4159355b5aSreyk 
42f75ac035Stedu #ifndef nitems
43f75ac035Stedu #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
44f75ac035Stedu #endif
45f75ac035Stedu 
46b7b6a941Sreyk #define CONF_FILE		"/etc/httpd.conf"
47b7b6a941Sreyk #define HTTPD_USER		"www"
48b7b6a941Sreyk #define HTTPD_SERVERNAME	"OpenBSD httpd"
4933cf7fc3Sreyk #define HTTPD_DOCROOT		"/htdocs"
50cbced0bdSian #define HTTPD_ERRDOCTEMPLATE	"err" /* 3-char name */
51cbced0bdSian #define HTTPD_ERRDOCROOT_MAX	(PATH_MAX - sizeof("000.html"))
5233cf7fc3Sreyk #define HTTPD_INDEX		"index.html"
53af5adad1Sreyk #define HTTPD_FCGI_SOCKET	"/run/slowcgi.sock"
54cf605f40Sreyk #define HTTPD_LOGROOT		"/logs"
55cf605f40Sreyk #define HTTPD_ACCESS_LOG	"access.log"
56cf605f40Sreyk #define HTTPD_ERROR_LOG		"error.log"
57108ab390Sflorian #define HTTPD_MAX_ALIAS_IP	16
588f5bf38cSflorian #define HTTPD_REALM_MAX		255
598f5bf38cSflorian #define HTTPD_LOCATION_MAX	255
60d24f6b1eSreyk #define HTTPD_DEFAULT_TYPE	{ "bin", "application", "octet-stream", NULL }
61de190d6bSreyk #define HTTPD_LOGVIS		VIS_NL|VIS_TAB|VIS_CSTYLE
62a760b3d3Sreyk #define HTTPD_TLS_CERT		"/etc/ssl/server.crt"
63a760b3d3Sreyk #define HTTPD_TLS_KEY		"/etc/ssl/private/server.key"
64d193c4ffSjasper #define HTTPD_TLS_CONFIG_MAX	511
650b1f3db1Sjsing #define HTTPD_TLS_CIPHERS	"compat"
66051776c0Sjsing #define HTTPD_TLS_DHE_PARAMS	"none"
6789f7e997Sjsing #define HTTPD_TLS_ECDHE_CURVES	"default"
6803cb893cSpirofti #define HTTPD_FCGI_NAME_MAX	511
6903cb893cSpirofti #define HTTPD_FCGI_VAL_MAX	511
70b7b6a941Sreyk #define FD_RESERVE		5
71b7b6a941Sreyk 
72b7b6a941Sreyk #define SERVER_MAX_CLIENTS	1024
73b7b6a941Sreyk #define SERVER_TIMEOUT		600
74da1a1214Sreyk #define SERVER_REQUESTTIMEOUT	60
75b7b6a941Sreyk #define SERVER_CACHESIZE	-1	/* use default size */
76b7b6a941Sreyk #define SERVER_NUMPROC		3
77b7b6a941Sreyk #define SERVER_MAXHEADERLENGTH	8192
78e139abd5Sreyk #define SERVER_MAXREQUESTS	100	/* max requests per connection */
794dd188b5Sreyk #define SERVER_MAXREQUESTBODY	1048576	/* 1M */
80b7b6a941Sreyk #define SERVER_BACKLOG		10
81b7b6a941Sreyk #define SERVER_OUTOF_FD_RETRIES	5
82e62aeaeeSflorian #define SERVER_MAX_PREFETCH	256
83e62aeaeeSflorian #define SERVER_MIN_PREFETCHED	32
84f5d55328Sflorian #define SERVER_HSTS_DEFAULT_AGE	31536000
85142cfc82Sreyk #define SERVER_MAX_RANGES	4
86fe006a11Sclaudio #define SERVER_DEF_TLS_LIFETIME	(2 * 3600)
87fe006a11Sclaudio #define SERVER_MIN_TLS_LIFETIME	(60)
88fe006a11Sclaudio #define SERVER_MAX_TLS_LIFETIME	(24 * 3600)
89b7b6a941Sreyk 
909b9ff8ecSreyk #define MEDIATYPE_NAMEMAX	128	/* file name extension */
919b9ff8ecSreyk #define MEDIATYPE_TYPEMAX	64	/* length of type/subtype */
929b9ff8ecSreyk 
93b7b6a941Sreyk #define CONFIG_RELOAD		0x00
949b9ff8ecSreyk #define CONFIG_MEDIA		0x01
959b9ff8ecSreyk #define CONFIG_SERVERS		0x02
96602531d9Sreyk #define CONFIG_AUTH		0x04
97b7b6a941Sreyk #define CONFIG_ALL		0xff
98b7b6a941Sreyk 
99b6a65335Sflorian #define FCGI_CONTENT_SIZE	65535
1009ea72f95Stracey #define FCGI_DEFAULT_PORT	"9000"
101b6a65335Sflorian 
1028e01c6e3Sreyk #define PROC_PARENT_SOCK_FILENO	3
1038e01c6e3Sreyk #define PROC_MAX_INSTANCES	32
1048e01c6e3Sreyk 
105b7b6a941Sreyk enum httpchunk {
106b7b6a941Sreyk 	TOREAD_UNLIMITED		= -1,
107833d1df9Sbenno 	TOREAD_HTTP_HEADER		= -2,
108833d1df9Sbenno 	TOREAD_HTTP_CHUNK_LENGTH	= -3,
109833d1df9Sbenno 	TOREAD_HTTP_CHUNK_TRAILER	= -4,
110833d1df9Sbenno 	TOREAD_HTTP_NONE		= -5,
111142cfc82Sreyk 	TOREAD_HTTP_RANGE		= TOREAD_HTTP_CHUNK_LENGTH
112b7b6a941Sreyk };
113b7b6a941Sreyk 
114ae9552a5Sreyk #if DEBUG
115b7b6a941Sreyk #define DPRINTF		log_debug
116b7b6a941Sreyk #else
117b7b6a941Sreyk #define DPRINTF(x...)	do {} while(0)
118b7b6a941Sreyk #endif
119b7b6a941Sreyk 
120b7b6a941Sreyk struct ctl_flags {
1214703e0faSreyk 	uint8_t		 cf_opts;
1224703e0faSreyk 	uint32_t	 cf_flags;
123fe006a11Sclaudio 	uint8_t		 cf_tls_sid[TLS_MAX_SESSION_ID_LENGTH];
124b7b6a941Sreyk };
125b7b6a941Sreyk 
126b7b6a941Sreyk TAILQ_HEAD(kvlist, kv);
127b7b6a941Sreyk RB_HEAD(kvtree, kv);
128b7b6a941Sreyk 
129b7b6a941Sreyk struct kv {
130b7b6a941Sreyk 	char			*kv_key;
131b7b6a941Sreyk 	char			*kv_value;
132b7b6a941Sreyk 
133b7b6a941Sreyk 	struct kvlist		 kv_children;
134b7b6a941Sreyk 	struct kv		*kv_parent;
135b7b6a941Sreyk 	TAILQ_ENTRY(kv)		 kv_entry;
136b7b6a941Sreyk 
137b7b6a941Sreyk 	RB_ENTRY(kv)		 kv_node;
138b7b6a941Sreyk };
139b7b6a941Sreyk 
140b7b6a941Sreyk struct portrange {
141b7b6a941Sreyk 	in_port_t		 val[2];
1424703e0faSreyk 	uint8_t			 op;
143b7b6a941Sreyk };
144b7b6a941Sreyk 
145b7b6a941Sreyk struct address {
146b7b6a941Sreyk 	struct sockaddr_storage	 ss;
147b7b6a941Sreyk 	int			 ipproto;
148d9bba0abSreyk 	int			 prefixlen;
149b7b6a941Sreyk 	struct portrange	 port;
150b7b6a941Sreyk 	char			 ifname[IFNAMSIZ];
151b7b6a941Sreyk 	TAILQ_ENTRY(address)	 entry;
152b7b6a941Sreyk };
153b7b6a941Sreyk TAILQ_HEAD(addresslist, address);
154b7b6a941Sreyk 
155b7b6a941Sreyk /* initially control.h */
156b7b6a941Sreyk struct control_sock {
157b7b6a941Sreyk 	const char	*cs_name;
158b7b6a941Sreyk 	struct event	 cs_ev;
159b7b6a941Sreyk 	struct event	 cs_evt;
160b7b6a941Sreyk 	int		 cs_fd;
161b7b6a941Sreyk 	int		 cs_restricted;
162b7b6a941Sreyk 	void		*cs_env;
163b7b6a941Sreyk 
164b7b6a941Sreyk 	TAILQ_ENTRY(control_sock) cs_entry;
165b7b6a941Sreyk };
166b7b6a941Sreyk TAILQ_HEAD(control_socks, control_sock);
167b7b6a941Sreyk 
168b7b6a941Sreyk struct imsgev {
169b7b6a941Sreyk 	struct imsgbuf		 ibuf;
170b7b6a941Sreyk 	void			(*handler)(int, short, void *);
171b7b6a941Sreyk 	struct event		 ev;
172b7b6a941Sreyk 	struct privsep_proc	*proc;
173b7b6a941Sreyk 	void			*data;
174b7b6a941Sreyk 	short			 events;
175b7b6a941Sreyk };
176b7b6a941Sreyk 
177b7b6a941Sreyk #define IMSG_SIZE_CHECK(imsg, p) do {				\
178b7b6a941Sreyk 	if (IMSG_DATA_SIZE(imsg) < sizeof(*p))			\
179b7b6a941Sreyk 		fatalx("bad length imsg received");		\
180b7b6a941Sreyk } while (0)
181b7b6a941Sreyk #define IMSG_DATA_SIZE(imsg)	((imsg)->hdr.len - IMSG_HEADER_SIZE)
18288ad1069Sjsing #define MAX_IMSG_DATA_SIZE	(MAX_IMSGSIZE - IMSG_HEADER_SIZE)
183b7b6a941Sreyk 
184b7b6a941Sreyk struct ctl_conn {
185b7b6a941Sreyk 	TAILQ_ENTRY(ctl_conn)	 entry;
1864703e0faSreyk 	uint8_t			 flags;
1874703e0faSreyk 	unsigned int		 waiting;
188b7b6a941Sreyk #define CTL_CONN_NOTIFY		 0x01
189b7b6a941Sreyk 	struct imsgev		 iev;
190b7b6a941Sreyk 
191b7b6a941Sreyk };
192b7b6a941Sreyk TAILQ_HEAD(ctl_connlist, ctl_conn);
193b7b6a941Sreyk 
194b7b6a941Sreyk enum imsg_type {
195b7b6a941Sreyk 	IMSG_NONE,
196b7b6a941Sreyk 	IMSG_CTL_OK,
197b7b6a941Sreyk 	IMSG_CTL_FAIL,
198b7b6a941Sreyk 	IMSG_CTL_VERBOSE,
199887f279cSrzalamena 	IMSG_CTL_PROCFD,
200b7b6a941Sreyk 	IMSG_CTL_RESET,
201b7b6a941Sreyk 	IMSG_CTL_SHUTDOWN,
202b7b6a941Sreyk 	IMSG_CTL_RELOAD,
203b7b6a941Sreyk 	IMSG_CTL_NOTIFY,
204b7b6a941Sreyk 	IMSG_CTL_END,
205b7b6a941Sreyk 	IMSG_CTL_START,
206844c3615Sreyk 	IMSG_CTL_REOPEN,
207b7b6a941Sreyk 	IMSG_CFG_SERVER,
2086f8bdc86Sjsing 	IMSG_CFG_TLS,
2099b9ff8ecSreyk 	IMSG_CFG_MEDIA,
210602531d9Sreyk 	IMSG_CFG_AUTH,
21103cb893cSpirofti 	IMSG_CFG_FCGI,
212844c3615Sreyk 	IMSG_CFG_DONE,
213844c3615Sreyk 	IMSG_LOG_ACCESS,
214cf605f40Sreyk 	IMSG_LOG_ERROR,
215fe006a11Sclaudio 	IMSG_LOG_OPEN,
216fe006a11Sclaudio 	IMSG_TLSTICKET_REKEY
217b7b6a941Sreyk };
218b7b6a941Sreyk 
219b7b6a941Sreyk enum privsep_procid {
220b7b6a941Sreyk 	PROC_ALL	= -1,
221b7b6a941Sreyk 	PROC_PARENT	= 0,
222b7b6a941Sreyk 	PROC_SERVER,
223844c3615Sreyk 	PROC_LOGGER,
224b7b6a941Sreyk 	PROC_MAX
225488a4384Sderaadt };
226488a4384Sderaadt extern enum privsep_procid privsep_process;
227b7b6a941Sreyk 
228b7b6a941Sreyk /* Attach the control socket to the following process */
229844c3615Sreyk #define PROC_CONTROL	PROC_LOGGER
230b7b6a941Sreyk 
231b7b6a941Sreyk struct privsep_pipes {
232b7b6a941Sreyk 	int				*pp_pipes[PROC_MAX];
233b7b6a941Sreyk };
234b7b6a941Sreyk 
235b7b6a941Sreyk struct privsep {
236b7b6a941Sreyk 	struct privsep_pipes		*ps_pipes[PROC_MAX];
237b7b6a941Sreyk 	struct privsep_pipes		*ps_pp;
238b7b6a941Sreyk 
239b7b6a941Sreyk 	struct imsgev			*ps_ievs[PROC_MAX];
240b7b6a941Sreyk 	const char			*ps_title[PROC_MAX];
2414703e0faSreyk 	uint8_t				 ps_what[PROC_MAX];
242b7b6a941Sreyk 
2434703e0faSreyk 	unsigned int			 ps_instances[PROC_MAX];
2444703e0faSreyk 	unsigned int			 ps_instance;
245b7b6a941Sreyk 
246b7b6a941Sreyk 	struct control_sock		 ps_csock;
247b7b6a941Sreyk 	struct control_socks		 ps_rcsocks;
248b7b6a941Sreyk 
249b7b6a941Sreyk 	/* Event and signal handlers */
250b7b6a941Sreyk 	struct event			 ps_evsigint;
251b7b6a941Sreyk 	struct event			 ps_evsigterm;
252b7b6a941Sreyk 	struct event			 ps_evsigchld;
253b7b6a941Sreyk 	struct event			 ps_evsighup;
254b7b6a941Sreyk 	struct event			 ps_evsigpipe;
255844c3615Sreyk 	struct event			 ps_evsigusr1;
256b7b6a941Sreyk 
257b7b6a941Sreyk 	int				 ps_noaction;
258b7b6a941Sreyk 	struct passwd			*ps_pw;
259b7b6a941Sreyk 	struct httpd			*ps_env;
260b7b6a941Sreyk };
261b7b6a941Sreyk 
262b7b6a941Sreyk struct privsep_proc {
263b7b6a941Sreyk 	const char		*p_title;
264b7b6a941Sreyk 	enum privsep_procid	 p_id;
265b7b6a941Sreyk 	int			(*p_cb)(int, struct privsep_proc *,
266b7b6a941Sreyk 				    struct imsg *);
2675811a22aSrzalamena 	void			(*p_init)(struct privsep *,
268b7b6a941Sreyk 				    struct privsep_proc *);
269b7b6a941Sreyk 	const char		*p_chroot;
270b7b6a941Sreyk 	struct privsep		*p_ps;
27169b8d8bcSreyk 	void			(*p_shutdown)(void);
2721b81e077Sreyk 	struct passwd		*p_pw;
273b7b6a941Sreyk };
274b7b6a941Sreyk 
275887f279cSrzalamena struct privsep_fd {
276887f279cSrzalamena 	enum privsep_procid		 pf_procid;
277887f279cSrzalamena 	unsigned int			 pf_instance;
278887f279cSrzalamena };
279887f279cSrzalamena 
28019d2af9eSflorian enum fcgistate {
28119d2af9eSflorian 	FCGI_READ_HEADER,
2826d469730Sflorian 	FCGI_READ_CONTENT,
2836d469730Sflorian 	FCGI_READ_PADDING
28419d2af9eSflorian };
28519d2af9eSflorian 
2869917324bSflorian struct fcgi_data {
2879917324bSflorian 	enum fcgistate		 state;
2889917324bSflorian 	int			 toread;
2899917324bSflorian 	int			 padding_len;
2909917324bSflorian 	int			 type;
2919917324bSflorian 	int			 chunked;
2929917324bSflorian 	int			 end;
2939917324bSflorian 	int			 status;
2949917324bSflorian 	int			 headersdone;
2955a7cb2b1Sflorian 	int			 headerssent;
2969917324bSflorian };
2979917324bSflorian 
298142cfc82Sreyk struct range {
299142cfc82Sreyk 	off_t	start;
300142cfc82Sreyk 	off_t	end;
301142cfc82Sreyk };
302142cfc82Sreyk 
303142cfc82Sreyk struct range_data {
304142cfc82Sreyk 	struct range		 range[SERVER_MAX_RANGES];
305142cfc82Sreyk 	int			 range_count;
306142cfc82Sreyk 	int			 range_index;
307142cfc82Sreyk 	off_t			 range_toread;
308142cfc82Sreyk 
309142cfc82Sreyk 	/* For the Content headers in each part */
310142cfc82Sreyk 	struct media_type	*range_media;
311142cfc82Sreyk 	size_t			 range_total;
312142cfc82Sreyk };
313142cfc82Sreyk 
314b7b6a941Sreyk struct client {
3154703e0faSreyk 	uint32_t		 clt_id;
316b7b6a941Sreyk 	pid_t			 clt_pid;
3171940bab6Sreyk 	void			*clt_srv;
3189fb8351aSreyk 	void			*clt_srv_conf;
3194703e0faSreyk 	uint32_t		 clt_srv_id;
3206af43371Sreyk 	struct sockaddr_storage	 clt_srv_ss;
32159355b5aSreyk 	struct str_match	 clt_srv_match;
322b7b6a941Sreyk 
323b7b6a941Sreyk 	int			 clt_s;
324b7b6a941Sreyk 	in_port_t		 clt_port;
325b7b6a941Sreyk 	struct sockaddr_storage	 clt_ss;
326b7b6a941Sreyk 	struct bufferevent	*clt_bev;
327b7b6a941Sreyk 	struct evbuffer		*clt_output;
328b7b6a941Sreyk 	struct event		 clt_ev;
329873b6565Sclaudio 	struct http_descriptor	*clt_descreq;
330873b6565Sclaudio 	struct http_descriptor	*clt_descresp;
331720c14e5Sreyk 	int			 clt_sndbufsiz;
332142cfc82Sreyk 	uint64_t		 clt_boundary;
333b7b6a941Sreyk 
334b7b6a941Sreyk 	int			 clt_fd;
3350e3bc1d9Sjsing 	struct tls		*clt_tls_ctx;
336151a32cfSreyk 	struct bufferevent	*clt_srvbev;
337f3e6e694Sflorian 	int			 clt_srvbev_throttled;
338b7b6a941Sreyk 
339b7b6a941Sreyk 	off_t			 clt_toread;
34012312c27Sreyk 	size_t			 clt_headerlen;
341bf6a310cSreyk 	int			 clt_headersdone;
3424703e0faSreyk 	unsigned int		 clt_persist;
34371b1c91aSreyk 	unsigned int		 clt_pipelining;
344b7b6a941Sreyk 	int			 clt_line;
345b7b6a941Sreyk 	int			 clt_done;
346ac2cdcb6Sreyk 	int			 clt_chunk;
34712312c27Sreyk 	int			 clt_inflight;
34876ed9045Smillert 	int			 clt_fcgi_count;
349142cfc82Sreyk 	struct range_data	 clt_ranges;
3509917324bSflorian 	struct fcgi_data	 clt_fcgi;
351ebfb0322Stb 	const char		*clt_fcgi_error;
352daa1b608Sflorian 	char			*clt_remote_user;
35319d2af9eSflorian 	struct evbuffer		*clt_srvevb;
354b7b6a941Sreyk 
355b7b6a941Sreyk 	struct evbuffer		*clt_log;
356b7b6a941Sreyk 	struct timeval		 clt_timeout;
357b7b6a941Sreyk 	struct timeval		 clt_tv_start;
358b7b6a941Sreyk 	struct timeval		 clt_tv_last;
359b7b6a941Sreyk 	struct event		 clt_inflightevt;
360b7b6a941Sreyk 
361b7b6a941Sreyk 	SPLAY_ENTRY(client)	 clt_nodes;
362b7b6a941Sreyk };
363b7b6a941Sreyk SPLAY_HEAD(client_tree, client);
364b7b6a941Sreyk 
365c73e9521Sreyk #define SRVFLAG_INDEX		0x00000001
366c73e9521Sreyk #define SRVFLAG_NO_INDEX	0x00000002
367c73e9521Sreyk #define SRVFLAG_AUTO_INDEX	0x00000004
368c73e9521Sreyk #define SRVFLAG_NO_AUTO_INDEX	0x00000008
369c73e9521Sreyk #define SRVFLAG_ROOT		0x00000010
370c73e9521Sreyk #define SRVFLAG_LOCATION	0x00000020
371c73e9521Sreyk #define SRVFLAG_FCGI		0x00000040
372c73e9521Sreyk #define SRVFLAG_NO_FCGI		0x00000080
373c73e9521Sreyk #define SRVFLAG_LOG		0x00000100
374c73e9521Sreyk #define SRVFLAG_NO_LOG		0x00000200
375cbced0bdSian #define SRVFLAG_ERRDOCS		0x00000400
376c73e9521Sreyk #define SRVFLAG_SYSLOG		0x00000800
377c73e9521Sreyk #define SRVFLAG_NO_SYSLOG	0x00001000
378c73e9521Sreyk #define SRVFLAG_TLS		0x00002000
379c73e9521Sreyk #define SRVFLAG_ACCESS_LOG	0x00004000
380c73e9521Sreyk #define SRVFLAG_ERROR_LOG	0x00008000
381602531d9Sreyk #define SRVFLAG_AUTH		0x00010000
382602531d9Sreyk #define SRVFLAG_NO_AUTH		0x00020000
383f8932becSreyk #define SRVFLAG_BLOCK		0x00040000
384f8932becSreyk #define SRVFLAG_NO_BLOCK	0x00080000
38559355b5aSreyk #define SRVFLAG_LOCATION_MATCH	0x00100000
38659355b5aSreyk #define SRVFLAG_SERVER_MATCH	0x00200000
387f5d55328Sflorian #define SRVFLAG_SERVER_HSTS	0x00400000
388d24f6b1eSreyk #define SRVFLAG_DEFAULT_TYPE	0x00800000
38993038d14Sreyk #define SRVFLAG_PATH_REWRITE	0x01000000
39093038d14Sreyk #define SRVFLAG_NO_PATH_REWRITE	0x02000000
3918e3d8d5aSbluhm #define SRVFLAG_GZIP_STATIC	0x04000000
392e96b74b9Sdenis #define SRVFLAG_LOCATION_FOUND	0x40000000
393e96b74b9Sdenis #define SRVFLAG_LOCATION_NOT_FOUND 0x80000000
39443d7585dSreyk 
39543d7585dSreyk #define SRVFLAG_BITS							\
396435dc7cdSreyk 	"\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX"		\
397cbced0bdSian 	"\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13ERRDOCS"	\
398e286121aSflorian 	"\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG"		\
39959355b5aSreyk 	"\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH"		\
400e96b74b9Sdenis 	"\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" \
401e96b74b9Sdenis 	"\37LOCATION_FOUND\40LOCATION_NOT_FOUND"
40243d7585dSreyk 
403eb242fe1Sreyk #define TCPFLAG_NODELAY		0x01
404eb242fe1Sreyk #define TCPFLAG_NNODELAY	0x02
405eb242fe1Sreyk #define TCPFLAG_SACK		0x04
406eb242fe1Sreyk #define TCPFLAG_NSACK		0x08
407eb242fe1Sreyk #define TCPFLAG_BUFSIZ		0x10
408eb242fe1Sreyk #define TCPFLAG_IPTTL		0x20
409eb242fe1Sreyk #define TCPFLAG_IPMINTTL	0x40
410eb242fe1Sreyk #define TCPFLAG_NSPLICE		0x80
411eb242fe1Sreyk #define TCPFLAG_DEFAULT		0x00
412eb242fe1Sreyk 
413eb242fe1Sreyk #define TCPFLAG_BITS						\
414eb242fe1Sreyk 	"\10\01NODELAY\02NO_NODELAY\03SACK\04NO_SACK"		\
415eb242fe1Sreyk 	"\05SOCKET_BUFFER_SIZE\06IP_TTL\07IP_MINTTL\10NO_SPLICE"
416eb242fe1Sreyk 
41752f7cd50Sreyk #define HSTSFLAG_SUBDOMAINS	0x01
41852f7cd50Sreyk #define HSTSFLAG_PRELOAD	0x02
41952f7cd50Sreyk #define HSTSFLAG_BITS		"\10\01SUBDOMAINS\02PRELOAD"
42052f7cd50Sreyk 
4211d0dc528Sjsing #define TLSFLAG_CA		0x01
4221d0dc528Sjsing #define TLSFLAG_CRL		0x02
4231d0dc528Sjsing #define TLSFLAG_OPTIONAL	0x04
4241d0dc528Sjsing #define TLSFLAG_BITS		"\10\01CA\02CRL\03OPTIONAL"
4251d0dc528Sjsing 
426ea62a379Sdoug enum log_format {
427af3cfad1Sdoug 	LOG_FORMAT_COMMON,
428944a3fefSreyk 	LOG_FORMAT_COMBINED,
42934ff7cffStb 	LOG_FORMAT_CONNECTION,
43034ff7cffStb 	LOG_FORMAT_FORWARDED
431ea62a379Sdoug };
432ea62a379Sdoug 
433cf605f40Sreyk struct log_file {
4348f5bf38cSflorian 	char			log_name[PATH_MAX];
435cf605f40Sreyk 	int			log_fd;
4364703e0faSreyk 	uint32_t		log_id;
437cf605f40Sreyk 	TAILQ_ENTRY(log_file)	log_entry;
438cf605f40Sreyk };
439488a4384Sderaadt extern TAILQ_HEAD(log_files, log_file) log_files;
440cf605f40Sreyk 
441d24f6b1eSreyk struct media_type {
442d24f6b1eSreyk 	char			 media_name[MEDIATYPE_NAMEMAX];
443d24f6b1eSreyk 	char			 media_type[MEDIATYPE_TYPEMAX];
444d24f6b1eSreyk 	char			 media_subtype[MEDIATYPE_TYPEMAX];
445d24f6b1eSreyk 	char			*media_encoding;
446d24f6b1eSreyk 	RB_ENTRY(media_type)	 media_entry;
447d24f6b1eSreyk };
448d24f6b1eSreyk RB_HEAD(mediatypes, media_type);
449d24f6b1eSreyk 
450602531d9Sreyk struct auth {
451602531d9Sreyk 	char			 auth_htpasswd[PATH_MAX];
4524703e0faSreyk 	uint32_t		 auth_id;
453602531d9Sreyk 	TAILQ_ENTRY(auth)	 auth_entry;
454602531d9Sreyk };
455602531d9Sreyk TAILQ_HEAD(serverauth, auth);
456602531d9Sreyk 
457fe006a11Sclaudio struct server_tls_ticket {
458fe006a11Sclaudio 	uint32_t	tt_id;
459fe006a11Sclaudio 	uint32_t	tt_keyrev;
460fe006a11Sclaudio 	unsigned char	tt_key[TLS_TICKET_KEY_SIZE];
461fe006a11Sclaudio };
462fe006a11Sclaudio 
46303cb893cSpirofti struct fastcgi_param {
46403cb893cSpirofti 	char			name[HTTPD_FCGI_NAME_MAX];
46503cb893cSpirofti 	char			value[HTTPD_FCGI_VAL_MAX];
46603cb893cSpirofti 
46703cb893cSpirofti 	TAILQ_ENTRY(fastcgi_param) entry;
46803cb893cSpirofti };
46903cb893cSpirofti TAILQ_HEAD(server_fcgiparams, fastcgi_param);
47003cb893cSpirofti 
471b7b6a941Sreyk struct server_config {
4724703e0faSreyk 	uint32_t		 id;
4734703e0faSreyk 	uint32_t		 parent_id;
474b9fc9a72Sderaadt 	char			 name[HOST_NAME_MAX+1];
4758f5bf38cSflorian 	char			 location[HTTPD_LOCATION_MAX];
476b9fc9a72Sderaadt 	char			 root[PATH_MAX];
47793038d14Sreyk 	char			 path[PATH_MAX];
47893038d14Sreyk 	char			 index[PATH_MAX];
4798f5bf38cSflorian 	char			 accesslog[PATH_MAX];
4808f5bf38cSflorian 	char			 errorlog[PATH_MAX];
481d24f6b1eSreyk 	struct media_type	 default_type;
48243d7585dSreyk 
4839ea72f95Stracey 	struct sockaddr_storage	 fastcgi_ss;
4849ea72f95Stracey 
485b7b6a941Sreyk 	in_port_t		 port;
486b7b6a941Sreyk 	struct sockaddr_storage	 ss;
487cf605f40Sreyk 	int			 prefixlen;
4887a5a4a11Sreyk 	struct timeval		 timeout;
489da1a1214Sreyk 	struct timeval		 requesttimeout;
4904703e0faSreyk 	uint32_t		 maxrequests;
4914dd188b5Sreyk 	size_t			 maxrequestbody;
492d9bba0abSreyk 
4931d0dc528Sjsing 	uint8_t			*tls_ca;
4941d0dc528Sjsing 	char			*tls_ca_file;
4951d0dc528Sjsing 	size_t			 tls_ca_len;
4964703e0faSreyk 	uint8_t			*tls_cert;
4979ed68474Sreyk 	size_t			 tls_cert_len;
498a760b3d3Sreyk 	char			*tls_cert_file;
4998f5bf38cSflorian 	char			 tls_ciphers[HTTPD_TLS_CONFIG_MAX];
5001d0dc528Sjsing 	uint8_t			*tls_crl;
5011d0dc528Sjsing 	char			*tls_crl_file;
5021d0dc528Sjsing 	size_t			 tls_crl_len;
5038f5bf38cSflorian 	char			 tls_dhe_params[HTTPD_TLS_CONFIG_MAX];
5048f5bf38cSflorian 	char			 tls_ecdhe_curves[HTTPD_TLS_CONFIG_MAX];
5051d0dc528Sjsing 	uint8_t			 tls_flags;
5064703e0faSreyk 	uint8_t			*tls_key;
5079ed68474Sreyk 	size_t			 tls_key_len;
508a760b3d3Sreyk 	char			*tls_key_file;
5094703e0faSreyk 	uint32_t		 tls_protocols;
510e80948e2Sbeck 	uint8_t			*tls_ocsp_staple;
511e80948e2Sbeck 	size_t			 tls_ocsp_staple_len;
512e80948e2Sbeck 	char			*tls_ocsp_staple_file;
513fe006a11Sclaudio 	struct server_tls_ticket tls_ticket_key;
514fe006a11Sclaudio 	int			 tls_ticket_lifetime;
51545767b45Sjsing 
5164703e0faSreyk 	uint32_t		 flags;
5174624b10aSchrisz 	int			 strip;
5184703e0faSreyk 	uint8_t			 tcpflags;
519eb242fe1Sreyk 	int			 tcpbufsiz;
520eb242fe1Sreyk 	int			 tcpbacklog;
5214703e0faSreyk 	uint8_t			 tcpipttl;
5224703e0faSreyk 	uint8_t			 tcpipminttl;
523eb242fe1Sreyk 
524ea62a379Sdoug 	enum log_format		 logformat;
525cf605f40Sreyk 	struct log_file		*logaccess;
526cf605f40Sreyk 	struct log_file		*logerror;
527ea62a379Sdoug 
5288f5bf38cSflorian 	char			 auth_realm[HTTPD_REALM_MAX];
5294703e0faSreyk 	uint32_t		 auth_id;
5301413cd80Sreyk 	const struct auth	*auth;
531602531d9Sreyk 
532f8932becSreyk 	int			 return_code;
533f8932becSreyk 	char			*return_uri;
534f8932becSreyk 	off_t			 return_uri_len;
535f8932becSreyk 
536f5d55328Sflorian 	int			 hsts_max_age;
5374703e0faSreyk 	uint8_t			 hsts_flags;
538f5d55328Sflorian 
53903cb893cSpirofti 	struct server_fcgiparams fcgiparams;
5402cf74b7fSflorian 	int			 fcgistrip;
541cbced0bdSian 	char			 errdocroot[HTTPD_ERRDOCROOT_MAX];
54203cb893cSpirofti 
543d9bba0abSreyk 	TAILQ_ENTRY(server_config) entry;
544b7b6a941Sreyk };
545d9bba0abSreyk TAILQ_HEAD(serverhosts, server_config);
546b7b6a941Sreyk 
54788ad1069Sjsing enum tls_config_type {
5481d0dc528Sjsing 	TLS_CFG_CA,
54988ad1069Sjsing 	TLS_CFG_CERT,
5501d0dc528Sjsing 	TLS_CFG_CRL,
55188ad1069Sjsing 	TLS_CFG_KEY,
55288ad1069Sjsing 	TLS_CFG_OCSP_STAPLE,
55388ad1069Sjsing };
55488ad1069Sjsing 
5556f8bdc86Sjsing struct tls_config {
5564703e0faSreyk 	uint32_t		 id;
5576f8bdc86Sjsing 
55888ad1069Sjsing 	enum tls_config_type	 tls_type;
55988ad1069Sjsing 	size_t			 tls_len;
56088ad1069Sjsing 	size_t			 tls_chunk_len;
56188ad1069Sjsing 	size_t			 tls_chunk_offset;
5626f8bdc86Sjsing };
5636f8bdc86Sjsing 
564b7b6a941Sreyk struct server {
565b7b6a941Sreyk 	TAILQ_ENTRY(server)	 srv_entry;
566b7b6a941Sreyk 	struct server_config	 srv_conf;
567d9bba0abSreyk 	struct serverhosts	 srv_hosts;
568b7b6a941Sreyk 
569b7b6a941Sreyk 	int			 srv_s;
570b7b6a941Sreyk 	struct event		 srv_ev;
571b7b6a941Sreyk 	struct event		 srv_evt;
572b7b6a941Sreyk 
5730e3bc1d9Sjsing 	struct tls		 *srv_tls_ctx;
5740e3bc1d9Sjsing 	struct tls_config	 *srv_tls_config;
5753fe67476Sreyk 
576b7b6a941Sreyk 	struct client_tree	 srv_clients;
577b7b6a941Sreyk };
578b7b6a941Sreyk TAILQ_HEAD(serverlist, server);
579b7b6a941Sreyk 
580b7b6a941Sreyk struct httpd {
5814703e0faSreyk 	uint8_t			 sc_opts;
5824703e0faSreyk 	uint32_t		 sc_flags;
583b7b6a941Sreyk 	const char		*sc_conffile;
584b7b6a941Sreyk 	struct event		 sc_ev;
5854703e0faSreyk 	uint16_t		 sc_prefork_server;
5864703e0faSreyk 	uint16_t		 sc_id;
587844c3615Sreyk 	int			 sc_paused;
588bde157a8Sjsg 	char			*sc_chroot;
589032d2b93Sbeck 	char			*sc_logdir;
590b7b6a941Sreyk 
591fe006a11Sclaudio 	uint8_t			 sc_tls_sid[TLS_MAX_SESSION_ID_LENGTH];
592fe006a11Sclaudio 
593b7b6a941Sreyk 	struct serverlist	*sc_servers;
5949b9ff8ecSreyk 	struct mediatypes	*sc_mediatypes;
595d24f6b1eSreyk 	struct media_type	 sc_default_type;
596602531d9Sreyk 	struct serverauth	*sc_auth;
597b7b6a941Sreyk 
598b7b6a941Sreyk 	struct privsep		*sc_ps;
599b7b6a941Sreyk 	int			 sc_reload;
600cbced0bdSian 
601cbced0bdSian 	int			 sc_custom_errdocs;
602cbced0bdSian 	char			 sc_errdocroot[HTTPD_ERRDOCROOT_MAX];
603b7b6a941Sreyk };
604b7b6a941Sreyk 
605b7b6a941Sreyk #define HTTPD_OPT_VERBOSE		0x01
606b7b6a941Sreyk #define HTTPD_OPT_NOACTION		0x04
607b7b6a941Sreyk 
608b7b6a941Sreyk /* control.c */
609b7b6a941Sreyk int	 control_init(struct privsep *, struct control_sock *);
610b7b6a941Sreyk int	 control_listen(struct control_sock *);
611b7b6a941Sreyk void	 control_cleanup(struct control_sock *);
612b7b6a941Sreyk void	 control_dispatch_imsg(int, short, void *);
613b607ef5aSrzalamena void	 control_imsg_forward(struct privsep *, struct imsg *);
614b7b6a941Sreyk struct ctl_conn	*
615b7b6a941Sreyk 	 control_connbyfd(int);
616b7b6a941Sreyk 
617b7b6a941Sreyk /* parse.y */
618b7b6a941Sreyk int	 parse_config(const char *, struct httpd *);
619b7b6a941Sreyk int	 load_config(const char *, struct httpd *);
620b7b6a941Sreyk int	 cmdline_symset(char *);
621b7b6a941Sreyk 
622b7b6a941Sreyk /* server.c */
6235811a22aSrzalamena void	 server(struct privsep *, struct privsep_proc *);
624d587572fSclaudio int	 server_tls_cmp(struct server *, struct server *);
6251d0dc528Sjsing int	 server_tls_load_ca(struct server *);
6261d0dc528Sjsing int	 server_tls_load_crl(struct server *);
627a760b3d3Sreyk int	 server_tls_load_keypair(struct server *);
62888f25489Sjsing int	 server_tls_load_ocsp(struct server *);
629fe006a11Sclaudio void	 server_generate_ticket_key(struct server_config *);
630b7b6a941Sreyk int	 server_privinit(struct server *);
631b4ec2d25Sreyk void	 server_purge(struct server *);
632bd1bab2fSreyk void	 serverconfig_free(struct server_config *);
633bd1bab2fSreyk void	 serverconfig_reset(struct server_config *);
634b7b6a941Sreyk int	 server_socket_af(struct sockaddr_storage *, in_port_t);
635b7b6a941Sreyk in_port_t
636b7b6a941Sreyk 	 server_socket_getport(struct sockaddr_storage *);
63722049912Sreyk int	 server_socket_connect(struct sockaddr_storage *, in_port_t,
63822049912Sreyk 	    struct server_config *);
639b7b6a941Sreyk void	 server_write(struct bufferevent *, void *);
640b7b6a941Sreyk void	 server_read(struct bufferevent *, void *);
641b7b6a941Sreyk void	 server_error(struct bufferevent *, short, void *);
642944a3fefSreyk void	 server_log(struct client *, const char *);
643cf605f40Sreyk void	 server_sendlog(struct server_config *, int, const char *, ...)
644cf605f40Sreyk 	    __attribute__((__format__ (printf, 3, 4)));
645b7b6a941Sreyk void	 server_close(struct client *, const char *);
646b7b6a941Sreyk void	 server_dump(struct client *, const void *, size_t);
647b7b6a941Sreyk int	 server_client_cmp(struct client *, struct client *);
6482e7af781Sreyk int	 server_bufferevent_printf(struct client *, const char *, ...)
6492e7af781Sreyk 	    __attribute__((__format__ (printf, 2, 3)));
650b7b6a941Sreyk int	 server_bufferevent_print(struct client *, const char *);
651b7b6a941Sreyk int	 server_bufferevent_write_buffer(struct client *,
652b7b6a941Sreyk 	    struct evbuffer *);
653b7b6a941Sreyk int	 server_bufferevent_write_chunk(struct client *,
654b7b6a941Sreyk 	    struct evbuffer *, size_t);
655b7b6a941Sreyk int	 server_bufferevent_add(struct event *, int);
656b7b6a941Sreyk int	 server_bufferevent_write(struct client *, void *, size_t);
657d9bba0abSreyk struct server *
6580bac6c35Sreyk 	 server_byaddr(struct sockaddr *, in_port_t);
659cf605f40Sreyk struct server_config *
6604703e0faSreyk 	 serverconfig_byid(uint32_t);
661cf605f40Sreyk int	 server_foreach(int (*)(struct server *,
662cf605f40Sreyk 	    struct server_config *, void *), void *);
663ceaea836Sjsing struct server *
664ceaea836Sjsing 	 server_match(struct server *, int);
665b7b6a941Sreyk 
666b7b6a941Sreyk SPLAY_PROTOTYPE(client_tree, client, clt_nodes, server_client_cmp);
667b7b6a941Sreyk 
668b7b6a941Sreyk /* server_http.c */
669b7b6a941Sreyk void	 server_http_init(struct server *);
670781985a7Srzalamena void	 server_http(void);
671b7b6a941Sreyk int	 server_httpdesc_init(struct client *);
672b7b6a941Sreyk void	 server_read_http(struct bufferevent *, void *);
6734703e0faSreyk void	 server_abort_http(struct client *, unsigned int, const char *);
6744703e0faSreyk unsigned int
6754703e0faSreyk 	 server_httpmethod_byname(const char *);
676b7b6a941Sreyk const char
6774703e0faSreyk 	*server_httpmethod_byid(unsigned int);
678b7b6a941Sreyk const char
6794703e0faSreyk 	*server_httperror_byid(unsigned int);
680b7b6a941Sreyk void	 server_read_httpcontent(struct bufferevent *, void *);
681b7b6a941Sreyk void	 server_read_httpchunks(struct bufferevent *, void *);
682142cfc82Sreyk void	 server_read_httprange(struct bufferevent *, void *);
6834aa750c1Sreyk int	 server_writeheader_http(struct client *clt, struct kv *, void *);
684d08e4976Sreyk int	 server_headers(struct client *, void *,
6854aa750c1Sreyk 	    int (*)(struct client *, struct kv *, void *), void *);
686b7b6a941Sreyk int	 server_writeresponse_http(struct client *);
687a3d8d4e4Sbenno int	 server_response_http(struct client *, unsigned int,
688a3d8d4e4Sbenno 	    struct media_type *, off_t, time_t);
689b7b6a941Sreyk void	 server_reset_http(struct client *);
690b7b6a941Sreyk void	 server_close_http(struct client *);
6915fa30660Sreyk int	 server_response(struct httpd *, struct client *);
6924624b10aSchrisz const char *
6934624b10aSchrisz 	 server_root_strip(const char *, int);
694de6550b1Sreyk struct server_config *
695de6550b1Sreyk 	 server_getlocation(struct client *, const char *);
696e96b74b9Sdenis int	 server_locationaccesstest(struct server_config *, const char *);
6976af43371Sreyk const char *
6986af43371Sreyk 	 server_http_host(struct sockaddr_storage *, char *, size_t);
69977fd0032Sreyk char	*server_http_parsehost(char *, char *, size_t, int *);
700be5ab2e6Schrisz ssize_t	 server_http_time(time_t, char *, size_t);
7014703e0faSreyk int	 server_log_http(struct client *, unsigned int, size_t);
702b7b6a941Sreyk 
703b7b6a941Sreyk /* server_file.c */
7045fa30660Sreyk int	 server_file(struct httpd *, struct client *);
705cebbf23cSreyk void	 server_file_error(struct bufferevent *, short, void *);
706b7b6a941Sreyk 
707ab07c989Sflorian /* server_fcgi.c */
708ab07c989Sflorian int	 server_fcgi(struct httpd *, struct client *);
709b6a65335Sflorian int	 fcgi_add_stdin(struct client *, struct evbuffer *);
710ab07c989Sflorian 
711b7b6a941Sreyk /* httpd.c */
712b7b6a941Sreyk void		 event_again(struct event *, int, short,
713b7b6a941Sreyk 		    void (*)(int, short, void *),
714b7b6a941Sreyk 		    struct timeval *, struct timeval *, void *);
715586dade4Sreyk int		 expand_string(char *, size_t, const char *, const char *);
716a383dca2Sreyk const char	*url_decode(char *);
71711caa597Sreyk char		*url_encode(const char *);
718c9351fd6Sreyk const char	*canonicalize_path(const char *, char *, size_t);
71941241ca0Sreyk size_t		 path_info(char *);
7207fa6cf2cSflorian char		*escape_html(const char *);
721b7b6a941Sreyk void		 socket_rlimit(int);
72257c60317Sreyk char		*evbuffer_getline(struct evbuffer *);
7234703e0faSreyk char		*get_string(uint8_t *, size_t);
7244703e0faSreyk void		*get_data(uint8_t *, size_t);
725d9bba0abSreyk int		 sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
7264703e0faSreyk struct in6_addr *prefixlen2mask6(uint8_t, uint32_t *);
7274703e0faSreyk uint32_t	 prefixlen2mask(uint8_t);
728b7b6a941Sreyk int		 accept_reserve(int, struct sockaddr *, socklen_t *, int,
729b7b6a941Sreyk 		    volatile int *);
730b7b6a941Sreyk struct kv	*kv_add(struct kvtree *, char *, char *);
7314703e0faSreyk int		 kv_set(struct kv *, char *, ...)
7324703e0faSreyk 		    __attribute__((__format__ (printf, 2, 3)));
7334703e0faSreyk int		 kv_setkey(struct kv *, char *, ...)
7344703e0faSreyk 		    __attribute__((__format__ (printf, 2, 3)));
735b7b6a941Sreyk void		 kv_delete(struct kvtree *, struct kv *);
736b7b6a941Sreyk struct kv	*kv_extend(struct kvtree *, struct kv *, char *);
737b7b6a941Sreyk void		 kv_purge(struct kvtree *);
738b7b6a941Sreyk void		 kv_free(struct kv *);
739b7b6a941Sreyk struct kv	*kv_find(struct kvtree *, struct kv *);
740b7b6a941Sreyk int		 kv_cmp(struct kv *, struct kv *);
7419b9ff8ecSreyk struct media_type
7429b9ff8ecSreyk 		*media_add(struct mediatypes *, struct media_type *);
7439b9ff8ecSreyk void		 media_delete(struct mediatypes *, struct media_type *);
7449b9ff8ecSreyk void		 media_purge(struct mediatypes *);
7459b9ff8ecSreyk struct media_type *
746d24f6b1eSreyk 		 media_find(struct mediatypes *, const char *);
747d24f6b1eSreyk struct media_type *
748d24f6b1eSreyk 		 media_find_config(struct httpd *, struct server_config *,
749d24f6b1eSreyk 		    const char *);
7509b9ff8ecSreyk int		 media_cmp(struct media_type *, struct media_type *);
751b7b6a941Sreyk RB_PROTOTYPE(kvtree, kv, kv_node, kv_cmp);
7529b9ff8ecSreyk RB_PROTOTYPE(mediatypes, media_type, media_entry, media_cmp);
753602531d9Sreyk struct auth	*auth_add(struct serverauth *, struct auth *);
7544703e0faSreyk struct auth	*auth_byid(struct serverauth *, uint32_t);
755602531d9Sreyk void		 auth_free(struct serverauth *, struct auth *);
756b7b6a941Sreyk const char	*print_host(struct sockaddr_storage *, char *, size_t);
7574703e0faSreyk const char	*printb_flags(const uint32_t, const char *);
758b7b6a941Sreyk void		 getmonotime(struct timeval *);
759b7b6a941Sreyk 
760781985a7Srzalamena extern struct httpd *httpd_env;
761781985a7Srzalamena 
76208141198Sreyk /* log.c */
7630f12961aSreyk void	log_init(int, int);
7640f12961aSreyk void	log_procinit(const char *);
765871fc12cSreyk void	log_setverbose(int);
766871fc12cSreyk int	log_getverbose(void);
76708141198Sreyk void	log_warn(const char *, ...)
76808141198Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
76908141198Sreyk void	log_warnx(const char *, ...)
77008141198Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
77108141198Sreyk void	log_info(const char *, ...)
77208141198Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
77308141198Sreyk void	log_debug(const char *, ...)
77408141198Sreyk 	    __attribute__((__format__ (printf, 1, 2)));
77508141198Sreyk void	logit(int, const char *, ...)
77608141198Sreyk 	    __attribute__((__format__ (printf, 2, 3)));
77708141198Sreyk void	vlog(int, const char *, va_list)
77808141198Sreyk 	    __attribute__((__format__ (printf, 2, 0)));
7790f12961aSreyk __dead void fatal(const char *, ...)
7800f12961aSreyk 	    __attribute__((__format__ (printf, 1, 2)));
7810f12961aSreyk __dead void fatalx(const char *, ...)
7820f12961aSreyk 	    __attribute__((__format__ (printf, 1, 2)));
78308141198Sreyk 
784b7b6a941Sreyk /* proc.c */
785887f279cSrzalamena enum privsep_procid
786887f279cSrzalamena 	    proc_getid(struct privsep_proc *, unsigned int, const char *);
78738b34180Sbluhm void	 proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
78871b294e4Sreyk 	    int, char **, enum privsep_procid);
789b7b6a941Sreyk void	 proc_kill(struct privsep *);
790887f279cSrzalamena void	 proc_connect(struct privsep *);
791b7b6a941Sreyk void	 proc_dispatch(int, short event, void *);
792887f279cSrzalamena void	 proc_run(struct privsep *, struct privsep_proc *,
7934703e0faSreyk 	    struct privsep_proc *, unsigned int,
794b7b6a941Sreyk 	    void (*)(struct privsep *, struct privsep_proc *, void *), void *);
795b7b6a941Sreyk void	 proc_range(struct privsep *, enum privsep_procid, int *, int *);
796b7b6a941Sreyk int	 proc_compose_imsg(struct privsep *, enum privsep_procid, int,
797f19e65beSreyk 	    u_int16_t, u_int32_t, int, void *, u_int16_t);
798f19e65beSreyk int	 proc_compose(struct privsep *, enum privsep_procid,
799f19e65beSreyk 	    uint16_t, void *, uint16_t);
800b7b6a941Sreyk int	 proc_composev_imsg(struct privsep *, enum privsep_procid, int,
801f19e65beSreyk 	    u_int16_t, u_int32_t, int, const struct iovec *, int);
802f19e65beSreyk int	 proc_composev(struct privsep *, enum privsep_procid,
803f19e65beSreyk 	    uint16_t, const struct iovec *, int);
804b7b6a941Sreyk int	 proc_forward_imsg(struct privsep *, struct imsg *,
805b7b6a941Sreyk 	    enum privsep_procid, int);
806b7b6a941Sreyk struct imsgbuf *
807b7b6a941Sreyk 	 proc_ibuf(struct privsep *, enum privsep_procid, int);
808b7b6a941Sreyk struct imsgev *
809b7b6a941Sreyk 	 proc_iev(struct privsep *, enum privsep_procid, int);
81093c3ddf9Sreyk int	 proc_flush_imsg(struct privsep *, enum privsep_procid, int);
811b7b6a941Sreyk void	 imsg_event_add(struct imsgev *);
8124703e0faSreyk int	 imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
8134703e0faSreyk 	    pid_t, int, void *, uint16_t);
8144703e0faSreyk int	 imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
815b7b6a941Sreyk 	    pid_t, int, const struct iovec *, int);
816b7b6a941Sreyk 
817b7b6a941Sreyk /* config.c */
818b7b6a941Sreyk int	 config_init(struct httpd *);
8194703e0faSreyk void	 config_purge(struct httpd *, unsigned int);
8204703e0faSreyk int	 config_setreset(struct httpd *, unsigned int);
821b7b6a941Sreyk int	 config_getreset(struct httpd *, struct imsg *);
822b7b6a941Sreyk int	 config_getcfg(struct httpd *, struct imsg *);
823b7b6a941Sreyk int	 config_setserver(struct httpd *, struct server *);
82488ad1069Sjsing int	 config_setserver_tls(struct httpd *, struct server *);
82503cb893cSpirofti int	 config_setserver_fcgiparams(struct httpd *, struct server *);
826b7b6a941Sreyk int	 config_getserver(struct httpd *, struct imsg *);
82788ad1069Sjsing int	 config_getserver_tls(struct httpd *, struct imsg *);
82803cb893cSpirofti int	 config_getserver_fcgiparams(struct httpd *, struct imsg *);
8299b9ff8ecSreyk int	 config_setmedia(struct httpd *, struct media_type *);
8309b9ff8ecSreyk int	 config_getmedia(struct httpd *, struct imsg *);
831602531d9Sreyk int	 config_setauth(struct httpd *, struct auth *);
832602531d9Sreyk int	 config_getauth(struct httpd *, struct imsg *);
833b7b6a941Sreyk 
834844c3615Sreyk /* logger.c */
8355811a22aSrzalamena void	 logger(struct privsep *, struct privsep_proc *);
836cf605f40Sreyk int	 logger_open_priv(struct imsg *);
837844c3615Sreyk 
838b7b6a941Sreyk #endif /* _HTTPD_H */
839