1 /* $NetBSD: bozohttpd.h,v 1.73 2022/09/12 10:30:39 martin 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 char *bindport; /* bind port; default "http" */ 113 char *bindaddress; /* address for binding - INADDR_ANY */ 114 int debug; /* debugging level */ 115 char *virthostname; /* my name */ 116 const char *server_software;/* our brand :-) */ 117 const char *index_html; /* our home page */ 118 const char *public_html; /* ~user/public_html page */ 119 int enable_users; /* enable public_html */ 120 int enable_cgi_users; /* use the cgi handler */ 121 int *sock; /* bound sockets */ 122 int nsock; /* number of above */ 123 struct pollfd *fds; /* current poll fd set */ 124 int request_times; /* # times a request was processed */ 125 int dir_indexing; /* handle directories */ 126 const char *dir_readme; /* include README footer in indexes */ 127 int hide_dots; /* hide .* */ 128 int process_cgi; /* use the cgi handler */ 129 char *cgibin; /* cgi-bin directory */ 130 unsigned ssl_timeout; /* ssl timeout */ 131 unsigned initial_timeout;/* first line timeout */ 132 unsigned header_timeout; /* header lines timeout */ 133 unsigned request_timeout;/* total session timeout */ 134 char *ssl_min_proto; /* minimum ssl protocol level */ 135 #ifndef NO_LUA_SUPPORT 136 int process_lua; /* use the Lua handler */ 137 SIMPLEQ_HEAD(, lua_state_map) lua_states; 138 #endif 139 void *sslinfo; /* pointer to ssl struct */ 140 int dynamic_content_map_size;/* size of dyn cont map */ 141 bozo_content_map_t *dynamic_content_map;/* dynamic content map */ 142 size_t mmapsz; /* size of region to mmap */ 143 char *getln_buffer; /* space for getln buffer */ 144 ssize_t getln_buflen; /* length of allocated space */ 145 char *errorbuf; /* no dynamic allocation allowed */ 146 bozo_consts_t consts; /* various constants */ 147 } bozohttpd_t; 148 149 /* bozo_httpreq_t */ 150 typedef struct bozo_httpreq_t { 151 bozohttpd_t *hr_httpd; 152 int hr_method; 153 #define HTTP_GET 0x01 154 #define HTTP_POST 0x02 155 #define HTTP_HEAD 0x03 156 #define HTTP_OPTIONS 0x04 /* not supported */ 157 #define HTTP_PUT 0x05 /* not supported */ 158 #define HTTP_DELETE 0x06 /* not supported */ 159 #define HTTP_TRACE 0x07 /* not supported */ 160 #define HTTP_CONNECT 0x08 /* not supported */ 161 const char *hr_methodstr; 162 char *hr_virthostname; /* server name (if not identical 163 to hr_httpd->virthostname) */ 164 char *hr_file_free; /* pointer to file buffer to free() */ 165 char *hr_file; /* pointer into file buffer */ 166 char *hr_oldfile; /* if we added an index_html */ 167 char *hr_query; 168 char *hr_host; /* HTTP/1.1 Host: or virtual hostname, 169 possibly including a port number */ 170 #ifndef NO_USER_SUPPORT 171 char *hr_user; /* username if we hit userdir request */ 172 #endif /* !NO_USER_SUPPORT */ 173 const char *hr_proto; 174 const char *hr_content_type; 175 const char *hr_content_length; 176 const char *hr_allow; 177 const char *hr_referrer; 178 const char *hr_range; 179 const char *hr_if_modified_since; 180 const char *hr_accept_encoding; 181 int hr_have_range; 182 off_t hr_first_byte_pos; 183 off_t hr_last_byte_pos; 184 /*const*/ char *hr_remotehost; 185 /*const*/ char *hr_remoteaddr; 186 /*const*/ char *hr_serverport; 187 #ifdef DO_HTPASSWD 188 /*const*/ char *hr_authrealm; 189 /*const*/ char *hr_authuser; 190 /*const*/ char *hr_authpass; 191 #endif 192 struct qheaders hr_headers; 193 struct qheaders hr_replheaders; 194 unsigned hr_nheaders; 195 size_t hr_header_bytes; 196 } bozo_httpreq_t; 197 198 /* helper to access the "active" host name from a httpd/request pair */ 199 #define BOZOHOST(HTTPD,REQUEST) ((REQUEST)->hr_virthostname ? \ 200 (REQUEST)->hr_virthostname : \ 201 (HTTPD)->virthostname) 202 203 /* structure to hold string based (name, value) pairs with preferences */ 204 typedef struct bozoprefs_t { 205 size_t size; /* size of the two arrays */ 206 size_t count; /* # of entries in arrays */ 207 char **name; /* names of each entry */ 208 char **value; /* values for the name entries */ 209 } bozoprefs_t; 210 211 /* sun2 has a tiny VA range */ 212 #ifdef __mc68010__ 213 #ifndef BOZO_WRSZ 214 #define BOZO_WRSZ (16 * 1024) 215 #endif 216 #ifndef BOZO_MMAPSZ 217 #define BOZO_MMAPSZ (BOZO_WRSZ * 4) 218 #endif 219 #endif 220 221 /* by default write in upto 64KiB chunks, and mmap in upto 64MiB chunks */ 222 #ifndef BOZO_WRSZ 223 #define BOZO_WRSZ (64 * 1024) 224 #endif 225 #ifndef BOZO_MMAPSZ 226 #define BOZO_MMAPSZ (BOZO_WRSZ * 1024) 227 #endif 228 229 /* only allow this many total headers bytes */ 230 #define BOZO_HEADERS_MAX_SIZE (16 * 1024) 231 232 #define BOZO_MINBUFSIZE (4 * 1024) 233 234 /* debug flags */ 235 #define DEBUG_NORMAL 1 236 #define DEBUG_FAT 2 237 #define DEBUG_OBESE 3 238 #define DEBUG_EXPLODING 4 239 240 #define strornull(x) ((x) ? (x) : "<null>") 241 242 #if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__lint__) 243 #define BOZO_PRINTFLIKE(x,y) __attribute__((__format__(__printf__, x,y))) 244 #define BOZO_DEAD __attribute__((__noreturn__)) 245 #define BOZO_CHECKRET __attribute__((__warn_unused_result__)) 246 #else 247 #define BOZO_PRINTFLIKE(x,y) 248 #define BOZO_DEAD 249 #define BOZO_CHECKRET 250 #endif 251 252 #ifdef NO_DEBUG 253 #define debug(x) 254 #define have_debug (0) 255 #else 256 void debug__(bozohttpd_t *, int, const char *, ...) BOZO_PRINTFLIKE(3, 4); 257 #define debug(x) debug__ x 258 #define have_debug (1) 259 #endif /* NO_DEBUG */ 260 261 #define BOZO_HTTP_PORT "80" 262 #define BOZO_HTTPS_PORT "443" 263 264 /* 265 * bozohttpd special files. avoid serving these out. 266 * 267 * When you add some .bz* file, make sure to also check it in 268 * bozo_check_special_files() 269 */ 270 271 #ifndef REDIRECT_FILE 272 #define REDIRECT_FILE ".bzredirect" 273 #endif 274 #ifndef ABSREDIRECT_FILE 275 #define ABSREDIRECT_FILE ".bzabsredirect" 276 #endif 277 #ifndef REMAP_FILE 278 #define REMAP_FILE ".bzremap" 279 #endif 280 #ifndef AUTH_FILE 281 #define AUTH_FILE ".htpasswd" 282 #endif 283 284 /* be sure to always return this error up */ 285 int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *); 286 287 int bozo_check_special_files(bozo_httpreq_t *, const char *, bool) BOZO_CHECKRET; 288 char *bozo_http_date(char *, size_t); 289 void bozo_print_header(bozo_httpreq_t *, struct stat *, const char *, 290 const char *); 291 char *bozo_escape_rfc3986(bozohttpd_t *httpd, const char *url, int absolute); 292 char *bozo_escape_html(bozohttpd_t *httpd, const char *url); 293 int bozo_decode_url_percent(bozo_httpreq_t *, char *); 294 295 /* these are similar to libc functions, no underscore here */ 296 void bozowarn(bozohttpd_t *, const char *, ...) 297 BOZO_PRINTFLIKE(2, 3); 298 void bozoerr(bozohttpd_t *, int, const char *, ...) 299 BOZO_PRINTFLIKE(3, 4) 300 BOZO_DEAD; 301 void bozoasprintf(bozohttpd_t *, char **, const char *, ...) 302 BOZO_PRINTFLIKE(3, 4); 303 char *bozodgetln(bozohttpd_t *, int, ssize_t *, ssize_t (*)(bozohttpd_t *, 304 int, void *, size_t)); 305 char *bozostrnsep(char **, const char *, ssize_t *); 306 void *bozomalloc(bozohttpd_t *, size_t); 307 void *bozorealloc(bozohttpd_t *, void *, size_t); 308 char *bozostrdup(bozohttpd_t *, bozo_httpreq_t *, const char *); 309 310 #define bozo_noop do { /* nothing */ } while (/*CONSTCOND*/0) 311 312 #define have_core (1) 313 314 /* ssl-bozo.c */ 315 #ifdef NO_SSL_SUPPORT 316 #define bozo_ssl_set_opts(w, x, y) bozo_noop 317 #define bozo_ssl_set_ciphers(w, x) bozo_noop 318 #define bozo_ssl_init(x) bozo_noop 319 #define bozo_ssl_accept(x) (0) 320 #define bozo_ssl_shutdown(x) bozo_noop 321 #define bozo_ssl_destroy(x) bozo_noop 322 #define have_ssl (0) 323 #else 324 void bozo_ssl_set_opts(bozohttpd_t *, const char *, const char *); 325 void bozo_ssl_set_ciphers(bozohttpd_t *, const char *); 326 void bozo_ssl_init(bozohttpd_t *); 327 int bozo_ssl_accept(bozohttpd_t *); 328 void bozo_ssl_shutdown(bozohttpd_t *); 329 void bozo_ssl_destroy(bozohttpd_t *); 330 #define have_ssl (1) 331 #endif 332 333 334 /* auth-bozo.c */ 335 #ifdef DO_HTPASSWD 336 void bozo_auth_init(bozo_httpreq_t *); 337 int bozo_auth_check(bozo_httpreq_t *, const char *); 338 void bozo_auth_cleanup(bozo_httpreq_t *); 339 int bozo_auth_check_headers(bozo_httpreq_t *, char *, char *, ssize_t); 340 void bozo_auth_check_401(bozo_httpreq_t *, int); 341 void bozo_auth_cgi_setenv(bozo_httpreq_t *, char ***); 342 int bozo_auth_cgi_count(bozo_httpreq_t *); 343 #else 344 #define bozo_auth_init(x) bozo_noop 345 #define bozo_auth_check(x, y) (0) 346 #define bozo_auth_cleanup(x) bozo_noop 347 #define bozo_auth_check_headers(y, z, a, b) (0) 348 #define bozo_auth_check_401(x, y) bozo_noop 349 #define bozo_auth_cgi_setenv(x, y) bozo_noop 350 #define bozo_auth_cgi_count(x) (0) 351 #endif /* DO_HTPASSWD */ 352 353 354 /* cgi-bozo.c */ 355 #ifdef NO_CGIBIN_SUPPORT 356 #define bozo_cgi_setbin(h,s) bozo_noop 357 #define bozo_process_cgi(h) (0) 358 #define have_cgibin (0) 359 #else 360 void bozo_cgi_setbin(bozohttpd_t *, const char *); 361 void bozo_setenv(bozohttpd_t *, const char *, const char *, char **); 362 int bozo_process_cgi(bozo_httpreq_t *); 363 #define have_cgibin (1) 364 #endif /* NO_CGIBIN_SUPPORT */ 365 366 367 /* lua-bozo.c */ 368 #ifdef NO_LUA_SUPPORT 369 #define bozo_process_lua(h) (0) 370 #define bozo_add_lua_map(h,s,t) bozo_noop 371 #define have_lua (0) 372 #else 373 void bozo_add_lua_map(bozohttpd_t *, const char *, const char *); 374 int bozo_process_lua(bozo_httpreq_t *); 375 #define have_lua (1) 376 #endif /* NO_LUA_SUPPORT */ 377 378 379 /* daemon-bozo.c */ 380 #ifdef NO_DAEMON_MODE 381 #define bozo_daemon_init(x) bozo_noop 382 #define bozo_daemon_fork(x) (0) 383 #define bozo_daemon_closefds(x) bozo_noop 384 #define have_daemon_mode (0) 385 #else 386 void bozo_daemon_init(bozohttpd_t *); 387 int bozo_daemon_fork(bozohttpd_t *); 388 void bozo_daemon_closefds(bozohttpd_t *); 389 #define have_daemon_mode (1) 390 #endif /* NO_DAEMON_MODE */ 391 392 393 /* tilde-luzah-bozo.c */ 394 #ifdef NO_USER_SUPPORT 395 #define bozo_user_transform(x) (0) 396 #define bozo_user_free(x) /* nothing */ 397 #define have_user (0) 398 #else 399 int bozo_user_transform(bozo_httpreq_t *); 400 #define bozo_user_free(x) free(x) 401 #define have_user (1) 402 #endif /* NO_USER_SUPPORT */ 403 404 405 /* dir-index-bozo.c */ 406 #ifdef NO_DIRINDEX_SUPPORT 407 #define bozo_dir_index(a, b, c) (0) 408 #define have_dirindex (0) 409 #else 410 int bozo_dir_index(bozo_httpreq_t *, const char *, int); 411 #define have_dirindex (1) 412 #endif /* NO_DIRINDEX_SUPPORT */ 413 414 415 /* content-bozo.c */ 416 const char *bozo_content_type(bozo_httpreq_t *, const char *); 417 const char *bozo_content_encoding(bozo_httpreq_t *, const char *); 418 bozo_content_map_t *bozo_match_content_map(bozohttpd_t *, const char *, int); 419 bozo_content_map_t *bozo_get_content_map(bozohttpd_t *, const char *); 420 #ifdef NO_DYNAMIC_CONTENT 421 #define bozo_add_content_map_mime(h,s,t,u,v) bozo_noop 422 #define have_dynamic_content (0) 423 #else 424 void bozo_add_content_map_mime(bozohttpd_t *, const char *, const char *, 425 const char *, const char *); 426 #define have_dynamic_content (1) 427 #endif 428 429 /* additional cgi-bozo.c */ 430 #if have_cgibin && have_dynamic_content 431 void bozo_add_content_map_cgi(bozohttpd_t *, const char *, const char *); 432 #else 433 #define bozo_add_content_map_cgi(h,s,t) 434 #endif 435 436 /* I/O */ 437 int bozo_printf(bozohttpd_t *, const char *, ...) BOZO_PRINTFLIKE(2, 3); 438 ssize_t bozo_read(bozohttpd_t *, int, void *, size_t); 439 ssize_t bozo_write(bozohttpd_t *, int, const void *, size_t); 440 int bozo_flush(bozohttpd_t *, FILE *); 441 442 /* misc */ 443 int bozo_init_httpd(bozohttpd_t *); 444 int bozo_init_prefs(bozohttpd_t *, bozoprefs_t *); 445 int bozo_set_defaults(bozohttpd_t *, bozoprefs_t *); 446 int bozo_setup(bozohttpd_t *, bozoprefs_t *, const char *, const char *); 447 void bozo_cleanup(bozohttpd_t *, bozoprefs_t *); 448 bozo_httpreq_t *bozo_read_request(bozohttpd_t *); 449 void bozo_process_request(bozo_httpreq_t *); 450 void bozo_clean_request(bozo_httpreq_t *); 451 int bozo_set_timeout(bozohttpd_t *, bozoprefs_t *, const char *, const char *); 452 bozoheaders_t *addmerge_reqheader(bozo_httpreq_t *, const char *, 453 const char *, ssize_t); 454 bozoheaders_t *addmerge_replheader(bozo_httpreq_t *, const char *, 455 const char *, ssize_t); 456 457 /* variables */ 458 int bozo_set_pref(bozohttpd_t *, bozoprefs_t *, const char *, const char *); 459 char *bozo_get_pref(bozoprefs_t *, const char *); 460 461 int bozo_get_version(char */*buf*/, size_t /*size*/); 462 463 extern volatile sig_atomic_t bozo_timeout_hit; 464 465 #endif /* BOZOHTTPD_H_ */ 466