bottle.py: 全局修改(重写)用于测试网络应用程序的请求路径?

bottle.py: globally modify (rewrite) request path for testing a web-application?

我正在用 $ uwsgi --http :1024 --wsgi-file app.py 设置 bottle.py with uWSGI 运行。 app.py包含默认值:

import bottle
application = bottle.default_app()

以及许多路由装饰器和函数,例如:

@bottle.route('/<A>/<B>')
def somedef():
    return bottle.template(...)

这暂时由 http://example.com/secret_URL/ 提供,这当然会导致 <A> 总是被解析为 "secret_URL"。

如何修改 URL("rewrite",剥离 "secret_URL/"),以便 Web 应用程序,即 bottle 不 "see" 它?

我找到了 add_hook but so far I have not been able to modify the path of the request:

@bottle.hook('before_request')
def test():
    bottle.request.url = bottle.request.url.replace("secret_URL/","")

原因一目了然:

The Request class wraps a WSGI environment and provides helpful methods to parse and access form data, cookies, file uploads and other metadata. Most of the attributes are read-only.

文档还指出:

Adding new attributes to a request actually adds them to the environ dictionary (as ‘bottle.request.ext.’). This is the recommended way to store and access request-specific data.

environ

The wrapped WSGI environ dictionary. This is the only real attribute. All other attributes actually are read-only properties.

bottle.request.environ 包含 REQUEST_URI, PATH_INFO, bottle.raw_path, bottle.request, bottle.request.urlparts 和一些对象。

这些中哪些是可以写的,哪些需要写才能达到预期的效果?

这也提出了如何在客户端处理此类链接的问题 HTML 而不更改每个链接 href

通过反复试验:

@bottle.hook('before_request')
def test():
    bottle.request.environ['PATH_INFO'] = bottle.request.environ['PATH_INFO'].replace("secret_URL/","")

对于客户:

  • 相对 URL 可能是一种解决方案,但它们会破坏用户副本(除非浏览器替换它们)并且应用程序需要跟踪路径级别
  • 相对于来源的 URL 可能适用于 <base>(下面的 link)

相关:


来自https://bottlepy.org/docs/stable/recipes.html?highlight=cache#ignore-trailing-slashes

or add a WSGI middleware that strips trailing slashes from all URLs:

class StripPathMiddleware(object):
  def __init__(self, app):
    self.app = app
  def __call__(self, e, h):
    e['PATH_INFO'] = e['PATH_INFO'].rstrip('/')
    return self.app(e,h)

app = bottle.app()
myapp = StripPathMiddleware(app)
bottle.run(app=myapp)