[core] config opt to intercept dynamic handler err (fixes #974)
[lighttpd.git] / src / base.h
blobe4982bca7526660eba2e05b133a93b73732040d3
1 #ifndef _BASE_H_
2 #define _BASE_H_
3 #include "first.h"
5 #include "settings.h"
7 #include <sys/types.h>
8 #include <sys/time.h>
9 #include <sys/stat.h>
11 #include <limits.h>
13 #ifdef HAVE_STDINT_H
14 # include <stdint.h>
15 #endif
17 #ifdef HAVE_INTTYPES_H
18 # include <inttypes.h>
19 #endif
21 #include "buffer.h"
22 #include "array.h"
23 #include "chunk.h"
24 #include "keyvalue.h"
25 #include "fdevent.h"
26 #include "sys-socket.h"
27 #include "splaytree.h"
28 #include "etag.h"
30 #ifdef HAVE_FAM_H
31 # include <fam.h>
32 #endif
34 #ifndef O_BINARY
35 # define O_BINARY 0
36 #endif
38 #ifndef O_LARGEFILE
39 # define O_LARGEFILE 0
40 #endif
42 #ifndef SIZE_MAX
43 # ifdef SIZE_T_MAX
44 # define SIZE_MAX SIZE_T_MAX
45 # else
46 # define SIZE_MAX ((size_t)~0)
47 # endif
48 #endif
50 #ifndef SSIZE_MAX
51 # define SSIZE_MAX ((size_t)~0 >> 1)
52 #endif
54 #ifdef __APPLE__
55 #include <crt_externs.h>
56 #define environ (* _NSGetEnviron())
57 #else
58 extern char **environ;
59 #endif
61 /* for solaris 2.5 and NetBSD 1.3.x */
62 #ifndef HAVE_SOCKLEN_T
63 typedef int socklen_t;
64 #endif
66 /* solaris and NetBSD 1.3.x again */
67 #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t))
68 # define uint32_t u_int32_t
69 #endif
72 #ifndef SHUT_WR
73 # define SHUT_WR 1
74 #endif
76 typedef enum { T_CONFIG_UNSET,
77 T_CONFIG_STRING,
78 T_CONFIG_SHORT,
79 T_CONFIG_INT,
80 T_CONFIG_BOOLEAN,
81 T_CONFIG_ARRAY,
82 T_CONFIG_LOCAL,
83 T_CONFIG_DEPRECATED,
84 T_CONFIG_UNSUPPORTED
85 } config_values_type_t;
87 typedef enum { T_CONFIG_SCOPE_UNSET,
88 T_CONFIG_SCOPE_SERVER,
89 T_CONFIG_SCOPE_CONNECTION
90 } config_scope_type_t;
92 typedef struct {
93 const char *key;
94 void *destination;
96 config_values_type_t type;
97 config_scope_type_t scope;
98 } config_values_t;
100 typedef enum { DIRECT, EXTERNAL } connection_type;
102 typedef struct {
103 char *key;
104 connection_type type;
105 char *value;
106 } request_handler;
108 typedef struct {
109 char *key;
110 char *host;
111 unsigned short port;
112 int used;
113 short factor;
114 } fcgi_connections;
117 typedef union {
118 #ifdef HAVE_IPV6
119 struct sockaddr_in6 ipv6;
120 #endif
121 struct sockaddr_in ipv4;
122 #ifdef HAVE_SYS_UN_H
123 struct sockaddr_un un;
124 #endif
125 struct sockaddr plain;
126 } sock_addr;
128 /* fcgi_response_header contains ... */
129 #define HTTP_STATUS BV(0)
130 #define HTTP_CONNECTION BV(1)
131 #define HTTP_CONTENT_LENGTH BV(2)
132 #define HTTP_DATE BV(3)
133 #define HTTP_LOCATION BV(4)
134 #define HTTP_TRANSFER_ENCODING BV(5)
136 typedef struct {
137 /** HEADER */
138 /* the request-line */
139 buffer *request;
140 buffer *uri;
142 buffer *orig_uri;
144 http_method_t http_method;
145 http_version_t http_version;
147 buffer *request_line;
149 /* strings to the header */
150 buffer *http_host; /* not alloced */
151 const char *http_range;
152 const char *http_content_type;
153 const char *http_if_modified_since;
154 const char *http_if_none_match;
156 array *headers;
158 /* CONTENT */
159 off_t content_length; /* returned by strtoll() */
160 off_t te_chunked;
162 /* internal representation */
163 int accept_encoding;
165 /* internal */
166 buffer *pathinfo;
167 } request;
169 typedef struct {
170 off_t content_length;
171 int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */
173 array *headers;
175 enum {
176 HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED
177 } transfer_encoding;
178 } response;
180 typedef struct {
181 buffer *scheme; /* scheme without colon or slashes ( "http" or "https" ) */
183 /* authority with optional portnumber ("site.name" or "site.name:8080" ) NOTE: without "username:password@" */
184 buffer *authority;
186 /* path including leading slash ("/" or "/index.html") - urldecoded, and sanitized ( buffer_path_simplify() && buffer_urldecode_path() ) */
187 buffer *path;
188 buffer *path_raw; /* raw path, as sent from client. no urldecoding or path simplifying */
189 buffer *query; /* querystring ( everything after "?", ie: in "/index.php?foo=1", query is "foo=1" ) */
190 } request_uri;
192 typedef struct {
193 buffer *path;
194 buffer *basedir; /* path = "(basedir)(.*)" */
196 buffer *doc_root; /* path = doc_root + rel_path */
197 buffer *rel_path;
199 buffer *etag;
200 } physical;
202 typedef struct {
203 buffer *name;
204 buffer *etag;
206 struct stat st;
208 time_t stat_ts;
210 #ifdef HAVE_LSTAT
211 char is_symlink;
212 #endif
214 #ifdef HAVE_FAM_H
215 int dir_version;
216 #endif
218 buffer *content_type;
219 } stat_cache_entry;
221 typedef struct {
222 splay_tree *files; /* the nodes of the tree are stat_cache_entry's */
224 buffer *dir_name; /* for building the dirname from the filename */
225 #ifdef HAVE_FAM_H
226 splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */
228 FAMConnection fam;
229 int fam_fcce_ndx;
230 #endif
231 buffer *hash_key; /* temp-store for the hash-key */
232 } stat_cache;
234 typedef struct {
235 array *mimetypes;
237 /* virtual-servers */
238 buffer *document_root;
239 buffer *server_name;
240 buffer *error_handler;
241 buffer *error_handler_404;
242 buffer *server_tag;
243 buffer *dirlist_encoding;
244 buffer *errorfile_prefix;
246 unsigned short high_precision_timestamps;
247 unsigned short max_keep_alive_requests;
248 unsigned short max_keep_alive_idle;
249 unsigned short max_read_idle;
250 unsigned short max_write_idle;
251 unsigned short use_xattr;
252 unsigned short follow_symlink;
253 unsigned short range_requests;
254 unsigned short stream_request_body;
255 unsigned short stream_response_body;
256 unsigned short error_intercept;
258 /* debug */
260 unsigned short log_file_not_found;
261 unsigned short log_request_header;
262 unsigned short log_request_handling;
263 unsigned short log_response_header;
264 unsigned short log_condition_handling;
265 unsigned short log_timeouts;
268 /* server wide */
269 unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */
270 unsigned short defer_accept;
271 unsigned short ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
272 unsigned short allow_http11;
273 unsigned short etag_use_inode;
274 unsigned short etag_use_mtime;
275 unsigned short etag_use_size;
276 unsigned short force_lowercase_filenames; /* if the FS is case-insensitive, force all files to lower-case */
277 unsigned int http_parseopts;
278 unsigned int max_request_size;
279 int listen_backlog;
281 unsigned short kbytes_per_second; /* connection kb/s limit */
283 /* configside */
284 unsigned short global_kbytes_per_second; /* */
286 off_t global_bytes_per_second_cnt;
287 /* server-wide traffic-shaper
289 * each context has the counter which is inited once
290 * a second by the global_kbytes_per_second config-var
292 * as soon as global_kbytes_per_second gets below 0
293 * the connected conns are "offline" a little bit
295 * the problem:
296 * we somehow have to loose our "we are writable" signal
297 * on the way.
300 off_t *global_bytes_per_second_cnt_ptr; /* */
302 #if defined(__FreeBSD__) || defined(__NetBSD__) \
303 || defined(__OpenBSD__) || defined(__DragonFly__)
304 buffer *bsd_accept_filter;
305 #endif
307 } specific_config;
309 /* the order of the items should be the same as they are processed
310 * read before write as we use this later */
311 typedef enum {
312 CON_STATE_CONNECT,
313 CON_STATE_REQUEST_START,
314 CON_STATE_READ,
315 CON_STATE_REQUEST_END,
316 CON_STATE_READ_POST,
317 CON_STATE_HANDLE_REQUEST,
318 CON_STATE_RESPONSE_START,
319 CON_STATE_WRITE,
320 CON_STATE_RESPONSE_END,
321 CON_STATE_ERROR,
322 CON_STATE_CLOSE
323 } connection_state_t;
325 typedef enum {
326 /* condition not active at the moment because itself or some
327 * pre-condition depends on data not available yet
329 COND_RESULT_UNSET,
331 /* special "unset" for branches not selected due to pre-conditions
332 * not met (but pre-conditions are not "unset" anymore)
334 COND_RESULT_SKIP,
336 /* actually evaluated the condition itself */
337 COND_RESULT_FALSE, /* not active */
338 COND_RESULT_TRUE, /* active */
339 } cond_result_t;
341 typedef struct {
342 /* current result (with preconditions) */
343 cond_result_t result;
344 /* result without preconditions (must never be "skip") */
345 cond_result_t local_result;
346 int patterncount;
347 int matches[3 * 10];
348 buffer *comp_value; /* just a pointer */
349 } cond_cache_t;
351 typedef struct connection {
352 connection_state_t state;
354 /* timestamps */
355 time_t read_idle_ts;
356 time_t close_timeout_ts;
357 time_t write_request_ts;
359 time_t connection_start;
360 time_t request_start;
361 struct timespec request_start_hp;
363 size_t request_count; /* number of requests handled in this connection */
364 size_t loops_per_request; /* to catch endless loops in a single request
366 * used by mod_rewrite, mod_fastcgi, ... and others
367 * this is self-protection
370 int fd; /* the FD for this connection */
371 int fde_ndx; /* index for the fdevent-handler */
372 int ndx; /* reverse mapping to server->connection[ndx] */
374 /* fd states */
375 int is_readable;
376 int is_writable;
378 int keep_alive; /* only request.c can enable it, all other just disable */
379 int keep_alive_idle; /* remember max_keep_alive_idle from config */
381 int file_started;
382 int file_finished;
384 chunkqueue *write_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */
385 chunkqueue *read_queue; /* a small queue for low-level read ( HTTP request ) [ mem ] */
386 chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/
388 int traffic_limit_reached;
390 off_t bytes_written; /* used by mod_accesslog, mod_rrd */
391 off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */
392 off_t bytes_read; /* used by mod_accesslog, mod_rrd */
393 off_t bytes_header;
395 int http_status;
397 sock_addr dst_addr;
398 buffer *dst_addr_buf;
400 /* request */
401 buffer *parse_request;
402 unsigned int parsed_response; /* bitfield which contains the important header-fields of the parsed response header */
404 request request;
405 request_uri uri;
406 physical physical;
407 response response;
409 size_t header_len;
411 array *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */
413 /* response */
414 int got_response;
416 int in_joblist;
418 connection_type mode;
420 void **plugin_ctx; /* plugin connection specific config */
422 specific_config conf; /* global connection specific config */
423 cond_cache_t *cond_cache;
425 buffer *server_name;
427 /* error-handler */
428 int error_handler_saved_status;
429 http_method_t error_handler_saved_method;
431 struct server_socket *srv_socket; /* reference to the server-socket */
432 int (* network_write)(struct server *srv, struct connection *con, chunkqueue *cq, off_t max_bytes);
433 int (* network_read)(struct server *srv, struct connection *con, chunkqueue *cq, off_t max_bytes);
435 /* etag handling */
436 etag_flags_t etag_flags;
438 int conditional_is_valid[COMP_LAST_ELEMENT];
439 } connection;
441 typedef struct {
442 connection **ptr;
443 size_t size;
444 size_t used;
445 } connections;
448 #ifdef HAVE_IPV6
449 typedef struct {
450 int family;
451 union {
452 struct in6_addr ipv6;
453 struct in_addr ipv4;
454 } addr;
455 char b2[INET6_ADDRSTRLEN + 1];
456 time_t ts;
457 } inet_ntop_cache_type;
458 #endif
461 typedef struct {
462 buffer *uri;
463 time_t mtime;
464 int http_status;
465 } realpath_cache_type;
467 typedef struct {
468 time_t mtime; /* the key */
469 buffer *str; /* a buffer for the string represenation */
470 } mtime_cache_type;
472 typedef struct {
473 void *ptr;
474 size_t used;
475 size_t size;
476 } buffer_plugin;
478 typedef struct {
479 unsigned short port;
480 buffer *bindhost;
482 buffer *errorlog_file;
483 unsigned short errorlog_use_syslog;
484 buffer *breakagelog_file;
486 unsigned short dont_daemonize;
487 unsigned short preflight_check;
488 buffer *changeroot;
489 buffer *username;
490 buffer *groupname;
492 buffer *pid_file;
494 buffer *event_handler;
496 buffer *modules_dir;
497 buffer *network_backend;
498 array *modules;
499 array *upload_tempdirs;
500 unsigned int upload_temp_file_size;
501 unsigned int max_request_field_size;
503 unsigned short max_worker;
504 unsigned short max_fds;
505 unsigned short max_conns;
507 unsigned short log_request_header_on_error;
508 unsigned short log_state_handling;
510 enum { STAT_CACHE_ENGINE_UNSET,
511 STAT_CACHE_ENGINE_NONE,
512 STAT_CACHE_ENGINE_SIMPLE
513 #ifdef HAVE_FAM_H
514 , STAT_CACHE_ENGINE_FAM
515 #endif
516 } stat_cache_engine;
517 unsigned short enable_cores;
518 unsigned short reject_expect_100_with_417;
519 buffer *xattr_name;
521 unsigned short http_header_strict;
522 unsigned short http_host_strict;
523 unsigned short http_host_normalize;
524 unsigned short high_precision_timestamps;
525 time_t loadts;
526 double loadavg[3];
527 } server_config;
529 typedef struct server_socket {
530 sock_addr addr;
531 int fd;
532 int fde_ndx;
534 unsigned short is_ssl;
535 unsigned short sidx;
537 buffer *srv_token;
538 } server_socket;
540 typedef struct {
541 server_socket **ptr;
543 size_t size;
544 size_t used;
545 } server_socket_array;
547 typedef struct server {
548 server_socket_array srv_sockets;
550 /* the errorlog */
551 int errorlog_fd;
552 enum { ERRORLOG_FILE, ERRORLOG_FD, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode;
553 buffer *errorlog_buf;
555 fdevents *ev, *ev_ins;
557 buffer_plugin plugins;
558 void *plugin_slots;
560 /* counters */
561 int con_opened;
562 int con_read;
563 int con_written;
564 int con_closed;
566 int max_fds; /* max possible fds */
567 int cur_fds; /* currently used fds */
568 int want_fds; /* waiting fds */
569 int sockets_disabled;
571 size_t max_conns;
573 /* buffers */
574 buffer *parse_full_path;
575 buffer *response_header;
576 buffer *response_range;
577 buffer *tmp_buf;
579 buffer *tmp_chunk_len;
581 buffer *empty_string; /* is necessary for cond_match */
583 buffer *cond_check_buf;
585 /* caches */
586 #ifdef HAVE_IPV6
587 inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX];
588 #endif
589 mtime_cache_type mtime_cache[FILE_CACHE_MAX];
591 array *split_vals;
593 /* Timestamps */
594 time_t cur_ts;
595 time_t last_generated_date_ts;
596 time_t last_generated_debug_ts;
597 time_t startup_ts;
599 buffer *ts_debug_str;
600 buffer *ts_date_str;
602 /* config-file */
603 array *config_touched;
605 array *config_context;
606 specific_config **config_storage;
608 server_config srvconf;
610 short int config_deprecated;
611 short int config_unsupported;
613 connections *conns;
614 connections *joblist;
615 connections *fdwaitqueue;
617 stat_cache *stat_cache;
620 * The status array can carry all the status information you want
621 * the key to the array is <module-prefix>.<name>
622 * and the values are counters
624 * example:
625 * fastcgi.backends = 10
626 * fastcgi.active-backends = 6
627 * fastcgi.backend.<key>.load = 24
628 * fastcgi.backend.<key>....
630 * fastcgi.backend.<key>.disconnects = ...
632 array *status;
634 fdevent_handler_t event_handler;
636 int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes);
637 handler_t (* request_env)(struct server *srv, connection *con);
639 uid_t uid;
640 gid_t gid;
641 } server;
644 #endif