Nginx – keep double slashes when working with passenger

nginxphusion-passenger

I've urls on my site that have nested urls encoded by encodeURI function.

www.site.com/http%3A%2F%2Fwww.site.com%2F

My site is running using nginx 0.8.53
The problem is that when nginx gets such url it decodes the whole url and remove double slashes passing incorrect url down to passenger and then in my ruby code.
Here is my general nginx configuration:

daemon off;

user  www-data;
pid   /var/run/nginx.pid;
worker_processes  1;

events {
    worker_connections  1024;
}



http {
    passenger_root /usr/local/rvm/gems/ruby-1.9.2-p136@global/gems/passenger-3.0.2;
    passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.2-p136@site.com/ruby;

    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    tcp_nodelay        on;

    gzip  on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        log_format combined-realip '$remote_addr ($http_x_real_ip) - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
        access_log /opt/nginx/logs/access.log combined-realip;

        if (-f /home/site.com/current/maintenance) {
            return 503;
        }

        root /home/site.com/current/public;
        passenger_enabled on;

        rack_env production;
        passenger_set_cgi_param SERVER_NAME $http_host;

        error_page 503 /503.html;
        location = /503.html {
            root   html;
        }

        include /home/site.com/current/*nginx.conf;
    }
}

I tried setting merge_slashes to off in /home/site.com/current/nginx.conf

merge_slashes off;

but it didn't work. I don't have any ideas except start passenger as standalone and use proxy_pass, but another problem is that I'm using cloud service which provides nginx and passenger and I can only edit that /home/site.com/current/nginx.conf and nothing else.

Please help me.

Best Answer

merge_slashes only works as a directive in a server block when that server is a default server. Specify it instead in your http block.

Note however that even with merge_slashes off, nginx will still decode the slashes, and Passenger will still merge them. I worked around this on my site by looking for things like "http:/" in my action and modifying them appropriately:

missing_double_slash_match = /\A([a-z]+)\:\/([^\/])/.match(term)
if !missing_double_slash_match.nil?
    term = term.sub(missing_double_slash_match[0], "#{missing_double_slash_match[1]}://#{missing_double_slash_match[2]}")
end