4

I am trying to redirect a subdirectory to a php file. Instead of serving the file, it downloads it, meaning that it does not read it as a php file.

More exactly it does not enter the fastcgi location ~ \.php$ directive.

Some interesting facts :

  • Everything works perfectly well for the admin bloc but not for the login block.
  • When I move the location ~ \.php$ directive above the login one and that I change ^~ /login into ~ /login, it works exept for the rewrite rule rewrite ^/login/(.+\.php)$ /$1 last;.

I did read the Wiki Nginx documentation on the topic so I am aware of the priorities in which nginx read the location directives but that does not tell me how to deal with this case! I also read

Here is the config:

server {
 listen  80;

 server_name tyba-one.com *.tyba-one.com;
 root /var/www/tyba/public_html;
 rewrite_log on;
 error_page 404 /404.php;
 client_max_body_size 4M;

 if ($host ~* ^www\.(.*)){
  set $host_without_www $1;
  rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
 }

 location = / {
   rewrite ^/$ /index.php last;
 }

 location ^~ /login {
  rewrite ^(/login)$ $1/ permanent;
  rewrite ^/login/$ /login.php last;
  rewrite ^/login/(.+\.php)$ /$1 last;
 }    

 location ^~ /admin {
  rewrite ^(/admin)$ $1/ permanent;
  rewrite ^/admin/$ /page_builder.php last;
  rewrite ^/admin/(.+\.php)$ /$1 last;
 }

 location ~ \.php$ {
  try_files $uri =404;
  include /opt/nginx/conf/fastcgi_params;
  fastcgi_pass 127.0.0.1:9000;
  fastcgi_index index.php;
  fastcgi_param SCRIPT_FILENAME /var/www/tyba/public_html$fastcgi_script_name;
 }
}

I would like to understand what's going on and how to deal with such situations.

Tristan
  • 143
  • 1
  • 5

2 Answers2

2

nginx only processes one location block at each nesting level, and so /login.php is handled by the ^~ /login block and not the ~ \.php$ block. Since you only have rewrite statements in your location blocks, you actually don't need the location blocks at all (as long as the rewrite matches are specific enough, which yours are). Just move your rewrite statements into the root of the server block so that requests for /login and /admin still use the \.php$ location block:

rewrite ^/$ /index.php last;
rewrite ^(/login)$ $1/ permanent;
rewrite ^/login/$ /login.php last;
rewrite ^/login/(.+\.php)$ /$1 last;
rewrite ^(/admin)$ $1/ permanent;
rewrite ^/admin/$ /page_builder.php last;
rewrite ^/admin/(.+\.php)$ /$1 last;

location ~ \.php$ {
    ...
}
mgorven
  • 30,615
  • 7
  • 79
  • 122
  • Thank you for your answer, I thought using Location blocks improved the processing time though no? And any idea why the page_builder.php would be served right in that case? – Tristan Mar 12 '13 at 09:07
  • @Tristan There's a marginal performance improvement with the location blocks because it reduces the number of regular expressions which are processed, but you're not going to notice it. `page_builder.php` works fine because none of the location blocks matches it. – mgorven Mar 12 '13 at 16:30
  • I meant tyba-one.com/admin serves `page_builder.php` as a php file but tyba-one.com/login that gives login.php as a binary file. Strange no? They both match their location block. – Tristan Mar 12 '13 at 17:19
  • @Tristan `/login.php` matches the `^~ /login` location block, but `/page_builder.php` doesn't match anything other than `~ \.php$`. – mgorven Mar 12 '13 at 17:35
  • I got it now, thank you, I was getting crazy with this! – Tristan Mar 13 '13 at 09:15
0

mgorven's answer solved my issue and I am so grateful I wanted to reply but I don't have the rep to just comment so I'm going to reply here with an update that though this was asked and answered 8 years ago here in 2021 I have been banging my head against this issue for a couple days

I had a Wordpress instance that was hidden/protected with a HideMyWordPress addon - I had ported the instance from another server that was apache2 and worked flawlessly with apache rewrites - but I'm new to nginx - mgorven's very helpful response not only solved my issue but really explained a thing I had totally missed in all my digging.. about the location blocks vs rewrite - I am now going through all my sites I've moved over to see if I can vastly simplify my nginx configs

Again sorry for replying with an "answer" instead of comment but

Even in 2021 this is damn useful information and saved my bacon

THANK YOU

  • Please don't add "thank you" as an answer. Once you have sufficient [reputation](https://serverfault.com/help/whats-reputation), you will be able to [vote up questions and answers](https://serverfault.com/help/privileges/vote-up) that you found helpful. - [From Review](/review/late-answers/504920) – Dave M Dec 10 '21 at 21:11