如何在位置块中组合不同根的重写

时间:2014-03-04 18:05:42

标签: nginx rewrite php

我很难理解当重写的位置块需要不同的根时,如何控制重写PHP脚本。

这是简化的例子。我的全部前端控制器必须位于Web根目录中,但firewall.php脚本不能是。

这样做的目的是提供对不在根目录下的文件的门控访问。

server {

    # Requests for media forced through firewall script outside web root
    # /path/to/secure-area/firewall.php
    #
    location ^~ /downloads/ {
       root /path/to/secure-area;
       rewrite ^/.+$ /firewall.php last;
    }

    # Regular requests bootstrap front controller under web-root
    # /path/to/web-root/index.php;
    #
    location / {
        root /path/to/web-root;
        index index.php
        if ( -e $request_filename ) {
            break;
        }
        rewrite ^.+$ /index.php last;
    }

    # Execute PHP via php-fpm
    # rewrites hitting this are not mapping request_filename properly
    #
    location ~ \.php$ {
       if ( !-f $request_filename ) {
         return 404;
       }
       include /usr/local/nginx/conf/fastcgi_params;
       fastcgi_pass   unix:/tmp/php.sock;
       fastcgi_index  index.php;
    }
}

显而易见的解决方案是拥有一个共同的根,但在我的情况下这是不可能的。我无法将安全位置放在Web根目录下,并且Web根目录必须保持原样。

看起来root指令只在定义它的位置块内有效。重写单独工作正常,但是当~ \.php块被命中时,根就会丢失。

我显然做错了,所以我应该如何做到这一点?

1 个答案:

答案 0 :(得分:1)

未经测试,但这样的事情应该对你有所帮助。它使用http://wiki.nginx.org/XSendfile从不同的根目录提供受保护的内容。还使用了try_files,这对于前端控制器来说是一个更好的模式。

    server {

    # More here: http://wiki.nginx.org/XSendfile
    #
    # To serve /downloads/some.zip
    # get php to set the http header:
    #
    # X-Accel-Redirect: /downloads/some.zip
    #
    # and then the file /path/to/secure-area/downloads/some.zip
    # will be sent by nginx
    location /downloads/ {
      internal;
      root   /path/to/secure-area;
    }        

    location / {
        root /path/to/web-root;
        index index.php
        try_files $uri $uri/ /index.php;
    }

    # make sure you read http://wiki.nginx.org/Pitfalls
    location ~* \.php$ {
      try_files $uri =404;
      fastcgi_pass   unix:/tmp/php.sock;
      fastcgi_index  index.php;
      include /usr/local/nginx/conf/fastcgi_params;
    }
}