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
> Webware-discuss@lists.sourceforge.net
> 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

Reply via email to