sanic-org/sanic

Use reverse proxy headers (x-forwarded-proto, x-forwarded-path, ...) in url_for construction

开放

#2,471 创建于 2022年5月26日

 (5 条评论) (0 个反应) (0 位负责人)Python (1,515 个派生)batch import
feature requesthelp wanted

仓库指标

星标
 (17,623 个星标)
PR 合并指标
 (30 天内没有已合并 PR)

描述

Is your feature request related to a problem? Please describe. I'm running Sanic behind an nginx reverse proxy, mounted to a subdirectory. I want app.url_for(_external=True) to return correct absolute URLs. In my own code I have a helper function for that, but extensions (like the openapi code in sanic-ext) don't know about them.

Describe the solution you'd like The current documentation regarding proxy headers (https://github.com/sanic-org/sanic-guide/blob/927cebaf33394481810f0c50dac15898edd4ed67/src/en/guide/advanced/proxy-headers.md?plain=1#L48) suggests that the headers x-forwarded-proto, x-forwarded-host, x-forwarded-port, x-forwarded-path, and x-scheme could be used for URL construction.

Example: Suppose I have a route like

@app.route("/hi")
async def hello(request):
    return html('<a href="' + app.url_for('hello', _external=True) + '">here</a>')

I have app.config.REAL_IP_HEADER = 'X-Real-IP' and a request comes in as

GET /hi HTTP/1.0
X-Real-IP: 198.51.100.23
X-Forwarded-Host: example.com
X-Forwarded-Path: /api
X-Forwarded-Proto: https

I want it to return <a href="https://example.com/api/hi">here</a>

Additional context There is a slight problem here in that url_for() doesn't receive the request object. For reference, django-rest-api for example solves this by always passing in the request into Serializers (which might call reverse()). But even adding a _request doesn't solve the problem of existing naive code that's calling url_for() with no request object (and might not even have a request object reference).

Is there some sort of context variable for "the current request", like in Flask?

贡献者指南