Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 665

Show
Ignore:
Timestamp:
09/19/05 17:09:36
Author:
fumanchu
Message:

Fix for #309 (confusion between threads and requests).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/__init__.py

    r654 r665  
    5555    from cherrypy._cpthreadinglocal import local 
    5656 
     57# Create a threadlocal object to hold the request and response objects. 
     58# In this way, we can easily dump those objects when we stop/start a 
     59# new HTTP conversation. 
     60serving = local() 
     61 
     62class _AttributeDump: 
     63    pass 
     64 
     65class _ThreadLocalProxy: 
     66     
     67    def __init__(self, attrname): 
     68        self.__dict__["__attrname__"] = attrname 
     69     
     70    def purge__(self): 
     71        """Make a new, emtpy proxied object in cherrypy.serving.""" 
     72        setattr(serving, self.__attrname__, _AttributeDump()) 
     73     
     74    def __getattr__(self, name): 
     75        childobject = getattr(serving, self.__attrname__) 
     76        return getattr(childobject, name) 
     77     
     78    def __setattr__(self, name, value): 
     79        childobject = getattr(serving, self.__attrname__) 
     80        setattr(childobject, name, value) 
     81     
     82    def __delattr__(self, name): 
     83        childobject = getattr(serving, self.__attrname__) 
     84        delattr(childobject, name) 
     85 
    5786# Create request and response object (the same objects will be used 
    58 #   throughout the entire life of the webserver) 
    59 request = local() 
    60 response = local() 
     87#   throughout the entire life of the webserver, but will redirect 
     88#   to the "serving" object) 
     89request = _ThreadLocalProxy('request') 
     90response = _ThreadLocalProxy('response') 
    6191 
    6292# Create threadData object as a thread-specific all-purpose storage 
  • trunk/cherrypy/_cphttpserver.py

    r583 r665  
    8181        if not self.parse_request(): # An error code has been sent, just exit 
    8282            return 
     83         
     84        cherrypy.request.purge__() 
     85        cherrypy.response.purge__() 
    8386         
    8487        cherrypy.request.multithread = cherrypy.config.get("server.threadPool") > 1 
  • trunk/cherrypy/_cpwsgi.py

    r626 r665  
    8989     
    9090    try: 
     91        cherrypy.request.purge__() 
     92        cherrypy.response.purge__() 
     93         
    9194        # LOGON_USER is served by IIS, and is the name of the 
    9295        # user after having been mapped to a local account. 
  • trunk/cherrypy/lib/filter/cachefilter.py

    r555 r665  
    126126        global cherrypy 
    127127        import cherrypy 
    128         cherrypy.threadData.cacheable = True 
     128        cherrypy.request.cacheable = True 
    129129     
    130130    def beforeMain(self): 
     
    137137         
    138138        cacheData = cherrypy._cache.get() 
    139         cherrypy.threadData.cacheable = not cacheData 
     139        cherrypy.request.cacheable = not cacheData 
    140140        if cacheData: 
    141141            expirationTime, lastModified, obj = cacheData 
     
    159159            return 
    160160         
    161         if cherrypy.threadData.cacheable: 
     161        if cherrypy.request.cacheable: 
    162162            status = cherrypy.response.status 
    163163            headers = cherrypy.response.headers 
  • trunk/cherrypy/lib/filter/sessionauthenticatefilter.py

    r598 r665  
    7070        elif cherrypy.request.path.endswith('doLogout'): 
    7171            cherrypy.session[sessionKey] = None 
    72             cherrypy.threadData.user = None 
     72            cherrypy.request.user = None 
    7373            fromPage = cherrypy.request.paramMap.get('fromPage', '..') 
    7474            cherrypy.response.body = httptools.redirect(fromPage) 
     
    9999        if loadUserByUsername: 
    100100            username = cherrypy.session[sessionKey] 
    101             cherrypy.threadData.user = loadUserByUsername(username) 
     101            cherrypy.request.user = loadUserByUsername(username) 
  • trunk/cherrypy/lib/filter/sessionfilter.py

    r647 r665  
    2828 
    2929""" Session implementation for CherryPy. 
    30 We use cherrypy.threadData to store some convenient variables as 
     30We use cherrypy.request to store some convenient variables as 
    3131well as data about the session for the current request. Instead of 
    32 polluting cherrypy.threadData we use a dummy object called 
    33 cherrypy.threadData._session (sess) to store these variables. 
     32polluting cherrypy.request we use a dummy object called 
     33cherrypy.request._session (sess) to store these variables. 
    3434 
    3535Variables used to store config options: 
     
    8989        conf = cherrypy.config.get 
    9090         
    91         cherrypy.threadData._session = EmptyClass() 
    92         sess = cherrypy.threadData._session 
     91        cherrypy.request._session = EmptyClass() 
     92        sess = cherrypy.request._session 
    9393        now = datetime.datetime.now() 
    9494        # Dont enable session if sessionFilter is off or if this is a 
     
    187187            self._clean(sess) 
    188188         
    189         sess = cherrypy.threadData._session 
     189        sess = cherrypy.request._session 
    190190        if not sess.sessionStorage: 
    191191            # Sessions are not enabled: do nothing 
     
    197197     
    198198    def afterErrorResponse(self): 
    199         sess = cherrypy.threadData._session 
     199        sess = cherrypy.request._session 
    200200        if not sess.sessionStorage: 
    201201            # Sessions are not enabled: do nothing 
     
    223223     
    224224    def acquireLock(self): 
    225         sess = cherrypy.threadData._session 
     225        sess = cherrypy.request._session 
    226226        id = cherrypy.session['_id'] 
    227227        lock = cherrypy._sessionLockDict.get(id) 
     
    238238     
    239239    def releaseLock(self): 
    240         sess = cherrypy.threadData._session 
     240        sess = cherrypy.request._session 
    241241        id = cherrypy.session['_id'] 
    242242        cherrypy._sessionLockDict[id].release() 
     
    244244     
    245245    def cleanUp(self): 
    246         sess = cherrypy.threadData._session 
     246        sess = cherrypy.request._session 
    247247        toBeDeleted = [] 
    248248        now = datetime.datetime.now() 
     
    278278     
    279279    def acquireLock(self): 
    280         sess = cherrypy.threadData._session 
     280        sess = cherrypy.request._session 
    281281        filePath = self._getFilePath(cherrypy.session['_id']) 
    282282        lockFilePath = filePath + self.LOCK_SUFFIX 
     
    285285     
    286286    def releaseLock(self): 
    287         sess = cherrypy.threadData._session 
     287        sess = cherrypy.request._session 
    288288        filePath = self._getFilePath(cherrypy.session['_id']) 
    289289        lockFilePath = filePath + self.LOCK_SUFFIX 
     
    292292     
    293293    def cleanUp(self): 
    294         sess = cherrypy.threadData._session 
     294        sess = cherrypy.request._session 
    295295        storagePath = cherrypy.config.get('sessionFilter.storagePath') 
    296296        now = datetime.datetime.now() 
     
    326326     
    327327    def _lockFile(self, path): 
    328         sess = cherrypy.threadData._session 
     328        sess = cherrypy.request._session 
    329329        startTime = time.time() 
    330330        while True: 
     
    403403     
    404404    def cleanUp(self): 
    405         sess = cherrypy.threadData._session 
     405        sess = cherrypy.request._session 
    406406        now = datetime.datetime.now() 
    407407        self.cursor.execute( 
     
    424424#   to be thread-specific so we use a special wrapper that forwards 
    425425#   calls to cherrypy.session to a thread-specific dictionary called 
    426 #   cherrypy.threadData._session.sessionData 
     426#   cherrypy.request._session.sessionData 
    427427class SessionWrapper: 
    428428     
    429429    def __getattr__(self, name): 
    430         sess = cherrypy.threadData._session 
     430        sess = cherrypy.request._session 
    431431        if sess.sessionStorage is None: 
    432432            raise SessionNotEnabledError() 
  • trunk/cherrypy/lib/filter/xmlrpcfilter.py

    r569 r665  
    149149    def beforeRequestBody(self): 
    150150        """ Called after the request header has been read/parsed""" 
    151         cherrypy.threadData.xmlRpcFilterOn = cherrypy.config.get('xmlRpcFilter.on', False) 
    152         if not cherrypy.threadData.xmlRpcFilterOn: 
     151        cherrypy.request.xmlRpcFilterOn = cherrypy.config.get('xmlRpcFilter.on', False) 
     152        if not cherrypy.request.xmlRpcFilterOn: 
    153153            return True 
    154154         
     
    183183    def beforeFinalize(self): 
    184184        """ Called before finalizing output """ 
    185         if (not cherrypy.threadData.xmlRpcFilterOn 
     185        if (not cherrypy.request.xmlRpcFilterOn 
    186186            or not cherrypy.request.isRPC): 
    187187            return 
     
    202202    def beforeErrorResponse(self): 
    203203        try: 
    204             if not cherrypy.threadData.xmlRpcFilterOn: 
     204            if not cherrypy.request.xmlRpcFilterOn: 
    205205                return 
    206206            body = ''.join([chunk for chunk in cherrypy.response.body]) 
  • trunk/cherrypy/test/helper.py

    r660 r665  
    101101        if body is not None: 
    102102            body = StringIO.StringIO(body) 
     103         
     104        cherrypy.request.purge__() 
     105        cherrypy.response.purge__() 
    103106         
    104107        cherrypy.server.request((self.HOST, self.PORT), self.HOST, 
  • trunk/cherrypy/test/test_core.py

    r641 r665  
    254254    def upload(self, file): 
    255255        return "Size: %s" % len(file.file.read()) 
     256 
     257class ThreadLocal(Test): 
     258     
     259    def index(self): 
     260        existing = repr(getattr(cherrypy.request, "asdf", None)) 
     261        cherrypy.request.asdf = "hello" 
     262        return existing 
     263 
    256264 
    257265logFile = os.path.join(localDir, "error.log") 
     
    310318            ('/foo/nex', 'baz', 'that2'), 
    311319        ] 
     320        cherrypy.request.purge__() 
    312321        for path, key, expected in tests: 
    313322            cherrypy.request.path = path 
     
    669678            self.assertStatus("413 Request Entity Too Large") 
    670679            self.assertInBody("Request Entity Too Large") 
     680     
     681    def testEmptyThreadlocals(self): 
     682        results = [] 
     683        for x in xrange(20): 
     684            self.getPage("/threadlocal/") 
     685            results.append(self.body) 
     686        self.assertEqual(results, ["None"] * 20) 
     687 
    671688 
    672689if __name__ == '__main__': 

Hosted by WebFaction

Log in as guest/cpguest to create tickets