|
Dr. L.A. Timochouk
L.A.Timochouk at ukc.ac.uk
Fri Aug 11 23:00:29 EST 2000
Hello All,
Please find attached a patch for mod_python-2.4.1. It addresses two issues:
(1) The current implementation of "req_read" method seems to contain a bug
(or a problematic feature?): it may return less bytes than was requested,
due to a known sockets phenomenon called "short read". Namely, a single
"read" on a TCP socket returns data ONLY up to the end of the current
IP packet; several "read"s may be required to get the whole amount
requested. The current implementation did not guard against that; on the
contrary, it shrank the output buffer is less-than-expected bytes were
received. In particular, this may result in incomplete receiving of POSTed
data (the problem shows up on large submissions only). The proposed
patch fixes it.
(2) A new Apache directive,
PythonOptimize On|Off
is implemented. If set, it allows us to run the interpreter in the
fully-optimising mode (equivalent to -OO Python command-line argument)
which may be useful for time-critical applications.
Best regards,
Dr. Leonid Timochouk
Computing Laboratory
University of Kent at Canterbury
England
===============================================================================
--- mod_python.c.orig Tue Jul 4 18:49:31 2000
+++ mod_python.c Sun Jul 23 16:39:55 2000
@@ -1277,7 +1277,7 @@
static PyObject * req_read(requestobject *self, PyObject *args)
{
- int len, rc, bytes_read;
+ int len, rc, bytes_read, chunk_len;
char *buffer;
PyObject *result;
@@ -1316,13 +1316,18 @@
return NULL;
/* read it in */
+ /* BEWARE of short reads! */
buffer = PyString_AS_STRING((PyStringObject *) result);
- bytes_read = ap_get_client_block(self->request_rec, buffer, len);
-
- /* resize if necessary */
- if (bytes_read < len)
- if(_PyString_Resize(&result, bytes_read))
+ bytes_read = 0;
+ while (bytes_read < len)
+ {
+ chunk_len = ap_get_client_block
+ (self->request_rec, buffer+bytes_read, len-bytes_read);
+ if (chunk_len == 0)
+ /* Connection closed -- it's better not to return anything */
return NULL;
+ bytes_read += chunk_len;
+ }
return result;
}
@@ -2087,6 +2092,19 @@
}
/**
+ ** directive_PythonOptimize
+ **
+ * This function called whenever PythonOptimize directive
+ * is encountered.
+ */
+static const char *directive_PythonOptimize(cmd_parms *cmd, void *mconfig,
+ int val) {
+ if (val)
+ Py_OptimizeFlag = 2; /* Optimize and remove function descr strings */
+ return NULL;
+}
+
+/**
** directive_PythonInterpPerDirectory
**
* This function called whenever PythonInterpPerDirectory directive
@@ -2409,6 +2427,14 @@
OR_ALL,
FLAG,
"Send (most) Python error output to the client rather than logfile."
+ },
+ {
+ "PythonOptimize",
+ directive_PythonOptimize,
+ NULL,
+ OR_ALL,
+ FLAG,
+ "Set the equivalent of the -O command-line flag on the interpreter."
},
{
"PythonNoReload",
|