bigywater.tech
Flask · 134

HTTPS 与反向代理

HTTPS 在 nginx 终止之后,Flask 怎么知道用户走的是 https?重定向和外部链接会不会变成 http?上传限制和流式响应经过 nginx 会怎样?这篇起一个真的 nginx 与 gunicorn,把每种配置的结果量出来。

http → https
没有处理代理头时,308 重定向的 Location 变成 http 的方向
413
nginx 在请求到达 Flask 之前拒绝超过 client_max_body_size 的上传
1551 → 311 ms
proxy_buffering on 与 off 时流式响应第一块到达的时间

Flask 看到的是 http

实测 · 本机执行输出
  /info → {'external': 'http://localhost:9603/info', 'host': 'localhost:9603', 'is_secure': False, 'remote_addr': '127.0.0.1', 'scheme': 'http'}
  GET /dir(规则是 /dir/)→ 308 Location: http://localhost:9603/dir/

上一篇:安全响应头;下一篇:信任代理头配置。

nginx 是自己用 brew 装的,用自己的配置文件跑在非默认端口,证书是临时生成的自签证书(请求时关闭证书校验)。

gunicorn 的默认行为

实测 · 本机执行输出
  /info → {'external': 'https://localhost:9606/info', 'host': 'localhost:9606', 'is_secure': True, 'remote_addr': '127.0.0.1', 'scheme': 'https'}
  GET /dir(规则是 /dir/)→ 308 Location: https://localhost:9606/dir/
  (gunicorn 自己把 X-Forwarded-Proto 翻译成了 wsgi.url_scheme)

ProxyFix 显式信任

实测 · 本机执行输出
  /info → {'external': 'https://localhost:9609/info', 'host': 'localhost:9609', 'is_secure': True, 'remote_addr': '127.0.0.1', 'scheme': 'https'}
  GET /dir(规则是 /dir/)→ 308 Location: https://localhost:9609/dir/

http 跳转 https

实测 · 本机执行输出
  http://…/info?x=1 → 301 Location: https://127.0.0.1:9612/info?x=1

nginx 先于 Flask 的限制

实测 · 本机执行输出
  上传 500 KB → 200 ('512000')
  上传 900 KB → 200 ('921600')
  上传 1100 KB → 413 (nginx 直接拒绝,请求没有到达 Flask)
  上传 3000 KB → 413 (nginx 直接拒绝,请求没有到达 Flask)
  client_max_body_size 5m 后上传 3000 KB → 200

代理缓冲与流式响应

实测 · 本机执行输出
  proxy_buffering on  读到每一块数据的时间(ms): [1551, 1551, 1551, 1551, 1551]
  proxy_buffering off 读到每一块数据的时间(ms): [311, 617, 918, 1222, 1533]

分步演示

HTTPS 与反向代理
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。nginx 1.31.6(自己的配置、非默认端口)、gunicorn、自签证书
    • 没有验证:Let's Encrypt 等真实证书的签发与续期、HTTP/2 与 HTTP/3、TLS 版本与密码套件配置、WebSocket 的升级头配置(见第 150 篇)、X-Accel-Buffering 头、proxy_read_timeout 对慢请求的 504
    京ICP备2026067502号-1京公网安备11010502063487号