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