root/trunk/src/base.h

Revision 2245, 15.0 kB (checked in by stbuehler, 4 weeks ago)

merged from @1874: add ETag configuration (#1442)

  • Property svn:eol-style set to native
Line 
1#ifndef _BASE_H_
2#define _BASE_H_
3
4#include <sys/types.h>
5#include <sys/stat.h>
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include <limits.h>
12#ifdef HAVE_STDINT_H
13# include <stdint.h>
14#endif
15#ifdef HAVE_INTTYPES_H
16# include <inttypes.h>
17#endif
18
19#include "settings.h"
20
21#ifdef HAVE_GLIB_H
22/* include glib.h before our buffer.h and array.h to make sure their parameter-names
23 * don't clash with our type-names */
24#include <glib.h>
25#endif
26
27#include "buffer.h"
28#include "array.h"
29#include "chunk.h"
30#include "filter.h"
31#include "keyvalue.h"
32#include "settings.h"
33#include "fdevent.h"
34#include "sys-socket.h"
35#include "http_req.h"
36#include "etag.h"
37
38#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
39# define USE_OPENSSL
40# include <openssl/ssl.h>
41#endif
42
43#ifdef HAVE_SYS_INOTIFY_H
44# include <sys/inotify.h>
45#endif
46
47#ifdef USE_LINUX_AIO_SENDFILE
48# include <libaio.h>
49#endif
50
51#ifdef USE_POSIX_AIO
52# include <aio.h>
53#endif
54
55/** some compat */
56#ifndef O_BINARY
57# define O_BINARY 0
58#endif
59
60#ifndef SIZE_MAX
61# ifdef SIZE_T_MAX
62#  define SIZE_MAX SIZE_T_MAX
63# else
64#  define SIZE_MAX ((size_t)~0)
65# endif
66#endif
67
68#ifndef SSIZE_MAX
69# define SSIZE_MAX ((size_t)~0 >> 1)
70#endif
71
72#ifdef __APPLE__
73#include <crt_externs.h>
74#define environ (* _NSGetEnviron())
75#elif !defined(_WIN32)
76extern char **environ;
77#endif
78
79/* for solaris 2.5 and NetBSD 1.3.x */
80#ifndef HAVE_SOCKLEN_T
81typedef int socklen_t;
82#endif
83
84/* solaris and NetBSD 1.3.x again */
85#if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t))
86/* # define uint32_t u_int32_t */
87typedef unsigned __int32 uint32_t;
88#endif
89
90
91#ifndef SHUT_WR
92# define SHUT_WR 1
93#endif
94
95#include "settings.h"
96
97typedef enum {
98        TIME_CONNECTION_ACCEPT,
99        TIME_REQUEST_START,
100        TIME_BACKEND_CONNECT,
101
102        TIME_BACKEND_SEND_HEADER_START,
103        TIME_BACKEND_SEND_HEADER_END,
104        TIME_BACKEND_SEND_CONTENT_START,
105        TIME_BACKEND_SEND_CONTENT_END,
106
107        TIME_BACKEND_RECV_HEADER_START,
108        TIME_BACKEND_RECV_HEADER_END,
109        TIME_BACKEND_RECV_CONTENT_START,
110        TIME_BACKEND_RECV_CONTENT_END,
111
112        TIME_BACKEND_DISCONNECT,
113
114        TIME_SEND_HEADER_START,
115        TIME_SEND_HEADER_END,
116
117        TIME_SEND_CONTENT_START,
118       
119        TIME_SEND_ASYNC_READ_QUEUED, /* for async-io read */
120        TIME_SEND_ASYNC_READ_START, /* for async-io read */
121        TIME_SEND_ASYNC_READ_END, /* for async-io read */
122        TIME_SEND_ASYNC_READ_END_QUEUED, /* for async-io read */
123
124        TIME_SEND_WRITE_START,
125        TIME_SEND_WRITE_END,
126       
127        TIME_SEND_CONTENT_END,
128
129        TIME_REQUEST_END,
130        TIME_CONNECTION_CLOSE,
131
132        TIME_LAST_ELEMENT
133} connection_time_field_t;
134
135typedef enum { T_CONFIG_UNSET,
136                T_CONFIG_STRING,
137                T_CONFIG_SHORT,
138                T_CONFIG_INT,
139                T_CONFIG_BOOLEAN,
140                T_CONFIG_ARRAY,
141                T_CONFIG_LOCAL,
142                T_CONFIG_DEPRECATED,
143                T_CONFIG_UNSUPPORTED
144} config_values_type_t;
145
146typedef enum { T_CONFIG_SCOPE_UNSET,
147                T_CONFIG_SCOPE_SERVER,
148                T_CONFIG_SCOPE_CONNECTION
149} config_scope_type_t;
150
151typedef struct {
152        const char *key;
153        void *destination;
154
155        config_values_type_t type;
156        config_scope_type_t scope;
157} config_values_t;
158
159typedef enum { DIRECT, EXTERNAL } connection_type;
160
161typedef struct {
162        char *key;
163        connection_type type;
164        char *value;
165} request_handler;
166
167typedef struct {
168        char *key;
169        char *host;
170        unsigned short port;
171        int used;
172        short factor;
173} fcgi_connections;
174
175typedef struct {
176        /** HEADER */
177        /* the request-line */
178        buffer *request;
179        buffer *uri;
180
181        buffer *orig_uri;
182
183        http_method_t  http_method;
184        http_version_t http_version;
185
186        buffer *http_host;
187
188        array  *headers;
189
190        /* CONTENT */
191        off_t   content_length; /* returned by strtoul() */
192
193        /* internal representation */
194        int     accept_encoding;
195
196        /* internal */
197        buffer *pathinfo;
198} request;
199
200typedef struct {
201        off_t   content_length;
202        int     keep_alive;               /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */
203
204        array  *headers;
205
206        enum {
207                HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED
208        } transfer_encoding;
209} response;
210
211typedef struct {
212        buffer *scheme;
213        buffer *authority;
214        buffer *path;
215        buffer *path_raw;
216        buffer *query;
217} request_uri;
218
219typedef struct {
220        buffer *path;
221        buffer *basedir; /* path = "(basedir)(.*)" */
222
223        buffer *doc_root; /* path = doc_root + rel_path */
224        buffer *rel_path;
225
226        buffer *etag;
227} physical;
228
229typedef struct {
230        buffer *name;
231        buffer *etag;
232
233        struct stat st;
234
235        time_t stat_ts;
236
237        enum {
238                STAT_CACHE_ENTRY_UNSET, 
239                STAT_CACHE_ENTRY_ASYNC_STAT, 
240                STAT_CACHE_ENTRY_STAT_FINISHED
241        } state;
242
243#ifdef HAVE_LSTAT
244        char is_symlink;
245#endif
246
247#if defined(HAVE_SYS_INOTIFY_H)
248        int    dir_version; /* when this entry was created the dir had this version */
249        int    dir_ndx;
250#endif
251
252        buffer *content_type;
253} stat_cache_entry;
254
255typedef struct {
256#ifdef HAVE_GLIB_H
257        GHashTable *files; /* a HashTable of stat_cache_entries for the files */
258        GHashTable *dirs;  /* a HashTable of stat_cache_entries for the dirs */
259#endif
260
261        buffer *dir_name;  /* for building the dirname from the filename */
262        buffer *hash_key;  /* tmp-buf for building the hash-key */
263
264#if defined(HAVE_SYS_INOTIFY_H)
265        iosocket *sock;    /* socket to the inotify fd (this should be in a backend struct */
266#endif
267} stat_cache;
268
269typedef struct {
270        array *mimetypes;
271
272        /* virtual-servers */
273        buffer *document_root;
274        buffer *server_name;
275        buffer *error_handler;
276        buffer *server_tag;
277        buffer *dirlist_encoding;
278        buffer *errorfile_prefix;
279
280        unsigned short max_keep_alive_requests;
281        unsigned short max_keep_alive_idle;
282        unsigned short max_read_idle;
283        unsigned short max_write_idle;
284        unsigned short max_connection_idle;
285        unsigned short use_xattr;
286        unsigned short follow_symlink;
287        unsigned short range_requests;
288
289        /* debug */
290
291        unsigned short log_file_not_found;
292        unsigned short log_request_header;
293        unsigned short log_request_handling;
294        unsigned short log_response_header;
295        unsigned short log_condition_handling;
296        unsigned short log_condition_cache_handling;
297
298
299        /* server wide */
300        buffer *ssl_pemfile;
301        buffer *ssl_ca_file;
302        buffer *ssl_cipher_list;
303        unsigned short ssl_use_sslv2;
304        unsigned short use_ipv6;
305        unsigned short is_ssl;
306        unsigned short allow_http11;
307        unsigned short etag_use_inode;
308        unsigned short etag_use_mtime;
309        unsigned short etag_use_size;
310        unsigned short force_lowercase_filenames; /* if the FS is case-insensitive, force all files to lower-case */
311        unsigned int max_request_size;
312
313        unsigned short kbytes_per_second; /* connection kb/s limit */
314       
315        /* configside */
316        unsigned short global_kbytes_per_second; /*  */
317
318        off_t  global_bytes_per_second_cnt;
319        /* server-wide traffic-shaper
320         *
321         * each context has the counter which is inited once
322         * per second by the global_kbytes_per_second config-var
323         *
324         * as soon as global_kbytes_per_second gets below 0
325         * the connected conns are "offline" a little bit
326         *
327         * the problem:
328         * we somehow have to lose our "we are writable" signal
329         * on the way.
330         *
331         */
332        off_t *global_bytes_per_second_cnt_ptr; /*  */
333
334#ifdef USE_OPENSSL
335        SSL_CTX *ssl_ctx;
336#endif
337} specific_config;
338
339/* the order of the items should be the same as they are processed
340 * read before write as we use this later */
341typedef enum {
342        CON_STATE_CONNECT,         /** we are wait for a connect */
343        CON_STATE_REQUEST_START,   /** after the connect, the request is initialized, keep-alive starts here again */
344        CON_STATE_READ_REQUEST_HEADER,   /** loop in the read-request-header until the full header is received */
345        CON_STATE_VALIDATE_REQUEST_HEADER,   /** validate the request-header */
346        CON_STATE_HANDLE_REQUEST_HEADER, /** find a handler for the request */
347        CON_STATE_READ_REQUEST_CONTENT,  /** forward the request content to the handler */
348        CON_STATE_HANDLE_RESPONSE_HEADER, /** the backend bounces the response back to the client */
349        CON_STATE_WRITE_RESPONSE_HEADER,
350        CON_STATE_WRITE_RESPONSE_CONTENT,
351        CON_STATE_RESPONSE_END,
352        CON_STATE_ERROR,
353        CON_STATE_CLOSE
354} connection_state_t;
355
356typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t;
357typedef struct {
358        cond_result_t result;
359        int patterncount;
360        int matches[3 * 10];
361        buffer *comp_value; /* just a pointer */
362
363        comp_key_t comp_type;
364} cond_cache_t;
365
366typedef struct {
367        connection_state_t state;
368
369        /* timestamps */
370        time_t read_idle_ts;
371        time_t close_timeout_ts;
372        time_t write_request_ts;
373
374        time_t connection_start;
375        time_t request_start;
376
377        struct timeval start_tv;
378
379        size_t request_count;        /* number of requests handled in this connection */
380        size_t loops_per_request;    /* to catch endless loops in a single request
381                                      *
382                                      * used by mod_rewrite, mod_fastcgi, ... and others
383                                      * this is self-protection
384                                      */
385
386        iosocket *sock;
387        int ndx;                     /* reverse mapping to server->connection[ndx] */
388
389        /* fd states */
390        int is_readable;
391        int is_writable;
392
393        int     keep_alive;          /* only request.c can enable it, all others just disable */
394
395        int file_started;
396
397        chunkqueue *send;            /* the response-content before filters are applied */
398        chunkqueue *recv;            /* the request-content, without encoding */
399
400        filter_chain *send_filters;  /* the chain of filters to apply to response-content. */
401        chunkqueue *send_raw;        /* the full response (HTTP-Header + compression + chunking ) */
402        chunkqueue *recv_raw;        /* the full request (HTTP-Header + chunking ) */
403
404        int traffic_limit_reached;
405
406        off_t bytes_written;          /* used by mod_accesslog, mod_rrd */
407        off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */
408        off_t bytes_read;             /* used by mod_accesslog, mod_rrd */
409        off_t bytes_header;
410
411        int http_status;
412
413        sock_addr dst_addr;
414        buffer *dst_addr_buf;
415
416        /* request */
417        buffer *parse_request;
418
419        http_req *http_req;
420        request  request;
421        request_uri uri;
422        physical physical;
423        response response;
424
425        size_t header_len;
426
427        buffer *authed_user;
428        array  *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */
429
430        /* response */
431        int    got_response;
432
433        int    in_joblist;
434
435        connection_type mode;
436
437        void **plugin_ctx;           /* plugin connection specific config */
438
439        specific_config conf;        /* global connection specific config */
440        cond_cache_t *cond_cache;
441
442        buffer *server_name;
443
444        /* error-handler */
445        buffer *error_handler;
446        int error_handler_saved_status;
447        int in_error_handler;
448
449        void *srv_socket;   /* reference to the server-socket (typecast to server_socket) */
450
451        /* etag handling */
452        etag_flags_t etag_flags;
453
454
455#ifdef HAVE_GLIB_H
456        GTimeVal timestamps[TIME_LAST_ELEMENT]; /**< used by timing.h */
457#endif
458
459        int conditional_is_valid[COMP_LAST_ELEMENT];
460} connection;
461
462typedef struct {
463        connection **ptr;
464        size_t size;
465        size_t used;
466} connections;
467
468
469#ifdef HAVE_IPV6
470typedef struct {
471        int family;
472        union {
473                struct in6_addr ipv6;
474                struct in_addr  ipv4;
475        } addr;
476        char b2[INET6_ADDRSTRLEN + 1];
477        time_t ts;
478} inet_ntop_cache_type;
479#endif
480
481
482typedef struct {
483        buffer *uri;
484        time_t mtime;
485        int http_status;
486} realpath_cache_type;
487
488typedef struct {
489        time_t  mtime;  /* the key */
490        buffer *str;    /* a buffer for the string represenation */
491} mtime_cache_type;
492
493typedef struct {
494        void  *ptr;
495        size_t used;
496        size_t size;
497} buffer_plugin;
498
499typedef enum {
500        NETWORK_STATUS_UNSET,
501        NETWORK_STATUS_SUCCESS,
502        NETWORK_STATUS_FATAL_ERROR,
503        NETWORK_STATUS_CONNECTION_CLOSE,
504        NETWORK_STATUS_WAIT_FOR_EVENT,
505        NETWORK_STATUS_WAIT_FOR_AIO_EVENT,
506        NETWORK_STATUS_WAIT_FOR_FD,
507        NETWORK_STATUS_INTERRUPTED
508} network_status_t;
509
510typedef struct {
511        unsigned short port;
512        buffer *bindhost;
513
514        unsigned short dont_daemonize;
515        unsigned short daemonize_on_shutdown;
516        buffer *changeroot;
517        buffer *username;
518        buffer *groupname;
519
520        buffer *pid_file;
521
522        buffer *event_handler;
523
524        buffer *modules_dir;
525        buffer *network_backend;
526        array *modules;
527        array *upload_tempdirs;
528
529        unsigned short use_noatime;
530
531        unsigned short max_worker;
532        unsigned short max_fds;
533        unsigned short max_conns;
534        unsigned int max_request_size;
535
536        unsigned short log_request_header_on_error;
537        unsigned short log_state_handling;
538        unsigned short log_timing;
539
540        enum { STAT_CACHE_ENGINE_UNSET,
541                        STAT_CACHE_ENGINE_NONE,
542                        STAT_CACHE_ENGINE_SIMPLE,
543                        STAT_CACHE_ENGINE_FAM,
544                        STAT_CACHE_ENGINE_INOTIFY
545        } stat_cache_engine;
546        unsigned short enable_cores;
547
548        buffer *errorlog_file;
549        unsigned short errorlog_use_syslog;
550
551        unsigned short max_stat_threads;
552        unsigned short max_read_threads;
553} server_config;
554
555typedef enum {
556        NETWORK_BACKEND_UNSET,
557
558        NETWORK_BACKEND_WRITE,
559        NETWORK_BACKEND_WRITEV,
560
561        NETWORK_BACKEND_LINUX_SENDFILE,
562        NETWORK_BACKEND_LINUX_AIO_SENDFILE,
563        NETWORK_BACKEND_POSIX_AIO,
564        NETWORK_BACKEND_GTHREAD_AIO,
565        NETWORK_BACKEND_GTHREAD_SENDFILE,
566
567        NETWORK_BACKEND_FREEBSD_SENDFILE,
568        NETWORK_BACKEND_SOLARIS_SENDFILEV,
569
570        NETWORK_BACKEND_WIN32_SEND,
571        NETWORK_BACKEND_WIN32_TRANSMITFILE,
572
573} network_backend_t;
574
575
576typedef struct {
577        sock_addr addr;
578        iosocket *sock;
579
580        buffer *ssl_pemfile;
581        buffer *ssl_ca_file;
582        buffer *ssl_cipher_list;
583        unsigned short ssl_use_sslv2;
584        unsigned short use_ipv6;
585        unsigned short is_ssl;
586
587        buffer *srv_token;
588
589#ifdef USE_OPENSSL
590        SSL_CTX *ssl_ctx;
591#endif
592} server_socket;
593
594typedef struct {
595        server_socket **ptr;
596
597        size_t size;
598        size_t used;
599} server_socket_array;
600
601typedef struct server {
602        server_socket_array srv_sockets;
603
604        fdevents *ev, *ev_ins;
605
606        buffer_plugin plugins;
607        void *plugin_slots;
608
609        /* counters */
610        int con_opened;
611        int con_read;
612        int con_written;
613        int con_closed;
614
615        int ssl_is_init;
616
617        int max_fds;    /* max possible fds */
618        int sockets_disabled;
619
620        size_t max_conns;
621
622        /* buffers */
623        buffer *parse_full_path;
624        buffer *response_header;
625        buffer *response_range;
626        buffer *tmp_buf;
627
628        buffer *tmp_chunk_len;
629
630        buffer *empty_string; /* is necessary for cond_match */
631
632        buffer *cond_check_buf;
633
634        /* caches */
635#ifdef HAVE_IPV6
636        inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX];
637#endif
638        mtime_cache_type mtime_cache[FILE_CACHE_MAX];
639
640        array *split_vals;
641
642        /* Timestamps */
643        time_t cur_ts;
644        time_t last_generated_date_ts;
645        time_t last_generated_debug_ts;
646        time_t startup_ts;
647
648        buffer *ts_debug_str;
649        buffer *ts_date_str;
650
651        /* config-file */
652        array *config;
653        array *config_touched;
654
655        array *config_context;
656        specific_config **config_storage;
657
658        server_config  srvconf;
659
660        short unsigned config_deprecated;
661        short unsigned config_unsupported;
662
663        connections *conns;
664        connections *joblist;
665        connections *joblist_prev;
666        connections *fdwaitqueue;
667
668        stat_cache  *stat_cache;
669
670        fdevent_handler_t event_handler;
671
672        network_status_t (* network_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
673        network_status_t (* network_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
674#ifdef USE_OPENSSL
675        network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
676        network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
677#endif
678
679#ifdef HAVE_PWD_H
680        uid_t uid;
681        gid_t gid;
682#endif
683#ifdef USE_GTHREAD
684#ifdef USE_LINUX_AIO_SENDFILE
685        io_context_t linux_io_ctx;
686
687        struct iocb *linux_io_iocbs;
688
689#endif
690#ifdef USE_POSIX_AIO
691        struct aiocb *posix_aio_iocbs;
692#endif
693
694        GAsyncQueue *stat_queue; /* send a stat_job into this queue and joblist_queue will get a wakeup when the stat is finished */
695        GAsyncQueue *joblist_queue;
696        GAsyncQueue *aio_write_queue;
697#endif
698        network_backend_t network_backend;
699        int is_shutdown;
700} server;
701
702int server_out_of_fds(server *srv, connection *con);
703
704LI_EXPORT unsigned short sock_addr_get_port(sock_addr *addr); /* configfile-glue.c */
705
706#endif
Note: See TracBrowser for help on using the browser.