Multiviews in nginx (sorta)

I use wsvn on my svn subdomain. Nginx doesn’t have real support for this, but there is a way to sorta do this.

First we set this in our / location:

                #Sorta emulate multiviews.
                set $path_info "";
                if ($uri ~ "^/wsvn/(.+)$")
                {
                        set $path_info "/$1";
                        rewrite ^(.+)$ /wsvn.php?$1 last;
                }

Now I just need to let fastcgi know this. My fast cgi params are in their own file, but this is the only thing that uses this. So I do not bother with adding it into the params file. I just define it after my SCRIPT_FILENAME param is defined.

                fastcgi_param  PATH_INFO $path_info;

That gets it working.. However, I ran into two issues so far while working with this.
1. when trying to view a file that has a .php extension, it will try to run that through fastcgi. You can’t use fastcgi inside of a if statement. So there is no way I could see to resolve this. This is actually my breaking point of using nginx to serve my wsvn pages.
2. For some reason, it urlencodes the data in PATH_INFO. Apache when it sets this, does not (spaces are not converted to %20). I had to modify the wsvn code that used multiviews and told it to urldecode() the path info before it handled it elsewhere in the script.

Maybe somebody else who knows more about nginx can resolve these two issues. I would be glad to hear anything about it.

Update:
After more working, I did find a solution for the php issue. Not a nice solution, but it gets around the issue. The urlencode issue still exists. But a minor change to my wsvn.php to fix this was no biggie.

Update 2:
I did locate a solution on nginx’s website. Although I found it by chance.
http://wiki.nginx.org/HttpFcgiModule#fastcgi_split_path_info

However, I would like to note while this solution would work, it would fail still if a .php exist in the url.

I am including my current entire config for my svn sub domain just to show how its being done. I know some things can be done better and would love to hear thoughts.

I should note that the note at the top is what I am using as reference for what ports fastcgi ports I can use on this virtualhost. Since each php configuration needs its own .ini file, I need a simple way to know what ports to be using.

# FastCGI Ports: 9050 - 9059
server
{
	listen   443;
	server_name  svn.sleepycode.com;

	ssl on;
	ssl_certificate  /home/certs/svn.sleepycode.pem;
	ssl_certificate_key  /home/certs/svn.sleepycode.key;
	ssl_session_timeout  5m;

	access_log  /var/log/nginx/svn.sleepycode.com-.access.log;
        error_log  /var/log/nginx/svn.sleepycode.com-error.log;

	## TODO: test this :P
	location /code
	{
		proxy_pass      http://svn.sleepycode.com:8999;
		include         /etc/nginx/proxy.conf;
		set  $dest  $http_destination;
		proxy_set_header  Destination   $dest;
	}

	location /
	{
		root   /home/sites/svn.sleepycode.com/public_html;
		index  index.php;

		location /wsvn/
		{
			# Sorta emulates multiviews.
			set $path_info "";
			if ($uri ~ "^/wsvn/(.+)$")
			{
				set $path_info "/$1";
			}

			include /etc/nginx/fastcgi_params;
			fastcgi_pass   127.0.0.1:9050;
			fastcgi_index  wsvn.php;
			fastcgi_param  SCRIPT_FILENAME  /home/sites/svn.sleepycode.com/public_html/wsvn.php;
			fastcgi_param  PATH_INFO $path_info;
			fastcgi_param  SCRIPT_NAME /wsvn;

			# Some reason php files still don't work, this is a solution?
			location ~ \.php$
			{
				set $path_info "";
				if ($uri ~ "^/wsvn/(.+)$")
				{
					set $path_info "/$1";
				}

				include /etc/nginx/fastcgi_params;
				fastcgi_pass   127.0.0.1:9050;
				fastcgi_index  wsvn.php;
				fastcgi_param  SCRIPT_FILENAME  /home/sites/svn.sleepycode.com/public_html/wsvn.php;
				fastcgi_param  PATH_INFO $path_info;
				fastcgi_param  SCRIPT_NAME /wsvn;

				break;
			}
		}
	}

	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
	#
	location  ~ \.php$
	{
                include /etc/nginx/fastcgi_params;
                fastcgi_pass   127.0.0.1:9050;
                fastcgi_index  wsvn.php;
                fastcgi_param  SCRIPT_FILENAME  /home/sites/svn.sleepycode.com/public_html/$fastcgi_script_name;
		fastcgi_param  PATH_INFO $path_info;
                #includefastcgi_params;
        }

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	location ~ /\.ht
	{
		deny  all;
	}
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.