1 import cherrypy
2 from cherrypy._cpcompat import ntou
3 from cherrypy._cptree import Application
4 from cherrypy.test import helper
5
6 script_names = ["", "/foo", "/users/fred/blog", "/corp/blog"]
7
8
10
12 class Root:
13 def index(self, name="world"):
14 return name
15 index.exposed = True
16
17 def foobar(self):
18 return "bar"
19 foobar.exposed = True
20
21 def default(self, *params, **kwargs):
22 return "default:" + repr(params)
23 default.exposed = True
24
25 def other(self):
26 return "other"
27 other.exposed = True
28
29 def extra(self, *p):
30 return repr(p)
31 extra.exposed = True
32
33 def redirect(self):
34 raise cherrypy.HTTPRedirect('dir1/', 302)
35 redirect.exposed = True
36
37 def notExposed(self):
38 return "not exposed"
39
40 def confvalue(self):
41 return cherrypy.request.config.get("user")
42 confvalue.exposed = True
43
44 def redirect_via_url(self, path):
45 raise cherrypy.HTTPRedirect(cherrypy.url(path))
46 redirect_via_url.exposed = True
47
48 def translate_html(self):
49 return "OK"
50 translate_html.exposed = True
51
52 def mapped_func(self, ID=None):
53 return "ID is %s" % ID
54 mapped_func.exposed = True
55 setattr(Root, "Von B\xfclow", mapped_func)
56
57
58 class Exposing:
59 def base(self):
60 return "expose works!"
61 cherrypy.expose(base)
62 cherrypy.expose(base, "1")
63 cherrypy.expose(base, "2")
64
65 class ExposingNewStyle(object):
66 def base(self):
67 return "expose works!"
68 cherrypy.expose(base)
69 cherrypy.expose(base, "1")
70 cherrypy.expose(base, "2")
71
72
73 class Dir1:
74 def index(self):
75 return "index for dir1"
76 index.exposed = True
77
78 def myMethod(self):
79 return "myMethod from dir1, path_info is:" + repr(cherrypy.request.path_info)
80 myMethod.exposed = True
81 myMethod._cp_config = {'tools.trailing_slash.extra': True}
82
83 def default(self, *params):
84 return "default for dir1, param is:" + repr(params)
85 default.exposed = True
86
87
88 class Dir2:
89 def index(self):
90 return "index for dir2, path is:" + cherrypy.request.path_info
91 index.exposed = True
92
93 def script_name(self):
94 return cherrypy.tree.script_name()
95 script_name.exposed = True
96
97 def cherrypy_url(self):
98 return cherrypy.url("/extra")
99 cherrypy_url.exposed = True
100
101 def posparam(self, *vpath):
102 return "/".join(vpath)
103 posparam.exposed = True
104
105
106 class Dir3:
107 def default(self):
108 return "default for dir3, not exposed"
109
110 class Dir4:
111 def index(self):
112 return "index for dir4, not exposed"
113
114 class DefNoIndex:
115 def default(self, *args):
116 raise cherrypy.HTTPRedirect("contact")
117 default.exposed = True
118
119
120 class ByMethod:
121 exposed = True
122
123 def __init__(self, *things):
124 self.things = list(things)
125
126 def GET(self):
127 return repr(self.things)
128
129 def POST(self, thing):
130 self.things.append(thing)
131
132 class Collection:
133 default = ByMethod('a', 'bit')
134
135 Root.exposing = Exposing()
136 Root.exposingnew = ExposingNewStyle()
137 Root.dir1 = Dir1()
138 Root.dir1.dir2 = Dir2()
139 Root.dir1.dir2.dir3 = Dir3()
140 Root.dir1.dir2.dir3.dir4 = Dir4()
141 Root.defnoindex = DefNoIndex()
142 Root.bymethod = ByMethod('another')
143 Root.collection = Collection()
144
145 d = cherrypy.dispatch.MethodDispatcher()
146 for url in script_names:
147 conf = {'/': {'user': (url or "/").split("/")[-2]},
148 '/bymethod': {'request.dispatch': d},
149 '/collection': {'request.dispatch': d},
150 }
151 cherrypy.tree.mount(Root(), url, conf)
152
153
154 class Isolated:
155 def index(self):
156 return "made it!"
157 index.exposed = True
158
159 cherrypy.tree.mount(Isolated(), "/isolated")
160
161 class AnotherApp:
162
163 exposed = True
164
165 def GET(self):
166 return "milk"
167
168 cherrypy.tree.mount(AnotherApp(), "/app", {'/': {'request.dispatch': d}})
169 setup_server = staticmethod(setup_server)
170
171
173 for url in script_names:
174 prefix = self.script_name = url
175
176 self.getPage('/')
177 self.assertBody('world')
178
179 self.getPage("/dir1/myMethod")
180 self.assertBody("myMethod from dir1, path_info is:'/dir1/myMethod'")
181
182 self.getPage("/this/method/does/not/exist")
183 self.assertBody("default:('this', 'method', 'does', 'not', 'exist')")
184
185 self.getPage("/extra/too/much")
186 self.assertBody("('too', 'much')")
187
188 self.getPage("/other")
189 self.assertBody('other')
190
191 self.getPage("/notExposed")
192 self.assertBody("default:('notExposed',)")
193
194 self.getPage("/dir1/dir2/")
195 self.assertBody('index for dir2, path is:/dir1/dir2/')
196
197
198 self.getPage("/dir1/dir2")
199 self.assertStatus(301)
200 self.assertHeader('Location', '%s/dir1/dir2/' % self.base())
201
202
203 self.getPage("/dir1/myMethod/")
204 self.assertStatus(301)
205 self.assertHeader('Location', '%s/dir1/myMethod' % self.base())
206
207
208 self.getPage("/dir1/dir2/dir3/dir4/index")
209 self.assertBody("default for dir1, param is:('dir2', 'dir3', 'dir4', 'index')")
210
211
212
213 self.getPage("/defnoindex")
214 self.assertStatus((302, 303))
215 self.assertHeader('Location', '%s/contact' % self.base())
216 self.getPage("/defnoindex/")
217 self.assertStatus((302, 303))
218 self.assertHeader('Location', '%s/defnoindex/contact' % self.base())
219 self.getPage("/defnoindex/page")
220 self.assertStatus((302, 303))
221 self.assertHeader('Location', '%s/defnoindex/contact' % self.base())
222
223 self.getPage("/redirect")
224 self.assertStatus('302 Found')
225 self.assertHeader('Location', '%s/dir1/' % self.base())
226
227 if not getattr(cherrypy.server, "using_apache", False):
228
229
230 self.getPage("/Von%20B%fclow?ID=14")
231 self.assertBody("ID is 14")
232
233
234
235
236 self.getPage("/page%2Fname")
237 self.assertBody("default:('page/name',)")
238
239 self.getPage("/dir1/dir2/script_name")
240 self.assertBody(url)
241 self.getPage("/dir1/dir2/cherrypy_url")
242 self.assertBody("%s/extra" % self.base())
243
244
245 self.getPage("/confvalue")
246 self.assertBody((url or "/").split("/")[-2])
247
248 self.script_name = ""
249
250
251 self.getPage('http://%s:%s/' % (self.interface(), self.PORT))
252 self.assertBody('world')
253
254 self.getPage('http://%s:%s/abs/?service=http://192.168.0.1/x/y/z' %
255 (self.interface(), self.PORT))
256 self.assertBody("default:('abs',)")
257
258 self.getPage('/rel/?service=http://192.168.120.121:8000/x/y/z')
259 self.assertBody("default:('rel',)")
260
261
262
263
264 self.getPage("/isolated/")
265 self.assertStatus("200 OK")
266 self.assertBody("made it!")
267 self.getPage("/isolated/doesnt/exist")
268 self.assertStatus("404 Not Found")
269
270
271
272 self.getPage("/foobar")
273 self.assertBody("bar")
274
287
311
313 self.getPage("/dir1/dir2/posparam/18/24/hut/hike")
314 self.assertBody("18/24/hut/hike")
315
316
317
318 self.getPage("/dir1/dir2/5/3/sir")
319 self.assertBody("default for dir1, param is:('dir2', '5', '3', 'sir')")
320
321
322
323 self.getPage("/dir1/dir2/script_name/extra/stuff")
324 self.assertStatus(404)
325
345
347 self.getPage("/bymethod")
348 self.assertBody("['another']")
349 self.assertHeader('Allow', 'GET, HEAD, POST')
350
351 self.getPage("/bymethod", method="HEAD")
352 self.assertBody("")
353 self.assertHeader('Allow', 'GET, HEAD, POST')
354
355 self.getPage("/bymethod", method="POST", body="thing=one")
356 self.assertBody("")
357 self.assertHeader('Allow', 'GET, HEAD, POST')
358
359 self.getPage("/bymethod")
360 self.assertBody(repr(['another', ntou('one')]))
361 self.assertHeader('Allow', 'GET, HEAD, POST')
362
363 self.getPage("/bymethod", method="PUT")
364 self.assertErrorPage(405)
365 self.assertHeader('Allow', 'GET, HEAD, POST')
366
367
368 self.getPage("/collection/silly", method="POST")
369 self.getPage("/collection", method="GET")
370 self.assertBody("['a', 'bit', 'silly']")
371
372
373 self.getPage("/app")
374 self.assertBody("milk")
375
377 class Root(object):
378 def hello(self):
379 return "Hello world!"
380 hello.exposed = True
381
382
383
384 a = Application(Root(), '/somewhere')
385 self.assertRaises(ValueError, cherrypy.tree.mount, a, '/somewhereelse')
386
387
388 a = Application(Root(), '/somewhere')
389
390 cherrypy.tree.mount(a, '/somewhere')
391 self.getPage('/somewhere/hello')
392 self.assertStatus(200)
393
394 del cherrypy.tree.apps['/somewhere']
395 cherrypy.tree.mount(a)
396 self.getPage('/somewhere/hello')
397 self.assertStatus(200)
398
399
400
401 a = Application(Root(), script_name=None)
402
403 self.assertRaises(TypeError, cherrypy.tree.mount, a, None)
404