我有一个在nginx后面不能识别SSL的应用程序,因此我需要执行以下操作
http://example.com/f1/f2/page?next_page=http%3A//example.com/f3/new_page
必须改变
https://example.com/f1/f2/page?next_page=https%3A//example.com/f3/new_page
所以有两件事要做,改变我所能做到的scheme,并且改变我已经有所成就的url参数,但是它并不完全工作。
我发现了一个页面,做了我想做的,但它不适合我: https : //blog.imaginea.com/modifying-query-parameters-nginx-in-reverse-proxy-mode/
我的nginxconfiguration的相关部分:
server { listen 443 ssl; server_name example.com; ssl on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_certificate /path/to/bundle.crt; ssl_certificate_key /path/to/bundle.key; ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; ssl_prefer_server_ciphers on; underscores_in_headers on; rewrite_log on; location / { if ($args ~* (.*)(next_page=http%3A)(.*)) { set $args $1next_page=https%3A$3; rewrite ^(.*)$ $1; } proxy_pass http://127.0.0.1:80; proxy_redirect http:// https://; proxy_set_header Host $host; proxy_set_header HTTPS "on"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host:$server_port; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Port 443; } }
nginx_error.log:
2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" matches "next_page=http%3A//example.com/f3/new_page", client: XXXX, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com" 2017/09/20 13:48:13 [notice] 25115#0: *1 "^(.*)$" matches "/f1/f2/page", client: XXXX, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com" 2017/09/20 13:48:13 [notice] 25115#0: *1 rewritten data: "/f1/f2/page", args: "next_page=https3A//example.com/f3/new_page", client: XXXX, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com" 2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" does not match "next_page=https3A//example.com/f3/new_page", client: XXXX, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com" 2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" does not match "", client: XXXX, server: example.com, request: "GET /f1/f2/cookie/++resource++baseimg/regio.ico HTTP/1.1", host: "example.com", referrer: "https://example.com/f1/f2/page?next_page=http%3A//example.com/f3/new_page"
所以这个scheme被proxy_redirect改变了(我需要这样做,因为应用程序本身会redirect到一些http-URI),proxy_pass将它转发给正确的服务器,并且改变参数,但是请求不会改变。 我在这里错过了什么?
浏览器中显示的url:
https://example.com/f1/f1/page?next_page=http%3A//example.com/f3/new_page
顺便说一句。 nginx版本是1.10.1,我现在无法升级它
一个可能的问题是nginx可能不允许设置它自己定义的variables。 我不知道这是肯定的,这是一个受过教育的猜测。
这意味着您应该为参数使用不同的名称。
更好的办法是使用mapfunction来获取新的查询参数。
在configuration的http级别中,添加以下映射:
map $args $newargs { default $args; ~^(.*)next_page=http:(.*)$ $1next_page=https:$2; }
并在您的server块,使用以下location :
location / { proxy_pass http://127.0.0.1:80$uri$is_args$newargs; ... }
无论如何,你的设置看起来有点奇怪,因为你是代理的http端口,我认为这是运行在服务器上的nginx …我只是做一个redirect到https的所有请求到http端口。
所以,结果工作正在改变
if ($args ~* (.*)(next_page=http%3A)(.*)) { set $args $1next_page=https%3A$3; rewrite ^(.*)$ $1; } proxy_pass http://127.0.0.1:80; proxy_redirect http:// https://;
至
if ($args ~* (.*)(next_page=http%3A)(.*)) { set $args $1next_page=https%3A$3; rewrite ^.*$ $1 redirect; } proxy_pass http://127.0.0.1:80$uri$is_args$args; proxy_redirect http:// https://;