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

Nicolas Lehuen nicolas.lehuen at gmail.com
Sun Apr 24 03:29:06 EDT 2005


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