我的配置中有以下内容作为图像的反向代理:
location ~ ^/image/(.+) {
proxy_pass http://example.com/$1;
}
问题是并非所有图像都是example.com图像,因此我们需要传入完整的URL。如果我尝试:
location ~ ^/image/(.+) {
proxy_pass $1;
}
我收到错误:
invalid URL prefix in "https:/somethingelse.com/someimage.png"
答案 0 :(得分:0)
问题非常模糊,但是,根据错误消息,您尝试执行的操作是完全基于用户输入执行proxy_pass
,方法是使用{之后指定的完整网址{1}} URI的前缀。
基本上,这是一个非常糟糕的主意,因为您正在打开自己以成为一个开放的代理。但是,它在您提供的配置中不起作用的原因是由于URL规范化,在您的情况下,将/image/
压缩为http://example
(双斜杠变为单一),这是在http:/example
的背景下有所不同。
如果您不关心安全性,只需将merge_slashes
从默认的proxy_pass
更改为on
:
off
另一种可能性与nginx proxy_pass and URL decoding
有些相关merge_slashes off;
location …
正确的解决方案是实施白名单,可能借助于location ~ ^/image/.+ {
rewrite ^ $request_uri;
rewrite ^/image/(.*) $1 break;
return 400;
proxy_pass $uri; # will result in an open-proxy, don't try at home
}
甚至是基于前缀的位置指令:
map
请注意,根据前面的说明,上面的位置受location ~ ^/image/(http):/(upload.example.org)/(.*) {
proxy_pass $1://$2/$3;
}
设置的约束,因此,默认情况下它永远不会有双merge_slash
,因此需要在//
阶段手动添加双//
。
答案 1 :(得分:0)
在这种情况下我会使用地图
map $request_uri $proxied_url {
# if you don't care about domain and file extension
~*/image/(https?)://?(.*) $1://$2;
# if you want to limit file extension
~*/image/(https?)://?(.*\.(png|jpg|jpeg|ico))$ $1://$2;
# if you want to limit file extension and domain
~*/image/(https?)://?(abc\.xyz\.com/)(.*\.(png|jpg|jpeg|ico))$ $1://$2$3;
default "/404";
}
然后在您的代理传递部分中,您将使用类似下面的内容
location /image/ {
proxy_pass $proxied_url;
}
我根据你想要的方式给出了三个不同的例子