|
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
|