imbolc avatar imbolc committed 620ea35

fix redirect with unicode url

Comments (0)

Files changed (2)

     max_post_size = None  # максимальный размер post-данных
     _new_flashes = None
     _clear_flashes = False
-    
+
     def __init__(self, environ):
         self.environ = environ
         self.path = environ['PATH_INFO'].decode(self.charset, self.encoding_errors)
-    
+
     @cached_property
     def context(self):
         res = {'rq': self, 'url4': url4, 'cfg': cfg}
         return MultiDict((k.decode(self.charset, self.encoding_errors),
             v[-1].decode(self.charset, self.encoding_errors))
                 for k, v in cgi.parse_qs(self.environ['QUERY_STRING']).iteritems())
-        
+
     @cached_property
     def POST(self):
         '''
     def url(self):
         '''Полный урл'''
         return '%s://%s%s' % (self.scheme, self.host, self.full_path)
-    
+
     @cached_property
     def ip(self):
         '''
     @cached_property
     def referer(self):
         return self.environ.get('HTTP_REFERER', '')
-        
+
     @cached_property
     def user_agent(self):
         return self.environ.get('HTTP_USER_AGENT', '')
-    
+
     @cached_property
     def basic_user(self):
         if cfg.BASIC_AUTH_SSL_ONLY and self.scheme != 'https':
         if cfg.BASIC_AUTH_DB.get(user) != sha1(passwd).hexdigest():
             raise BasicAuth
         return user
-        
+
     @cached_property
     def flashes(self):
         ret = []
     charset = 'utf-8'  # дефолтная кодировка
     encoding_errors = 'ignore'
     content_type = 'text/html'  # дефолтный Content-Type
-    
+
     def __init__(self, body='', headers=None, cookies=None, **kwargs):
         '''
         Response
         for k, v in kwargs.iteritems():
             self.COOKIES[key][k] = v
         return self
-        
+
     def delete_cookie(self, key):
         return self.set_cookie(key, '', expires=-1)
 
         else:
             self.headers['Content-Type'] = self.content_type
         self.headers['Content-Length'] = str(len(self.body))
-        
+
         return status, list(self.headers.iterallitems()), [self.body]
-        
+
 
 class App(object):
     def __init__(self, cfg_module='cfg'):
             *cfg_module - модуль конфигурации
         '''
         self.cfg_module = cfg_module
-    
+
     def setup(self, environ, start_response):
         '''
         Первый запуск
                         raise
                 abort(404)
             return wrapper
-        
+
         try:
             cfg_module = obj_from_str(self.cfg_module)
         except ImportError:
         Request.max_post_size = cfg.POST_MAX_SIZE
         Response.charset = cfg.CHARSET
         add_apps(cfg.INSTALLED_APPS)
-        
+
         list_obj_from_str(cfg.CONTEXT_PROCESSORS)
         mdls = list_obj_from_str(cfg.MIDDLEWARES)
         self.request_middlewares = [m().process_request for m in mdls
     code = 301 if permanent else 302
     if not url.startswith(('/', 'http://', 'https://')):
         url = url4(url, **kwargs) or url
+    if isinstance(url, unicode):
+        url = url.encode('utf-8')
     return Response('', code=code, headers={'Location': url})
 
 def abort(code):
     raise HttpError(code)
-    
+
 
 HTTP_CODES = {
     100:    'Continue',
 import os
 from setuptools import setup
 
-VERSION = '0.8.7'
+VERSION = '0.8.8'
 PACKAGE = 'pysi'
 
 if __name__ == '__main__':
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.