Changeset 3771

Show
Ignore:
Timestamp:
11/26/07 20:50:18 (1 year ago)
Author:
faide
Message:

Fix for tickets: #1598, #1407 and #1022.
Applied a fix following an idea of Robert Brewer, and another one following streawkceur's report from some other guy named Adi. Thanks to the three of them!
And last but not least, added some tests to prove the fix works. Tests were supplied by simonk. I had some hard time applying this one after so long, but it was definitely worth it!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.0/turbogears/identity/tests/test_identity.py

    r3693 r3771  
    441441        assert 'identity_failed' in firstline, firstline 
    442442 
     443    def test_decode_filter(self): 
     444        """Test that the decode filter doesn't break with nested 
     445        variables and Identity""" 
     446        testutil.create_request('/in_admin_group?a.b=1&a.c=2') 
     447        firstline = cherrypy.response.body[0] 
     448        assert 'identity_failed_answer' in firstline, firstline 
    443449 
    444450class TestTGUser(testutil.DBTest): 
  • branches/1.0/turbogears/tests/test_controllers.py

    r3753 r3771  
    221221            "isinstance(tg_exceptions, KeyError)")(raise_all_exc) 
    222222    raise_all_exc = turbogears.expose()(raise_all_exc) 
     223 
     224    def internal_redirect(self, **kwargs): 
     225        raise cherrypy.InternalRedirect('/internal_redirect_target') 
     226    internal_redirect = turbogears.expose()(internal_redirect) 
     227     
     228    def internal_redirect_target(self, **kwargs): 
     229        return "redirected OK" 
     230    internal_redirect_target = turbogears.expose()(internal_redirect_target) 
    223231 
    224232class TestRoot(unittest.TestCase): 
     
    483491        #assert "AssertionError" not in outputcap.getvalue() 
    484492 
     493    def test_internal_redirect(self):  
     494        ''' 
     495        test to make sure we don't have regressions on tickets: #1598, #1407 
     496        and #1022 
     497        ''' 
     498        testutil.createRequest("/internal_redirect")  
     499        firstline = cherrypy.response.body[0]  
     500        assert "redirected OK" in firstline  
     501         
     502    def test_internal_redirect_nested_variables(self):  
     503        ''' 
     504        test to make sure we don't have regressions on tickets: #1598, #1407 
     505        and #1022 
     506        ''' 
     507        testutil.createRequest("/internal_redirect?a.b=1&a.c=2")  
     508        firstline = cherrypy.response.body[0]  
     509        print firstline  
     510        assert "redirected OK" in firstline 
     511 
    485512    def test_exc_value(self): 
    486513        ''' 
     
    605632        turbogears.startup.startTurboGears() 
    606633 
    607  
    608634def test_index_trailing_slash(): 
    609635    "If there is no trailing slash on an index method call, redirect" 
  • branches/1.0/turbogears/visit/api.py

    r3762 r3771  
    4949    raise RuntimeError("VisitManager plugin missing: %s" % plugin_name) 
    5050 
     51def monkey_before_main(self): 
     52    ''' 
     53    this function is used to monkey patch the decoding filter from cherrypy 
     54    ''' 
     55    conf = cherrypy.config.get 
     56     
     57    if not conf('decoding_filter.on', False): 
     58        return 
     59     
     60    if getattr(cherrypy.request, "_decoding_attempted", False): 
     61        return 
     62    cherrypy.request._decoding_attempted = True 
     63 
     64    enc = conf('decoding_filter.encoding', None) 
     65    if not enc: 
     66        ct = cherrypy.request.headers.elements("Content-Type") 
     67        if ct: 
     68            ct = ct[0] 
     69            enc = ct.params.get("charset", None) 
     70            if (not enc) and ct.value.lower().startswith("text/"): 
     71                # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1 
     72                # When no explicit charset parameter is provided by the 
     73                # sender, media subtypes of the "text" type are defined 
     74                # to have a default charset value of "ISO-8859-1" when 
     75                # received via HTTP. 
     76                enc = "ISO-8859-1" 
     77         
     78        if not enc: 
     79            enc = conf('decoding_filter.default_encoding', "utf-8") 
     80     
     81    try: 
     82        self.decode(enc) 
     83    except UnicodeDecodeError: 
     84        # IE and Firefox don't supply a charset when submitting form 
     85        # params with a CT of application/x-www-form-urlencoded. 
     86        # So after all our guessing, it could *still* be wrong. 
     87        # Start over with ISO-8859-1, since that seems to be preferred. 
     88        self.decode("ISO-8859-1") 
     89 
    5190# Interface for the TurboGears extension 
    5291def start_extension(): 
     
    5897    if _manager: 
    5998        return 
     99 
     100    # Monkey patch CP Decoding filter 
     101    from cherrypy.filters import decodingfilter 
     102    decodingfilter.DecodingFilter.before_main = monkey_before_main 
    60103 
    61104    log.info("Visit Tracking starting") 
     
    132175        an existing visit. 
    133176        ''' 
     177        def encode_utf8(params): 
     178            ''' 
     179            will recursively encode to utf-8 all values in a dictionnary 
     180            ''' 
     181            res = dict() 
     182            for k, v in params.items(): 
     183                if type(v) is dict: 
     184                    res[k] = encode_utf8(v) 
     185 
     186                else: 
     187                    res[k] = v.encode('utf-8') 
     188 
     189            return res 
     190 
    134191        if not turbogears.config.get("visit.on", True): 
    135192            set_current(None) 
     
    164221            cherrypy.request.object_path = e.path 
    165222 
    166         for k,v in cherrypy.request.params.iteritems(): 
    167             if isinstance(v, types.DictType): 
    168                 # we don't do anything with this... 
    169                 # anyway the decode filter of CP will not work 
    170                 # with dicts 
    171                 cherrypy.request.params[k] = v 
    172  
    173             else: 
    174                 cherrypy.request.params[k] = v.encode('utf-8') 
     223        cherrypy.request.params = encode_utf8(cherrypy.request.params) 
    175224 
    176225    def _generate_key(self):