<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brain Matters &#187; nginx</title>
	<atom:link href="http://blog.agoragames.com/tag/nginx/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.agoragames.com</link>
	<description></description>
	<lastBuildDate>Thu, 29 Jul 2010 19:13:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>vBulletin and NGINX</title>
		<link>http://blog.agoragames.com/2010/03/11/vbulletin-and-nginx/</link>
		<comments>http://blog.agoragames.com/2010/03/11/vbulletin-and-nginx/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 19:27:34 +0000</pubDate>
		<dc:creator>Jason LaPorte</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vbulletin]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=504</guid>
		<description><![CDATA[It&#8217;s no secret that Agorian systems folk favor NGINX for our web serving needs. We&#8217;ve written about it a lot before. Therefore, it should be no surprise that we end up making a lot of things designed to work on Apache work on NGINX. (We&#8217;ve also written about that before, come to think of it&#8230;)
One [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s no secret that Agorian systems folk favor <a href="http://nginx.org/" target="_blank">NGINX</a> for our web serving needs. We&#8217;ve written about it a lot before. Therefore, it should be no surprise that we end up making a lot of things designed to work on <a href="http://httpd.apache.org/" target="_blank">Apache</a> work on NGINX. (We&#8217;ve also written about that before, come to think of it&#8230;)</p>
<p>One example is <a href="http://www.vbulletin.com/" target="_blank">vBulletin</a>. A number of Agora&#8217;s sites are powered by the forum software, which comes with rewriting rules for Apache&#8217;s <a href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html" target="_blank">mod_rewrite</a> and <a href="http://www.iis.net/" target="_blank">IIS</a>&#8230; but not NGINX.</p>
<p>So, if you&#8217;re interested in setting up vBulletin behind NGINX (and are using the advanced URL rewriting, like we are), you can find a sample configuration for doing so <a href="http://files.agoragames.com/jason/vb-nginx.txt" target="_blank">here</a>.</p>
<p>Let us know if you have any questions!</p>




	<a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2010%2F03%2F11%2Fvbulletin-and-nginx%2F&amp;title=vBulletin%20and%20NGINX" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2010%2F03%2F11%2Fvbulletin-and-nginx%2F&amp;title=vBulletin%20and%20NGINX&amp;bodytext=It%27s%20no%20secret%20that%20Agorian%20systems%20folk%20favor%20NGINX%20for%20our%20web%20serving%20needs.%20We%27ve%20written%20about%20it%20a%20lot%20before.%20Therefore%2C%20it%20should%20be%20no%20surprise%20that%20we%20end%20up%20making%20a%20lot%20of%20things%20designed%20to%20work%20on%20Apache%20work%20on%20NGINX.%20%28We%27ve%20also%20writt" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2010%2F03%2F11%2Fvbulletin-and-nginx%2F&amp;title=vBulletin%20and%20NGINX&amp;notes=It%27s%20no%20secret%20that%20Agorian%20systems%20folk%20favor%20NGINX%20for%20our%20web%20serving%20needs.%20We%27ve%20written%20about%20it%20a%20lot%20before.%20Therefore%2C%20it%20should%20be%20no%20surprise%20that%20we%20end%20up%20making%20a%20lot%20of%20things%20designed%20to%20work%20on%20Apache%20work%20on%20NGINX.%20%28We%27ve%20also%20writt" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2010%2F03%2F11%2Fvbulletin-and-nginx%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2010/03/11/vbulletin-and-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Page Caching Hacks in NGINX</title>
		<link>http://blog.agoragames.com/2009/06/26/advanced-page-caching-hacks-in-nginx/</link>
		<comments>http://blog.agoragames.com/2009/06/26/advanced-page-caching-hacks-in-nginx/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 17:59:07 +0000</pubDate>
		<dc:creator>Jason LaPorte</dc:creator>
				<category><![CDATA[Bending Rails]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[page caching]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=308</guid>
		<description><![CDATA[Those of you in the Rails community who use NGINX may have come across this before: Ezra Zygmuntowicz&#8217;s NGINX config. It bears some similarity to the ones we use at Agora. Specifically, the section relating to serving page-cached files. The relevant lines (pulled from one of our configs) looks like this:
if (-f $request_filename.html) { rewrite [...]]]></description>
			<content:encoded><![CDATA[<p>Those of you in the Rails community who use NGINX may have come across <a href="http://brainspl.at/nginx.conf.txt" target="_blank">this</a> before: Ezra Zygmuntowicz&#8217;s NGINX config. It bears some similarity to the ones we use at Agora. Specifically, the section relating to serving page-cached files. The relevant lines (pulled from one of our configs) looks like this:</p>
<pre>if (-f $request_filename.html) { rewrite (.*) $1.html break; }
if (-f $request_filename/index.html) { rewrite (.*) $1/index.html break; }
if (!-f $request_filename) { proxy_pass http://some-proxy; }</pre>
<p>This generally works well, for simple cases. Unfortunately, we&#8217;ve run into some more complex ones where it didn&#8217;t cut it. I&#8217;ll outline two of those cases below and show what we did to fix it.</p>
<p><span id="more-308"></span></p>
<p>The first problem came up when we were page-caching both HTML and XML files (that is, there might be a <tt>slots/show/47.html</tt> and a <tt>slots/show/47.xml</tt>. (You can&#8217;t do this by default in Rails. We had to patch it.) The problem was that when you request <tt>/slots/show/47</tt>, the NGINX config only checks for and serves the HTML file, even when what you really wanted was XML. Of course, checking for the XML file gives the reverse problem: if you&#8217;re in a web browser, you get XML instead of pretty HTML. Not so hot.</p>
<p>My solution was to assume that the user wants XML unless their browser says otherwise (via the HTTP Accepts: header), in which case we check for HTML first instead. If we can&#8217;t find the relevant file, we try with the other extension (in case we guessed wrong), and finally we kick the request to the proxy if we can&#8217;t satisfy it. Thus, it looks like this:</p>
<pre># figure out the order we should search the cache
set $preferred_format xml;
set $secondary_format html;

if ($http_accept ~* text/html) {
  set $preferred_format html;
  set $secondary_format xml;
}

# check the cache for cached files
if (-f $request_filename.$preferred_format) {
  rewrite (.*) $1.$preferred_format break;
}

if (-f $request_filename/index.$preferred_format) {
  rewrite (.*) $1/index.$preferred_format break;
}

if (-f $request_filename.$secondary_format) {
  rewrite (.*) $1.$secondary_format break;
}

if (-f $request_filename/index.$secondary_format) {
  rewrite (.*) $1/index.$secondary_format break;
}

# if the file doesn't exist, let the application sort everything out
if (!-f $request_filename) { proxy_pass http://some-proxy; }</pre>
<p>The second case was a bit more subtle, but is similar in theory: one of our sites uses proper REST (that is, we support the HTTP GET, PUT, DELETE, etc. methods). When a user performed a GET request, the page gets cached; if they perform a DELETE sometime after that, NGINX (which is not configured to handle REST by default) simply returns the cached file happily instead of forwarding the DELETE request to the application. (As you can imagine, tracking down the source of this problem was not the easiest thing in the world.)</p>
<p>The solution in this case was to disable page caching for GET requests. Unfortunately, NGINX&#8217;s support for if statements isn&#8217;t so hot, so we had to do something fairly hacky to get it to work. (For the record, while I&#8217;ve not been enthused with the if statements, I tend to like NGINX in most other areas, so a couple silly warts like this are excusable for me.)</p>
<pre># Look for "/foo.zmog" unless we're asking for a GET request, in which case
# we look for "/foo.xml". Since "/foo.zmog" will never exist, this means
# that we will only check for pagecached files on a GET request. (Yes, this
# is totally ass-backwards. NGINX is awesome except in this case.)
set $cache_suffix "zmog";
if ($request_method = GET) {
  set $cache_suffix "xml";
}

# Caching rewrites
if (-f $request_filename.$cache_suffix) {
  rewrite (.*) $1.$cache_suffix break;
}

if (-f $request_filename/index.$cache_suffix) {
  rewrite (.*) $1/index.$cache_suffix break;
}

# More metrics logging for cached files
if (!-f $request_filename) { proxy_pass http://switchblade_proxy; }</pre>
<p>As you can see, sometimes, making NGINX play nice requires some lateral thinking, but you can generally always get it to do what you need to.</p>




	<a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F06%2F26%2Fadvanced-page-caching-hacks-in-nginx%2F&amp;title=Advanced%20Page%20Caching%20Hacks%20in%20NGINX" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F06%2F26%2Fadvanced-page-caching-hacks-in-nginx%2F&amp;title=Advanced%20Page%20Caching%20Hacks%20in%20NGINX&amp;bodytext=Those%20of%20you%20in%20the%20Rails%20community%20who%20use%20NGINX%20may%20have%20come%20across%20this%20before%3A%20Ezra%20Zygmuntowicz%27s%20NGINX%20config.%20It%20bears%20some%20similarity%20to%20the%20ones%20we%20use%20at%20Agora.%20Specifically%2C%20the%20section%20relating%20to%20serving%20page-cached%20files.%20The%20relevant%20" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F06%2F26%2Fadvanced-page-caching-hacks-in-nginx%2F&amp;title=Advanced%20Page%20Caching%20Hacks%20in%20NGINX&amp;notes=Those%20of%20you%20in%20the%20Rails%20community%20who%20use%20NGINX%20may%20have%20come%20across%20this%20before%3A%20Ezra%20Zygmuntowicz%27s%20NGINX%20config.%20It%20bears%20some%20similarity%20to%20the%20ones%20we%20use%20at%20Agora.%20Specifically%2C%20the%20section%20relating%20to%20serving%20page-cached%20files.%20The%20relevant%20" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2009%2F06%2F26%2Fadvanced-page-caching-hacks-in-nginx%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2009/06/26/advanced-page-caching-hacks-in-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making WebDAV and NGINX Play Nice Together</title>
		<link>http://blog.agoragames.com/2009/03/20/webdav-nginx-play-nice/</link>
		<comments>http://blog.agoragames.com/2009/03/20/webdav-nginx-play-nice/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 21:26:44 +0000</pubDate>
		<dc:creator>Jason LaPorte</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webdav]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=236</guid>
		<description><![CDATA[NGINX supports WebDAV, but its support is incomplete. Here&#8217;s how we made a quick PHP hack to allow us to use WebDAV without having to proxy to another web server.

WebDAV is a pretty awesome method of maintaining a shared data repository: it&#8217;s simple, secure (or, at least, easily secured), and supported out of the box [...]]]></description>
			<content:encoded><![CDATA[<p>NGINX supports WebDAV, but its support is incomplete. Here&#8217;s how we made a quick PHP hack to allow us to use WebDAV without having to proxy to another web server.</p>
<p><span id="more-236"></span></p>
<p><a href="http://en.wikipedia.org/wiki/WebDAV" target="_blank">WebDAV</a> is a pretty awesome method of maintaining a shared data repository: it&#8217;s simple, secure (or, at least, easily secured), and supported out of the box by just about everything across multiple platforms. The problem with it is that finding a decent WebDAV server is pretty hard: <a href="http://httpd.apache.org/" target="_blank">Apache</a> and <a href="http://www.lighttpd.net/" target="_blank">LightTPD</a> each provide WebDAV (to varying levels of support), but I had a very hard time finding other reputable-looking servers, and adding either of those two web servers into what is otherwise an <a href="http://nginx.net/" target="_blank">NGINX</a>-only web server architecture isn&#8217;t very clean. (Personally, I hate maintaining Apache and LightTPD, as they are both CPU and memory hogs, Apache especially.)</p>
<p>NGINX &#8220;supports&#8221; WebDAV by means of a module, but this support is incomplete: it only handles the WebDAV methods PUT, DELETE, MKCOL, COPY, and MOVE, and leaves the necessary OPTIONS and PROPFIND (and the optional LOCK, UNLOCK, and PROPPATCH) methods unimplemented. This basically translates to being able to read and write files on disk, but being unable to do an &#8220;ls&#8221; or &#8220;dir&#8221; to see what files are available. Obviously, this is insufficient, so I created some magic to allow us to use a WebDAV repository with a technology stack we already have in place (namely, NGINX and PHP FCGI).</p>
<p>Looking around the internet for similar things, I find that <a href="http://notes.xiaoka.com/2008/04/13/git-repository-over-http-webdav-with-nginx/" target="_blank">we&#8217;re not the only ones trying to do this,</a> and came across a <a href="http://plan9.aichi-u.ac.jp/netlib/webappls/webdav.cgi" target="_blank">Perl CGI script</a> that is/can be used in a similar fashion. Unfortunately, NGINX doesn&#8217;t play very nice with CGI (as opposed to FCGI, which works great with it), and I felt like I needed some semblance of performance out of this script, so I wasn&#8217;t going to fire up a Perl process for every request (which is how CGI works). Instead, I wrote up a similar script in PHP. (In case you&#8217;re not familiar with how FCGI works, it instead runs a daemon, which simply returns a response to each given request without having to run new processes. This cuts out a lot of overhead and allows for much better performance.)</p>
<p>The idea is this: we have NGINX put up it&#8217;s WebDAV support, and for every method that NGINX doesn&#8217;t know how to respond to, we proxy the request to a PHP script that can handle it on NGINX&#8217;s behalf. Making a simple FCGI script in PHP is not especially complicated. The original skeleton of it looked like this:</p>
<pre>&lt;?php

$request_method = $ENV_['REQUEST_METHOD']

switch ($request_method) {
  case 'PROPFIND':
    # Code to handle PROPFIND goes here.
    break;

  case 'OPTIONS':
    # Code to handle OPTIONS goes here.
    break;

  default:
    header ('HTTP/1.1 400 Bad Request');
    break;
}

?&gt;</pre>
<p>We are given the request method via an environment variable from NGINX. Depending on the method given, we have to handle it in its own special way. If we get a method we don&#8217;t understand, we merely return an HTTP error. Simple!</p>
<p>In fact, implementing the PROPFIND and OPTIONS methods wasn&#8217;t especially difficult, aside from the fact that reading the <a href="http://www.ietf.org/rfc/rfc2518.txt" target="_blank">WebDAV RFC</a> is mind-numbingly tedious. (The OPTIONS method simply spits out a couple static headers, while PROPFIND returns an XML document of a directory listing. You can see my final implementation here. Be aware I didn&#8217;t bother to fully support WebDAV: I merely implemented the simplest possible subset of the WebDAV functionality.)</p>
<p>So, I hooked it up end to end. The NGINX configuration to do so looked something like this:</p>
<pre>server {
  server_name &lt;hostname&gt;;
  listen 80;

  root &lt;document root&gt;;

  dav_methods PUT DELETE MKCOL COPY MOVE;
  dav_access group:rw all:r;
  create_full_put_path on;

  include /etc/nginx/fastcgi_params;
  fastcgi_param SCRIPT_FILENAME /var/www/webdav-extensions.php;
  fastcgi_param DEPTH $http_depth;

  location / {
    if ($request_method ~ ^(PROPFIND|OPTIONS)$) {
      fastcgi_pass localhost:9000;
      break;
    }
  }
}</pre>
<p>The document root (and everything in it!) was chowned &#8220;www-data:www-data&#8221;, which is the user that NGINX runs as. Make sure the directory <em>above</em> your document root is owned by root, so that people using WebDAV aren&#8217;t allowed to mess with the document root itself.</p>
<p>You will note that we&#8217;re running a PHP FCGI process (which we spawn with the LightTPD-supplied &#8220;spawn-fcgi&#8221; program) on localhost, on port 9000. Make sure you firewall whatever port you run your FCGI process on, or else you&#8217;ll have a great, big security hole in your network.</p>
<p>Also bear in mind that you can&#8217;t use a vanilla Debian NGINX (or, whatever UNIX flavor you prefer), as it doesn&#8217;t support WebDAV out-of-the-box. You will need to custom compile it with the &#8220;&#8211;with-http_dav_module&#8221; flag passed to &#8220;./configure&#8221;. It&#8217;s not complicated, but compiling NGINX is beyond the scope of this article.</p>
<p>I tested it with a <a href="http://www.webdav.org/cadaver/" target="_blank">UNIX client I had handy</a>, and things worked pretty well. I could look around the directories, put and retrieve files, move things around, etc. Success!</p>
<p>&#8230;well, not quite. I then tried firing up a Windows client. I could put and get files just fine, but it would error out when I tried to do anything relating to directories. Spending an hour or so poking around in the NGINX access logs and the NGINX WebDAV module&#8217;s source code and I came to realize that the Windows WebDAV client didn&#8217;t follow the HTTP spec: when specifying a directory in HTTP, you must follow it with a slash (e.g. &#8220;http://example.com/directory/&#8221;, and not &#8220;http://example.com/directory&#8221;). Web browsers automatically account for these errors, which is why we never think about this sort of thing. However, NGINX&#8217;s WebDAV support requires the HTTP-compliant behavior (trailing slashes and all), and thus rejects the request. This is mostly easy to fix in NGINX:</p>
<pre>server {
  # ...

  location / {
    # ...

    if (-d $request_filename) { rewrite ^(.*[^/])$ $1/ break; }
    if ($request_method = MKCOL) { rewrite ^(.*[^/])$ $1/ break; }
  }
}</pre>
<p>This says that if the file exists and is a directory, add a trailing slash to the request if it doesn&#8217;t already exist. We do similarly for MKCOL (that is, create directory) requests, since we can&#8217;t check for the directory (since we havn&#8217;t created it yet!).</p>
<p>This solved the problem of creating and deleting directories in Windows! But there was still another problem lurking beneath the surface: the COPY and MOVE methods. See, it was the same problem as above (a lack of a trailing slash), but the destination of the COPY or MOVE is specified in the HTTP &#8220;Destination&#8221; header. While we can retrieve headers in NGINX (since they are made available in variables, such as &#8220;$http_destination&#8221;), NGINX provides no way to modify them.</p>
<p>I first attemped to mangle the headers in NGINX and use a proxy request to NGINX itself to solve this problem. Predictably, I was unable to do so, and even if I had succeeded, the fix would have been positively maddening. So, I took the easy way out and added support for the COPY and MOVE methods into my PHP script, leaving NGINX to handle only PUT, DELETE, and MKCOL (in addition to the raw GET, HEAD, etc. methods). Again, simple, but tedious. Once I implemented it and got it tested, though, it worked perfectly on all platforms I tested it on.</p>
<p>Performance looks great, but that doesn&#8217;t surprise me, considering that the IO-heavy methods (GET and PUT) are implemented in NGINX. The methods I support (OPTIONS, PROPFIND, COPY, and MOVE) are all very simple and transient, meaning that when we do have to drop to PHP, we don&#8217;t have to do so for very long.</p>
<p>The final NGINX setup (which included HTTP Basic Authentication and SSL, for security), looked like this:</p>
<pre>server {
  server_name &lt;hostname&gt;;
  listen 443;

  root &lt;document root&gt;;

  ssl on;
  ssl_certificate &lt;ssl certificate&gt;;
  ssl_certificate_key &lt;ssl private key&gt;;

  auth_basic &lt;authentication realm&gt;;
  auth_basic_user_file &lt;password file&gt;;

  dav_methods PUT DELETE MKCOL;
  dav_access group:rw all:r;
  create_full_put_path on;

  autoindex on;
  autoindex_exact_size off;

  # Variables necessary for proper execution of the PHP script used below.
  include /etc/nginx/fastcgi_params;
  fastcgi_param SCRIPT_FILENAME /var/www/webdav-extensions.php;
  fastcgi_param DEPTH $http_depth;
  fastcgi_param HOST $host;
  fastcgi_param DESTINATION $http_destination;
  fastcgi_param OVERWRITE $http_overwrite;

  location / {
    # NGINX WebDAV support is incomplete and somewhat too strict. We handle
    # a few WebDAV methods manually in a PHP script to fill out the cracks.
    if ($request_method ~ ^(PROPFIND|OPTIONS|COPY|MOVE)$) {
      fastcgi_pass localhost:9000;
      break;
    }

    # NGINX WebDAV requires trailing slashes on directories, yet certain
    # common WebDAV clients don't support them. Do rewrites to fix it,
    if (-d $request_filename) { rewrite ^(.*[^/])$ $1/ break; }
    if ($request_method = MKCOL) { rewrite ^(.*[^/])$ $1/ break; }
  }
}</pre>
<p>The final PHP script is <a href="http://files.agoragames.com/jason/webdav-extensions.php.txt" target="_blank">here</a>. (It&#8217;s not 100% WebDAV complient. Or even close. But it seems to cover all the common cases, as we havn&#8217;t had any trouble with it yet.)</p>
<p>What&#8217;s especially awesome is that, if you just want quick read-only access, you can hit the WebDAV URL in a web browser and surf around that way (thanks to the NGINX &#8220;autoindex&#8221; module). You can also mount this (in just about any OS, including the built-in Mac OS X, Windows, and Ubuntu clients) for drag-and-drop access to the share, just like it was a local disk.</p>
<p>I have some vague notions to extend it to handle SVN and GIT (as we currently proxy to Apache for HTTP access to those). Seeing as how the logic is so simple, it would probably be trivial to patch the NGINX WebDAV module with these changes as well. Those are blog posts for another day, though.</p>




	<a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F20%2Fwebdav-nginx-play-nice%2F&amp;title=Making%20WebDAV%20and%20NGINX%20Play%20Nice%20Together" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F20%2Fwebdav-nginx-play-nice%2F&amp;title=Making%20WebDAV%20and%20NGINX%20Play%20Nice%20Together&amp;bodytext=NGINX%20supports%20WebDAV%2C%20but%20its%20support%20is%20incomplete.%20Here%27s%20how%20we%20made%20a%20quick%20PHP%20hack%20to%20allow%20us%20to%20use%20WebDAV%20without%20having%20to%20proxy%20to%20another%20web%20server.%0D%0A%0D%0A%0D%0A%0D%0AWebDAV%20is%20a%20pretty%20awesome%20method%20of%20maintaining%20a%20shared%20data%20repository%3A%20it%27s%20" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F20%2Fwebdav-nginx-play-nice%2F&amp;title=Making%20WebDAV%20and%20NGINX%20Play%20Nice%20Together&amp;notes=NGINX%20supports%20WebDAV%2C%20but%20its%20support%20is%20incomplete.%20Here%27s%20how%20we%20made%20a%20quick%20PHP%20hack%20to%20allow%20us%20to%20use%20WebDAV%20without%20having%20to%20proxy%20to%20another%20web%20server.%0D%0A%0D%0A%0D%0A%0D%0AWebDAV%20is%20a%20pretty%20awesome%20method%20of%20maintaining%20a%20shared%20data%20repository%3A%20it%27s%20" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F20%2Fwebdav-nginx-play-nice%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2009/03/20/webdav-nginx-play-nice/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->