我想根据web.py中的某种形式的身份验证有选择地隐藏一些资源,但是它们的存在是由我对任何尚未实现的HTTP方法的405响应所揭示的.
这是一个例子:
import web
urls = (
'/secret','secret',)
app = web.application(urls,globals())
class secret():
def GET(self):
if web.cookies().get('password') == 'secretpassword':
return "Dastardly secret plans..."
raise web.notfound()
if __name__ == "__main__":
app.run()
$curl -v -X DELETE http://localhost:8080/secret
...
> DELETE /secret HTTP/1.1
...
< HTTP/1.1 405 Method Not Allowed
< Content-Type: text/html
< Allow: GET
...
我可以对HTTP规范中的其他常见方法执行相同的检查,但是创造性的不法分子可能会创建自己的:
$curl -v -X SHENANIGANS http://localhost:8080/secret
...
> SHENANIGANS /secret HTTP/1.1
...
< HTTP/1.1 405 Method Not Allowed
< Content-Type: text/html
< Allow: GET
...
有没有办法在web.py类中为任何HTTP方法实现catch all方法,所以我可以确保运行安全检查?
或者是否有另一种隐藏这些资源的方法?
最佳答案
在Daniel Kluev的回答的启发下,我最终从web.application派生出来,在_delegate方法中添加了对默认方法的支持:
import types
class application(web.application):
def _delegate(self,f,fvars,args=[]):
def handle_class(cls):
meth = web.ctx.method
if meth == 'HEAD' and not hasattr(cls,meth):
meth = 'GET'
if not hasattr(cls,meth):
if hasattr(cls,'_default'):
tocall = getattr(cls(),'_default')
return tocall(*args)
raise web.nomethod(cls)
tocall = getattr(cls(),meth)
return tocall(*args)
def is_class(o): return isinstance(o,(types.ClassType,type))
...
实例:
app = application(urls,globals())
页面类:
class secret():
def _default(self):
raise web.notfound()
def GET(self):
...
我更喜欢这种解决方案,因为它可以保持页面类清洁,并在一个地方提供进一步的自定义委派过程.例如,我想要的另一个功能是透明重载POST(例如,使用method = DELETE将POST请求重定向到页面类的DELETE方法),这里也很容易添加:
...
meth = web.ctx.method
if meth == 'POST' and 'method' in web.input():
meth = web.input()['method']
...