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

Changeset 1569

Show
Ignore:
Timestamp:
12/28/06 13:53:28
Author:
fumanchu
Message:

2.x backport of RFC-2047 header encoding/decoding (see [1166] et al).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/cherrypy-2.x/cherrypy/_cphttptools.py

    r1521 r1569  
    196196            # only Konqueror does that), only the last one will remain in headers 
    197197            # (but they will be correctly stored in request.simple_cookie). 
    198             self.headers[name] = value 
     198            self.headers[name] = httptools.decode_TEXT(value) 
    199199             
    200200            # Handle cookies differently because on Konqueror, multiple 
     
    427427         
    428428        # Transform our header dict into a sorted list of tuples. 
    429         self.header_list = self.headers.sorted_list(
     429        self.header_list = self.headers.sorted_list(protocol=self.version
    430430         
    431431        cookie = self.simple_cookie.output() 
  • branches/cherrypy-2.x/cherrypy/lib/httptools.py

    r1489 r1569  
    1717 
    1818import cgi 
     19from email.Header import Header, decode_header 
    1920import re 
    2021import time 
     
    262263    return result 
    263264 
     265def decode_TEXT(value): 
     266    """Decode RFC-2047 TEXT (e.g. "=?utf-8?q?f=C3=BCr?=" -> u"f\xfcr").""" 
     267    atoms = decode_header(value) 
     268    decodedvalue = "" 
     269    for atom, charset in atoms: 
     270        if charset is not None: 
     271            atom = atom.decode(charset) 
     272        decodedvalue += atom 
     273    return decodedvalue 
    264274 
    265275def validStatus(status): 
     
    453463        order_map[_] = 2 
    454464     
    455     def sorted_list(self): 
     465    def sorted_list(self, protocol=(1, 0)): 
    456466        """Transform self into a sorted list of (name, value) tuples. 
    457467         
     
    467477            if not isinstance(valueList, list): 
    468478                valueList = [valueList] 
    469             for value in valueList: 
    470                 header_list.append((order, (key, str(value)))) 
     479            for v in valueList: 
     480                 
     481                if isinstance(v, unicode): 
     482                    # HTTP/1.0 says, "Words of *TEXT may contain octets 
     483                    # from character sets other than US-ASCII." and 
     484                    # "Recipients of header field TEXT containing octets 
     485                    # outside the US-ASCII character set may assume that 
     486                    # they represent ISO-8859-1 characters." 
     487                    try: 
     488                        v = v.encode("iso-8859-1") 
     489                    except UnicodeEncodeError: 
     490                        if protocol >= (1, 1): 
     491                            # Encode RFC-2047 TEXT 
     492                            # (e.g. u"\u8200" -> "=?utf-8?b?6IiA?="). 
     493                            v = Header(v, 'utf-8').encode() 
     494                        else: 
     495                            raise 
     496                else: 
     497                    # This coercion should not take any time at all 
     498                    # if value is already of type "str". 
     499                    v = str(v) 
     500                 
     501                header_list.append((order, (key, v))) 
    471502        header_list.sort() 
    472503        return [item[1] for item in header_list] 
  • branches/cherrypy-2.x/cherrypy/test/test.py

    r1567 r1569  
    9292        self.protocol = "HTTP/1.1" 
    9393         
    94         longopts = ['cover', 'profile', 'dumb', '1.1', 'help', 
     94        longopts = ['cover', 'profile', 'dumb', '1.0', 'help', 
    9595                    'basedir=', 'port=', 'server='] 
    9696        longopts.extend(self.available_tests) 
  • branches/cherrypy-2.x/cherrypy/test/test_core.py

    r1520 r1569  
    266266             
    267267            return "double header test" 
    268  
    269  
     268         
     269        def ifmatch(self): 
     270            val = cherrypy.request.headers['If-Match'] 
     271            cherrypy.response.headers['ETag'] = val 
     272            return repr(val) 
     273     
     274     
    270275    class HeaderElements(Test): 
    271276         
     
    773778                    'Expires', 'Location', 'Server']: 
    774779            self.assertEqual(hnames.count(key), 1) 
     780         
     781        if cherrypy.config.get('server.protocol_version') == "HTTP/1.1": 
     782            # Test RFC-2047-encoded request and response header values 
     783            c = "=E2=84=ABngstr=C3=B6m" 
     784            self.getPage("/headers/ifmatch", [('If-Match', '=?utf-8?q?%s?=' % c)]) 
     785            self.assertBody("u'\\u212bngstr\\xf6m'") 
     786            self.assertHeader("ETag", '=?utf-8?b?4oSrbmdzdHLDtm0=?=') 
     787             
     788            # Test a *LONG* RFC-2047-encoded request and response header value 
     789            self.getPage("/headers/ifmatch", 
     790                         [('If-Match', '=?utf-8?q?%s?=' % (c * 10))]) 
     791            self.assertBody("u'%s'" % ('\\u212bngstr\\xf6m' * 10)) 
     792            self.assertHeader("ETag", 
     793                              '=?utf-8?b?4oSrbmdzdHLDtm3ihKtuZ3N0csO2beKEq25nc3Ryw7Zt4oSrbmdzdHLDtm0=?=' 
     794                              '=?utf-8?b?4oSrbmdzdHLDtm3ihKtuZ3N0csO2beKEq25nc3Ryw7Zt4oSrbmdzdHLDtm0=?=' 
     795                              '=?utf-8?b?4oSrbmdzdHLDtm3ihKtuZ3N0csO2bQ==?=') 
    775796     
    776797    def testHTTPMethods(self): 

Hosted by WebFaction

Log in as guest/cpguest to create tickets