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