JordanLu
JordanLu

Reputation: 150

rewrite prefix url in nginx location

My nginx config file like this:

server {
    listen 80;
    listen 443 ssl;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log main;

    root /data/www/;
    index index.php index.html index.htm;

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

We need to config the nginx to satisfy following:

1、If url does not has prefix "/api/mobile/index.php",and the request's port is 80, redirect it to https 2、If url has prefix "/api/mobile/index.php",just go on

So I add content in the config file:

    location ~ ^(?!/api/mobile/index\.php).*$ {
        if ($server_port = "80") {
               return 301 https://$server_name$request_uri;
        }

        rewrite /* $server_name$reqeust_uri last;
    }

Now the config file content is :

server {
    listen 80;
    listen 443 ssl;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log main;

    root /data/www/;
    index index.php index.html index.htm;

    location ~ ^(?!/api/mobile/index\.php).*$ {
        if ($server_port = "80") {
               return 301 https://$server_name$request_uri;
        }

        rewrite /* $server_name$reqeust_uri last;
    }

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

Than the request match the first location, will not match the other location.

That means these request couldn't go through the php cgi.

Is there anyone who knows how to solve the problem?

Upvotes: 10

Views: 2608

Answers (2)

Ernani Azevedo
Ernani Azevedo

Reputation: 461

There's the option to use two separated server context, and didn't use if statement (read why here: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/).

The configuration could be:

server {
    listen 80;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_error.log;
    access_log /log/nginx/xxx.com_access.log;

    root /data/www;
    index index.php index.html index.htm;

    location /api/mobile/index.php {
        rewrite ^(.*)$ https://$host$1 redirect;
    }

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_param;
    }
}

server {
    listen 443 ssl http2;
    server_name XXX.com;

    error_log  /log/nginx/xxx.com_ssl_error.log;
    access_log /log/nginx/xxx.com_ssl_access.log;

    root /data/www;
    index index.php index.html index.htm;

    location ~ \.php$ {
        add_header X-Frame-Options SAMEORIGIN;

        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_param;
    }
}

Upvotes: 0

Justinas
Justinas

Reputation: 43441

Nginx matches only one location. Move config to first location too.

location ~ ^(?!/api/mobile/index\.php).*$ {
    if ($server_port = "80") {
           return 301 https://$server_name$request_uri;
    }

    add_header X-Frame-Options SAMEORIGIN;

    fastcgi_pass   127.0.0.1:9000;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

location ~ \.php$ {
    add_header X-Frame-Options SAMEORIGIN;

    fastcgi_pass   127.0.0.1:9000;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

Upvotes: 4

Related Questions