1

The routing script of my application expects the URI to be

/api/v0/create

My request goes to

http://my-server.test/subdir/api/v0/create

How can I configure nginx to remove the "/subdir" from the URI, providing the expected path to the application's router?

I tried this one, but got only "404 File not found" from the server (not the app):

location /subdir/api/ {
    rewrite ^/subdir(.*)$ $1 last;
    try_files $uri $uri/ /subdir/api/public/index.php$is_args$args;
}

With the rewrite flag break and without the rewrite part altogether I get a 404 from my application for the subdir still in URI.

Edit:

I need a way without redirect to /api for there is another analogue URI http://my-server.test/anothersubdir/api/v0 which would have the same /api part.

All this comes down to the question: Is there a way to configure nginx to give the target application a rewritten URI in a way that for example $_SERVER['REQUEST_URI'] in php reflects it?

Edit: Here is the complete nginx configuration:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}

# configuration file /etc/nginx/mime.types:
types {
    text/html                                        html htm shtml;
    ... omitted
}

# configuration file /etc/nginx/conf.d/php.conf:
server {
    listen 80;
    server_name my-server.test;
    root /var/www;

    location /subdir/api/ {
        rewrite ^/subdir(.*)$ $1 last;
        try_files $uri $uri/ /subdir/api/public/index.php$is_args$args;
        location ~* \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass   php:9000;
            include fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME     $fastcgi_script_name;
        }
    }
}

Thank you for helping!

hangerer
  • 11
  • 3
  • Please add output of `nginx -T` to the question so that we can see the full nginx configuration. – Tero Kilkanen Jun 09 '23 at 19:37
  • @TeroKilkanen: Thanks for your comment - I put the nginx -T output. – hangerer Jun 11 '23 at 08:34
  • Does this answer your question? [Nginx reverse proxy + URL rewrite](https://serverfault.com/questions/379675/nginx-reverse-proxy-url-rewrite) – djdomi Jun 11 '23 at 10:48
  • @djdomi: Thanks for the link, but I have no proxy to redirect to - the application should be served from the same server. I tried ```rewrite ^/subdir(.*)$ $1 break;``` also, but there is no other outcome, subdir is still in the path received by the app. – hangerer Jun 12 '23 at 09:27
  • It is actually better to build support for prefixes like this in the application itself. Especially if the application will create URLs that refer to itself, it needs the knowledge of the URL that is usable from outside. – Tero Kilkanen Jul 09 '23 at 13:25
  • @TeroKilkanen: Yes, you're right, that seems the only way to handle this. Thank you! – hangerer Jul 10 '23 at 14:37

1 Answers1

1

You don't have any location block that will handle the request after the redirect (lets say after the rewrite, your request changes from /subdir/api/v0/create to this /api/v0/create, there's no matching block that will process such requests. I would suggest to take out the nested location block outside, also add the root location block (if needed)

server {
    listen 80;
    server_name my-server.test;
    root /var/www;

    location /subdir/api/ {
        rewrite ^/subdir(.*)$ $1 permanent;
        try_files $uri $uri/ /subdir/api/public/index.php$is_args$args;
    }

    location ~* \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass   php:9000;
            include fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME     $fastcgi_script_name;
    }

    location / {
        <REST OF YOUR CONFIGURATION>
    }
}
faizan
  • 98
  • 4
  • Thank you, this surely works, if I put the ```try_files``` block in a location which matches ```/api```. Unfortunately I made not clear in my question that I need a solution without redirect to /api/... for I have another similar looking applications: ```http://my-server.test/anothersubdir/api/v0``` which would conflict in this way. – hangerer Jun 13 '23 at 07:19