The mod_python.publisher implementation always decodes form parameters
regardless of whether the method being called can accept any and also ignores
whether the content type is even of a type where form parameters can be
decoded in the first place. This means that it is not possible using the
mod_python.publisher module to implement a method which accepts POST
requests with a inbound content type such as "text/xml". Attempting to do
so yields an error such as:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>501 Method Not Implemented</title>
</head><body>
<h1>Method Not Implemented</h1>
<p>POST to /xmlrpc/service not supported.<br />
</p>
<hr />
<address>Apache/2.0.51 (Unix) mod_python/3.1.4 Python/2.3 Server at localhost Port 8080</address>
</body></html>
The "Method Not Implemented" error in this case is due to FieldStorage
rejecting the content type of "text/xml".
A check could be added to ensure that FieldStorage is only used to decode
form parameters if the content type is appropriate. Ie.,
if not req.headers_in.has_key("content-type"):
content_type = "application/x-www-form-urlencoded"
else:
content_type = req.headers_in["content-type"]
if content_type == "application/x-www-form-urlencoded" or \
content_type[:10] == "multipart/":
Because req.form is passed to util.apply_fs_data(), code where it is called
would need to be changed to pass None instead and util.apply_fs_data()
would need to be modified to see that the argument is None and not do
the field conversion process of stuff in the form etc etc.
Description
The mod_python.publisher implementation always decodes form parameters
regardless of whether the method being called can accept any and also ignores
whether the content type is even of a type where form parameters can be
decoded in the first place. This means that it is not possible using the
mod_python.publisher module to implement a method which accepts POST
requests with a inbound content type such as "text/xml". Attempting to do
so yields an error such as:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>501 Method Not Implemented</title>
</head><body>
<h1>Method Not Implemented</h1>
<p>POST to /xmlrpc/service not supported.<br />
</p>
<hr />
<address>Apache/2.0.51 (Unix) mod_python/3.1.4 Python/2.3 Server at localhost Port 8080</address>
</body></html>
The "Method Not Implemented" error in this case is due to FieldStorage
rejecting the content type of "text/xml".
A check could be added to ensure that FieldStorage is only used to decode
form parameters if the content type is appropriate. Ie.,
if not req.headers_in.has_key("content-type"):
content_type = "application/x-www-form-urlencoded"
else:
content_type = req.headers_in["content-type"]
if content_type == "application/x-www-form-urlencoded" or \
content_type[:10] == "multipart/":
req.form = util.FieldStorage(req,keep_blank_values=1)
Because req.form is passed to util.apply_fs_data(), code where it is called
would need to be changed to pass None instead and util.apply_fs_data()
would need to be modified to see that the argument is None and not do
the field conversion process of stuff in the form etc etc.
Whether one allows this means making some sort of policy decision about what the purpose of mod_python.publisher is. If it is mean't as a more generalised dispatcher for URLs to published functions, then it should probably allow inbound content types for POST other than those appropriate to forms. If one allows that though, then you open up a whole can of worms as to whether it should therefore restrict the method type to HEAD, GET and POST as it does now. Ie., should it start with:
def handler(req):
req.allow_methods(["GET", "POST", "HEAD"])
if req.method not in ["GET", "POST", "HEAD"]:
raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED
To make it more generalised may be more trouble that its worth, so tt may well thus be best to constrain the purpose of mod_python.publisher and say that if you want to do anything else such as handle other inbound content types and other method types that you do it using some other mechanism.
Graham Dumpleton added a comment - 14/Feb/06 09:25 AM Whether one allows this means making some sort of policy decision about what the purpose of mod_python.publisher is. If it is mean't as a more generalised dispatcher for URLs to published functions, then it should probably allow inbound content types for POST other than those appropriate to forms. If one allows that though, then you open up a whole can of worms as to whether it should therefore restrict the method type to HEAD, GET and POST as it does now. Ie., should it start with:
def handler(req):
req.allow_methods(["GET", "POST", "HEAD"])
if req.method not in ["GET", "POST", "HEAD"]:
raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED
To make it more generalised may be more trouble that its worth, so tt may well thus be best to constrain the purpose of mod_python.publisher and say that if you want to do anything else such as handle other inbound content types and other method types that you do it using some other mechanism.
def handler(req):
req.allow_methods(["GET", "POST", "HEAD"])
if req.method not in ["GET", "POST", "HEAD"]:
raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED
To make it more generalised may be more trouble that its worth, so tt may well thus be best to constrain the purpose of mod_python.publisher and say that if you want to do anything else such as handle other inbound content types and other method types that you do it using some other mechanism.