Removed some leftovers from media.xsl.
[enkel.git] / enkel / batteri / session.py
blob9073dbcba8f0a41e4f4fcb18fe9e816427bfc2f9
1 # This file is part of the Enkel web programming library.
3 # Copyright (C) 2007 Espen Angell Kristiansen (espeak@users.sourceforge.net)
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 from enkel.cookie import Cookie, get_cookies
20 from enkel.session.backend import NoSuchSessionError
23 class StartResponseWrapper(object):
24 """ Used by SessionMiddleware. """
25 def __init__(self, start_response, cookie):
26 self.start_response = start_response
27 self.cookie = cookie
29 def __call__(self, status, headers, exc_info=None):
30 headers.append(self.cookie.get_httpheader())
31 return self.start_response(status, headers, exc_info)
34 class SessionMiddleware(object):
35 """ A session middleware.
37 Test/Example
38 ============
39 >>> from enkel.wansgli.apptester import AppTester
40 >>> from enkel.session.memory import MemorySession
42 >>> def myapp(env, start_response):
43 ... start_response("200 OK", [("Content-type", "text/plain")])
44 ... session = env["enkel.session"]
45 ... if "num" in session:
46 ... session["num"] += 1
47 ... else:
48 ... session["num"] = 0
49 ... return ["This is call number %(num)d to this app" % session]
51 >>> class MyBackend(MemorySession):
52 ... def generate_sid(self):
53 ... return "xxAb"
55 >>> b = MyBackend()
56 >>> sessionapp = SessionMiddleware(myapp, b)
58 >>> AppTester(sessionapp).run_get().body
59 'This is call number 0 to this app'
61 >>> t = AppTester(sessionapp)
62 >>> t.set_env("HTTP_COOKIE", "sid=xxAb")
63 >>> t.run_get().body
64 'This is call number 1 to this app'
66 @cvar ENV_KEY: The environ key used to contain the session.
67 """
68 ENV_KEY = "enkel.session"
69 def __init__(self, app, backend, cookiename="sid",
70 cookiedomain=None, cookiepath="/"):
71 """
72 @param app: A WSGI application.
73 @param backend: A session backend following the
74 L{enkel.session.backend.SessionBackend} interface.
75 @param cookiename: The name of the session cookie.
76 @param cookiedomain: See L{enkel.cookie.Cookie.domain}.
77 @param cookiepath: See L{enkel.cookie.Cookie.path}.
78 """
79 self.app = app
80 self.backend = backend
81 self.cookiename = cookiename
82 self.cookiedomain = cookiedomain
83 self.cookiepath = cookiepath
85 def __call__(self, env, start_response):
87 # import info from cookie
88 cookies = get_cookies(env)
89 session = None
90 if cookies and self.cookiename in cookies:
91 try:
92 sid = cookies[self.cookiename]
93 except KeyError:
94 pass
95 else:
96 try:
97 session = self.backend.load(sid)
98 except NoSuchSessionError:
99 pass
101 if session == None:
102 session = dict()
103 sid = self.backend.generate_sid()
104 env[self.ENV_KEY] = session
106 # create new cookie
107 cookie = Cookie(self.cookiename, sid)
108 cookie.path = self.cookiepath
109 cookie.domain = self.cookiedomain
110 cookie.set_timeout(self.backend.timeout)
112 # run app
113 sr = StartResponseWrapper(start_response, cookie)
114 for buf in self.app(env, sr):
115 yield buf
116 self.backend.save(sid, session)
120 def suite():
121 import doctest
122 return doctest.DocTestSuite()
124 if __name__ == "__main__":
125 from enkel.wansgli.testhelpers import run_suite
126 run_suite(suite())