PyFCGI now handles fcgi socket creation
Add a -l --listen option to set the socket path or address:port Fix a bug using thread safe functions from libfcgi
This commit is contained in:
parent
d1eaf6979f
commit
f685f83369
7 changed files with 70 additions and 11 deletions
6
README
6
README
|
|
@ -9,10 +9,10 @@ Building & running pyfcgi :
|
|||
$ ./configure
|
||||
$ make
|
||||
# To run foo_pep333.entrypoint() PEP333 application
|
||||
$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo_pep333 -E entrypoint
|
||||
$ src/pyfcgi -l '127.0.0.1:9000' -S -e foo_pep333 -E entrypoint
|
||||
or
|
||||
# To run foo.entrypoint() sending to FCGI python stdout
|
||||
$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo -E entrypoint -A
|
||||
$ src/pyfcgi -l '127.0.0.1:9000' -S -e foo -E entrypoint -A
|
||||
|
||||
|
||||
configure script determine python flags, libs & includes paths using
|
||||
|
|
@ -23,7 +23,7 @@ Example : linking against a debug build of python :
|
|||
---------
|
||||
$ ./configure PYTHON_CONFIG_PATH=/usr/bin/python3dm-config --enable-debug
|
||||
$ make clean && make
|
||||
$ valgrind --log-file=/tmp/val.log --trace-children=yes spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo_pep333 -E entrypoint -L '/tmp/foo.log;0xff;{datetime} {msg} {ident}'
|
||||
$ valgrind --log-file=/tmp/val.log --trace-children=yes src/pyfcgi -S -e foo_pep333 -E entrypoint -L '/tmp/foo.log;0xff;{datetime} {msg} {ident}'
|
||||
|
||||
logging to file example :
|
||||
-------------------------
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.TH "pyfcgi" 1 "Sat Aug 24 2019" "Version 0.0.1" "PyFCGI" \" -*- nroff -*-
|
||||
.TH "pyfcgi" 1 "Mon Oct 28 2019" "Version 0.0.1" "PyFCGI" \" -*- nroff -*-
|
||||
.ad l
|
||||
.nh
|
||||
.SH NAME
|
||||
|
|
@ -24,11 +24,16 @@ Display help and exit
|
|||
Display pyfcgi and Python version and exit
|
||||
.RE
|
||||
.PP
|
||||
\fB-c --config=FILE\fP
|
||||
\fB-C --config=FILE\fP
|
||||
.RS 4
|
||||
load a configuration file
|
||||
.RE
|
||||
.PP
|
||||
\fB-l --listen=SOCK_PATH\fP
|
||||
.RS 4
|
||||
fcgi listen socket path\&. For TCP socket use 'IPv4:PORT' syntax ( '127\&.0\&.0\&.1:9000' by default)
|
||||
.RE
|
||||
.PP
|
||||
\fB-e --pymodule=MODULE_NAME\fP
|
||||
.RS 4
|
||||
python entrypoint module name
|
||||
|
|
@ -134,11 +139,11 @@ unix with HOST a valid PATH
|
|||
.PP
|
||||
To run foo_pep333\&.entrypoint() PEP333 application :
|
||||
.PP
|
||||
spawn-fcgi -d \&. -n -p 9000 -a 127\&.0\&.0\&.1 -- src/pyfcgi -S \\ -e foo_pep333 -E entrypoint
|
||||
spawn-fcgi -d \&. -n -p 9000 -a 127\&.0\&.0\&.1 -- src/pyfcgi -S -e foo_pep333 -E entrypoint
|
||||
.PP
|
||||
Logfile example :
|
||||
.PP
|
||||
spawn-fcgi -d \&. -n -p 9000 -a 127\&.0\&.0\&.1 -- src/pyfcgi -S \\ -e foo_pep333 -E entrypoint \\ -L '/tmp/foo\&.log;0xff;{datetime} {msg} {ident}'
|
||||
spawn-fcgi -d \&. -n -p 9000 -a 127\&.0\&.0\&.1 -- src/pyfcgi -S -e foo_pep333 -E entrypoint -L '/tmp/foo\&.log;0xff;{datetime} {msg} {ident}'
|
||||
.SH "AUTHOR"
|
||||
.PP
|
||||
Written by Yann Weber <yann.weber@member.fsf.org>
|
||||
|
|
|
|||
|
|
@ -74,12 +74,16 @@ pyfcgi_conf_t PyFCGI_conf;
|
|||
/**@ingroup ret_status */
|
||||
#define PYFCGI_FATAL 128
|
||||
|
||||
/**@brief Backlog argument for socket creation */
|
||||
#define PYFCGI_SOCK_BACKLOG 100
|
||||
|
||||
#define PYFCGI_NAME "spawn-fcgi [OPTIONS] -- pyfcgi"
|
||||
|
||||
#define PYFCGI_SHORT_OPT "Ce:E:Aw:W:m:ft:L:SPs:vVh"
|
||||
#define PYFCGI_SHORT_OPT "C:l:e:E:Aw:W:m:ft:L:SPs:vVh"
|
||||
|
||||
#define PYFCGI_LONG_OPT { \
|
||||
{"config", required_argument, 0, 'C'},\
|
||||
{"listen", required_argument, 0, 'l'},\
|
||||
{"pymodule", required_argument, 0, 'e'},\
|
||||
{"pyapp", required_argument, 0, 'E'},\
|
||||
{"alt-io", no_argument, 0, 'A'},\
|
||||
|
|
@ -100,6 +104,7 @@ pyfcgi_conf_t PyFCGI_conf;
|
|||
|
||||
#define PYFCGI_OPT_HELP {\
|
||||
{"Load options from configuration file", "CONFIG"},\
|
||||
{"Listen socket path (a path for UNIX socket or a 'IPV4:PORT' string)", "SOCK_PATH"},\
|
||||
{"Search application function in given python module", "MODULE_NAME"},\
|
||||
{"Python application entrypoint function name", "FUNC_NAME"},\
|
||||
{"Use stdout to communicate with web server instead of entrypoint return as specified in PEP 333", NULL},\
|
||||
|
|
@ -176,6 +181,12 @@ struct pyfcgi_context_s {
|
|||
/**@brief Stores parent process PID */
|
||||
pid_t ppid;
|
||||
|
||||
/**@brief Returned by FCGX_OpenSocket for responder process */
|
||||
int fcgi_socket;
|
||||
|
||||
/**@brief Request information (local to each worker) */
|
||||
FCGX_Request fcgi_request;
|
||||
|
||||
/**@brief Stores the watchdog timer */
|
||||
timer_t wd_timer;
|
||||
/**@brief Security timer sending a sigkill */
|
||||
|
|
@ -215,6 +226,10 @@ struct pyfcgi_conf_s
|
|||
/** @brief Stores pidfile path */
|
||||
char *pidfile;
|
||||
|
||||
/**@brief Stores the socket path argument
|
||||
* @ingroup conf_glob
|
||||
* Can be a file path for a UNIX socket or IPv4:PORT string */
|
||||
char *sock_path;
|
||||
/**@brief Entrypoint module name
|
||||
* @ingroup conf_glob */
|
||||
char *py_entrymod;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ void print_version(int fd)
|
|||
void default_conf()
|
||||
{
|
||||
memset(&PyFCGI_conf, 0, sizeof(pyfcgi_conf_t));
|
||||
PyFCGI_conf.sock_path = "127.0.0.1:9000";
|
||||
PyFCGI_conf.context.pid = getpid();
|
||||
PyFCGI_conf.min_wrk = 1;
|
||||
PyFCGI_conf.max_wrk = 5;
|
||||
|
|
@ -72,6 +73,9 @@ int parse_args(int argc, char *argv[])
|
|||
case 'C':
|
||||
dprintf(2, "Config parser not yet implemented :'(\n");
|
||||
exit(1);
|
||||
case 'l':
|
||||
PyFCGI_conf.sock_path = strdup(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
PyFCGI_conf.py_entrymod = strdup(optarg);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -362,8 +362,11 @@ if ($programname contains 'pyfcgi') then {
|
|||
* Display help and exit
|
||||
* @par -V --version
|
||||
* Display pyfcgi and Python version and exit
|
||||
* @par -c --config=FILE
|
||||
* @par -C --config=FILE
|
||||
* load a configuration file
|
||||
* @par -l --listen=SOCK_PATH
|
||||
* fcgi listen socket path. For TCP socket use "IPv4:PORT" syntax (
|
||||
* "127.0.0.1:9000" by default)
|
||||
* @par -e --pymodule=MODULE_NAME
|
||||
* python entrypoint module name
|
||||
* @par -E --pyapp=FUNC_NAME
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ int work333(int wrk_id)
|
|||
int count, pipe_out[2], pipe_err[2];
|
||||
int max_reqs;
|
||||
struct timeval start, stop;
|
||||
FCGX_Request *request;
|
||||
|
||||
max_reqs = PyFCGI_conf.max_reqs;
|
||||
|
||||
|
|
@ -72,13 +73,28 @@ int work333(int wrk_id)
|
|||
|
||||
start_response = get_start_response();
|
||||
|
||||
// Initialise FCGI request
|
||||
request = &(PyFCGI_conf.context.fcgi_request);
|
||||
if(FCGX_InitRequest(request, PyFCGI_conf.context.fcgi_socket,
|
||||
FCGI_FAIL_ACCEPT_ON_INTR) == -1)
|
||||
{
|
||||
pyfcgi_log(LOG_ALERT, "Unable to init FCGI request");
|
||||
exit(PYFCGI_FATAL);
|
||||
}
|
||||
|
||||
_worker_idle = 0;
|
||||
worker_set_idle();
|
||||
// requests accepting loop
|
||||
count = 0;
|
||||
while ((!count || count != max_reqs) &&
|
||||
FCGX_Accept(&in_stream, &out_stream, &err_stream, &envp) >= 0)
|
||||
FCGX_Accept_r(request) == 0)
|
||||
{
|
||||
|
||||
in_stream = request->in;
|
||||
out_stream = request->out;
|
||||
err_stream = request->err;
|
||||
envp = request->envp;
|
||||
|
||||
pyfcgi_wd_arm();
|
||||
sem_post(PyFCGI_SEM(SEM_WREQS).sem); // increment request counter discarding OF
|
||||
gettimeofday(&start, NULL);
|
||||
|
|
@ -136,7 +152,7 @@ int work333(int wrk_id)
|
|||
FCGX_FClose(out_stream);
|
||||
FCGX_FClose(in_stream);
|
||||
FCGX_FClose(err_stream);
|
||||
FCGI_Finish();
|
||||
FCGX_Finish_r(request);
|
||||
|
||||
gettimeofday(&stop, NULL);
|
||||
stop.tv_sec = stop.tv_sec - start.tv_sec;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,22 @@ void init_context()
|
|||
}
|
||||
bzero(PyFCGI_conf.context.wrk_pids,
|
||||
sizeof(pid_t) * (PyFCGI_conf.max_wrk + 1));
|
||||
|
||||
// Open FCGI listen socket
|
||||
PyFCGI_conf.context.fcgi_socket = FCGX_OpenSocket(PyFCGI_conf.sock_path,
|
||||
PYFCGI_SOCK_BACKLOG);
|
||||
if(PyFCGI_conf.context.fcgi_socket == -1)
|
||||
{
|
||||
pyfcgi_log(LOG_ALERT, "Unable to open socket : '%s'",
|
||||
PyFCGI_conf.sock_path);
|
||||
clean_exit(PYFCGI_FATAL);
|
||||
}
|
||||
if(FCGX_Init() != 0)
|
||||
{
|
||||
pyfcgi_log(LOG_ALERT, "Unable to init libfcgi");
|
||||
clean_exit(PYFCGI_FATAL);
|
||||
}
|
||||
pyfcgi_log(LOG_INFO, "Listening on %s", PyFCGI_conf.sock_path);
|
||||
}
|
||||
|
||||
int responder_loop()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue