[mod_python] Internal redirect does not end processing and session is not saved on internal redirect - mpservlets

Scott Chapman scottie at mischko.com
Mon Mar 28 13:48:15 EST 2005


Here's my uberServlet which demonstrates this "interesting" behavior.  
If I use the external redirect and comment out the internal redirect, 
everything works perfectly.

Note that I have changed mpservlets to call prep BEFORE auth.  This 
makes better sense to me.

uberServlet:

> from mod_python.servlet import Servlet
> from mod_python import apache,util
> from pages import Pages
> import data_object
>
> class uberservlet(Servlet):
>     use_session = True
>
>     def prep(self):
>         Servlet.prep(self)
>
>     def auth(self):
>         pages=Pages()
>         
> methodName=self.req.uri[:len(self.req.uri)-len(self.req.path_info)][1:]
>         self.req.log_error('AUTH - methodName: ' + methodName)
>         if methodName in ['login','doLogin','logout']:
>             return
>         method=getattr(pages,methodName,None)
>         if method:
>             self.req.log_error('AUTH - method found')
>
>             # Check to see if the page requires user to be logged in
>             requiresLogin = data_object.requires_login(methodName)
>
>             if requiresLogin == 'unknown':
>                 self.req.log_error('AUTH - page: %s not found in pages 
> table' % methodName)
>                 raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
>
>             if not requiresLogin:
>                 self.req.log_error('AUTH - page: %s does not require 
> login' % methodName)
>                 return
>
>             if requiresLogin:
>                 self.req.log_error('AUTH - page: %s requires login' % 
> methodName)
>                 userName = self.session.get('username', None)
>                 # Check to see if the user is logged in
>                 if userName:
>                     self.req.log_error('AUTH - user already logged in: 
> %s' % userName)
>                     # Check that the user has access to the page.
>                     access_ok = 
> data_object.check_access(methodName,userName)
>                     if access_ok:
>                         return
>                     else:
>                         raise apache.SERVER_RETURN, apache.HTTP_FORBIDDEN
>                 else:
>                     self.req.log_error('AUTH - user not logged in')
>                     self.session['returnto'] = self.req.unparsed_uri
>                     self.req.log_error('AUTH - sid when returnto set: 
> ' + str(self.session.id()))
>                     self.req.log_error('AUTH - returnto: ' + 
> self.session['returnto'])
>                     self.req.log_error('AUTH - internal redirect to 
> login')
>                     #Tried doing an internal redirect here but
>                     #things don't go well. Code is executed after the 
> internal redirect.
>                     #The cookie with the session info is not sent to 
> the client here so the returnto is lost.
>                     self.session.save()
>                     self.session.unlock()
>                     self.req.internal_redirect('/login')
>                     
>                     #util.redirect(self.req,'/login')
>
>                     #The next line should never be reached.  
>                     #It is reached when internal redirect is done, not 
> when external is done.
>                     self.req.log_error('AUTH - logging after redirect 
> - should never happen!')
>         else:
>             self.req.log_error('AUTH - method not found')
>             raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
>         return
>         
>     def respond(self):
>         
> methodName=self.req.uri[:len(self.req.uri)-len(self.req.path_info)][1:]
>         self.req.log_error ('UBERSERVLET RESPOND - method name: %s' % 
> methodName)
>         pages=Pages()
>         method=getattr(pages,methodName,None)
>         if method:
>             self.req.log_error('UBERSERVLET RESPOND - calling method')
>             if self.form.list:
>                 self.write(method(self,self.form))
>             else:
>                 self.write(method(self))
>             return True
>         else:
>             self.req.log_error('UBERSERVLET RESPOND - method not found')
>             return False
>         


      
Here's the "pages" contents:

> from mod_python import util, apache
> import data_object
> import templates
> import table_builder
>
> class Pages:
>     def login(self,uberServlet):
>         center=templates.login_template
>         return templates.site_template(2,center=center,menu=False)
>
>
>     def doLogin(self,uberServlet, form):
>         login = form.getfirst('login')
>         password = form.getfirst('password')
>         if data_object.checkLoginAndPassword(login, password):
>             uberServlet.session['username'] = login
>             uberServlet.req.log_error('DOLOGIN - username and password 
> confirmed')
>             uberServlet.req.log_error('DOLOGIN - sid: ' + 
> str(uberServlet.session.id()))
>             return_to = uberServlet.session.pop('returnto','/index')
>             uberServlet.req.log_error('DOLOGIN - return_to' + return_to)
>             util.redirect(uberServlet.req,return_to)
>         else:
>             return self.login()
>
>     def table(self,uberServlet):
>         return ....


Here's my log of the session, using internal redirect with code above:

> --- session cookies cleared in browser and request for /table 
> submitted ----
> HANDLER-calling prep
> HANDLER-calling auth
> AUTH - methodName: table
> AUTH - method found
> AUTH - page: table requires login
> AUTH - user not logged in
> AUTH - sid when returnto set: 01e782d539e43cf4d490196e104bd257
> AUTH - returnto: /table
> AUTH - internal redirect to login
> HANDLER-calling prep
> HANDLER-calling auth
> AUTH - methodName: login
> HANDLER-calling respond
> UBERSERVLET RESPOND - method name: login
> UBERSERVLET RESPOND - calling method
> HANDLER-calling wrapup
> AUTH - logging after redirect - should never happen!
> HANDLER-calling respond
> UBERSERVLET RESPOND - method name: table
> UBERSERVLET RESPOND - calling method
> HANDLER-calling wrapup
> ---- login screen in browser ----
> HANDLER-calling prep, referer: http://nsnserver/table
> HANDLER-calling auth, referer: http://nsnserver/table
> AUTH - methodName: doLogin, referer: http://nsnserver/table
> HANDLER-calling respond, referer: http://nsnserver/table
> UBERSERVLET RESPOND - method name: doLogin, referer: 
> http://nsnserver/table
> UBERSERVLET RESPOND - calling method, referer: http://nsnserver/table
> DOLOGIN - username and password confirmed, referer: http://nsnserver/table
> DOLOGIN - sid: b8efe481dabadabdba61b7301de32f98, referer: 
> http://nsnserver/table
> DOLOGIN - return_to/index, referer: http://nsnserver/table
> ---- table contents shows up in browser as text (no headers sent back 
> to browser) followed by redirect

Here's what showed in the browser (not view source):

<-snip->
</tr>
</tbody>
</table>
</body>
</html>
HTTP/1.1 302 Found
Date: Mon, 28 Mar 2005 18:41:40 GMT
Server: Apache/2.0.53 (Unix) mod_ssl/2.0.53 OpenSSL/0.9.7d 
mod_python/3.1.4 Python/2.4.1c2
Location: /index
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/plain

38
<p>The document has moved <a href="/index">here</a></p>

0

Cordially,
Scott


More information about the Mod_python mailing list