You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by gr...@apache.org on 2003/11/04 21:30:39 UTC
cvs commit: httpd-python/src psp_parser.c psp_parser.l requestobject.c
grisha 2003/11/04 12:30:39
Modified: Doc modpython4.tex
lib/python/mod_python psp.py
src psp_parser.c psp_parser.l requestobject.c
Log:
Psp now defers flushing until the end of template, which improves performance
greatly. Also the psp template can take a list of global vars now in the
constructor (as well as the run() method).
Revision Changes Path
1.62 +11 -3 httpd-python/Doc/modpython4.tex
Index: modpython4.tex
===================================================================
RCS file: /home/cvs/httpd-python/Doc/modpython4.tex,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- modpython4.tex 8 Oct 2003 03:48:17 -0000 1.61
+++ modpython4.tex 4 Nov 2003 20:30:39 -0000 1.62
@@ -738,8 +738,13 @@
client.
\end{methoddesc}
-\begin{methoddesc}[request]{write}{string}
- Writes \var{string} directly to the client, then flushes the buffer.
+\begin{methoddesc}[request]{write}{string\optional{, flush=1}}
+ Writes \var{string} directly to the client, then flushes the buffer,
+ unless flush is 0.
+\end{methoddesc}
+
+\begin{methoddesc}[request]{flush}{}
+ Flushes the output buffer.
\end{methoddesc}
\begin{methoddesc}[request]{set_content_length}{len}
@@ -2139,13 +2144,16 @@
argument, then the file can be specified as a relative path, otherwise
it has to be absolute.
-\begin{classdesc}{PSP}{req, \optional{, filename, string}}
+\begin{classdesc}{PSP}{req, \optional{, filename, string, vars}}
This class represents a PSP object.
\var{req} is a request object; \var{filename} and \var{string} are
optional keyword arguments which indicate the source of the PSP
code. Only one of these can be specified. If neither is specified,
\code{req.filename} is used as \var{filename}.
+
+ \var{vars} is a dictionary of global variables. Vars passed in the
+ \method{run()} method will override vars passed in here.
This class is used internally by the PSP handler, but can also be
used as a general purpose templating tool.
1.24 +19 -5 httpd-python/lib/python/mod_python/psp.py
Index: psp.py
===================================================================
RCS file: /home/cvs/httpd-python/lib/python/mod_python/psp.py,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- psp.py 8 Sep 2003 19:31:50 -0000 1.23
+++ psp.py 4 Nov 2003 20:30:39 -0000 1.24
@@ -127,12 +127,12 @@
code = None
dbmcache = None
- def __init__(self, req, filename=None, string=None):
+ def __init__(self, req, filename=None, string=None, vars={}):
if (string and filename):
raise ValueError, "Must specify either filename or string"
- self.req = req
+ self.req, self.vars = req, vars
if not filename and not string:
filename = req.filename
@@ -140,6 +140,13 @@
self.filename, self.string = filename, string
if filename:
+
+ # if filename is not absolute, default to our guess
+ # of current directory
+ if not os.path.isabs(filename):
+ base = os.path.split(req.filename)[0]
+ self.filename = os.path.join(base, filename)
+
self.load_from_file()
else:
@@ -234,10 +241,12 @@
global_scope = globals().copy()
global_scope.update({"req":req, "session":session,
"form":form, "psp":psp})
- global_scope.update(vars)
+ global_scope.update(self.vars) # passed in __init__()
+ global_scope.update(vars) # passed in run()
try:
exec code in global_scope
-
+ req.flush()
+
# the mere instantiation of a session changes it
# (access time), so it *always* has to be saved
if session:
@@ -252,6 +261,11 @@
finally:
if session:
session.unlock()
+
+ def __str__(self):
+ self.req.content_type = 'text/html'
+ self.run()
+ return ""
def display_code(self):
"""
1.17 +4 -4 httpd-python/src/psp_parser.c
Index: psp_parser.c
===================================================================
RCS file: /home/cvs/httpd-python/src/psp_parser.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- psp_parser.c 15 Oct 2003 01:32:20 -0000 1.16
+++ psp_parser.c 4 Nov 2003 20:30:39 -0000 1.17
@@ -880,7 +880,7 @@
YY_RULE_SETUP
#line 102 "psp_parser.l"
{ /* expression */
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\"); req.write(str("));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\",0); req.write(str("));
PSP_PG(is_psp_echo) = 1;
BEGIN PYCODE;
@@ -890,7 +890,7 @@
YY_RULE_SETUP
#line 109 "psp_parser.l"
{ /* python code */
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\");"));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\",0);"));
CLEAR_WHITESPACE(&PSP_PG(whitespace));
PSP_PG(seen_newline) = 0;
BEGIN PYCODE;
@@ -935,7 +935,7 @@
yypop_buffer_state(yyscanner);
if (!YY_CURRENT_BUFFER) {
/* this is really the end */
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\")\n"));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\",0)\n"));
yyterminate();
}
else {
@@ -961,7 +961,7 @@
{
if (PSP_PG(is_psp_echo)) {
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR(")); req.write(\"\"\""));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("),0); req.write(\"\"\""));
PSP_PG(is_psp_echo) = 0;
}
else {
1.17 +5 -5 httpd-python/src/psp_parser.l
Index: psp_parser.l
===================================================================
RCS file: /home/cvs/httpd-python/src/psp_parser.l,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- psp_parser.l 10 Sep 2003 02:11:22 -0000 1.16
+++ psp_parser.l 4 Nov 2003 20:30:39 -0000 1.17
@@ -100,14 +100,14 @@
}
<TEXT>"<%=" { /* expression */
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\"); req.write(str("));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\",0); req.write(str("));
PSP_PG(is_psp_echo) = 1;
BEGIN PYCODE;
}
<TEXT>"<%" { /* python code */
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\");"));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\",0);"));
CLEAR_WHITESPACE(&PSP_PG(whitespace));
PSP_PG(seen_newline) = 0;
BEGIN PYCODE;
@@ -137,7 +137,7 @@
yypop_buffer_state(yyscanner);
if (!YY_CURRENT_BUFFER) {
/* this is really the end */
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\")\n"));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("\"\"\",0)\n"));
yyterminate();
}
else {
@@ -156,7 +156,7 @@
<PYCODE>"%>" {
if (PSP_PG(is_psp_echo)) {
- psp_string_appendl(&PSP_PG(pycode), STATIC_STR(")); req.write(\"\"\""));
+ psp_string_appendl(&PSP_PG(pycode), STATIC_STR("),0); req.write(\"\"\""));
PSP_PG(is_psp_echo) = 0;
}
else {
1.54 +33 -4 httpd-python/src/requestobject.c
Index: requestobject.c
===================================================================
RCS file: /home/cvs/httpd-python/src/requestobject.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- requestobject.c 8 Oct 2003 03:48:17 -0000 1.53
+++ requestobject.c 4 Nov 2003 20:30:39 -0000 1.54
@@ -848,7 +848,7 @@
}
/**
- ** request.write(request self, string what)
+ ** request.write(request self, string what, flush=1)
**
* write output to the client
*/
@@ -858,15 +858,16 @@
int len;
int rc;
char *buff;
+ int flush=1;
- if (! PyArg_ParseTuple(args, "s#", &buff, &len))
+ if (! PyArg_ParseTuple(args, "s#|i", &buff, &len, &flush))
return NULL; /* bad args */
if (len > 0 ) {
Py_BEGIN_ALLOW_THREADS
rc = ap_rwrite(buff, len, self->request_rec);
- if (rc != -1)
+ if (flush && (rc != -1))
rc = ap_rflush(self->request_rec);
Py_END_ALLOW_THREADS
if (rc == -1) {
@@ -880,6 +881,33 @@
}
+/**
+ ** request.flush(request self)
+ **
+ * flush output buffer
+ */
+
+static PyObject * req_flush(requestobject *self)
+{
+ int rc;
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = ap_rflush(self->request_rec);
+ Py_END_ALLOW_THREADS
+ if (rc == -1) {
+ PyErr_SetString(PyExc_IOError, "Flush failed, client closed connection.");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/**
+ ** request.sendfile
+ **
+ */
+
static PyObject * req_sendfile(requestobject *self, PyObject *args)
{
char *fname;
@@ -933,6 +961,7 @@
{"add_handler", (PyCFunction) req_add_handler, METH_VARARGS},
{"allow_methods", (PyCFunction) req_allow_methods, METH_VARARGS},
{"document_root", (PyCFunction) req_document_root, METH_NOARGS},
+ {"flush", (PyCFunction) req_flush, METH_NOARGS},
{"get_basic_auth_pw", (PyCFunction) req_get_basic_auth_pw, METH_NOARGS},
{"get_addhandler_exts", (PyCFunction) req_get_addhandler_exts, METH_NOARGS},
{"get_config", (PyCFunction) req_get_config, METH_NOARGS},