quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Graham Dumpleton" <grah...@dscpl.com.au>
Subject Re: [Mod_python Wiki] Update of "Session use with classes" by MartinStoufer
Date Mon, 04 Dec 2006 23:28:48 GMT
Sorry, but I am going to take issue with where this session example is headed
as there are number of things being done which I at least would regard as being
bad practice. Please don't take this wrong way, your effort in doing this stuff in
the first place is much appreciated and I hope I don't dissuade you from
continuing. It is just a matter of using our collective minds to ensure that
overall the example is robust and secure.

I'll quickly mention the issues I see and when I get a chance and if no one else
has piped up and explained it more, I respond in more detail.

The first as I mentioned once before is that you are still using MemorySession
as the session type which means this example will only work for people on
Windows and will not always work for people using prefork/worker on UNIX
platforms.

The second is that it promotes a bad practice of having functions accessible
under multiple URLs thereby exacerbating a problem with mod_python.publisher
related to trailing slashes and determining relative URLs. Ie., the following both
map to the same thing.

  http://your.domain.com/ExampleSession/ExampleSession.py/foo
  http://your.domain.com/ExampleSession/ExampleSession.py/foo/foo

The third is that in general it is exposing all sorts of private stuff which it should
not.

  http://your.domain.com/ExampleSession/ExampleSession.py/tags
  http://your.domain.com/ExampleSession/ExampleSession.py/foo/t
  http://your.domain.com/ExampleSession/ExampleSession.py/foo/session
  http://your.domain.com/ExampleSession/ExampleSession.py/foo/session/....

The fourth is that it isn't thread safe and will fail with a multithread MPM.

The fifth is that it caches the session object and thus holds a reference to
the request object beyond the actual life time of the request. With the exposure
of private stuff above, my guess is I could crash the web server by using the
following URL after first request has been done.

  http://your.domain.com/ExampleSession/ExampleSession.py/foo/session/make_cookie

The sixth is that I believe we should be persuading users to not be doing
session creation stuff inside of individual publisher functions as they then
tend to duplicate the same code everywhere. It might be better to show them
how to use stacked handlers to have the session object created even before
publisher gets invoked, or at least show them the convention of storing the
session object as req.session and always checking for its existence there
before creating it, so as to avoid deadlocks. That or at least hive the session
creation into a common function they call.

More later.

Graham

Apache Wiki wrote ..
> Dear Wiki user,
> 
> You have subscribed to a wiki page or wiki category on "Mod_python Wiki"
> for change notification.
> 
> The following page has been changed by MartinStoufer:
> http://wiki.apache.org/mod_python/Session_use_with_classes
> 
> The comment on the change is:
> Added working example
> 
> ------------------------------------------------------------------------------
>   
>   Once you understand this framework, you can then add your own content.
>   
> - First, lets augment a directory element in the ''httpd.conf'' to enable
> both the Publisher model and session support.
> + The nominal URL you will be using is of the following form:
> + {{{
> + http://your.domain.com/ExampleSession.py/foo
> + }}}
>   
> + If you want to enforce and/or simplify the type of backing store for
> sessions running under mod_python, you can augment the directory element
> in the ''httpd.conf''. We also enable the Publisher model here.
>   {{{
>   <Directory /usr/local/apache2/htdocs/DomProdLib>
>       AddHandler mod_python .py
> @@ -22, +26 @@
> 
>   
>   Here we see the '''[http://modpython.org/live/current/doc-html/dir-handlers-ph.html
> PythonHandler]''' using the publisher object. Utilizing and extending this
> is described in [http://modpython.org/live/current/doc-html/hand-pub.html
> Section 6.1] of the mod_python documentation.
>   
> - We also see a new '''[http://modpython.org/live/current/doc-html/dir-other-po.html
> PythonOption]''' added calling for the ''session'' option to be set with
> the ''[http://modpython.org/live/current/doc-html/pyapi-sess.html MemorySession]''
> value. Other values are available and are defined in  [http://modpython.org/live/current/doc-html/pyapi-sess.html
> Section 4.5] of the mod_python documentation. This is not strictly required
> as a default one will be selected for you by mod_python/Apache when your
> session based application is run.
> + We also see our new '''[http://modpython.org/live/current/doc-html/dir-other-po.html
> PythonOption]''' added calling for the ''session'' option to be set with
> the ''[http://modpython.org/live/current/doc-html/pyapi-sess.html MemorySession]''
> value. Other values are available and are defined in  [http://modpython.org/live/current/doc-html/pyapi-sess.html
> Section 4.5] of the mod_python documentation. 
> + 
> + If you choose not to constrain your mod_python applications to all use
> the same session, you have two programattic options.  
> + 
> +  Use the default selected for you by mod_python/Apache when your session
> based application is run:: Save this file as ''Example``Session.py'' {{{#!python
> + from mod_python import apache, Session
> + 
> + tags = (1,2,3,4)
> + 
> + class Bar:
> +    def __call__(self, req):
> +        self.session = Session.Session(req)
> +        if self.session.is_new():
> +           self.t = self.session.created()
> +        return self.foo()
> + 
> +    def __init__(self, *args):
> +        # Do some important initializing here
> +        pass
> + 
> +    def foo(self):
> +        delta = int(self.session.last_accessed()-self.t)
> +        try:
> +            self.session['hits'] += 1
> +        except:
> +            self.session['hits'] = 1
> + 
> +        self.session.save()
> +        return """Session ID: %s
> + This session has been active for %d seconds
> + This session has been accessed %d times""" % (self.session.id(), delta,
> self.session['hits'])
> + 
> + foo=Bar(tags)
> + }}}
> +  
> +  Instantiate a derived Session class:: {{{Bar}}}
> + 
> + One major difference you'll notice is that the `__init__` isn't used
> directly by mod_python. You can of course initialize internals here from
> global values, but it isn't until the `__call__` is invoked that the ''req''
> object is passed in and gives us the hook we need to process the request.
>   
>   === The rest is forthcoming in short order ===
>   ---- 

Mime
View raw message