1 """CherryPy Application and Tree objects."""
2
3 import os
4 import cherrypy
5 from cherrypy import _cpconfig, _cplogging, _cprequest, _cpwsgi, tools
6 from cherrypy.lib import http as _http
7
8
10 """A CherryPy Application.
11
12 Servers and gateways should not instantiate Request objects directly.
13 Instead, they should ask an Application object for a request object.
14
15 An instance of this class may also be used as a WSGI callable
16 (WSGI application object) for itself.
17 """
18
19 __metaclass__ = cherrypy._AttributeDocstrings
20
21 root = None
22 root__doc = """
23 The top-most container of page handlers for this app. Handlers should
24 be arranged in a hierarchy of attributes, matching the expected URI
25 hierarchy; the default dispatcher then searches this hierarchy for a
26 matching handler. When using a dispatcher other than the default,
27 this value may be None."""
28
29 config = {}
30 config__doc = """
31 A dict of {path: pathconf} pairs, where 'pathconf' is itself a dict
32 of {key: value} pairs."""
33
34 namespaces = _cpconfig.NamespaceSet()
35 toolboxes = {'tools': cherrypy.tools}
36
37 log = None
38 log__doc = """A LogManager instance. See _cplogging."""
39
40 wsgiapp = None
41 wsgiapp__doc = """A CPWSGIApp instance. See _cpwsgi."""
42
43 request_class = _cprequest.Request
44 response_class = _cprequest.Response
45
46 relative_urls = False
47
48 - def __init__(self, root, script_name="", config=None):
61
63 return "%s.%s(%r, %r)" % (self.__module__, self.__class__.__name__,
64 self.root, self.script_name)
65
66 script_name__doc = """
67 The URI "mount point" for this app. A mount point is that portion of
68 the URI which is constant for all URIs that are serviced by this
69 application; it does not include scheme, host, or proxy ("virtual host")
70 portions of the URI.
71
72 For example, if script_name is "/my/cool/app", then the URL
73 "http://www.example.com/my/cool/app/page1" might be handled by a
74 "page1" method on the root object.
75
76 The value of script_name MUST NOT end in a slash. If the script_name
77 refers to the root of the URI, it MUST be an empty string (not "/").
78
79 If script_name is explicitly set to None, then the script_name will be
80 provided for each call from request.wsgi_environ['SCRIPT_NAME'].
81 """
83 if self._script_name is None:
84
85 return cherrypy.request.wsgi_environ['SCRIPT_NAME'].rstrip("/")
86 return self._script_name
88 if value:
89 value = value.rstrip("/")
90 self._script_name = value
91 script_name = property(fget=_get_script_name, fset=_set_script_name,
92 doc=script_name__doc)
93
100
115
128
129 - def __call__(self, environ, start_response):
131
132
134 """A registry of CherryPy applications, mounted at diverse points.
135
136 An instance of this class may also be used as a WSGI callable
137 (WSGI application object), in which case it dispatches to all
138 mounted apps.
139 """
140
141 apps = {}
142 apps__doc = """
143 A dict of the form {script name: application}, where "script name"
144 is a string declaring the URI mount point (no trailing slash), and
145 "application" is an instance of cherrypy.Application (or an arbitrary
146 WSGI callable if you happen to be using a WSGI server)."""
147
150
151 - def mount(self, root, script_name="", config=None):
152 """Mount a new app from a root object, script_name, and config.
153
154 root: an instance of a "controller class" (a collection of page
155 handler methods) which represents the root of the application.
156 This may also be an Application instance, or None if using
157 a dispatcher other than the default.
158 script_name: a string containing the "mount point" of the application.
159 This should start with a slash, and be the path portion of the
160 URL at which to mount the given root. For example, if root.index()
161 will handle requests to "http://www.example.com:8080/dept/app1/",
162 then the script_name argument would be "/dept/app1".
163
164 It MUST NOT end in a slash. If the script_name refers to the
165 root of the URI, it MUST be an empty string (not "/").
166 config: a file or dict containing application config.
167 """
168
169 script_name = script_name.rstrip("/")
170
171 if isinstance(root, Application):
172 app = root
173 if script_name != "" and script_name != app.script_name:
174 raise ValueError, "Cannot specify a different script name and pass an Application instance to cherrypy.mount"
175 script_name = app.script_name
176 else:
177 app = Application(root, script_name)
178
179
180 if (script_name == "" and root is not None
181 and not hasattr(root, "favicon_ico")):
182 favicon = os.path.join(os.getcwd(), os.path.dirname(__file__),
183 "favicon.ico")
184 root.favicon_ico = tools.staticfile.handler(favicon)
185
186 if config:
187 app.merge(config)
188
189 self.apps[script_name] = app
190
191 return app
192
193 - def graft(self, wsgi_callable, script_name=""):
198
200 """The script_name of the app at the given path, or None.
201
202 If path is None, cherrypy.request is used.
203 """
204
205 if path is None:
206 try:
207 path = _http.urljoin(cherrypy.request.script_name,
208 cherrypy.request.path_info)
209 except AttributeError:
210 return None
211
212 while True:
213 if path in self.apps:
214 return path
215
216 if path == "":
217 return None
218
219
220 path = path[:path.rfind("/")]
221
222 - def __call__(self, environ, start_response):
240