Redirect post request using nginx - nginx

I am currently getting post request like this:
POST /api/x/y HTTP/1.1
With request body: a=x&b=y etc.
I want to redirect the request to another server in any of these two ways:
1. GET x.x.x.x:8888/xy/abc?a=x&b=y
2. POST x.x.x.x:8888/xy/abc with body a=x&b=y
I am trying these two redirect options:
1.rewrite ^(.*) http://server/api$request_body redirect;
//this is not sending body params
2. return 307 http://server/api?$request_body;
//this is giving me 400

If you do this:
location /api/ {
proxy_pass http://x.x.x.x:8888;
}
Then a request to example.com/api/x/y/ will be proxied to http://x.x.x.x:8888/api/x/y/.
If you do this:
location /api/x/y/ {
proxy_pass http://x.x.x.x:8888/xy/abc/;
}
Then a request to example.com/api/x/y/ will be proxied to http://x.x.x.x:8888/xy/abc/.
Request method will be unchanged, unless you tell Nginx to change it. Some headers will not be passed, unless you tell Nginx to pass them.

Related

How to escape "?" in nginx rewrite rule output

I am trying to reverse proxy in nginx, rewriting a front end page like "/a/b?page=2" into a backend request to "/a/b%3fpage=2"
I cannot figure out how to get nginx to make reverse proxy requests which include "%3f".
With the following config:
rewrite ^/one$ /a%3fb;
rewrite ^/two$ /a?b;
rewrite ^/three$ /a\?b;
/one makes a backend request like GET /a%253fb HTTP/1.0
/two makes a backend request like GET /a?b HTTP/1.0
/three makes a backend request like GET /a\?b HTTP/1.0
How can I get a backend request like GET /a%3fb HTTP/1.0?
Thanks to #Richard Smith's comment, I was able to fix this for my specific case with the following code:
location / {
set $backend_uri $request_uri;
if ($args ~* "page=(\d+)") {
set $page $1;
set $backend_uri $uri%3fpage=$1;
}
proxy_pass http://example.com$backend_uri;
}
I think that I might also have been able to do something more general with the lua rewrite directive, but I was unable to install mod-lua on an Amazon Linux 2 machine, see https://serverfault.com/questions/961337/how-to-install-nginx-mod-lua-on-amazon-linux-2

nginx - Passing request header variables to upstream URL as query parameter

I have an application running on localhost listening on port 8080
nginx is running as reverse proxy, listening on port 80
So, a request coming to nginx on port 80 is sent to this application listening on localhost:8080 and response from this application sent back to the user
Now this application is incapable of reading the header variables from request header and can read only query parameters
So I want nginx to pass header values as query parameters to this application listening on localhost:8080
E.g. let us say in the request header there is a custom variable called 'userid'.
How do we pass this userid as &userid=value appended to the url to application listening on localhost 8080
My current test file of site-available and site-enabled is
server {
location /test {
proxy_pass http://localhost:8080;
}
}
So there is no need to do rewrite or anything else. Simply pass the header parameters that you want to pass as query parameter to the localhost application like below by appending to the arguments.
If you have custom header parameter like userid, then it would be $http_userid
server {
location /test {
set $args $args&host=$http_host;
proxy_pass http://localhost:8080;
}
}
If you have a request header called userid, it will be available within an Nginx variable called $http_userid.
You can alter the query parameters of the original request with a rewrite...break statement.
For example:
location /test {
rewrite ^(.*)$ $1?userid=$http_userid break;
proxy_pass http://localhost:8080;
}
See this document for details.

NGINX Redirect All Requests Matching URL with Parameters to Subdomain

I have a website that is also serving api requests to an app on the main domain. I would like to send all matching /api requests to an api subdomain.
For example I would like https://example.com/api + https://example.com/api/some_action + https://example.com/api/some_action?params1=somevalue&params2=value2.... to redirect to the same url structure but just on the subdomain.
So for the above example:
https://example.com/api
-> https://api.example.com/api
https://example.com/api/some_action
-> https://api.example.com/api/some_action
https://example.com/api/some_action?params1=somevalue&params2=value2....
-> https://api.example.com/api/some_action?params1=somevalue&params2=value2....
For all types of requests (get, posts etc) as well. So far I have tried this in the server directive for the main domain (in the 443 SSL server directive)
location ~ /api(.*)$ {
return 301 https://api.example.com/api/$request_uri$is_args$args;
}
The result I get when performing a simple GET request on https://api.example.com/api/some_action?param1=value ... is https://api.example.com//some_action without parameters and missing the api.
To redirect example.com/api/foo?bar to api.example.com/api/foo?bar you should use:
location ^~ /api {
return 307 https://api.exemple.com$request_uri;
}
The $request_uri variable contains the original request, including the /api/ prefix and the query sring.
The ^~ operator gives this location precedence (see this document for details). The 307 status code maintains GET/POST through the redirection (see this link for more).

Use nginx as proxy to get around CORS

I am trying to use nginx as a proxy so that i can hit an API directly from a browser.
Currently. I wrote the nginx line below,
location /binance-api {
add_header Access-Control-Allow-Origin *;
rewrite ^/binance-api/(.*) /$1 break;
proxy_pass http://api.binance.com;
}
Basically whenever i try to hit the server containing nginx
http://nginx-server/binance-api/
I want nginx to hit http://api.binance.com instead.
But for some reason, judging by inspecting XHR responses, my request URL itself keeps getting redirected to https://api.binance.com and CORS would trigger and my request will fail.
What am I missing here?
Thanks

Simple Nginx Proxy Pass and Regex

I want a simple nginx rule to pass the following example.
request http://myserver:8888/application/external/testUrl_1
redirect to
http://myglassfishserver:8080/application/external/testUrl_1
Then say I sent in
http://myserver:8888/application/external/testUrl_2
it would redirect to
http://myglassfishserver:8080/application/external/testUrl_2
I should also keep all post data if I were to send a http POST.
To me this seems like it should be simple.
I'm trying
location ^/application/external {
proxy_pass http://myglassfishserver:8080/$1;
allow all;
}
I'm getting *1 access forbidden by rule, client: which I know is because it didn't match a rule. I've tried numerous combinations. What is it I've done wrong ? I'm guessing its the $1
location /application/external/ {
proxy_pass http://myglassfishserver:8080;
}

Resources