惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
I
InfoQ
U
Unit 42
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
月光博客
月光博客
D
Docker
Stack Overflow Blog
Stack Overflow Blog
D
DataBreaches.Net
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
V
Visual Studio Blog
博客园 - 聂微东
A
About on SuperTechFans
腾讯CDC
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
博客园 - 【当耐特】
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
M
MIT News - Artificial intelligence

达拉斯・卢

一些没有意义的事情 博客程序的一次大重构 OpenWRT 使用 udp2raw 对抗 WireGuard 阻断 如何证明你是原创作者 Nginx 泛域名配置的隐患与对策 WISeID S/MIME 证书 V2EX 刑满释放记 使用 Radicale 在 Ubuntu 24.04 中搭建 vCards CardDav 服务 邮件服务的域名成功从 SURBL 黑名单移除 网站多语言的设计细节 网站评论系统的目前进展和展望 在公网使用 iptables 转发端口时保留客户端 IP 邮件投递平台 Postal 的使用经验 自建 Postal 完美替代 SendGrid 互联网在崩塌吗,然后呢 在 SvelteKit 应用中使用 JSON-LD 网页的打印样式应该怎么写 “茴字的四种写法”之 IP 与域名 怎么伪造 Git 提交的时区 供大众交流的论坛和其它替代产品还是不好用 Nginx 反代 Apache Subversion 添加 HTTPS 使用你的主域名作为 Mastodon 实例名 使用你的主网域作為 Mastodon 實例名 Firefox 和 Chrome 为何要革 EV 证书的命 Firefox 和 Chrome 为何要革 EV 证书的命
Nginx 反代 Apache Subversion
达拉斯・卢 · 2022-01-03 · via 达拉斯・卢

Subversion 聽上去像是十年前的東西了,尤其是 mod_dav_svn。不過祖傳代碼放在哪裡可就不好說了。總之,你已經有了一個現成的 Nginx,希望為已經一個一直裸奔著的代碼倉庫添加 HTTPS 的支持,但並非一句 proxy_pass 就能搞得定。

例如:

upstream subversion{
    127.0.0.1:1080;
}
server{
    listen [::]:443;
    server_name svn.example.com;

    # SSL ...

    location / {
        proxy_pass http://subversion;
    }
}

首先,恭喜一下,沒有使用 proxy_pass http://subversion/,避免了第一個坑。因為結尾的 / 字符會使得 Nginx 自動對 URL 進行編碼,從而影響正常使用。但馬上就會在提交時會遇到 502 錯誤。

COPY 和 DELETE 的支援

Subversion 認爲 https://svn.example.com 是一个 HTTPS 連結,而 Apache 只提供了 HTTP 服務,所以請求 Header 中的 Destination 應以 http:// 開頭才能正常工作。

很快,你從 Stackoverfollow 找到了修改的辦法:

location / {
    proxy_pass http://subversion;
    set $fixed_destination $http_destination;
    if ( $http_destination ~* ^https(.*)$ ) {
        set $fixed_destination http$1;
    }
    proxy_set_header Destination $fixed_destination;
}

然後發現一切 OK。很好,果然掉進了第二個坑。

Nginx 的迷惑行爲

$fixed_destination 看起來只是把 https:// 替換成了 http://,非常簡單明瞭,沒有問題。

當你愉快地從主幹上複製了一個新分支,修改了一個檔案名包含中文的檔案,順利地編譯並通過測試;然後再合併回主乾時,如果足夠細心的話,就會發現這個檔案名被 urlencode 了。當然,並不是僅僅包括中文名檔案,想像一下,可是分支中的提交的所有檔案的名字都被 urlencode 了哦!而且已經被 urlencode 過的檔案名,下次合併分支時還會被再 urlencode 一次哦!

問題就在於 $fixed_destinationhttp$1 其實就被 Nginx 進行了一次 urlencode。也許你決定把修改 Destination 的操作交給 Apache,或者決定寫一段 lua 腳本進行解碼,來規避這個神奇的問題。且慢!這裡還有一個神奇的解決辦法:

location / {
    proxy_pass http://subversion;
    set $fixed_destination $http_destination;
    if ( $http_destination ~* ^https(?<unencoded_destinaton>.*)$ ) {
        set $fixed_destination http$unencoded_destinaton;
    }
    proxy_set_header Destination $fixed_destination;
}

給匹配用的正則組加一個命名就 OK 了……

其他

這個解決方案出自 Maxim Dounin 九年多以前的回复。所以,在 Nginx 中使用正則修改變量最好使用命名捕獲組

十年前的架構,十年前的問題,十年後仍然存在。神奇的是,十年前的方案仍然管用。