Browse Source

Deleted loglines, updated README + add check on FCGX_PutStr calls

Yann Weber 5 years ago
parent
commit
de7269f833
4 changed files with 68 additions and 40 deletions
  1. 14
    8
      README
  2. 2
    0
      include/python_pyfcgi.h
  3. 50
    26
      src/python_pyfcgi.c
  4. 2
    6
      src/pyworker.c

+ 14
- 8
README View File

8
 	$ ./autogen.sh
8
 	$ ./autogen.sh
9
 	$ ./configure
9
 	$ ./configure
10
 	$ make
10
 	$ make
11
-
12
-	$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo -E entrypoint -A
13
-or
11
+	# To run foo_pep333.entrypoint() PEP333 application
14
 	$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo_pep333 -E entrypoint
12
 	$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo_pep333 -E entrypoint
13
+or
14
+	# To run foo.entrypoint() sending to FCGI python stdout
15
+	$ spawn-fcgi -d . -n -p 9000 -a 127.0.0.1 -- src/pyfcgi -S -e foo -E entrypoint -A
15
 
16
 
16
-logging to file example :
17
--------------------------
18
--L '/tmp/foo.log;0xff;{datetime} {msg} {ident}'
19
 
17
 
20
-Debugging :
21
------------
18
+configure script determine python flags, libs & includes paths using
19
+python3-config programm. The path can be specified using the
20
+PYTHON_CONFIG_PATH environment variable.
21
+
22
+Example : linking against a debug build of python :
23
+---------
22
 	$ ./configure PYTHON_CONFIG_PATH=/usr/bin/python3dm-config --enable-debug
24
 	$ ./configure PYTHON_CONFIG_PATH=/usr/bin/python3dm-config --enable-debug
23
 	$ make clean && make
25
 	$ make clean && make
24
 	$ 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}'
26
 	$ 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}'
27
+
28
+logging to file example :
29
+-------------------------
30
+-L '/tmp/foo.log;0xff;{datetime} {msg} {ident}'

+ 2
- 0
include/python_pyfcgi.h View File

72
 	size_t heads_buf_sz;
72
 	size_t heads_buf_sz;
73
 	/**@brief Persistent buffer for PEP333 status */
73
 	/**@brief Persistent buffer for PEP333 status */
74
 	char status_buf[LIBPYFCGI_STATUS_SZ];
74
 	char status_buf[LIBPYFCGI_STATUS_SZ];
75
+	size_t rep_sz;
75
 };
76
 };
76
 
77
 
77
 typedef struct libpyfcgi_context_s libpyfcgi_context_t;
78
 typedef struct libpyfcgi_context_s libpyfcgi_context_t;
91
 	if(libpyfcgi.headers) { Py_DECREF(libpyfcgi.headers); }
92
 	if(libpyfcgi.headers) { Py_DECREF(libpyfcgi.headers); }
92
 	libpyfcgi.headers = NULL;
93
 	libpyfcgi.headers = NULL;
93
 	libpyfcgi.headers_sent = 0;
94
 	libpyfcgi.headers_sent = 0;
95
+	libpyfcgi.rep_sz = 0;
94
 }
96
 }
95
 
97
 
96
 /**@brief Send headers stored in @ref libpyfcgi context
98
 /**@brief Send headers stored in @ref libpyfcgi context

+ 50
- 26
src/python_pyfcgi.c View File

123
 		return;
123
 		return;
124
 	}
124
 	}
125
 
125
 
126
-repr = PyObject_ASCII(libpyfcgi.headers);
127
-Py_INCREF(repr);
128
-pyfcgi_log(LOG_DEBUG, "Sending headers : '%s'", PyUnicode_AsUTF8(repr));
129
-Py_DECREF(repr);
130
-
131
-
132
 	heads_iter = PyObject_GetIter(libpyfcgi.headers);
126
 	heads_iter = PyObject_GetIter(libpyfcgi.headers);
133
 	if(!heads_iter)
127
 	if(!heads_iter)
134
 	{
128
 	{
257
 
251
 
258
 void libpyfcgi_send_headers()
252
 void libpyfcgi_send_headers()
259
 {
253
 {
254
+	size_t sz;
255
+	int ret;
256
+
260
 	if(!libpyfcgi.out)
257
 	if(!libpyfcgi.out)
261
 	{
258
 	{
262
 		// invalid context
259
 		// invalid context
279
 		log_expt(LOG_ALERT);
276
 		log_expt(LOG_ALERT);
280
 		exit(PYFCGI_FATAL);
277
 		exit(PYFCGI_FATAL);
281
 	}
278
 	}
282
-pyfcgi_log(LOG_DEBUG, "Headers ready to be sent : '%s'", libpyfcgi.heads_buf);
283
-	FCGX_PutStr(libpyfcgi.heads_buf, strlen(libpyfcgi.heads_buf),
284
-		libpyfcgi.out);
285
-pyfcgi_log(LOG_DEBUG, "Headers sent...");
286
-	FCGX_PutStr("\r\n", 2, libpyfcgi.out);
279
+	sz = strlen(libpyfcgi.heads_buf);
280
+	ret = FCGX_PutStr(libpyfcgi.heads_buf, sz, libpyfcgi.out);
281
+	if(ret < 0 )
282
+	{
283
+		pyfcgi_log(LOG_ERR, "Unable to send headers");
284
+		return;
285
+	}
286
+	libpyfcgi.rep_sz += ret;
287
+	ret = FCGX_PutStr("\r\n", 2, libpyfcgi.out);
288
+	if(ret < 0)
289
+	{
290
+		pyfcgi_log(LOG_ALERT, "Unable to send last \r\n from headers !");
291
+	}
292
+	libpyfcgi.rep_sz += ret;
287
 	libpyfcgi.headers_sent = 1;
293
 	libpyfcgi.headers_sent = 1;
288
 }
294
 }
289
 
295
 
297
 	// init module & globals
303
 	// init module & globals
298
 	libpyfcgi.status = NULL;
304
 	libpyfcgi.status = NULL;
299
 	libpyfcgi.headers = NULL;
305
 	libpyfcgi.headers = NULL;
306
+	libpyfcgi.rep_sz = 0;
300
 	libpyfcgi.self = PyModule_Create(&pyfcgimodule);
307
 	libpyfcgi.self = PyModule_Create(&pyfcgimodule);
301
 	if(libpyfcgi.self == NULL) { return NULL; }
308
 	if(libpyfcgi.self == NULL) { return NULL; }
302
 	return libpyfcgi.self;
309
 	return libpyfcgi.self;
336
 		   exc_info */
343
 		   exc_info */
337
 	}
344
 	}
338
 
345
 
339
-PyObject *repr = PyObject_ASCII(libpyfcgi.headers);
340
-pyfcgi_log(LOG_DEBUG, "start_response called, headers : '%s'", PyUnicode_AsUTF8(repr));
341
-Py_DECREF(repr);
342
-
343
 	return PyObject_GetAttrString(self, "write_body");
346
 	return PyObject_GetAttrString(self, "write_body");
344
 }
347
 }
345
 
348
 
347
 {
350
 {
348
 	char err[128];
351
 	char err[128];
349
 
352
 
350
-pyfcgi_log(LOG_DEBUG, "Write body called...");
351
 	if(argc != 1)
353
 	if(argc != 1)
352
 	{
354
 	{
353
 		snprintf(err, 128,
355
 		snprintf(err, 128,
366
 	const char *dat;
368
 	const char *dat;
367
 	PyObject *bytes, *cur, *iter, *repr;
369
 	PyObject *bytes, *cur, *iter, *repr;
368
 	Py_ssize_t sz;
370
 	Py_ssize_t sz;
371
+	int ret;
369
 
372
 
370
 
373
 
371
 	if(!libpyfcgi.out)
374
 	if(!libpyfcgi.out)
397
 	{
400
 	{
398
 		Py_INCREF(iter);
401
 		Py_INCREF(iter);
399
 		cur = PyIter_Next(iter);
402
 		cur = PyIter_Next(iter);
400
-pyfcgi_log(LOG_DEBUG, "Got iter for writing body...");
401
 	}
403
 	}
402
 
404
 
403
 	if(!cur)
405
 	if(!cur)
409
 	// if headers not sent yet, send them....
411
 	// if headers not sent yet, send them....
410
 	if(!libpyfcgi.headers_sent)
412
 	if(!libpyfcgi.headers_sent)
411
 	{
413
 	{
412
-pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them...");
414
+		pyfcgi_log(LOG_DEBUG, "Headers not sent... sending them...");
413
 		libpyfcgi_send_headers();
415
 		libpyfcgi_send_headers();
414
 	}
416
 	}
415
 
417
 
422
 			dat = PyUnicode_AsUTF8AndSize(cur, &sz);
424
 			dat = PyUnicode_AsUTF8AndSize(cur, &sz);
423
 			if(!dat)
425
 			if(!dat)
424
 			{
426
 			{
427
+				if(PyErr_Occurred()) { goto err_clean; }
425
 				repr = PyObject_ASCII(cur);
428
 				repr = PyObject_ASCII(cur);
426
 				snprintf(err, 128,
429
 				snprintf(err, 128,
427
 					"libpyfcgi.__write_body unable to encode string as UTF-8 : %s",
430
 					"libpyfcgi.__write_body unable to encode string as UTF-8 : %s",
428
 					PyUnicode_AsUTF8(repr));
431
 					PyUnicode_AsUTF8(repr));
429
 				Py_DECREF(repr);
432
 				Py_DECREF(repr);
430
 				PyErr_SetString(PyExc_ValueError, err);
433
 				PyErr_SetString(PyExc_ValueError, err);
431
-				Py_RETURN_NONE;
434
+				goto err_clean;
432
 			}
435
 			}
433
 		}
436
 		}
434
 		else if(PyBytes_Check(cur))
437
 		else if(PyBytes_Check(cur))
436
 			dat = PyBytes_AsString(cur);
439
 			dat = PyBytes_AsString(cur);
437
 			if(!dat)
440
 			if(!dat)
438
 			{
441
 			{
439
-				/**@todo if no expt set, set error str */
440
-				Py_RETURN_NONE;
442
+				if(PyErr_Occurred()) { goto err_clean; }
443
+
444
+				snprintf(err, 128,
445
+					"Unable to get bytes buffer when sending body data");
446
+				PyErr_SetString(PyExc_ValueError, err);
447
+				goto err_clean;
441
 			}
448
 			}
442
 			sz = PyBytes_GET_SIZE(cur);
449
 			sz = PyBytes_GET_SIZE(cur);
443
 		}
450
 		}
446
 			bytes = PyObject_Bytes(cur);
453
 			bytes = PyObject_Bytes(cur);
447
 			if(!bytes)
454
 			if(!bytes)
448
 			{
455
 			{
456
+				if(PyErr_Occurred()) { goto err_clean; }
457
+
449
 				repr = PyObject_ASCII(cur);
458
 				repr = PyObject_ASCII(cur);
450
 				snprintf(err, 128,
459
 				snprintf(err, 128,
451
 					"libpyfcgi.__write_body expected str or bytes but %s given",
460
 					"libpyfcgi.__write_body expected str or bytes but %s given",
452
 					PyUnicode_AsUTF8(repr));
461
 					PyUnicode_AsUTF8(repr));
453
 				Py_DECREF(repr);
462
 				Py_DECREF(repr);
454
 				PyErr_SetString(PyExc_ValueError, err);
463
 				PyErr_SetString(PyExc_ValueError, err);
455
-				Py_RETURN_NONE;
464
+				goto err_clean;
456
 			}
465
 			}
457
 			dat = PyBytes_AsString(cur);
466
 			dat = PyBytes_AsString(cur);
458
 			if(!dat)
467
 			if(!dat)
459
 			{
468
 			{
460
-				/**@todo if no expt set, set error str */
461
-				Py_RETURN_NONE;
469
+				if(PyErr_Occurred()) { goto err_clean; }
470
+
471
+				snprintf(err, 128,
472
+					"Unable to get bytes buffer when sending body data");
473
+				PyErr_SetString(PyExc_ValueError, err);
474
+				goto err_clean;
462
 			}
475
 			}
463
 			sz = PyBytes_GET_SIZE(cur);
476
 			sz = PyBytes_GET_SIZE(cur);
464
 		}
477
 		}
465
 		
478
 		
466
-pyfcgi_log(LOG_DEBUG, "Sending '%s'", dat);
467
-		FCGX_PutStr(dat, sz, libpyfcgi.out);
479
+		ret = FCGX_PutStr(dat, sz, libpyfcgi.out);
480
+		if(ret < 0)
481
+		{
482
+			pyfcgi_log(LOG_ALERT, "Unable to send reply");
483
+			goto err_clean;
484
+		}
485
+		libpyfcgi.rep_sz += ret;
468
 
486
 
469
 		if(bytes) { Py_DECREF(bytes); }
487
 		if(bytes) { Py_DECREF(bytes); }
470
 		Py_DECREF(cur);
488
 		Py_DECREF(cur);
475
 		Py_DECREF(iter);
493
 		Py_DECREF(iter);
476
 	}
494
 	}
477
 	Py_RETURN_NONE;
495
 	Py_RETURN_NONE;
496
+
497
+err_clean:
498
+	if(bytes) { Py_DECREF(bytes); }
499
+	Py_DECREF(cur);
500
+	if(iter) { Py_DECREF(iter); }
501
+	Py_RETURN_NONE;
478
 }
502
 }

+ 2
- 6
src/pyworker.c View File

85
 	{
85
 	{
86
 		gettimeofday(&start, NULL);
86
 		gettimeofday(&start, NULL);
87
 		worker_set_busy(semid);
87
 		worker_set_busy(semid);
88
-pyfcgi_log(LOG_DEBUG, "Working !!");
89
 		count++;
88
 		count++;
90
 		environ = update_pyenv(py_osmod, envp);
89
 		environ = update_pyenv(py_osmod, envp);
91
 
90
 
92
 		libpyfcgi_clean_response();
91
 		libpyfcgi_clean_response();
93
 		libpyfcgi.out = out_stream;
92
 		libpyfcgi.out = out_stream;
94
 		args = Py_BuildValue("OO", environ, start_response);
93
 		args = Py_BuildValue("OO", environ, start_response);
95
-pyfcgi_log(LOG_DEBUG, "Calling entrypoint :D");
96
 		entry_ret = PyObject_CallObject(entry_fun, args);
94
 		entry_ret = PyObject_CallObject(entry_fun, args);
97
 		Py_INCREF(entry_ret);
95
 		Py_INCREF(entry_ret);
98
 
96
 
102
 		}
100
 		}
103
 		// able to process returned value
101
 		// able to process returned value
104
 		// Simulate python call of libpyfcgi.write_body()
102
 		// Simulate python call of libpyfcgi.write_body()
105
-pyfcgi_log(LOG_DEBUG, "Writing body !");
106
 		_pyfcgi_write_body(entry_ret);
103
 		_pyfcgi_write_body(entry_ret);
107
 		if(PyErr_Occurred())
104
 		if(PyErr_Occurred())
108
 		{
105
 		{
109
 			log_expt(LOG_ERR);
106
 			log_expt(LOG_ERR);
110
 		}
107
 		}
111
-pyfcgi_log(LOG_DEBUG, "Cleaning...");
112
 
108
 
113
 		// clean stuffs
109
 		// clean stuffs
114
 		Py_DECREF(args);
110
 		Py_DECREF(args);
131
 			stop.tv_usec += 1000000;
127
 			stop.tv_usec += 1000000;
132
 			stop.tv_sec -= 1;
128
 			stop.tv_sec -= 1;
133
 		}
129
 		}
134
-		pyfcgi_log(LOG_DEBUG, "Worker[%d] request %d END [OK] in %ld.%06lds",
135
-			wrk_id, count, stop.tv_sec, stop.tv_usec);
130
+		pyfcgi_log(LOG_DEBUG, "Worker[%d] request %d END [OK] %lu bytes in %ld.%06lds",
131
+			wrk_id, count, libpyfcgi.rep_sz, stop.tv_sec, stop.tv_usec);
136
 	}
132
 	}
137
 	return 0;
133
 	return 0;
138
 }
134
 }

Loading…
Cancel
Save