Clean URLs working fine, pager, overlay and other queries not

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
luxpir's picture

In D7 (upgraded from D6) I have managed to get clean URLs working with Nginx thanks to the various help and documentation available here and there online.

What doesn't work are queries of the ?page=1 or ?destination= type, for some reason.

The config is very similar to: http://docs.ngx.cc/en/latest/topics/apps/drupal.html, particulary the line:

  location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;

and the few preceding lines.

In effect this means that the pagers and overlays are broken, and other queries I haven't come across yet.

Anyone got a fix for this in mind?

Comments

Try somesing like

chilic's picture

Try somesing like this:

location / {
    try_files      $uri  $uri/  @drupal;
}

That is not recomendet:

location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;

Thanks - already in place

luxpir's picture

Above the @rewrite lines is the following, already in place:

location / {
try_files $uri $uri/ @rewrite;
}

So, with no '@drupal' section in the vhosts file, what would @drupal refer to if I used it?

(Thanks)

EDIT:
I changed the @rewrite reference to @drupal, in case the @rewrite call was causing the problem. Doesn't seem to make a difference?

You need to update the config

perusio's picture

The config you referenced is old, slow and not very secure.

Thanks Perusio

luxpir's picture

Thanks for the advice. I am not using that config specifically. I have more security features in place on the config I have (/backup, settings.php, code files etc. all denied)

I know your own config is very secure, but I wanted something simple and easy to maintain for a low-level sysadmin (me!). I see in your config you use Lua to solve the query problem. Is there no other way?

So far it works great for clean URLs, but I'm stuck on this query issue. Can you comment on the rewrite line in particular? I'll repaste the relevant section here:

    location / {
            try_files $uri $uri/ @rewrite;
            #try_files $uri $uri/ /index.php?$args @rewrite;
        #try_files $uri $uri/ /index.php?q=$uri&$query_string @rewrite;
    }

    location @rewrite {
            # Some modules enforce no slash (/) at the end of the URL
            # Else this rewrite block wouldn't be needed (GlobalRedirect)
        #rewrite ^(.)$ /?q=$1&$args last;
        #rewrite ^/(.
)$ /index.php?q=$1&$args;
        rewrite ^/(.)$ /index.php?q=$1;
        #rewrite ^/(.
)$ /index.php?q=$uri&$query_string;

The #commented out lines are just some tests I've run in the last day, trying to fix this. I'll delete them soon if I can get confirmation that they won't work in some other config.

Stabbing in the dark a bit, as you'll see.

Lua is used when you have URIs that need to be escaped

perusio's picture

is that your problem?

Remove the /$uri from the try_files all requests go through index.php.

Perhaps not

luxpir's picture

Thanks, not sure if this counts as escaping, but I need the overlays in the format /url/#overlay[...] and
/url/page?=2 to work as planned. I tried your suggestion - top line of try_files is what it was, uncommented line is what I tried. Neither seemed to do the trick yet?

location / {
            #try_files $uri $uri/ @rewrite;
            try_files $uri/ @rewrite; #also tried try_files $uri @rewrite;
    }

    location @rewrite {
        rewrite ^/(.)$ /index.php?q=$1;
}

No luck yet, then. Appreciate any further thoughts. I presume nobody else has this problem with their configs, which makes me wonder what I've done wrong!

Simplify this:

perusio's picture

location / {
try_files $uri /index.php?q=$uri&$args;

}

Simplify it to

perusio's picture

location / {          
    try_files $uri /index.php?q=$uri&$args;
}

Tried, failed; thanks

luxpir's picture

Still not sure what's happening. I ran debug on Nginx while accessing:

/blog?page=1

And here is the result: http://pastebin.com/XiEc3Wkd (fun starts on line 65, I think)

The full vhost config is here: http://pastebin.com/h97tHfyE

Nothing to see there

perusio's picture

you stopped the paste too soon. Let it go until the end, i.e., returning something as reponse.

Updated log link

luxpir's picture

Here's the rest of that section of the log: http://pastebin.com/HN00T2jm

Paste your FastCGI config

perusio's picture

It seems something could be fishy there.

This config?

luxpir's picture

fastcgi_params: http://pastebin.com/cDuJRaB8

In the course of testing things I added line two, now commented out. Nothing else changed.

New information: getting the following error

Notice: Undefined variable: base_path in eval() (line 3 of /usr/share/nginx/www/modules/php/php.module(80) : eval()'d code).

in Watchdog and Ajax not working in Views preview. Throwing a 500/internal server error. Could all be related to the same issue - how PHP is handled?

Definitely

perusio's picture

something is wrong in the PHP handling of your config, hence the 500.

Suggestion: Try my config and see how it goes. Start simple.

Hello,Are you trying with

johntang's picture

Hello,

Are you trying with this:

In your nginx.conf, add fastcgi.conf with the content:

#-*- mode: nginx; mode: flyspell-prog; ispell-local-dictionary: "american" -*-
### Generic fastcgi configuration.
include fastcgi_params;
fastcgi_buffers 256 4k;
fastcgi_intercept_errors on;
## allow 4 hrs - pass timeout responsibility to upstream.
fastcgi_read_timeout 14400;
fastcgi_index index.php;
## Hide the X-Drupal-Cache header provided by Pressflow.
fastcgi_hide_header 'X-Drupal-Cache';
## Hide the Drupal 7 header X-Generator.
fastcgi_hide_header 'X-Generator';

In your server name config, check my reference:

location / {
        index index.php index.htm index.html;
        try_files $uri $uri/ @rewrite;
        expires max;
    }
location @rewrite {
        if (!-e $request_filename) {
            rewrite  ^/(.*)$  /index.php?q=$1  last;
            break;
        }   
    }
location ~ \.php$ {
        root        [your drupal physical path];
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_intercept_errors on;
    }

Please note along SCRIPT_FILENAME we having $document_root, some document I was seen /scripts instead of $document_root.

Thanks folks - fixed

luxpir's picture

Appreciate the help, folks. I bit the bullet in the end and switched over to Perusio's config. It has taken me a while to get my head around the dependencies and the settings, but not half as long as it was taking to write my own 'simple' config.

Now the admin overlays and pagers are working as planned (half think it was in my fastcgi_params that I was missing something) and I'm back underway with development.

The next hurdle will be implementing ssl certs, but hopefully that won't be such a change as the Perusio config obviously is already set up to handle these.

So again, many thanks, and hope to be able to be of as much use to you or others one of these days.

?destination=node showing error page

hinaresh2000's picture

Hi Luxpir
I am also facing the issue mentioned in subject line.
I have configured recently nginx with drupal project,
home page is coming but when i go for login then the above URL is coming with error page. I tried configuring as suggested in post but might be i am missing something which Perusio's config suggested and you have used.
please provide some help / text to put in config file.
few lines of my config file is :
location / {
root html;
index index.php index.htm index.html;
try_files $uri $uri/ @rewrite;
expires max;
}

location @rewrite {
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
break;
}

Seeking a quick help here.
Thanks,
Naresh K.

Working config in response to original poster.

threading_signals's picture

This is one of those questions that didn't have an answer posted.

Specifically, as of 12/29/2014, http://wiki.nginx.org/Drupal ...has the following rewrite:

    location / {
            # This is cool because no php is touched for static content
            try_files $uri @rewrite;
    }

    location @rewrite {
            # You have 2 options here
            # For D7 and above:
            # Clean URLs are handled in drupal_environment_initialize().
            rewrite ^ /index.php;
            # For Drupal 6 and bwlow:
            # Some modules enforce no slash (/) at the end of the URL
            # Else this rewrite block wouldn't be needed (GlobalRedirect)
            #rewrite ^/(.*)$ /index.php?q=$1;
    }

    location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_intercept_errors on;
            fastcgi_pass unix:/tmp/phpfpm.sock;
    }

As you can see, the above also works for overlays because it try_files $uri first, and then rewrites using, "rewrite ^ /index.php;", in which case, then it will go to the last php location.

I haven't tried perusio's nginx configuration in its entirety that's in github but I've been modifying various parts of it to make it easier to understand, and to improve on it.

It appears that he uses https://raw.githubusercontent.com/perusio/drupal-with-nginx/D7/apps/drup... ...to redirect to the hardcoded fastcgi parameters instead of having a rewrite location mentioned above.

You should use http://tools.pingdom.com/fpt/ and/or locally installed tools to verify that the changes do make for improvements.

great

koffer's picture

This solution work for me!

same issue, wnmp web server

musicster's picture

worker_processes 1;

error_log logs/error.log;
pid logs/nginx.pid;

events {
# Max value 16384
worker_connections 8192;
# Accept multiple connections
multi_accept on;
}

Settings that affect all server blocks

http {
include php_processes.conf;
include mime.types;
default_type application/octet-stream;

access_log  logs/access.log;

sendfile on;

keepalive_timeout  65;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1 SSLv3;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5:!DSS;
ssl_prefer_server_ciphers on;
gzip  on;
# http server

Begin HTTP Server

server {
listen 80; # IPv4
server_name localhost;

## Parametrization using hostname of access and log filenames.
access_log logs/localhost_access.log;
error_log logs/localhost_error.log;

## Root and index files.
root html;
index  index.php index.html index.htm;

## If no favicon exists return a 204 (no content error).
location = /favicon.ico {
    try_files $uri =204;
    log_not_found off;
    access_log off;
}

## Don't log robots.txt requests.
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

location @rewrite {
    rewrite ^/(.*)$ drupal/index.php?q=$1;

}

## Try the requested URI as files before handling it to PHP.

location / {
try_files $uri /drupal/index.php?$query_string;

    ## Regular PHP processing.
    location ~ \.php$ {
        fastcgi_pass   php_processes;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    ## Static files
    location ~* \.(?:css|gif|htc|ico|js|jpe?g|png|swf)$ {
    try_files $uri $uri/ @rewrite;
        expires max;
        log_not_found off;
        ## No need to bleed constant updates. Send the all shebang in one
        ## fell swoop.
        tcp_nodelay off;
        ## Set the OS file cache.
        open_file_cache max=1000 inactive=120s;
        open_file_cache_valid 45s;
        open_file_cache_min_uses 2;
        open_file_cache_errors off;
    }

    ## Keep a tab on the 'big' static files.
    location ~* ^.+\.(?:ogg|pdf|pptx?)$ {
        expires 30d;
        ## No need to bleed constant updates. Send the all shebang in one
        ## fell swoop.
        tcp_nodelay off;
    }
    } # / location

}

End HTTP Server

Begin HTTPS Server

server {
listen 443 http2 ssl;
server_name localhost;
ssl_certificate cert.pem;
ssl_certificate_key key.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

## Parametrization using hostname of access and log filenames.
access_log logs/localhost_access.log;
error_log logs/localhost_error.log;

## Root and index files.
root html;
index  index.php index.html index.htm;

## If no favicon exists return a 204 (no content error).
location = /favicon.ico {
    try_files $uri =204;
    log_not_found off;
    access_log off;
}

## Don't log robots.txt requests.
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}
location @rewrite {
    rewrite ^/(.*)$ drupal/index.php?q=$1;

}

## Try the requested URI as files before handling it to PHP.
location / {
try_files $uri /drupal/index.php?$query_string;

    ## Regular PHP processing.
    location ~ \.php$ {
        fastcgi_pass   php_processes;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    ## Static files are served directly.
    location ~* \.(?:css|gif|htc|ico|js|jpe?g|png|swf)$ {
        expires max;
        log_not_found off;
        ## No need to bleed constant updates. Send the all shebang in one
        ## fell swoop.
        tcp_nodelay off;
        ## Set the OS file cache.
        open_file_cache max=1000 inactive=120s;
        open_file_cache_valid 45s;
        open_file_cache_min_uses 2;
        open_file_cache_errors off;
    }

    ## Keep a tab on the 'big' static files.
    location ~* ^.+\.(?:ogg|pdf|pptx?)$ {
        expires 30d;
        ## No need to bleed constant updates. Send the all shebang in one
        ## fell swoop.
        tcp_nodelay off;
    }
    } # / location

} # End HTTPS Server
}