Nginx proxy_pass after rewrite loses URI segments - nginx

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;
}

Related

NGINX proxy_pass rewrite asset uri

I'm trying to do a basic NGINX reverse proxy by subdomian, to localhost/folder and am stumped getting it to rewrite my assets+links.
My http://localhost:8080/myapp/ works like a charm, but via NGINX+subdomain it fails on the subfolder assets.
I believe I'm stumped on the 'rewrite' clause for NGINX.
How can I rewrite the HTML going to the client browser to drop the /myapp/ context?
server {
listen 443 ssl;
server_name app1.domain.com;
location / {
rewrite ^/myapp/(.*) /$1 break; # this line seems to do nothing
proxy_pass http://localhost:8080/myapp/;
}
}
I'm expecting my resultant HTML (via https://app1.domain.com) to be rewritten without the subfolder /myapp/, so when assets are requested they can be found instead of a 404 against https://app1.domain.com/myapp/assets/. It should just be https://app1.domain.com/assets/ (which if I manually go there they work)
--thanks.
Feeding from Ivan's response and finalizing my solution as:
server {
listen 443 ssl;
server_name app1.domain.com;
location / {
sub_filter '/myapp/' '/'; # rewrites HTML strings to remove context
sub_filter_once off; # ensures it loops through the whole HTML (required)
proxy_pass http://localhost:8080/myapp/;
}
}
As nginx proxy_pass documentation states:
In some cases, the part of a request URI to be replaced cannot be determined:
...
When the URI is changed inside a proxied location using the rewrite directive, and this same configuration will be used to process a request (break):
location /name/ {
rewrite /name/([^/]+) /users?name=$1 break;
proxy_pass http://127.0.0.1;
}
In this case, the URI specified in the directive is ignored and the full changed request URI is passed to the server.
So with this configuration block after you rewrite /myapp/assets/some_asset URI to /assets/some_asset and use a break flag, nginx ignores /myapp/ suffix on a proxy_pass directive and passes /assets/some_asset request to your backend. However strange it is, what you need is to use this rewrite rule instead:
rewrite ^(/myapp/.*)$ $1 break;
Another (may be even better) solution is to use two location blocks:
location / {
proxy_pass http://localhost:8080/myapp/;
}
location /myapp/ {
proxy_pass http://localhost:8080;
}

How to rewrite nginx to proxy?

New to rewrites. Running 2 services on my host:
location /{
#this works fine
proxy_pass http://myMainServiceIp/;
}
location /wordpress{
#works but redirects to http://example.com/wp-admin/install.php
#rather than http://example.com/blog/wp-admin/install.php
proxy_pass http://wordpressServiceIp/;
}
How can I forward /blog/*params*/*etc*/*etc* to my wordpress service correctly?
There are two separate but related issues. The location needs a trailing / so that proxy_pass can alias the URIs correctly.
location /blog/ {
proxy_pass http://wordpressServiceIp/;
}
location = /blog {
rewrite ^ /blog/ last;
}
I have added the second location block to handle the one special case.
The second issue is HOME and SITEURL needs to point to http://example.com/blog/. See this document for more.

Nginx rewrite to proxy_pass server/path

Is it possible to use Nginx proxy_pass to rewrite URL as below:
location /foo {
proxy_pass http://external-server-IP:8080/some/path/;
}
Just in case someone still needs this, the easy way to do this:
location ~ ^/foo/.* {
rewrite ^/foo(.*) /$1 break;
proxy_pass https://external-server:8080/remote-path/;
}
rewrite ^/foo$ /foo/ redirect;
What this does is that it sends the request to the external server, masquerading it under your own domain.
rewrite ^/foo(.*) /$1 break;
The first rewrite is just to remove the added URL path (the remote server is not expecting that.
rewrite ^/foo$ /foo/ redirect;
And the 2nd rewrite is just in case you want to use the index page, so that it actually goes to the remote index page as well.

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 proxy_pass to localhost

I'm trying to use proxy_pass in nginx to forward requests to another port on localhost like this:
location /foo {
rewrite ^/foo/(.*) /$1 break;
proxy_pass http://127.0.0.1:8080/;
}
location /bar {
rewrite ^/bar/(.*) /$1 break;
proxy_pass http://localhost:8080/;
}
location /blah {
rewrite ^/blah/(.*) /$1 break;
proxy_pass http://192.168.77.56:8080/;
}
So only the last one works. The first two give me a page-unavailable error.
I know the endpoint is working as I can go directly to localhost:8080 and see output I expected.
Any idea what I'm doing wrong?
[Edit]: Further enlightenment... It seems the rewrite line has something to do with it. Using it like I have here seems to work on non-localhost IPs, i.e. it removes /blah from the path and keeps the rest as it sends it to its final destination. If I remove the rewrite line I can proxy to localhost (of course losing my indented other stuff on the url).
This worked:
location /blah {
rewrite ^/blah/(.*) /$1 break;
proxy_pass http://$server_addr:8080;
}

Resources