[mod_python] returning errors from python handler and ErrorDocument

Graham Dumpleton grahamd at dscpl.com.au
Sun Dec 11 06:02:06 EST 2005


On 01/12/2005, at 5:17 PM, Martin _ wrote:

> I like the idea, unfortunately it seems to suffer from the same
> problem - the file is created, status is 200 as it leaves the python,
> but ends up as a 404, and a browser refresh is needed to fetch the
> content. Even bumping up the pre-check to HeaderParserHandler had the
> same problem, which makes me wonder if apache has already decided if
> the file exists or not when it resolves the filename, and doesn't look
> again... but then I don't quite understand why it doesn't set the 404
> then. Or maybe the file isn't created 'enough', or there's some kinda
> race condition... I don't know. As the file is created literally with:
> if not os.path.isfile(req.filename):
>     fi = file(req.filename, mode='wb')
>     ## etc ##
> it really should be finding the file if it looks...

Use req.internal_redirect() to force Apache to reevaluate the URL from
the beginning.

   from mod_python import apache
   import os

   def fixuphandler(req):
     apache.log_error('req.filename=%s'%req.filename)
     if not os.path.exists(req.filename):
       file = open(req.filename,"w")
       file.write(req.unparsed_uri)
       file.close()
       req.internal_redirect(req.unparsed_uri)
       return apache.DONE
     return apache.OK

Not sure if there is a better way or not. There are also some 
implications
of using req.internal_redirect() if the original request was POST. That 
is
that on subsequent interpretation it will be seen as a GET request 
instead.
This will be a problem if the form parameters for the POST were in the
content of the request and not in the URL as with GET.

I'll think some more about other ways of doing it.

Graham

> On 11/28/05, Graham Dumpleton <grahamd at dscpl.com.au> wrote:
>> My guess is that once the content handler phase has been executed,
>> or logically passed, that you have no chance of changing what the 
>> return
>> status is. Thus, since for an ErrorDocument directive it is only 
>> applied
>> after the content handler phase of the first attempt has been passed,
>> whether that is for a mod_python content handler or an inbuilt static
>> Apache handler for serving static files, you will not be able to do 
>> it.
>>
>> What you instead need to do is to try and detect the condition of a
>> missing
>> file before the content handler phase is executed. To do that, setup a
>> PythonFixupHandler. Eg:
>>
>>    <Directory "D:/website/search">
>>    PythonFixupHandler check_for_missing_target
>>    </Directory>
>>
>> This should be done for the search directory. You DO NOT not need to
>> specify any corresponding SetHandler/AddHandler directive as they
>> are only relevant to PythonHandler directive and not the other phase
>> directives.
>>
>> What will happen now is that for any request received, it will be 
>> routed
>> through the function "fixuphandler" within the specified module. In 
>> that
>> module, you could check for the existance of the target. If it doesn't
>> exist, then create it:
>>
>>    # check_for_missing_target.py (module)
>>
>>    def fixuphandler(req):
>>      if target is missing:
>>        create target of request
>>      return apache.OK
>>
>> With the target now existing, the content handler phase when applied
>> will
>> possibly be able to find it. I say possibly, as I don't know what you
>> are
>> serving up and other issues such as Apache's URL matching algorithms
>> may come into play. You may need to actually adjust req.filename to
>> undo some of what Apache has done.
>>
>> Anyway, hope that gives you some ideas to play with.
>>
>> Graham
>>
>> On 28/11/2005, at 9:27 AM, Martin _ wrote:
>>
>>> In a related query to this one, is it possible to undo a raised
>>> http error? I've not had much luck in sending 404s to a script that
>>> then creates the resource asked for and bounces apache back to try
>>> again from the start, the 404 sticks despite my best attempts to
>>> overwrite it with a 200:
>>>
>>> # httpd.conf
>>> <Directory "D:/website/search">
>>>         ErrorDocument 404 /py/404.xml
>>> </Directory>
>>>
>>> <Directory "D:/website/py">
>>>         AddHandler mod_python .xml
>>>         PythonHandler index
>>> </Directory>
>>>
>>> # D:/website/py/index.py
>>> def handler(req):
>>>         if not req.prev:
>>>                 return apache.HTTP_FORBIDDEN
>>>
>>>         ## create relevant resource here ##
>>>
>>>         # doesn't help # req.prev.state = apache.HTTP_OK
>>>         # doesn't help # req.state = apache.HTTP_OK
>>>         req.internal_redirect(req.prev.unparsed_uri)
>>>         # doesn't help # req.next.state = apache.HTTP_OK
>>>         # doesn't help # raise apache.SERVER_RETURN, apache.HTTP_OK
>>>         return apache.OK
>>>
>>> I'm open to complete rethinks here, this doesn't strike me as
>>> optimal, as the few requests that don't want existing resources
>>> will go through three independant handlers, but for requirements:
>>> -I want to serve static content, even if it's generated because of
>>> that request, as static content, not mod_python created chunked 
>>> output
>>> -I want to keep all python stuff in that /py/ dir, rather than
>>> scattering scripts all over the tree
>>>
>>> Any wise thoughts gratefully received,
>>>
>>> Martin
>>> _______________________________________________
>>> Mod_python mailing list
>>> Mod_python at modpython.org
>>> http://mailman.modpython.org/mailman/listinfo/mod_python
>>>
>>
>>



More information about the Mod_python mailing list