1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 Application Wrapper
19 ===================
20
21 This modules wraps the WSGI interface, initializes middleware and provides
22 an application friendly wrapper.
23 """
24 __author__ = u"Andr\xe9 Malo"
25 __docformat__ = "restructuredtext en"
26
27 from wtf import util as _util
28 from wtf.app import response as _response
29
30
32 """
33 Main dispatching loop
34
35 :IVariables:
36 - `config`: Configuration
37 - `opts`: Command line options
38 - `args`: Positioned command line arguments
39
40 :Types:
41 - `config`: `wtf.config.Config`
42 - `opts`: ``optparse.OptionContainer``
43 - `args`: ``list``
44 """
45
47 """
48 Initialization
49
50 :Parameters:
51 - `config`: Configuration
52 - `opts`: Command line options
53 - `args`: Positioned command line arguments
54
55 :Types:
56 - `config`: `wtf.config.Config`
57 - `opts`: ``optparse.OptionContainer``
58 - `args`: ``list``
59 """
60 self.config, self.opts, self.args = config, opts, args
61 self._resolver = _util.load_dotted(config.app.resolver)(
62 config, opts, args
63 )
64 self._request = _util.load_dotted(
65 config.app('request', 'wtf.app.request.Request'))
66 self._response = _util.load_dotted(
67 config.app('response', 'wtf.app.response.Response'))
68
69 if 'codec' in config.app and 'cookie' in config.app.codec:
70 cookie_codec = config.app.codec.cookie.encode('ascii')
71 else:
72 cookie_codec = 'wtf.app.cookie.DefaultCookie'
73
74 self._addenv = {
75 'wtf.codec.cookie':
76 _util.load_dotted(cookie_codec)(config, opts, args)(),
77 }
78
79 - def __call__(self, environ, start_response):
80 """
81 WSGI entry point
82
83 :Parameters:
84 - `environ`: WSGI environment
85 - `start_response`: Response starter callable
86
87 :Types:
88 - `environ`: ``dict``
89 - `start_response`: ``callable``
90 """
91 environ.update(self._addenv)
92 req = self._request(environ)
93 resp = self._response(req, start_response)
94 func, errorfuncs = None, set()
95 while True:
96 try:
97 try:
98 try:
99 if func is None:
100 func = self._resolver.resolve(req)
101 ret = func(req, resp)
102 except _response.Done:
103 ret = None
104 resp.write('')
105 return ret or []
106 except _response.http.HTTPRedirectResponse, e:
107 e.param['location'] = abs_location(
108 req, e.param['location']
109 )
110 raise
111 except _response.http.HTTPResponse, e:
112 resp.status(e.status, e.reason)
113 func = self._resolver.error(e.status)
114 if func and func not in errorfuncs:
115 errorfuncs.add(func)
116 continue
117 e.headers(resp.headers)
118 resp.write('')
119 return [e.body()]
120
121
122 break
123
124
126 """ Make absolute location """
127 import urlparse as _urlparse
128
129 if isinstance(location, unicode):
130 location = location.encode('utf-8')
131 else:
132 location = str(location)
133 parsed = _urlparse.urlparse(location)
134 if parsed[0] and parsed[1]:
135 return location
136 return str(request.abs_uri(location, decode=False))
137