NGINX 1.13.8 Rewrite url not works
This should be possible to do without using the rewrite command.
location ~* /payment/gateway/v2/order/complete/(.+)$ {
proxy_pass http://api.test.com:8085/payment/gateway/v2/order/complete?order_id=$1;
}
In this example we use the case insensitive regex (~*
) to capture everything after complete
in the URL, then inside the location we rebuild the request using the $1.
To test the setup, I added a configuration to my nginx:
server {
listen 80;
server_name localhost;
location ~* /payment/gateway/v2/order/complete/(.+)$ {
proxy_pass http://localhost:8085/payment/gateway/v2/order/complete?order_id=$1;
}
location / {
return 404;
}
}
server {
listen 8085;
server_name localhost;
location ~ /payment/gateway/v2/order/complete(.*) {
return 202;
}
}
This is configured so that a successful hit will be proxied to the other server and return a 202, and any unsuccessful hit will result in a 40x response.
This can be tested from the 'client side' using curl, like this:
$ curl -v http://localhost:80/payment/gateway/v2/order/complete/1234 -L
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /payment/gateway/v2/order/complete/1234 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 202 Accepted
< Server: nginx/1.18.0 (Ubuntu)
< Date: Thu, 12 Nov 2020 02:02:12 GMT
< Content-Type: application/octet-stream
< Content-Length: 0
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
And seeing the logs, we observe two entries:
- The connection from the 'client' to the 'frontend' with the original path:
127.0.0.1 - - [12/Nov/2020:02:02:12 +0000] "GET /payment/gateway/v2/order/complete/1234 HTTP/1.1" 202 0 "-" "curl/7.68.0"
- The connection from the 'frontend' to the 'backend' which includes the modified path:
127.0.0.1 - - [12/Nov/2020:02:02:12 +0000] "GET /payment/gateway/v2/order/complete?order_id=1234 HTTP/1.0" 202 0 "-" "curl/7.68.0"
This could also be cleaned up a bit to only match requests that contain a valid ID using a more complex regex. Nginx supports full PCRE for match/set expressions.
Source: https://nginx.org/en/docs/http/ngx_http_core_module.html#location
What about this?
location /payment/gateway/v2/order/complete {
rewrite ^/payment/gateway/v2/order/complete/([^/]+)/? /payment/gateway/v2/order/complete/?order_id=$1? break;
proxy_pass http://api.test.com:8080;
}
Note that I have removed the end string char $
and that I have added an optional trailing slash /?
. I have also changed the redirect flag last
with break
to prevent redirection loops. Finally, the trailing ?
in the destination URL prevents nginx from adding the previous request arguments if there were any. That regular expression matchs strings like these:
/payment/gateway/v2/order/complete/123123
/payment/gateway/v2/order/complete/123123/
/payment/gateway/v2/order/complete/123123/whatever
/payment/gateway/v2/order/complete/123123/whatever?var=a
In all those cases, $1
would be 123123
and the redirect destination is /payment/gateway/v2/order/complete/?order_id=123123
You can test the redirection with curl:
curl -I https://yoursite/payment/gateway/v2/order/complete/123123/whatever/you/want/?var1=1&var2=b
You should get a response with Location: https://yoursite/payment/gateway/v2/order/complete/?order_id=123123
Documentation: http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite