1 /* $NetBSD: bozohttpd.h,v 1.74 2026/05/03 21:40:37 mrg Exp $ */ 2 3 /* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */ 4 5 /* 6 * Copyright (c) 1997-2022 Matthew R. Green 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer and 16 * dedication in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 */ 32 #ifndef BOZOHTTPD_H_ 33 #define BOZOHTTPD_H_ 1 34 35 #include "netbsd_queue.h" 36 37 #include <stdbool.h> 38 #include <stdio.h> 39 #include <signal.h> 40 41 #include <sys/stat.h> 42 43 #ifndef NO_LUA_SUPPORT 44 #include <lua.h> 45 #endif 46 47 #ifndef NO_BLOCKLIST_SUPPORT 48 #include <blocklist.h> 49 void pfilter_notify(const int, const int); 50 #endif 51 52 /* QNX provides a lot of NetBSD things in nbutil.h */ 53 #ifdef HAVE_NBUTIL_H 54 #include <nbutil.h> 55 #endif 56 57 /* lots of "const" but gets free()'ed etc at times, sigh */ 58 59 /* headers */ 60 typedef struct bozoheaders { 61 /*const*/ char *h_header; 62 /*const*/ char *h_value; /* this gets free()'ed etc at times */ 63 SIMPLEQ_ENTRY(bozoheaders) h_next; 64 } bozoheaders_t; 65 SIMPLEQ_HEAD(qheaders, bozoheaders); 66 67 #ifndef NO_LUA_SUPPORT 68 typedef struct lua_handler { 69 const char *name; 70 int ref; 71 SIMPLEQ_ENTRY(lua_handler) h_next; 72 } lua_handler_t; 73 74 typedef struct lua_state_map { 75 const char *script; 76 const char *prefix; 77 lua_State *L; 78 SIMPLEQ_HEAD(, lua_handler) handlers; 79 SIMPLEQ_ENTRY(lua_state_map) s_next; 80 } lua_state_map_t; 81 #endif 82 83 typedef struct bozo_content_map_t { 84 const char *name; /* postfix of file */ 85 const char *type; /* matching content-type */ 86 const char *encoding; /* matching content-encoding */ 87 const char *encoding11; /* matching content-encoding (HTTP/1.1) */ 88 const char *cgihandler; /* optional CGI handler */ 89 } bozo_content_map_t; 90 91 /* this struct holds the bozo constants */ 92 typedef struct bozo_consts_t { 93 const char *http_09; /* "HTTP/0.9" */ 94 const char *http_10; /* "HTTP/1.0" */ 95 const char *http_11; /* "HTTP/1.1" */ 96 const char *text_plain; /* "text/plain" */ 97 } bozo_consts_t; 98 99 /* this structure encapsulates all the bozo flags and control vars */ 100 typedef struct bozohttpd_t { 101 char *rootdir; /* root directory */ 102 int numeric; /* avoid gethostby*() */ 103 char *virtbase; /* virtual directory base */ 104 int unknown_slash; /* unknown vhosts go to normal slashdir */ 105 int logstderr; /* log to stderr (even if not tty) */ 106 int nolog; /* do not log anything */ 107 int background; /* drop into daemon mode */ 108 int foreground; /* keep daemon mode in foreground */ 109 char *pidfile; /* path to the pid file, if any */ 110 size_t page_size; /* page size */ 111 char *slashdir; /* www slash directory */ 112 const char *defbindport; /* default "http"; ssl sets to "https" */ 113 char *bindport; /* bind port; default "http" */ 114 char *bindaddress; /* address for binding - INADDR_ANY */ 115 int debug; /* debugging level */ 116 char *virthostname; /* my name */ 117 const char *server_software;/* our brand :-) */ 118 const char *index_html; /* our home page */ 119 const char *public_html; /* ~user/public_html page */ 120 int enable_users; /* enable public_html */ 121 int enable_cgi_users; /* use the cgi handler */ 122 int *sock; /* bound sockets */ 123 int nsock; /* number of above */ 124 struct pollfd *fds; /* current poll fd set */ 125 int request_times; /* # times a request was processed */ 126 int dir_indexing; /* handle directories */ 127 const char *dir_readme; /* include README footer in indexes */ 128 int hide_dots; /* hide .* */ 129 int process_cgi; /* use the cgi handler */ 130 char *cgibin; /* cgi-bin directory */ 131 unsigned ssl_timeout; /* ssl timeout */ 132 unsigned initial_timeout;/* first line timeout */ 133 unsigned header_timeout; /* header lines timeout */ 134 unsigned request_timeout;/* total session timeout */ 135 char *ssl_min_proto; /* minimum ssl protocol level */ 136 #ifndef NO_LUA_SUPPORT 137 int process_lua; /* use the Lua handler */ 138 SIMPLEQ_HEAD(, lua_state_map) lua_states; 139 #endif 140 void *sslinfo; /* pointer to ssl struct */ 141 int dynamic_content_map_size;/* size of dyn cont map */ 142 bozo_content_map_t *dynamic_content_map;/* dynamic content map */ 143 size_t mmapsz; /* size of region to mmap */ 144 char *getln_buffer; /* space for getln buffer */ 145 ssize_t getln_buflen; /* length of allocated space */ 146 char *errorbuf; /* no dynamic allocation allowed */ 147 bozo_consts_t consts; /* various constants */ 148 } bozohttpd_t; 149 150 /* bozo_httpreq_t */ 151 typedef struct bozo_httpreq_t { 152 bozohttpd_t *hr_httpd; 153 int hr_method; 154 #define HTTP_GET 0x01 155 #define HTTP_POST 0x02 156 #define HTTP_HEAD 0x03 157 #define HTTP_OPTIONS 0x04 /* not supported */ 158 #define HTTP_PUT 0x05 /* not supported */ 159 #define HTTP_DELETE 0x06 /* not supported */ 160 #define HTTP_TRACE 0x07 /* not supported */ 161 #define HTTP_CONNECT 0x08 /* not supported */ 162 const char *hr_methodstr; 163 char *hr_virthostname; /* server name (if not identical 164 to hr_httpd->virthostname) */ 165 char *hr_file_free; /* pointer to file buffer to free() */ 166 char *hr_file; /* pointer into file buffer */ 167 char *hr_oldfile; /* if we added an index_html */ 168 char *hr_query; 169 char *hr_host; /* HTTP/1.1 Host: or virtual hostname, 170 possibly including a port number */ 171 #ifndef NO_USER_SUPPORT 172 char *hr_user; /* username if we hit userdir request */ 173 #endif /* !NO_USER_SUPPORT */ 174 const char *hr_proto; 175 const char *hr_content_type; 176 const char *hr_content_length; 177 const char *hr_allow; 178 const char *hr_referrer; 179 const char *hr_range; 180 const char *hr_if_modified_since; 181 const char *hr_accept_encoding; 182 int hr_have_range; 183 off_t hr_first_byte_pos; 184 off_t hr_last_byte_pos; 185 /*const*/ char *hr_remotehost; 186 /*const*/ char *hr_remoteaddr; 187 /*const*/ char *hr_serverport; 188 #ifdef DO_HTPASSWD 189 /*const*/ char *hr_authrealm; 190 /*const*/ char *hr_authuser; 191 /*const*/ char *hr_authpass; 192 #endif 193 struct qheaders hr_headers; 194 struct qheaders hr_replheaders; 195 unsigned hr_nheaders; 196 size_t hr_header_bytes; 197 } bozo_httpreq_t; 198 199 /* helper to access the "active" host name from a httpd/request pair */ 200 #define BOZOHOST(HTTPD,REQUEST) ((REQUEST)->hr_virthostname ? \ 201 (REQUEST)->hr_virthostname : \ 202 (HTTPD)->virthostname) 203 204 /* structure to hold string based (name, value) pairs with preferences */ 205 typedef struct bozoprefs_t { 206 size_t size; /* size of the two arrays */ 207 size_t count; /* # of entries in arrays */ 208 char **name; /* names of each entry */ 209 char **value; /* values for the name entries */ 210 } bozoprefs_t; 211 212 /* sun2 has a tiny VA range */ 213 #ifdef __mc68010__ 214 #ifndef BOZO_WRSZ 215 #define BOZO_WRSZ (16 * 1024) 216 #endif 217 #ifndef BOZO_MMAPSZ 218 #define BOZO_MMAPSZ (BOZO_WRSZ * 4) 219 #endif 220 #endif 221 222 /* by default write in upto 64KiB chunks, and mmap in upto 64MiB chunks */ 223 #ifndef BOZO_WRSZ 224 #define BOZO_WRSZ (64 * 1024) 225 #endif 226 #ifndef BOZO_MMAPSZ 227 #define BOZO_MMAPSZ (BOZO_WRSZ * 1024) 228 #endif 229 230 /* only allow this many total headers bytes */ 231 #define BOZO_HEADERS_MAX_SIZE (16 * 1024) 232 233 #define BOZO_MINBUFSIZE (4 * 1024) 234 235 /* debug flags */ 236 #define DEBUG_NORMAL 1 237 #define DEBUG_FAT 2 238 #define DEBUG_OBESE 3 239 #define DEBUG_EXPLODING 4 240 241 #define strornull(x) ((x) ? (x) : "<null>") 242 243 #if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__lint__) 244 #define BOZO_PRINTFLIKE(x,y) __attribute__((__format__(__printf__, x,y))) 245 #define BOZO_DEAD __attribute__((__noreturn__)) 246 #define BOZO_CHECKRET __attribute__((__warn_unused_result__)) 247 #else 248 #define BOZO_PRINTFLIKE(x,y) 249 #define BOZO_DEAD 250 #define BOZO_CHECKRET 251 #endif 252 253 #ifdef NO_DEBUG 254 #define debug(x) 255 #define have_debug (0) 256 #else 257 void debug__(bozohttpd_t *, int, const char *, ...) BOZO_PRINTFLIKE(3, 4); 258 #define debug(x) debug__ x 259 #define have_debug (1) 260 #endif /* NO_DEBUG */ 261 262 #define BOZO_HTTP_PORT "80" 263 #define BOZO_HTTPS_PORT "443" 264 265 /* 266 * bozohttpd special files. avoid serving these out. 267 * 268 * When you add some .bz* file, make sure to also check it in 269 * bozo_check_special_files() 270 */ 271 272 #ifndef REDIRECT_FILE 273 #define REDIRECT_FILE ".bzredirect" 274 #endif 275 #ifndef ABSREDIRECT_FILE 276 #define ABSREDIRECT_FILE ".bzabsredirect" 277 #endif 278 #ifndef REMAP_FILE 279 #define REMAP_FILE ".bzremap" 280 #endif 281 #ifndef AUTH_FILE 282 #define AUTH_FILE ".htpasswd" 283 #endif 284 285 /* be sure to always return this error up */ 286 int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *); 287 288 int bozo_check_special_files(bozo_httpreq_t *, const char *, bool) BOZO_CHECKRET; 289 char *bozo_http_date(char *, size_t); 290 void bozo_print_header(bozo_httpreq_t *, struct stat *, const char *, 291 const char *); 292 char *bozo_escape_rfc3986(bozohttpd_t *httpd, const char *url, int absolute); 293 char *bozo_escape_html(bozohttpd_t *httpd, const char *url); 294 int bozo_decode_url_percent(bozo_httpreq_t *, char *); 295 296 /* these are similar to libc functions, no underscore here */ 297 void bozowarn(bozohttpd_t *, const char *, ...) 298 BOZO_PRINTFLIKE(2, 3); 299 void bozoerr(bozohttpd_t *, int, const char *, ...) 300 BOZO_PRINTFLIKE(3, 4) 301 BOZO_DEAD; 302 void bozoasprintf(bozohttpd_t *, char **, const char *, ...) 303 BOZO_PRINTFLIKE(3, 4); 304 char *bozodgetln(bozohttpd_t *, int, ssize_t *, ssize_t (*)(bozohttpd_t *, 305 int, void *, size_t)); 306 char *bozostrnsep(char **, const char *, ssize_t *); 307 void *bozomalloc(bozohttpd_t *, size_t); 308 void *bozorealloc(bozohttpd_t *, void *, size_t); 309 char *bozostrdup(bozohttpd_t *, bozo_httpreq_t *, const char *); 310 311 #define bozo_noop do { /* nothing */ } while (/*CONSTCOND*/0) 312 313 #define have_core (1) 314 315 /* ssl-bozo.c */ 316 #ifdef NO_SSL_SUPPORT 317 #define bozo_ssl_set_opts(w, x, y) bozo_noop 318 #define bozo_ssl_set_ciphers(w, x) bozo_noop 319 #define bozo_ssl_init(x) bozo_noop 320 #define bozo_ssl_accept(x) (0) 321 #define bozo_ssl_shutdown(x) bozo_noop 322 #define bozo_ssl_destroy(x) bozo_noop 323 #define have_ssl (0) 324 #else 325 void bozo_ssl_set_opts(bozohttpd_t *, const char *, const char *); 326 void bozo_ssl_set_ciphers(bozohttpd_t *, const char *); 327 void bozo_ssl_init(bozohttpd_t *); 328 int bozo_ssl_accept(bozohttpd_t *); 329 void bozo_ssl_shutdown(bozohttpd_t *); 330 void bozo_ssl_destroy(bozohttpd_t *); 331 #define have_ssl (1) 332 #endif 333 334 335 /* auth-bozo.c */ 336 #ifdef DO_HTPASSWD 337 void bozo_auth_init(bozo_httpreq_t *); 338 int bozo_auth_check(bozo_httpreq_t *, const char *); 339 void bozo_auth_cleanup(bozo_httpreq_t *); 340 int bozo_auth_check_headers(bozo_httpreq_t *, char *, char *, ssize_t); 341 void bozo_auth_check_401(bozo_httpreq_t *, int); 342 void bozo_auth_cgi_setenv(bozo_httpreq_t *, char ***); 343 int bozo_auth_cgi_count(bozo_httpreq_t *); 344 #else 345 #define bozo_auth_init(x) bozo_noop 346 #define bozo_auth_check(x, y) (0) 347 #define bozo_auth_cleanup(x) bozo_noop 348 #define bozo_auth_check_headers(y, z, a, b) (0) 349 #define bozo_auth_check_401(x, y) bozo_noop 350 #define bozo_auth_cgi_setenv(x, y) bozo_noop 351 #define bozo_auth_cgi_count(x) (0) 352 #endif /* DO_HTPASSWD */ 353 354 355 /* cgi-bozo.c */ 356 #ifdef NO_CGIBIN_SUPPORT 357 #define bozo_cgi_setbin(h,s) bozo_noop 358 #define bozo_process_cgi(h) (0) 359 #define have_cgibin (0) 360 #else 361 void bozo_cgi_setbin(bozohttpd_t *, const char *); 362 void bozo_setenv(bozohttpd_t *, const char *, const char *, char **); 363 int bozo_process_cgi(bozo_httpreq_t *); 364 #define have_cgibin (1) 365 #endif /* NO_CGIBIN_SUPPORT */ 366 367 368 /* lua-bozo.c */ 369 #ifdef NO_LUA_SUPPORT 370 #define bozo_process_lua(h) (0) 371 #define bozo_add_lua_map(h,s,t) bozo_noop 372 #define have_lua (0) 373 #else 374 void bozo_add_lua_map(bozohttpd_t *, const char *, const char *); 375 int bozo_process_lua(bozo_httpreq_t *); 376 #define have_lua (1) 377 #endif /* NO_LUA_SUPPORT */ 378 379 380 /* daemon-bozo.c */ 381 #ifdef NO_DAEMON_MODE 382 #define bozo_daemon_init(x) bozo_noop 383 #define bozo_daemon_fork(x) (0) 384 #define bozo_daemon_closefds(x) bozo_noop 385 #define have_daemon_mode (0) 386 #else 387 void bozo_daemon_init(bozohttpd_t *); 388 int bozo_daemon_fork(bozohttpd_t *); 389 void bozo_daemon_closefds(bozohttpd_t *); 390 #define have_daemon_mode (1) 391 #endif /* NO_DAEMON_MODE */ 392 393 394 /* tilde-luzah-bozo.c */ 395 #ifdef NO_USER_SUPPORT 396 #define bozo_user_transform(x) (0) 397 #define bozo_user_free(x) /* nothing */ 398 #define have_user (0) 399 #else 400 int bozo_user_transform(bozo_httpreq_t *); 401 #define bozo_user_free(x) free(x) 402 #define have_user (1) 403 #endif /* NO_USER_SUPPORT */ 404 405 406 /* dir-index-bozo.c */ 407 #ifdef NO_DIRINDEX_SUPPORT 408 #define bozo_dir_index(a, b, c) (0) 409 #define have_dirindex (0) 410 #else 411 int bozo_dir_index(bozo_httpreq_t *, const char *, int); 412 #define have_dirindex (1) 413 #endif /* NO_DIRINDEX_SUPPORT */ 414 415 416 /* content-bozo.c */ 417 const char *bozo_content_type(bozo_httpreq_t *, const char *); 418 const char *bozo_content_encoding(bozo_httpreq_t *, const char *); 419 bozo_content_map_t *bozo_match_content_map(bozohttpd_t *, const char *, int); 420 bozo_content_map_t *bozo_get_content_map(bozohttpd_t *, const char *); 421 #ifdef NO_DYNAMIC_CONTENT 422 #define bozo_add_content_map_mime(h,s,t,u,v) bozo_noop 423 #define have_dynamic_content (0) 424 #else 425 void bozo_add_content_map_mime(bozohttpd_t *, const char *, const char *, 426 const char *, const char *); 427 #define have_dynamic_content (1) 428 #endif 429 430 /* additional cgi-bozo.c */ 431 #if have_cgibin && have_dynamic_content 432 void bozo_add_content_map_cgi(bozohttpd_t *, const char *, const char *); 433 #else 434 #define bozo_add_content_map_cgi(h,s,t) 435 #endif 436 437 /* I/O */ 438 int bozo_printf(bozohttpd_t *, const char *, ...) BOZO_PRINTFLIKE(2, 3); 439 ssize_t bozo_read(bozohttpd_t *, int, void *, size_t); 440 ssize_t bozo_write(bozohttpd_t *, int, const void *, size_t); 441 int bozo_flush(bozohttpd_t *, FILE *); 442 443 /* misc */ 444 int bozo_init_httpd(bozohttpd_t *); 445 int bozo_init_prefs(bozohttpd_t *, bozoprefs_t *); 446 int bozo_set_defaults(bozohttpd_t *, bozoprefs_t *); 447 int bozo_setup(bozohttpd_t *, bozoprefs_t *, const char *, const char *); 448 void bozo_cleanup(bozohttpd_t *, bozoprefs_t *); 449 bozo_httpreq_t *bozo_read_request(bozohttpd_t *); 450 void bozo_process_request(bozo_httpreq_t *); 451 void bozo_clean_request(bozo_httpreq_t *); 452 int bozo_set_timeout(bozohttpd_t *, bozoprefs_t *, const char *, const char *); 453 bozoheaders_t *addmerge_reqheader(bozo_httpreq_t *, const char *, 454 const char *, ssize_t); 455 bozoheaders_t *addmerge_replheader(bozo_httpreq_t *, const char *, 456 const char *, ssize_t); 457 458 /* variables */ 459 int bozo_set_pref(bozohttpd_t *, bozoprefs_t *, const char *, const char *); 460 char *bozo_get_pref(bozoprefs_t *, const char *); 461 462 int bozo_get_version(char */*buf*/, size_t /*size*/); 463 464 extern volatile sig_atomic_t bozo_timeout_hit; 465 466 #endif /* BOZOHTTPD_H_ */ 467