set dynamic's request complete time just once (from close_connection())
[mod_fastcgi.git] / fcgi.h
blobed62539929f090680c4289709258a3120e6a0e03
1 /*
2 * $Id: fcgi.h,v 1.36 2002/03/12 13:06:29 robs Exp $
3 */
5 #ifndef FCGI_H
6 #define FCGI_H
8 #ifdef WIN32
9 #pragma warning( disable : 4115 )
10 #endif
12 /* Apache header files */
13 #include "httpd.h"
14 #include "http_config.h"
15 #include "http_request.h"
16 #include "http_core.h"
17 #include "http_protocol.h"
18 #include "http_main.h"
19 #include "http_log.h"
20 #include "util_script.h"
21 #include "http_conf_globals.h"
22 #include "util_md5.h"
24 #if MODULE_MAGIC_NUMBER < 19990320
25 #error "This version of mod_fastcgi is incompatible with Apache versions older than 1.3.6."
26 #endif
28 #ifndef NO_WRITEV
29 #include <sys/uio.h>
30 #endif
32 #ifdef WIN32
33 #include "multithread.h"
34 #pragma warning( default : 4115)
35 #else
36 #include <sys/un.h>
37 #endif
39 /* FastCGI header files */
40 #include "mod_fastcgi.h"
41 /* @@@ This should go away when fcgi_protocol is re-written */
42 #include "fcgi_protocol.h"
44 typedef struct {
45 int size; /* size of entire buffer */
46 int length; /* number of bytes in current buffer */
47 char *begin; /* begining of valid data */
48 char *end; /* end of valid data */
49 char data[1]; /* buffer data */
50 } Buffer;
52 #ifdef WIN32
53 #define READER 0
54 #define WRITER 1
56 #define MBOX_EVENT 0 /* mboc is ready to be read */
57 #define TERM_EVENT 1 /* termination event */
58 #define WAKE_EVENT 2 /* notification of child Fserver dieing */
60 typedef struct _fcgi_pm_job {
61 char id;
62 char *fs_path;
63 char *user;
64 char * group;
65 unsigned long qsec;
66 unsigned long start_time;
67 struct _fcgi_pm_job *next;
68 } fcgi_pm_job;
69 #endif
71 enum process_state {
72 FCGI_RUNNING_STATE, /* currently running */
73 FCGI_START_STATE, /* needs to be started by PM */
74 FCGI_VICTIM_STATE, /* SIGTERM was sent by PM */
75 FCGI_KILLED_STATE, /* a wait() collected VICTIM */
76 FCGI_READY_STATE /* empty cell, init state */
80 * ServerProcess holds data for each process associated with
81 * a class. It is embedded in fcgi_server below.
83 typedef struct _FcgiProcessInfo {
84 #ifdef WIN32
85 HANDLE handle; /* process handle */
86 HANDLE terminationEvent; /* Event used to signal process termination */
87 #endif
88 pid_t pid; /* pid of associated process */
89 enum process_state state; /* state of the process */
90 time_t start_time; /* time the process was started */
91 } ServerProcess;
94 * fcgi_server holds info for each AppClass specified in this
95 * Web server's configuration.
97 typedef struct _FastCgiServerInfo {
98 int flush;
99 char *fs_path; /* pathname of executable */
100 array_header *pass_headers; /* names of headers to pass in the env */
101 u_int idle_timeout; /* fs idle secs allowed before aborting */
102 char **envp; /* if NOT NULL, this is the env to send
103 * to the fcgi app when starting a server
104 * managed app. */
105 u_int listenQueueDepth; /* size of listen queue for IPC */
106 u_int appConnectTimeout; /* timeout (sec) for connect() requests */
107 u_int numProcesses; /* max allowed processes of this class,
108 * or for dynamic apps, the number of
109 * processes actually running */
110 time_t restartTime; /* most recent time when the process
111 * manager started a process in this
112 * class. */
113 int initStartDelay; /* min number of seconds to wait between
114 * starting of AppClass processes at init */
115 u_int restartDelay; /* number of seconds to wait between
116 * restarts after failure. Can be zero. */
117 int restartOnExit; /* = TRUE = restart. else terminate/free */
118 u_int numFailures; /* num restarts due to exit failure */
119 int bad; /* is [not] having start problems */
120 struct sockaddr *socket_addr; /* Socket Address of FCGI app server class */
121 #ifdef WIN32
122 struct sockaddr *dest_addr; /* for local apps on NT need socket address */
123 /* bound to localhost */
124 const char *mutex_env_string; /* string holding the accept mutex handle */
125 #endif
126 int socket_addr_len; /* Length of socket */
127 enum {APP_CLASS_UNKNOWN,
128 APP_CLASS_STANDARD,
129 APP_CLASS_EXTERNAL,
130 APP_CLASS_DYNAMIC}
131 directive; /* AppClass or ExternalAppClass */
132 const char *socket_path; /* Name used to create a socket */
133 const char *host; /* Hostname for externally managed
134 * FastCGI application processes */
135 unsigned short port; /* Port number either for externally
136 * managed FastCGI applications or for
137 * server managed FastCGI applications,
138 * where server became application mngr. */
139 int listenFd; /* Listener socket of FCGI app server
140 * class. Passed to app server process
141 * at process creation. */
142 u_int processPriority; /* If locally server managed process,
143 * this is the priority to run the
144 * processes in this class at. */
145 struct _FcgiProcessInfo *procs; /* Pointer to array of
146 * processes belonging to this class. */
147 int keepConnection; /* = 1 = maintain connection to app. */
148 uid_t uid; /* uid this app should run as (suexec) */
149 gid_t gid; /* gid this app should run as (suexec) */
150 const char *username; /* suexec user arg */
151 const char *group; /* suexec group arg, AND used in comm
152 * between RH and PM */
153 const char *user; /* used in comm between RH and PM */
154 /* Dynamic FastCGI apps configuration parameters */
155 u_long totalConnTime; /* microseconds spent by the web server
156 * waiting while fastcgi app performs
157 * request processing since the last
158 * dynamicUpdateInterval */
159 u_long smoothConnTime; /* exponentially decayed values of the
160 * connection times. */
161 u_long totalQueueTime; /* microseconds spent by the web server
162 * waiting to connect to the fastcgi app
163 * since the last dynamicUpdateInterval. */
164 struct _FastCgiServerInfo *next;
165 } fcgi_server;
169 * fcgi_request holds the state of a particular FastCGI request.
171 typedef struct {
172 #ifdef WIN32
173 SOCKET fd;
174 #else
175 int fd; /* connection to FastCGI server */
176 #endif
177 int gotHeader; /* TRUE if reading content bytes */
178 unsigned char packetType; /* type of packet */
179 int dataLen; /* length of data bytes */
180 int paddingLen; /* record padding after content */
181 fcgi_server *fs; /* FastCGI server info */
182 const char *fs_path; /* fcgi_server path */
183 Buffer *serverInputBuffer; /* input buffer from FastCgi server */
184 Buffer *serverOutputBuffer; /* output buffer to FastCgi server */
185 Buffer *clientInputBuffer; /* client input buffer */
186 Buffer *clientOutputBuffer; /* client output buffer */
187 table *authHeaders; /* headers received from an auth fs */
188 int auth_compat; /* whether the auth request is spec compat */
189 table *saved_subprocess_env; /* subprocess_env before auth handling */
190 int expectingClientContent; /* >0 => more content, <=0 => no more */
191 array_header *header;
192 char *fs_stderr;
193 int fs_stderr_len;
194 int parseHeader; /* TRUE iff parsing response headers */
195 request_rec *r;
196 int readingEndRequestBody;
197 FCGI_EndRequestBody endRequestBody;
198 Buffer *erBufPtr;
199 int exitStatus;
200 int exitStatusSet;
201 unsigned int requestId;
202 int eofSent;
203 int role; /* FastCGI Role: Authorizer or Responder */
204 int dynamic; /* whether or not this is a dynamic app */
205 struct timeval startTime; /* dynamic app's connect() attempt start time */
206 struct timeval queueTime; /* dynamic app's connect() complete time */
207 struct timeval completeTime; /* dynamic app's connection close() time */
208 int keepReadingFromFcgiApp; /* still more to read from fcgi app? */
209 const char *user; /* user used to invoke app (suexec) */
210 const char *group; /* group used to invoke app (suexec) */
211 #ifdef WIN32
212 BOOL using_npipe_io; /* named pipe io */
213 #endif
214 } fcgi_request;
216 /* Values of parseHeader field */
217 #define SCAN_CGI_READING_HEADERS 1
218 #define SCAN_CGI_FINISHED 0
219 #define SCAN_CGI_BAD_HEADER -1
220 #define SCAN_CGI_INT_REDIRECT -2
221 #define SCAN_CGI_SRV_REDIRECT -3
223 /* Opcodes for Server->ProcMgr communication */
224 #define FCGI_SERVER_START_JOB 83 /* 'S' - start */
225 #define FCGI_SERVER_RESTART_JOB 82 /* 'R' - restart */
226 #define FCGI_REQUEST_TIMEOUT_JOB 84 /* 'T' - timeout */
227 #define FCGI_REQUEST_COMPLETE_JOB 67 /* 'C' - complete */
229 /* Authorizer types, for auth directives handling */
230 #define FCGI_AUTH_TYPE_AUTHENTICATOR 0
231 #define FCGI_AUTH_TYPE_AUTHORIZER 1
232 #define FCGI_AUTH_TYPE_ACCESS_CHECKER 2
234 /* Bits for auth_options */
235 #define FCGI_AUTHORITATIVE 1
236 #define FCGI_COMPAT 2
238 typedef struct
240 const char *authorizer;
241 u_char authorizer_options;
242 const char *authenticator;
243 u_char authenticator_options;
244 const char *access_checker;
245 u_char access_checker_options;
246 } fcgi_dir_config;
248 #define FCGI_OK 0
249 #define FCGI_FAILED 1
251 #ifdef WIN32
253 #define FCGI_LOG_EMERG_ERRNO __FILE__,__LINE__,APLOG_EMERG /* system is unusable */
254 #define FCGI_LOG_ALERT_ERRNO __FILE__,__LINE__,APLOG_ALERT /* action must be taken immediately */
255 #define FCGI_LOG_CRIT_ERRNO __FILE__,__LINE__,APLOG_CRIT /* critical conditions */
256 #define FCGI_LOG_ERR_ERRNO __FILE__,__LINE__,APLOG_ERR /* error conditions */
257 #define FCGI_LOG_WARN_ERRNO __FILE__,__LINE__,APLOG_WARNING /* warning conditions */
258 #define FCGI_LOG_NOTICE_ERRNO __FILE__,__LINE__,APLOG_NOTICE /* normal but significant condition */
259 #define FCGI_LOG_INFO_ERRNO __FILE__,__LINE__,APLOG_INFO /* informational */
260 #define FCGI_LOG_DEBUG_ERRNO __FILE__,__LINE__,APLOG_DEBUG /* debug-level messages */
262 #define FCGI_LOG_EMERG __FILE__,__LINE__,APLOG_EMERG|APLOG_WIN32ERROR
263 #define FCGI_LOG_ALERT __FILE__,__LINE__,APLOG_ALERT|APLOG_WIN32ERROR
264 #define FCGI_LOG_CRIT __FILE__,__LINE__,APLOG_CRIT|APLOG_WIN32ERROR
265 #define FCGI_LOG_ERR __FILE__,__LINE__,APLOG_ERR|APLOG_WIN32ERROR
266 #define FCGI_LOG_WARN __FILE__,__LINE__,APLOG_WARNING|APLOG_WIN32ERROR
267 #define FCGI_LOG_NOTICE __FILE__,__LINE__,APLOG_NOTICE|APLOG_WIN32ERROR
268 #define FCGI_LOG_INFO __FILE__,__LINE__,APLOG_INFO|APLOG_WIN32ERROR
269 #define FCGI_LOG_DEBUG __FILE__,__LINE__,APLOG_DEBUG|APLOG_WIN32ERROR
271 #else
273 #define FCGI_LOG_EMERG __FILE__,__LINE__,APLOG_EMERG /* system is unusable */
274 #define FCGI_LOG_ALERT __FILE__,__LINE__,APLOG_ALERT /* action must be taken immediately */
275 #define FCGI_LOG_CRIT __FILE__,__LINE__,APLOG_CRIT /* critical conditions */
276 #define FCGI_LOG_ERR __FILE__,__LINE__,APLOG_ERR /* error conditions */
277 #define FCGI_LOG_WARN __FILE__,__LINE__,APLOG_WARNING /* warning conditions */
278 #define FCGI_LOG_NOTICE __FILE__,__LINE__,APLOG_NOTICE /* normal but significant condition */
279 #define FCGI_LOG_INFO __FILE__,__LINE__,APLOG_INFO /* informational */
280 #define FCGI_LOG_DEBUG __FILE__,__LINE__,APLOG_DEBUG /* debug-level messages */
282 #define FCGI_LOG_EMERG_ERRNO FCGI_LOG_EMERG
283 #define FCGI_LOG_ALERT_ERRNO FCGI_LOG_ALERT
284 #define FCGI_LOG_CRIT_ERRNO FCGI_LOG_CRIT
285 #define FCGI_LOG_ERR_ERRNO FCGI_LOG_ERR
286 #define FCGI_LOG_WARN_ERRNO FCGI_LOG_WARN
287 #define FCGI_LOG_NOTICE_ERRNO FCGI_LOG_NOTICE
288 #define FCGI_LOG_INFO_ERRNO FCGI_LOG_INFO
289 #define FCGI_LOG_DEBUG_ERRNO FCGI_LOG_DEBUG
291 #endif
293 #define FCGI_LOG_EMERG_NOERRNO __FILE__,__LINE__,APLOG_EMERG|APLOG_NOERRNO
294 #define FCGI_LOG_ALERT_NOERRNO __FILE__,__LINE__,APLOG_ALERT|APLOG_NOERRNO
295 #define FCGI_LOG_CRIT_NOERRNO __FILE__,__LINE__,APLOG_CRIT|APLOG_NOERRNO
296 #define FCGI_LOG_ERR_NOERRNO __FILE__,__LINE__,APLOG_ERR|APLOG_NOERRNO
297 #define FCGI_LOG_WARN_NOERRNO __FILE__,__LINE__,APLOG_WARNING|APLOG_NOERRNO
298 #define FCGI_LOG_NOTICE_NOERRNO __FILE__,__LINE__,APLOG_NOTICE|APLOG_NOERRNO
299 #define FCGI_LOG_INFO_NOERRNO __FILE__,__LINE__,APLOG_INFO|APLOG_NOERRNO
300 #define FCGI_LOG_DEBUG_NOERRNO __FILE__,__LINE__,APLOG_DEBUG|APLOG_NOERRNO
302 #ifdef FCGI_DEBUG
303 #define FCGIDBG1(a) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a);
304 #define FCGIDBG2(a,b) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b);
305 #define FCGIDBG3(a,b,c) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c);
306 #define FCGIDBG4(a,b,c,d) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d);
307 #define FCGIDBG5(a,b,c,d,e) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e);
308 #define FCGIDBG6(a,b,c,d,e,f) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e,f);
309 #define FCGIDBG7(a,b,c,d,e,f,g) ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e,f,g);
310 #else
311 #define FCGIDBG1(a)
312 #define FCGIDBG2(a,b)
313 #define FCGIDBG3(a,b,c)
314 #define FCGIDBG4(a,b,c,d)
315 #define FCGIDBG5(a,b,c,d,e)
316 #define FCGIDBG6(a,b,c,d,e,f)
317 #define FCGIDBG7(a,b,c,d,e,f,g)
318 #endif
321 * Holds the status of the sending of the environment.
322 * A quick hack to dump the static vars for the NT port.
324 typedef struct {
325 enum { PREP, HEADER, NAME, VALUE } pass;
326 char **envp;
327 int headerLen, nameLen, valueLen, totalLen;
328 char *equalPtr;
329 unsigned char headerBuff[8];
330 } env_status;
333 * fcgi_config.c
335 void *fcgi_config_create_dir_config(pool *p, char *dummy);
336 const char *fcgi_config_make_dir(pool *tp, char *path);
337 const char *fcgi_config_make_dynamic_dir(pool *p, const int wax);
338 const char *fcgi_config_new_static_server(cmd_parms *cmd, void *dummy, const char *arg);
339 const char *fcgi_config_new_external_server(cmd_parms *cmd, void *dummy, const char *arg);
340 const char *fcgi_config_set_config(cmd_parms *cmd, void *dummy, const char *arg);
341 const char *fcgi_config_set_fcgi_uid_n_gid(int set);
342 const char *fcgi_config_new_auth_server(cmd_parms * const cmd,
343 fcgi_dir_config *dir_config, const char *fs_path, const char * const compat);
344 const char *fcgi_config_set_authoritative_slot(const cmd_parms * const cmd,
345 fcgi_dir_config * const dir_config, int arg);
346 const char *fcgi_config_set_socket_dir(cmd_parms *cmd, void *dummy, char *arg);
347 const char *fcgi_config_set_wrapper(cmd_parms *cmd, void *dummy, const char *arg);
348 void fcgi_config_reset_globals(void* dummy);
349 const char *fcgi_config_set_env_var(pool *p, char **envp, unsigned int *envc, char * var);
352 * fcgi_pm.c
354 #ifdef WIN32
355 void fcgi_pm_main(void *dummy);
356 #else
357 int fcgi_pm_main(void *dummy, child_info *info);
358 #endif
361 * fcgi_protocol.c
363 void fcgi_protocol_queue_begin_request(fcgi_request *fr);
364 void fcgi_protocol_queue_client_buffer(fcgi_request *fr);
365 int fcgi_protocol_queue_env(request_rec *r, fcgi_request *fr, env_status *env);
366 int fcgi_protocol_dequeue(pool *p, fcgi_request *fr);
369 * fcgi_buf.c
371 #define BufferLength(b) ((b)->length)
372 #define BufferFree(b) ((b)->size - (b)->length)
373 #define BufferSize(b) ((b)->size)
375 void fcgi_buf_check(Buffer *bufPtr);
376 void fcgi_buf_reset(Buffer *bufPtr);
377 Buffer *fcgi_buf_new(pool *p, int size);
378 void BufferDelete(Buffer *bufPtr);
380 #ifndef WIN32
381 typedef int SOCKET;
382 #endif
384 int fcgi_buf_socket_recv(Buffer *b, SOCKET socket);
385 int fcgi_buf_socket_send(Buffer *b, SOCKET socket);
387 void fcgi_buf_added(Buffer * const b, const unsigned int len);
388 void fcgi_buf_removed(Buffer * const b, unsigned int len);
389 void fcgi_buf_get_block_info(Buffer *bufPtr, char **beginPtr, int *countPtr);
390 void fcgi_buf_toss(Buffer *bufPtr, int count);
391 void fcgi_buf_get_free_block_info(Buffer *bufPtr, char **endPtr, int *countPtr);
392 void fcgi_buf_add_update(Buffer *bufPtr, int count);
393 int fcgi_buf_add_block(Buffer *bufPtr, char *data, int datalen);
394 int fcgi_buf_add_string(Buffer *bufPtr, char *str);
395 int fcgi_buf_get_to_block(Buffer *bufPtr, char *data, int datalen);
396 void fcgi_buf_get_to_buf(Buffer *toPtr, Buffer *fromPtr, int len);
397 void fcgi_buf_get_to_array(Buffer *buf, array_header *arr, int len);
400 * fcgi_util.c
403 char *fcgi_util_socket_hash_filename(pool *p, const char *path,
404 const char *user, const char *group);
405 const char *fcgi_util_socket_make_path_absolute(pool * const p,
406 const char *const file, const int dynamic);
407 #ifndef WIN32
408 const char *fcgi_util_socket_make_domain_addr(pool *p, struct sockaddr_un **socket_addr,
409 int *socket_addr_len, const char *socket_path);
410 #endif
411 const char *fcgi_util_socket_make_inet_addr(pool *p, struct sockaddr_in **socket_addr,
412 int *socket_addr_len, const char *host, unsigned short port);
413 const char *fcgi_util_check_access(pool *tp,
414 const char * const path, const struct stat *statBuf,
415 const int mode, const uid_t uid, const gid_t gid);
416 fcgi_server *fcgi_util_fs_get_by_id(const char *ePath, uid_t uid, gid_t gid);
417 fcgi_server *fcgi_util_fs_get(const char *ePath, const char *user, const char *group);
418 const char *fcgi_util_fs_is_path_ok(pool * const p, const char * const fs_path, struct stat *finfo);
419 fcgi_server *fcgi_util_fs_new(pool *p);
420 void fcgi_util_fs_add(fcgi_server *s);
421 const char *fcgi_util_fs_set_uid_n_gid(pool *p, fcgi_server *s, uid_t uid, gid_t gid);
422 ServerProcess *fcgi_util_fs_create_procs(pool *p, int num);
424 int fcgi_util_ticks(struct timeval *);
426 #ifdef WIN32
427 int fcgi_pm_add_job(fcgi_pm_job *new_job);
428 #endif
432 * Globals
435 extern pool *fcgi_config_pool;
437 extern server_rec *fcgi_apache_main_server;
439 extern const char *fcgi_wrapper; /* wrapper path */
440 extern uid_t fcgi_user_id; /* the run uid of Apache & PM */
441 extern gid_t fcgi_group_id; /* the run gid of Apache & PM */
443 extern fcgi_server *fcgi_servers;
445 extern char *fcgi_socket_dir; /* default FastCgiIpcDir */
447 /* pipe used for comm between the request handlers and the PM */
448 extern int fcgi_pm_pipe[];
450 extern pid_t fcgi_pm_pid;
452 extern char *fcgi_dynamic_dir; /* directory for the dynamic
453 * fastcgi apps' sockets */
455 extern char *fcgi_empty_env;
457 extern int fcgi_dynamic_total_proc_count;
458 extern time_t fcgi_dynamic_epoch;
459 extern time_t fcgi_dynamic_last_analyzed;
461 #ifdef WIN32
462 extern HANDLE *fcgi_dynamic_mbox_mutex;
463 extern HANDLE fcgi_event_handles[3];
464 extern fcgi_pm_job *fcgi_dynamic_mbox;
465 #endif
467 extern u_int dynamicMaxProcs;
468 extern int dynamicMinProcs;
469 extern int dynamicMaxClassProcs;
470 extern u_int dynamicKillInterval;
471 extern u_int dynamicUpdateInterval;
472 extern float dynamicGain;
473 extern int dynamicThreshold1;
474 extern int dynamicThresholdN;
475 extern u_int dynamicPleaseStartDelay;
476 extern u_int dynamicAppConnectTimeout;
477 extern char **dynamicEnvp;
478 extern u_int dynamicProcessSlack;
479 extern int dynamicAutoRestart;
480 extern int dynamicAutoUpdate;
481 extern u_int dynamicListenQueueDepth;
482 extern u_int dynamicInitStartDelay;
483 extern u_int dynamicRestartDelay;
484 extern array_header *dynamic_pass_headers;
485 extern u_int dynamic_idle_timeout;
486 extern int dynamicFlush;
488 extern module MODULE_VAR_EXPORT fastcgi_module;
490 #endif /* FCGI_H */