Skip to content

Commit

Permalink
Made req.handler writable. (MODPYTHON-125)
Browse files Browse the repository at this point in the history
  • Loading branch information
grahamd committed Feb 21, 2006
1 parent f574ffe commit 6a62766
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 7 deletions.
5 changes: 5 additions & 0 deletions Doc/appendixc.tex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ \chapter{Changes from Version (3.2.7)\label{app-changes}}
Interpreter Lock (GIL), as described in PEP 311, can now be used. The
only requirement is that such modules can only be used in the context
of the \samp{main_interpreter}.
\item
(\citetitle[http://issues.apache.org/jira/browse/MODPYTHON-125]{MODPYTHON-125})
The \code{req.handler} attribute is now writable. This allows a handler
executing in a phase prior to the response phase to specify which
Apache module will be responsible for generating the content.
\end{itemize}

Bug Fixes
Expand Down
20 changes: 17 additions & 3 deletions Doc/modpython4.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,23 @@ \subsubsection{Request Members\label{pyapi-mprequest-mem}}
\end{memberdesc}

\begin{memberdesc}[request]{handler}
The name of the handler currently being processed. This is the handler
set by mod_mime, not the mod_python handler. In most cases it will be
"\samp{mod_python}. \emph{(Read-Only})
The symbolic name of the content handler (as in module, not mod_python
handler) that will service the request during the response phase. When
the SetHandler/AddHandler directives are used to trigger mod_python, this
will be set to \samp{mod_python} by mod_mime. A mod_python handler executing
prior to the response phase may also set this to \samp{mod_python} along
with calling \samp{req.add_handler()} to register a mod_python handler
for the response phase.

\begin{verbatim}
def typehandler(req):
if os.path.splitext(req.filename)[1] == ".py":
req.handler = "mod_python"
req.add_handler("PythonHandler", "mod_python.publisher")
return apache.OK
return apache.DECLINED
\end{verbatim}

\end{memberdesc}

\begin{memberdesc}[request]{content_encoding}
Expand Down
2 changes: 1 addition & 1 deletion lib/python/mod_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
__all__ = ["apache", "cgihandler", "psp",
"publisher", "util", "python22"]

version = "3.3.0-dev-20060219"
version = "3.3.0-dev-20060221"

4 changes: 2 additions & 2 deletions src/include/mpversion.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#define MPV_MAJOR 3
#define MPV_MINOR 3
#define MPV_PATCH 0
#define MPV_BUILD 20060219
#define MPV_STRING "3.3.0-dev-20060219"
#define MPV_BUILD 20060221
#define MPV_STRING "3.3.0-dev-20060221"
11 changes: 10 additions & 1 deletion src/requestobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,15 @@ static int setreq_recmbr(requestobject *self, PyObject *val, void *name)
apr_pstrdup(self->request_rec->pool, PyString_AsString(val));
return 0;
}
else if (strcmp(name, "handler") == 0) {
if (! PyString_Check(val)) {
PyErr_SetString(PyExc_TypeError, "handler must be a string");
return -1;
}
self->request_rec->handler =
apr_pstrdup(self->request_rec->pool, PyString_AsString(val));
return 0;
}

return PyMember_SetOne((char*)self->request_rec,
find_memberdef(request_rec_mbrs, (char*)name),
Expand Down Expand Up @@ -1553,7 +1562,7 @@ static PyGetSetDef request_getsets[] = {
{"read_chunked", (getter)getreq_recmbr, NULL, "Reading chunked transfer-coding", "read_chunked"},
{"expecting_100", (getter)getreq_recmbr, NULL, "Is client waitin for a 100 response?", "expecting_100"},
{"content_type", (getter)getreq_recmbr, (setter)setreq_recmbr, "Content type", "content_type"},
{"handler", (getter)getreq_recmbr, NULL, "The handler string", "handler"},
{"handler", (getter)getreq_recmbr, (setter)setreq_recmbr, "The handler string", "handler"},
{"content_encoding", (getter)getreq_recmbr, NULL, "How to encode the data", "content_encoding"},
{"content_languages", (getter)getreq_rec_ah, NULL, "Content languages", "content_languages"},
{"vlist_validator", (getter)getreq_recmbr, NULL, "Variant list validator (if negotiated)", "vlist_validator"},
Expand Down
12 changes: 12 additions & 0 deletions test/htdocs/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,18 @@ def req_sendfile3(req):
os.remove(fname)
return apache.OK

def req_handler(req):
if req.phase == "PythonFixupHandler":
req.handler = "mod_python"
req.add_handler("PythonHandler","tests::req_handler")
return apache.OK
elif req.phase == "PythonHandler":
req.write('test ok')
return apache.OK
else:
req.write('test failed')
return apache.OK

def fileupload(req):
from mod_python import util
import md5
Expand Down
4 changes: 4 additions & 0 deletions test/httpdconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ class PythonTransHandler(Directive):
def __init__(self, val):
Directive.__init__(self, self.__class__.__name__, val)

class PythonFixupHandler(Directive):
def __init__(self, val):
Directive.__init__(self, self.__class__.__name__, val)

class PythonImport(Directive):
def __init__(self, val):
Directive.__init__(self, self.__class__.__name__, val)
Expand Down
26 changes: 26 additions & 0 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,31 @@ def test_req_sendfile3(self):
else:
print "\n * Skipping req.sendfile() for a file which is a symbolic link"

def test_req_handler_conf(self):

c = VirtualHost("*",
ServerName("test_req_handler"),
DocumentRoot(DOCUMENT_ROOT),
Directory(DOCUMENT_ROOT,
PythonFixupHandler("tests::req_handler"),
PythonDebug("On")))
return str(c)

def test_req_handler(self):

print "\n * Testing req.handler"

conn = httplib.HTTPConnection("127.0.0.1:%s" % PORT)
conn.putrequest("GET", "/", skip_host=1)
conn.putheader("Host", "%s:%s" % ("test_req_handler", PORT))
conn.endheaders()
response = conn.getresponse()
rsp = response.read()
conn.close()

if (rsp != "test ok"):
self.fail(`rsp`)

def test_fileupload_conf(self):

c = VirtualHost("*",
Expand Down Expand Up @@ -2058,6 +2083,7 @@ def testPerRequestTests(self):
perRequestSuite.addTest(PerRequestTestCase("test_req_sendfile"))
perRequestSuite.addTest(PerRequestTestCase("test_req_sendfile2"))
perRequestSuite.addTest(PerRequestTestCase("test_req_sendfile3"))
perRequestSuite.addTest(PerRequestTestCase("test_req_handler"))
perRequestSuite.addTest(PerRequestTestCase("test_fileupload"))
perRequestSuite.addTest(PerRequestTestCase("test_fileupload_embedded_cr"))
perRequestSuite.addTest(PerRequestTestCase("test_fileupload_split_boundary"))
Expand Down

0 comments on commit 6a62766

Please sign in to comment.