Deleted loglines, updated README + add check on FCGX_PutStr calls

This commit is contained in:
Yann Weber 2019-08-04 11:36:26 +02:00
commit de7269f833
4 changed files with 69 additions and 41 deletions

24
README
View file

@ -8,17 +8,23 @@ Building & running pyfcgi :
$ ./autogen.sh $ ./autogen.sh
$ ./configure $ ./configure
$ make $ make
# To run foo_pep333.entrypoint() PEP333 application
$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo -E entrypoint -A
or
$ 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
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
configure script determine python flags, libs & includes paths using
python3-config programm. The path can be specified using the
PYTHON_CONFIG_PATH environment variable.
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}'
logging to file example : logging to file example :
------------------------- -------------------------
-L '/tmp/foo.log;0xff;{datetime} {msg} {ident}' -L '/tmp/foo.log;0xff;{datetime} {msg} {ident}'
Debugging :
-----------
$ ./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}'

View file

@ -72,6 +72,7 @@ struct libpyfcgi_context_s
size_t heads_buf_sz; size_t heads_buf_sz;
/**@brief Persistent buffer for PEP333 status */ /**@brief Persistent buffer for PEP333 status */
char status_buf[LIBPYFCGI_STATUS_SZ]; char status_buf[LIBPYFCGI_STATUS_SZ];
size_t rep_sz;
}; };
typedef struct libpyfcgi_context_s libpyfcgi_context_t; typedef struct libpyfcgi_context_s libpyfcgi_context_t;
@ -91,6 +92,7 @@ inline void libpyfcgi_clean_response()
if(libpyfcgi.headers) { Py_DECREF(libpyfcgi.headers); } if(libpyfcgi.headers) { Py_DECREF(libpyfcgi.headers); }
libpyfcgi.headers = NULL; libpyfcgi.headers = NULL;
libpyfcgi.headers_sent = 0; libpyfcgi.headers_sent = 0;
libpyfcgi.rep_sz = 0;
} }
/**@brief Send headers stored in @ref libpyfcgi context /**@brief Send headers stored in @ref libpyfcgi context

View file

@ -123,12 +123,6 @@ void libpyfcgi_set_headers_buf()
return; return;
} }
repr = PyObject_ASCII(libpyfcgi.headers);
Py_INCREF(repr);
pyfcgi_log(LOG_DEBUG, "Sending headers : '%s'", PyUnicode_AsUTF8(repr));
Py_DECREF(repr);
heads_iter = PyObject_GetIter(libpyfcgi.headers); heads_iter = PyObject_GetIter(libpyfcgi.headers);
if(!heads_iter) if(!heads_iter)
{ {
@ -257,6 +251,9 @@ head_decode_err:
void libpyfcgi_send_headers() void libpyfcgi_send_headers()
{ {
size_t sz;
int ret;
if(!libpyfcgi.out) if(!libpyfcgi.out)
{ {
// invalid context // invalid context
@ -279,11 +276,20 @@ void libpyfcgi_send_headers()
log_expt(LOG_ALERT); log_expt(LOG_ALERT);
exit(PYFCGI_FATAL); exit(PYFCGI_FATAL);
} }
pyfcgi_log(LOG_DEBUG, "Headers ready to be sent : '%s'", libpyfcgi.heads_buf); sz = strlen(libpyfcgi.heads_buf);
FCGX_PutStr(libpyfcgi.heads_buf, strlen(libpyfcgi.heads_buf), ret = FCGX_PutStr(libpyfcgi.heads_buf, sz, libpyfcgi.out);
libpyfcgi.out); if(ret < 0 )
pyfcgi_log(LOG_DEBUG, "Headers sent..."); {
FCGX_PutStr("\r\n", 2, libpyfcgi.out); pyfcgi_log(LOG_ERR, "Unable to send headers");
return;
}
libpyfcgi.rep_sz += ret;
ret = FCGX_PutStr("\r\n", 2, libpyfcgi.out);
if(ret < 0)
{
pyfcgi_log(LOG_ALERT, "Unable to send last \r\n from headers !");
}
libpyfcgi.rep_sz += ret;
libpyfcgi.headers_sent = 1; libpyfcgi.headers_sent = 1;
} }
@ -297,6 +303,7 @@ PyInit_libpyfcgi(void)
// init module & globals // init module & globals
libpyfcgi.status = NULL; libpyfcgi.status = NULL;
libpyfcgi.headers = NULL; libpyfcgi.headers = NULL;
libpyfcgi.rep_sz = 0;
libpyfcgi.self = PyModule_Create(&pyfcgimodule); libpyfcgi.self = PyModule_Create(&pyfcgimodule);
if(libpyfcgi.self == NULL) { return NULL; } if(libpyfcgi.self == NULL) { return NULL; }
return libpyfcgi.self; return libpyfcgi.self;
@ -336,10 +343,6 @@ PyObject* pyfcgi_start_response(PyObject* self, PyObject** argv, Py_ssize_t argc
exc_info */ exc_info */
} }
PyObject *repr = PyObject_ASCII(libpyfcgi.headers);
pyfcgi_log(LOG_DEBUG, "start_response called, headers : '%s'", PyUnicode_AsUTF8(repr));
Py_DECREF(repr);
return PyObject_GetAttrString(self, "write_body"); return PyObject_GetAttrString(self, "write_body");
} }
@ -347,7 +350,6 @@ PyObject* pyfcgi_write_body(PyObject* self, PyObject** argv, Py_ssize_t argc)
{ {
char err[128]; char err[128];
pyfcgi_log(LOG_DEBUG, "Write body called...");
if(argc != 1) if(argc != 1)
{ {
snprintf(err, 128, snprintf(err, 128,
@ -366,6 +368,7 @@ PyObject* _pyfcgi_write_body(PyObject *body_data)
const char *dat; const char *dat;
PyObject *bytes, *cur, *iter, *repr; PyObject *bytes, *cur, *iter, *repr;
Py_ssize_t sz; Py_ssize_t sz;
int ret;
if(!libpyfcgi.out) if(!libpyfcgi.out)
@ -397,7 +400,6 @@ PyObject* _pyfcgi_write_body(PyObject *body_data)
{ {
Py_INCREF(iter); Py_INCREF(iter);
cur = PyIter_Next(iter); cur = PyIter_Next(iter);
pyfcgi_log(LOG_DEBUG, "Got iter for writing body...");
} }
if(!cur) if(!cur)
@ -409,7 +411,7 @@ pyfcgi_log(LOG_DEBUG, "Got iter for writing body...");
// if headers not sent yet, send them.... // if headers not sent yet, send them....
if(!libpyfcgi.headers_sent) if(!libpyfcgi.headers_sent)
{ {
pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them..."); pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them...");
libpyfcgi_send_headers(); libpyfcgi_send_headers();
} }
@ -422,13 +424,14 @@ pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them...");
dat = PyUnicode_AsUTF8AndSize(cur, &sz); dat = PyUnicode_AsUTF8AndSize(cur, &sz);
if(!dat) if(!dat)
{ {
if(PyErr_Occurred()) { goto err_clean; }
repr = PyObject_ASCII(cur); repr = PyObject_ASCII(cur);
snprintf(err, 128, snprintf(err, 128,
"libpyfcgi.__write_body unable to encode string as UTF-8 : %s", "libpyfcgi.__write_body unable to encode string as UTF-8 : %s",
PyUnicode_AsUTF8(repr)); PyUnicode_AsUTF8(repr));
Py_DECREF(repr); Py_DECREF(repr);
PyErr_SetString(PyExc_ValueError, err); PyErr_SetString(PyExc_ValueError, err);
Py_RETURN_NONE; goto err_clean;
} }
} }
else if(PyBytes_Check(cur)) else if(PyBytes_Check(cur))
@ -436,8 +439,12 @@ pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them...");
dat = PyBytes_AsString(cur); dat = PyBytes_AsString(cur);
if(!dat) if(!dat)
{ {
/**@todo if no expt set, set error str */ if(PyErr_Occurred()) { goto err_clean; }
Py_RETURN_NONE;
snprintf(err, 128,
"Unable to get bytes buffer when sending body data");
PyErr_SetString(PyExc_ValueError, err);
goto err_clean;
} }
sz = PyBytes_GET_SIZE(cur); sz = PyBytes_GET_SIZE(cur);
} }
@ -446,25 +453,36 @@ pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them...");
bytes = PyObject_Bytes(cur); bytes = PyObject_Bytes(cur);
if(!bytes) if(!bytes)
{ {
if(PyErr_Occurred()) { goto err_clean; }
repr = PyObject_ASCII(cur); repr = PyObject_ASCII(cur);
snprintf(err, 128, snprintf(err, 128,
"libpyfcgi.__write_body expected str or bytes but %s given", "libpyfcgi.__write_body expected str or bytes but %s given",
PyUnicode_AsUTF8(repr)); PyUnicode_AsUTF8(repr));
Py_DECREF(repr); Py_DECREF(repr);
PyErr_SetString(PyExc_ValueError, err); PyErr_SetString(PyExc_ValueError, err);
Py_RETURN_NONE; goto err_clean;
} }
dat = PyBytes_AsString(cur); dat = PyBytes_AsString(cur);
if(!dat) if(!dat)
{ {
/**@todo if no expt set, set error str */ if(PyErr_Occurred()) { goto err_clean; }
Py_RETURN_NONE;
snprintf(err, 128,
"Unable to get bytes buffer when sending body data");
PyErr_SetString(PyExc_ValueError, err);
goto err_clean;
} }
sz = PyBytes_GET_SIZE(cur); sz = PyBytes_GET_SIZE(cur);
} }
pyfcgi_log(LOG_DEBUG, "Sending '%s'", dat); ret = FCGX_PutStr(dat, sz, libpyfcgi.out);
FCGX_PutStr(dat, sz, libpyfcgi.out); if(ret < 0)
{
pyfcgi_log(LOG_ALERT, "Unable to send reply");
goto err_clean;
}
libpyfcgi.rep_sz += ret;
if(bytes) { Py_DECREF(bytes); } if(bytes) { Py_DECREF(bytes); }
Py_DECREF(cur); Py_DECREF(cur);
@ -475,4 +493,10 @@ pyfcgi_log(LOG_DEBUG, "Sending '%s'", dat);
Py_DECREF(iter); Py_DECREF(iter);
} }
Py_RETURN_NONE; Py_RETURN_NONE;
err_clean:
if(bytes) { Py_DECREF(bytes); }
Py_DECREF(cur);
if(iter) { Py_DECREF(iter); }
Py_RETURN_NONE;
} }

View file

@ -85,14 +85,12 @@ int work333(int wrk_id, int semid)
{ {
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
worker_set_busy(semid); worker_set_busy(semid);
pyfcgi_log(LOG_DEBUG, "Working !!");
count++; count++;
environ = update_pyenv(py_osmod, envp); environ = update_pyenv(py_osmod, envp);
libpyfcgi_clean_response(); libpyfcgi_clean_response();
libpyfcgi.out = out_stream; libpyfcgi.out = out_stream;
args = Py_BuildValue("OO", environ, start_response); args = Py_BuildValue("OO", environ, start_response);
pyfcgi_log(LOG_DEBUG, "Calling entrypoint :D");
entry_ret = PyObject_CallObject(entry_fun, args); entry_ret = PyObject_CallObject(entry_fun, args);
Py_INCREF(entry_ret); Py_INCREF(entry_ret);
@ -102,13 +100,11 @@ pyfcgi_log(LOG_DEBUG, "Calling entrypoint :D");
} }
// able to process returned value // able to process returned value
// Simulate python call of libpyfcgi.write_body() // Simulate python call of libpyfcgi.write_body()
pyfcgi_log(LOG_DEBUG, "Writing body !");
_pyfcgi_write_body(entry_ret); _pyfcgi_write_body(entry_ret);
if(PyErr_Occurred()) if(PyErr_Occurred())
{ {
log_expt(LOG_ERR); log_expt(LOG_ERR);
} }
pyfcgi_log(LOG_DEBUG, "Cleaning...");
// clean stuffs // clean stuffs
Py_DECREF(args); Py_DECREF(args);
@ -131,8 +127,8 @@ pyfcgi_log(LOG_DEBUG, "Cleaning...");
stop.tv_usec += 1000000; stop.tv_usec += 1000000;
stop.tv_sec -= 1; stop.tv_sec -= 1;
} }
pyfcgi_log(LOG_DEBUG, "Worker[%d] request %d END [OK] in %ld.%06lds", pyfcgi_log(LOG_DEBUG, "Worker[%d] request %d END [OK] %lu bytes in %ld.%06lds",
wrk_id, count, stop.tv_sec, stop.tv_usec); wrk_id, count, libpyfcgi.rep_sz, stop.tv_sec, stop.tv_usec);
} }
return 0; return 0;
} }