Form url for existing Nginx rewrite rule - nginx

i have question to Nginx specialist. There are such rules on Nginx.
If i request with header 'main', it adds /ismain to url:
if ($http_main) {
rewrite ^(.*)$ /ismain/$1;
}
Next it cut /ismain/ from url and goes to Host
location /ismain/ {
rewrite ^/ismain/(.*)$ $1 break;
proxy_pass http://Host:9999;
}
It works good and i can't change it because of company sequrity policy.
But now i need to do callback and headers are not allowed.
So i request in such a way(without header):
http://11.11.117.111:8077/ismain/someaddress
But Nginx cut off all slashes after port... and responses 400 Bad URI.
In logs i can see such url after cut:
http://11.11.117.111:8077someaddress
I tried request with double slashes:
http://11.11.117.111:8077//ismain/someaddress
http://11.11.117.111:8077/ismain//someaddress
But it's not work. I have the same response. I'm in frustration why i works with header, but doesn't want with my formed path. I suppose it's the same.
Maybe i need to screen slash with some symbol ? Can you advice me ?

All Nginx URIs contain a leading /.
Your first rewrite statement is adding a double //. You should use:
rewrite ^(.*)$ /ismain$1;
or:
rewrite ^/(.*)$ /ismain/$1;
Your second rewrite statement relies on the first bug. You should use:
rewrite ^/ismain(/.*)$ $1 break;
or:
rewrite ^/ismain/(.*)$ /$1 break;

Related

NGINX Rewrite is encoding querystring as a path

I want to rewrite internally several locations /customers/foo?bar=2 to an existing location in my nginx configuration at /blah so that it's as if the request was to /blah/customers/foo?bar=2.
location /blah {
# View in fiddler
proxy_pass http://127.0.0.1:8888/;
# Lots of config here I don't want to repeat everywhere else
}
location /customers/ {
rewrite ^/customers/(.*) /blah/customers/$1$is_args$args;
}
location /other/ {
rewrite ^/other/(.*) /blah/other/$1$is_args$args;
}
# etc...
Nginx is rewriting the URL with the querystring encoded as a path /blah/customers/foo%34bar=2.
The same thing happens with rewrite ^ /blah$request_uri;. It encodes the ? as %3F effectively garbling the URL.
If I do a client redirect rewrite ^ /blah$request_uri permanent; the URL is correct and contains the ? but I want an internal redirect inside my NGINX config.
Don't use $is_args$args, because the rewrite directive will automatically append any existing query string.
For example:
rewrite ^/customers/(.*) /blah/customers/$1 last;
Although, I would prefer:
rewrite ^(.*)$ /blah$1 last;
Or even:
rewrite ^ /blah$uri last;

Nginx proxy_pass after rewrite loses URI segments

I am trying to rewrite a url then proxy_pass the result to another server. Here is my setup:
server {
rewrite ^/foo(.*)$ $1 last;
location /bar {
proxy_pass http://myserver/;
}
}
So when I make a GET request for /foo/bar/dir/file.txt I expect the first rewrite to remove /foo, the location block to catch the result of the rewrite, then proxy_pass to http://myserver:8000/dir/file.txt because the trailing slash on the proxy_pass will strip off /bar.
This is what I expect however when I have the trailing slash then /dir/file.txt is lost in the proxy_pass, and the request is only made to http://mysever/ root URI. I confirmed when I take off the slash then /bar/dir/file.txt is indeed the request the upstream server.
Is there some extra step I am missing?
Sounds weird, I expect the same behaviour from this config as you. What if you strip the /bar prefix inside the location block? Maybe this workaround would work?
location /bar {
rewrite ^/bar(.*) $1 break;
proxy_pass http://myserver;
}

What's the rewrite syntax for an NGINX regex location?

Using NGINX as a load balancer running on 10.1.2.15:9002, I have a need to rewrite http://10.1.2.15:9002/proxy.stream?opt=1 to http://10.1.2.15:9002/app/proxy.stream?opt=1.
Following are bits from my nginx.conf file:
http {
upstream app_cluster {
server 10.1.2.23:8080;
server 10.1.2.25:8080;
}
server {
listen 9002 default_server;
location /app/ {
proxy_pass http://app_cluster/;
}
location ~ ^/proxy.stream(.*)$ {
rewrite ^(.*)$ /app/$request_uri last;
}
}
}
By the way, I can replace the rewrite line with return 401 (for example), and I can see the 401 HTTP status returned using Chrome Developer Tools, so I know the regex is matching. I just can't get the URI rewritten properly. In fact, I only see the original request with a 406 status in Developer Tools, so I suspect something is wrong with my rewrite syntax.
Does anyone see what is wrong with this configuration?
Using $request_uri in the replacement string of a rewrite statement is problematic, as it has not been normalised and also contains the query string, which by default, rewrite will append again.
Also, your replacement string contains //, as you are appending a URI which already has a leading /.
The regular expression location is not necessary, as a prefix or exact match location will suffice and is more efficient for nginx to process. See this document for more.
For example:
location /proxy.stream {
rewrite ^ /app$uri last;
}
Make use of the matching part from the regex instead of $request_uri
rewrite ^(.*)$ /app/$1 last;

How to modify the Request URI in nginx

I have an nginx server on which I need to remove a portion of the requested URI.
Example: The request will come as www.domain.com/removeme/myprofile.jpg and I need to treat it as www.domain.com/myprofile.jpg
/removename from the request URI needs to be removed for all the requests where the URI starts with /removename
How can I achieve this?
Though you might achieve it without modifying the request_uri, try this out, :)
if ($request_uri ~* /removeme/.*) {
rewrite ^ $request_uri;
rewrite /removeme/(.*) /$1 break;
}

Nginx rewrite unencodes url

It seems Nginx it always un-encodes urls when used with a regular expression. I have a rewrite rule:
location /api/ {
rewrite /api/(.*)$ $1 break;
proxy_pass http://127.0.0.1:8000/$1;
}
I would like to remove the api from the usl but keep the rest of the path. Part of the path is an email address someone#somewhere.com. I am passing someone%40somewhere.com but Nginx is turning it back with the # sign.
The correct answer seem to be
location /api/ {
rewrite ^ $request_uri;
rewrite ^/api/(.*) $1 break;
return 400;
proxy_pass http://127.0.0.1:8000/$uri;
}
See Nginx pass_proxy subdirectory without url decoding for full answer and original author.
(I realize this question is older than the one I referenced but I found this in google search and may not be the last one, so ...)
That is how Nginx handles urls. You can bypass it by changing your web application to escape the "%" character as "%25" and pass someone%2540somewhere.com.
This will be unescaped as someone%40somewhere.com.

Resources