diff options
author | Marc Abramowitz <marc@marc-abramowitz.com> | 2015-04-30 17:39:24 -0700 |
---|---|---|
committer | Marc Abramowitz <marc@marc-abramowitz.com> | 2015-04-30 17:39:24 -0700 |
commit | fa100c92c06d3a8a61a0dda1a2e06018437b09c6 (patch) | |
tree | a1cc50f93fbf257685c3849e03496c5e33949281 /paste/flup_session.py | |
download | paste-git-fa100c92c06d3a8a61a0dda1a2e06018437b09c6.tar.gz |
test_wsgirequest_charset: Use UTF-8 instead of iso-8859-1test_wsgirequest_charset_use_UTF-8_instead_of_iso-8859-1
because it seems that the defacto standard for encoding URIs is to use UTF-8.
I've been reading about url encoding and it seems like perhaps using an
encoding other than UTF-8 is very non-standard and not well-supported (this
test is trying to use `iso-8859-1`).
From http://en.wikipedia.org/wiki/Percent-encoding
> For a non-ASCII character, it is typically converted to its byte sequence in
> UTF-8, and then each byte value is represented as above.
> The generic URI syntax mandates that new URI schemes that provide for the
> representation of character data in a URI must, in effect, represent
> characters from the unreserved set without translation, and should convert
> all other characters to bytes according to UTF-8, and then percent-encode
> those values. This requirement was introduced in January 2005 with the
> publication of RFC 3986
From http://tools.ietf.org/html/rfc3986:
> Non-ASCII characters must first be encoded according to UTF-8 [STD63], and
> then each octet of the corresponding UTF-8 sequence must be percent-encoded
> to be represented as URI characters. URI producing applications must not use
> percent-encoding in host unless it is used to represent a UTF-8 character
> sequence.
From http://tools.ietf.org/html/rfc3987:
> Conversions from URIs to IRIs MUST NOT use any character encoding other than
> UTF-8 in steps 3 and 4, even if it might be possible to guess from the
> context that another character encoding than UTF-8 was used in the URI. For
> example, the URI "http://www.example.org/r%E9sum%E9.html" might with some
> guessing be interpreted to contain two e-acute characters encoded as
> iso-8859-1. It must not be converted to an IRI containing these e-acute
> characters. Otherwise, in the future the IRI will be mapped to
> "http://www.example.org/r%C3%A9sum%C3%A9.html", which is a different URI from
> "http://www.example.org/r%E9sum%E9.html".
See issue #7, which I think this at least partially fixes.
Diffstat (limited to 'paste/flup_session.py')
-rw-r--r-- | paste/flup_session.py | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/paste/flup_session.py b/paste/flup_session.py new file mode 100644 index 0000000..6f5c750 --- /dev/null +++ b/paste/flup_session.py @@ -0,0 +1,108 @@ +# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) +# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php + +""" +Creates a session object. + +In your application, use:: + + environ['paste.flup_session_service'].session + +This will return a dictionary. The contents of this dictionary will +be saved to disk when the request is completed. The session will be +created when you first fetch the session dictionary, and a cookie will +be sent in that case. There's current no way to use sessions without +cookies, and there's no way to delete a session except to clear its +data. +""" + +from paste import httpexceptions +from paste import wsgilib +import flup.middleware.session +flup_session = flup.middleware.session + +# This is a dictionary of existing stores, keyed by a tuple of +# store type and parameters +store_cache = {} + +class NoDefault(object): + pass + +class SessionMiddleware(object): + + session_classes = { + 'memory': (flup_session.MemorySessionStore, + [('session_timeout', 'timeout', int, 60)]), + 'disk': (flup_session.DiskSessionStore, + [('session_timeout', 'timeout', int, 60), + ('session_dir', 'storeDir', str, '/tmp/sessions')]), + 'shelve': (flup_session.ShelveSessionStore, + [('session_timeout', 'timeout', int, 60), + ('session_file', 'storeFile', str, + '/tmp/session.shelve')]), + } + + + def __init__(self, app, + global_conf=None, + session_type=NoDefault, + cookie_name=NoDefault, + **store_config + ): + self.application = app + if session_type is NoDefault: + session_type = global_conf.get('session_type', 'disk') + self.session_type = session_type + try: + self.store_class, self.store_args = self.session_classes[self.session_type] + except KeyError: + raise KeyError( + "The session_type %s is unknown (I know about %s)" + % (self.session_type, + ', '.join(self.session_classes.keys()))) + kw = {} + for config_name, kw_name, coercer, default in self.store_args: + value = coercer(store_config.get(config_name, default)) + kw[kw_name] = value + self.store = self.store_class(**kw) + if cookie_name is NoDefault: + cookie_name = global_conf.get('session_cookie', '_SID_') + self.cookie_name = cookie_name + + def __call__(self, environ, start_response): + service = flup_session.SessionService( + self.store, environ, cookieName=self.cookie_name, + fieldName=self.cookie_name) + environ['paste.flup_session_service'] = service + + def cookie_start_response(status, headers, exc_info=None): + service.addCookie(headers) + return start_response(status, headers, exc_info) + + try: + app_iter = self.application(environ, cookie_start_response) + except httpexceptions.HTTPException as e: + headers = (e.headers or {}).items() + service.addCookie(headers) + e.headers = dict(headers) + service.close() + raise + except: + service.close() + raise + + return wsgilib.add_close(app_iter, service.close) + +def make_session_middleware(app, global_conf, + session_type=NoDefault, + cookie_name=NoDefault, + **store_config): + """ + Wraps the application in a session-managing middleware. + The session service can then be found in + ``environ['paste.flup_session_service']`` + """ + return SessionMiddleware( + app, global_conf=global_conf, + session_type=session_type, cookie_name=cookie_name, + **store_config) |