#ifndef _FCGI_CGI_FASTCGI_H #define _FCGI_CGI_FASTCGI_H /* NO multiplexing support */ /* Keep fastcgi.* independent */ #include #include /* FastCGI constants */ # define FCGI_VERSION_1 1 # define FCGI_HEADER_LEN 8 enum FCGI_Type { FCGI_BEGIN_REQUEST = 1, FCGI_ABORT_REQUEST = 2, FCGI_END_REQUEST = 3, FCGI_PARAMS = 4, FCGI_STDIN = 5, FCGI_STDOUT = 6, FCGI_STDERR = 7, FCGI_DATA = 8, FCGI_GET_VALUES = 9, FCGI_GET_VALUES_RESULT = 10, FCGI_UNKNOWN_TYPE = 11 }; # define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE) enum FCGI_Flags { FCGI_KEEP_CONN = 1 }; enum FCGI_Role { FCGI_RESPONDER = 1, FCGI_AUTHORIZER = 2, FCGI_FILTER = 3 }; enum FCGI_ProtocolStatus { FCGI_REQUEST_COMPLETE = 0, FCGI_CANT_MPX_CONN = 1, FCGI_OVERLOADED = 2, FCGI_UNKNOWN_ROLE = 3 }; #define FASTCGI_MAX_KEYLEN 1024 #define FASTCGI_MAX_VALUELEN 64*1024 /* end FastCGI constants */ struct fastcgi_server; typedef struct fastcgi_server fastcgi_server; struct fastcgi_callbacks; typedef struct fastcgi_callbacks fastcgi_callbacks; struct fastcgi_connection; typedef struct fastcgi_connection fastcgi_connection; struct fastcgi_queue; typedef struct fastcgi_queue fastcgi_queue; struct fastcgi_server { /* custom user data */ gpointer data; /* private data */ gboolean do_shutdown; const fastcgi_callbacks *callbacks; guint max_connections; GPtrArray *connections; guint cur_requests; gint fd; struct ev_loop *loop; ev_io fd_watcher; ev_prepare closing_watcher; }; struct fastcgi_callbacks { void (*cb_new_connection)(fastcgi_connection *fcon); /* new connection accepted */ void (*cb_new_request)(fastcgi_connection *fcon); /* new request on connection, env/params are ready */ void (*cb_wrote_data)(fastcgi_connection *fcon); void (*cb_received_stdin)(fastcgi_connection *fcon, GByteArray *data); /* data == NULL => eof */ void (*cb_received_data)(fastcgi_connection *fcon, GByteArray *data); /* data == NULL => eof */ void (*cb_request_aborted)(fastcgi_connection *fcon); void (*cb_reset_connection)(fastcgi_connection *fcon); /* cleanup custom data before fcon is freed, not for keep-alive */ }; struct fastcgi_queue { GQueue queue; gsize offset; /* offset in first chunk */ gsize length; gboolean closed; }; struct fastcgi_connection { /* custom user data */ gpointer data; /* read/write */ GPtrArray *environ; /* read only */ fastcgi_server *fsrv; guint fcon_id; /* index in server con array */ gboolean closing; /* "dead" connection */ /* current request */ guint16 requestID; guint16 role; guint8 flags; /* private data */ unsigned char headerbuf[8]; guint headerbuf_used; gboolean first; struct { guint8 version; guint8 type; guint16 requestID; guint16 contentLength; guint8 paddingLength; } current_header; guint content_remaining, padding_remaining; GByteArray *buffer, *parambuf; gint fd; ev_io fd_watcher; gboolean read_suspended; /* write queue */ fastcgi_queue write_queue; }; fastcgi_server *fastcgi_server_create(struct ev_loop *loop, gint socketfd, const fastcgi_callbacks *callbacks, guint max_connections); void fastcgi_server_stop(fastcgi_server *fsrv); /* stop accepting new connections, closes listening socket */ void fastcgi_server_free(fastcgi_server *fsrv); void fastcgi_suspend_read(fastcgi_connection *fcon); void fastcgi_resume_read(fastcgi_connection *fcon); void fastcgi_end_request(fastcgi_connection *fcon, gint32 appStatus, enum FCGI_ProtocolStatus status); void fastcgi_send_out(fastcgi_connection *fcon, GString *data); void fastcgi_send_err(fastcgi_connection *fcon, GString *data); void fastcgi_send_out_bytearray(fastcgi_connection *fcon, GByteArray *data); void fastcgi_send_err_bytearray(fastcgi_connection *fcon, GByteArray *data); void fastcgi_connection_close(fastcgi_connection *fcon); /* shouldn't be needed */ void fastcgi_connection_environ_clear(fastcgi_connection *fcon); const gchar* fastcgi_connection_environ_lookup(fastcgi_connection *fcon, const gchar* key, gsize keylen); void fastcgi_queue_append_string(fastcgi_queue *queue, GString *buf); void fastcgi_queue_append_bytearray(fastcgi_queue *queue, GByteArray *buf); void fastcgi_queue_clear(fastcgi_queue *queue); /* return values: 0 ok, -1 error, -2 con closed */ gint fastcgi_queue_write(int fd, fastcgi_queue *queue, gsize max_write); #endif