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

Changeset 5

Show
Ignore:
Timestamp:
11/20/04 10:20:21
Author:
rdelon
Message:
    • Check that response is a string *after* filters have been applied (ticket #28) (Remi)
    • Removed all XML-RPC references from the core: it is now a filter (ticket #30) (Remi)
    • Removed Generator processing for the core: it is now a filter (Remi)
    • Removed "response encoding" from the core: it is now in a filter (ticket #31) (Remi)
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ChangeLog.txt

    r1 r5  
     1    * Check that response is a string *after* filters have been applied (ticket #28) (Remi) 
     2    * Removed all XML-RPC references from the core: it is now a filter (ticket #30) (Remi) 
     3    * Removed Generator processing for the core: it is now a filter (Remi) 
     4    * Removed "response encoding" from the core: it is now in a filter (ticket #31) (Remi) 
    15    * Implemented filters and a couple of sample filters (Remi) 
    26        * Fixed "cleanUpOldSessions" bug (ticket #12) (Remi) 
     
    711 
    8122004/10/13: 
    9     * First alpha release of CherryPy-2 
     13    * First alpha release of CherryPy-2 (Remi) 
    1014 
  • cherrypy/_cpconfig.py

    r1 r5  
    5959    cpg.configOption.sslVerifyDepth = 1 
    6060 
    61     # Variable used to determine what types of request to accept 
    62     cpg.configOption.typeOfRequests = ('web', ) 
    63  
    6461    # Variable used to flush cache 
    6562    cpg.configOption.flushCacheDelay=0 
     
    7774    cpg.configOption.sessionCookieName = "CherryPySession" 
    7875    cpg.configOption.sessionStorageFileDir = "" 
    79  
    80     # Variable used to change default encoding 
    81     cpg.configOption.encoding = "UTF-8" 
    8276 
    8377def parseConfigFile(configFile = None, parsedConfigFile = None): 
     
    115109            ('server', 'sslCACertificateFile', 'str'), 
    116110            ('server', 'sslVerifyDepth', 'int'), 
    117             ('server', 'typeOfRequests', 'str'), 
    118             ('server', 'encoding', 'str'), 
    119111            ('session', 'storageType', 'str'), 
    120112            ('session', 'timeout', 'float'), 
     
    156148    _cpLogMessage("  forking: %s" % cpg.configOption.forking, 'CONFIG') 
    157149    _cpLogMessage("  sslKeyFile: %s" % cpg.configOption.sslKeyFile, 'CONFIG') 
    158     _cpLogMessage("  encoding: %s" % cpg.configOption.encoding, 'CONFIG') 
    159150    if cpg.configOption.sslKeyFile: 
    160151        _cpLogMessage("  sslCertificateFile: %s" % cpg.configOption.sslCertificateFile, 'CONFIG') 
     
    162153        _cpLogMessage("  sslCACertificateFile: %s" % cpg.configOption.sslCACertificateFile, 'CONFIG') 
    163154        _cpLogMessage("  sslVerifyDepth: %s" % cpg.configOption.sslVerifyDepth, 'CONFIG') 
    164         _cpLogMessage("  typeOfRequests: %s"%str(cpg.configOption.typeOfRequests), 'CONFIG') 
    165155        _cpLogMessage("  flushCacheDelay: %s min" % cpg.configOption.flushCacheDelay, 'CONFIG') 
    166156    _cpLogMessage("  sessionStorageType: %s" % cpg.configOption.sessionStorageType, 'CONFIG') 
     
    185175            from OpenSSL import SSL 
    186176        except: raise "CherryError: PyOpenSSL 0.5.1 or later must be installed to use SSL. You can get it from http://pyopenssl.sourceforge.net" 
    187     if 'xmlRpc' in _typeOfRequests: 
    188         try: 
    189             global xmlrpclib 
    190             import xmlrpclib 
    191         except: raise "CherryError: xmlrpclib must be installed to use XML-RPC. It is included in Python-2.2 and higher, or else you can get it from http://www.pythonware.com" 
    192177    if _socketPort and _socketFile: raise "CherryError: In configuration file: socketPort and socketFile conflict with each other" 
    193178    if not _socketFile and not _socketPort: _socketPort=8000 # Default port 
     
    202187    except: pass 
    203188 
    204     for typeOfRequest in _typeOfRequests: 
    205         if typeOfRequest not in ('xmlRpc', 'web'): raise "CherryError: Configuration file an invalid typeOfRequest: '%s'"%typeOfRequest 
    206  
    207189    if _sessionStorageType not in ('', 'custom', 'ram', 'file', 'cookie'): raise "CherryError: Configuration file an invalid sessionStorageType: '%s'"%_sessionStorageType 
    208190    if _sessionStorageType in ('custom', 'ram', 'cookie') and _sessionStorageFileDir!='': raise "CherryError: Configuration file has sessionStorageType set to 'custom, 'ram' or 'cookie' but a sessionStorageFileDir is specified" 
  • cherrypy/_cpdefaults.py

    r1 r5  
    4242    cpg.response.body = bodyFile.getvalue() 
    4343    cpg.response.headerMap['Content-Type'] = 'text/plain' 
    44     if cpg.request.isXmlRpc: 
    45         # Special case for XML-RPC: 
    46         cpg.response.body = xmlrpclib.dumps(xmlrpclib.Fault(1, response.body)) 
    47         cpg.response.headerMap['Content-Type'] = 'text/xml' 
    48  
    49     cpg.response.headerMap["Content-Type"] = "text/plain" 
    5044 
    5145def _cpInitThread(numThread): pass 
  • cherrypy/_cphttptools.py

    r1 r5  
    3535    cpg.request.fileTypeMap = {} 
    3636    cpg.request.paramTuple = () 
    37     cpg.request.isXmlRpc = 0 
    3837    i = cpg.request.path.find('?') 
    3938    if i != -1: 
     
    7574    else: data="" 
    7675 
    77     cpg.request.isXmlRpc=0 
    78     # Try to parse request body as an XML-RPC call 
    79     if 'xmlRpc' in cpg.configOption.typeOfRequests and data and cpg.request.headerMap.get("Content-Type","") == "text/xml": 
    80         xmlRpcPathList = [] 
    81         if cpg.request.path == 'RPC2': pass 
    82         elif cpg.request.path.find('/') > -1: xmlRpcPathList = cpg.request.path.split('/') 
    83         elif not cpg.request.path: pass 
    84         else: xmlRpcPathList = [request.path] 
    85         try: 
    86             try: cpg.request.paramTuple,thisXmlRpcMethod=xmlrpclib.loads(data) 
    87             except: raise "XML-RPC ERROR" 
    88             thisXmlRpcMethod = str(thisXmlRpcMethod) # Get rid of unicode 
    89             cpg.request.isXmlRpc=1 # If parsing worked, it is an XML-RPC request 
    90             xmlRpcPathList += thisXmlRpcMethod.split('.') 
    91         except "XML-RPC ERROR": 
    92             # error reading data; must not have been an xmlrpc file 
    93             pass 
    94  
    95     if cpg.request.isXmlRpc: 
    96         cpg.request.path = '/'.join(xmlRpcPathList) 
    97     else: 
    98         # It's a normal browser call 
    99         # Put data in a StringIO so FieldStorage can read it 
    100         newRfile = StringIO.StringIO(data) 
    101         # Create a copy of headerMap with lowercase keys because 
    102         #   FieldStorage doesn't work otherwise 
    103         lowerHeaderMap = {} 
    104         for key, value in cpg.request.headerMap.items(): 
    105             lowerHeaderMap[key.lower()] = value 
    106         forms = cgi.FieldStorage(fp = newRfile, headers = lowerHeaderMap, environ = {'REQUEST_METHOD':'POST'}, keep_blank_values = 1) 
    107         for key in forms.keys(): 
    108             # Check if it's a list or not 
    109             valueList = forms[key] 
    110             if type(valueList) == type([]): 
    111                 # It's a list of values 
    112                 cpg.request.paramMap[key] = [] 
    113                 cpg.request.filenameMap[key] = [] 
    114                 cpg.request.fileTypeMap[key] = [] 
    115                 for item in valueList: 
    116                     cpg.request.paramMap[key].append(item.value) 
    117                     cpg.request.filenameMap[key].append(item.filename) 
    118                     cpg.request.fileTypeMap[key].append(item.type) 
    119             else: 
    120                 # It's a single value 
    121                 # In case it's a file being uploaded, we save the filename in a map (user might need it) 
    122                 cpg.request.paramMap[key] = valueList.value 
    123                 cpg.request.filenameMap[key] = valueList.filename 
    124                 cpg.request.fileTypeMap[key] = valueList.type 
     76    # Put data in a StringIO so FieldStorage can read it 
     77    newRfile = StringIO.StringIO(data) 
     78    # Create a copy of headerMap with lowercase keys because 
     79    #   FieldStorage doesn't work otherwise 
     80    lowerHeaderMap = {} 
     81    for key, value in cpg.request.headerMap.items(): 
     82        lowerHeaderMap[key.lower()] = value 
     83    forms = cgi.FieldStorage(fp = newRfile, headers = lowerHeaderMap, environ = {'REQUEST_METHOD':'POST'}, keep_blank_values = 1) 
     84    for key in forms.keys(): 
     85        # Check if it's a list or not 
     86        valueList = forms[key] 
     87        if type(valueList) == type([]): 
     88            # It's a list of values 
     89            cpg.request.paramMap[key] = [] 
     90            cpg.request.filenameMap[key] = [] 
     91            cpg.request.fileTypeMap[key] = [] 
     92            for item in valueList: 
     93                cpg.request.paramMap[key].append(item.value) 
     94                cpg.request.filenameMap[key].append(item.filename) 
     95                cpg.request.fileTypeMap[key].append(item.type) 
     96        else: 
     97            # It's a single value 
     98            # In case it's a file being uploaded, we save the filename in a map (user might need it) 
     99            cpg.request.paramMap[key] = valueList.value 
     100            cpg.request.filenameMap[key] = valueList.filename 
     101            cpg.request.fileTypeMap[key] = valueList.type 
    125102 
    126103def applyFilterList(methodName): 
     
    192169        _cputil.getSpecialFunction('_cpSaveSessionData')(sessionId, cpg.request.sessionMap, expirationTime) 
    193170 
     171    # Set the content-length 
     172    if cpg.response.headerMap.has_key('Content-Length') and cpg.response.headerMap['Content-Length']==0: 
     173        cpg.response.headerMap['Content-Length'] = len(cpg.response.body) 
     174 
    194175    wfile.write('%s %s\r\n' % (cpg.response.headerMap['protocolVersion'], cpg.response.headerMap['Status'])) 
    195176    for key, valueList in cpg.response.headerMap.items(): 
     
    198179            for value in valueList: 
    199180                wfile.write('%s: %s\r\n'%(key, value)) 
     181 
    200182    # Send response cookies 
    201183    cookie = cpg.response.simpleCookie.output() 
    202     # print "Sending back cookie:", cookie 
    203184    if cookie: 
    204185        wfile.write(cookie+'\r\n') 
     
    208189 
    209190    applyFilterList('beforeResponseFullBody') 
     191 
     192    # Check that the response body is a string 
     193    if type(cpg.response.body) != types.StringType: 
     194        raise cperror.WrongResponseType 
    210195 
    211196    wfile.write(cpg.response.body) 
     
    220205    cpg.response.wfile = wfile 
    221206    cpg.response.sendResponse = 1 
    222  
    223     # Default encoding 
    224     cpg.response.encoding = cpg.configOption.encoding 
    225207 
    226208    if cpg.configOption.sslKeyFile: 
     
    273255            f=open(fname, 'rb') 
    274256            cpg.response.body = f.read() 
    275             cpg.response.headerMap['Content-Length'] = len(cpg.response.body) 
    276257            f.close() 
    277258            # Set content-type based on filename extension 
     
    328309    if not path: 
    329310        pathList = [] 
    330     elif cpg.request.isXmlRpc: 
    331         pathList = path.split('.') 
    332311    else: 
    333312        pathList = path.split('/') 
     
    397376        raise cperror.NotFound 
    398377 
    399     if cpg.request.isXmlRpc: 
    400         cpg.response.body = func(*(cpg.request.paramTuple)) 
    401     else: 
    402         # XXX 
    403         myPath += '/' 
    404         if len(myPath) > 1: 
    405             myPath = '/' + myPath 
    406  
    407         cpg.request.objectPath = myPath 
    408         cpg.request.virtualPath = cpg.request.path[len(myPath)-1:] 
    409         cpg.response.body = func(**(cpg.request.paramMap)) 
    410  
    411     if cpg.request.isXmlRpc: 
    412         # Marshall the result if it's an XML-RPC call 
    413         # Wrap the response into a singleton tuple 
    414         cpg.response.body = (response.body,) 
    415         cpg.response.body = xmlrpclib.dumps(response.body, methodresponse=1) 
    416         # Response type is text/xml for an XML-RPC call 
    417         cpg.response.headerMap["Content-Type"]="text/xml" 
    418      
    419     # check if results are generators 
    420     # don't forget that python2.1 doesn't have generators 
    421     if isinstance(cpg.response.body, types.GeneratorType): 
    422         # makes a list of the generator. it's easier but less efficient than to 
    423         # loop over the iterator while writing to the wfile. This code does not 
    424         # check if all lines are strings. 
    425         cpg.response.body = "".join(list(cpg.response.body)) 
    426  
    427     elif not isinstance(cpg.response.body, types.StringTypes): 
    428          raise "CherryError: The method didn't return a string!" # TODO 
    429  
    430     # if it's unicode, encode it and specify the encoding in the content-type header 
    431     elif isinstance(cpg.response.body, unicode): # Potential gotcha: on jython, type("") == type(u"") !! 
    432         # extract the encoding from the content-type header if present 
    433         contentType = cpg.response.headerMap["Content-Type"].split(";") 
    434         if len(contentType)>1: 
    435             csdef = contentType[1].split("=") 
    436             if len(csdef)>1 and csdef[0].strip() == "charset": 
    437                 cpg.response.headerMap["Content-Type"] = contentType[0].strip() 
    438                 cpg.response.encoding = csdef[1].strip() 
    439              
    440         cpg.response.body = cpg.response.body.encode(cpg.response.encoding) 
    441         cpg.response.headerMap["Content-Type"] += "; charset=%s" % cpg.response.encoding 
    442  
    443     # if it's something different than a string, bail out 
    444     elif type(cpg.response.body) != types.StringType: 
    445         raise "CherryError: The method didn't return a string (returned type: %s) !" % type(cpg.response.body) 
    446      
    447     if cpg.response.headerMap.has_key('Content-Length') and cpg.response.headerMap['Content-Length']==0: 
    448         cpg.response.headerMap['Content-Length'] = len(cpg.response.body) 
     378    myPath += '/' 
     379    if len(myPath) > 1: 
     380        myPath = '/' + myPath 
     381 
     382    cpg.request.objectPath = myPath 
     383    cpg.request.virtualPath = cpg.request.path[len(myPath)-1:] 
     384    cpg.response.body = func(**(cpg.request.paramMap)) 
    449385 
    450386    if cpg.response.sendResponse: 
     
    458394    return sha.sha(s).hexdigest() 
    459395 
     396 
  • cherrypy/_cputil.py

    r1 r5  
    6262            path = '' 
    6363        if path: 
    64             if cpg.request.isXmlRpc: 
    65                 pathList = path.split('.') 
    66             else: 
    67                 pathList = path.split('/') 
     64            pathList = path.split('/') 
    6865 
    6966            obj = cpg.root 
  • cherrypy/cperror.py

    r1 r5  
    2828    """ Happens when a URL couldn't be mapped to any class.method """ 
    2929    pass 
     30 
     31class WrongResponseType(Error): 
     32    """ Happens when the cpg.response.body is not a string """ 
     33    pass 
  • cherrypy/lib/filter/gzipfilter.py

    r1 r5  
    2626 
    2727    def beforeResponse(self): 
    28         ct = cpg.response.headerMap.get('Content-Type') 
     28        ct = cpg.response.headerMap.get('Content-Type').split(';')[0] 
    2929        ae = cpg.request.headerMap.get('Accept-Encoding', '') 
    3030        if (ct in self.mimeTypeList) and ('gzip' in ae): 
  • cherrypy/tutorial/tutorial09.py

    r1 r5  
    99 
    1010from cherrypy import cpg 
     11from cherrypy.lib.filter import generatorfilter 
    1112 
    1213class GeneratorDemo: 
     14    _cpFilterList = [generatorfilter.GeneratorFilter()] 
    1315    def header(self): 
    1416        return "<html><body><h2>Generators rule!</h2>" 
  • cherrypy/unittest/testFilter1.py

    r4 r5  
    1313import helper, gzip, StringIO 
    1414 
    15 code = """ 
     15code = r""" 
    1616from cherrypy import cpg 
    1717import cherrypy.lib.filter.gzipfilter as gzipfilter 
     18import cherrypy.lib.filter.encodingfilter as encodingfilter 
     19import cherrypy.lib.filter.generatorfilter as generatorfilter 
     20europoundUnicode = u'\x80\xa3' 
    1821class Root: 
    19     _cpFilterList = [gzipfilter.GzipFilter()] 
     22    _cpFilterList = [ 
     23        generatorfilter.GeneratorFilter(), 
     24        encodingfilter.EncodingFilter(), 
     25        gzipfilter.GzipFilter() 
     26    ] 
    2027    def index(self): 
    21         return "Hello, world" 
     28        yield u"Hello," 
     29        yield u"world" 
     30        yield europoundUnicode 
    2231    index.exposed = True 
    2332cpg.root = Root() 
     
    2534""" 
    2635config = "" 
    27 expectedResult = "" 
     36europoundUnicode = u'\x80\xa3' 
     37expectedResult = (u"Hello," + u"world" + europoundUnicode).encode('utf-8') 
    2838 
    2939def test(infoMap, failedList, skippedList): 
    30     print "    Testing Gzip Filter...", 
     40    print "    Testing Filters (1) ...", 
    3141    zbuf = StringIO.StringIO() 
    3242    zfile = gzip.GzipFile(mode='wb', fileobj = zbuf, compresslevel = 9) 
    33     zfile.write("Hello, world"
     43    zfile.write(expectedResult
    3444    zfile.close() 
    3545    # Gzip compression doesn't always return the same exact result ! 
  • cherrypy/unittest/unittest.py

    r1 r5  
    8181testList = [ 
    8282    'testObjectMapping', 
    83     'testGzipFilter', 
     83    'testFilter1', 
    8484] 
    8585 

Hosted by WebFaction

Log in as guest/cpguest to create tickets