[mod_python] Passing information through req.internal_redirect().

Graham Dumpleton grahamd at dscpl.com.au
Sun Apr 24 03:36:17 EDT 2005


I'll check in a while, but suspect that that still isn't going to give
access to any Python specific stuff that has been stashed in the "req"
object. I remember that one of the past mailing list messages was about
someone having tried this and found it wasn't possible. I would imagine
though that "req.prev.notes" would give you access to the table object
of previous request object, since the table object is stored in Apache.

Graham

On 24/04/2005, at 5:29 PM, Nicolas Lehuen wrote:

> I didn't test it, but it seems the 'prev' member field could help you
> get the initial request object after an internal redirect. Quoting
> from the documentation :
>
> http://www.modpython.org/live/current/doc-html/pyapi-mprequest-mem.html
>
> next
>     If this is an internal redirect, the request object we redirect
> to. (Read-Only)
>
> prev
>     If this is an internal redirect, the request object we redirect
> from. (Read-Only)
>
> Regards,
> Nicolas
>
> On 4/24/05, Graham Dumpleton <grahamd at dscpl.com.au> wrote:
>>> How about req.notes - does that work? That may be a more appropriate
>>> table to use than subprocess_env.
>>>
>>> Grisha
>>
>> Nothing I put in "req.notes" survives the redirect.
>>
>> There is some stuff in there:
>>
>>    python_init_ran = 1
>>    mod_userdir_user = grahamd
>>
>> The "python_init_ran" is put there by either of:
>>
>>    PythonHeaderParserHandler
>>    PythonPostReadRequestHandler
>>
>> code in mod_python.c and seems to be a bookkeeping flag to ensure 
>> that:
>>
>>    PythonInitHandler
>>
>> is only run once.
>>
>> The "moduserdir_user" setting seems to be inherited from Apache.
>>
>> Thus, "req.notes" appears to be created for each invocation of request
>> handler phases.
>>
>> However, if one instead uses "req.connection.notes", ie., notes object
>> which
>> exists in the connection object, then they are preserved.
>>
>> So therefore have two ways of passing information, either in the table
>> object
>> "req.subprocess_env" or in table object "req.connection.notes". In the
>> latter,
>> the key names are preserved as they were whereas in
>> "req.subprocess_env" they
>> get "REDIRECT_" prefixed.
>>
>> Because it is a table object in both cases, value can still only be a
>> string.
>>
>> Information in "req.subprocess_env" is still useful in its own right 
>> if
>> the
>> original URI was required.
>>
>> Anyway, useful stuff to know even though I am not sure I have a use 
>> for
>> it
>> at the moment.
>>
>> Graham
>>
>> On 24/04/2005, at 12:47 PM, Gregory (Grisha) Trubetskoy wrote:
>>
>>> On Sat, 23 Apr 2005, Graham Dumpleton wrote:
>>>
>>>> There has been a few times on the list where questions have been
>>>> asked about
>>>> how to pass information through a "req.internal_redirect()" call. 
>>>> The
>>>> problem
>>>> is that any data which is stashed in the "req" object isn't 
>>>> available
>>>> to the
>>>> target of the internal redirect because Apache/mod_python constructs
>>>> a new
>>>> "req" object for the subsequent handler invocation.
>>>>
>>>> Turns out there is actually a way of passing at least some
>>>> information. This
>>>> is done by adding new key/values to the "req.subprocess_env" table.
>>>> This table
>>>> is held within Apache data structures associated with the request 
>>>> and
>>>> contents
>>>> of it are propagated through to the target of the internal redirect.
>>>> The only
>>>> trick is that the key names get modified when the redirect occurs.
>>>> You also
>>>> can only store string values.
>>>>
>>>> Take for example a handler which contains:
>>>>
>>>>  from mod_python import apache
>>>>  import os
>>>>
>>>>  def handler(req):
>>>>    req.subprocess_env.add("XXX","YYY")
>>>>    req.internal_redirect(os.path.split(req.uri)[0]+'/page')
>>>>    return apache.OK
>>>>
>>>> and is accessed as:
>>>>
>>>>  /~grahamd/redirect/redirect
>>>>
>>>> And a second handler which is triggered as the target of the 
>>>> redirect
>>>> which
>>>> contains:
>>>>
>>>>  from mod_python import apache
>>>>
>>>>  def handler(req):
>>>>    req.content_type = "text/plain"
>>>>    for key in req.subprocess_env.keys():
>>>>      print >> req, key, "=", req.subprocess_env[key]
>>>>    return apache.OK
>>>>
>>>> That is, URL for this is:
>>>>
>>>>  /~grahamd/redirect/page
>>>>
>>>> The result of making a request against the first URL is that
>>>> redirection to
>>>> the second occurs, with the output being:
>>>>
>>>>  REDIRECT_GATEWAY_INTERFACE = CGI/1.1
>>>>  REDIRECT_SERVER_PROTOCOL = HTTP/1.1
>>>>  REDIRECT_REQUEST_METHOD = GET
>>>>  REDIRECT_QUERY_STRING =
>>>>  REDIRECT_REQUEST_URI = /~grahamd/redirect/redirect
>>>>  REDIRECT_SCRIPT_NAME = /~grahamd/redirect/redirect
>>>>  REDIRECT_XXX = YYY
>>>>  REDIRECT_STATUS = 200
>>>>  GATEWAY_INTERFACE = CGI/1.1
>>>>  SERVER_PROTOCOL = HTTP/1.1
>>>>  REQUEST_METHOD = GET
>>>>  QUERY_STRING =
>>>>  REQUEST_URI = /~grahamd/redirect/redirect
>>>>  SCRIPT_NAME = /~grahamd/redirect/page
>>>>
>>>> As can be seen, the key/value pair of "XXX" and "YYY" have 
>>>> persisted,
>>>> although
>>>> the key name is now "REDIRECT_XXX". One can also see that other
>>>> preexisting
>>>> variables set by Apache for the original request are also propagated
>>>> as well,
>>>> with similar key name change.
>>>>
>>>> That one can pass a newly created value would be useful where for
>>>> example a
>>>> initial handler had created a new session object as it could store
>>>> the session
>>>> ID in this table such that it is accessible to the second handler. 
>>>> In
>>>> the past
>>>> people have noticed how in redirects both handlers end up creating
>>>> separate
>>>> new session IDs if the first handler had to create one, because the
>>>> new session
>>>> ID is lost and not usable by the second handler.
>>>>
>>>> The information propagated about the initial request is useful as
>>>> well for the
>>>> fact that the original URI is present. This could be used by the
>>>> second handler
>>>> in some way.
>>>>
>>>> As an example, when using the ErrorDocument directive, Apache uses 
>>>> an
>>>> internal
>>>> redirect to redirect to the page when it is a local URI. As
>>>> documented in:
>>>>
>>>>  http://httpd.apache.org/docs-2.0/custom-error.html
>>>>
>>>> the req.subprocess_env would contain the "REDIRECT_*" values shown
>>>> above. In
>>>> this case the internal redirect is being done in Apache itself, but
>>>> there is
>>>> no reason that you couldn't implement your own version of the
>>>> ErrorDocument
>>>> functionality in your own custom handler code.
>>>>
>>>> Anyway, thought I would put together this ramble about this stuff
>>>> when I found
>>>> that this could be done since it may have been a solution to 
>>>> problems
>>>> a few
>>>> people had faced before, but that it could be done doesn't seem to
>>>> have ever
>>>> been mentioned on the mailing list before. At least now anyone
>>>> searching the
>>>> archives may find this. :-)
>>>>
>>>> Enjoy.
>>>>
>>>> Graham
>>>>
>>>> _______________________________________________
>>>> Mod_python mailing list
>>>> Mod_python at modpython.org
>>>> http://mailman.modpython.org/mailman/listinfo/mod_python
>>>>
>>
>> _______________________________________________
>> 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