xref: /lighttpd1.4/src/gw_backend.h (revision c412bb59)
1 #ifndef INCLUDED_GW_BACKEND_H
2 #define INCLUDED_GW_BACKEND_H
3 
4 #include "first.h"
5 
6 #include <sys/types.h>
7 #include "sys-socket.h"
8 
9 #include "array.h"
10 #include "buffer.h"
11 
12 typedef struct {
13     char **ptr;
14     uint32_t used;
15 } char_array;
16 
17 typedef struct gw_proc {
18     struct gw_proc *next; /* see first */
19     enum {
20         PROC_STATE_RUNNING,    /* alive */
21         PROC_STATE_OVERLOADED, /* listen-queue is full */
22         PROC_STATE_DIED_WAIT_FOR_PID, /* */
23         PROC_STATE_DIED,       /* marked as dead, should be restarted */
24         PROC_STATE_KILLED      /* killed (signal sent to proc) */
25     } state;
26     uint32_t load; /* number of requests waiting on this process */
27     unix_time64_t last_used; /* see idle_timeout */
28     int *stats_load;
29     int *stats_connected;
30     pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
31     int is_local;
32     uint32_t id; /* id will be between 1 and max_procs */
33     socklen_t saddrlen;
34     struct sockaddr *saddr;
35 
36     unix_time64_t disabled_until; /* proc disabled until given time */
37     struct gw_proc *prev; /* see first */
38 
39     /* either tcp:<host>:<port> or unix:<socket> for debugging purposes */
40     buffer *connection_name;
41     buffer *unixsocket; /* config.socket + "-" + id */
42     unsigned short port;  /* config.port + pno */
43 } gw_proc;
44 
45 struct gw_handler_ctx;  /* declaration */
46 
47 typedef struct {
48     /* list of processes handling this extension
49      * sorted by lowest load
50      *
51      * whenever a job is done move it up in the list
52      * until it is sorted, move it down as soon as the
53      * job is started
54      */
55     gw_proc *first;
56 
57     uint32_t active_procs; /* how many procs in state PROC_STATE_RUNNING */
58     uint32_t gw_hash;
59 
60     int32_t load;
61     int *stats_load;
62     int *stats_global_active;
63 
64     /*
65      * host:port
66      *
67      * if host is one of the local IP addresses the
68      * whole connection is local
69      *
70      * if port is not 0, and host is not specified,
71      * "localhost" (INADDR_LOOPBACK) is assumed.
72      *
73      */
74     unsigned short port;
75     unsigned short family; /* sa_family_t */
76     const buffer *host;
77 
78     /* the key that is used to reference this value */
79     const buffer *id;
80     gw_proc *unused_procs;
81 
82     /*
83      * spawn at least min_procs, at max_procs.
84      *
85      * as soon as the load of the first entry
86      * is max_load_per_proc we spawn a new one
87      * and add it to the first entry and give it
88      * the load
89      *
90      */
91 
92     unsigned short min_procs;
93     unsigned short max_procs;
94     uint32_t num_procs;    /* how many procs are started */
95 
96     unsigned short max_load_per_proc;
97 
98     /*
99      * kick the process from the list if it was not
100      * used for idle_timeout until min_procs is
101      * reached. this helps to get the processlist
102      * small again we had a small peak load.
103      *
104      */
105 
106     unsigned short idle_timeout;
107 
108     /*
109      * time after a disabled remote connection is tried to be re-enabled
110      *
111      *
112      */
113 
114     unsigned short disable_time;
115 
116     unsigned short read_timeout;
117     unsigned short write_timeout;
118     unsigned short connect_timeout;
119     struct gw_handler_ctx *hctxs;
120 
121     /*
122      * some gw processes get a little bit larger
123      * than wanted. max_requests_per_proc kills a
124      * process after a number of handled requests.
125      *
126      */
127     /*uint32_t max_requests_per_proc;*//* not implemented */
128 
129 
130     /* config */
131 
132     /*
133      * Unix Domain Socket
134      *
135      * instead of TCP/IP we can use Unix Domain Sockets
136      * - more secure (you have fileperms to play with)
137      * - more control (on locally)
138      * - more speed (no extra overhead)
139      */
140     const buffer *unixsocket;
141 
142     /* if socket is local we can start the gw process ourself
143      *
144      * bin-path is the path to the binary
145      *
146      * check min_procs and max_procs for the number
147      * of process to start up
148      */
149     const buffer *bin_path;
150 
151     /* bin-path is set bin-environment is taken to
152      * create the environment before starting the
153      * FastCGI process
154      *
155      */
156     const array *bin_env;
157 
158     const array *bin_env_copy;
159 
160     /*
161      * docroot-translation between URL->phys and the
162      * remote host
163      *
164      * reasons:
165      * - different dir-layout if remote
166      * - chroot if local
167      *
168      */
169     const buffer *docroot;
170 
171     /*
172      * append PATH_INFO to SCRIPT_FILENAME
173      *
174      * php needs this if cgi.fix_pathinfo is provided
175      *
176      */
177 
178     unsigned short break_scriptfilename_for_php;
179 
180     /*
181      * check_local tells you if the phys file is stat()ed
182      * or not. FastCGI doesn't care if the service is
183      * remote. If the web-server side doesn't contain
184      * the FastCGI-files we should not stat() for them
185      * and say '404 not found'.
186      */
187     unsigned short check_local;
188 
189     /*
190      * workaround for program when prefix="/"
191      *
192      * rule to build PATH_INFO is hardcoded for when check_local is disabled
193      * enable this option to use the workaround
194      *
195      */
196 
197     unsigned short fix_root_path_name;
198 
199     /*
200      * If the backend includes X-Sendfile in the response
201      * we use the value as filename and ignore the content.
202      *
203      */
204     unsigned short xsendfile_allow;
205     const array *xsendfile_docroot;
206 
207     uint32_t max_id; /* corresponds most of the time to num_procs */
208 
209     const buffer *strip_request_uri;
210 
211     unsigned short tcp_fin_propagate;
212     unsigned short kill_signal; /* we need a setting for this as libfcgi
213                                    applications prefer SIGUSR1 while the
214                                    rest of the world would use SIGTERM
215                                    *sigh* */
216 
217     int listen_backlog;
218     int refcount;
219 
220     char_array args;
221 } gw_host;
222 
223 /*
224  * one extension can have multiple hosts assigned
225  * one host can spawn additional processes on the same
226  *   socket (if we control it)
227  *
228  * ext -> host -> procs
229  *    1:n     1:n
230  *
231  * if the gw process is remote that whole goes down
232  * to
233  *
234  * ext -> host -> procs
235  *    1:n     1:1
236  *
237  * in case of PHP and FCGI_CHILDREN we have again a procs
238  * but we don't control it directly.
239  *
240  */
241 
242 typedef struct {
243     const buffer key; /* like .php */
244 
245     int note_is_sent;
246     int last_used_ndx;
247 
248     gw_host **hosts;
249     uint32_t used;
250     uint32_t size;
251 } gw_extension;
252 
253 typedef struct {
254     gw_extension *exts;
255     uint32_t used;
256     uint32_t size;
257 } gw_exts;
258 
259 
260 
261 
262 #include "base_decls.h"
263 #include "chunk.h"
264 #include "plugin.h"
265 #include "response.h"
266 
267 typedef struct gw_plugin_config {
268     gw_exts *exts;
269     gw_exts *exts_auth;
270     gw_exts *exts_resp;
271     const array *ext_mapping;
272     int balance;
273     int proto;
274     int debug;
275 } gw_plugin_config;
276 
277 /* generic plugin data, shared between all connections */
278 typedef struct gw_plugin_data {
279     PLUGIN_DATA;
280     pid_t srv_pid; /* must precede gw_plugin_config for mods w/ larger struct */
281     gw_plugin_config conf; /* used only as long as no gw_handler_ctx is setup */
282     gw_plugin_config defaults;/*(must not be used by gw_backend.c: lg struct) */
283 } gw_plugin_data;
284 
285 /* connection specific data */
286 typedef enum {
287     GW_STATE_INIT,
288     GW_STATE_CONNECT_DELAYED,
289     GW_STATE_PREPARE_WRITE,
290     GW_STATE_WRITE,
291     GW_STATE_READ
292 } gw_connection_state_t;
293 
294 struct fdevents;        /* declaration */
295 
296 #define GW_RESPONDER  1
297 #define GW_AUTHORIZER 2
298 #define GW_FILTER     3  /*(not implemented)*/
299 
300 typedef struct gw_handler_ctx {
301     gw_proc *proc;
302     gw_host *host;
303     gw_extension *ext;
304     gw_extension *ext_auth; /* (future: might allow multiple authorizers)*/
305     unsigned short gw_mode; /* mode: GW_AUTHORIZER or GW_RESPONDER */
306 
307     gw_connection_state_t state;
308 
309     chunkqueue *rb; /* read queue */
310     off_t     wb_reqlen;
311     chunkqueue wb; /* write queue */
312 
313     buffer   *response;
314 
315     struct fdevents *ev;
316     fdnode   *fdn;       /* fdevent (fdnode *) object */
317     int       fd;        /* fd to the gw process */
318     int       revents;   /* ready events on fd */
319 
320     pid_t     pid;
321     int       reconnects; /* number of reconnect attempts */
322 
323     int       request_id;
324     int       send_content_body;
325 
326     http_response_opts opts;
327     gw_plugin_config conf;
328 
329     request_st *r;               /* dumb pointer */
330     connection *con;             /* dumb pointer */
331     gw_plugin_data *plugin_data; /* dumb pointer */
332     unix_time64_t read_ts;
333     unix_time64_t write_ts;
334     handler_t(*stdin_append)(struct gw_handler_ctx *hctx);
335     handler_t(*create_env)(struct gw_handler_ctx *hctx);
336     struct gw_handler_ctx *prev;
337     struct gw_handler_ctx *next;
338     void(*backend_error)(struct gw_handler_ctx *hctx);
339     void(*handler_ctx_free)(void *hctx);
340 } gw_handler_ctx;
341 
342 
343 __attribute_cold__
344 __attribute_malloc__
345 void * gw_init(void);
346 
347 __attribute_cold__
348 void gw_plugin_config_free(gw_plugin_config *s);
349 
350 __attribute_cold__
351 void gw_free(void *p_d);
352 
353 __attribute_cold__
354 void gw_exts_clear_check_local(gw_exts *exts);
355 
356 __attribute_cold__
357 int gw_set_defaults_backend(server *srv, gw_plugin_data *p, const array *a, gw_plugin_config *s, int sh_exec, const char *cpkkey);
358 
359 __attribute_cold__
360 int gw_get_defaults_balance(server *srv, const buffer *b);
361 
362 handler_t gw_check_extension(request_st *r, gw_plugin_data *p, int uri_path_handler, size_t hctx_sz);
363 handler_t gw_handle_request_reset(request_st *r, void *p_d);
364 handler_t gw_handle_subrequest(request_st *r, void *p_d);
365 handler_t gw_handle_trigger(server *srv, void *p_d);
366 handler_t gw_handle_waitpid_cb(server *srv, void *p_d, pid_t pid, int status);
367 
368 void gw_set_transparent(gw_handler_ctx *hctx);
369 
370 #endif
371