Reccomend against using appConnTimeout
[mod_fastcgi.git] / fcgi.h
blob976af312ec52b01c34f694958693a7e96dc3a81c
1 /*
2 * $Id: fcgi.h,v 1.23 2000/04/29 21:01:43 robs Exp $
3 */
5 #ifndef FCGI_H
6 #define FCGI_H
8 /* Apache header files */
9 #include "httpd.h"
10 #include "http_config.h"
11 #include "http_request.h"
12 #include "http_core.h"
13 #include "http_protocol.h"
14 #include "http_main.h"
15 #include "http_log.h"
16 #include "util_script.h"
17 #include "http_conf_globals.h"
18 #include "util_md5.h"
20 #if MODULE_MAGIC_NUMBER < 19980806
21 #error "This version of mod_fastcgi is incompatible with Apache versions 1.3.1 and earlier."
22 #error "Please upgrade, or try the last Apache 1.2 compatible release, mod_fastcgi 2.0.18 (no DSO support)."
23 #endif
25 #ifndef NO_WRITEV
26 #include <sys/uio.h>
27 #endif
29 #ifndef WIN32
30 #include <sys/un.h>
31 #endif
33 /* FastCGI header files */
34 #include "mod_fastcgi.h"
35 /* @@@ This should go away when fcgi_protocol is re-written */
36 #include "fcgi_protocol.h"
38 typedef struct {
39 int size; /* size of entire buffer */
40 int length; /* number of bytes in current buffer */
41 char *begin; /* begining of valid data */
42 char *end; /* end of valid data */
43 char data[1]; /* buffer data */
44 } Buffer;
46 #ifdef WIN32
47 #define READER 0
48 #define WRITER 1
50 #define MBOX_EVENT 0 /* mboc is ready to be read */
51 #define TERM_EVENT 1 /* termination event */
52 #define WAKE_EVENT 2 /* notification of child Fserver dieing */
54 /* Reader/Writer lock structure for NT */
55 typedef struct _FcgiRWLock {
56 HANDLE read_event; /* reader handle */
57 HANDLE lock_mutex; /* lock mutex */
58 HANDLE write_event; /* write handle */
59 long counter; /* number of readers */
60 } FcgiRWLock;
62 typedef struct _fcgi_pm_job {
63 char id;
64 char *fs_path;
65 char *user;
66 char * group;
67 unsigned long qsec;
68 unsigned long start_time;
69 struct _fcgi_pm_job *next;
70 } fcgi_pm_job;
71 #endif
74 * ServerProcess holds data for each process associated with
75 * a class. It is embedded in fcgi_server below.
77 typedef struct _FcgiProcessInfo {
78 #ifdef WIN32
79 HANDLE pid; /* handle of associated process */
80 #else
81 pid_t pid; /* pid of associated process */
82 #endif
83 enum {STATE_STARTED, /* currently running */
84 STATE_NEEDS_STARTING, /* needs to be started by PM */
85 STATE_KILL, /* kill() is needed */
86 STATE_VICTIM, /* SIGTERM was sent by PM */
87 STATE_KILLED, /* a wait() collected VICTIM */
88 STATE_READY} /* empty cell, init state */
89 state; /* state of the process */
90 } ServerProcess;
93 * fcgi_server holds info for each AppClass specified in this
94 * Web server's configuration.
96 typedef struct _FastCgiServerInfo {
97 int flush;
98 const char *fs_path; /* pathname of executable */
99 array_header *pass_headers; /* names of headers to pass in the env */
100 u_int idle_timeout; /* fs idle secs allowed before aborting */
101 char **envp; /* if NOT NULL, this is the env to send
102 * to the fcgi app when starting a server
103 * managed app. */
104 u_int listenQueueDepth; /* size of listen queue for IPC */
105 u_int appConnectTimeout; /* timeout (sec) for connect() requests */
106 u_int numProcesses; /* max allowed processes of this class,
107 * or for dynamic apps, the number of
108 * processes actually running */
109 time_t restartTime; /* most recent time when the process
110 * manager started a process in this
111 * class. */
112 u_int initStartDelay; /* min number of seconds to wait between
113 * starting of AppClass processes at init */
114 u_int restartDelay; /* number of seconds to wait between
115 * restarts after failure. Can be zero. */
116 int restartOnExit; /* = TRUE = restart. else terminate/free */
117 u_int numRestarts; /* Total number of restarts */
118 u_int numFailures; /* num restarts due to exit failure */
119 struct sockaddr *socket_addr; /* Socket Address of FCGI app server class */
120 #ifdef WIN32
121 struct sockaddr *dest_addr; /* for local apps on NT need socket address */
122 /* bound to localhost */
123 #endif
124 int socket_addr_len; /* Length of socket */
125 enum {APP_CLASS_UNKNOWN,
126 APP_CLASS_STANDARD,
127 APP_CLASS_EXTERNAL,
128 APP_CLASS_DYNAMIC}
129 directive; /* AppClass or ExternalAppClass */
130 const char *socket_path; /* Name used to create a socket */
131 const char *host; /* Hostname for externally managed
132 * FastCGI application processes */
133 unsigned short port; /* Port number either for externally
134 * managed FastCGI applications or for
135 * server managed FastCGI applications,
136 * where server became application mngr. */
137 int listenFd; /* Listener socket of FCGI app server
138 * class. Passed to app server process
139 * at process creation. */
140 u_int processPriority; /* If locally server managed process,
141 * this is the priority to run the
142 * processes in this class at. */
143 struct _FcgiProcessInfo *procs; /* Pointer to array of
144 * processes belonging to this class. */
145 int keepConnection; /* = 1 = maintain connection to app. */
146 uid_t uid; /* uid this app should run as (suexec) */
147 gid_t gid; /* gid this app should run as (suexec) */
148 const char *username; /* suexec user arg */
149 const char *group; /* suexec group arg, AND used in comm
150 * between RH and PM */
151 const char *user; /* used in comm between RH and PM */
152 /* Dynamic FastCGI apps configuration parameters */
153 u_long totalConnTime; /* microseconds spent by the web server
154 * waiting while fastcgi app performs
155 * request processing since the last
156 * dynamicUpdateInterval */
157 u_long smoothConnTime; /* exponentially decayed values of the
158 * connection times. */
159 u_long totalQueueTime; /* microseconds spent by the web server
160 * waiting to connect to the fastcgi app
161 * since the last dynamicUpdateInterval. */
162 #ifdef WIN32
163 FcgiRWLock *dynamic_lock; /* dynamic server lock */
164 HANDLE hPipeMutex;
165 #endif
167 struct _FastCgiServerInfo *next;
168 } fcgi_server;
172 * fcgi_request holds the state of a particular FastCGI request.
174 typedef struct {
175 #ifdef WIN32
176 SOCKET fd;
177 #else
178 int fd; /* connection to FastCGI server */
179 #endif
180 int gotHeader; /* TRUE if reading content bytes */
181 unsigned char packetType; /* type of packet */
182 int dataLen; /* length of data bytes */
183 int paddingLen; /* record padding after content */
184 fcgi_server *fs; /* FastCGI server info */
185 const char *fs_path; /* fcgi_server path */
186 Buffer *serverInputBuffer; /* input buffer from FastCgi server */
187 Buffer *serverOutputBuffer; /* output buffer to FastCgi server */
188 Buffer *clientInputBuffer; /* client input buffer */
189 Buffer *clientOutputBuffer; /* client output buffer */
190 table *authHeaders; /* headers received from an auth fs */
191 int auth_compat; /* whether the auth request is spec compat */
192 table *saved_subprocess_env; /* subprocess_env before auth handling */
193 #if defined(SIGPIPE) && MODULE_MAGIC_NUMBER < 19990320
194 void (*apache_sigpipe_handler)(int);
195 #endif
196 int expectingClientContent; /* >0 => more content, <=0 => no more */
197 array_header *header;
198 char *fs_stderr;
199 int fs_stderr_len;
200 int parseHeader; /* TRUE iff parsing response headers */
201 request_rec *r;
202 int readingEndRequestBody;
203 FCGI_EndRequestBody endRequestBody;
204 Buffer *erBufPtr;
205 int exitStatus;
206 int exitStatusSet;
207 unsigned int requestId;
208 int eofSent;
209 int role; /* FastCGI Role: Authorizer or Responder */
210 int dynamic; /* whether or not this is a dynamic app */
211 struct timeval startTime; /* dynamic app's connect() attempt start time */
212 struct timeval queueTime; /* dynamic app's connect() complete time */
213 struct timeval completeTime; /* dynamic app's connection close() time */
214 #ifdef WIN32
215 FcgiRWLock *lockFd; /* dynamic app's reader/writer lock */
216 #else
217 int lockFd; /* dynamic app's lockfile file descriptor */
218 #endif
219 int keepReadingFromFcgiApp; /* still more to read from fcgi app? */
220 const char *user; /* user used to invoke app (suexec) */
221 const char *group; /* group used to invoke app (suexec) */
222 #ifdef WIN32
223 BOOL using_npipe_io; /* named pipe io */
224 #endif
225 } fcgi_request;
227 /* Values of parseHeader field */
228 #define SCAN_CGI_READING_HEADERS 1
229 #define SCAN_CGI_FINISHED 0
230 #define SCAN_CGI_BAD_HEADER -1
231 #define SCAN_CGI_INT_REDIRECT -2
232 #define SCAN_CGI_SRV_REDIRECT -3
234 /* Opcodes for Server->ProcMgr communication */
235 #define PLEASE_START 83 /* 'S' - start */
236 #define CONN_TIMEOUT 84 /* 'T' - timeout */
237 #define REQ_COMPLETE 67 /* 'C' - complete */
239 /* Authorizer types, for auth directives handling */
240 #define FCGI_AUTH_TYPE_AUTHENTICATOR 0
241 #define FCGI_AUTH_TYPE_AUTHORIZER 1
242 #define FCGI_AUTH_TYPE_ACCESS_CHECKER 2
244 /* Bits for auth_options */
245 #define FCGI_AUTHORITATIVE 1
246 #define FCGI_COMPAT 2
248 typedef struct
250 const char *authorizer;
251 u_char authorizer_options;
252 const char *authenticator;
253 u_char authenticator_options;
254 const char *access_checker;
255 u_char access_checker_options;
256 } fcgi_dir_config;
258 #define FCGI_LOG_EMERG __FILE__,__LINE__,APLOG_EMERG /* system is unusable */
259 #define FCGI_LOG_ALERT __FILE__,__LINE__,APLOG_ALERT /* action must be taken immediately */
260 #define FCGI_LOG_CRIT __FILE__,__LINE__,APLOG_CRIT /* critical conditions */
261 #define FCGI_LOG_ERR __FILE__,__LINE__,APLOG_ERR /* error conditions */
262 #define FCGI_LOG_WARN __FILE__,__LINE__,APLOG_WARNING /* warning conditions */
263 #define FCGI_LOG_NOTICE __FILE__,__LINE__,APLOG_NOTICE /* normal but significant condition */
264 #define FCGI_LOG_INFO __FILE__,__LINE__,APLOG_INFO /* informational */
265 #define FCGI_LOG_DEBUG __FILE__,__LINE__,APLOG_DEBUG /* debug-level messages */
267 #define FCGI_LOG_EMERG_NOERRNO __FILE__,__LINE__,APLOG_EMERG|APLOG_NOERRNO
268 #define FCGI_LOG_ALERT_NOERRNO __FILE__,__LINE__,APLOG_ALERT|APLOG_NOERRNO
269 #define FCGI_LOG_CRIT_NOERRNO __FILE__,__LINE__,APLOG_CRIT|APLOG_NOERRNO
270 #define FCGI_LOG_ERR_NOERRNO __FILE__,__LINE__,APLOG_ERR|APLOG_NOERRNO
271 #define FCGI_LOG_WARN_NOERRNO __FILE__,__LINE__,APLOG_WARNING|APLOG_NOERRNO
272 #define FCGI_LOG_NOTICE_NOERRNO __FILE__,__LINE__,APLOG_NOTICE|APLOG_NOERRNO
273 #define FCGI_LOG_INFO_NOERRNO __FILE__,__LINE__,APLOG_INFO|APLOG_NOERRNO
274 #define FCGI_LOG_DEBUG_NOERRNO __FILE__,__LINE__,APLOG_DEBUG|APLOG_NOERRNO
276 #ifdef FCGI_DEBUG
277 #define FCGIDBG1(a) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a);
278 #define FCGIDBG2(a,b) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b);
279 #define FCGIDBG3(a,b,c) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c);
280 #define FCGIDBG4(a,b,c,d) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d);
281 #define FCGIDBG5(a,b,c,d,e) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e);
282 #else
283 #define FCGIDBG1(a)
284 #define FCGIDBG2(a,b)
285 #define FCGIDBG3(a,b,c)
286 #define FCGIDBG4(a,b,c,d)
287 #define FCGIDBG5(a,b,c,d,e)
288 #endif
291 * Holds the status of the sending of the environment.
292 * A quick hack to dump the static vars for the NT port.
294 typedef struct {
295 enum { PREP, HEADER, NAME, VALUE } pass;
296 char **envp;
297 int headerLen, nameLen, valueLen, totalLen;
298 char *equalPtr;
299 unsigned char headerBuff[8];
300 } env_status;
303 * fcgi_config.c
305 void *fcgi_config_create_dir_config(pool *p, char *dummy);
306 const char *fcgi_config_make_dir(pool *tp, char *path);
307 const char *fcgi_config_make_dynamic_dir(pool *p, const int wax);
308 const char *fcgi_config_new_static_server(cmd_parms *cmd, void *dummy, const char *arg);
309 const char *fcgi_config_new_external_server(cmd_parms *cmd, void *dummy, const char *arg);
310 const char *fcgi_config_set_config(cmd_parms *cmd, void *dummy, const char *arg);
311 const char *fcgi_config_set_fcgi_uid_n_gid(int set);
312 const char *fcgi_config_new_auth_server(cmd_parms * const cmd,
313 fcgi_dir_config *dir_config, const char *fs_path, const char * const compat);
314 const char *fcgi_config_set_authoritative_slot(const cmd_parms * const cmd,
315 fcgi_dir_config * const dir_config, int arg);
316 const char *fcgi_config_set_socket_dir(cmd_parms *cmd, void *dummy, char *arg);
317 const char *fcgi_config_set_suexec(cmd_parms *cmd, void *dummy, const char *arg);
318 void fcgi_config_reset_globals(void* dummy);
319 const char *fcgi_config_set_env_var(pool *p, char **envp, unsigned int *envc, char * var);
322 * fcgi_pm.c
324 #ifdef WIN32
325 void fcgi_pm_main(void *dummy);
326 #else
327 int fcgi_pm_main(void *dummy, child_info *info);
328 #endif
331 * fcgi_protocol.c
333 void fcgi_protocol_queue_begin_request(fcgi_request *fr);
334 void fcgi_protocol_queue_client_buffer(fcgi_request *fr);
335 int fcgi_protocol_queue_env(request_rec *r, fcgi_request *fr, env_status *env);
336 int fcgi_protocol_dequeue(pool *p, fcgi_request *fr);
339 * fcgi_buf.c
341 #define BufferLength(b) ((b)->length)
342 #define BufferFree(b) ((b)->size - (b)->length)
343 #define BufferSize(b) ((b)->size)
345 void fcgi_buf_check(Buffer *bufPtr);
346 void fcgi_buf_reset(Buffer *bufPtr);
347 Buffer *fcgi_buf_new(pool *p, int size);
348 void BufferDelete(Buffer *bufPtr);
350 #ifdef WIN32
351 int fcgi_buf_add_fd(Buffer *buf, SOCKET fd);
352 int fcgi_buf_get_to_fd(Buffer *bufPtr, SOCKET fd);
353 #else
354 int fcgi_buf_add_fd(Buffer *buf, int fd);
355 int fcgi_buf_get_to_fd(Buffer *bufPtr, int fd);
356 #endif
358 void fcgi_buf_get_block_info(Buffer *bufPtr, char **beginPtr, size_t *countPtr);
359 void fcgi_buf_toss(Buffer *bufPtr, size_t count);
360 void fcgi_buf_get_free_block_info(Buffer *bufPtr, char **endPtr, size_t *countPtr);
361 void fcgi_buf_add_update(Buffer *bufPtr, size_t count);
362 int fcgi_buf_add_block(Buffer *bufPtr, char *data, size_t datalen);
363 int fcgi_buf_add_string(Buffer *bufPtr, char *str);
364 int fcgi_buf_get_to_block(Buffer *bufPtr, char *data, int datalen);
365 void fcgi_buf_get_to_buf(Buffer *toPtr, Buffer *fromPtr, int len);
366 void fcgi_buf_get_to_array(Buffer *buf,array_header *arr, size_t len);
369 * fcgi_util.c
372 /* Set a shared read lock, wait until you have it. */
373 #ifdef WIN32
374 #define fcgi_wait_for_shared_read_lock(fd) fcgi_rdwr_lock(fd, READER)
375 #else
376 #define fcgi_wait_for_shared_read_lock(fd) fcgi_util_lock_fd((fd), F_SETLKW, F_RDLCK, 0, SEEK_SET, 0)
377 #endif
379 /* Set an exclusive write lock, no wait, failure->errno==EACCES. */
380 #ifdef WIN32
381 #define fcgi_get_exclusive_write_lock_no_wait(fd) fcgi_rdwr_try_lock(fd, WRITER)
382 #else
383 #define fcgi_get_exclusive_write_lock_no_wait(fd) fcgi_util_lock_fd(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0)
384 #endif
386 /* Set a shared write lock, wait until you have it. */
387 #ifdef WIN32
388 #define fcgi_wait_for_shared_write_lock(fd) fcgi_rdwr_lock(fd, WRITER)
389 #else
390 #define fcgi_wait_for_shared_write_lock(fd) fcgi_util_lock_fd(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0)
391 #endif
393 char *fcgi_util_socket_hash_filename(pool *p, const char *path,
394 const char *user, const char *group);
395 const char *fcgi_util_socket_make_path_absolute(pool * const p,
396 const char *const file, const int dynamic);
397 const char *fcgi_util_socket_get_lock_filename(pool *p, const char *socket_path);
398 #ifndef WIN32
399 const char *fcgi_util_socket_make_domain_addr(pool *p, struct sockaddr_un **socket_addr,
400 int *socket_addr_len, const char *socket_path);
401 #endif
402 const char *fcgi_util_socket_make_inet_addr(pool *p, struct sockaddr_in **socket_addr,
403 int *socket_addr_len, const char *host, unsigned short port);
404 const char *fcgi_util_check_access(pool *tp,
405 const char * const path, const struct stat *statBuf,
406 const int mode, const uid_t uid, const gid_t gid);
407 fcgi_server *fcgi_util_fs_get_by_id(const char *ePath, uid_t uid, gid_t gid);
408 fcgi_server *fcgi_util_fs_get(const char *ePath, const char *user, const char *group);
409 const char *fcgi_util_fs_is_path_ok(pool * const p, const char * const fs_path,
410 struct stat *finfo, const uid_t uid, const gid_t gid);
411 fcgi_server *fcgi_util_fs_new(pool *p);
412 void fcgi_util_fs_add(fcgi_server *s);
413 const char *fcgi_util_fs_set_uid_n_gid(pool *p, fcgi_server *s, uid_t uid, gid_t gid);
414 ServerProcess *fcgi_util_fs_create_procs(pool *p, int num);
415 int fcgi_util_lock_fd(int fd, int cmd, int type, off_t offset, int whence, off_t len);
417 int fcgi_util_gettimeofday(struct timeval *);
419 #ifdef WIN32
420 FcgiRWLock * fcgi_rdwr_create(void);
421 void fcgi_rdwr_destroy(FcgiRWLock *);
422 int fcgi_rdwr_lock(FcgiRWLock *, int);
423 int fcgi_rdwr_try_lock(FcgiRWLock *, int);
424 int fcgi_rdwr_unlock(FcgiRWLock *, int);
426 int fcgi_pm_add_job(fcgi_pm_job *new_job);
427 #endif
431 * Globals
434 extern pool *fcgi_config_pool;
436 extern server_rec *fcgi_apache_main_server;
438 extern const char *fcgi_suexec; /* suexec_bin path */
439 extern uid_t fcgi_user_id; /* the run uid of Apache & PM */
440 extern gid_t fcgi_group_id; /* the run gid of Apache & PM */
442 extern fcgi_server *fcgi_servers;
444 extern char *fcgi_socket_dir; /* default FastCgiIpcDir */
446 /* pipe used for comm between the request handlers and the PM */
447 extern int fcgi_pm_pipe[];
449 extern pid_t fcgi_pm_pid;
451 extern char *fcgi_dynamic_dir; /* directory for the dynamic
452 * fastcgi apps' sockets */
454 extern char *fcgi_empty_env;
456 extern int fcgi_dynamic_total_proc_count;
457 extern time_t fcgi_dynamic_epoch;
458 extern time_t fcgi_dynamic_last_analyzed;
460 #ifdef WIN32
461 extern HANDLE *fcgi_dynamic_mbox_mutex;
462 extern HANDLE fcgi_event_handles[3];
463 extern fcgi_pm_job *fcgi_dynamic_mbox;
464 #endif
466 extern u_int dynamicMaxProcs;
467 extern u_int dynamicMinProcs;
468 extern u_int dynamicMaxClassProcs;
469 extern u_int dynamicKillInterval;
470 extern u_int dynamicUpdateInterval;
471 extern float dynamicGain;
472 extern u_int dynamicThreshhold1;
473 extern u_int dynamicThreshholdN;
474 extern u_int dynamicPleaseStartDelay;
475 extern u_int dynamicAppConnectTimeout;
476 extern char **dynamicEnvp;
477 extern u_int dynamicProcessSlack;
478 extern int dynamicAutoRestart;
479 extern int dynamicAutoUpdate;
480 extern u_int dynamicListenQueueDepth;
481 extern u_int dynamicInitStartDelay;
482 extern u_int dynamicRestartDelay;
483 extern array_header *dynamic_pass_headers;
484 extern u_int dynamic_idle_timeout;
486 extern module MODULE_VAR_EXPORT fastcgi_module;
488 #endif /* FCGI_H */