Hi Michel,
I ended up reimplementing Automatic Path Sessions in a Page subclass,
because I wanted to locate the session in another part of the URL, avoid
placing session ids in URLs shown to a spider, and implement some
convenience methods for accessing Extra Path Info fields.
The attached code for ExtraPathPage runs on Webware 0.8.1 with
"ExtraPathInfo" set to 1 and "UseAutomaticPathSessions" set to 0.
The ExtraPathPage class includes a link() function which is used to generate
internal URLs, given an absolute target and a list of fields to be passed as
Extra Path Info fields. The session id is appended at the end of the URL if
no cookie was sent.
It may seem cumbersome to call a function to generate URLs, but it's really
no strain at all in our production environment. TabletHotels.com is using a
version of this code in production. Try browsing without cookies.
If you (or anyone else) find this useful I can make some time to post it on
the Wiki.
Regards,
Ben
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] Behalf Of
> michelts
> Sent: Friday, May 13, 2005 10:34 AM
> To: Webware discussion list
> Subject: [Webware-discuss] Session Bug?
>
>
> Hi guys
>
> I'm using the last svn webware, I having problems with the
> AutomaticPathSession stuff. I use to redirect my pages to the webware
> context like this:
>
> RewriteCond %{REQUEST_URI} !^.*_SID_.*$
> RewriteRule ^(.*)$ /wk/somecontext$1 [L,PT]
>
> This redirect the root to /wk/somecontext a first time, if I set
> UseAutomaticPathSession Webware 0.8.1 try to redirect me to
> /wk/_SID_=.../somecontext, this make the apache try to redirect to
> /wk/_SID_=.../somecontext/wk/somecontext, this is skipped by the
> rewrite condition before the rule.
>
> On webware 0.8.1 this works well, in webware from svn this is not
> working, webware redirect me to /wk/_SID_=.../somecontext and if I
> have cookies enabled it sends me back (redirecting) to
> /wk/somecontext... This way it ends sending me to
> /wk/somecontext/wk/somecontext...
>
> I think the solution is to check if the user has cookies enabled, is
> he has doesn't do nothing but set the session cookie and if he hasn't
> the use automatic path session...
>
> Is this a bug or this is the application design? I this is a bug, I
> will try to fix it and send a patch to you...
>
> thanks for attention.
>
> --
> Michel Thadeu Sabchuk
> Curitiba - Brasil
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by Oracle Space Sweepstakes
> Want to be the first software developer in space?
> Enter now for the Oracle Space Sweepstakes!
> http://ads.osdn.com/?ad_ids93&alloc_id281&op=ick
> _______________________________________________
> Webware-discuss mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/webware-discuss
>
>
from WebKit.Page import Page
from types import ListType, NoneType
ROBOT_IDENTIFIERS =
['googlebot','ia_archive','infoseek','scooter','slurp','teoma','ultraseek','webcrawler','yahooseeker']
def robotAgent(userAgent):
''' Returns True if the userAgent is a known robot, else False '''
userAgent = userAgent.lower()
for i in ROBOT_IDENTIFIERS:
if userAgent.find(i) > -1:
return True
return False
class ExtraPathPage(Page):
''' Provides convenience methods for accessing extra path fields
Provides methods for passing the session id in the url
'''
def _checkForIndex(self, transaction):
''' Compensate for Webware's handling of ExtraPathInfo and index pages
'''
if self.name() == 'index':
req = transaction.request()
uri = req.uri()
if (not uri) or (uri[-1] != '/' and req.uri()[-5:] != 'index'):
transaction.response().sendRedirect(uri+'/')
self.endResponse()
def writeExceptionReport(self, handler):
handler.writeTitle(self.__class__.__name__)
handler.write('Session identifier: '+self.session().identifier())
def awake(self, transaction):
## This is a crufty little bugfix needed to compensate for Webware's
handling of ExtraPathInfo
self._checkForIndex(transaction) # ... do we still need this? -BP
# Handle the path session BEFORE the Page wakes up, checks for a
session and sets all its local references
self._pathSession = None
self.initPathSession(transaction)
# Wake up the super class
Page.awake(self, transaction)
# Now initialize the path fields
self._pathFields = None
self.initFields()
def sleep(self, transaction):
self._pathFields = None
self._pathSession = None
Page.sleep(self, transaction)
def initPathSession(self, transaction):
# If we don't have a session already, check for a session id at the end
of the request, set it if valid
request = transaction.request()
possibleSID = request.pathTranslated().rstrip('/').split('/')[-1]
if not request.sessionId() and possibleSID:
request.setField('_SID_', possibleSID)
if transaction.application().isSessionIdProblematic(request):
request.delField('_SID_')
else:
self._pathSession = possibleSID
def pathSession(self):
return self._pathSession
def initFields(self):
''' Subclasses may extend to perform extra validation
Make sure to invoke super, or call initPathFields explicitly
'''
self.initPathFields()
def initPathFields(self):
extraPath = self.request().extraURLPath().strip('/')
if extraPath:
self._pathFields = extraPath.split('/')
if self.pathSession() or self._pathFields[-1] ==
self.session().identifier():
# Make sure the path session doesn't show in the list of
available extra path fields
del self._pathFields[-1]
def pathFields(self):
return self._pathFields
def hasPathField(self, idx):
return (idx < len(self._pathFields))
def pathField(self, idx):
''' Return the value of the indexed path field, or None '''
try:
return self._pathFields[idx]
except (IndexError, TypeError):
return None
def field(self, pathIndex, fieldName=None):
''' Pulls the path field, or a request field as the fallback
Returns None for missing fields
'''
value = self.pathField(pathIndex)
if value == None and fieldName:
value = self.request().field(fieldName, None)
return value
def link(self, target, argList=None):
''' Returns a URL including the session id if the browser didn't send a
cookie session id '''
link = target.rstrip('/')
if argList:
link += ('/%s'*len(argList)) % tuple(argList)
if not self.request().hasCookie('_SID_') and not self.robotClient():
link += '/'+self.session().identifier()
return link+'/'
def robotClient(self):
''' Returns True if the userAgent is a known robot,
False if not a bot,
None if no user agent string found
'''
userAgent = self.request().environ().get("HTTP_USER_AGENT", None)
if userAgent:
return robotAgent(userAgent)
return None