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

Changeset 320

Show
Ignore:
Timestamp:
06/16/05 01:53:37
Author:
fumanchu
Message:

Fix and test for ticket #165 (header case-sensitivity).

Files:

Legend:

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

    r317 r320  
    5050 
    5151 
     52class KeyTitlingDict(dict): 
     53    """dict subclass which changes each key to str(key).title() 
     54     
     55    This should allow response headers to be case-insensitive and 
     56    avoid duplicates. 
     57    """ 
     58     
     59    def __getitem__(self, key): 
     60        return dict.__getitem__(self, str(key).title()) 
     61     
     62    def __setitem__(self, key, value): 
     63        dict.__setitem__(self, str(key).title(), value) 
     64     
     65    def __delitem__(self, key, value): 
     66        dict.__delitem__(self, str(key).title(), value) 
     67     
     68    def __contains__(self, item): 
     69        return dict.__contains__(self, str(item).title()) 
     70     
     71    def get(self, key, default=None): 
     72        return dict.get(self, str(key).title(), default) 
     73     
     74    def has_key(self, key): 
     75        return dict.has_key(self, str(key).title()) 
     76     
     77    def update(self, E): 
     78        for k in E.keys(): 
     79            self[str(k).title()] = E[k] 
     80     
     81    def fromkeys(cls, seq, value=None): 
     82        newdict = cls() 
     83        for k in seq: 
     84            newdict[str(k).title()] = value 
     85        return newdict 
     86    fromkeys = classmethod(fromkeys) 
     87     
     88    def setdefault(key, x=None): 
     89        key = str(key).title() 
     90        try: 
     91            return self[key] 
     92        except KeyError: 
     93            self[key] = x 
     94            return x 
     95     
     96    def pop(self, key, default): 
     97        return dict.pop(self, str(key).title(), default) 
     98 
     99 
    52100class Request(object): 
    53101    """Process a request and yield a series of response chunks. 
     
    87135        date = ("%s, %02d %3s %4d %02d:%02d:%02d GMT" % 
    88136                (weekdayname[wd], day, monthname[month], year, hh, mm, ss)) 
    89         cpg.response.headerMap = { 
     137        cpg.response.headerMap = KeyTitlingDict() 
     138        cpg.response.headerMap.update({ 
    90139            "Content-Type": "text/html", 
    91140            "Server": "CherryPy/" + cpg.__version__, 
     
    93142            "Set-Cookie": [], 
    94143            "Content-Length": 0 
    95         } 
     144        }) 
    96145        cpg.response.simpleCookie = Cookie.SimpleCookie() 
    97146         
  • trunk/cherrypy/test/helper.py

    r319 r320  
    105105                key, value = line.split(":", 1) 
    106106                cpg.response.headerMap[key.strip()] = value.strip() 
    107             cpg.response.headers = cpg.response.headerMap 
     107            cpg.response.headers = [(k, v) for k, v 
     108                                    in cpg.response.headerMap.iteritems()] 
    108109             
    109110            cpg.response.body = response.read() 
  • trunk/cherrypy/test/test_core.py

    r315 r320  
    119119            yield "oops" 
    120120        return inner() 
     121 
     122 
     123class Headers(Test): 
     124     
     125    def index(self): 
     126        # From http://www.cherrypy.org/ticket/165: 
     127        # "header field names should not be case sensitive sayes the rfc. 
     128        # if i set a headerfield in complete lowercase i end up with two 
     129        # header fields, one in lowercase, the other in mixed-case." 
     130         
     131        # Set the most common headers 
     132        cpg.response.headerMap['content-type'] = "text/html" 
     133        cpg.response.headerMap['content-length'] = 18 
     134        cpg.response.headerMap['server'] = 'CherryPy headertest' 
     135        cpg.response.headerMap['location'] = 'http://127.0.0.1:8000/headers/' 
     136         
     137        # Set a rare header for fun 
     138        cpg.response.headerMap['Expires'] = 'Thu, 01 Dec 2194 16:00:00 GMT' 
     139         
     140        return "double header test" 
    121141 
    122142 
     
    215235            self.assertEqual(cpg.response.status, "200 OK") 
    216236            self.assertEqual(cpg.response.body, "helloUnrecoverable error in the server.") 
     237     
     238    def testHeaderCaseSensitivity(self): 
     239        helper.request("/headers/") 
     240        hnames = [name.title() for name, val in cpg.response.headers] 
     241        hnames.sort() 
     242        self.assertEqual(hnames, ['Content-Length', 'Content-Type', 'Date', 'Expires', 
     243                                  'Location', 'Server']) 
     244        self.assertEqual(cpg.response.body, "double header test") 
    217245 
    218246 

Hosted by WebFaction

Log in as guest/cpguest to create tickets