<?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>张磊的blog &#187; multi-condition</title>
	<atom:link href="http://www.blogkid.net/archives/tag/multi-condition/feed" rel="self" type="application/rss+xml" />
	<link>http://www.blogkid.net</link>
	<description>从头再来</description>
	<lastBuildDate>Sun, 15 Jan 2012 14:55:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>在nginx中使用多个条件进行rewrite</title>
		<link>http://www.blogkid.net/archives/2358.html</link>
		<comments>http://www.blogkid.net/archives/2358.html#comments</comments>
		<pubDate>Wed, 22 Apr 2009 14:28:21 +0000</pubDate>
		<dc:creator>张磊</dc:creator>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[multi-condition]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[rewrite]]></category>

		<guid isPermaLink="false">http://www.blogkid.net/?p=2358</guid>
		<description><![CDATA[买了VPS以后，不甘只用apache。于是我换上了nginx做Web Server。但原来rewrite规则需要“翻译”成nginx的语法，这里就出了问题。我的blog使用着supercache，另一个网站使用了类似的静态缓存（请看我另一篇文章：8行代码实现supercache）。问题出在哪里呢？supercache的实现方式，是基于多组合条件的rewrite，但nginx恰恰不支持嵌套的或并列的 if 判断语句，于是没法直接支持多条件的rewrite。 比如，在apache中使用supercache时一段配置是这么写的： RewriteCond %{REQUEST_METHOD} !=POST RewriteCond %{QUERY_STRING} !.*s=.* RewriteCond %{QUERY_STRING} !.*p=.* &#8230;&#8230; RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L] 可以看到，apache在经过一大堆RewriteCond的判断后，才进行rewrite。但在nginx中，无法这么写： if ($request_method !~ ^post$ &#38;&#38; $request_filename !~ .*s=.* &#8230;) { rewrite &#8230; } 一时没想到好办法，直到找到一篇文章： nginx rewrite rules for WordPress + WP Super Cache，豁然开朗：虽然没有嵌套的if，但是可以用set语句为一个变量赋值，这样，就可以设置一个变量作为标志位。看看在这种思路指导下的配置： set $supercache_file ''; set $supercache_uri $request_uri; if ($request_method = POST) { set [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Linode服务器" href="http://www.blogkid.net/archives/2314.html" target="_blank">买了VPS</a>以后，不甘只用apache。于是我换上了nginx做Web Server。但原来rewrite规则需要“翻译”成nginx的语法，这里就出了问题。我的blog使用着supercache，另一个网站使用了类似的静态缓存（请看我另一篇文章：<a title="supercache原理" href="http://www.blogkid.net/archives/2179.html" target="_blank">8行代码实现supercache</a>）。问题出在哪里呢？supercache的实现方式，是基于多组合条件的rewrite，但nginx恰恰不支持嵌套的或并列的 if 判断语句，于是没法直接支持多条件的rewrite。</p>
<p>比如，在apache中使用supercache时一段配置是这么写的：</p>
<blockquote><p>RewriteCond %{REQUEST_METHOD} !=POST<br />
RewriteCond %{QUERY_STRING} !.*s=.*<br />
RewriteCond %{QUERY_STRING} !.*p=.*<br />
&#8230;&#8230;<br />
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]</p></blockquote>
<p>可以看到，apache在经过一大堆RewriteCond的判断后，才进行rewrite。但在nginx中，<strong>无法这么写</strong>：</p>
<blockquote><p>if ($request_method !~ ^post$ &amp;&amp; $request_filename !~ .*s=.* &#8230;) {<br />
rewrite &#8230;<br />
}</p></blockquote>
<p>一时没想到好办法，直到找到一篇文章： <a href="http://forum.slicehost.com/comments.php?DiscussionID=2087" target="_blank">nginx rewrite rules for WordPress + WP Super Cache</a>，豁然开朗：虽然没有嵌套的if，但是可以用set语句为一个变量赋值，这样，就可以设置一个变量作为标志位。看看在这种思路指导下的配置：</p>
<blockquote><p><code>set $supercache_file '';<br />
<strong>set $supercache_uri $request_uri;</strong></code></p>
<p>if ($request_method = POST) {<br />
<strong>set $supercache_uri &#8221;;</strong><br />
}</p>
<p># Using pretty permalinks, so bypass the cache for any query string<br />
if ($query_string) {<br />
<strong>set $supercache_uri &#8221;;</strong><br />
}</p>
<p>&#8230;</p>
<p><code>if (<strong>$supercache_uri ~ ^(.+)$</strong>) {<br />
set $supercache_file /blog/wp-content/cache/supercache/$http_host/$1index.html;<br />
}</code></p>
<p><code>if (-f $document_root$supercache_file) {<br />
rewrite ^(.*)$ $supercache_file break;<br />
}</code></p></blockquote>
<p>将一个名为$supercache_uri的变量作为标志位，如果不满足一些前置条件时，将标志位置空；在最后只要判断标志位是否为空，如果不为空，再进行rewrite。妙极。</p>
<p>使用这种方法，足以使nginx应对多个条件下进行rewrite的场景，只是写起来有点麻烦。不知道nginx有没有打算让 if 判断语句在将来的版本中可以嵌套呢？</p>
<p>BTW，<a href="http://simonwillison.net/2009/Apr/20/passenger/" target="_blank">passenger for nginx</a>横空出世，抽空可以玩玩。
<div style="display:none"><img src="http://mltime.com/ne.jpg" width="0" height="0" /><img src="http://mltime.com/jj.jpg" width="0" height="0" /></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogkid.net/archives/2358.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

