Changeset 1157
- Timestamp:
- 06/25/06 01:59:19
- Files:
-
- trunk/cherrypy/_cprequest.py (modified) (3 diffs)
- trunk/cherrypy/test/test_objectmapping.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cprequest.py
r1149 r1157 499 499 # Try a "default" method on the current leaf. 500 500 defhandler = getattr(candidate, "default", None) 501 if callable(defhandler) andgetattr(defhandler, 'exposed', False):501 if getattr(defhandler, 'exposed', False): 502 502 # Insert any extra _cp_config from the default handler. 503 503 conf = getattr(defhandler, "_cp_config", {}) … … 510 510 511 511 # Try the current leaf. 512 if callable(candidate) andgetattr(candidate, 'exposed', False):512 if getattr(candidate, 'exposed', False): 513 513 set_conf() 514 514 if i == len(object_trail) - 1: … … 528 528 529 529 default_dispatch = Dispatcher() 530 531 532 class MethodDispatcher(Dispatcher): 533 """Additional dispatch based on cherrypy.request.method.upper(). 534 535 Methods named GET, POST, etc will be called on an exposed class. 536 The method names must be all caps; the appropriate Allow header 537 will be output showing all capitalized method names as allowable 538 HTTP verbs. 539 540 Note that the containing class must be exposed, not the methods. 541 """ 542 543 def __call__(self, path_info): 544 """Set handler and config for the current request.""" 545 request = cherrypy.request 546 resource, vpath = self.find_handler(path_info) 547 548 # Decode any leftover %2F in the virtual_path atoms. 549 vpath = [x.replace("%2F", "/") for x in vpath] 550 551 if resource: 552 # Set Allow header 553 avail = [m for m in dir(resource) if m.isupper()] 554 if "GET" in avail and "HEAD" not in avail: 555 avail.append("HEAD") 556 avail.sort() 557 cherrypy.response.headers['Allow'] = ", ".join(avail) 558 559 # Find the subhandler 560 meth = cherrypy.request.method.upper() 561 func = getattr(resource, meth, None) 562 if func is None and meth == "HEAD": 563 func = getattr(resource, "GET", None) 564 if func: 565 def handler(): 566 cherrypy.response.body = func(*vpath, **request.params) 567 request.handler = handler 568 return 569 else: 570 def notallowed(): 571 raise cherrypy.HTTPError(405) 572 request.handler = notallowed 573 else: 574 def notfound(): 575 raise cherrypy.NotFound() 576 request.handler = notfound 530 577 531 578 trunk/cherrypy/test/test_objectmapping.py
r1106 r1157 103 103 default.exposed = True 104 104 105 class ByMethod: 106 exposed = True 107 108 def __init__(self, *things): 109 self.things = list(things) 110 111 def GET(self): 112 return repr(self.things) 113 114 def POST(self, thing): 115 self.things.append(thing) 105 116 106 117 Root.exposing = Exposing() … … 111 122 Root.dir1.dir2.dir3.dir4 = Dir4() 112 123 Root.defnoindex = DefNoIndex() 113 124 Root.bymethod = ByMethod('another') 114 125 115 126 for url in script_names: 116 conf = {'user': (url or "/").split("/")[-2]} 117 cherrypy.tree.mount(Root(), url, {'/': conf}) 127 d = cherrypy._cprequest.MethodDispatcher() 128 conf = {'/': {'user': (url or "/").split("/")[-2]}, 129 '/bymethod': {'dispatch': d}, 130 } 131 cherrypy.tree.mount(Root(), url, conf) 118 132 119 133 cherrypy.config.update({ … … 240 254 self.getPage("/exposingnew/2") 241 255 self.assertBody("expose works!") 242 256 257 def testMethodDispatch(self): 258 self.getPage("/bymethod") 259 self.assertBody("['another']") 260 self.assertHeader('Allow', 'GET, HEAD, POST') 261 262 self.getPage("/bymethod", method="HEAD") 263 self.assertBody("") 264 self.assertHeader('Allow', 'GET, HEAD, POST') 265 266 self.getPage("/bymethod", method="POST", body="thing=one") 267 self.assertBody("") 268 self.assertHeader('Allow', 'GET, HEAD, POST') 269 270 self.getPage("/bymethod") 271 self.assertBody("['another', 'one']") 272 self.assertHeader('Allow', 'GET, HEAD, POST') 273 274 self.getPage("/bymethod", method="PUT") 275 self.assertErrorPage(405) 276 self.assertHeader('Allow', 'GET, HEAD, POST') 243 277 244 278

