<?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>james holden &#187; Web Development</title>
	<atom:link href="http://jamesholden.net/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://jamesholden.net</link>
	<description>the website of james holden, who ain't a dance music dj</description>
	<lastBuildDate>Thu, 27 May 2010 08:43:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Locations and conditional rewrites in Nginx</title>
		<link>http://jamesholden.net/2009/09/03/locations-and-conditional-rewrites-in-nginx/</link>
		<comments>http://jamesholden.net/2009/09/03/locations-and-conditional-rewrites-in-nginx/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 11:50:08 +0000</pubDate>
		<dc:creator>James Holden</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://jamesholden.net/?p=198</guid>
		<description><![CDATA[jamesholden.net runs on nginx, and has done ever since the anti-terror billboard went totally viral. Whilst many people haven’t heard of nginx, it’s got a fair few success stories to its name and powers some major sites including Wordpress.com and FastMail.FM.]]></description>
			<content:encoded><![CDATA[<p><a href="http://jamesholden.net/">jamesholden.net</a> runs on <a href="http://nginx.net">nginx</a>, and has done ever since the <a href="/billboard/">anti-terror billboard</a> went <a href="http://theridiculant.metro.co.uk/2009/04/antiterror-poster-remix-lols.html">totally</a> <a href="http://www.b3ta.com/newsletter/issue373/#line209">viral</a>.</p>
<p>Whilst many people haven&#8217;t heard of nginx, it&#8217;s got a fair few success stories to its name and powers some major sites including <a href="http://barry.wordpress.com/2008/04/28/load-balancer-update/">WordPress.com</a> and <a href="http://blog.fastmail.fm/2007/01/04/webimappop-frontend-proxies-changed-to-nginx/">FastMail.FM</a>.</p>
<p><img src="/images/nginx.jpg" /></p>
<p><span id="more-198"></span></p>
<p>With nginx, many operations beyond serving of static files are treated by nginx as a proxy operations, whether it&#8217;s passing the request to one or more back-end servers or to a CGI handler such as PHP. For example, the server that runs jamesholden.net also runs a subversion repository but nginx can&#8217;t do that by itself, so it passes any requests for the subversion repository to an instance of Apache running behind the scenes. There&#8217;s a huge amount of flexibility afforded in how a request is handled.</p>
<p>The configuration file format used by nginx differs from that of Apache in that nginx uses braces to define nested sections and allows conditional tests to determine whether a section of the configuration should be included for a particular request, while Apache uses nested tags in angle brackets to open and close sections.</p>
<p>A basic server configurations looks similar to this:</p>
<pre>
http {
    server {
        listen 1.2.3.4:80;
        server_name testing.example.com;
        root /var/www;
    }
}
</pre>
<p>This is analogous to an Apache style &lt;VirtualHost&gt; directive, complete with ServerName and DocumentRoot. The <em>location</em> block is fundamental to tailoring the behavior of nginx as the expression that follows can be used to handle different URI paths in different ways. Without this flexibility nginx would not be able to pass PHP scripts to the fastcgi backend or proxy requests to back-end systems. The location does not need to be a path &#8211; it can also be a label which we can use to break out of another location under certain circumstances.</p>
<p>At present, all this basic example above will do is serve static pages from the document root <tt>/var/www</tt>. If we want to serve PHP files, we would need to include an additional location with a pattern to match requests ending in .php. This would be placed within the server block.</p>
<pre>
location ~* \.php$ {
    fastcgi_pass 127.0.0.1:10005;
}
</pre>
<p>Assuming that there is a fastcgi handler living on localhost port 10005, and that the rest of the fastcgi configuration has been included at an earlier point in the config, we can now pass PHP scripts to the fastcgi handler. In the location directive, the ~* indicates that pattern is case-insensitive, and the \.php$ is a regular expression that matches the string &#8220;.php&#8221; at the end of the request. nginx prioritises the PHP location directive because it uses a regular expression.</p>
<p>You may specify location matches without the use of regular expressions. This can be useful to ensure that static content is handled as a priority. For example:</p>
<pre>
location = / {
    # Matches only requests for the home page (and only the home page)
    # This can be useful to serve a cached version of the home page on a high volume site, yet
    # allow for dynamic content on the rest of the site
}

location ^~ /static/ {
    # Matches requests beginning /static/
}

location *~ \.bin$ {
    # Matches only files ending in .bin that are not in /static/
}
</pre>
<p>Only one location will match per request unless we re-write it, so it is not possible to define overrides on anything other than the URI using location directives. You can do this within a directive block though, using conditional statements.</p>
<p>Two useful directives are the &#8220;root&#8221; directive and the &#8220;alias&#8221; directive. At first sight, these may seem to be similar, but they are subtly different. For example:</p>
<pre>
location ^~ /docs/ {
    root /usr/share/web;
    # Requests for /docs/foo.txt will be served from /usr/share/web/docs/foo.txt
}

location ^~ /icons/ {
    alias /var/www/icons;
    # Requests for /icons/error.png will be served from /var/www/icons/error.png
}
</pre>
<p>A caveat is that the alias directive cannot be used in a location based on a regular expression.</p>
<p>The final type of location directive is a named location. This can be used in conjunction with a &#8220;try_files&#8221; directive to allow static files to be served, while passing other requests to a CMS such as wordpress, eg:</p>
<pre>
location / {
    root /var/www;
    try_files $uri @wordpress;
}

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

location ~ \.php$ {
    fastcgi_pass 127.0.0.1:10005;
}
</pre>
<p>This works because the @wordpress location transforms the request into a call to index.php. This causes the request to be re-entered, where it will match the third location block and be passed to the PHP fastcgi handler for execution. There are multiple ways of achieving this, however.</p>
<p>We just used the rewrite directive to transform the URL into another. Just like Apache, we can use regular expressions to match particular URLs and to transform the request. A common use for this is to provide redirection from bare domain names to their www counterparts or vice-versa, for example this is used on jamesholden.net to bounce visitors off www.jamesholden.net to jamesholden.net, which is my preferred URL:</p>
<pre>
server {
    listen 1.2.3.4:80;
    server_name www.jamesholden.net;
    rewrite ^(.*) http://jamesholden.net$1 permanent;
}
</pre>
<p>In this example, we don&#8217;t even need to use a location directive because the entire site is being redirected. The &#8220;permanent&#8221; parameter on the rewrite rule ensures that nginx issues an HTTP 301 response.</p>
<p>Conditional statements can be used to check server variables from within a location directive. You could use this to prevent image hotlinking as follows:</p>
<pre>
location ~* \.jpg$ {
    if ( $http_referer !~ ^http://jamesholden.net/ ) {
        rewrite ^(.*) /nostealing.jpg last;
    }
}

location = /nostealing.jpg { }
</pre>
<p>Requests for .jpg files where the referer does not begin http://jamesholden.net/ will be re-written to /nostealing.jpg. The final empty location ensures that the replacement image is not rewritten itself, otherwise a loop would ensue.</p>
<p>These examples are just the tip of the iceberg of what can be done with nginx, so feel free to share your own examples in the comments section. Thanks for reading!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamesholden.net/2009/09/03/locations-and-conditional-rewrites-in-nginx/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GeekUp Leeds Was Fun!</title>
		<link>http://jamesholden.net/2007/09/19/geekup-leeds-was-fun/</link>
		<comments>http://jamesholden.net/2007/09/19/geekup-leeds-was-fun/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 23:38:10 +0000</pubDate>
		<dc:creator>James Holden</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://jamesholden.net/2007/09/19/geekup-leeds-was-fun/</guid>
		<description><![CDATA[James Holden went to Geekup Leeds, and gave a talk on SMS and MMS messaging. Here are the slides and a link to the interactive SMS/MMS text-in wall.]]></description>
			<content:encoded><![CDATA[<p>Just got back from the Leeds GeekUp meeting&#8230; which was lots of fun :)</p>
<p>My talk seemed to go down well, and I met lots of really nice people.</p>
<p>My <a href="/docs/phonemeetsweb.odp">talk slides</a> are available for download for anyone who wants one, and the <a href="http://geekup.jamesholden.net/">GeekUp SMS/MMS graffiti wall</a> is there for posterity (and future use and other GeekUp meetings).</p>
<p><img src="http://farm2.static.flickr.com/1172/1411019639_0f498fc0dc_m_d.jpg" alt="James Holden giving his talk at GeekUp" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamesholden.net/2007/09/19/geekup-leeds-was-fun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pear AJAX Library for PHP</title>
		<link>http://jamesholden.net/2006/03/24/pear-ajax-library-for-php/</link>
		<comments>http://jamesholden.net/2006/03/24/pear-ajax-library-for-php/#comments</comments>
		<pubDate>Fri, 24 Mar 2006 18:07:49 +0000</pubDate>
		<dc:creator>James Holden</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://jamesholden.net/2006/03/24/pear-ajax-library-for-php/</guid>
		<description><![CDATA[A colleague pointed me to the Pear HTML_AJAX library today. The library essentially allows nominated PHP classes to be instantiated and called from Javascript on the client end. It looks very cool indeed. I think I&#8217;ll have a look at this for the WYLUG talk manager I&#8217;m writing.]]></description>
			<content:encoded><![CDATA[<p>A colleague pointed me to the <a target="_blank" title="Pear HTML_AJAX library" href="http://pear.php.net/package/HTML_AJAX/">Pear HTML_AJAX</a> library today. The library essentially allows nominated PHP classes to be instantiated and called from Javascript on the client end. It looks very cool indeed. I think I&#8217;ll have a look at this for the WYLUG talk manager I&#8217;m writing.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamesholden.net/2006/03/24/pear-ajax-library-for-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
