<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-29252337</id><updated>2012-02-17T13:17:12.365+08:00</updated><title type='text'>Human &amp; Machine</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default?start-index=101&amp;max-results=100'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>193</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-29252337.post-143123402450168143</id><published>2012-02-03T15:55:00.001+08:00</published><updated>2012-02-03T15:55:12.726+08:00</updated><title type='text'>Test::Nginx 0.18 just released to CPAN</title><content type='html'>I&amp;#39;ve just uploaded Test::Nginx 0.18 to CPAN:&lt;br&gt;&lt;br&gt;   &lt;a href="http://search.cpan.org/dist/Test-Nginx/"&gt;http://search.cpan.org/dist/Test-Nginx/&lt;/a&gt;&lt;br&gt;&lt;br&gt;It will appear on the CPAN mirror near you in the next few hours or so.&lt;br&gt; &lt;br&gt;Special thanks go to all of our users :)&lt;br&gt;&lt;br&gt;Here&amp;#39;s the complete change log for this release, compared to the last CPAN release, 0.17:&lt;br&gt;&lt;ul&gt;&lt;li&gt;feature: added new section &amp;quot;--- no_error_log&amp;quot; which could be used to specify patterns of lines that do not appear in error.log at all.&lt;/li&gt; &lt;li&gt;feature: added MOCKEAGAIN_VERBOSE, DYLD_INSERT_LIBRARIES, TOCKEAGAIN_WRITE_TIMEOUT_PATTERN, and LD_PRELOAD to the environments that should be kept through nginx reload and restart.&lt;/li&gt;&lt;li&gt;doc: added Naxsi and ngx_rds_csv to the user module list in the POD documentation.&lt;/li&gt; &lt;li&gt;feature: now we can use the environment TEST_NGINX_USE_VALGRIND to specify the valgrind command-line options, when set to 1 or other non-zero numbers, it is effectively equivalent to the value &amp;quot;--tool=memcheck --leak-check=full&amp;quot;. To use Valgrind SGCheck to run the tests, just specify the environment TEST_NGINX_USE_VALGRIND=&amp;quot;--tool=exp-sgcheck&amp;quot; first.&lt;/li&gt; &lt;li&gt;feature: added support for environment TEST_NGINX_VERBOSE.&lt;/li&gt;&lt;li&gt;feature: added support for environment TEST_NGINX_USE_HUP.&lt;/li&gt;&lt;li&gt;feature: added support for the TEST_NGINX_POSTPONE_OUTPUT environment.&lt;/li&gt;&lt;li&gt;feature: now we&amp;#39;ll retry sending the QUIT signal for at most 5 times when the nginx process is refusing to quit. after 5 trials, KILL signal will be sent.&lt;/li&gt; &lt;li&gt;feature: exposes the &amp;quot;master_off&amp;quot; API which turns off the nginx master process.&lt;/li&gt;&lt;li&gt;feature: added new section &amp;quot;--- ignore_response&amp;quot; to test bad responses.&lt;/li&gt;&lt;li&gt;bugfix: Test::Nginx::Socket will retry 10 times if fail to connect because nginx with valgrind can be very slow to start in some systems.&lt;/li&gt; &lt;li&gt;feature: added new section name &amp;quot;--- error_log&amp;quot; to test error lines. requested by Piotr Sikora in the last year or so.&lt;/li&gt;&lt;li&gt;feature: added the TEST_NGINX_EVENT_TYPE environment to specify an event API type (like &amp;quot;epoll&amp;quot; or &amp;quot;select&amp;quot;) when running the test suite.&lt;/li&gt; &lt;/ul&gt;This Perl module provides a test scaffold based on &lt;a href="http://search.cpan.org/perldoc?IO::Socket"&gt;IO::Socket&lt;/a&gt; or LWP for automated testing in Nginx C module development.&lt;br&gt;&lt;br&gt;This class inherits from &lt;a href="http://search.cpan.org/perldoc?Test::Base"&gt;Test::Base&lt;/a&gt;, thus bringing all its declarative power to the Nginx C module testing practices.&lt;br&gt; &lt;br&gt;Please check out the full documentation on CPAN:&lt;br&gt;&lt;br&gt;    &lt;a href="http://search.cpan.org/perldoc?Test::Nginx::Socket"&gt;http://search.cpan.org/perldoc?Test::Nginx::Socket&lt;/a&gt;&lt;br&gt;&lt;br&gt;All of our Nginx modules are using Test::Nginx to drive their test suites.&lt;br&gt; &lt;br&gt;Please note that this is different from the Test::Nginx module developed by Maxim Dounin.&lt;br&gt;&lt;br&gt;Enjoy! &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-143123402450168143?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/143123402450168143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=143123402450168143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/143123402450168143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/143123402450168143'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/02/testnginx-018-just-released-to-cpan.html' title='Test::Nginx 0.18 just released to CPAN'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8682996741066324129</id><published>2012-02-01T12:52:00.001+08:00</published><updated>2012-02-01T12:52:55.408+08:00</updated><title type='text'>ngx_openresty stable version 1.0.10.48 released!</title><content type='html'>I&amp;#39;m happy to announce that the new stable release of ngx_openresty, 1.0.10.48, has just been kicked out of door:&lt;br&gt;&lt;br&gt;     &lt;a href="http://openresty.org/#Download"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt;&lt;br&gt;This is the 3rd stable release of ngx_openresty that is based on the Nginx core 1.0.10, which is a maintenance release. &lt;br&gt; &lt;br&gt;Special thanks go to all our contributors and users to help make this &lt;span&gt;release&lt;/span&gt; happen :)&lt;br&gt;&lt;br&gt;Here goes the complete change log for this &lt;span&gt;release&lt;/span&gt;, as compared to the last stable &lt;span&gt;release&lt;/span&gt;, 1.0.10.44, &lt;span&gt;released&lt;/span&gt; about two weeks ago:&lt;br&gt; &lt;div class="viewer"&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.4.1.&lt;ul&gt;&lt;li&gt; bugfix: &lt;code&gt;ngx_http_lua_header_filter_init&lt;/code&gt;  was called with an argument which actually accepts none. this could  cause compilation errors at least with gcc 4.3.4 as reported in github &lt;a target="_blank" title="External link to http://github.com/chaoslawful/lua-nginx-module/issues/80" href="http://github.com/chaoslawful/lua-nginx-module/issues/80" class="externalLink"&gt;issue #80&lt;/a&gt;. thanks bigplum (Simon).&lt;/li&gt; &lt;li&gt; bugfix: fixed all the warnings from the &lt;code&gt;clang&lt;/code&gt; static analyzer.&lt;/li&gt;&lt;li&gt; bugfix: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.exit" href="http://wiki.nginx.org/HttpLuaModule#ngx.exit" class="externalLink"&gt;ngx.exit&lt;/a&gt;, &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.redirect" href="http://wiki.nginx.org/HttpLuaModule#ngx.redirect" class="externalLink"&gt;ngx.redirect&lt;/a&gt;, &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.exec" href="http://wiki.nginx.org/HttpLuaModule#ngx.exec" class="externalLink"&gt;ngx.exec&lt;/a&gt;, and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.set_uri" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.set_uri" class="externalLink"&gt;ngx.req.set_uri(uri, true)&lt;/a&gt;  could return (they should never return as per the documentation). this  bug had appeared in ngx_lua v0.3.1rc4 and ngx_openresty 1.0.6.13. thanks  &lt;a target="_blank" title="External link to http://weibo.com/cyberty" href="http://weibo.com/cyberty" class="externalLink"&gt;@cyberty&lt;/a&gt; for reporting it.&lt;/li&gt;&lt;li&gt; feature: allow use of the &lt;code&gt;DDEBUG&lt;/code&gt; macro from the outside (via the &lt;code&gt;-D DDEBUG=1&lt;/code&gt; cc opton).&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="DrizzleNginxModule - ZhangYichun, Mon 28 Nov 2011 02:39:00 PM CST"&gt;DrizzleNginxModule&lt;/a&gt; to v0.1.2rc6.&lt;ul&gt;&lt;li&gt; bugfix: fixed all the warnings from the &lt;code&gt;clang&lt;/code&gt; static analyzer.&lt;/li&gt; &lt;li&gt; feature: allow use of the &lt;code&gt;DDEBUG&lt;/code&gt; macro from the outside (via the &lt;code&gt;-D DDEBUG=1&lt;/code&gt; cc opton).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="EchoNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;EchoNginxModule&lt;/a&gt; to 0.38rc1, &lt;a class="tiddlyLink tiddlyLinkExisting" title="SetMiscNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;SetMiscNginxModule&lt;/a&gt; to 0.22rc5, &lt;a class="tiddlyLink tiddlyLinkExisting" title="HeadersMoreNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;HeadersMoreNginxModule&lt;/a&gt; to 0.17rc1, and &lt;a class="tiddlyLink tiddlyLinkExisting" title="MemcNginxModule - ZhangYichun, Fri 26 Aug 2011 09:11:00 AM CST"&gt;MemcNginxModule&lt;/a&gt; to 0.13rc3, to allow use of the &lt;code&gt;DDEBUG&lt;/code&gt; macro from the outside (via the &lt;code&gt;-D DDEBUG=1&lt;/code&gt; cc opton).&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;   As always, you&amp;#39;re welcome to report bugs and feature requests either here or directly to me :)&lt;br&gt;&lt;br&gt;&lt;span&gt;&lt;span class="il"&gt;OpenResty&lt;/span&gt;&lt;/span&gt; (aka. &lt;span&gt;&lt;span class="il"&gt;ngx_openresty&lt;/span&gt;&lt;/span&gt;)  is a full-fledged web application server by bundling the standard Nginx  core, lots of 3rd-party Nginx modules, as well as most of their  external dependencies.&lt;br&gt;  &lt;br&gt;By taking adantage of various well-designed Nginx modules, &lt;span&gt;&lt;span class="il"&gt;OpenResty&lt;/span&gt;&lt;/span&gt;  effectively turns the nginx server into a powerful web app server, in  which the web developers can use the Lua programming language to script  various existing nginx C modules and Lua modules and construct extremely  high-performance web applications that is capable to handle 10K+  connections.&lt;br&gt;  &lt;br&gt;&lt;span&gt;&lt;span class="il"&gt;OpenResty&lt;/span&gt;&lt;/span&gt; aims to run your server-side web  app completely in the Nginx server, leveraging Nginx&amp;#39;s event model to do  non-blocking I/O not only with the HTTP clients, but also with remote  backends like MySQL, PostgreSQL, Memcached, and Redis.&lt;br&gt;  &lt;br&gt;You can find more details on the homepage of &lt;span&gt;&lt;span class="il"&gt;ngx_openresty&lt;/span&gt;&lt;/span&gt; here:&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org/" target="_blank"&gt;http://&lt;span&gt;&lt;span class="il"&gt;openresty&lt;/span&gt;&lt;/span&gt;.org&lt;/a&gt;&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8682996741066324129?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8682996741066324129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8682996741066324129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8682996741066324129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8682996741066324129'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/02/ngxopenresty-stable-version-101048.html' title='ngx_openresty stable version 1.0.10.48 released!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1481021698511901446</id><published>2012-02-01T12:01:00.001+08:00</published><updated>2012-02-01T12:01:42.971+08:00</updated><title type='text'>ngx_lua module v0.4.1 released!</title><content type='html'>I&amp;#39;m happy to announce the v0.4.1 &lt;span class="il"&gt;release&lt;/span&gt; of our &lt;span class="il"&gt;ngx_lua&lt;/span&gt; module. You can get the &lt;span class="il"&gt;release&lt;/span&gt; tarball from the download page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/tags" target="_blank"&gt;https://github.com/chaoslawful/&lt;span class="il"&gt;lua&lt;/span&gt;-nginx-module/tags&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Here&amp;#39;s the change log compared to the last formal release, v0.4.0:&lt;br&gt;&lt;ul&gt;&lt;li&gt; bugfix: &lt;a href="http://wiki.nginx.org/HttpLuaModule#ngx.exit"&gt;ngx.exit&lt;/a&gt;, &lt;a href="http://wiki.nginx.org/HttpLuaModule#ngx.redirect"&gt;ngx.redirect&lt;/a&gt;, &lt;a href="http://wiki.nginx.org/HttpLuaModule#ngx.exec"&gt;ngx.exec&lt;/a&gt;, and &lt;a href="http://wiki.nginx.org/HttpLuaModule#ngx.req.set_uri"&gt;ngx.req.set_uri(uri, true)&lt;/a&gt;  could return (they should never return as per the documentation). this  bug had appeared in ngx_lua v0.3.1rc4 and ngx_openresty 1.0.6.13. thanks  &lt;a rel="nofollow" class="external text" href="http://weibo.com/cyberty"&gt;@cyberty&lt;/a&gt; for reporting it. &lt;/li&gt;&lt;li&gt; bugfix: &lt;code&gt;ngx_http_lua_header_filter_init&lt;/code&gt; was  called with an argument which actually accepts none. this could cause  compilation errors at least with gcc 4.3.4 as reported in &lt;a rel="nofollow" class="external text" href="http://github.com/chaoslawful/lua-nginx-module/issues/80"&gt;github issue #80&lt;/a&gt;. thanks bigplum (Simon). &lt;/li&gt;&lt;li&gt; bugfix: fixed all the warnings from the clang static analyzer. &lt;/li&gt;&lt;li&gt; feature: allow use of the &lt;code&gt;DDEBUG&lt;/code&gt; macro from the outside (via the &lt;code&gt;-D DDEBUG=1&lt;/code&gt; C compiler opton). &lt;/li&gt;&lt;/ul&gt; Special thanks go to all of our contributors and users!&lt;br&gt;&lt;br&gt;I&amp;#39;m currently focusing on the ngx_lua cosocket branch which will become the v0.5.x series. With the upcoming cosocket support, we&amp;#39;ll be able to code up nonblocking network client drivers for various backend services (memcached, mysql, redis, to name a few) in pure Lua, and these drivers could be even faster than the old approach that requires combining nginx subrequests and nginx upstream modules.&lt;br&gt; &lt;br&gt;This Nginx module embeds the &lt;span class="il"&gt;Lua&lt;/span&gt; 5.1 interpreter or LuaJIT 2.0 into the nginx core and integrates the powerful &lt;span class="il"&gt;Lua&lt;/span&gt; threads (aka &lt;span class="il"&gt;Lua&lt;/span&gt; coroutines) into the nginx event model by means of nginx subrequests.&lt;br&gt;  &lt;br&gt;Unlike Apache&amp;#39;s mod_lua and Lighttpd&amp;#39;s mod_magnet, &lt;span class="il"&gt;Lua&lt;/span&gt; code written atop this module can be 100% non-blocking on network traffic as long as you use the &lt;span class="il"&gt;ngx&lt;/span&gt;.location.capture or &lt;span class="il"&gt;ngx&lt;/span&gt;.location.capture_multi  interfaces to let the Nginx core do all your requests to mysql,  postgresql, memcached, redis, upstream http web services, and etc etc  etc.&lt;br&gt; &lt;br&gt;This module is also included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org/" target="_blank"&gt;http://openresty.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;You can find the complete documentation for this module on the following wiki page:&lt;br&gt;  &lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpLuaModule" target="_blank"&gt;http://wiki.nginx.org/HttpLuaModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;And you always get the latest source code from the git repository here:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module" target="_blank"&gt;https://github.com/chaoslawful/&lt;span class="il"&gt;lua&lt;/span&gt;-nginx-module&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Have fun! &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1481021698511901446?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1481021698511901446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1481021698511901446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1481021698511901446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1481021698511901446'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/02/ngxlua-module-v041-released.html' title='ngx_lua module v0.4.1 released!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1052271654107111718</id><published>2012-01-16T22:32:00.002+08:00</published><updated>2012-01-16T22:43:38.775+08:00</updated><title type='text'>ngx_openresty stable version 1.0.10.44 released!</title><content type='html'>I'm happy to announce that the new stable &lt;span class="il"&gt;release&lt;/span&gt; of &lt;span class="il"&gt;ngx_openresty&lt;/span&gt;, 1.0.10.44, has just been kicked out of door:&lt;br /&gt;&lt;br /&gt;  &lt;a href="http://openresty.org/#Download" target="_blank"&gt;http://&lt;span class="il"&gt;openresty&lt;/span&gt;.org/#Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is the second stable &lt;span class="il"&gt;release&lt;/span&gt; of &lt;span class="il"&gt;ngx_openresty&lt;/span&gt; that is based on the Nginx core 1.0.10 (and the next one will be based on the Nginx core 1.0.11+).&lt;br /&gt;&lt;br /&gt;Special thanks go to all our contributors and users to help make this &lt;span class="il"&gt;release&lt;/span&gt; happen :)&lt;br /&gt;&lt;br /&gt;Here goes the complete change log for this &lt;span class="il"&gt;release&lt;/span&gt;, as compared to the last stable &lt;span class="il"&gt;release&lt;/span&gt;, 1.0.10.24, &lt;span class="il"&gt;released&lt;/span&gt; about one month ago:&lt;br /&gt;&lt;div class="viewer"&gt;&lt;ul&gt;&lt;li&gt; upgraded Mike Pall's &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaJIT - ZhangYichun, Tue 21 Jun 2011 05:11:00 PM CST"&gt;LuaJIT&lt;/a&gt; to 2.0.0beta9.&lt;ul&gt;&lt;li&gt; changes: &lt;a target="_blank" title="External link to http://luajit.org/changes.html" href="http://luajit.org/changes.html" class="externalLink"&gt;http://luajit.org/changes.html&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="EchoNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;EchoNginxModule&lt;/a&gt; to 0.37.&lt;ul&gt;&lt;li&gt; bugfix: fixed two spots that we did not check null pointers returned by the memory allocator.&lt;/li&gt; &lt;li&gt; bugfix: attempt to fix places where &lt;code&gt;ngx_time_update&lt;/code&gt; might not be compiled properly.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="HeadersMoreNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;HeadersMoreNginxModule&lt;/a&gt; to 0.16.&lt;ul&gt; &lt;li&gt; bugfix: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpHeadersMoreModule#more_set_input_headers" href="http://wiki.nginx.org/HttpHeadersMoreModule#more_set_input_headers" class="externalLink"&gt;more_set_input_headers&lt;/a&gt; and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpHeadersMoreModule#more_clear_input_headers" href="http://wiki.nginx.org/HttpHeadersMoreModule#more_clear_input_headers" class="externalLink"&gt;more_clear_input_headers&lt;/a&gt; did not handle the &lt;code&gt;Accept-Encoding&lt;/code&gt; request headers properly. thanks 天街夜色.&lt;/li&gt; &lt;li&gt;  bugfix: removing builtin headers in huge request headers with 20+  entries could result in data loss. thanks Chris Dumoulin for the patch  in &lt;a target="_blank" title="External link to https://github.com/agentzh/headers-more-nginx-module/issues/6" href="https://github.com/agentzh/headers-more-nginx-module/issues/6" class="externalLink"&gt;github issue #6&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; bugfix: the &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpHeadersMoreModule#more_set_headers" href="http://wiki.nginx.org/HttpHeadersMoreModule#more_set_headers" class="externalLink"&gt;more_set_input_headers&lt;/a&gt; directive might cause invalid memory reads because Nginx request header values must be null terminated. thanks Maxim Dounin.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.4.0.&lt;ul&gt;&lt;li&gt; bugfix: &lt;code&gt;ngx.flush(true)&lt;/code&gt; could not be used before I/O calls like &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" class="externalLink"&gt;ngx.location.capture&lt;/a&gt;. this bug had appeared in v0.3.1rc34.&lt;/li&gt; &lt;li&gt; bugfix: &lt;code&gt;ngx.var.VARIABLE&lt;/code&gt; did not evaluate to &lt;code&gt;nil&lt;/code&gt; when the Nginx variable's &lt;code&gt;valid&lt;/code&gt; flag is &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; docs: various documentation improvements. thanks Nginx User.&lt;/li&gt; &lt;li&gt; bugfix: there were various places where we did not check the pointer returned by the memory allocator.&lt;/li&gt;&lt;li&gt; bugfix: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.get_uri_args" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.get_uri_args" class="externalLink"&gt;ngx.req.get_uri_args&lt;/a&gt; and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.get_post_args" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.get_post_args" class="externalLink"&gt;ngx.req.get_post_args&lt;/a&gt;  now only parse up to 100 arguments by default. but one can specify the  optional argument to these two methods to specify a custom maximum  number of args. thanks Tzury Bar Yochay for reporting this.&lt;/li&gt;&lt;li&gt; bugfix:  &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.get_headers" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.get_headers" class="externalLink"&gt;ngx.req.get_headers&lt;/a&gt;  now only parse up to 100 request headers by default. but one can  specify the optional argument to this method to specify a custom maximum  number of headers.&lt;/li&gt;&lt;li&gt; bugfix: removing builtin headers via &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.clear_header" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.clear_header" class="externalLink"&gt;ngx.req.clear_header&lt;/a&gt; and its equivalent in huge request headers with 20+ entries could result in data loss. thanks Chris Dumoulin for the patch in &lt;a target="_blank" title="External link to https://github.com/agentzh/headers-more-nginx-module/issues/6" href="https://github.com/agentzh/headers-more-nginx-module/issues/6" class="externalLink"&gt;github issue #6&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;  bugfix: could not compile with Nginx 1.1.12+ because Nginx 1.1.12  changed its regex API. now we call PCRE API directly and require at  least PCRE 8.21 for the PCRE JIT support in our &lt;code&gt;&lt;a href="http://ngx.re/"&gt;ngx.re&lt;/a&gt;&lt;/code&gt; API (since PCRE 8.20 had a bug in its JIT engine that it did not honor &lt;code&gt;pcre_malloc&lt;/code&gt; and &lt;code&gt;pcre_free&lt;/code&gt; at all).&lt;/li&gt; &lt;li&gt; bugfix: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header" class="externalLink"&gt;ngx.req.set_header&lt;/a&gt; might cause invalid memory reads because Nginx request header values must be null terminated. thanks Maxim Dounin.&lt;/li&gt; &lt;li&gt; bugfix: &lt;code&gt;ngx.var.VARIABLE&lt;/code&gt; might evaluate to nil even if there is a valid value because the Nginx variable value's &lt;code&gt;valid&lt;/code&gt; flag might not be initialized properly. this bad had appeared in v0.3.1rc40.&lt;/li&gt; &lt;li&gt; bugfix: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header" class="externalLink"&gt;ngx.req.set_header&lt;/a&gt; and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.clear_header" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.clear_header" class="externalLink"&gt;ngx.req.clear_header&lt;/a&gt; did not handle the &lt;code&gt;Accept-Encoding&lt;/code&gt; request headers properly. thanks 天街夜色.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="EncryptedSessionNginxModule - ZhangYichun, Tue 21 Jun 2011 04:39:00 PM CST"&gt;EncryptedSessionNginxModule&lt;/a&gt; to 0.02.&lt;ul&gt;&lt;li&gt; bugfix: the &lt;code&gt;-lssl&lt;/code&gt; option broke nginx linking when &lt;code&gt;--with-openssl=DIR&lt;/code&gt; is specified. thanks charlieyang for reporting this issue.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="SetMiscNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;SetMiscNginxModule&lt;/a&gt; to v0.22rc4.&lt;ul&gt;&lt;li&gt; bugfix: fixed one place that does not check the pointer returned by the memory allocator.&lt;/li&gt; &lt;li&gt; src: converted &lt;code&gt;CRLF&lt;/code&gt; in the source files and test files to &lt;code&gt;LF&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="SrcacheNginxModule - ZhangYichun, Fri 26 Aug 2011 09:11:00 AM CST"&gt;SrcacheNginxModule&lt;/a&gt; to v0.13rc3.&lt;ul&gt; &lt;li&gt; bugfix: fixed a regression with &lt;a class="tiddlyLink tiddlyLinkExisting" title="XssNginxModule - ZhangYichun, Tue 21 Jun 2011 05:07:00 PM CST"&gt;XssNginxModule&lt;/a&gt; for cache hits. this bug had appeared in v0.13rc1. thanks &lt;a target="_blank" title="External link to http://weibo.com/liseen" href="http://weibo.com/liseen" class="externalLink"&gt;万�新&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; bugfix: we did not cache the &lt;code&gt;Location&lt;/code&gt; response header at all for &lt;code&gt;301&lt;/code&gt;/&lt;code&gt;302&lt;/code&gt; responses.&lt;/li&gt;&lt;li&gt; bugfix: we should not blindly cache the &lt;code&gt;Accept-Ranges: bytes&lt;/code&gt; response headers regardless of the actual current requests.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="XssNginxModule - ZhangYichun, Tue 21 Jun 2011 05:07:00 PM CST"&gt;XssNginxModule&lt;/a&gt; to v0.03rc8.&lt;ul&gt;&lt;li&gt; bugfix: fixed a few debug-level log messages; the old text was misleading.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded Maxim Dounin's &lt;a class="tiddlyLink tiddlyLinkExisting" title="UpstreamKeepaliveNginxModule - ZhangYichun, Fri 26 Aug 2011 09:11:00 AM CST"&gt;UpstreamKeepaliveNginxModule&lt;/a&gt; to 0.7.&lt;ul&gt;&lt;li&gt; Bugfix: unbuffered connection might not be kept alive under Linux.&lt;/li&gt; &lt;li&gt; Bugfix: module could not be built on Windows.&lt;/li&gt;&lt;li&gt; Bugfix: module could not be built without the ngx_http_ssl_module.&lt;/li&gt;&lt;li&gt; Feature: https connections support (requires patches).&lt;/li&gt;&lt;li&gt; Bugfix: invalid connections might be cached.&lt;/li&gt; &lt;li&gt; Bugfix: the &lt;code&gt;"[alert] ... open socket ... left in connection ..."&lt;/code&gt; messages were logged on nginx worker process gracefull exit for each cached connection; the bug had appeared in version 0.3.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; bugfix: fixed issues with relative path DIR in the &lt;code&gt;--with-openssl=DIR&lt;/code&gt; option for &lt;code&gt;./configure&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; bugfix: fixed compatibility of the packaging scripts on Darwin and *BSD. thanks nightsailer and Piotr Sikora.&lt;/li&gt; &lt;li&gt; bugfix: the &lt;code&gt;install&lt;/code&gt; phony target did not depend on the &lt;code&gt;all&lt;/code&gt; phony target in the Makefile generated by &lt;code&gt;./configure&lt;/code&gt;. thanks &lt;a target="_blank" title="External link to http://weibo.com/yaoweibin" href="http://weibo.com/yaoweibin" class="externalLink"&gt;姚伟斌&lt;/a&gt; for reporting this issue.&lt;/li&gt; &lt;li&gt; bugfix: the &lt;code&gt;./configure&lt;/code&gt; script's  &lt;code&gt;--add-module&lt;/code&gt; option did not accept relative path values. thanks &lt;a target="_blank" title="External link to http://weibo.com/yaoweibin" href="http://weibo.com/yaoweibin" class="externalLink"&gt;姚伟斌&lt;/a&gt; for the patch.&lt;/li&gt; &lt;li&gt; bugfix: some old version of shell &lt;code&gt;cp&lt;/code&gt; command does not support trailing slashes in the destination argument and could break our &lt;code&gt;./configure&lt;/code&gt; script. thanks &lt;a target="_blank" title="External link to http://weibo.com/yaoweibin" href="http://weibo.com/yaoweibin" class="externalLink"&gt;姚伟斌&lt;/a&gt; for reporting it.&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;As always, you're welcome to report bugs and feature requests either here or directly to me :)&lt;br /&gt;&lt;br /&gt;&lt;span class="il"&gt;OpenResty&lt;/span&gt; (aka. &lt;span class="il"&gt;ngx_openresty&lt;/span&gt;)  is a full-fledged web application server by bundling the standard Nginx  core, lots of 3rd-party Nginx modules, as well as most of their  external dependencies.&lt;br /&gt;&lt;br /&gt;By taking adantage of various well-designed Nginx modules, &lt;span class="il"&gt;OpenResty&lt;/span&gt;  effectively turns the nginx server into a powerful web app server, in  which the web developers can use the Lua programming language to script  various existing nginx C modules and Lua modules and construct extremely  high-performance web applications that is capable to handle 10K+  connections.&lt;br /&gt;&lt;br /&gt;&lt;span class="il"&gt;OpenResty&lt;/span&gt; aims to run your server-side web  app completely in the Nginx server, leveraging Nginx's event model to do  non-blocking I/O not only with the HTTP clients, but also with remote  backends like MySQL, PostgreSQL, Memcached, and Redis.&lt;br /&gt;&lt;br /&gt;You can find more details on the homepage of &lt;span class="il"&gt;ngx_openresty&lt;/span&gt; here:&lt;br /&gt;&lt;br /&gt;    &lt;a href="http://openresty.org/" target="_blank"&gt;http://&lt;span class="il"&gt;openresty&lt;/span&gt;.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1052271654107111718?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1052271654107111718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1052271654107111718' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1052271654107111718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1052271654107111718'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/01/ngxopenresty-stable-version-101024.html' title='ngx_openresty stable version 1.0.10.44 released!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5463427914842292661</id><published>2012-01-16T15:05:00.001+08:00</published><updated>2012-01-16T15:05:48.721+08:00</updated><title type='text'>ngx_headers_more module v0.16 released!</title><content type='html'>I&amp;#39;m happy to announce the v0.16 release of our &lt;span&gt;&lt;span class="il"&gt;ngx_headers_more&lt;/span&gt;&lt;/span&gt;  module with various bug fixes accumulated in the last 6 months. You can download the source code tarball from the download page below:&lt;br&gt; &lt;br&gt; &amp;nbsp; &amp;nbsp;&lt;a href="http://github.com/agentzh/headers-more-nginx-module/tags" target="_blank"&gt;http://github.com/agentzh/&lt;span class="il"&gt;headers&lt;/span&gt;-&lt;span class="il"&gt;more&lt;/span&gt;-nginx-module/tags&lt;/a&gt;&lt;br&gt; &lt;br&gt; Here&amp;#39;s the complete change log for this version (as compared to the last formal release, v0.15):&lt;br&gt;&lt;ul&gt;&lt;li&gt; bugfix: the on-demand handler/filter registration mechanism did not work fully for config reload via the &lt;code&gt;HUP&lt;/code&gt; signal. &lt;/li&gt;&lt;li&gt; bugfix: when setting a multi-value response header to a single value, the single value might be repeated on each old value. &lt;/li&gt;&lt;li&gt; feature: added some debugging outputs that can be enabled by the &lt;code&gt;--with-debug&lt;/code&gt; option when building nginx or &lt;a rel="nofollow" class="external text" href="http://openresty.org/"&gt;ngx_openresty&lt;/a&gt;. &lt;/li&gt;&lt;li&gt; bugfix: we should set header hash using &lt;code&gt;ngx_hash_key_lc&lt;/code&gt;, not simply to &lt;code&gt;1&lt;/code&gt;. &lt;/li&gt;&lt;li&gt; bugfix: Setting &lt;code&gt;Cache-Control&lt;/code&gt; response headers might not work with other nginx output filter modules because we did not properly prepare the &lt;code&gt;r-&amp;gt;cache_control&lt;/code&gt; array at the same time. &lt;/li&gt;&lt;li&gt; bugfix: &lt;a href="http://wiki.nginx.org/HttpHeadersMoreModule#more_set_input_headers"&gt;more_set_input_headers&lt;/a&gt; and &lt;a href="http://wiki.nginx.org/HttpHeadersMoreModule#more_clear_input_headers"&gt;more_clear_input_headers&lt;/a&gt; did not handle the &lt;code&gt;Accept-Encoding&lt;/code&gt; request headers properly. thanks 天街夜色. &lt;/li&gt;&lt;li&gt; bugfix: the &lt;a href="http://wiki.nginx.org/HttpHeadersMoreModule#more_set_input_headers"&gt;more_set_input_headers&lt;/a&gt; directive might cause invalid memory reads because Nginx request header values must be null terminated. thanks Maxim Dounin. &lt;/li&gt;&lt;li&gt; bugfix: removing builtin headers in huge request headers with  20+ entries could result in data loss. thanks Chris Dumoulin for the  patch in &lt;a rel="nofollow" class="external text" href="https://github.com/agentzh/headers-more-nginx-module/issues/6"&gt;github issue #6&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Special thanks go to all of our contributors and users!&lt;br&gt;&lt;/p&gt;&lt;p&gt;The &lt;span&gt;&lt;span class="il"&gt;ngx_headers_more&lt;/span&gt;&lt;/span&gt; module allows you to add,  set, or clear any output or input header that you specify. This is an enhanced version of the standard &lt;span class="il"&gt;headers&lt;/span&gt; module because it provides &lt;span class="il"&gt;more&lt;/span&gt; utilities like resetting or clearing &amp;quot;builtin &lt;span class="il"&gt;headers&lt;/span&gt;&amp;quot; like &lt;span style="font-family:courier new,monospace"&gt;Content-Type&lt;/span&gt;, &lt;span style="font-family:courier new,monospace"&gt;Content-Length&lt;/span&gt;, and &lt;span style="font-family:courier new,monospace"&gt;Server&lt;/span&gt;.&lt;br&gt;   &lt;br&gt; You can always get the latest source code from its project page on  GitHub&lt;br&gt; &lt;br&gt; &amp;nbsp; &amp;nbsp;&lt;a href="http://github.com/agentzh/headers-more-nginx-module" target="_blank"&gt;http://github.com/agentzh/&lt;span class="il"&gt;headers&lt;/span&gt;-&lt;span class="il"&gt;more&lt;/span&gt;-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt; and the full documentation from the nginx wiki&lt;br&gt; &lt;br&gt; &amp;nbsp; &amp;nbsp;&lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule" target="_blank"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module is included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org/" target="_blank"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Enjoy!&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5463427914842292661?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5463427914842292661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5463427914842292661' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5463427914842292661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5463427914842292661'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/01/ngxheadersmore-module-v016-released.html' title='ngx_headers_more module v0.16 released!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2475413646423287120</id><published>2012-01-13T17:05:00.001+08:00</published><updated>2012-01-13T17:05:23.313+08:00</updated><title type='text'>ngx_echo module v0.37 released!</title><content type='html'>I&amp;#39;m happy to announce the v0.37 release of the ngx_echo module, which includes lots of bugfixes in the last 6 months.&lt;br&gt;&lt;br&gt;You can get the release tarball from the download page below&lt;br&gt;&lt;br&gt;   &lt;a href="https://github.com/agentzh/echo-nginx-module/tags"&gt;https://github.com/agentzh/echo-nginx-module/tags&lt;/a&gt;&lt;br&gt; &lt;br&gt;Here&amp;#39;s the complete change log for this release (compared to the last release, v0.36):&lt;br&gt; &lt;ul&gt;&lt;li&gt; bugfix: data truncation might occur with &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_after_body"&gt;echo_after_body&lt;/a&gt; in not-so-good networks (we should be prepared for &lt;code&gt;NGX_AGAIN&lt;/code&gt; returned by downstream output filters). thanks 林青  (Kindy Lin) for reporting it. &lt;/li&gt;&lt;li&gt; bugfix: we no longer check &lt;code&gt;sync&lt;/code&gt; buffers for subrequests because it is incorrect. &lt;/li&gt;&lt;li&gt; bugfix: fixed a bug when sending out response headers: we did not take into account the &lt;code&gt;NGX_ERROR&lt;/code&gt; error code returned by &lt;code&gt;ngx_http_send_header&lt;/code&gt;. &lt;/li&gt;&lt;li&gt; bugfix: we did not work with HEAD http requests before. &lt;/li&gt;&lt;li&gt; bugfix: now we carefully eliminate empty flush buffers in &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_after_body"&gt;echo_after_body&lt;/a&gt; to work around a long-standing bug in the standard &lt;a href="http://wiki.nginx.org/HttpGzipModule" title="HttpGzipModule"&gt;HttpGzipModule&lt;/a&gt;. &lt;/li&gt;&lt;li&gt; bugfix: we might send empty chain link in &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_after_body"&gt;echo_after_body&lt;/a&gt; because it may trigger the infamous &lt;code&gt;&amp;quot;the http output chain is empty&amp;quot;&lt;/code&gt; alert in &lt;code&gt;error.log&lt;/code&gt; when the standard &lt;a href="http://wiki.nginx.org/HttpSsiModule" title="HttpSsiModule"&gt;HttpSsiModule&lt;/a&gt; is disabled. thanks Sparsh Gupta. &lt;/li&gt;&lt;li&gt; bugfix: we did not set subrequest&amp;#39;s &lt;code&gt;Content-Length&lt;/code&gt; request headers which could cause problems in the backends. &lt;/li&gt;&lt;li&gt; bugfix: &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_exec"&gt;echo_exec&lt;/a&gt; + named locations might cause weird issues and now we explicitly clear all the modules&amp;#39; contexts before calling &lt;code&gt;ngx_http_named_location&lt;/code&gt;. &lt;/li&gt;&lt;li&gt; bugfix: &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_exec"&gt;echo_exec&lt;/a&gt; might hang when running after &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_sleep"&gt;echo_sleep&lt;/a&gt; (or other I/O interruption calls): we should have called &lt;code&gt;ngx_http_finalize_request&lt;/code&gt; on &lt;code&gt;NGX_DONE&lt;/code&gt; to decrement &lt;code&gt;r-&amp;gt;main-&amp;gt;count&lt;/code&gt; anyway. &lt;/li&gt;&lt;li&gt; bugfix: there was a memory issue in both &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_sleep"&gt;echo_sleep&lt;/a&gt; and &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_blocking_sleep"&gt;echo_blocking_sleep&lt;/a&gt;: we should not pass &lt;code&gt;ngx_str_t&lt;/code&gt; strings to &lt;code&gt;atof()&lt;/code&gt; which expects C strings. &lt;/li&gt;&lt;li&gt; bugfix: some users report that this module cannot be compiled with Nginx 1.0.x on their systems due to &lt;code&gt;ngx_time_update&lt;/code&gt; (as in &lt;a rel="nofollow" class="external text" href="https://github.com/agentzh/echo-nginx-module/issues/7"&gt;github issue #7&lt;/a&gt;). this is a blind attemp to fix it because we could not reproduce it on our side. &lt;/li&gt;&lt;li&gt; bugfix: fixed places in the source code that we did not check null pointers returned by the memory allocator. &lt;/li&gt;&lt;/ul&gt; You can also view the HTML-version of the change log here (which may look better):&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpEchoModule#v0.37"&gt;http://wiki.nginx.org/HttpEchoModule#v0.37&lt;/a&gt;&lt;br&gt;&lt;br&gt;The ngx_echo module wraps lots of Nginx internal APIs for streaming input and output, parallel/sequential subrequests, timers and sleeping, as well as various meta data accessing. You can read the full documentation on the following wiki page:&lt;br&gt; &lt;br&gt;   &lt;a href="http://wiki.nginx.org/HttpEchoModule"&gt;http://wiki.nginx.org/HttpEchoModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;and you can always get the latest source code from GitHub:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/echo-nginx-module"&gt;http://github.com/agentzh/echo-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;The ngx_echo module is included and enabled by default in our ngx_openresty bundle:&lt;br&gt;&lt;br&gt;  &lt;a href="http://openresty.org"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Happy echoing!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2475413646423287120?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2475413646423287120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2475413646423287120' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2475413646423287120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2475413646423287120'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/01/ngxecho-module-v037-released.html' title='ngx_echo module v0.37 released!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1920278710761493505</id><published>2012-01-11T23:07:00.001+08:00</published><updated>2012-01-11T23:07:35.015+08:00</updated><title type='text'>ngx_lua module v0.4.0 released!</title><content type='html'>After four months&amp;#39; active development of our contributors, I&amp;#39;m happy to announce the v0.4.0 release of our ngx_lua module. You can get the release tarball from the download page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/tags"&gt;https://github.com/chaoslawful/lua-nginx-module/tags&lt;/a&gt;&lt;br&gt; &lt;br&gt;There&amp;#39;s many many new features and bug fixes that you can find out in the following complete change log for this release (it is just too long to put here :P):&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpLuaModule#v0.4.0"&gt;http://wiki.nginx.org/HttpLuaModule#v0.4.0&lt;/a&gt;&lt;br&gt; &lt;br&gt;Special thanks go to all of our contributors and users!&lt;br&gt;&lt;br&gt;This module embeds the Lua 5.1 interpreter or LuaJIT 2.0 into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model by means of nginx subrequests.&lt;br&gt; &lt;br&gt;Unlike Apache&amp;#39;s mod_lua and Lighttpd&amp;#39;s mod_magnet, Lua code written atop this module can be 100% non-blocking on network traffic as long as you use the ngx.location.capture or ngx.location.capture_multi interfaces to let the Nginx core do all your requests to mysql, postgresql, memcached, redis, upstream http web services, and etc etc etc.&lt;br&gt; &lt;br&gt;This module is also included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org/"&gt;http://openresty.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;You can find the complete documentation for this module on the following wiki page:&lt;br&gt; &lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpLuaModule"&gt;http://wiki.nginx.org/HttpLuaModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;And you always get the latest source code from the git repository here:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module"&gt;https://github.com/chaoslawful/lua-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;Have fun!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1920278710761493505?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1920278710761493505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1920278710761493505' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1920278710761493505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1920278710761493505'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2012/01/ngxlua-module-v040-released.html' title='ngx_lua module v0.4.0 released!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8599429593608538169</id><published>2011-12-11T23:19:00.001+08:00</published><updated>2011-12-11T23:19:28.469+08:00</updated><title type='text'>ngx_openresty stable version 1.0.10.24 released</title><content type='html'>I&amp;#39;m happy to announce that the new stable release of ngx_openresty, 1.0.10.24, has just been kicked out of door:&lt;br&gt;&lt;br&gt;&amp;nbsp; &lt;a href="http://openresty.org/#Download" target="_blank"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt;&lt;br&gt; This is the first stable release of ngx_openresty that is based on the Nginx core 1.0.10.&lt;br&gt; &lt;br&gt;Special thanks go to all our contributors and users to help make this release happen :)&lt;br&gt;&lt;br&gt;Here goes the complete change log for this release, as compared to the last stable release, 1.0.9.10, released nearly one month ago:&lt;br&gt;  &lt;div class="viewer"&gt;&lt;ul&gt;&lt;li&gt; upgraded the Nginx core to 1.0.10.&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.3.1rc38.&lt;ul&gt; &lt;li&gt; feature: added opions &lt;code&gt;copy_all_vars&lt;/code&gt; and &lt;code&gt;vars&lt;/code&gt; to &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" class="externalLink"&gt;ngx.location.capture&lt;/a&gt; and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi" href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi" class="externalLink"&gt;ngx.location.capture_multi&lt;/a&gt;. thanks Marcus Clyne for the patch.&lt;/li&gt; &lt;li&gt; feature: added new Lua API &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.now" href="http://wiki.nginx.org/HttpLuaModule#ngx.now" class="externalLink"&gt;ngx.now&lt;/a&gt; to return the current time (including the ms part as the decimal part). thanks 林青.&lt;/li&gt; &lt;li&gt; feature: added new Lua API &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.update_time" href="http://wiki.nginx.org/HttpLuaModule#ngx.update_time" class="externalLink"&gt;ngx.update_time&lt;/a&gt; to forcibly updating nginx&amp;#39;s time cache.&lt;/li&gt; &lt;li&gt; feature: added &lt;code&gt;wait&lt;/code&gt; boolean argument to &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.flush" href="http://wiki.nginx.org/HttpLuaModule#ngx.flush" class="externalLink"&gt;ngx.flush()&lt;/a&gt; to support synchronous flushing; &lt;code&gt;ngx.flush(true)&lt;/code&gt; will not return until all the data has been flushed into the system send buffer or the send timeout has expired.&lt;/li&gt; &lt;li&gt; feature: added constant &lt;code&gt;ngx.HTTP_GATEWAY_TIMEOUT&lt;/code&gt; (504) per Fry-kun in &lt;a target="_blank" title="External link to https://github.com/chaoslawful/lua-nginx-module/issues/73" href="https://github.com/chaoslawful/lua-nginx-module/issues/73" class="externalLink"&gt;github issue #73&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; feature: added new regex options &lt;code&gt;&amp;quot;j&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;d&amp;quot;&lt;/code&gt; to &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.re.match" href="http://wiki.nginx.org/HttpLuaModule#ngx.re.match" class="externalLink"&gt;ngx.re.match&lt;/a&gt;, &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.re.gmatch" href="http://wiki.nginx.org/HttpLuaModule#ngx.re.gmatch" class="externalLink"&gt;ngx.re.gmatch&lt;/a&gt;, &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.re.sub" href="http://wiki.nginx.org/HttpLuaModule#ngx.re.sub" class="externalLink"&gt;ngx.re.sub&lt;/a&gt;, and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.re.gsub" href="http://wiki.nginx.org/HttpLuaModule#ngx.re.gsub" class="externalLink"&gt;ngx.re.gsub&lt;/a&gt;  so as to enable the PCRE &lt;a target="_blank" title="External link to http://www.manpagez.com/man/3/pcrejit/" href="http://www.manpagez.com/man/3/pcrejit/" class="externalLink"&gt;JIT mode&lt;/a&gt; and DFA mode, respectively. thanks &lt;a target="_blank" title="External link to http://weibo.com/egis" href="http://weibo.com/egis" class="externalLink"&gt;@姜大炮&lt;/a&gt; for providing the patch.&lt;/li&gt; &lt;li&gt; feature: added &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.hmac_sha1" href="http://wiki.nginx.org/HttpLuaModule#ngx.hmac_sha1" class="externalLink"&gt;ngx.hmac_sha1&lt;/a&gt;. thanks &lt;a target="_blank" title="External link to http://weibo.com/drdrxp" href="http://weibo.com/drdrxp" class="externalLink"&gt;drdrxp&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; bugfix: fixed a bad regression in &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi" href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi" class="externalLink"&gt;ngx.location.capture_multi&lt;/a&gt; when the request option table is specified. this bug had appeared in ngx_lua 0.3.1rc26 and ngx_openresty 1.0.9.1.&lt;/li&gt; &lt;li&gt; bugfix: now we check timed out downstream connections in our write event handler.&lt;/li&gt;&lt;li&gt; bugfix: use of the &lt;a href="http://ngx.re"&gt;ngx.re&lt;/a&gt; API might lead to errors like &lt;code&gt;pcre_compile() failed: failed to get memory in ...&lt;/code&gt; due to incorrect &lt;code&gt;pcre_malloc&lt;/code&gt; and &lt;code&gt;pcre_free&lt;/code&gt; handling. thanks Vittly for reporting this as &lt;a target="_blank" title="External link to https://github.com/chaoslawful/lua-nginx-module/issues/72" href="https://github.com/chaoslawful/lua-nginx-module/issues/72" class="externalLink"&gt;github issue #72&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; docs: documented the long-existent &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.md5" href="http://wiki.nginx.org/HttpLuaModule#ngx.md5" class="externalLink"&gt;ngx.md5&lt;/a&gt; and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.md5_bin" href="http://wiki.nginx.org/HttpLuaModule#ngx.md5_bin" class="externalLink"&gt;ngx.md5_bin&lt;/a&gt; APIs.&lt;/li&gt; &lt;li&gt; docs: massive documentation improvements. thanks Nginx User.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="MemcNginxModule - ZhangYichun, Fri 26 Aug 2011 09:11:00 AM CST"&gt;MemcNginxModule&lt;/a&gt; to 0.13rc2.&lt;ul&gt; &lt;li&gt; bugfix: now we use &lt;code&gt;signed char&lt;/code&gt; explicitly instead of the vague &lt;code&gt;char&lt;/code&gt; type which could be unsigned by default in certain systems like PowerPC. thanks Dmitry E. Oboukhov.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="Redis2NginxModule - ZhangYichun, Tue 06 Sep 2011 04:34:00 PM CST"&gt;Redis2NginxModule&lt;/a&gt; to 0.08rc2.&lt;ul&gt; &lt;li&gt; bugfix: when &lt;code&gt;char&lt;/code&gt; defaults to &lt;code&gt;unsigned char&lt;/code&gt;, the Ragel-based Redis response parser could not accept non-ascci bytes. thanks Dmitry E. Oboukhov.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="RdsJsonNginxModule - ZhangYichun, Tue 21 Jun 2011 04:40:00 PM CST"&gt;RdsJsonNginxModule&lt;/a&gt; to v0.12rc7.&lt;ul&gt; &lt;li&gt; added more debug level error log outputs to ease debugging (as discussed in &lt;a target="_blank" title="External link to https://github.com/agentzh/rds-json-nginx-module/issues/2" href="https://github.com/agentzh/rds-json-nginx-module/issues/2" class="externalLink"&gt;github issue #2&lt;/a&gt;).&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="XssNginxModule - ZhangYichun, Tue 21 Jun 2011 05:07:00 PM CST"&gt;XssNginxModule&lt;/a&gt; to v0.03rc7.&lt;ul&gt;&lt;li&gt; now we use the &lt;code&gt;ngx_log_debugN&lt;/code&gt; macros to emit debugging outputs instead of &lt;code&gt;info&lt;/code&gt; level error logging because the latter is costly in production.&lt;/li&gt; &lt;li&gt; bugfix: now we use &lt;code&gt;signed char&lt;/code&gt; explicitly instead of the vague &lt;code&gt;char&lt;/code&gt; type which could be unsigned by default in certain systems like PowerPC. thanks Dmitry E. Oboukhov.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; bugfix: fixed a serious regression for Linux AIO in &lt;a target="_blank" title="External link to https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.10-epoll_check_stale_wev.patch" href="https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.10-epoll_check_stale_wev.patch" class="externalLink"&gt;nginx-1.0.10-epoll_check_stale_wev.patch&lt;/a&gt;, thanks Maxim Dounin.&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;   As always, you&amp;#39;re welcome to report bugs and feature requests either here or directly to me :)&lt;br&gt;&lt;br&gt;OpenResty (aka. ngx_openresty) is a full-fledged web application server by bundling the standard Nginx core, lots of 3rd-party Nginx modules, as well as most of their external dependencies.&lt;br&gt;  &lt;br&gt;By taking adantage of various well-designed Nginx modules, OpenResty effectively turns the nginx server into a powerful web app server, in which the web developers can use the Lua programming language to script various existing nginx C modules and Lua modules and construct extremely high-performance web applications that is capable to handle 10K+ connections.&lt;br&gt;  &lt;br&gt;OpenResty aims to run your server-side web app completely in the Nginx server, leveraging Nginx&amp;#39;s event model to do non-blocking I/O not only with the HTTP clients, but also with remote backends like MySQL, PostgreSQL, Memcached, and Redis.&lt;br&gt;  &lt;br&gt;You can find more details on the homepage of ngx_openresty here:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://openresty.org" target="_blank"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8599429593608538169?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8599429593608538169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8599429593608538169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8599429593608538169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8599429593608538169'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/12/ngxopenresty-stable-version-101024.html' title='ngx_openresty stable version 1.0.10.24 released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1824648090718057634</id><published>2011-12-06T15:54:00.001+08:00</published><updated>2011-12-06T15:54:59.964+08:00</updated><title type='text'>Working on Nginx Tutorials in Chinese</title><content type='html'>I&amp;#39;ve been posting Nginx tutorials in Chinese to my yet another blog site hosted by Sina Blog here:&lt;br&gt;&lt;br&gt;   &lt;a href="http://blog.sina.com.cn/openresty"&gt;http://blog.sina.com.cn/openresty&lt;/a&gt;&lt;br&gt;&lt;br&gt;I&amp;#39;m currently posting tutorials for the &amp;quot;Nginx Variables&amp;quot; series in great details. And I&amp;#39;m trying to post an article every work day.&lt;br&gt; &lt;br&gt;I&amp;#39;m hoping that I can eventually work out an Nginx book in Chinese based on these materials soon so I&amp;#39;m working hard and seriously.&lt;br&gt;&lt;br&gt;If you cannot read Chinese, please try out translating tools like Google Translator ;) I&amp;#39;m very willing to find someone to translate these to English or any other languages though :)&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1824648090718057634?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1824648090718057634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1824648090718057634' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1824648090718057634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1824648090718057634'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/12/working-on-nginx-tutorials-in-chinese_06.html' title='Working on Nginx Tutorials in Chinese'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2064254531573403124</id><published>2011-11-16T11:28:00.001+08:00</published><updated>2011-11-16T11:28:32.203+08:00</updated><title type='text'>ngx_openresty 1.0.9.10 (stable) released</title><content type='html'>I&amp;#39;m happy to announce that the new stable release of &lt;span class="il"&gt;ngx_openresty&lt;/span&gt;, &lt;span class="il"&gt;1.0&lt;/span&gt;.9&lt;span class="il"&gt;.10&lt;/span&gt;, has just been kicked out of door:&lt;br&gt;&lt;br&gt;&amp;nbsp; &lt;a href="http://openresty.org/#Download" target="_blank"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt; &lt;br&gt; This is the first stable release of &lt;span class="il"&gt;ngx_openresty&lt;/span&gt; that is based on the Nginx core &lt;span class="il"&gt;1.0&lt;/span&gt;.9.&lt;br&gt;&lt;br&gt;Special thanks go to all our contributors and users to help make this release happen :)&lt;br&gt; &lt;br&gt;Here goes the complete change log for this release, as compared to the last stable release, &lt;span class="il"&gt;1.0&lt;/span&gt;.8.26, released two weeks ago:&lt;br&gt;&lt;div class="viewer"&gt;&lt;ul&gt;&lt;li&gt; upgraded the Nginx core to 1.0.9.&lt;/li&gt; &lt;li&gt; applied the &lt;a target="_blank" title="External link to http://mailman.nginx.org/pipermail/nginx-devel/2011-November/001408.html" href="http://mailman.nginx.org/pipermail/nginx-devel/2011-November/001408.html" class="externalLink"&gt;epoll_check_stale_wev patch&lt;/a&gt; to the Nginx 1.0.9 core. this issue affected &lt;a class="tiddlyLink tiddlyLinkExisting" title="PostgresNginxModule - ZhangYichun, Wed 22 Jun 2011 03:36:00 PM CST"&gt;PostgresNginxModule&lt;/a&gt; when connecting to a remote PostgreSQL server over a slow network. thanks &lt;a target="_blank" title="External link to http://weibo.com/u/1878897190" href="http://weibo.com/u/1878897190" class="externalLink"&gt;@晓旭XX&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; bugfix: &lt;a target="_blank" title="External link to https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.9-variable_header_ignore_no_hash.patch" href="https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.9-variable_header_ignore_no_hash.patch" class="externalLink"&gt;nginx-1.0.9-variable_header_ignore_no_hash.patch&lt;/a&gt; might introduce a memory overflow issue in multi-header variables. thanks Markus Linnala.&lt;/li&gt; &lt;li&gt; bugfix: fixed the error message length while the &lt;code&gt;./configure&lt;/code&gt; script fails.&lt;/li&gt;&lt;li&gt; feature: applied &lt;a target="_blank" title="External link to https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.9-log_escape_non_ascii.patch" href="https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.9-log_escape_non_ascii.patch" class="externalLink"&gt;a patch&lt;/a&gt; to add new directives &lt;code&gt;log_escape_non_ascii&lt;/code&gt; to prevent escaping non-ascii bytes in access log variable values. requested by &lt;a target="_blank" title="External link to http://weibo.com/egis" href="http://weibo.com/egis" class="externalLink"&gt;@姜大炮&lt;/a&gt;. It can be turned &lt;code&gt;on&lt;/code&gt; and &lt;code&gt;off&lt;/code&gt;, and default to &lt;code&gt;on&lt;/code&gt; just as the standard Nginx version.&lt;/li&gt; &lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="DrizzleNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;DrizzleNginxModule&lt;/a&gt; to 0.1.2rc4.&lt;ul&gt;&lt;li&gt; bugfix: fixed issues with &lt;code&gt;poll&lt;/code&gt;, &lt;code&gt;rtsig&lt;/code&gt;, and &lt;code&gt;select&lt;/code&gt; used by the Nginx event model by eliminating the &lt;code&gt;poll&lt;/code&gt; syscall performed by &lt;code&gt;libdrizzle&lt;/code&gt;. This also gives rise to a nice speedup (about 10% in simple cases).&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.3.1rc28.&lt;ul&gt;&lt;li&gt; feature: added the &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.encode_args" href="http://wiki.nginx.org/HttpLuaModule#ngx.encode_args" class="externalLink"&gt;ngx.encode_args&lt;/a&gt; method to encode a Lua code to a URI query string. thanks 郭颖 (&lt;a target="_blank" title="External link to http://weibo.com/shrimp0597" href="http://weibo.com/shrimp0597" class="externalLink"&gt;0597虾&lt;/a&gt;).&lt;/li&gt; &lt;li&gt; feature: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" class="externalLink"&gt;ngx.location.capture&lt;/a&gt; and &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.exec" href="http://wiki.nginx.org/HttpLuaModule#ngx.exec" class="externalLink"&gt;ngx.exec&lt;/a&gt; now supports the same Lua args table format as in &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.encode_args" href="http://wiki.nginx.org/HttpLuaModule#ngx.encode_args" class="externalLink"&gt;ngx.encode_args&lt;/a&gt;. thanks 郭颖 (&lt;a target="_blank" title="External link to http://weibo.com/shrimp0597" href="http://weibo.com/shrimp0597" class="externalLink"&gt;0597虾&lt;/a&gt;).&lt;/li&gt; &lt;li&gt; bugfix: &lt;code&gt;Cache-Control&lt;/code&gt; header modification might introduce empty value headers when using with the standard &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpHeadersModule" href="http://wiki.nginx.org/HttpHeadersModule" class="externalLink"&gt;ngx_headers&lt;/a&gt; module.&lt;/li&gt; &lt;li&gt; feature: added the &lt;code&gt;ctx&lt;/code&gt; option to &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture" class="externalLink"&gt;ngx.location.capture&lt;/a&gt;: you can now specify a custom Lua table to pass to the subrequest as its &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.ctx" href="http://wiki.nginx.org/HttpLuaModule#ngx.ctx" class="externalLink"&gt;ngx.ctx&lt;/a&gt;. thanks &lt;a target="_blank" title="External link to http://weibo.com/hugozhu" href="http://weibo.com/hugozhu" class="externalLink"&gt;@hugozhu&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; bugfix: fixed compatibility with nginx 0.8.54. thanks &lt;a target="_blank" title="External link to http://weibo.com/shrimp0597" href="http://weibo.com/shrimp0597" class="externalLink"&gt;@0579虾&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="HeadersMoreNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;HeadersMoreNginxModule&lt;/a&gt; to 0.16rc4.&lt;ul&gt; &lt;li&gt; bugfix: &lt;code&gt;Cache-Control&lt;/code&gt; header modification might introduce empty value headers when using with the standard &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpHeadersModule" href="http://wiki.nginx.org/HttpHeadersModule" class="externalLink"&gt;ngx_headers&lt;/a&gt; module.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="PostgresNginxModule - ZhangYichun, Wed 22 Jun 2011 03:36:00 PM CST"&gt;PostgresNginxModule&lt;/a&gt; to 0.9rc2&lt;ul&gt;&lt;li&gt; bugfix: now we log an error message when the &lt;code&gt;postgres_pass&lt;/code&gt; target is not found at all and returns 500 in this case instead of returning empty response.&lt;/li&gt; &lt;li&gt;  bugfix: we should no longer return &lt;code&gt;NGX_AGAIN&lt;/code&gt; when the re-polling returns IO WAIT in case of the &amp;quot;connection made&amp;quot; state.&lt;/li&gt;&lt;li&gt; feature: added some debugging outputs which be enabled by passing the &lt;code&gt;--with-debug&lt;/code&gt; option while building Nginx or &lt;a class="tiddlyLink tiddlyLinkExisting" title="OpenResty - ZhangYichun, Tue 21 Jun 2011 01:09:00 PM CST"&gt;OpenResty&lt;/a&gt;.&lt;/li&gt; &lt;li&gt; bugfix: fixed compatibility issues with Nginx 1.1.4+: &lt;code&gt;ngx_chain_update_chains&lt;/code&gt; now requires a pool argument.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaRdsParserLibrary - ZhangYichun, Wed 31 Aug 2011 03:40:00 PM CST"&gt;LuaRdsParserLibrary&lt;/a&gt; to 0.04.&lt;ul&gt; &lt;li&gt; bugfix: fixed a serious memory leak reported by bearnard.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="XssNginxModule - ZhangYichun, Tue 21 Jun 2011 05:07:00 PM CST"&gt;XssNginxModule&lt;/a&gt; to 0.03rc5.&lt;ul&gt; &lt;li&gt; bugfix: the callback argument value parser did not accept JavaScript identifier names started with underscores. thanks Sam Mulube.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;As always, you&amp;#39;re welcome to report bugs and feature requests either here or directly to me :)&lt;br&gt; &lt;br&gt;It&amp;#39;ll also be highly appreciated to try out the devel releases (based on the Nginx core &lt;span class="il"&gt;1.0&lt;/span&gt;.10+) that are coming out later ;)&lt;br&gt; &lt;br&gt;OpenResty (aka. &lt;span&gt;&lt;span class="il"&gt;ngx_openresty&lt;/span&gt;&lt;/span&gt;) is a full-fledged web application server by bundling the standard &lt;a title="Nginx - ZhangYichun, Tue 21 Jun 2011 04:24:00 PM CST"&gt;Nginx&lt;/a&gt; core, lots of &lt;a title="External link to http://wiki.nginx.org/3rdPartyModules" href="http://wiki.nginx.org/3rdPartyModules" target="_blank"&gt;3rd-party Nginx modules&lt;/a&gt;, as well as most of their external dependencies.&lt;br&gt;   &lt;br&gt;By taking adantage of various well-designed Nginx modules, OpenResty  effectively turns the nginx server into a powerful web app server, in  which the web developers can use the Lua programming language to script  various existing nginx C modules and Lua modules and construct extremely  high-performance web applications that is capable to handle 10K+  connections.&lt;br&gt;&lt;br&gt;OpenResty aims to run your server-side web app  completely in the Nginx server, leveraging Nginx&amp;#39;s event model to do  non-blocking I/O not only with the HTTP clients, but also with remote  backends like MySQL, PostgreSQL, Memcached, and Redis.&lt;br&gt;&lt;br&gt;You can find more details on the homepage of &lt;span&gt;&lt;span class="il"&gt;ngx_openresty&lt;/span&gt;&lt;/span&gt; here:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://openresty.org/" target="_blank"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2064254531573403124?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2064254531573403124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2064254531573403124' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2064254531573403124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2064254531573403124'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/11/ngxopenresty-10910-stable-released.html' title='ngx_openresty 1.0.9.10 (stable) released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8029685173736605280</id><published>2011-11-03T17:24:00.001+08:00</published><updated>2011-11-03T17:24:09.323+08:00</updated><title type='text'>ngx_openresty 1.0.8.26 (stable) released</title><content type='html'>I&amp;#39;m happy to announce that the new stable release of ngx_openresty, 1.0.8.26, has just been kicked out of door:&lt;br&gt;&lt;br&gt;  &lt;a href="http://openresty.org/#Download" target="_blank"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt;&lt;br&gt; This is the first stable release of ngx_openresty that is based on the Nginx core 1.0.8.&lt;br&gt;&lt;br&gt;Here goes the complete change log for this release, as compared to the last stable release, 1.0.6.22, released nearly a month ago:&lt;br&gt; &lt;div class="viewer"&gt;&lt;ul&gt;&lt;li&gt; upgraded the Nginx core to 1.0.8.&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.3.1rc23.&lt;ul&gt; &lt;li&gt; feature: added new directive &lt;code&gt;lua_shared_dict&lt;/code&gt;: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#lua_shared_dict" href="http://wiki.nginx.org/HttpLuaModule#lua_shared_dict" class="externalLink"&gt;http://wiki.nginx.org/HttpLuaModule#lua_shared_dict&lt;/a&gt;&lt;/li&gt; &lt;li&gt; feature: added Lua API for the shm-based dictionary: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT" href="http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT" class="externalLink"&gt;http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT&lt;/a&gt;&lt;/li&gt; &lt;li&gt; feature: now we apply the patch to the nginx core so as to allow main request body modifications.&lt;/li&gt;&lt;li&gt; feature: added new Lua API &lt;code&gt;ngx.req.set_body_file()&lt;/code&gt;: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_file" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_file" class="externalLink"&gt;http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_file&lt;/a&gt;&lt;/li&gt; &lt;li&gt; feature: added new Lua API &lt;code&gt;ngx.req.set_body_data()&lt;/code&gt;: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_data" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_data" class="externalLink"&gt;http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_data&lt;/a&gt;&lt;/li&gt; &lt;li&gt; feature: added new Lua functions &lt;code&gt;ngx.req.read_body()&lt;/code&gt;, &lt;code&gt;ngx.req.discard_body()&lt;/code&gt;, &lt;code&gt;ngx.req.get_body_data()&lt;/code&gt;, and &lt;code&gt;ngx.req.get_body_file()&lt;/code&gt;. see the docs here: &lt;a target="_blank" title="External link to http://wiki.nginx.org/HttpLuaModule#ngx.req.read_body" href="http://wiki.nginx.org/HttpLuaModule#ngx.req.read_body" class="externalLink"&gt;http://wiki.nginx.org/HttpLuaModule#ngx.req.read_body&lt;/a&gt;&lt;/li&gt; &lt;li&gt; feature: now we implemented &lt;code&gt;ngx.req.set_uri()&lt;/code&gt; and &lt;code&gt;ngx.req.set_uri_args()&lt;/code&gt; to emulate &lt;code&gt;ngx_rewrite&lt;/code&gt;&amp;#39;s &lt;code&gt;rewrite&lt;/code&gt; directive (without &lt;code&gt;redirect&lt;/code&gt; or &lt;code&gt;permanent&lt;/code&gt; modifiers). thanks Vladimir Protasov (utros) and Nginx User.&lt;/li&gt; &lt;li&gt; feature: added constant &lt;code&gt;ngx.HTTP_METHOD_NOT_IMPLEMENTED&lt;/code&gt; (501). thanks Nginx User.&lt;/li&gt;&lt;li&gt; feature: now for HTTP 1.0 requests, we disable the automatic full buffering mode if the user sets the &lt;code&gt;Content-Length&lt;/code&gt;  response header before sending out the headers. this allows streaming  output for HTTP 1.0 requests if the content length can be calculated  beforehand. thanks Li Ziyi.&lt;/li&gt;&lt;li&gt; bugfix: now we properly support setting the &lt;code&gt;Cache-Control&lt;/code&gt; response header via the &lt;code&gt;ngx.header.HEADER&lt;/code&gt; interface.&lt;/li&gt;&lt;li&gt; bugfix: no longer set header hash to 1. use the &lt;code&gt;ngx_hash_key_lc&lt;/code&gt; instead.&lt;/li&gt; &lt;li&gt; bugfix: now we skip rewrite phase Lua handlers altogether if &lt;code&gt;ngx_rewrite&lt;/code&gt;&amp;#39;s &lt;code&gt;rewrite&lt;/code&gt; directive issue a location re-lookup by changing URIs (but not including rewrite ... break). thanks Nginx User.&lt;/li&gt; &lt;li&gt; bugfix: fixed hanging issues when using &lt;code&gt;ngx.exec()&lt;/code&gt; within &lt;code&gt;rewrite_by_lua&lt;/code&gt; and &lt;code&gt;access_by_lua&lt;/code&gt;. thanks Nginx User for reporting it.&lt;/li&gt;&lt;li&gt; bugfix: &lt;code&gt;lua_need_request_body&lt;/code&gt; should not skip requests with methods other than &lt;code&gt;POST&lt;/code&gt; and &lt;code&gt;PUT&lt;/code&gt;. thanks Nginx User.&lt;/li&gt; &lt;li&gt; bugfix: &lt;code&gt;ndk.set_var.DIRECTIVE&lt;/code&gt; had a memory issue and might pass empty argument values to the directive being called. thanks dannynoonan.&lt;/li&gt;&lt;li&gt; bugfix: no longer free request body buffers that are not allocated by ourselves.&lt;/li&gt; &lt;li&gt; bugfix: now we allow setting &lt;code&gt;ngx.var.VARIABLE&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; bugfix: now we explicitly clear all the modules&amp;#39; contexts before dump to named location with &lt;code&gt;ngx.exec&lt;/code&gt;. thanks Nginx User.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="EchoNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;EchoNginxModule&lt;/a&gt; to 0.37rc7.&lt;ul&gt;&lt;li&gt; bugfix: fixed a memory issue in both &lt;code&gt;echo_sleep&lt;/code&gt; and &lt;code&gt;echo_blocking_sleep&lt;/code&gt;: we should not pass &lt;code&gt;ngx_str_t&lt;/code&gt; strings to &lt;code&gt;atof()&lt;/code&gt; which expects C strings.&lt;/li&gt; &lt;li&gt; bugfix: now we explicitly clear all the modules&amp;#39; contexts before dump to named location with &lt;code&gt;echo_exec&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; bugfix: bugfix: &lt;code&gt;echo_exec&lt;/code&gt; may hang when running after &lt;code&gt;echo_sleep&lt;/code&gt; (or other I/O interruption calls): we should have called &lt;code&gt;ngx_http_finalize_request&lt;/code&gt; on &lt;code&gt;NGX_DONE&lt;/code&gt; to decrement &lt;code&gt;r-&amp;gt;main-&amp;gt;count&lt;/code&gt; anyway.&lt;/li&gt; &lt;li&gt; bugfix: now we properly set the &lt;code&gt;Content-Length&lt;/code&gt; request header for subrequests.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="SrcacheNginxModule - ZhangYichun, Fri 26 Aug 2011 09:11:00 AM CST"&gt;SrcacheNginxModule&lt;/a&gt; to 0.13rc2.&lt;ul&gt; &lt;li&gt; feature: implemented response status line and general response header cachin and added new directives &lt;code&gt;srcache_store_hide_header&lt;/code&gt; and &lt;code&gt;srcache_store_pass_header&lt;/code&gt; to control which headers to cache and which not.&lt;/li&gt; &lt;li&gt; feature: added new directive &lt;code&gt;srcache_response_cache_control&lt;/code&gt; to control whether honor response headers &lt;code&gt;Cache-Control&lt;/code&gt; and &lt;code&gt;Expires&lt;/code&gt;, default &lt;code&gt;on&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; feature: we disable &lt;code&gt;srcache_store&lt;/code&gt; automatically by default when &lt;code&gt;Cache-Control: max-age=0&lt;/code&gt; and &lt;code&gt;Expires: &amp;lt;date no more recently than now&amp;gt;&lt;/code&gt; are seen.&lt;/li&gt; &lt;li&gt; feature: implemented builtin nginx variable &lt;code&gt;$srcache_expire&lt;/code&gt; for automatic expiration time calculation based on response headers &lt;code&gt;Cache-Control&lt;/code&gt; (&lt;code&gt;max-age&lt;/code&gt;) and &lt;code&gt;Expires&lt;/code&gt;; also added new directives &lt;code&gt;srcache_max_expire&lt;/code&gt; and &lt;code&gt;srcache_default_expire&lt;/code&gt;.&lt;/li&gt; &lt;li&gt; feature: implemented the &lt;code&gt;srcache_store_no_cache&lt;/code&gt; directive; now by default, we do not store responses with the header &lt;code&gt;Cache-Control: no-cache&lt;/code&gt; into the cache.&lt;/li&gt;&lt;li&gt; feature: implemented &lt;code&gt;the srcache_store_no_store directive&lt;/code&gt; (default &lt;code&gt;off&lt;/code&gt;). Now by default, responses with the header &lt;code&gt;Cache-Control: no-store&lt;/code&gt; will not be stored into the cache.&lt;/li&gt; &lt;li&gt; feature: implemented the &lt;code&gt;srcache_store_private&lt;/code&gt; directive to control whether to store responses with the header &lt;code&gt;Cache-Control: private&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; feature: implemented the &lt;code&gt;srcache_request_cache_control&lt;/code&gt; directive to allow request headers &lt;code&gt;Cache-Control: no-cache&lt;/code&gt; or &lt;code&gt;Pragma: no-cache&lt;/code&gt; to force bypassing cache lookup. it also honors the request header &lt;code&gt;Cache-Control: no-store&lt;/code&gt;. this directive is turned off by default.&lt;/li&gt; &lt;li&gt; feature: now we check response header &lt;code&gt;Content-Encoding&lt;/code&gt; by default and a non-empty header value will &lt;code&gt;skip srcache_store&lt;/code&gt;; also introduced a new directive named &lt;code&gt;srcache_ignore_content_encoding&lt;/code&gt; to ignore this response header.&lt;/li&gt; &lt;li&gt; feature: implemented the &lt;code&gt;srcache_methods&lt;/code&gt; directive to specify request methods that are cacheable, by default, only &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;HEAD&lt;/code&gt; are cacheable.&lt;/li&gt;&lt;li&gt; bugfix: we no longer set header hash to 1; we use &lt;code&gt;ngx_hash_key_lc&lt;/code&gt; instead.&lt;/li&gt; &lt;li&gt; bugfix: when we skip &lt;code&gt;srcache_fetch&lt;/code&gt; by means of &lt;code&gt;srcache_fetch_skip&lt;/code&gt;, we should not automatically skip &lt;code&gt;srcache_store&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; bugfix: now we ignore the &lt;code&gt;Content-Length&lt;/code&gt; header (if any) of the main request for the subrequests.&lt;/li&gt; &lt;li&gt; bugfix: there might be a segfault when failing to allocate memory in &lt;code&gt;ngx_http_srcache_add_copy_chain&lt;/code&gt;. thanks Shaun savage.&lt;/li&gt;&lt;li&gt; feature: implemented new directive &lt;code&gt;srcache_store_statuses&lt;/code&gt; to allow the user to specify the response status code list that is to be stored into the cache.&lt;/li&gt; &lt;li&gt; bugfix: we now only cache 200, 301, and 302 responses by default.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="IconvNginxModule - ZhangYichun, Wed 22 Jun 2011 03:36:00 PM CST"&gt;IconvNginxModule&lt;/a&gt; to 0.10rc5.&lt;ul&gt; &lt;li&gt; bugfix: fixed &lt;code&gt;-Wset-but-not-used&lt;/code&gt; warnings issued by gcc 4.6.0. thanks Zhi Jiale (Calio).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="HeadersMoreNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;HeadersMoreNginxModule&lt;/a&gt; to 0.16rc3.&lt;ul&gt; &lt;li&gt; bugfix: we should set header hash using &lt;code&gt;ngx_hash_key_lc&lt;/code&gt;, not simply to 1.&lt;/li&gt;&lt;li&gt; bugfix: fixed setting &lt;code&gt;Cache-Control&lt;/code&gt; response headers. we should properly prepare the &lt;code&gt;r-&amp;gt;cache_control&lt;/code&gt; array as well.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="RdsJsonNginxModule - ZhangYichun, Tue 21 Jun 2011 04:40:00 PM CST"&gt;RdsJsonNginxModule&lt;/a&gt; to 0.12rc6.&lt;ul&gt;&lt;li&gt; bugfix: fixed compatibility with nginx 1.1.4+.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="RdsCsvNginxModule - ZhangYichun, Wed 31 Aug 2011 03:42:00 PM CST"&gt;RdsCsvNginxModule&lt;/a&gt; to 0.04.&lt;ul&gt;&lt;li&gt; bugfix: fixed compatibility issues with nginx 1.1.4+.&lt;/li&gt; &lt;li&gt; optimization: now we only register our filters when &lt;code&gt;rds_csv&lt;/code&gt; is actually used in &lt;code&gt;nginx.conf&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="Redis2NginxModule - ZhangYichun, Tue 06 Sep 2011 04:34:00 PM CST"&gt;Redis2NginxModule&lt;/a&gt; to 0.08rc1.&lt;ul&gt; &lt;li&gt; bugfix: fixed compatibility with nginx 1.1.4+.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="DrizzleNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;DrizzleNginxModule&lt;/a&gt; to 0.1.2rc2.&lt;ul&gt; &lt;li&gt; bugfix: fixed compatibility with nginx 1.1.4+&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="MemcNginxModule - ZhangYichun, Fri 26 Aug 2011 09:11:00 AM CST"&gt;MemcNginxModule&lt;/a&gt; to 0.13rc1.&lt;ul&gt; &lt;li&gt; bugfix: fixed compatibility with nginx 1.1.4+.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="SetMiscNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;SetMiscNginxModule&lt;/a&gt; to v0.22rc3.&lt;ul&gt; &lt;li&gt; minor code cleanup.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; applied the patch to the Nginx core that always clears all modules&amp;#39; contexts in &lt;code&gt;ngx_http_named_location&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; applied the patch for the variable-header-ignore-no-hash issue. see &lt;a target="_blank" title="External link to http://forum.nginx.org/read.php?29,216062" href="http://forum.nginx.org/read.php?29,216062" class="externalLink"&gt;http://forum.nginx.org/read.php?29,216062&lt;/a&gt; for details.&lt;/li&gt; &lt;/ul&gt;&lt;/div&gt;As always, you&amp;#39;re welcome to report bugs and feature requests either here or directly to me :)&lt;br&gt;&lt;br&gt;It&amp;#39;ll also be highly appreciated to try out the devel releases (based on the Nginx core 1.0.9+) that are coming out later ;)&lt;br&gt; &lt;br&gt;OpenResty (aka. &lt;span class="il"&gt;ngx_openresty&lt;/span&gt;) is a full-fledged web application server by bundling the standard &lt;a title="Nginx - ZhangYichun, Tue 21 Jun 2011 04:24:00 PM CST"&gt;Nginx&lt;/a&gt; core, lots of &lt;a title="External link to http://wiki.nginx.org/3rdPartyModules" href="http://wiki.nginx.org/3rdPartyModules" target="_blank"&gt;3rd-party Nginx modules&lt;/a&gt;, as well as most of their external dependencies.&lt;br&gt;  &lt;br&gt;By taking adantage of various well-designed Nginx modules, OpenResty  effectively turns the nginx server into a powerful web app server, in  which the web developers can use the Lua programming language to script  various existing nginx C modules and Lua modules and construct extremely  high-performance web applications that is capable to handle 10K+  connections.&lt;br&gt;&lt;br&gt;OpenResty aims to run your server-side web app  completely in the Nginx server, leveraging Nginx&amp;#39;s event model to do  non-blocking I/O not only with the HTTP clients, but also with remote  backends like MySQL, PostgreSQL, Memcached, and Redis.&lt;br&gt;&lt;br&gt;You can find more details on the homepage of &lt;span class="il"&gt;ngx_openresty&lt;/span&gt; here:&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org/" target="_blank"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt; &lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8029685173736605280?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8029685173736605280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8029685173736605280' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8029685173736605280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8029685173736605280'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/11/ngxopenresty-10826-stable-released.html' title='ngx_openresty 1.0.8.26 (stable) released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2674990374030172515</id><published>2011-10-08T14:58:00.001+08:00</published><updated>2011-10-08T14:58:38.788+08:00</updated><title type='text'>openresty.org will be down temporarily for maintenance</title><content type='html'>We&amp;#39;re moving the sites &lt;a href="http://openresty.org"&gt;openresty.org&lt;/a&gt; and &lt;a href="http://agentzh.org"&gt;agentzh.org&lt;/a&gt; to a Linode data center in Japan and these sites will be down for just a few hours or so on Oct 8. Sorry for the inconvenience.&lt;br&gt; &lt;br&gt;Sorry for the inconvenience :)&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2674990374030172515?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2674990374030172515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2674990374030172515' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2674990374030172515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2674990374030172515'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/10/openrestyorg-will-be-down-temporarily.html' title='openresty.org will be down temporarily for maintenance'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6157737143689471319</id><published>2011-10-07T13:11:00.001+08:00</published><updated>2011-10-07T13:11:57.032+08:00</updated><title type='text'>ngx_openresty 1.0.6.22 released</title><content type='html'>I&amp;#39;m happy to announce that the stable release of ngx_openresty, 1.0.6.22, has just been released:&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org/#Download" target="_blank"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt;&lt;br&gt;Here goes the complete change log for this release, as compared to the last stable release, &lt;a href="http://1.0.6.12"&gt;1.0.6.12&lt;/a&gt;:&lt;br&gt;  &lt;ul&gt;&lt;li&gt; added new option &lt;code&gt;-jN&lt;/code&gt; (e.g., &lt;code&gt;-j8&lt;/code&gt;, &lt;code&gt;-j10&lt;/code&gt;, and etc.) to &lt;a title="OpenResty - ZhangYichun, Tue 21 Jun 2011 01:09:00 PM CST"&gt;OpenResty&lt;/a&gt;&amp;#39;s &lt;code&gt;./configure&lt;/code&gt; script to allow parallel build of the dependencies like &lt;a title="LuaJIT - ZhangYichun, Tue 21 Jun 2011 05:11:00 PM CST"&gt;LuaJIT&lt;/a&gt;; thanks @Lance.&lt;/li&gt;  &lt;/ul&gt;&lt;h1&gt;&lt;/h1&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to v0.3.1rc8.&lt;ul&gt;&lt;li&gt; exposes the &lt;code&gt;CRC-32&lt;/code&gt; API of the Nginx core to the Lua land, in the form of the &lt;code&gt;ngx.crc32_short&lt;/code&gt; and &lt;code&gt;ngx.crc32_long&lt;/code&gt; methods. thanks @Lance.&lt;/li&gt;  &lt;li&gt;now &lt;code&gt;ngx.exec()&lt;/code&gt; supports lua table as the second &lt;code&gt;args&lt;/code&gt; argument value. thanks sexybabes.&lt;/li&gt;&lt;li&gt; implemented the &lt;code&gt;ngx.headers_sent&lt;/code&gt; API to check if response headers are sent (by ngx_lua). thanks @hugozhu.&lt;/li&gt;  &lt;li&gt;now we also return the &lt;code&gt;Last-Modified&lt;/code&gt; header (if any) for the subrequest response object. thanks @cyberty and sexybabes.&lt;/li&gt;&lt;li&gt;fixed an issue in &lt;code&gt;ngx.redirect&lt;/code&gt;, &lt;code&gt;ngx.exit&lt;/code&gt;, and &lt;code&gt;ngx.exec&lt;/code&gt;: these function calls would be intercepted by Lua &lt;code&gt;pcall&lt;/code&gt;/&lt;code&gt;xpcall&lt;/code&gt; because they used lua exceptions; now they use lua yield just as &lt;code&gt;ngx.location.capture&lt;/code&gt;. thanks @hugozhu for reporting this.&lt;/li&gt;  &lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;OpenResty (aka. ngx_openresty) is a full-fledged web application server by bundling the standard &lt;a class="tiddlyLink tiddlyLinkExisting" title="Nginx - ZhangYichun, Tue 21 Jun 2011 04:24:00 PM CST"&gt;Nginx&lt;/a&gt; core, lots of &lt;a target="_blank" title="External link to http://wiki.nginx.org/3rdPartyModules" href="http://wiki.nginx.org/3rdPartyModules" class="externalLink"&gt;3rd-party Nginx modules&lt;/a&gt;, as well as most of their external dependencies.&lt;br&gt; &lt;br&gt;By taking adantage of various well-designed Nginx modules, OpenResty  effectively turns the nginx server into a powerful web app server, in  which the web developers can use the Lua programming language to script  various existing nginx C modules and Lua modules and construct extremely  high-performance web applications that is capable to handle 10K+  connections.&lt;br&gt;&lt;br&gt;OpenResty aims to run your server-side web app  completely in the Nginx server, leveraging Nginx&amp;#39;s event model to do  non-blocking I/O not only with the HTTP clients, but also with remote  backends like MySQL, PostgreSQL, Memcached, and Redis.&lt;br&gt;&lt;br&gt;You can find more details on the homepage of ngx_openresty here:&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6157737143689471319?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6157737143689471319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6157737143689471319' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6157737143689471319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6157737143689471319'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/10/ngxopenresty-10622-released.html' title='ngx_openresty 1.0.6.22 released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3901551659300305197</id><published>2011-09-21T23:28:00.001+08:00</published><updated>2011-09-21T23:28:13.663+08:00</updated><title type='text'>ngx_openresty 1.0.6.12 released</title><content type='html'>I&amp;#39;ve just kicked ngx_openresty&amp;#39;s 1.0.6.12 release out of the door, which is the first stable release of ngx_openresty based on the nginx 1.0.6 core:&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org/#Download"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt; &lt;br&gt;Here goes the complete change log, as compared to the last stable release &lt;a href="http://1.0.5.1"&gt;1.0.5.1&lt;/a&gt;:&lt;br&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="RdsJsonNginxModule - ZhangYichun, Tue 21 Jun 2011 04:40:00 PM CST"&gt;RdsJsonNginxModule&lt;/a&gt; to v0.12rc4.&lt;ul&gt; &lt;li&gt; made &lt;code&gt;rds_json_ret&lt;/code&gt; honor &lt;code&gt;rds_json_success_property&lt;/code&gt; and &lt;code&gt;rds_json_user_property&lt;/code&gt;. thanks Liseen Wan (万珣新)&lt;/li&gt;&lt;li&gt; only register our output filters when the &lt;code&gt;rds_json&lt;/code&gt; directive is actually used in &lt;code&gt;nginx.conf&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="RdsCsvNginxModule - ZhangYichun, Wed 31 Aug 2011 03:42:00 PM CST"&gt;RdsCsvNginxModule&lt;/a&gt; to v0.03.&lt;ul&gt;&lt;li&gt; only register our output filters when the &lt;code&gt;rds_csv&lt;/code&gt; directive is actually used in &lt;code&gt;nginx.conf&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; added new options &lt;code&gt;--with-luajit=PATH&lt;/code&gt; and &lt;code&gt;--with-lua51=PATH&lt;/code&gt; to the &lt;code&gt;./configure&lt;/code&gt; script. thanks NginxUser.&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="DrizzleNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;DrizzleNginxModule&lt;/a&gt; to v0.1.1.&lt;/li&gt; &lt;/ul&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="RdsJsonNginxModule - ZhangYichun, Tue 21 Jun 2011 04:40:00 PM CST"&gt;RdsJsonNginxModule&lt;/a&gt; to 0.12rc3.&lt;ul&gt;&lt;li&gt; implemented new directive &lt;code&gt;rds_json_root&lt;/code&gt;.&lt;/li&gt; &lt;li&gt; implemented new directive &lt;code&gt;rds_json_success_property&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; implemented new directive &lt;code&gt;rds_json_user_property&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.3.1rc3.&lt;ul&gt; &lt;li&gt; implemented and documented the API for reading response headers from within Lua: &lt;code&gt;value = ngx.header.HEADER&lt;/code&gt;.&lt;/li&gt;&lt;li&gt; fixed a bug when setting a multi-value response header to a single value (via writing to &lt;code&gt;ngx.header.HEADER&lt;/code&gt;): the single value will be repeated on each old value.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="EchoNginxModule - ZhangYichun, Fri 26 Aug 2011 09:12:00 AM CST"&gt;EchoNginxModule&lt;/a&gt; to 0.37rc4.&lt;ul&gt;&lt;li&gt; fixed a bug in &lt;code&gt;echo_after_body&lt;/code&gt;: when network is not perfect, data truncation might occur. we should have taken into account &lt;code&gt;NGX_AGAIN&lt;/code&gt; returned by the downstream output filters. thanks Sparsh Gupta.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="HeadersMoreNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;HeadersMoreNginxModule&lt;/a&gt; to v0.16rc2.&lt;ul&gt;&lt;li&gt; fixed a bug when setting a multi-value response header to a single value: the single value will be repeated on each old value.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt; applied the patch from Maxim Dounin to fix a bug in the standard ngx_gzip module when dealing with empty flush buffers: &lt;a target="_blank" title="External link to http://mailman.nginx.org/pipermail/nginx-devel/2011-February/000730.html" href="http://mailman.nginx.org/pipermail/nginx-devel/2011-February/000730.html" class="externalLink"&gt;http://mailman.nginx.org/pipermail/nginx-devel/2011-February/000730.html&lt;/a&gt;&lt;/li&gt; &lt;li&gt; updated the no-pool-patch to eliminate the &lt;code&gt;-Wset-but-not-used&lt;/code&gt; warnings issued by gcc 4.6.0.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="LuaNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;LuaNginxModule&lt;/a&gt; to 0.3.1rc1.&lt;ul&gt; &lt;li&gt;  fixed a bug when the both the main request and the subrequest are POST  requests with a body: we should not forward the main request&amp;#39;s &lt;code&gt;Content-Length&lt;/code&gt; headers to the user subrequests. thanks 朱峰.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; upgraded &lt;a class="tiddlyLink tiddlyLinkExisting" title="HeadersMoreNginxModule - ZhangYichun, Fri 26 Aug 2011 09:10:00 AM CST"&gt;HeadersMoreNginxModule&lt;/a&gt; to 0.16rc1.&lt;ul&gt; &lt;li&gt; fixed on-demand hander/filter registration trick for &lt;code&gt;HUP&lt;/code&gt; signal restarts.&lt;/li&gt;&lt;li&gt; added some debugging outputs that can be enabled by the &lt;code&gt;--with-debug&lt;/code&gt; option when building Nginx or &lt;a class="tiddlyLink tiddlyLinkExisting" title="OpenResty - ZhangYichun, Tue 21 Jun 2011 01:09:00 PM CST"&gt;OpenResty&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Upgraded the nginx core to 1.0.6&lt;/li&gt;&lt;/ul&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3901551659300305197?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3901551659300305197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3901551659300305197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3901551659300305197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3901551659300305197'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/09/ngxopenresty-10612-released.html' title='ngx_openresty 1.0.6.12 released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7592135020957311405</id><published>2011-09-17T13:07:00.001+08:00</published><updated>2011-09-17T13:07:46.583+08:00</updated><title type='text'>ngx_drizzle v0.1.1: fixed segfaults on 32-bit systems</title><content type='html'>I&amp;#39;m happy to announce that ngx_drizzle v0.1.1 has been released. You can download the latest release tarball from&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/drizzle-nginx-module/downloads"&gt;https://github.com/chaoslawful/drizzle-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;This release fixed a long-standing segmentation fault on 32-bit systems, as well as some other issues. Here goes the complete change log:&lt;br&gt;&lt;ul&gt;&lt;li&gt; fixed segmentation faults on 32-bit systems. thanks @魏世江 and @stefanli for reporting this issue. &lt;/li&gt;&lt;li&gt; documented the &lt;a href="http://wiki.nginx.org/HttpDrizzleModule#.24drizzle_thread_id"&gt;$drizzle_thread_id&lt;/a&gt; variable. &lt;/li&gt;&lt;li&gt; added lots of debug outputs (enabled by the &lt;code&gt;--with-debug&lt;/code&gt; option while building Nginx or OpenResty), inspired by github issue #10. &lt;/li&gt;&lt;li&gt; fixed issues regarding defining global variables in C header files: we should have defined &lt;code&gt;rds_rough_col_type_t&lt;/code&gt; as a type rather than a global variable. thanks @姜大炮. &lt;/li&gt;&lt;li&gt; documented the python -&amp;gt; python3 pitfall while building libdrizzle 1.0 on at least ArchLinux. &lt;/li&gt;&lt;li&gt; fixed the automatic libdrizzle searching algorithm in the config file: now we should look under &lt;code&gt;libdrizzle-1.0/&lt;/code&gt; instead. thanks 支家乐 (Calio) for reporting this issue. &lt;/li&gt;&lt;/ul&gt;ngx_drizzle  is an nginx upstream module integrating &lt;a href="https://launchpad.net/drizzle" class="external text" rel="nofollow"&gt;libdrizzle&lt;/a&gt; into Nginx in a non-blocking and streamming way. &lt;p&gt;Essentially it provides a very efficient and flexible way for  nginx internals to access MySQL, Drizzle, as well as other RDBMS&amp;#39;s that  support the Drizzle or MySQL wired protocol. Also it can serve as a  direct REST interface to those RDBMS backends. &lt;/p&gt;&lt;p&gt;This module does not generate human-readable outputs, rather, in a  binary format called Resty-DBD-Stream (RDS) designed by ourselves. You  usually need other components, like &lt;a href="http://wiki.nginx.org/HttpRdsJsonModule" title="HttpRdsJsonModule"&gt;HttpRdsJsonModule&lt;/a&gt;, &lt;a href="http://wiki.nginx.org/HttpRdsCsvModule" title="HttpRdsCsvModule"&gt;HttpRdsCsvModule&lt;/a&gt;, or &lt;a href="http://wiki.nginx.org/LuaRdsParser" title="LuaRdsParser"&gt;LuaRdsParser&lt;/a&gt;, to work with this module. See &lt;a href="http://wiki.nginx.org/HttpDrizzleModule#Output_Format"&gt;Output Format&lt;/a&gt; for details about the RDS format. &lt;br&gt; &lt;/p&gt;&lt;p&gt;You can find the complete documentation for ngx_drizzle on Nginx Wiki:&lt;/p&gt;&lt;p&gt;    &lt;a href="http://wiki.nginx.org/HttpDrizzleModule"&gt;http://wiki.nginx.org/HttpDrizzleModule&lt;/a&gt;&lt;/p&gt;&lt;p&gt;and the latest source is on GitHub:&lt;/p&gt; &lt;p&gt;    &lt;a href="https://github.com/chaoslawful/drizzle-nginx-module"&gt;https://github.com/chaoslawful/drizzle-nginx-module&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This module is also bundled (though not enabled by default) by the ngx_openresty bundle:&lt;/p&gt; &lt;p&gt;    &lt;a href="http://openresty.org/"&gt;http://openresty.org/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You can check out this wiki page to enable this component while building ngx_openresty:&lt;/p&gt;&lt;p&gt;    &lt;a href="http://openresty.org/#DrizzleNginxModule"&gt;http://openresty.org/#DrizzleNginxModule&lt;/a&gt;&lt;br&gt; &lt;/p&gt;&lt;p&gt;Have fun!&lt;br&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7592135020957311405?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7592135020957311405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7592135020957311405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7592135020957311405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7592135020957311405'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/09/ngxdrizzle-v011-fixed-segfaults-on-32.html' title='ngx_drizzle v0.1.1: fixed segfaults on 32-bit systems'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1135855844316064305</id><published>2011-09-06T18:54:00.001+08:00</published><updated>2011-09-06T18:54:26.360+08:00</updated><title type='text'>My ngx_redis2 module now has a wiki page!</title><content type='html'>Today I turned the good old plain-text documentation of my ngx_redis2 module into a cute wiki page:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpRedis2Module"&gt;http://wiki.nginx.org/HttpRedis2Module&lt;/a&gt;&lt;br&gt;&lt;br&gt;I also generated a markdown version of this document with &lt;a href="https://github.com/agentzh/nginx-devel-utils/blob/master/wiki2markdown.pl"&gt;a Perl script&lt;/a&gt; for GitHub to display:&lt;br&gt; &lt;br&gt;    &lt;a href="https://github.com/agentzh/redis2-nginx-module"&gt;https://github.com/agentzh/redis2-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;This is an Nginx upstream module that makes Nginx talk to a &lt;a href="http://redis.io/" class="external text" rel="nofollow"&gt;Redis&lt;/a&gt;  2.x server in a non-blocking way. The full Redis 2.0 unified protocol  has been implemented including the Redis pipelining support. &lt;br&gt;&lt;br&gt;There&amp;#39;s a lot of success reports of using this module in production (combined with &lt;a href="http://wiki.nginx.org/HttpLuaModule"&gt;ngx_lua&lt;/a&gt; and &lt;a href="http://wiki.nginx.org/LuaRedisParser"&gt;lua-redis-parser&lt;/a&gt; for sure), including &lt;a href="http://www.qunar.com/"&gt;Qunar.com&lt;/a&gt;. Web applications built upon these components have remarkable performance especially when &lt;a href="http://luajit.org/luajit.html"&gt;LuaJIT&lt;/a&gt; and the TCP connection pool provided by &lt;a href="http://wiki.nginx.org/HttpUpstreamKeepaliveModule"&gt;ngx_upstream_keepalive&lt;/a&gt; are both enabled.&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1135855844316064305?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1135855844316064305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1135855844316064305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1135855844316064305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1135855844316064305'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/09/my-ngxredis2-module-now-has-wiki-page.html' title='My ngx_redis2 module now has a wiki page!'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2040943019685681923</id><published>2011-09-04T13:16:00.001+08:00</published><updated>2011-09-04T13:16:56.679+08:00</updated><title type='text'>The lua-rds-parser Lua library and ngx_rds_csv nginx module</title><content type='html'>Recently I wrote a Lua C library named lua-rds-parser for the &lt;a href="http://openresty.org"&gt;ngx_openresty&lt;/a&gt; world that we can now efficiently parse Resty DBD Stream (RDS) formatted data generated by &lt;a href="http://wiki.nginx.org/HttpDrizzleModule"&gt;ngx_drizzle&lt;/a&gt; and &lt;a href="http://github.com/FRiCKLE/ngx_postgres/"&gt;ngx_postgres&lt;/a&gt; into Lua data structures without using JSON as the intermediate data format. This can save both CPU time and memory for web applications running atop &lt;a href="http://wiki.nginx.org/HttpLuaModule"&gt;ngx_lua&lt;/a&gt;.&lt;br&gt; &lt;br&gt;Here is the project homepage for this Lua library:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/lua-rds-parser"&gt;https://github.com/agentzh/lua-rds-parser&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;Also, there&amp;#39;s a new Nginx filter module named ngx_rds_csv that can convert RDS output into the Comma-Separated Values (CSV) format in a streaming fashion:&lt;br&gt; &lt;br&gt;    &lt;a href="https://github.com/agentzh/rds-csv-nginx-module"&gt;https://github.com/agentzh/rds-csv-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;Both of these two components have already been included and enabled by default in the  latest &lt;a href="http://openresty.org/#Download"&gt;ngx_openresty stable  release&lt;/a&gt; :)&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2040943019685681923?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2040943019685681923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2040943019685681923' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2040943019685681923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2040943019685681923'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/09/lua-rds-parser-lua-library-and.html' title='The lua-rds-parser Lua library and ngx_rds_csv nginx module'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7070016692529564810</id><published>2011-09-02T16:20:00.001+08:00</published><updated>2011-09-02T16:20:23.294+08:00</updated><title type='text'>ngx_lua v0.3.0 released: new regex API, request args API, header filter hooks, and more</title><content type='html'>After two months&amp;#39; active development of our contributors, I&amp;#39;m happy to announce the v0.3.0 release of our ngx_lua module. You can get the release tarball from the download page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;This release contains a new PCRE regex API for Lua, an API for retrieving parsed URI query arguments and POST query arguments, as well as the new hooks that allow you to define nginx header filters directly in Lua. Also, the special &amp;quot;ngx.ctx&amp;quot; table is also implemented so that you can store arbitrary Lua values into this data which will have a lifetime identical to the current nginx request.&lt;br&gt; &lt;br&gt;There&amp;#39;s many more new features and bug fixes that you can find out in the following complete change log for this release:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpLuaModule#v0.3.0"&gt;http://wiki.nginx.org/HttpLuaModule#v0.3.0&lt;/a&gt;&lt;br&gt; &lt;br&gt;Special thanks go to our contributors and users, Liseen Wan, Lance, Ou Yuanning, Bertrand Mansion (golgote), James Hurst, Patrick Crosby, Bill Donahue, Jiang Dapao, and others.&lt;br&gt;&lt;br&gt;This module embeds the Lua interpreter or LuaJIT into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model by means of nginx subrequests.&lt;br&gt; &lt;br&gt;Unlike Apache&amp;#39;s mod_lua and Lighttpd&amp;#39;s mod_magnet, Lua code written atop this module can be 100% non-blocking on network traffic as long as you use the ngx.location.capture or ngx.location.capture_multi interfaces to let the nginx core do all your requests to mysql, postgresql, memcached, redis, upstream http web services, and etc etc etc.&lt;br&gt; &lt;br&gt;This module is also included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org/"&gt;http://openresty.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;You can find the complete documentation for this module on the following wiki page:&lt;br&gt; &lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpLuaModule"&gt;http://wiki.nginx.org/HttpLuaModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;And you always get the latest source code from the git repository here:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module"&gt;https://github.com/chaoslawful/lua-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7070016692529564810?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7070016692529564810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7070016692529564810' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7070016692529564810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7070016692529564810'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/09/ngxlua-v030-released-new-regex-api.html' title='ngx_lua v0.3.0 released: new regex API, request args API, header filter hooks, and more'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2372237879165921578</id><published>2011-08-09T15:44:00.001+08:00</published><updated>2011-08-09T15:44:17.073+08:00</updated><title type='text'>ngx_openresty 1.0.4.2 released</title><content type='html'>I&amp;#39;m happy to announce that ngx_openresty 1.0.4.2 has been released:&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org/#Download"&gt;http://openresty.org/#Download&lt;/a&gt;&lt;br&gt;&lt;br&gt;This release features the ability to be built and run on FreeBSD 8.2 and Solaris 11, even with LuaJIT enabled. Our &lt;a href="http://github.com/agentzh/set-misc-nginx-module"&gt;ngx_set_misc&lt;/a&gt;, &lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;ngx_lua&lt;/a&gt;, and &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; modules have been upgraded to their latest versions, with both bug fixes and new features. New options has also been added to the &lt;span style="font-family: courier new,monospace;"&gt;./configure&lt;/span&gt; script, like &lt;span style="font-family: courier new,monospace;"&gt;--with-libpq&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;--with-pg_config&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;--with-make&lt;/span&gt; and &lt;span style="font-family: courier new,monospace;"&gt;--with-no-pool-patch&lt;/span&gt;. You can find the complete change log on the following page:&lt;br&gt; &lt;br&gt;    &lt;a href="http://openresty.org/#ChangeLog1000004"&gt;http://openresty.org/#ChangeLog1000004&lt;/a&gt;&lt;br&gt;&lt;br&gt;The devel release 1.0.5.0rc1 is the first (pre)release that includes the latest nginx stable version 1.0.5.&lt;br&gt;&lt;br&gt; OpenResty (aka. ngx_openresty) is a full-fledged web application server by bundling the standard Nginx core, lots of 3rd-party Nginx modules, as well as most of their external dependencies.&lt;br&gt;&lt;br&gt;By taking adantage of various well-designed Nginx modules, OpenResty effectively turns the nginx server into a powerful web app server, in which the web developers can use the Lua programming language to script various existing nginx C modules and Lua modules and construct extremely high-performance web applications that is capable to handle 10K+ connections.&lt;br&gt; &lt;br&gt;You can find out more information on the OpenResty web site&lt;br&gt;&lt;br&gt;    &lt;a href="http://openresty.org/"&gt;http://openresty.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2372237879165921578?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2372237879165921578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2372237879165921578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2372237879165921578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2372237879165921578'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/08/ngxopenresty-1042-released.html' title='ngx_openresty 1.0.4.2 released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3994362936125170521</id><published>2011-07-27T22:02:00.001+08:00</published><updated>2011-07-27T22:02:05.466+08:00</updated><title type='text'>A sample for a dynamic request router based on ngx_lua + ngx_redis2</title><content type='html'>I wrote and tested a running sample that demonstrates how to use redis to route incoming requests to different HTTP backends based on the requests&amp;#39; User-Agent header, as a response to an email on the nginx mailing list:&lt;br&gt; &lt;br&gt;   &lt;a href="http://openresty.org/#DynamicRoutingBasedOnRedis"&gt;http://openresty.org/#DynamicRoutingBasedOnRedis&lt;/a&gt;&lt;br&gt;&lt;br&gt;Scripting the nginx core and various 3rd-party nginx modules with Lua is a lot of fun and the possibilities are unlimited :)&lt;br&gt; &lt;br&gt;I&amp;#39;m going to add more and more samples and demo apps on the wiki there ;)&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3994362936125170521?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3994362936125170521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3994362936125170521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3994362936125170521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3994362936125170521'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/sample-for-dynamic-request-router-based_27.html' title='A sample for a dynamic request router based on ngx_lua + ngx_redis2'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6994703067799475671</id><published>2011-07-22T12:26:00.001+08:00</published><updated>2011-07-22T12:26:07.109+08:00</updated><title type='text'>ngx_redis2 v0.07: nginx upstream module for the full redis 2.0 protocol</title><content type='html'>Hi, folks!&lt;br&gt;&lt;br&gt;I&amp;#39;m happy to announce that ngx_redis2 v0.07 has now been released!&lt;br&gt;&lt;br&gt;You can download the release tarball from its download page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/redis2-nginx-module/downloads"&gt;https://github.com/agentzh/redis2-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;This is an nginx upstream module that makes nginx talk to a redis 2.x server in a non-blocking way. The full Redis 2.0 unified protocol has been implemented including the redis pipelining support.&lt;br&gt;&lt;br&gt;This module returns the raw TCP response from the redis server. It&amp;#39;s recommended to use my lua-redis-parser module (written in pure C) to parse these responses into lua data structure when combined with the ngx_lua module:&lt;br&gt; &lt;br&gt;       &lt;a href="https://github.com/agentzh/lua-redis-parser"&gt;https://github.com/agentzh/lua-redis-parser&lt;/a&gt;&lt;br&gt;&lt;br&gt;If you only want to use the &amp;quot;get&amp;quot; redis command, you can try out the ngx_redis module here:&lt;br&gt; &lt;br&gt;       &lt;a href="http://wiki.nginx.org/HttpRedis"&gt;http://wiki.nginx.org/HttpRedis&lt;/a&gt;&lt;br&gt;&lt;br&gt;It returns the parsed content part of the redis response because only &amp;quot;get&amp;quot; is needed to implement.&lt;br&gt;&lt;br&gt;Another option is to parse the redis responses on your client side yourself.&lt;br&gt; &lt;br&gt;You can find the full documentation on its GitHub project page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/redis2-nginx-module"&gt;https://github.com/agentzh/redis2-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;Here goes the complete change log for this release:&lt;br&gt; &lt;ul&gt;&lt;li&gt;now we have implemented redis command pipelining by using multiple redis2_query directives in a single location. also updated the document to reflect this change.&lt;/li&gt;&lt;li&gt;implemented the new redis2_raw_queries directive which supports multiple pipelined redis commands in a single TCP query.&lt;/li&gt; &lt;li&gt;fixed github issue #5: CRLF in chunk data confused the response parser when packet segmentation happens. thanks dlogar.&lt;/li&gt;&lt;li&gt;fixed an issue in the multi-bulk reply parser that only chunks were allowed as elements. now single line replies are all allowed, but recursive multi-bulk replies are still not allowed.&lt;/li&gt; &lt;li&gt;fixed an issue regarding defining global variables in C header files: we should have defined the global ngx_http_redis2_module in a single compilation unit. thanks Jiang Dapao.&lt;/li&gt;&lt;li&gt;documented the redis2_next_upstream directive as per Lance.&lt;/li&gt; &lt;li&gt;documented the limited redis pub/sub feature support.&lt;/li&gt;&lt;li&gt;documented the various timeout config directives. thanks Mike Ferrier.&lt;/li&gt;&lt;li&gt;now we only issue a warning when there is left-over bytes in the redis response stream.&lt;/li&gt; &lt;li&gt;added a memory allocation failure check. (calio)&lt;/li&gt;&lt;li&gt;fixed a typo in the source; it does not affect runtime results though. thanks calio for catching it.&lt;/li&gt;&lt;li&gt;fixed one spot of unused-but-set-variable warning issued by gcc 4.6.&lt;/li&gt; &lt;li&gt;now we allow empty parameters in the redis2_query directive.&lt;/li&gt;&lt;li&gt;added a performance tuning section as per HowToMeetLadies.&lt;/li&gt;&lt;li&gt;fixed a typo in the source code reported by Rares Mirica.&lt;/li&gt;&lt;/ul&gt;Enjoy!&lt;br&gt;-agentzh &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6994703067799475671?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6994703067799475671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6994703067799475671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6994703067799475671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6994703067799475671'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxredis2-v007-nginx-upstream-module.html' title='ngx_redis2 v0.07: nginx upstream module for the full redis 2.0 protocol'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6409118369756312901</id><published>2011-07-11T12:58:00.001+08:00</published><updated>2011-07-11T12:58:28.075+08:00</updated><title type='text'>ngx_srcache v0.12: new config directives and bug fixes</title><content type='html'>I&amp;#39;m happy to announce that ngx_srcache v0.12 has just been released. You can download the release tarball from the download page below:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/srcache-nginx-module/downloads"&gt;http://github.com/agentzh/srcache-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;Special thanks go to Andre (shoki) for contributing a lot for this release :)&lt;br&gt;&lt;br&gt;Here goes the complete change log:&lt;br&gt;&lt;ul&gt;&lt;li&gt;now we properly support fetch/store subrequests with internal redirection in them. main requests with internal redirection will still not be stored into the cache if there is a cache miss. thanks Liseen Wan for reporting it.&lt;/li&gt; &lt;li&gt;fixed spots that trigger the unused-but-set-variable warning by gcc 4.6. &lt;/li&gt;&lt;li&gt;added srcache_store_skip and srcache_fetch_skip directives to skip cache fetching or storing based on variables that are set and not empty nor 0. thanks Andre. Examples of using Lua to set $nocache to avoid storing URIs that contain /tmp:&lt;/li&gt; &lt;/ul&gt; &lt;span style="font-family: courier new,monospace;"&gt;   set_by_lua $nocache &amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        if string.match(ngx.var.request_uri, &amp;quot;/tmp&amp;quot;) then&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;          return &amp;quot;true&amp;quot;                           &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        else &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;          return &amp;quot;&amp;quot;                               &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        end&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    srcache_store_skip $nocache;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;ul&gt;&lt;li&gt;added new directive srcache_store_max_size. thanks Andre.  &lt;/li&gt; &lt;li&gt;made our filter optimization work with nginx HUP by clearing the ngx_http_srcache_used flag at nginx pre-config callback. thanks Marcus Clyne.       &lt;/li&gt;&lt;li&gt;now we skip NULL chains in our output filters and also removed the SUBREQUEST_IN_MEMORY flag for our srcache_store subrequests because it will cause mysterious hanging issues when memcached returns CLIENT_ERROR for &amp;quot;get&amp;quot;.&lt;/li&gt; &lt;/ul&gt;The ngx_srcache module provides a transparent caching layer for arbitrary nginx locations (like those use an upstream or even serve static disk files). Usually, the ngx_memc module is used together with this module to provide a concrete caching storage backend. But technically, any modules that provide a REST interface can be used as the fetching and storage subrequests used by ngx_srcache, for example, ngx_redis2.&lt;br&gt; &lt;br&gt;For main requests, the srcache_fetch directive works at the end of the access phase, so the standard access module&amp;#39;s &amp;quot;allow&amp;quot; and &amp;quot;deny&amp;quot; direcives run *before* ours, which is usually the desired behavior for security reasons.&lt;br&gt; &lt;br&gt;You can find the complete documentation on the project page hosted on GitHub:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/srcache-nginx-module"&gt;http://github.com/agentzh/srcache-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;This module has been heavily used in our production environment for more than a year, as illustrated in the following chart:&lt;br&gt; &lt;br&gt;    &lt;a href="http://agentzh.org/misc/slides/perl-lz-apps/index.html#23"&gt;http://agentzh.org/misc/slides/perl-lz-apps/index.html#23&lt;/a&gt;&lt;br&gt;&lt;br&gt;Several outside users have also reported success in their production use.&lt;br&gt; &lt;br&gt;Also, this module is included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6409118369756312901?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6409118369756312901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6409118369756312901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6409118369756312901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6409118369756312901'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxsrcache-v012-new-config-directives.html' title='ngx_srcache v0.12: new config directives and bug fixes'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8198493760530820460</id><published>2011-07-08T16:56:00.001+08:00</published><updated>2011-07-08T16:56:30.006+08:00</updated><title type='text'>ngx_memc v0.12: improvements in the last 8 months</title><content type='html'>I&amp;#39;ve just released ngx_memc v0.12, which includes various improvements in the last 8 months:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/memc-nginx-module/downloads"&gt;http://github.com/agentzh/memc-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;Here&amp;#39;s the complete change log for this release:&lt;br&gt;&lt;ul&gt;&lt;li&gt;fixed the spots that trigger the unused-but-set-variable warning by gcc 4.6.&lt;/li&gt;&lt;li&gt;added more debug information when memcached sends back &amp;quot;invalid&amp;quot; responses.&lt;/li&gt; &lt;li&gt;we now document the timeout units properly. it should default to seconds.&lt;/li&gt;&lt;li&gt;now we use the 2-clause bsd license.&lt;/li&gt;&lt;li&gt;added an error message when no upstream backend is found in &amp;quot;memc_pass $backend&amp;quot;.&lt;/li&gt; &lt;/ul&gt;The ngx_memc module extends the standard memcached module to support almost the whole memcached ascii protocol. And it can be used with either the standard memcached server or other backends supporting the memcached wire protocol like TokyoTyrant.&lt;br&gt; &lt;br&gt;Maxim Dounin&amp;#39;s excellent ngx_http_upstream_keepalive module can also be used with this module to provide a powerful connection pool for memcached.&lt;br&gt;&lt;br&gt;See ngx_memc&amp;#39;s wiki page for more details:&lt;br&gt;&lt;br&gt;   &lt;a href="http://wiki.nginx.org/HttpMemcModule"&gt;http://wiki.nginx.org/HttpMemcModule&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module is included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8198493760530820460?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8198493760530820460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8198493760530820460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8198493760530820460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8198493760530820460'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxmemc-v012-improvements-in-last-8.html' title='ngx_memc v0.12: improvements in the last 8 months'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-642869210218466694</id><published>2011-07-08T16:14:00.001+08:00</published><updated>2011-07-08T16:14:12.909+08:00</updated><title type='text'>ngx_echo v0.36: bugfixes in the last 5 months</title><content type='html'>I&amp;#39;m happy to announce the v0.36 release of the ngx_echo module, which includes the various bugfixes in the last 5 months.&lt;br&gt;&lt;br&gt;You can get the release tarball from the download page below&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/echo-nginx-module/downloads"&gt;https://github.com/agentzh/echo-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;Here&amp;#39;s the complete change log for this release:&lt;br&gt;&lt;ul&gt;&lt;li&gt;now we back-ported the subrequest mechanism of ngx_lua to ngx_echo. this also helps some crazy test cases of deep-recursively mixing echo_location and echo_location_async pass now.&lt;/li&gt; &lt;li&gt;now echo_location and its friends can work with ngx_xss (as well as other output filter modules) completely. thanks wd for reporting this issue.&lt;br&gt;&lt;/li&gt;&lt;li&gt;done some minor optimization when modifying subrequest&amp;#39;s content-length header.&lt;/li&gt; &lt;li&gt;now we always pad a trailing \0 to filepath in  &amp;quot;echo_subrequest(_async) METHOD /path -f filepath&amp;quot; because ngx_open_cached_file requires a C string file name. thanks dr-dr xp.&lt;/li&gt;&lt;li&gt;made our filter optimization works with nginx HUP by clearing the ngx_http_echo_filter_used flag at nginx pre-config callback. thanks Marcus Clyne.&lt;/li&gt; &lt;/ul&gt;The echo module wraps lots of Nginx internal APIs for streaming input and output, parallel/sequential subrequests, timers and sleeping, as well as various meta data accessing. You can read the full documentation on the following wiki page:&lt;br&gt; &lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpEchoModule"&gt;http://wiki.nginx.org/HttpEchoModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;and you can always get the latest source code from GitHub:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/echo-nginx-module"&gt;http://github.com/agentzh/echo-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;The ngx_echo module is included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;Happy echoing!&lt;br&gt;&lt;br&gt;Best regards,&lt;br&gt;-agentzh&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-642869210218466694?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/642869210218466694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=642869210218466694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/642869210218466694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/642869210218466694'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxecho-v036-bugfixes-in-last-5-months.html' title='ngx_echo v0.36: bugfixes in the last 5 months'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5236524144115859993</id><published>2011-07-07T17:25:00.001+08:00</published><updated>2011-07-07T17:25:46.947+08:00</updated><title type='text'>Test::Nginx 0.16 released to CPAN</title><content type='html'>I&amp;#39;ve just uploaded Test::Nginx 0.16 to CPAN:&lt;br&gt;&lt;br&gt;    &lt;a href="http://search.cpan.org/dist/Test-Nginx/"&gt;http://search.cpan.org/dist/Test-Nginx/&lt;/a&gt;&lt;br&gt;&lt;br&gt;It will appear on the CPAN mirror near you in the next few hours or so.&lt;br&gt; &lt;br&gt;This Perl module provides a test scaffold based on non-blocking IO::Socket or LWP for automated testing in Nginx C module development.&lt;br&gt;&lt;br&gt;This class inherits from Test::Base, thus bringing all its declarative power to the Nginx C module testing practices.&lt;br&gt; &lt;br&gt;Please check out the full documentation on CPAN:&lt;br&gt;&lt;br&gt;    &lt;a href="http://search.cpan.org/perldoc?Test::Nginx::Socket"&gt;http://search.cpan.org/perldoc?Test::Nginx::Socket&lt;/a&gt;&lt;br&gt;&lt;br&gt;All of our Nginx modules are using Test::Nginx to drive their test suites.&lt;br&gt; &lt;br&gt;Please note that this is different from the Test::Nginx module used by Maxim Dounin.&lt;br&gt;&lt;br&gt;Antoine BONAVITA and Piotr Sikora have contributed a lot to this project. Special thanks go to them :)&lt;br&gt;&lt;br&gt;Here&amp;#39;s the complete change log for this release:&lt;br&gt; &lt;ul&gt;&lt;li&gt;fixed a bug that length(undef) produced lots of warnings on perl 5.10.x. thanks Guo Ying (shrimp).&lt;/li&gt;&lt;li&gt;now we automatically retry connecting for 3 times (1 sec delay)  in Test::Nginx::Socket::send_request. this will help automatically recovering from random slow valgrind loading problems.&lt;/li&gt; &lt;li&gt;when the directories specified in --- user_files do not exist, Test::Nginx will create it  automatically.&lt;/li&gt;&lt;li&gt;now we&amp;#39;ll issue warning when there is extra bytes after the last chunk in the chunked response parser.&lt;br&gt; &lt;/li&gt;&lt;/ul&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5236524144115859993?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5236524144115859993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5236524144115859993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5236524144115859993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5236524144115859993'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/testnginx-016-released-to-cpan.html' title='Test::Nginx 0.16 released to CPAN'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4664386407689347220</id><published>2011-07-06T12:12:00.001+08:00</published><updated>2011-07-06T12:12:03.325+08:00</updated><title type='text'>ngx_headers_more v0.15: bug fixes in the past 6 months</title><content type='html'>I&amp;#39;m happy to announce the v0.15 release of our &lt;span class="il"&gt;ngx_headers_more&lt;/span&gt;  module which features some minor optimizations and bug fixes. You can download the tarball from the download page below:&lt;br&gt; &lt;br&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module/downloads" target="_blank"&gt;http://github.com/agentzh/headers-more-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt; Here&amp;#39;s the complete change log for this version:&lt;br&gt; &lt;ul&gt;&lt;li&gt; now more_set_headers supports overriding charset in  Content-Type. thanks ML for reporting it. &lt;/li&gt;&lt;li&gt; fixed an issue in more_clear_headers: we should remove all the  instances of the headers specified, not only the first occurrence.  thanks Li Yang for reporting it. &lt;/li&gt;&lt;li&gt; back-ported a bugfix from ngx_lua: in output header set, we  should always set the header-&amp;gt;hash to 1. thanks moodydeath for  reporting it. &lt;/li&gt;&lt;li&gt; fixed a bug when clearing the Accept-Ranges header. thanks Bo  Blangstrup.&lt;/li&gt;&lt;/ul&gt;  The &lt;span class="il"&gt;ngx_headers_more&lt;/span&gt; module allows you to add,  set, or clear any output or input header that you specify. This is an enhanced version of the standard headers module because it provides more utilities like resetting or clearing &amp;quot;builtin headers&amp;quot; like &lt;span style="font-family: courier new,monospace;"&gt;Content-Type&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;Content-Length&lt;/span&gt;, and &lt;span style="font-family: courier new,monospace;"&gt;Server&lt;/span&gt;.&lt;br&gt;  &lt;br&gt; You can always get the latest source code from its project page on  GitHub&lt;br&gt; &lt;br&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module" target="_blank"&gt;http://github.com/agentzh/headers-more-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt; and the full documentation from the nginx wiki&lt;br&gt; &lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule" target="_blank"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module is included and enabled by default in our ngx_openresty bundle: &lt;a href="http://openresty.org"&gt;http://openresty.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;This is one of the most popular modules created by our team :)&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4664386407689347220?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4664386407689347220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4664386407689347220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4664386407689347220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4664386407689347220'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxheadersmore-v015-bug-fixes-in-past-6.html' title='ngx_headers_more v0.15: bug fixes in the past 6 months'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5949854586552477284</id><published>2011-07-06T11:32:00.001+08:00</published><updated>2011-07-06T11:32:05.669+08:00</updated><title type='text'>ngx_rds_json v0.11: compact JSON output support</title><content type='html'>I&amp;#39;m glad to announce that ngx_rds_json v0.11 has been released:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/rds-json-nginx-module/downloads"&gt;https://github.com/agentzh/rds-json-nginx-module/downloads&lt;/a&gt;&lt;br&gt;&lt;br&gt;This release includes the new directive &amp;quot;rds_json_format compact&amp;quot; to emit very compact JSON like&lt;br&gt; &lt;br&gt;    &lt;span style="font-family: courier new,monospace;"&gt;[[&amp;quot;id&amp;quot;,&amp;quot;name&amp;quot;,&amp;quot;age&amp;quot;],[1,&amp;quot;marry&amp;quot;,18],[2,&amp;quot;bob&amp;quot;,23],[3,&amp;quot;tom&amp;quot;,9]]&lt;/span&gt;&lt;br&gt;&lt;br&gt;instead of the more verbose default form&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   [{&amp;quot;id&amp;quot;:1,&amp;quot;name&amp;quot;:&amp;quot;marry&amp;quot;,&amp;quot;age&amp;quot;:18},&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     {&amp;quot;id&amp;quot;:2,&amp;quot;name&amp;quot;:&amp;quot;bob&amp;quot;,&amp;quot;age&amp;quot;:9},&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;     {&amp;quot;id&amp;quot;:3,&amp;quot;name&amp;quot;:&amp;quot;tom&amp;quot;,&amp;quot;age&amp;quot;:9}]&lt;/span&gt;&lt;br&gt;&lt;br&gt;The ngx_rds_json module provides an output filter that can format the RDS outputs generated by ngx_drizzle and ngx_postgres modules to JSON.&lt;br&gt; &lt;br&gt;You can find the complete documentation on its project page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/rds-json-nginx-module"&gt;https://github.com/agentzh/rds-json-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5949854586552477284?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5949854586552477284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5949854586552477284' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5949854586552477284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5949854586552477284'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxrdsjson-v011-compact-json-output.html' title='ngx_rds_json v0.11: compact JSON output support'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3683256930422939394</id><published>2011-07-05T18:08:00.001+08:00</published><updated>2011-07-05T18:08:50.831+08:00</updated><title type='text'>ngx_drizzle v0.1.0 released: now runs with mysql 5.5+ w/o patching libdrizzle</title><content type='html'>I&amp;#39;m happy to announce the ngx_drizzle module&amp;#39;s v0.1.0 release, which includes lots of bug fixes and new features accumulated in the last 8 months:&lt;br&gt;&lt;br&gt;   &lt;a href="https://github.com/chaoslawful/drizzle-nginx-module/downloads"&gt;https://github.com/chaoslawful/drizzle-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;The most exciting thing about this release is that we can now work with the latest libdrizzle 1.0 without patches on at least Linux and Mac OS X. And we can now connect to MySQL 5.5+ and we&amp;#39;re now more stable under load.&lt;br&gt; &lt;br&gt;This is an nginx upstream module integrating libdrizzle (&lt;a href="https://launchpad.net/drizzle"&gt;https://launchpad.net/drizzle&lt;/a&gt; ) into nginx in an  non-blocking and streamming way.&lt;br&gt;&lt;br&gt;Essentially it provides a very efficient and flexible way for nginx internals to access mysql, drizzle, as well as other RDBMS&amp;#39;s that support the drizzle protocol or mysql protocol. Also it can serve as a direct REST interface to those RDBMS backends. Alternatively it can be invoked by other modules like ngx_lua via subrequests.&lt;br&gt; &lt;br&gt;It also has a builtin per-worker connection pool mechanism.&lt;br&gt;&lt;br&gt;Check out its project page for the full documentation:&lt;br&gt;&lt;br&gt;   &lt;a href="https://github.com/chaoslawful/drizzle-nginx-module"&gt;https://github.com/chaoslawful/drizzle-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;Here goes the complete change log for this release:&lt;br&gt;&lt;ul&gt;&lt;li&gt;now we require at least libdrizzle 1.0, which supports official mysql 5.5+ and is much more stable under load. thanks Taylor Weibley for pushing this. We no longer require patching libdrizzle any more.&lt;/li&gt; &lt;li&gt;fixed a compilation issue on Mac OS X: we should include drizzle.h prior to nginx headers, or we will not get the &amp;quot;bool&amp;quot; type properly installed on Mac OS X.&lt;/li&gt;&lt;li&gt;fixed the spots that trigger -Wunused-but-set-variable by gcc 4.6.&lt;/li&gt; &lt;li&gt;fixed the duplicate last chunk issue: we should not set the last_buf flag ourselves in drizzle_output.c because ngx_http_upstream already sends a last buf for us.&lt;/li&gt;&lt;li&gt;ported over Maxim Dounin&amp;#39;s patch for ngx_http_upstream_keepalive connection pool fixes: we should have discarded stale read events for cached tcp connections in the pool.&lt;/li&gt; &lt;li&gt;implemented the new drizzle_status directive to provide connection pool status monitoring capability.&lt;/li&gt;&lt;li&gt;fixed a minor bug in the connection pool: we should resume the &amp;quot;name&amp;quot;,  &amp;quot;sockaddr&amp;quot;, and &amp;quot;socklen&amp;quot; fields for the connection from the pool such that we can get more detailed error log messages with the &amp;quot;upstream: drizzle://ip.add.re.ss:port&amp;quot; bit.&lt;/li&gt; &lt;li&gt;implemented the $drizzle_thread_id variable which is automatically set when mysql/drizzle times out.&lt;/li&gt;&lt;li&gt;now we use the 2-clause bsd license.&lt;/li&gt;&lt;li&gt;report an error message when upstream name not found for drizzle_pass.&lt;/li&gt; &lt;li&gt;now we implemented the charset option for the &amp;quot;drizzle_server&amp;quot; diredctive which causes ngx_drizzle send &amp;quot;set names xxx&amp;quot; automatcially for every connection to that drizzle server.&lt;/li&gt;&lt;li&gt;added a lot of more documentation.&lt;/li&gt; &lt;/ul&gt;Enjoy!&lt;br&gt;-agentzh&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3683256930422939394?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3683256930422939394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3683256930422939394' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3683256930422939394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3683256930422939394'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxdrizzle-v010-released-now-runs-with.html' title='ngx_drizzle v0.1.0 released: now runs with mysql 5.5+ w/o patching libdrizzle'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6051487069400756884</id><published>2011-07-05T17:12:00.000+08:00</published><updated>2011-07-05T17:13:01.453+08:00</updated><title type='text'>Slides for my nginx app talk in Beijing Perl Workshop 2011</title><content type='html'>I gave an nginx talk in Beijing Perl Workshop 2011, which titles &amp;quot;Applications of ngx_openresty and Perl in &lt;a href="http://lz.taobao.com"&gt;lz.taobao.com&lt;/a&gt;&amp;quot;. I showed how our nginx modules are used to build our company products.&lt;br&gt; &lt;br&gt;You can view the (English and Chinese) slides directly in your web browser:&lt;br&gt;&lt;br&gt;    &lt;a href="http://agentzh.org/misc/slides/perl-lz-apps/"&gt;http://agentzh.org/misc/slides/perl-lz-apps/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Please use the arrow keys or pageup/pagedown keys on your keyboard to switch pages.&lt;br&gt; &lt;br&gt;Alternatively, you can download the slides tarball and browse offline: &lt;a href="http://agentzh.org/misc/slides/perl-lz-apps.tar.gz"&gt;http://agentzh.org/misc/slides/perl-lz-apps.tar.gz&lt;/a&gt;&lt;br&gt;&lt;br&gt;You can find the slides for my other nginx talks on the page as well:&lt;br&gt; &lt;br&gt;    &lt;a href="http://agentzh.org/#Presentations"&gt;http://agentzh.org/#Presentations&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6051487069400756884?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6051487069400756884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6051487069400756884' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6051487069400756884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6051487069400756884'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/slides-for-my-nginx-app-talk-in-beijing.html' title='Slides for my nginx app talk in Beijing Perl Workshop 2011'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6948055347657239937</id><published>2011-07-05T13:26:00.001+08:00</published><updated>2011-07-05T13:26:46.953+08:00</updated><title type='text'>ngx_lua v0.2.0 is now released with lots of bug fixes</title><content type='html'>After 5 months&amp;#39; active development, the ngx_lua module v0.2.0 release is now finally released:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt;This release contains lots of bug fixes as well as some new features. Many many thanks go to all our users and contributors worldwide, especially moodydeath :)&lt;br&gt;&lt;br&gt;The ngx_lua module embeds the Lua/LuaJIT interpreter into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model by means of nginx subrequests.&lt;br&gt; &lt;br&gt;You can get the latest source code and full documentation from the ngx_lua&amp;#39;s project page:&lt;br&gt;&lt;br&gt;   &lt;a href="https://github.com/chaoslawful/lua-nginx-module/"&gt;https://github.com/chaoslawful/lua-nginx-module/&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module is now included in our ngx_openresty bundle: &lt;a href="http://openresty.org/"&gt;http://openresty.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Here goes the complete change log for this release:&lt;br&gt;&lt;ul&gt;&lt;li&gt;now we support ngx.var[1], ngx.var[2], and etc to refer to the nginx regex capturing variables \$1, \$2, and etc in Lua. this resolved github issue #43. thanks Tobia Conforto for reporting it.&lt;/li&gt; &lt;li&gt;now we use the same value overriding mechanism as ngx_rewrite&amp;#39;s set command for ngx.var.VAR = new_value. Assigning values to special variables like $limit_rate and $args should now work; also writing to built-in variables that are not changeable (like $arg_PARAMETER) will result in a 500 error page, as expected, now. thanks Richard Kearsley for reporting it.&lt;/li&gt; &lt;li&gt;fixed the lua_code_cache off warning when the lua_code_cache is explicitly on. thanks Feng Xingguo.&lt;/li&gt;&lt;li&gt;applied the patch from cyberty to add ngx.http_time() function to expose the nginx core function ngx_http_time to the Lua land.&lt;/li&gt; &lt;li&gt;fixed an issue on i386: we now use off_t consistently. mixing it with size_t on 32-bit systems can cause Bad Things. this fixed github issue #42. thanks moodydeath.&lt;/li&gt;&lt;li&gt;fixed an issue on i386: fixed a formatter mismatch issue in ngx_http_echo_adjust_subrequest. thanks Wang Bin. This caused incorrect subrequest Content-Length header when a body is specified.&lt;/li&gt; &lt;li&gt;now in the subrequest capturing processor, we worked around an issue in ngx_http_static_module that when it issues 301 redirect for directory access w/o a trailing slash, it does not inject r-&amp;gt;headers_out.location into the r-&amp;gt;headers_out.headers list. thanks moodydeath for reporting it in the discussion of github issue #41.&lt;/li&gt; &lt;li&gt;fixed a bug in ngx.location.capture() and ngx.location.capture_multi() that we could not capture locations with internal redirections in them. thanks moodydeath for reporting it in github issue #41.&lt;/li&gt;&lt;li&gt;fixed redundant last chunk issue for ngx.exec() invocation at rewrite and access phases: we should quit the current core_run_phases cycle; this also fixed github issue #40: 2 Subrequest calls when using access_by_lua, ngx.exec and echo_location.&lt;/li&gt; &lt;li&gt;fixed ngx.exit(status) where status &amp;gt;= 200 and status &amp;lt; 300 for access_by_lua* and rewrite_by_lua*: it should quit the whole request altegother and skip all those subsequent phase handlers (if any). thanks moodydeath for reporting it.&lt;/li&gt; &lt;li&gt;fixed github issue #39: setting differnt response headers in Lua with common prefix might interfere with each other. thanks moodydeath.&lt;/li&gt;&lt;li&gt;fixed GitHub issue #38: request headers did not forward to subrequests when the &amp;quot;method&amp;quot; or &amp;quot;body&amp;quot; option is explicitly specified by a non-nil value for ngx.location.capture(). thanks Richard Kearsley.&lt;/li&gt; &lt;li&gt;fixed a bug in output header set; we should always set the header-&amp;gt;hash to 1. thanks moodydeath for reporting it.&lt;/li&gt;&lt;li&gt;fixed spots that trigger the &amp;quot;variable set but not used&amp;quot; warning issued by gcc 4.6.0.&lt;/li&gt; &lt;li&gt;now we turn the ngx.req.header table into an ngx.req.get_headers() function; we also added ngx.req.set_header(name, value) and ngx.req.clear_header(name). thanks moodydeath.&lt;/li&gt;&lt;li&gt;now we make ngx_devel_kit (NDK) optional. thanks Kirill A. Korinskiy.&lt;/li&gt; &lt;li&gt;removed a duplicate definition of the ngx_str_set macro caught by ctags; also fixed a warning thrown by gcc -O3 on Mac OS X 10.6.&lt;/li&gt;&lt;li&gt;added patch to use PCRE related Lua extensions in ngx_lua (chaoslawful)&lt;/li&gt;&lt;li&gt; now we change the way we process HTTP 1.0 requests by automatically buffering all the user outputs generated by ngx.print()/ngx.say() calls, which is much more natural than the old broken way.&lt;/li&gt;&lt;li&gt;fixed the &amp;quot;ngx.exec() after ngx.location.capture() hanging&amp;quot; bug for rewrite_by_lua* and access_by_lua* as well. thanks Wendal Chen.&lt;/li&gt; &lt;li&gt;applied a patch from moodydeath to introduce the &amp;quot;ngx.is_subrequest&amp;quot; attribute.&lt;/li&gt;&lt;li&gt;now we encourage use of the client_body_in_single_buffer directive instead of big client_body_buffer_size when lua_need_request_body is turned on.&lt;/li&gt; &lt;li&gt;fixed the config script and added extra linking options needed by LuaJIT in 64-bit Mac OS X.&lt;/li&gt;&lt;li&gt;fixed the zero size alert caused by ngx.print(&amp;quot;&amp;quot;) in Lua.&lt;/li&gt;&lt;li&gt;now we always allocate r-&amp;gt;request_body for subrequests when the method option is specified for ngx.location.capture*. this prevents accidental inheritance of parent request&amp;#39;s request body when client_body_buffer_size &amp;lt; client_max_body_size.&lt;br&gt; &lt;/li&gt;&lt;/ul&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6948055347657239937?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6948055347657239937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6948055347657239937' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6948055347657239937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6948055347657239937'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/07/ngxlua-v020-is-now-released-with-lots.html' title='ngx_lua v0.2.0 is now released with lots of bug fixes'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-117410261006836120</id><published>2011-03-08T14:35:00.001+08:00</published><updated>2011-03-08T14:35:35.575+08:00</updated><title type='text'>How nginx "location if" works</title><content type='html'>Nginx&amp;#39;s &lt;a href="http://wiki.nginx.org/NginxHttpRewriteModule#if"&gt;if directive&lt;/a&gt; does have some weirdness in practice. And people may misuse it when they do not have enough knowledge about its behavior. In this post, I&amp;#39;ll analyze some examples here such that people &lt;i&gt;may&lt;/i&gt; get some light and use it correctly.&lt;br&gt; &lt;br&gt;In short, Nginx&amp;#39;s &amp;quot;if&amp;quot; block effectively creates a (nested) location block and once the &amp;quot;if&amp;quot; condition matches, only the content handler of the inner location block (i.e., the &amp;quot;if&amp;quot; block) will be executed.&lt;br&gt; &lt;br&gt;&lt;b&gt;Case 1&lt;/b&gt;&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  location /proxy {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           set $a 56;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       set $a 76;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       proxy_pass http://127.0.0.1:$server_port/$a;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location ~ /(\d+) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       echo $1;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt;&lt;br&gt;Calling &lt;span style="font-family: courier new,monospace;"&gt;/proxy&lt;/span&gt; gives 76 because it works in the following steps:&lt;br&gt;&lt;br&gt;1. Nginx runs all the rewrite phase directives in the order that they&amp;#39;re in the config file, i.e.,&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;      set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           set $a 56;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set $a 76;&lt;/span&gt;&lt;br&gt;&lt;br&gt;   and $a gets the final value of 76.&lt;br&gt;&lt;br&gt;2. Nginx traps into the &amp;quot;if&amp;quot; inner block because its condition &lt;span style="font-family: courier new,monospace;"&gt;$a = 32&lt;/span&gt; was met in step 1.&lt;br&gt; &lt;br&gt;3. The inner block does not has any content handler, &lt;a href="http://wiki.nginx.org/NginxHttpProxyModule"&gt;ngx_proxy&lt;/a&gt; inherits the content handler (that of &lt;span style="font-family: courier new,monospace;"&gt;ngx_proxy&lt;/span&gt;) in the outer scope (see src/http/modules/ngx_http_proxy_module.c:2025).&lt;br&gt; &lt;br&gt;4. Also the config specified by &lt;span style="font-family: courier new,monospace;"&gt;proxy_pass&lt;/span&gt; also gets inherited by the inner &amp;quot;if&amp;quot; block (see src/http/modules/ngx_http_proxy_module.c:2015)&lt;br&gt;&lt;br&gt;5. Request terminates (and the control flow never goes outside of the &amp;quot;if&amp;quot; block).&lt;br&gt; &lt;br&gt;That is, the &lt;a href="http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass"&gt;&lt;span style="font-family: courier new,monospace;"&gt;proxy_pass&lt;/span&gt;&lt;/a&gt; directive in the outer scope will never run in this example. It is &amp;quot;if&amp;quot; inner block that actually serves you.&lt;br&gt; &lt;br&gt;Let&amp;#39;s see what happens when we override the inner &amp;quot;if&amp;quot; block&amp;#39;s content handler with out own:&lt;br&gt;&lt;br&gt;&lt;b&gt;Case 2&lt;/b&gt;&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  location /proxy {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           set $a 56;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           echo &amp;quot;a = $a&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       set $a 76;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       proxy_pass http://127.0.0.1:$server_port/$a;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location ~ /(\d+) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       echo $1;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt;&lt;br&gt;You will get this while accessing /proxy:&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  a = 76&lt;/span&gt;&lt;br&gt;&lt;br&gt;Looks counter-intuitive? Oh, well, let&amp;#39;s see what&amp;#39;s happening this time:&lt;br&gt; &lt;br&gt;1. Nginx runs all the rewrite phase directives in the order that they&amp;#39;re in the config file, i.e.,&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;      set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           set $a 56;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       set $a 76;&lt;/span&gt;&lt;br&gt;&lt;br&gt;   and $a gets the final value of 76.&lt;br&gt; &lt;br&gt;2. Nginx traps into the &amp;quot;if&amp;quot; inner block because its condition &lt;span style="font-family: courier new,monospace;"&gt;$a = 32&lt;/span&gt; was met in step 1.&lt;br&gt;&lt;br&gt;3. The inner block &lt;i&gt;does&lt;/i&gt; has a content handler specified by &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;echo&lt;/span&gt;&amp;quot;, then the value of &lt;span style="font-family: courier new,monospace;"&gt;$a&lt;/span&gt; (76) gets emitted to the client side.&lt;br&gt; &lt;br&gt;4. Request terminates (and the control flow never goes outside of the &amp;quot;if&amp;quot; block), as in Case 1.&lt;br&gt;&lt;br&gt;We do have a choice to make Case 2 work as we like:&lt;br&gt;&lt;br&gt;&lt;b&gt;[Case 3]&lt;/b&gt;&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt; location /proxy {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           set $a 56;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           break;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           echo &amp;quot;a = $a&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set $a 76;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       proxy_pass http://127.0.0.1:$server_port/$a;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location ~ /(\d+) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       echo $1;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt;&lt;br&gt;This time, we just add a &lt;a href="http://wiki.nginx.org/NginxHttpRewriteModule#break"&gt;&lt;span style="font-family: courier new,monospace;"&gt;break&lt;/span&gt;&lt;/a&gt; directive inside the if block. This will stop nginx from running the rest ngx_rewrite directives. So we get&lt;br&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   a = 56&lt;/span&gt;&lt;br&gt;&lt;br&gt;So this time, nginx works this way:&lt;br&gt;&lt;br&gt;1. Nginx runs all the rewrite phase directives in the order that they&amp;#39;re in the config file, i.e.,&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;      set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           set $a 56;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           break;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br&gt;&lt;br&gt;   and $a gets the final value of 56.&lt;br&gt;&lt;br&gt;2. Nginx traps into the &amp;quot;if&amp;quot; inner block because its condition &lt;span style="font-family: courier new,monospace;"&gt;$a = 32&lt;/span&gt; was met in step 1.&lt;br&gt; &lt;br&gt;3. The inner block &lt;i&gt;does&lt;/i&gt; has a content handler specified by &lt;span style="font-family: courier new,monospace;"&gt;echo&lt;/span&gt;, then the value of &lt;span style="font-family: courier new,monospace;"&gt;$a&lt;/span&gt; (56) gets emitted to the client side.&lt;br&gt; &lt;br&gt;4. Request terminates (and the control flow never goes outside of the &amp;quot;if&amp;quot; block), just as in Case 1.&lt;br&gt;&lt;br&gt;Okay, you see how &lt;span style="font-family: courier new,monospace;"&gt;ngx_proxy&lt;/span&gt; module&amp;#39;s config inheritance among nested locations take the key role here, and make you &lt;i&gt;believe&lt;/i&gt; it works the way that you want. But other modules (like &lt;span style="font-family: courier new,monospace;"&gt;echo&lt;/span&gt; mentioned in one of my earlier emails) may not inherit content handlers in nested locations (in fact, most content handler modules, including upstream ones, don&amp;#39;t).&lt;br&gt; &lt;br&gt;And one must be careful about bad side effects of config inheritance of &amp;quot;if&amp;quot; blocks in other cases, consider the following example:&lt;br&gt;&lt;br&gt;&lt;b&gt;Case 4&lt;/b&gt;&lt;br&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location /proxy {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set $a 32;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       if ($a = 32) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           return 404;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set $a 76;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       proxy_pass http://127.0.0.1:$server_port/$a;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       more_set_headers &amp;quot;X-Foo: $a&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location ~ /(\d+) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       echo $1;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br&gt;Here, &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule"&gt;ngx_header_more&lt;/a&gt;&amp;#39;s &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#more_set_headers"&gt;&lt;span style="font-family: courier new,monospace;"&gt;more_set_headers&lt;/span&gt;&lt;/a&gt; will also be inherited by the implicit location created by the &amp;quot;if&amp;quot; block. So you will get:&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  $ curl localhost/proxy&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   HTTP/1.1 404 Not Found&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   Server: nginx/0.8.54 (without pool)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   Date: Mon, 14 Feb 2011 05:24:00 GMT&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   Content-Type: text/html&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   Content-Length: 184&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   Connection: keep-alive&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   X-Foo: 32&lt;/span&gt;&lt;br&gt;&lt;br&gt;which may or may not what you want :)&lt;br&gt; &lt;br&gt;BTW, the &lt;a href="http://wiki.nginx.org/NginxHttpHeadersModule#add_header"&gt;&lt;span style="font-family: courier new,monospace;"&gt;add_header&lt;/span&gt;&lt;/a&gt; directive will not emit an &lt;span style="font-family: courier new,monospace;"&gt;X-Foo&lt;/span&gt; header in this case, and it does not mean no directive inheritance happens here, but add_header&amp;#39;s header filter will skip 404 responses.&lt;br&gt; &lt;br&gt;You see, how tricky it is behind the scene! No wonder people keep saying &amp;quot;&lt;a href="http://wiki.nginx.org/IfIsEvil"&gt;if is evil&lt;/a&gt;&amp;quot;.&lt;br&gt;&lt;br&gt;We&amp;#39;ve been using the &lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;ngx_lua&lt;/a&gt; module to do such complicated nginx.conf branching (and also the whole application&amp;#39;s business logic) in Lua. Lua&amp;#39;s &amp;quot;if&amp;quot; is not evil anyway.&lt;br&gt; &lt;br&gt;For ngx_lua&amp;#39;s set_by_lua directive, there&amp;#39;s even no Lua coroutine overhead (though the overhead itself is very small).&lt;br&gt;&lt;br&gt;Please note that I did &lt;i&gt;not&lt;/i&gt; say that you should never use nginx&amp;#39;s &amp;quot;if&amp;quot;. Don&amp;#39;t take me wrong. My motivation of writing this explanation of the underlying mechanism is to help you use it correctly and wisely ;)&lt;br&gt; &lt;br&gt;I think Igor Sysoev will redesign the whole rewrite module in his nginx 2.0 devel branch. Then everything here will be changed.&lt;br&gt;&lt;br&gt;P.S. This article was originally posted to this nginx mailing list thread: &lt;a href="http://forum.nginx.org/read.php?2,174917"&gt;http://forum.nginx.org/read.php?2,174917&lt;/a&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-117410261006836120?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/117410261006836120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=117410261006836120' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/117410261006836120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/117410261006836120'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/03/how-nginx-location-if-works.html' title='How nginx &quot;location if&quot; works'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1223981576007361283</id><published>2011-02-09T17:59:00.000+08:00</published><updated>2011-02-09T18:00:00.230+08:00</updated><title type='text'>ngx_lua v0.1.5: ability to capture multiple parallel subrequests</title><content type='html'>&lt;div class="gmail_quote"&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="h5"&gt;&lt;div class="gmail_quote"&gt;&lt;div class="gmail_quote"&gt;&lt;div&gt;I&amp;#39;m pleased to announce that ngx_lua v0.1.5 is now released. You can download the release tarball from the download page:&lt;br&gt; &lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads" target="_blank"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br&gt;     &lt;br&gt;This version of the ngx_lua module implements the &lt;span style="font-family: courier new,monospace;"&gt;ngx.location.capture_multi&lt;/span&gt; method that can issue multiple nginx subrequests at the same time, capture their responses along the way, and then return the results in the same order that they&amp;#39;re specified in the arguments.&lt;br&gt;      &lt;br&gt;Here is a small example:&lt;br&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    location ~ &amp;#39;^/echo/(\w+)$&amp;#39; {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;        echo -n $1;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    location = /main {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        content_by_lua &amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            local res1, res2, res3 =&lt;br&gt;                ngx.location.capture_multi{&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                    { &amp;quot;/echo/sun&amp;quot; },&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;                &lt;/span&gt;&lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family: courier new,monospace;"&gt;{ &amp;quot;/echo/moon&amp;quot; },                 &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;                &lt;/span&gt;&lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family: courier new,monospace;"&gt;{ &amp;quot;/echo/earth&amp;quot; },                &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;                }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            ngx.say(res1.body)                    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            ngx.say(res2.body)                    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            ngx.say(res3.body)                    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;        &amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br&gt;&lt;br&gt;then accessing /main gives&lt;br&gt;&lt;br&gt;      &lt;span style="font-family: courier new,monospace;"&gt;    sun&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    moon&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;    earth&lt;/span&gt;&lt;br&gt;&lt;br&gt;and those three subrequests, &lt;span style="font-family: courier new,monospace;"&gt;GET /echo/sun&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;GET /echo/moon&lt;/span&gt;, and &lt;span style="font-family: courier new,monospace;"&gt;GET /echo/earth&lt;/span&gt;, were issued at the same time.&lt;br&gt;    &lt;br&gt;&lt;/div&gt;Below is a more complicated example that fires 2 &lt;i&gt;concurrent&lt;/i&gt; MySQL queries to calculate the count of dogs and the count cats, respectively, at the same time, and finally output the sum of these 2 counts, i.e., the total count of all the animals.&lt;div&gt;      &lt;br&gt;First of all, we define the remote mysql server upstream in the main &lt;span style="font-family: courier new,monospace;"&gt;http&lt;/span&gt; block:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;    upstream mysql_node {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;        drizzle_server &lt;a href="http://10.32.136.5:3306" target="_blank"&gt;10.32.136.5:3306&lt;/a&gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            user=monty password=some_pass dbname=main protocol=mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;        drizzle_keepalive max=100 mode=single overflow=ignore;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br&gt;      &lt;br&gt;&lt;/div&gt;then we define a general-purpose internal location to proxy SQL queries to remote MySQL node in our default virtual host server block:&lt;div&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;    location = /mysql {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;        internal;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        drizzle_query $echo_request_body;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;        drizzle_pass mysql_node;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        rds_json on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br&gt;after that, we define our main location that does the job:&lt;br&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;    location /main {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        content_by_lua &amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            local opts1 = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                method = ngx.HTTP_POST,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;/div&gt;&lt;span style="font-family: courier new,monospace;"&gt;                body = &amp;quot;select sum(1) cnt from cats&amp;quot;,&lt;/span&gt;&lt;div&gt;&lt;span style="font-family: courier new,monospace;"&gt;            }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            local opts2 = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                method = ngx.HTTP_POST,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;/div&gt;&lt;span style="font-family: courier new,monospace;"&gt;                body = &amp;quot;select sum(1) cnt from dogs&amp;quot;,&lt;/span&gt;&lt;div&gt;&lt;span style="font-family: courier new,monospace;"&gt;            }   &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            local res1, res2 =&lt;br&gt;                ngx.location.capture_multi{&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                    { &amp;quot;/mysql&amp;quot;, opts1 },&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;                    { &amp;quot;/mysql&amp;quot;, opts2 }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            local yajl = require(&amp;quot;yajl&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            local cats = yajl.to_value(res1.body)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            local dogs = yajl.to_value(res2.body)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            local total = cats[1].cnt + dogs[1].cnt&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;            ngx.say(&amp;quot;for total &amp;quot;, total, &amp;quot; animals.&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        &amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;      &lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;For brevity, I&amp;#39;ve omitted all the error handling code like checking if &lt;span style="font-family: courier new,monospace;"&gt;res1.status&lt;/span&gt; is 200 and validating &lt;span style="font-family: courier new,monospace;"&gt;cats.errcode&lt;/span&gt; has &lt;span style="font-family: courier new,monospace;"&gt;nil&lt;/span&gt; values ;)&lt;div&gt;      &lt;br&gt;The nginx modules &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module" target="_blank"&gt;ngx_drizzle&lt;/a&gt;, &lt;a href="http://github.com/agentzh/rds-json-nginx-module" target="_blank"&gt;ngx_rds_json&lt;/a&gt;, and the &lt;a href="https://github.com/brimworks/lua-yajl/" target="_blank"&gt;lua-yajl&lt;/a&gt; Lua library are also used in the sample above.&lt;br&gt;      &lt;br&gt;&lt;/div&gt;This example can be trivially extended to run tens or even more sql queries to &lt;i&gt;different&lt;/i&gt; MySQL machines and &lt;i&gt;combined&lt;/i&gt; with more PostgreSQL database servers. All in parallel and all are 100% non-blocking on network traffic.&lt;div&gt;  &lt;br&gt;    This v0.1.5 version of ngx_lua also contains&lt;br&gt;&lt;ul&gt;&lt;li&gt;optimizations on subrequest buffer management and thus saving much memory when using &lt;span style="font-family: courier new,monospace;"&gt;ngx.location.capture&lt;/span&gt; (and &lt;span style="font-family: courier new,monospace;"&gt;ngx.location.capture_multi&lt;/span&gt;).&lt;/li&gt;   &lt;li&gt;   fixes of the build system that we no longer require OpenSSL and ngx_lua no longer crash when used with statically linked OpenSSL. Thanks Marcus Clyne and Vladislav Manchev.&lt;/li&gt;&lt;li&gt;fixes of the Lua code cache handling that we no longer clear pre-loaded standard Lua packages like &amp;quot;table&amp;quot; and &amp;quot;string&amp;quot; when the Lua code cache is off.&lt;/li&gt;   &lt;/ul&gt;  The ngx_lua module embeds the Lua/LuaJIT interpreter into the nginx core  and integrates the powerful Lua threads (aka Lua coroutines) into the  nginx event model by means of nginx subrequests.&lt;br&gt;&lt;br&gt;You can get the  latest source code and full documentation from the  ngx_lua&amp;#39;s project page:&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/" target="_blank"&gt;https://github.com/chaoslawful/lua-nginx-module/&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Happy Lua and nginx.conf hacking!&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1223981576007361283?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1223981576007361283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1223981576007361283' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1223981576007361283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1223981576007361283'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/02/ngxlua-v015-ability-to-capture-multiple_6605.html' title='ngx_lua v0.1.5: ability to capture multiple parallel subrequests'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7863515430286151406</id><published>2011-02-07T18:58:00.001+08:00</published><updated>2011-02-07T18:58:41.999+08:00</updated><title type='text'>ngx_echo v0.35: ability to POST/PUT local files as subrequest bodies</title><content type='html'>I&amp;#39;m happy to announce the v0.35 release of the ngx_echo module, which features the ability to POST/PUT location files as subrequest bodies via the &lt;span style="font-family: courier new,monospace;"&gt;-f&lt;/span&gt; option of the &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_subrequest"&gt;&lt;span style="font-family: courier new,monospace;"&gt;echo_subrequest&lt;/span&gt;&lt;/a&gt; and &lt;a href="http://wiki.nginx.org/HttpEchoModule#echo_subrequest_async"&gt;echo_subrequest_async&lt;/a&gt; directives.&lt;br&gt; &lt;br&gt;You can get the release tarball from the download page below&lt;br&gt;&lt;br&gt;    &lt;a href="https://github.com/agentzh/echo-nginx-module/downloads"&gt;https://github.com/agentzh/echo-nginx-module/downloads&lt;/a&gt;&lt;br&gt;&lt;br&gt;This new feature was implemented by &lt;a href="https://github.com/dobe"&gt;Bernd Dorn&lt;/a&gt;. Many thanks to him ;)&lt;br&gt; &lt;p&gt;Bernd uses the nginx &lt;a href="http://www.grid.net.ru/nginx/upload.en.html"&gt;upload module&lt;/a&gt; &lt;a href="http://www.grid.net.ru/nginx/upload.en.html"&gt;&lt;/a&gt;to upload big files and he wants to issue a PUT  subrequest with the uploaded file to store the file somewhere else  based on its hash (hash generation is done by the upload module). So it&amp;#39;s nice to have something like a file option to replace  the &amp;quot;-b&amp;quot; option in the &lt;span style="font-family: courier new,monospace;"&gt;echo_subrequest&lt;/span&gt; directive like this:&lt;/p&gt;  &lt;p style="font-family: courier new,monospace;"&gt;      echo_subrequest PUT /some_upstream/$upload_file_md5 -f  $upload_tmp_path&lt;/p&gt;The echo module wraps lots of Nginx internal APIs for streaming input and  output, parallel/sequential subrequests, timers and sleeping, as well as  various meta data accessing. You can read the full documentation on the following wiki page:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/HttpEchoModule"&gt;http://wiki.nginx.org/HttpEchoModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;and you can always get the latest source code from GitHub:&lt;br&gt; &lt;br&gt;    &lt;a href="http://github.com/agentzh/echo-nginx-module"&gt;http://github.com/agentzh/echo-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;Happy echoing!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7863515430286151406?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7863515430286151406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7863515430286151406' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7863515430286151406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7863515430286151406'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/02/ngxecho-v035-ability-to-postput-local.html' title='ngx_echo v0.35: ability to POST/PUT local files as subrequest bodies'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6245260094018146027</id><published>2011-01-26T15:44:00.011+08:00</published><updated>2011-01-28T16:41:48.100+08:00</updated><title type='text'>Why nginx does not have an API reference</title><content type='html'>People keep asking me (and others) why there is no API reference for nginx internals. The answer is simple: it is still in flux and changing even in nginx's stable releases.&lt;br /&gt;&lt;br /&gt;For this reason, I won't work on such a reference and I bet Igor Sysoev and Maxim Dounin will not either. (Feel free to prove me wrong! :))&lt;br /&gt;&lt;br /&gt;Nginx 0.8.54 changed the meaning of the return values of rewrite-phase handlers, which made Valery's guide to phases out of date even before it was written:&lt;br /&gt;&lt;br /&gt; &lt;a href="http://www.nginxguts.com/2011/01/phases/"&gt;http://www.nginxguts.com/2011/01/phases/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;See my comment at the bottom of that article.&lt;br /&gt;&lt;br /&gt;This is not the only API change that is not backward compatible, rather, just a small example among many others.&lt;br /&gt;&lt;br /&gt;FWIW, the rewrite phase handlers do not even honor &lt;span style="font-family:courier new,monospace;"&gt;NGX_DONE&lt;/span&gt; nor &lt;span style="font-family:courier new,monospace;"&gt;NGX_AGAIN&lt;/span&gt; in the version range of 0.8.42 ~ 0.8.53. My mail to this list reporting this regression got completely ignored:&lt;br /&gt;&lt;br /&gt; &lt;a href="http://forum.nginx.org/read.php?29,103078,103078"&gt;http://forum.nginx.org/read.php?29,103078,103078&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Is it funny? Sure not ;)&lt;br /&gt;&lt;br /&gt;We've been adding more and more &lt;span style="font-family:courier new,monospace;"&gt;#if&lt;/span&gt;/&lt;span style="font-family:courier new,monospace;"&gt;#else&lt;/span&gt; craps to our modules' code just in the hope of being compatible with more and more versions of nginx. Let's count how many version checks in &lt;a href="http://wiki.nginx.org/NginxHttpEchoModule"&gt;ngx_echo&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt; $ ack '#if' src/|grep nginx_version|wc -l&lt;br /&gt;&lt;/span&gt; &lt;span style="font-family:courier new,monospace;"&gt; 11&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and that's the cost of making ngx_echo work with nginx 0.7.21 ~ 0.9.4.&lt;br /&gt;&lt;br /&gt;And the number is similar for &lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;ngx_lua&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt; $ ack '#if' src/|grep nginx_version|wc -l&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt; 10&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well, one has to invest enough time on the nginx source and trace &lt;span style="font-style: italic;"&gt;every&lt;/span&gt; new release carefully enough and prepare for API changes that may make your module even fail to compile :) Most of the API changes will not appear in the change log of the new nginx releases. Someone (IIRC, it was Marcus Clyne) had requested a change log for nginx C API changes on the list, but got ignored as always :)&lt;br /&gt;&lt;br /&gt;Anyway, this article should not be taken as a complaint, rather, it is just a report of the current status of nginx 3rd-party module/patch development. Yeah, it's the reality. If this post makes you feel the other way around, I apologize for that.&lt;br /&gt;&lt;br /&gt;We're currently maintaining dozens of nginx 3rd-party modules most of which were born in the 0.8.x era. Just some of them have been open-sourced. The maintenance work takes time, efforts and patience :) But still we've been trying very hard to optimize this process for fun, not only for maintaining existing modules but also for creating brand new ones ;)&lt;br /&gt;&lt;br /&gt;Hope you good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6245260094018146027?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6245260094018146027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6245260094018146027' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6245260094018146027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6245260094018146027'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/why-nginx-does-not-have-api-reference.html' title='Why nginx does not have an API reference'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2559570270609196475</id><published>2011-01-25T13:10:00.002+08:00</published><updated>2011-01-25T13:18:01.356+08:00</updated><title type='text'>ngx_headers_more v0.14: minor optimizations and fixes</title><content type='html'>I&amp;#39;m happy to announce the v0.14 release of our ngx_headers_more module which features some minor optimizations and bug fixes. You can download the tarball from the download page below:&lt;br /&gt;&lt;br /&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module/downloads"&gt;http://github.com/agentzh/headers-more-nginx-module/downloads&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;Here&amp;#39;s the complete change log for this version&lt;br /&gt; &lt;ul&gt;&lt;li&gt; now we postpone the rewrite phase handler only once rather than  on every main request previously. this will save some CPU cycles on  every request if &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#more_set_input_headers"&gt;more_set_input_headers&lt;/a&gt;  or &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#more_clear_input_headers"&gt;more_clear_input_headers&lt;/a&gt;  are used. &lt;/li&gt;&lt;li&gt; fixed two spots where we did not check against null pointers  when out of memory. &lt;/li&gt;&lt;li&gt; now we use the 2-clause bsd license instead. &lt;/li&gt;&lt;li&gt; various coding style fixes. &lt;/li&gt;&lt;/ul&gt;The ngx_headers_more module allows you to add, set, or clear any output or input header that you specify. This is an enhanced version of the standard headers module because it provides more utilities like resetting or clearing &amp;quot;builtin headers&amp;quot; like Content-Type, Content-Length, and Server. &lt;br /&gt; &lt;br /&gt;You can always get the latest source code from its project page on GitHub&lt;br /&gt;&lt;br /&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module"&gt;http://github.com/agentzh/headers-more-nginx-module&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and the full documentation from the nginx wiki&lt;br /&gt; &lt;br /&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2559570270609196475?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2559570270609196475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2559570270609196475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2559570270609196475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2559570270609196475'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/ngxheadersmore-v014-minor-optimizations.html' title='ngx_headers_more v0.14: minor optimizations and fixes'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-9163715339741558802</id><published>2011-01-24T18:30:00.002+08:00</published><updated>2011-01-24T18:37:36.924+08:00</updated><title type='text'>ngx_lua v0.1.4: ability to disable the Lua code cache</title><content type='html'>I&amp;#39;m delighted to announce the ngx_lua v0.1.4 release which features the ability to disable the Lua code cache to ease Lua development. You can get the release tarball from the download page:&lt;br /&gt;&lt;br /&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;By default, Lua code loaded into the ngx_lua module will be cached (the compiled/JIT&amp;#39;d form will be cached). So changing .lua files requires reloading or restarting the nginx server. From this release, we can use the following directive to disable the code cache:&lt;br /&gt; &lt;br /&gt;     lua_code_cache off;&lt;br /&gt;&lt;br /&gt;Then the Lua files referenced in set_by_lua_file, content_by_lua_file, access_by_lua_file, and rewrite_by_lua_file won&amp;#39;t be cached at all, and Lua&amp;#39;s &amp;quot;package.loaded&amp;quot; table will be cleared at every request&amp;#39;s entry point (such that Lua modules won&amp;#39;t be cached either). Developers can now enjoy the PHP-way, i.e., edit-and-refresh.&lt;br /&gt; &lt;br /&gt;But please note that Lua code inlined into nginx.conf like those specified by set_by_lua, content_by_lua, access_by_lua, and rewrite_by_lua will *always* be cached because only nginx knows how to parse nginx.conf and the only way to tell it to re-load the config file is to send a HUP signal to it or just to restart it from scratch.&lt;br /&gt; &lt;br /&gt;For now, ngx_lua does not support the &amp;quot;stat&amp;quot; mode like Apache&amp;#39;s mod_lua, but we will work on it in the future.&lt;br /&gt;&lt;br /&gt;This release also contains a small over-all optimization that the keys used for Lua code cache lookups are pre-calculated at config time wherever possible.&lt;br /&gt; &lt;br /&gt;The ngx_lua module embeds the Lua/LuaJIT interpreter into the nginx core  and integrates the powerful Lua threads (aka Lua coroutines) into the  nginx event model by means of nginx subrequests.&lt;br /&gt;&lt;br /&gt;You can get the latest source code and full documentation from the  ngx_lua&amp;#39;s project page:&lt;br /&gt;&lt;br /&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/"&gt;https://github.com/chaoslawful/lua-nginx-module/&lt;/a&gt;&lt;br /&gt;  &lt;br /&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-9163715339741558802?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/9163715339741558802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=9163715339741558802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/9163715339741558802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/9163715339741558802'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/ngxlua-v014-ability-to-disable-lua-code.html' title='ngx_lua v0.1.4: ability to disable the Lua code cache'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3262239538296116809</id><published>2011-01-18T12:36:00.002+08:00</published><updated>2011-01-18T16:58:25.936+08:00</updated><title type='text'>ngx_lua v0.1.3: improved Solaris and Mac portability</title><content type='html'>I&amp;#39;m delighted to announce that ngx_lua v0.1.3 has been released.&lt;br /&gt;&lt;br /&gt;You can download the tarball from the following download page:&lt;br /&gt;&lt;br /&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;In this version, we&amp;#39;ve improved the config-time detection logic for Solaris and Mac, and there&amp;#39;s success report on Solaris 11. Thanks the great help from Vladislav Manchev.&lt;br /&gt;&lt;br /&gt;There&amp;#39;s also some work for NetBSD/OpenBSD/FreeBSD systems from Piotr Sikora. *BSD folks are very welcome to try it out ;)&lt;br /&gt; &lt;br /&gt;Our main development and testing environment is 32-bit and 64-bit Linux though. Help for porting this module to more (exotic) systems will be highly appreciated as usual :)&lt;br /&gt;&lt;br /&gt;The ngx_lua module embeds the Lua/LuaJIT interpreter into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model by means of nginx subrequests.&lt;br /&gt;&lt;br /&gt;chaoslawful is currently working on the &amp;quot;cosocket&amp;quot; branch of ngx_lua that will emulate a common set of Lua socket API that will give you totally transparently non-blocking capability out of the box by means of a brand new upstream layer atop the nginx event model and no nginx subrequest overheads.&lt;br /&gt; &lt;br /&gt;You can get the latest source code and full documentation from the ngx_lua&amp;#39;s project page:&lt;br /&gt;&lt;br /&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module/"&gt;https://github.com/chaoslawful/lua-nginx-module/&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;Happy Lua and nginx.conf hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3262239538296116809?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3262239538296116809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3262239538296116809' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3262239538296116809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3262239538296116809'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/ngxlua-v013-improved-solaris-and-mac.html' title='ngx_lua v0.1.3: improved Solaris and Mac portability'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8949475433630870706</id><published>2011-01-13T20:01:00.001+08:00</published><updated>2011-01-13T20:01:12.486+08:00</updated><title type='text'>ngx_lua v0.1.2: rewrite_by_lua/access_by_lua fixes and new features</title><content type='html'>I&amp;#39;m happy to announce the v0.1.2 release of our ngx_lua module. You&lt;br&gt;&lt;div class="gmail_quote"&gt; can download the release tarball from the module&amp;#39;s download page:&lt;br&gt; &lt;br&gt;     &lt;a href="http://github.com/chaoslawful/lua-nginx-module/downloads" target="_blank"&gt;http://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt; This release contains the following changes:&lt;br&gt; &lt;br&gt;&lt;ul&gt;&lt;li&gt;Fixed a bug in rewrite_by_lua (introduced in ngx_lua v0.1.0) andaccess_by_lua (introduced in ngx_lua v0.1.1) that it always sent out default response headers even if there&amp;#39;s no user outputs in the rewrite/access Lua handlers. Thanks Roman Vasilyev.&lt;/li&gt; &lt;li&gt;The results returned from &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;ngx.location.capture&lt;/span&gt;&amp;quot; now support multi-value headers, like &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;Set-Cookie&lt;/span&gt;&amp;quot;. The value is a Lua(array) table that holds all the values in the order that they appear.&lt;br&gt; &lt;br&gt;For instance, if the subrequest response headers contains the following lines:&lt;br&gt;&lt;/li&gt;&lt;/ul&gt; &lt;span style="font-family: courier new,monospace;"&gt;       Set-Cookie: a=3&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       Set-Cookie: foo=bar&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       Set-Cookie: baz=blah&lt;/span&gt;&lt;br&gt;&lt;br&gt;      Then res.header[&amp;quot;Set-Cookie&amp;quot;] will be evaluted to the table value &lt;span style="font-family: courier new,monospace;"&gt;{&amp;quot;a=3&amp;quot;, &amp;quot;foo=bar&amp;quot;, &amp;quot;baz=blah&amp;quot;}&lt;/span&gt;.  Thanks neilljordan ( &lt;a href="https://github.com/neilljordan/" target="_blank"&gt;https://github.com/neilljordan/&lt;/a&gt; ).&lt;br&gt;  &lt;ul&gt;&lt;li&gt;&lt;span style="font-family: courier new,monospace;"&gt;rewrite_by_lua_file&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;access_by_lua_file&lt;/span&gt;, and &lt;span style="font-family: courier new,monospace;"&gt;content_by_lua_file&lt;/span&gt; now support nginx variables in the path value. For example:&lt;br&gt; &lt;/li&gt;&lt;/ul&gt; &lt;span style="font-family: courier new,monospace;"&gt;       # use nginx var in code path&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     # WARN: contents in nginx var must be carefully filtered,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;     # otherwise there&amp;#39;ll be great security risk!&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     location ~ ^/app/(.+) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;         content_by_lua_file /path/to/lua/app/root/$1.lua;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br&gt;   &lt;span style="font-family: courier new,monospace;"&gt;&lt;/span&gt;  Thanks Xiaozhe Wang (chaoslawful).&lt;br&gt; &lt;ul&gt;&lt;li&gt;Fixed support for HTTP 1.0 requests.&lt;br&gt;&lt;br&gt;Sometimes you may want to use nginx&amp;#39;s standard ngx_proxy module to proxy requests to another nginx machine configured by a location with &lt;span style="font-family: courier new,monospace;"&gt;content_by_lua&lt;/span&gt;. Because &lt;span style="font-family: courier new,monospace;"&gt;proxy_pass&lt;/span&gt; only supports the HTTP 1.0 protocol, we have to know the length of your response body and set the &lt;span style="font-family: courier new,monospace;"&gt;Content-Length&lt;/span&gt; header before emitting any data out. &lt;span style="font-family: courier new,monospace;"&gt;ngx_lua&lt;/span&gt; will automatically recognize HTTP 1.0 requests and try to send out an appropriate &lt;span style="font-family: courier new,monospace;"&gt;Content-Length&lt;/span&gt; header for you, at the first invocation of &lt;span style="font-family: courier new,monospace;"&gt;ngx.print()&lt;/span&gt; and &lt;span style="font-family: courier new,monospace;"&gt;ngx.say()&lt;/span&gt;, assuming all the response body data is in a single call of &lt;span style="font-family: courier new,monospace;"&gt;ngx.print()&lt;/span&gt; or &lt;span style="font-family: courier new,monospace;"&gt;ngx.say()&lt;/span&gt;.&lt;br&gt; &lt;br&gt;So if you want to support HTTP 1.0 clients like &lt;span style="font-family: courier new,monospace;"&gt;ngx_proxy&lt;/span&gt;, do not call &lt;span style="font-family: courier new,monospace;"&gt;ngx.print()&lt;/span&gt; or &lt;span style="font-family: courier new,monospace;"&gt;ngx.say()&lt;/span&gt; multiple times, try buffering the output data yourself wherever needed. This behavior is the same as the &lt;span style="font-family: courier new,monospace;"&gt;ngx_echo&lt;/span&gt; module.&lt;br&gt; &lt;/li&gt;&lt;/ul&gt;  Please also note that &lt;span style="font-family: courier new,monospace;"&gt;rewrite_by_lua&lt;/span&gt; will *not* work with nginx 0.8.41 ~ 0.8.53.&lt;br&gt; &lt;br&gt; Because the rewrite_by_lua and access_by_lua directives are very new, be prepared to hit some hidden bugs. And you&amp;#39;re very welcome to report any issues that you meet on your side.&lt;br&gt; &lt;br&gt; ngx_lua is an nginx C module that embeds the Lua or LuaJIT interpreter into the nginx core and you can find the latest source code and the complete documentation here&lt;br&gt; &lt;br&gt;    &lt;a href="https://github.com/chaoslawful/lua-nginx-module" target="_blank"&gt;https://github.com/chaoslawful/lua-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt; Have fun!&lt;br&gt; &lt;font color="#888888"&gt; &lt;/font&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8949475433630870706?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8949475433630870706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8949475433630870706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8949475433630870706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8949475433630870706'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/ngxlua-v012-rewritebyluaaccessbylua.html' title='ngx_lua v0.1.2: rewrite_by_lua/access_by_lua fixes and new features'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1689303555233607735</id><published>2011-01-13T19:44:00.001+08:00</published><updated>2011-01-13T19:44:16.838+08:00</updated><title type='text'>My fork of ngx_eval 2011.01.12 released</title><content type='html'>&lt;div class="gmail_quote"&gt; People have been reporting issues of my fork of &lt;span style="font-family: courier new,monospace;"&gt;ngx_eval&lt;/span&gt; when using it with recent versions of nginx. I&amp;#39;ve updated it to version 2011.01.12 to compatible with nginx 0.8.54+:&lt;br&gt;  &lt;br&gt;     &lt;a href="https://github.com/agentzh/nginx-eval-module/downloads" target="_blank"&gt;https://github.com/agentzh/nginx-eval-module/downloads&lt;/a&gt;&lt;br&gt; &lt;br&gt; Now &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;eval_subrequest_in_memory&lt;/span&gt;&amp;quot; is off by default. Because &lt;span style="font-family: courier new,monospace;"&gt;subrequest_in_memory&lt;/span&gt; mode is still having issues.&lt;br&gt;  &lt;br&gt; Here&amp;#39;s a small example for using ngx_eval with my ngx_redis2, an nginx upstream module that supports almost the full Redis 2.0 unified wire protocol:&lt;br&gt; &lt;br&gt;  &lt;span style="font-family: courier new,monospace;"&gt;  location /foo {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        eval_override_content_type &amp;#39;application/octet-stream&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        eval_subrequest_in_memory off;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        eval $res {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            redis2_literal_raw_query &amp;#39;set one 5\r\nfirst\r\n&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            redis2_pass &lt;/span&gt;&lt;a style="font-family: courier new,monospace;" href="http://127.0.0.1:6379" target="_blank"&gt;127.0.0.1:6379&lt;/a&gt;&lt;span style="font-family: courier new,monospace;"&gt;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        echo [$res];&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br&gt; &lt;br&gt; Accessing /foo with curl yields&lt;br&gt; &lt;br&gt;  &lt;span style="font-family: courier new,monospace;"&gt;  [+OK&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    ]&lt;/span&gt;&lt;br&gt; &lt;br&gt; on my side.&lt;br&gt; &lt;br&gt; Please ensure that you&amp;#39;re using nginx 0.8.54+ and the latest version of my fork of ngx_eval (at lease 2010.12.29+ is required).&lt;br&gt; &lt;br&gt; If you find any issues, please let me know.&lt;br&gt; &lt;br&gt; Special thanks go to Valery Kholodkov for creating &lt;span style="font-family: courier new,monospace;"&gt;ngx_eval&lt;/span&gt; in the first place.&lt;br&gt; &lt;br&gt;P.S. Still, it&amp;#39;s recommended to use &lt;span style="font-family: courier new,monospace;"&gt;ngx_lua&lt;/span&gt; module&amp;#39;s &lt;span style="font-family: courier new,monospace;"&gt;rewrite_by_lua&lt;/span&gt; or &lt;span style="font-family: courier new,monospace;"&gt;access_by_lua&lt;/span&gt; directives combined by the &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;ngx.location.capture&lt;/span&gt;&amp;quot; API to do what my fork of &lt;span style="font-family: courier new,monospace;"&gt;ngx_eval&lt;/span&gt; has been doing.&lt;br&gt;  &lt;/div&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1689303555233607735?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1689303555233607735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1689303555233607735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1689303555233607735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1689303555233607735'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/my-fork-of-ngxeval-20110112-released.html' title='My fork of ngx_eval 2011.01.12 released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-514026794147277500</id><published>2011-01-13T19:33:00.001+08:00</published><updated>2011-01-13T19:33:43.247+08:00</updated><title type='text'>ngx_lua v0.1.1: access_by_lua and access_by_lua_file landed</title><content type='html'>After the first public release of ngx_lua, I&amp;#39;m proud to annouce the v0.1.1 version, which has introduced the &lt;span style="font-family: courier new,monospace;"&gt;access_by_lua&lt;/span&gt; and &lt;span style="font-family: courier new,monospace;"&gt;access_by_lua_file&lt;/span&gt; directives:&lt;br&gt; &lt;br&gt;   &lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;br&gt;&lt;br&gt;Now we can code up our own nginx access-phase handlers directly in pure Lua, with all the capabilities with &lt;span style="font-family: courier new,monospace;"&gt;rewrite_by_lua&lt;/span&gt; and &lt;span style="font-family: courier new,monospace;"&gt;content_by_lua&lt;/span&gt;, like firing up subrequests to other locations, reading/writing nginx variables, changing response headers, internal redirection, HTTP 301/302 redirection, throwing out 403/500/etc error pages, and etc etc etc.&lt;br&gt; &lt;br&gt;Here&amp;#39;s a small example that emulates &lt;span style="font-family: courier new,monospace;"&gt;ngx_auth_request&lt;/span&gt;&amp;#39;s functionality in pure Lua:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location / {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       access_by_lua &amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           local res = ngx.location.capture(&amp;quot;/auth&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           if res.status == ngx.HTTP_OK then&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;               return&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           end&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           if res.status == ngx.HTTP_FORBIDDEN then&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;               ngx.exit(res.status)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           end&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;           ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       &amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       # proxy_pass/fastcgi_pass/postgres_pass/...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt; &lt;br&gt;which is approximately equivalent to&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location / {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       auth_request /auth;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       # proxy_pass/fastcgi_pass/postgres_pass/...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt; &lt;br&gt;except that &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;auth_request&lt;/span&gt;&amp;quot; runs at the beginning of the nginx access phase while &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;access_by_lua&lt;/span&gt;&amp;quot; runs at the end of the access phase.&lt;br&gt; &lt;br&gt;ngx_lua is an nginx C module that embeds the Lua or LuaJIT interpreter into the nginx core and you can find the latest source code and the complete documentation here&lt;br&gt;&lt;br&gt;   &lt;a href="https://github.com/chaoslawful/lua-nginx-module"&gt;https://github.com/chaoslawful/lua-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-514026794147277500?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/514026794147277500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=514026794147277500' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/514026794147277500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/514026794147277500'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/ngxlua-v011-accessbylua-and.html' title='ngx_lua v0.1.1: access_by_lua and access_by_lua_file landed'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5266698603297117302</id><published>2011-01-13T19:19:00.001+08:00</published><updated>2011-01-13T19:19:11.073+08:00</updated><title type='text'>ngx_lua v0.1.0: scripting nginx with Lua</title><content type='html'>I&amp;#39;m happy to announce the first public release of the ngx_lua module, v0.1.0:&lt;p&gt;&amp;#160; &amp;#160;&lt;a href="https://github.com/chaoslawful/lua-nginx-module/downloads"&gt;https://github.com/chaoslawful/lua-nginx-module/downloads&lt;/a&gt;&lt;p&gt;ngx_lua This module embeds the Lua/LuaJIT interpreter into the nginx&lt;br&gt;core and integrates the powerful Lua threads (aka Lua coroutines) into&lt;br&gt;the nginx event model by means of nginx subrequests.&lt;p&gt;Unlike Apache&amp;#39;s mod_lua and Lighttpd&amp;#39;s mod_magnet, Lua code written&lt;br&gt;atop this module can be 100% non-blocking on network traffic as long&lt;br&gt;as you use the ngx.location.capture interface to let the nginx core do&lt;br&gt;all your requests to mysql, postgresql, memcached, redis, upstream&lt;br&gt;http web services, and etc etc etc (see ngx_drizzle, ngx_postgres,&lt;br&gt;ngx_memc, ngx_redis2, and ngx_proxy modules for details).&lt;p&gt;You can find the latest source code as well as the latest documentation here:&lt;p&gt;&amp;#160; &amp;#160;&lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;http://github.com/chaoslawful/lua-nginx-module&lt;/a&gt;&lt;p&gt;We&amp;#39;ve already run ngx_lua as well as dozens of other nginx C modules&lt;br&gt;in Taobao.com&amp;#39;s web applications for months and this module is&lt;br&gt;considered production ready.&lt;p&gt;With ngx_lua, it&amp;#39;s now possible to construct true C10K-capable web&lt;br&gt;applications because everything can be trivially made non-blocking,&lt;br&gt;not only the network traffic between the clients, but also the traffic&lt;br&gt;to the backends like RDBMS and memcached clusters. And we&amp;#39;ve been&lt;br&gt;working hard to make it a much better substitution for traditional web&lt;br&gt;development solutions like PHP, not only in terms of performance, but&lt;br&gt;also ease of use.&lt;p&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5266698603297117302?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5266698603297117302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5266698603297117302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5266698603297117302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5266698603297117302'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2011/01/ngxlua-v010-scripting-nginx-with-lua.html' title='ngx_lua v0.1.0: scripting nginx with Lua'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-9156563633175688184</id><published>2010-11-06T18:01:00.001+08:00</published><updated>2010-11-06T18:01:56.635+08:00</updated><title type='text'>Video for my ngx_openresty talk on ECUG 2010</title><content type='html'>I gave a (Chinese) talk regarding ngx_openresty (aka nginx.conf scripting) at &lt;a href="http://ecug.org/2010:agenda"&gt;ECUG 2010&lt;/a&gt; in the last month. Here&amp;#39;s the video for the talk:&lt;br&gt;&lt;br&gt;    &lt;a href="http://v.ku6.com/show/D00rqtnRwKzJdIsB.html"&gt;http://v.ku6.com/show/D00rqtnRwKzJdIsB.html&lt;/a&gt;&lt;br&gt; &lt;br&gt;The slides can be viewed in a web browser from here:&lt;br&gt;&lt;br&gt;    &lt;a href="http://agentzh.org/misc/slides/nginx-state-of-the-art/"&gt;http://agentzh.org/misc/slides/nginx-state-of-the-art/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Please use the arrow keys on your keyboard to switch pages in the slides.&lt;br&gt; &lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-9156563633175688184?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/9156563633175688184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=9156563633175688184' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/9156563633175688184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/9156563633175688184'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/11/video-for-my-ngxopenresty-talk-on-ecug.html' title='Video for my ngx_openresty talk on ECUG 2010'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3686569719192511040</id><published>2010-10-28T12:14:00.001+08:00</published><updated>2010-10-28T12:14:29.343+08:00</updated><title type='text'>ngx_memc v0.11 released: small bug fixes and more documentation</title><content type='html'>I&amp;#39;ve just released the v0.11 version of our ngx_memc module:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/memc-nginx-module/tarball/v0.11"&gt;http://github.com/agentzh/memc-nginx-module/tarball/v0.11&lt;/a&gt;&lt;br&gt;&lt;br&gt;This version applies the patch from iframist, fixing the zero size buf alert in error.log when $memc_value is set to empty (&amp;quot;&amp;quot;).&lt;br&gt; &lt;br&gt;The ngx_memc module extends the standard memcached module to support almost the whole memcached &lt;a href="http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt"&gt;ascii protocol&lt;/a&gt;. And it can be used with either the standard memcached server or other backends supporting the memcached wire protocol like &lt;a href="http://fallabs.com/tokyotyrant/"&gt;TokyoTyrant&lt;/a&gt;.&lt;br&gt; &lt;br&gt;Maxim Dounin&amp;#39;s excellent &lt;a href="http://mdounin.ru/hg/ngx_http_upstream_keepalive/"&gt;ngx_http_upstream_keepalive&lt;/a&gt; module can also be used with this module to provide a powerful connection pool for memcached.&lt;br&gt; &lt;br&gt;See ngx_memc&amp;#39;s wiki page for more details:&lt;br&gt;&lt;br&gt;   &lt;a href="http://wiki.nginx.org/HttpMemcModule"&gt;http://wiki.nginx.org/HttpMemcModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;I&amp;#39;ve also updated the wiki page for this release and documented various directives like memc_connect_timeout, memc_read_timeout, memc_send_timeout, and memc_buffer_size. (These directives are inherited directly from the standard memcached module.)&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3686569719192511040?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3686569719192511040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3686569719192511040' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3686569719192511040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3686569719192511040'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/10/ngxmemc-v011-released-small-bug-fixes.html' title='ngx_memc v0.11 released: small bug fixes and more documentation'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1273883254985584202</id><published>2010-09-26T15:10:00.001+08:00</published><updated>2010-09-26T15:10:56.724+08:00</updated><title type='text'>淘宝（北京）量子团队的实习机会</title><content type='html'>&lt;div class="gmail_quote"&gt;&lt;div class="gmail_quote"&gt;&lt;div class="gmail_quote"&gt;&lt;div&gt;&lt;div&gt;我们是阿里巴巴淘宝网（北京）数据平台部门的量子团队（ &lt;a href="http://lz.taobao.com" target="_blank"&gt;http://lz.taobao.com&lt;/a&gt; ），我们正在寻找有想法有激情的同学到我们团队来实习。&lt;br&gt;&lt;br&gt;我们目前的几个实习岗位近期的主要工作包括&lt;br&gt; &lt;/div&gt;&lt;ul&gt; &lt;li&gt;基于 hive/hadoop 的数据仓库系统的自动化测试的方法研究和实施（Perl 5, PostgreSQL/mysql, Hive/Java）&lt;/li&gt;&lt;div&gt; &lt;li&gt;在数据产品的在线应用（Online Application）中进行 hive 计算任务的提交和异步执行的管理&lt;/li&gt; &lt;/div&gt;&lt;li&gt;基于 nginx 和 ngx_openresty 的数据 web service 平台的完善（C, Lua, Erlang, 以及我们自主设计的 LZSQL 语言）&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;感兴趣的同学可以在我的个人博客上找到更多的细节：&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://agentzh.spaces.live.com" target="_blank"&gt;http://agentzh.spaces.live.com&lt;/a&gt;&lt;br&gt;  &lt;br&gt;我们对学校、学历和专业都没有要求，因为我们相信真正有潜质的人并不必出自名牌大学，也不必是科班出身。我们也不会要求有很深很广的知识和技术背景，毕竟我们这里更多的是使用或者自己创造全新的知识和技术。我们看重的主要是&lt;br&gt;&lt;ul&gt;&lt;li&gt;有很强的求知欲和好奇心，对新事物和新想法有浓厚的兴趣，并愿意为之付出很大的努力，经常自己搞点有趣的事情玩&lt;/li&gt;  &lt;li&gt;同时有坚持力，愿意沉下心系统地学习一些学科、理论和技术细节，有耐心，能耐得住寂寞&lt;/li&gt;&lt;li&gt;拥有较好英语功底，可以无障碍地大量阅读英文文档和其他资料&lt;/li&gt;&lt;li&gt;能有较长较为稳定的实习期（6 个月以上），因为许多重要的工作需要足够长的时间才能达到足够的深度和广度&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;下面是我们觉得胜任此工作所必需具备的技术上的基本技能&lt;br&gt;&lt;ul&gt;&lt;li&gt;经常在 Linux 或者其他 *NIX 环境中工作，熟悉 shell 和命令行&lt;br&gt;   &lt;/li&gt;&lt;li&gt;经常使用像 vim 和 emacs 这样的文本编辑器&lt;/li&gt;&lt;li&gt;有比较好的 ANSI C 编程的基础&lt;/li&gt;&lt;li&gt;熟悉至少一门动态的脚本语言，比如 Perl 或者 Python&lt;br&gt;&lt;/li&gt;&lt;li&gt;曾经使用过某一种版本控制系统，例如 git 或者 subversion&lt;/li&gt;&lt;li&gt;熟悉至少一种 make 性质的项目构造和管理工具，例如 GNU make&lt;br&gt;&lt;/li&gt;&lt;li&gt;熟悉 SQL 语言和某一种 RDBMS，例如 mysql 或者 PostgreSQL&lt;br&gt;   &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;我们能提供和一直倡导的主要是&lt;br&gt;&lt;ul&gt;&lt;div&gt;&lt;li&gt;比较宽松的工作氛围和学习氛围&lt;/li&gt;&lt;li&gt;比较细致的技术指导和支持&lt;/li&gt;&lt;li&gt; 激进但不失必要谨慎的新技术的调研与生产应用&lt;/li&gt;&lt;li&gt;通过自己设计语言和工具，变无聊的体力活为有趣的创造性的事情&lt;/li&gt;&lt;/div&gt;&lt;li&gt;这个实习岗位工作会像正式员工的工作一样有趣，一样富有挑战&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;我们的办公地点在：北京市朝阳区东三环北街 38 号院 1 号楼泰康金融大厦 25 层。&lt;br&gt;&lt;br&gt;如果你对我们这个实习岗位感兴趣，请将你的简历通过电子信箱发送到我的信箱： chunlai at taobao dot com，并确保邮件标题中出现&amp;ldquo;应聘&amp;rdquo;这两个字，便我能及时看到 :)&lt;br&gt;  &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;/div&gt; &lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1273883254985584202?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1273883254985584202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1273883254985584202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1273883254985584202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1273883254985584202'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/09/blog-post.html' title='淘宝（北京）量子团队的实习机会'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4493225251289080719</id><published>2010-09-15T11:21:00.010+08:00</published><updated>2011-02-22T17:27:19.911+08:00</updated><title type='text'>LZSQL compiler hacking and future VoltDB applications</title><content type='html'>We've been working &lt;span class="il"&gt;on&lt;/span&gt; a compiler for our own language named "&lt;span class="il"&gt;lzsql&lt;/span&gt;". It's for our web service platform that drives our data product &lt;a href="http://lz.taobao.com/" target="_blank"&gt;lz.taobao.com&lt;/a&gt;. Our "&lt;span class="il"&gt;lzsql&lt;/span&gt;" compiler can now emit lua code that has passed lots of real world tests.&lt;br /&gt;&lt;br /&gt;We can now decide whether to run a sql query at a remote mysql node or at the nginx core, all in the &lt;span class="il"&gt;lzsql&lt;/span&gt; language.&lt;br /&gt;&lt;br /&gt;For "local sql queries", we've implemented a full-fledged sql engine in pure lua. It's damn fast, especially using &lt;a href="http://luajit.org/luajit.html" target="_blank"&gt;LuaJIT&lt;/a&gt;. 6k q/s for a single nginx worker process is not uncommon in our benchmark.&lt;br /&gt;&lt;br /&gt;And we've introduced a type system in our language such that it can handle sql quoting rules automatically. The typechecker can ensure that a &lt;span class="il"&gt;lzsql&lt;/span&gt; variable with a specific type is used correctly in the context of the sql query. The sql language is part of the language anyway. Therefore, sql injection cannot happen.&lt;br /&gt;&lt;br /&gt;We mostly use the "local sql engine" for merging data from completely different data sources, like those from both mysql and a non-relational data source. We do have some non-relational data sources like our real time stats services and other Java-powered web services from other departments of &lt;a href="http://www.taobao.com/" target="_blank"&gt;Taobao.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here's a small example:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new,monospace;"&gt;    text $pattern;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;    location $mysql_node;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;@a := select count(id) as count&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;      &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;from cats&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;      &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;where name contains $pattern&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;      &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;      group by park&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;    &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;      &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;at $mysql_node;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style="font-family:courier new,monospace;"&gt;   @b := select count(id) as count&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;  &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;        &lt;/span&gt;&lt;span style="font-family:courier new,monospace;"&gt;from other_service.some_api($&lt;wbr&gt;pattern&lt;span style="font-family: monospace;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;          group by park;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;    return (@a union all @b);&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;In this sample, "&lt;span style="font-family:courier new,monospace;"&gt;other_service.some_api&lt;/span&gt;" is a non-blocking call to some remote non-relational data source. And the first SQL query is run &lt;span class="il"&gt;on&lt;/span&gt; a remote mysql node specified by the variable $mysql_node while the last two are both running directly in the nginx core by our sql engine written in Lua.&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;.&lt;span class="il"&gt;lzsql&lt;/span&gt;&lt;/i&gt; source file is compiled down to (very compact) Lua code before deploying to our production servers. Because it is a true compiler, we use Perl 5, one of the not-so-fast scripting languages, to implement the whole compiler (approximately 3k lines of hand-written code). Perl modules like &lt;a href="http://search.cpan.org/perldoc?Moose" target="_blank"&gt;Moose&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?Parse::RecDescent" target="_blank"&gt;Parse::Descent&lt;/a&gt; has made the compiler construction process quite enjoyable :)&lt;br /&gt;&lt;br /&gt;In the future, the &lt;span class="il"&gt;lzsql&lt;/span&gt; compiler is also expected to optimize the sql queries automatically for specific remote sql engine, like mysql's.&lt;br /&gt;&lt;br /&gt;The &lt;span class="il"&gt;lzsql&lt;/span&gt; compiler will be eventually be released under an opensource license with the name "&lt;i&gt;RestyScript&lt;/i&gt;" when we decouple those our specific business logic from the compiler. For now, we hardcode some business logic into the compiler for the sake of convenience. We're going to move them into compiler or language plugins and make the &lt;span class="il"&gt;lzsql&lt;/span&gt; toolchain more general.&lt;br /&gt;&lt;br /&gt;My intern students become very productive when they start using the &lt;span class="il"&gt;lzsql&lt;/span&gt; language ;) The old system they're replacing is written in tons of ugly php, oh well ;) we've cut 90% of the codebase size and also got 20 ~ 30 times faster :D&lt;br /&gt;&lt;br /&gt;We're also puting our heads around &lt;a href="http://voltdb.com/" target="_blank"&gt;VoltDB&lt;/a&gt;, a really nice memory database. And we're also looking forward to rewriting our "real time stats services" mentioned above using VoltDB and Erlang or Lua or etc. An nginx upstream module for the VoltDB binary protocol is also &lt;span class="il"&gt;on&lt;/span&gt; chaoslawful's and my TODO list.&lt;br /&gt;&lt;br /&gt;The only sad part regarding VoltDB is that it's written in Java, but it's not a very big issue for us. It has some ugly limitations regarding its sql and interfaces, but we can work around those details &lt;span class="il"&gt;on&lt;/span&gt; the level of our &lt;span class="il"&gt;lzsql&lt;/span&gt; language and just use it (combined with java) as the runtime.&lt;br /&gt;&lt;br /&gt;It's already starting to become more and more interesting :)&lt;br /&gt;&lt;br /&gt;Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4493225251289080719?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4493225251289080719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4493225251289080719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4493225251289080719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4493225251289080719'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/09/lzsql-compiler-hacking-and-future.html' title='LZSQL compiler hacking and future VoltDB applications'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2162354401996753475</id><published>2010-09-05T18:42:00.001+08:00</published><updated>2010-09-05T18:42:06.834+08:00</updated><title type='text'>ngx_lua module updated</title><content type='html'>chaoslawful++ has just added several new features to our ngx_lua module. Checkout his blog article for details:&lt;br&gt;&lt;br&gt;    &lt;a href="http://chaoslawful.javaeye.com/blog/755013"&gt;http://chaoslawful.javaeye.com/blog/755013&lt;/a&gt;&lt;br&gt; &lt;br&gt;ngx_lua embeds the power of the Lua language into the nginx core and can be used to construct high performance web services and web applications:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;http://github.com/chaoslawful/lua-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;Happy lua hacking! :D&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2162354401996753475?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2162354401996753475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2162354401996753475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2162354401996753475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2162354401996753475'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/09/ngxlua-module-updated.html' title='ngx_lua module updated'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2164781357024693749</id><published>2010-09-02T16:15:00.001+08:00</published><updated>2010-09-02T16:15:24.877+08:00</updated><title type='text'>ngx_set_misc v0.14: extending ngx_rewrite's "set" directive</title><content type='html'>I&amp;#39;m happy to announce the first public release of our Taobao.com ngx_set_misc module, v0.14.&lt;br&gt;&lt;br&gt;ngx_set_misc is an nginx module that extends the standard ngx_rewrite module&amp;#39;s &amp;quot;set&amp;quot; directive to support various advanced functionalities like MD5, SHA1, json/mysql/postgresql string literal quoting, URI escaping/unescaping, default variable value assignment, upstream hashing based on a custom key, base32 encoding/decoding, and more :)&lt;br&gt; &lt;br&gt;Please see the project homepage for more details:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/set-misc-nginx-module"&gt;http://github.com/agentzh/set-misc-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;And the release tarball can be downloaded from&lt;br&gt; &lt;br&gt;    &lt;a href="http://github.com/agentzh/set-misc-nginx-module/tarball/v0.14"&gt;http://github.com/agentzh/set-misc-nginx-module/tarball/v0.14&lt;/a&gt;&lt;br&gt;&lt;br&gt;Various (funny) use cases can be found in my &amp;quot;nginx.conf scripting&amp;quot; talk&amp;#39;s slides:&lt;br&gt; &lt;br&gt;    &lt;a href="http://agentzh.org/misc/slides/nginx-conf-scripting/"&gt;http://agentzh.org/misc/slides/nginx-conf-scripting/&lt;/a&gt;  (use the arrow keys on your keyboard to switch pages)&lt;br&gt;&lt;br&gt;I must thank my colleagues shrimp and calio for their work on polishing this module in the last few months.&lt;br&gt; &lt;br&gt;This module won&amp;#39;t be possible if Marcus Clyne does not publish his crazy Nginx Development Kit (NDK) project:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/simpl-it/ngx_devel_kit"&gt;http://github.com/simpl-it/ngx_devel_kit&lt;/a&gt;&lt;br&gt; &lt;br&gt;And it&amp;#39;s a prerequisite for this module :)&lt;br&gt;&lt;br&gt;I know that this module has a really terrible name, but it&amp;#39;s been there for months already :P&lt;br&gt;&lt;br&gt;We&amp;#39;ve been using it extensively in our products of Taobao.com. And Qunar.com is also using it heavily in their production environment.&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2164781357024693749?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2164781357024693749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2164781357024693749' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2164781357024693749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2164781357024693749'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/09/ngxsetmisc-v014-extending-ngxrewrites.html' title='ngx_set_misc v0.14: extending ngx_rewrite&apos;s &quot;set&quot; directive'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7313498700436893138</id><published>2010-09-02T15:51:00.001+08:00</published><updated>2010-09-02T15:51:32.282+08:00</updated><title type='text'>ngx_drizzle v0.0.12: better timeout control</title><content type='html'>Hi, folks!&lt;br&gt;&lt;br&gt;I&amp;#39;m delighted to announce the v0.0.12 release of ngx_drizzle, a non-blocking upstream module that helps nginx talk directly to mysql, drizzle, and sqlite3 servers (and with an optional connection pool). The project source repository and the homepage is on GitHub:&lt;br&gt; &lt;br&gt;    &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;http://github.com/chaoslawful/drizzle-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;and the release tarball can be downloaded from&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module/tarball/v0.0.12"&gt;http://github.com/chaoslawful/drizzle-nginx-module/tarball/v0.0.12&lt;/a&gt;&lt;br&gt; &lt;br&gt;This release has the highlight of several new config directives that control the various timeout settings used by ngx_drizzle:&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  drizzle_connect_timeout &amp;lt;time&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   drizzle_send_query_timeout &amp;lt;time&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   drizzle_recv_cols_timeout &amp;lt;time&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;   drizzle_recv_rows_timeout &amp;lt;time&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;The default timeout values for them are all &amp;quot;60 s&amp;quot;, i.e., 60 seconds, which may be too long for many real world applications.&lt;br&gt; &lt;br&gt;Thanks my colleague shrimp++ for testing them and fixing bugs in the original (undocumented) implementation :)&lt;br&gt;&lt;br&gt;Also thanks Piotr Sikora for his tireless improving the test suite to fit our grand test build farm and his fixes for the recent nginx 0.8.47+ releases.&lt;br&gt; &lt;br&gt;As always, special thanks go to my colleague and closest friend, chaoslawful++, for creating such an excellent module in the first place ;)&lt;br&gt;&lt;br&gt;FWIW, we&amp;#39;re already using this module (combined with ngx_rds_json as well as many other modules) in production, in particular, the Taobao.com LiangZi Shop Stats website:&lt;br&gt; &lt;br&gt;    &lt;a href="http://lz.taobao.com/"&gt;http://lz.taobao.com/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt;-agentzh&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7313498700436893138?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7313498700436893138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7313498700436893138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7313498700436893138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7313498700436893138'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/09/ngxdrizzle-v0012-better-timeout-control.html' title='ngx_drizzle v0.0.12: better timeout control'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2161984116908909358</id><published>2010-08-19T11:24:00.001+08:00</published><updated>2010-08-19T11:24:15.187+08:00</updated><title type='text'>cheater: yet another rule-driven tool to generate random databases</title><content type='html'>&lt;p&gt;cheater 是我前一阵子开发的规则驱动的随机数据库生成器，是量子开发、测试工具链的组成部分。 &lt;/p&gt;&lt;p&gt;cheater  已在量子店铺统计的前端开发中得到了广泛的使用，为前端开发提供大量的指定模式的伪造数据，从而大大减轻了对后端和真实数据的依赖，同时也可以得到比较理想的数据覆盖率。 &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;cheater 工具的源码仓库位于下面这个位置： &lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://github.com/agentzh/cheater/" target="_top"&gt;http://github.com/agentzh/cheater/&lt;/a&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt;相比我们 QA 部门的 xdata，Ruby 世界的 &lt;a href="http://faker.rubyforge.org/"&gt;faker&lt;/a&gt; 和 Perl 世界的 &lt;a href="http://search.cpan.org/perldoc?Data::Faker"&gt;Data::Faker&lt;/a&gt; 等同类型的工具，cheater  具有以下优点： &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;ol&gt;&lt;li&gt; 能自动处理表间的关联和外键约束，因此是真正的&amp;ldquo;数据库实例生成器&amp;rdquo; &lt;/li&gt;&lt;li&gt; 定义了一种类 SQL 的小语言来表达期望生成的数据模型 &lt;/li&gt;&lt;li&gt; 支持强大的 {a, b, c} 离散集合，数值/时间/日期区间记法 a..b，Perl 正则表达式模式  /regex/，常量值 &amp;#39;string&amp;#39;, 1.32 等方式来表达数据字段的值域 &lt;/li&gt;&lt;li&gt; 能直接生成 JSON 或者 SQL insert 语句，便于导入到 mysql/Pg 等数据库或者 hive 等其他系统 &lt;/li&gt;&lt;/ol&gt;  &lt;p&gt; 下面是一个很简单的示例，演示其基本用法。 &lt;/p&gt;&lt;p&gt; 我们首先在一个工作目录（比如 ~/work/ 下）新建一个 .cht 文件，用来描述我们想生成的数据模型。假设我们有一个 company.cht  文件： &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;span style="font-family: courier new,monospace;"&gt;    # Empolyee table&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    table employees (&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        id serial;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        name text /[A-Z]a-z{2,5} [A-Z]a-z{2,7}/ not null unique;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        age integer 18..60 not null;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        tel text /1[35]8\d{8}/;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        birthday date;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        height real 1.50 .. 1.90 not null;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        grades text {&amp;#39;A&amp;#39;,&amp;#39;B&amp;#39;,&amp;#39;C&amp;#39;,&amp;#39;D&amp;#39;,&amp;#39;E&amp;#39;} not null;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        department references &lt;a href="http://departments.id"&gt;departments.id&lt;/a&gt;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    )&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    # Department table&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    table departments (&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        id serial;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        name text /\w{2,10}/ not null;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    )&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    10 employees;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    2 departments;&lt;/span&gt;&lt;br&gt; &lt;/pre&gt; &lt;p&gt; 这里我们使用的是 cheater 自己的小语言，其含义几乎是一眼就明了的，特别地，最后两行是说随机生成符合规则的 10 条 employees  表的记录和 2 条 departments 表的记录。 &lt;/p&gt;&lt;p&gt; 然后我们使用 cht-compile 命令来编译我们的 company.cht 生成随机的数据库实例： &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;span style="font-family: courier new,monospace;"&gt;    $ cht-compile company.cht&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    Wrote ./data/departments.rows.json&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    Wrote ./data/employees.rows.json&lt;/span&gt;&lt;br&gt;&lt;/pre&gt; &lt;p&gt; 我们看到它分别为 departments 和 employees 这两张表生成了两个 JSON 格式的数据文件。其中的  data/employees.rows.json 文件在我机器上的此次运行是这个样子的： &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;span style="font-family: courier new,monospace;"&gt;    $ cat data/employees.rows.json&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    [[&amp;quot;id&amp;quot;,&amp;quot;name&amp;quot;,&amp;quot;age&amp;quot;,&amp;quot;tel&amp;quot;,&amp;quot;birthday&amp;quot;,&amp;quot;height&amp;quot;,&amp;quot;grades&amp;quot;,&amp;quot;department&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;7606&amp;quot;,&amp;quot;Kxhwcn Cflub&amp;quot;,54,&amp;quot;15872171866&amp;quot;,&amp;quot;2011-04-01&amp;quot;,&amp;quot;1.67276&amp;quot;,&amp;quot;D&amp;quot;,&amp;quot;408862&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;63649&amp;quot;,&amp;quot;Whf Iajgw&amp;quot;,55,&amp;quot;13850771916&amp;quot;,null,&amp;quot;1.65297&amp;quot;,&amp;quot;E&amp;quot;,&amp;quot;844615&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;348161&amp;quot;,&amp;quot;Nnwe Obfkln&amp;quot;,27,&amp;quot;15801601215&amp;quot;,&amp;quot;2011-03-06&amp;quot;,&amp;quot;1.69275&amp;quot;,&amp;quot;D&amp;quot;,&amp;quot;408862&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;353404&amp;quot;,&amp;quot;Shgpak Xvqxw&amp;quot;,28,&amp;quot;15816453097&amp;quot;,null,&amp;quot;1.67796&amp;quot;,&amp;quot;A&amp;quot;,&amp;quot;408862&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;445500&amp;quot;,&amp;quot;Bdt Mhepht&amp;quot;,47,&amp;quot;13855517847&amp;quot;,null,&amp;quot;1.89943&amp;quot;,&amp;quot;C&amp;quot;,&amp;quot;844615&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;513515&amp;quot;,&amp;quot;Ipsa Mcbtk&amp;quot;,25,&amp;quot;13874017694&amp;quot;,&amp;quot;2011-01-06&amp;quot;,&amp;quot;1.79534&amp;quot;,&amp;quot;A&amp;quot;,&amp;quot;844615&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;658009&amp;quot;,&amp;quot;Lboe Etqo&amp;quot;,27,null,&amp;quot;2011-04-14&amp;quot;,&amp;quot;1.85162&amp;quot;,&amp;quot;E&amp;quot;,&amp;quot;408862&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;716899&amp;quot;,&amp;quot;Gey Elacflr&amp;quot;,18,&amp;quot;15804516095&amp;quot;,&amp;quot;2011-02-27&amp;quot;,&amp;quot;1.75681&amp;quot;,&amp;quot;A&amp;quot;,&amp;quot;844615&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;945911&amp;quot;,&amp;quot;Hsuz Qcmky&amp;quot;,39,&amp;quot;13862516775&amp;quot;,&amp;quot;2011-05-31&amp;quot;,&amp;quot;1.75947&amp;quot;,&amp;quot;B&amp;quot;,&amp;quot;408862&amp;quot;],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    [&amp;quot;960643&amp;quot;,&amp;quot;Qbmbe Ijnbqsb&amp;quot;,24,&amp;quot;15872418765&amp;quot;,&amp;quot;2011-04-11&amp;quot;,&amp;quot;1.78864&amp;quot;,&amp;quot;B&amp;quot;,&amp;quot;844615&amp;quot;]]&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;  &lt;p&gt; 最后，为导入到关系数据库，我们可以使用 cht-rows2sql 命令将得到的 .json 数据文件转换为 .sql 文件： &lt;/p&gt;&lt;p style="font-family: courier new,monospace;"&gt; &lt;/p&gt;&lt;pre&gt;&lt;span style="font-family: courier new,monospace;"&gt;    $ cht-rows2sql data/*.rows.json&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    Wrote ./sql/departments.rows.sql&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    Wrote ./sql/employees.rows.sql&lt;/span&gt;&lt;br&gt;&lt;/pre&gt; &lt;p&gt; 其中的 sql/departments.rows.sql 在我这里是这样的： &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;span style="font-family: courier new,monospace;"&gt;    $ cat sql/departments.rows.sql&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    insert into departments (id,name) values&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    (408862,&amp;#39;dJRq7LCXL&amp;#39;),&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    (844615,&amp;#39;G_m9Nkh3q&amp;#39;);&lt;/span&gt;&lt;br&gt; &lt;/pre&gt; &lt;p&gt; 这样我们就可以直接往 mysql 这样的数据库里导入数据了： &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;pre&gt;&lt;span style="font-family: courier new,monospace;"&gt;    $ mysql -u monty test -p &amp;lt; sql/departments.rows.sql&lt;/span&gt;&lt;br&gt;&lt;/pre&gt; &lt;p&gt; 目前 cheater 仍处于比较活跃的开发阶段，缺乏比较完整的文档。最完整的文档是它的自动化测试集： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     &lt;a href="http://github.com/agentzh/cheater/tree/master/t/" target="_top"&gt;http://github.com/agentzh/cheater/tree/master/t/&lt;/a&gt; &lt;/p&gt;&lt;p&gt; 点开其中的 .t 文件，便可以看到一个个的声明性的测试用例 &lt;img src="http://twiki.corp.taobao.com/pub/TWiki/SmiliesPlugin/wink.gif" alt="wink" title="wink" border="0"&gt; &lt;/p&gt;&lt;p&gt; 如果您在使用过程中发现任何 bug 或者有任何功能提议，请在 &lt;span class="twikiNewLink"&gt;&lt;a href="http://twiki.corp.taobao.com/bin/edit/%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E4%B8%8E%E4%BA%A7%E5%93%81%E9%83%A8/Taobao_Data_BJ/GitHub?topicparent=%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E4%B8%8E%E4%BA%A7%E5%93%81%E9%83%A8/Taobao_Data_BJ.CheaterTool;nowysiwyg=0" rel="nofollow" title="GitHub (this topic does not yet exist; you can  create it)"&gt;GitHub&lt;/a&gt;&lt;/span&gt;  上创建相应的 ticket: &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;     &lt;a href="http://github.com/agentzh/cheater/issues" target="_top"&gt;http://github.com/agentzh/cheater/issues&lt;/a&gt; &lt;/p&gt;&lt;p&gt; Enjoy! &lt;br&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2161984116908909358?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2161984116908909358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2161984116908909358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2161984116908909358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2161984116908909358'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/08/cheater-yet-another-rule-driven-tool-to.html' title='cheater: yet another rule-driven tool to generate random databases'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3534823193904160285</id><published>2010-08-10T11:30:00.001+08:00</published><updated>2010-08-10T11:30:04.425+08:00</updated><title type='text'>A patch for libdrizzle to fix issues on Mac OS X</title><content type='html'>&lt;a href="https://launchpad.net/libdrizzle"&gt;libdrizzle&lt;/a&gt; is an excellent piece of software but we&amp;#39;ve noticed that it does not compile on Mac OS X due to its use of the new &lt;span style="font-family: courier new,monospace;"&gt;bool&lt;/span&gt; type in C:&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  /usr/local/include/libdrizzle/result.h:69: error: syntax error before 'drizzle_result_eof'&lt;/span&gt;&lt;br&gt;&lt;br&gt;The following small patch for libdrizzle 0.8 fixes this (as well as another bug regarding streaming parsing on the TCP protocol level, as reported by my colleague chaoslawful++ months ago):&lt;br&gt; &lt;br&gt;    &lt;a href="http://agentzh.org/misc/nginx/libdrizzle-0.8-parsebug_and_mac_fixes.patch"&gt;http://agentzh.org/misc/nginx/libdrizzle-0.8-parsebug_and_mac_fixes.patch&lt;/a&gt;&lt;br&gt;&lt;br&gt;I&amp;#39;m looking forward to the next libdrizzle release or I&amp;#39;ll have to keep my patch for my  &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; module&amp;#39;s users ;)&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3534823193904160285?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3534823193904160285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3534823193904160285' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3534823193904160285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3534823193904160285'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/08/patch-for-libdrizzle-to-fix-issues-on.html' title='A patch for libdrizzle to fix issues on Mac OS X'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-926926609295319276</id><published>2010-08-03T11:24:00.001+08:00</published><updated>2010-08-03T11:24:54.949+08:00</updated><title type='text'>ngx_chunkin v0.20: fixed some memory bugs and added support for  chunked PUT</title><content type='html'>I&amp;#39;ve just pushed a new release (v0.20) for my ngx_chunkin module:&lt;br&gt;&lt;br&gt; &amp;nbsp; &lt;a href="http://github.com/agentzh/chunkin-nginx-module/tarball/v0.20"&gt;http://github.com/agentzh/chunkin-nginx-module/tarball/v0.20&lt;/a&gt;&lt;br&gt;&lt;br&gt; Here&amp;#39;s the changes included in this version:&lt;br&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp; fixed a bug that may read incomplete chunked body. thanks Gong Kaihui (龚开晖).&lt;/li&gt;&lt;li&gt;&amp;nbsp; fixed various memory issues in the implementation which may cause nginx processes to crash.&lt;/li&gt; &lt;li&gt;&amp;nbsp; added support for chunked POST requests.&lt;/li&gt;&lt;li&gt;&amp;nbsp; now we always require &amp;quot;error_page 411 @resume&amp;quot; and no default (buggy) magic any more. thanks Gong Kaihui (龚开晖).&lt;/li&gt;&lt;/ul&gt;This module adds HTTP 1.1 chunked input support for Nginx without the need of patching the Nginx core.&lt;br&gt; &lt;br&gt;Behind the scene, it registers an access-phase handler that will eagerly read and decode incoming request bodies when a &lt;span style="font-family: courier new,monospace;"&gt;&amp;quot;Transfer-Encoding: chunked&lt;/span&gt;&amp;quot; header triggers a 411 error page in Nginx. For requests that are not in the chunked transfer encoding, this module is a &amp;quot;no-op&amp;quot;.&lt;br&gt; &lt;br&gt;To enable the magic, just turn on the chunkin config option and define a custom 411 error_page using chunkin_resume, like this:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; server {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; chunkin on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; error_page 411 = @my_411_error;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; location @my_411_error {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; &amp;nbsp; &amp;nbsp; chunkin_resume;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br&gt;See its wiki page for the full documentation:&lt;br&gt;&lt;br&gt; &amp;nbsp; &lt;a href="http://wiki.nginx.org/NginxHttpChunkinModule"&gt;http://wiki.nginx.org/NginxHttpChunkinModule&lt;/a&gt;&lt;br&gt; &lt;br&gt;Note that nginx 0.8.41 and 0.7.67 are confirmed to work with this version. Nginx releases newer than 0.8.41 will &lt;i&gt;not&lt;/i&gt; work due to this&lt;br&gt;issue:&lt;br&gt;&lt;br&gt; &amp;nbsp; &lt;a href="http://forum.nginx.org/read.php?29,103078"&gt;http://forum.nginx.org/read.php?29,103078&lt;/a&gt;&lt;br&gt; &lt;br&gt;There&amp;#39;s no reply from the nginx author Igor Sysoev yet :(&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt;&lt;b&gt;Update&lt;/b&gt;: I&amp;#39;ve just kicked ngx_chunkin v0.21 out of the door, which applies a patch from Gong Kaihui that fixed a small bug:&lt;br&gt;  &lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;a href="http://wiki.nginx.org/NginxHttpChunkinModule#v0.21"&gt;http://wiki.nginx.org/NginxHttpChunkinModule#v0.21&lt;/a&gt;&lt;br&gt;&lt;br&gt;  &amp;nbsp; &amp;nbsp;&lt;a href="http://github.com/agentzh/chunkin-nginx-module/tarball/v0.21" target="_blank"&gt;http://github.com/agentzh/chunkin-nginx-module/tarball/v0.21&lt;/a&gt;&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-926926609295319276?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/926926609295319276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=926926609295319276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/926926609295319276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/926926609295319276'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/08/ngxchunkin-v020-fixed-some-memory-bugs.html' title='ngx_chunkin v0.20: fixed some memory bugs and added support for  chunked PUT'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6405845535597322083</id><published>2010-06-24T12:52:00.001+08:00</published><updated>2010-06-24T12:52:23.497+08:00</updated><title type='text'>ngx_lua now has (basic) subrequest support</title><content type='html'>Last night&amp;#39;s ngx_lua hackathon has been proven extremely fruitful. chaoslawful and I didn&amp;#39;t stop coding until midnight, and successfully finished the first draft of the most tricky bit in ngx_lua, that is, transparent non-blocking IO interface (or nginx subrequest interface) on the Lua land.&lt;br&gt; &lt;br&gt;The following test case is now passing:&lt;br&gt;&lt;br&gt;   location /other {&lt;br&gt;       echo &amp;quot;hello, world&amp;quot;;&lt;br&gt;   }&lt;br&gt; &lt;br&gt;   # transparent non-blocking I/O in Lua&lt;br&gt;   location /lua {&lt;br&gt;       content_by_lua &amp;#39;&lt;br&gt;            local res = ngx.location.capture(&amp;quot;/other&amp;quot;)&lt;br&gt;           if res.status == 200 then&lt;br&gt;               ngx.echo(res.body)&lt;br&gt;           end&amp;#39;;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;And on the client side:&lt;br&gt;&lt;br&gt;    $ curl &amp;#39;&lt;a href="http://localhost/lua"&gt;http://localhost/lua&lt;/a&gt;&amp;#39;&lt;br&gt;     hello, world&lt;br&gt;&lt;br&gt;In the /other location, we can actually have drizzle_pass, postgres_pass, memcached_pass,  proxy_pass, or any other content handler configuration.&lt;br&gt;&lt;br&gt;Here&amp;#39;s a more amusing example to do &amp;quot;recursive subrequest&amp;quot;:&lt;br&gt; &lt;br&gt; location /recur {&lt;br&gt;       content_by_lua &amp;#39;&lt;br&gt;           local num = tonumber(ngx.var.arg_num) or 0&lt;br&gt;           ngx.echo(&amp;quot;num is: &amp;quot;, num, &amp;quot;\\n&amp;quot;)&lt;br&gt;&lt;br&gt;           if num &amp;gt; 0 then&lt;br&gt;               res = ngx.location.capture(&amp;quot;/recur?num=&amp;quot; .. tostring(num - 1))&lt;br&gt;                ngx.echo(&amp;quot;status=&amp;quot;, res.status, &amp;quot; &amp;quot;)&lt;br&gt;               ngx.echo(&amp;quot;body=&amp;quot;, res.body)&lt;br&gt;           else&lt;br&gt;               ngx.echo(&amp;quot;end\\n&amp;quot;)&lt;br&gt;           end                             &lt;br&gt;            &amp;#39;;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;Here&amp;#39;s the output on the client side:&lt;br&gt;&lt;br&gt;    $ curl &amp;#39;&lt;a href="http://localhost/recur?num=3"&gt;http://localhost/recur?num=3&lt;/a&gt;&amp;#39;&lt;br&gt;    num is: 3&lt;br&gt;    status=200 body=num is: 2&lt;br&gt;     status=200 body=num is: 1&lt;br&gt;    status=200 body=num is: 0&lt;br&gt;    end            &lt;br&gt;&lt;br&gt;So...time to replace our PHP code in the business with nginx.conf + Lua scripts!&lt;br&gt;&lt;br&gt;We&amp;#39;d make the first public release of ngx_lua when its implementation and API become solid enough ;)&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6405845535597322083?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6405845535597322083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6405845535597322083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6405845535597322083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6405845535597322083'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxlua-now-has-basic-subrequest-support.html' title='ngx_lua now has (basic) subrequest support'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-109490078222141256</id><published>2010-06-22T17:49:00.001+08:00</published><updated>2010-06-22T17:49:38.004+08:00</updated><title type='text'>ngx_xss v0.02: fixed a bug that prevents responses from being gzipped</title><content type='html'>I&amp;#39;m glad to announce the v0.02 release of the ngx_xss module:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/xss-nginx-module/tarball/v0.02"&gt;http://github.com/agentzh/xss-nginx-module/tarball/v0.02&lt;/a&gt;&lt;br&gt;&lt;br&gt;This module provides native cross-site scripting (XSS) support in nginx, and cross-site GET via &lt;a href="http://en.wikipedia.org/wiki/JSON#JSONP"&gt;JSONP&lt;/a&gt; in particular. Please visit the project homepage for more details:&lt;br&gt; &lt;br&gt;    &lt;a href="http://github.com/agentzh/xss-nginx-module"&gt;http://github.com/agentzh/xss-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;This release fixes a nasty bug in &lt;span style="font-family: courier new,monospace;"&gt;Content-Type&lt;/span&gt; header handling. The previous version does not clear &lt;span style="font-family: courier new,monospace;"&gt;r-&amp;gt;headers_out.content_type_lowcase&lt;/span&gt; which sadly prevents responses from being compressed by the &lt;a href="http://wiki.nginx.org/NginxHttpGzipModule"&gt;ngx_http_gzip_filter_module&lt;/a&gt; if configured.&lt;br&gt; &lt;br&gt;Thanks my teammate kindy++ for catching it in our production environment :P&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-109490078222141256?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/109490078222141256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=109490078222141256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/109490078222141256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/109490078222141256'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxxss-v002-fixed-bug-that-prevents.html' title='ngx_xss v0.02: fixed a bug that prevents responses from being gzipped'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4101316519519613268</id><published>2010-06-21T17:48:00.001+08:00</published><updated>2010-06-21T17:48:54.008+08:00</updated><title type='text'>ngx_drizzle v0.0.11 and ngx_rds_json v0.09: significant performance  boost</title><content type='html'>I&amp;#39;m happy to announce that &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; v0.0.11 and &lt;a href="http://github.com/agentzh/rds-json-nginx-module"&gt;ngx_rds_json&lt;/a&gt; v0.09 are finally out:&lt;br&gt;&lt;br&gt;     &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module/tarball/v0.0.11"&gt;http://github.com/chaoslawful/drizzle-nginx-module/tarball/v0.0.11&lt;/a&gt;&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/rds-json-nginx-module/tarball/v0.09"&gt;http://github.com/agentzh/rds-json-nginx-module/tarball/v0.09&lt;/a&gt;&lt;br&gt; &lt;br&gt;ngx_drizzle is an upstream module that talks to mysql, drizzle, and sqlite3 by libdrizzle, and generates output in a binary format known as RDS (Resty DBD Stream), just like Piotr Sikora&amp;#39;s &lt;a href="http://github.com/FRiCKLE/ngx_postgres/"&gt;ngx_postgres&lt;/a&gt; module.&lt;br&gt; &lt;br&gt;ngx_rds_json is an output filter module that converts the RDS outputs of ngx_drizzle and ngx_postgres, to plain JSON text.&lt;br&gt;&lt;br&gt;The highlight of these releases are &lt;i&gt;significant&lt;/i&gt; performance boost due to extensive refactoring and optimizations in these two modules recently.&lt;br&gt; &lt;br&gt;One can observe hundreds of times of improvement for big responses above 300KB for both ngx_drizzle + ngx_rds_json and ngx_postgres + ngx_rds_json combination.&lt;br&gt;&lt;br&gt;We even observed that ngx_drizzle + ngx_rds_json achieved 128MB/sec (Yes, 1024Mbit/sec!) for a 380KB data-set query while connecting to a simple mysql server, about 3 ~ 4 times as fast as php + libmysql in an identical setting.&lt;br&gt; &lt;br&gt;Technically, we (partially) adapted the &amp;quot;fixed-size bufs&amp;quot; model used in ngx_http_gzip_filter_module (and elsewhere in the nginx core) in both of our modules, effectively eliminating lots of unnecessary packet splitting and buffer allocations, which contributes most of the performance boost. And we&amp;#39;d like ngx_postgres to apply this technique in the near future too (for a typical 470 KB data-set query, ngx_drizzle + ngx_rds_json is now more than 50% faster than ngx_postgres + ngx_rds_json).&lt;br&gt; &lt;br&gt;We also introduce the drizzle_buffer_size and rds_json_buffer_size directives to allow the user adjust the size of each buf that is used in the output emitter:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;     drizzle_buffer_size 4k;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;     rds_json_buffer_size 4k;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;The default setting is the page-size, usually 4k ~ 8k. The bigger the buffer size, the less streamming the output will be.&lt;br&gt; &lt;br&gt;At last but not least, this release of ngx_drizzle also includes various new features ported from ngx_postgres, like the &amp;quot;method-specific queries&amp;quot; support in the drizzle_query directive.&lt;br&gt;&lt;br&gt;Here&amp;#39;s an example that implements a full RESTful interface to a mysql backend using a single nginx location, and no &amp;quot;if hacks&amp;quot;:&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  location ~ &amp;#39;^/cat/(\d+)&amp;#39; {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       set $id $1;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       set_form_input $name;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       set_quote_sql_str $quoted_name $name;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       drizzle_query HEAD GET &amp;quot;select * from cats where id=$id&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;       drizzle_query DELETE &amp;quot;delete from cats where id=$id&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       drizzle_query POST &amp;quot;insert into cats (name) values($quoted_name)&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;       drizzle_pass my_mysql_backend;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br&gt;There&amp;#39;s also an example for ngx_postgres in my slides:&lt;br&gt;&lt;br&gt;    &lt;a href="http://agentzh.org/misc/slides/recent-dev-nginx-conf/#18"&gt;http://agentzh.org/misc/slides/recent-dev-nginx-conf/#18&lt;/a&gt;&lt;br&gt;&lt;br&gt;Have fun!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4101316519519613268?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4101316519519613268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4101316519519613268' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4101316519519613268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4101316519519613268'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxdrizzle-v0011-and-ngxrdsjson-v009.html' title='ngx_drizzle v0.0.11 and ngx_rds_json v0.09: significant performance  boost'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7811130615875535678</id><published>2010-06-21T11:33:00.000+08:00</published><updated>2010-06-21T11:34:01.446+08:00</updated><title type='text'>Recent developments in nginx.conf scripting</title><content type='html'>Last Saturday I gave a talk in Beijing OpenParty&amp;#39;s &lt;a href="http://app.beijing-open-party.org/event/2"&gt;monthly meetup&lt;/a&gt; regarding our recent developments in nginx.conf scripting with the highlight of new modules like &lt;a href="http://github.com/FRiCKLE/ngx_postgres/"&gt;ngx_postgres&lt;/a&gt;, &lt;a href="http://github.com/calio/form-input-nginx-module"&gt;ngx_form_input&lt;/a&gt;, &lt;a href="http://github.com/agentzh/srcache-nginx-module"&gt;ngx_srcache&lt;/a&gt;, &lt;a href="http://github.com/agentzh/encrypted-session-nginx-module"&gt;ngx_encrypted_session&lt;/a&gt;, and &lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;ngx_lua&lt;/a&gt;.&lt;br&gt; &lt;br&gt;Here&amp;#39;s the slides that I used in this event:&lt;br&gt;&lt;br&gt;     &lt;a href="http://agentzh.org/misc/slides/recent-dev-nginx-conf/"&gt;http://agentzh.org/misc/slides/recent-dev-nginx-conf/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Please use the arrow keys or page-up/page-down keys on your keyboard to navigate through them.&lt;br&gt; &lt;br&gt;Special thanks go to Piotr Sikora for his preview of these slides before the talk and lots of his good suggestions.&lt;br&gt;&lt;br&gt;Feedback and comments are very welcome as usual :)&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7811130615875535678?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7811130615875535678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7811130615875535678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7811130615875535678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7811130615875535678'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/recent-developments-in-nginxconf.html' title='Recent developments in nginx.conf scripting'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7239046056077697451</id><published>2010-06-18T15:41:00.001+08:00</published><updated>2010-06-18T15:41:25.163+08:00</updated><title type='text'>ngx_openresty 端午节大优化</title><content type='html'>端午节前后我对 &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; 和 &lt;a href="http://github.com/agentzh/rds-json-nginx-module"&gt;ngx_rds_json&lt;/a&gt; 进行了深入重构和优化，现在对于几百 KB 的大结果查询，比一周前提升了几百倍的性能。现在对于一个典型的 380 KB 的大结果集的 mysql 查询，10 并发，单机可达 430+ q/s，128 MB 的传输速率，20 ms 平均响应时间 [1]。&lt;br&gt; &lt;br&gt;nginx 这一侧没有使用任何针对结果集的缓存，mysql 那一侧倒是有可能用到了其自己的内存缓存，呵呵。现在我们的性能终于是 php + libmysql 的 4 倍左右了。&lt;br&gt;&lt;br&gt;主要的改动就是重新设计了缓冲区的管理模型，采用了类似 &lt;a href="http://wiki.nginx.org/NginxHttpGzipModule"&gt;ngx_http_gzip_filter_module&lt;/a&gt; 的定长 buf 链和回收机制，后面有机会再详细介绍一下，呵呵。&lt;br&gt; &lt;br&gt;值得一提的是，编译 nginx 时 gcc &lt;span style="font-family: courier new,monospace;"&gt;-O1&lt;/span&gt; 会比 &lt;span style="font-family: courier new,monospace;"&gt;-O0&lt;/span&gt; 提升 50%；&lt;span style="font-family: courier new,monospace;"&gt;-O2&lt;/span&gt; 比 &lt;span style="font-family: courier new,monospace;"&gt;-O1&lt;/span&gt; 只提升几个百分点的样子。&lt;br&gt; &lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;ngx_rds_json&lt;/span&gt; 的优化也让 &lt;a href="http://github.com/FRiCKLE/ngx_postgres/"&gt;ngx_postgres&lt;/a&gt; 和它一起工作时，性能提高了一二百倍 :)&lt;br&gt;&lt;br&gt;另外，git HEAD 中还分别给这两个模块新增了一条配置指令，一是 &lt;span style="font-family: courier new,monospace;"&gt;drizzle_buffer_size&lt;/span&gt;，一是 &lt;span style="font-family: courier new,monospace;"&gt;rds_json_buffer_size&lt;/span&gt;. 二者的默认值都是 page size, &amp;nbsp;即一般是 4k 或者 8k, 对于大结果集，适当调大有助于进一步提升性能，但 buffer size 设得越大，流输出的特性就越少。&lt;br&gt; &lt;br&gt;明天 &lt;a href="http://app.beijing-open-party.org/topic/10"&gt;OpenParty 的 talk&lt;/a&gt; 完了之后，我再发布这两个模块的新版本 :)&lt;br&gt;&lt;br&gt;Stay tuned~&lt;br&gt;&lt;br&gt;[1] 测试机器的配置是 4 核的 Intel(R) Xeon(R) CPU 5130 @ 2.00GHz, 4 GB RAM.&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7239046056077697451?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7239046056077697451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7239046056077697451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7239046056077697451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7239046056077697451'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxopenresty_18.html' title='ngx_openresty 端午节大优化'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4020999836917143623</id><published>2010-06-06T20:46:00.001+08:00</published><updated>2010-06-06T20:46:43.959+08:00</updated><title type='text'>ngx_headers_more v0.10: ability to remove a header completely</title><content type='html'>I&amp;#39;m happy to announce that the v0.10 release of &lt;a href="http://github.com/agentzh/headers-more-nginx-module"&gt;ngx_headers_more&lt;/a&gt; has just landed:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module/tarball/v0.10"&gt;http://github.com/agentzh/headers-more-nginx-module/tarball/v0.10&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module allows you to add, set, or clear any output or input header that you specify.  Please see the &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule"&gt;full documentation&lt;/a&gt; for more details.&lt;br&gt;&lt;br&gt;From this release, the &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#more_clear_headers"&gt;more_clear_headers&lt;/a&gt; and &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#more_clear_input_headers"&gt;more_clear_input_headers&lt;/a&gt; directives can remove a specified header &lt;i&gt;completely&lt;/i&gt;.&lt;br&gt; &lt;br&gt;In earlier releases, clearing out a header usually just clears the header&amp;#39;s &lt;i&gt;value&lt;/i&gt;, not its &lt;i&gt;key&lt;/i&gt;. For instance,&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    more_clear_headers &amp;#39;Server&amp;#39;;&lt;/span&gt;&lt;br&gt; &lt;br&gt;yields&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   Server:&lt;/span&gt;&lt;br&gt;&lt;br&gt;in the response headers. Now, it&amp;#39;ll be erased completely.&lt;br&gt;&lt;br&gt;Non-standard headers like &lt;span style="font-family: courier new,monospace;"&gt;X-Foo&lt;/span&gt; can be totally erased as well.&lt;br&gt; &lt;br&gt;The same change applies to &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#more_clear_input_headers"&gt;more_clear_input_headers&lt;/a&gt;, where we can erase an input header in the request object before forwarding it to a content handler like &lt;a href="http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass"&gt;proxy_pass&lt;/a&gt; or &lt;a href="http://wiki.nginx.org/NginxHttpFcgiModule#fastcgi_pass"&gt;fastcgi_pass&lt;/a&gt;.&lt;br&gt; &lt;br&gt;You&amp;#39;re very welcome to send bug report (if any!) or wishlist to us at &lt;a href="http://github.com/agentzh/headers-more-nginx-module/issues"&gt;GitHub Issues&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4020999836917143623?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4020999836917143623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4020999836917143623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4020999836917143623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4020999836917143623'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxheadersmore-v010-ability-to-remove.html' title='ngx_headers_more v0.10: ability to remove a header completely'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-9013875231767332443</id><published>2010-06-04T12:08:00.001+08:00</published><updated>2010-06-04T12:08:07.801+08:00</updated><title type='text'>ngx_echo v0.32: various memory issue fixes inspired by valgrind</title><content type='html'>I&amp;#39;m happy to announce the v0.32 release of the ngx_echo module:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/echo-nginx-module/tarball/v0.32"&gt;http://github.com/agentzh/echo-nginx-module/tarball/v0.32&lt;/a&gt;&lt;br&gt;&lt;br&gt;This module wraps lots of Nginx internal APIs for streaming input and output, parallel/sequential subrequests, timers and sleeping, as well as various meta data accessing. Basically it provides various utilities that help testing and debugging of other modules by trivially emulating different kinds of faked subrequest locations. &lt;br&gt; &lt;br&gt;This release fixes several memory issues reported by &lt;a href="http://valgrind.org/"&gt;valgrind&amp;#39;s memcheck&lt;/a&gt; tool and below is the complete change log for this version:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpEchoModule#v0.32"&gt;http://wiki.nginx.org/NginxHttpEchoModule#v0.32&lt;/a&gt;&lt;br&gt; &lt;br&gt;We&amp;#39;ve just integrated valgrind support into our test scaffold &lt;a href="http://github.com/agentzh/test-nginx"&gt;Test::Nginx&lt;/a&gt; which is used by all of our nginx module projects. Now running a particular module&amp;#39;s test suite with valgrind&amp;#39;s memcheck is as simple as&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    cd test&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     TEST_NGINX_USE_VALGRIND=1 prove -r t&lt;/span&gt;&lt;br&gt; &lt;br&gt;This facility also helps spotting quite a few memory-related issues in several other modules developed by ourselves :)&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-9013875231767332443?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/9013875231767332443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=9013875231767332443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/9013875231767332443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/9013875231767332443'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxecho-v032-various-memory-issue-fixes.html' title='ngx_echo v0.32: various memory issue fixes inspired by valgrind'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6415548223012396957</id><published>2010-06-03T11:00:00.001+08:00</published><updated>2010-06-03T11:00:29.753+08:00</updated><title type='text'>The upcoming nginx.conf scripting talk at OpenParty</title><content type='html'>I&amp;#39;m going to talk about nginx.conf scripting in this month&amp;#39;s OpenParty meetup:&lt;br&gt;&lt;br&gt;    &lt;a href="http://app.beijing-open-party.org/topic/10" target="_blank"&gt;http://app.beijing-open-party.org/topic/10&lt;/a&gt;&lt;br&gt;&lt;br&gt;You&amp;#39;re very welcome to attend my talk:&lt;br&gt;  &lt;br&gt;    &lt;a href="http://app.beijing-open-party.org/"&gt;http://app.beijing-open-party.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;See you there ;)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6415548223012396957?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6415548223012396957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6415548223012396957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6415548223012396957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6415548223012396957'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/upcoming-nginxconf-scripting-talk-at.html' title='The upcoming nginx.conf scripting talk at OpenParty'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5018009086767021984</id><published>2010-06-02T20:09:00.000+08:00</published><updated>2010-06-02T20:10:04.168+08:00</updated><title type='text'>ngx_headers_more v0.09: wildcard support in more_clear_headers</title><content type='html'>I&amp;#39;m delighted to announce the v0.09 release of the &lt;a href="http://github.com/agentzh/headers-more-nginx-module"&gt;ngx_headers_more&lt;/a&gt; module:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module/tarball/v0.09"&gt;http://github.com/agentzh/headers-more-nginx-module/tarball/v0.09&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module allows you to add, set, or clear any output or input headers that you specify. This is an enhanced version of the standard headers module because it provides more utilities like resetting or clearing &amp;quot;builtin headers&amp;quot; like &lt;span style="font-family: courier new,monospace;"&gt;Content-Type&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;Content-Length&lt;/span&gt;, and &lt;span style="font-family: courier new,monospace;"&gt;Server&lt;/span&gt;.&lt;br&gt; &lt;br&gt;This release features the wildcard (&lt;span style="font-family: courier new,monospace;"&gt;*&lt;/span&gt;) support in the more_clear_headers directive. For example, the following directive effectively clears any output headers starting by &lt;span style="font-family: courier new,monospace;"&gt;X-Hidden-&lt;/span&gt;:&lt;br&gt; &lt;br&gt;    more_clear_headers &amp;#39;X-Hidden-*&amp;#39;;&lt;br&gt;&lt;br&gt;Thanks our new contributor Bernd Dorn for implementing this :)&lt;br&gt;&lt;br&gt;See the complete change log for this version if you&amp;#39;re interested:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule#v0.09"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule#v0.09&lt;/a&gt;&lt;br&gt; &lt;br&gt;Also, in the previous version, i.e., v0.08, Bernd Dorn also introduced the &lt;span style="font-family: courier new,monospace;"&gt;-r&lt;/span&gt; option to the more_set_input_headers directive to replace the value of the input header specified &lt;i&gt;if and only if&lt;/i&gt; that header actually exists.&lt;br&gt; &lt;br&gt;You can find the complete documentation of this module on the nginx wiki site:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5018009086767021984?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5018009086767021984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5018009086767021984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5018009086767021984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5018009086767021984'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxheadersmore-v009-wildcard-support-in.html' title='ngx_headers_more v0.09: wildcard support in more_clear_headers'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-801853853018540211</id><published>2010-06-01T14:04:00.001+08:00</published><updated>2010-06-01T14:04:04.678+08:00</updated><title type='text'>Optimizing ngx_openresty for big responses</title><content type='html'>(Piotr Sikora blames me for posting my previous article in Chinese. Hence the following English transcript.)&lt;br&gt;&lt;br&gt;I&amp;#39;ve been spotting bottlenecks in &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; and &lt;a href="http://github.com/agentzh/rds-json-nginx-module"&gt;ngx_rds_json&lt;/a&gt; for responses with big data sets. Now it&amp;#39;s finally 1 times faster than php + libmysql for huge mysql responses of 380+ KB. The former can reach 250+ q/s using ab -c50 while the latter merely gets 120+ q/s.&lt;br&gt; &lt;br&gt;Earlier last week, for requests of such big responses, ngx_drizzle + ngx_rds_json merely got 12 ~ 14 q/s, just 1/10 of the that of php + libmysql, which drove me crazy.&lt;br&gt;&lt;br&gt;This serious performance issue mainly comes from the &amp;quot;strict context-free streamming output model&amp;quot; introduced into ngx_drizzle and ngx_rds_json around the beginning of this year, due to my laziness. This has been proven to be a really bad idea because it will split the data buffer into many many little pieces and even worse, it sets &lt;span style="font-family: courier new,monospace;"&gt;buf-&amp;gt;flush&lt;/span&gt; to true which effectively enables auto-flushing. Sigh. For that specific 380 KB result set query mentioned above, it will result in 10000+ times of writev syscalls and slowness compared to even php :)&lt;br&gt; &lt;br&gt;I&amp;#39;ve already turned off buf-&amp;gt;flush in ngx_drizzle v0.0.11rc1 and ngx_rds_json v0.08.&lt;br&gt;&lt;br&gt;calio++ will refactor the bufs and chains model used by these two modules this month, so as to achieve the best performance here.&lt;br&gt; &lt;div id="msgcns!FF3A735632E41548!568" class="bvMsg"&gt; &lt;br&gt;For little data sets (less than 500 bytes), ngx_drizzle&amp;#39;s qps is always one or two magnitude higher than php + libmysql, without doubt. Thousands of q/s is not uncommon at all.&lt;br&gt;&lt;br&gt;A good news is that, &lt;a href="http://qunar.com"&gt;qunar.com&lt;/a&gt; is already using &lt;a href="http://github.com/FRiCKLE/ngx_postgres/"&gt;ngx_postgres&lt;/a&gt; + ngx_rds_json to access PostgreSQL in production for several online services. And according to their report, they can achieve 7k ~ 8k q/s per machine without caching the result sets. Their nginx worker processes have run flawlessly for 12 days and never crash.&lt;br&gt; &lt;br&gt;We are also preparing to push ngx_drizzle online for &lt;a href="http://lz.taobao.com/"&gt;our own data product&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Stay tuned~~&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-801853853018540211?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/801853853018540211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=801853853018540211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/801853853018540211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/801853853018540211'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/optimizing-ngxopenresty-for-big.html' title='Optimizing ngx_openresty for big responses'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7355509839295610948</id><published>2010-06-01T11:28:00.001+08:00</published><updated>2010-06-01T11:28:50.002+08:00</updated><title type='text'>ngx_openresty 优化进行时</title><content type='html'>这几日我一直在优化 &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; 和 &lt;a href="http://github.com/agentzh/rds-json-nginx-module"&gt;ngx_rds_json&lt;/a&gt;. ngx_drizzle 对于 380 KB 这样的大结果集终于比 php + libmysql 快一倍以上了，前者是 250+ q/s 单机，后者是 120+ q/s.&lt;br&gt; &lt;br&gt;在上周的时候，这种大结果集的单次查询，ngx_drizzle + ngx_rds_json 只有 php + libmysql 的 1/10 的 q/s 性能，只有 12 ~ 14 q/s，当时我都快疯了，哈哈！&lt;br&gt;&lt;br&gt;小结果集 ngx_drizzle 比 php + libmysql 高一个数量级以上没什么悬念，呵呵。前者都是千级的 qps.&lt;br&gt;&lt;br&gt;原先对大结果集查询有性能瓶颈的主要原因是我年初做 ngx_drizzle 和 ngx_rds_json 的时候为偷懒，实现了一种上下文无关的严格流式输出模型，导致数据切片过细，并且置了 buf-&amp;gt;flush，导至 writev 系统调用次数过多（在上面那个 380 k 输出的测试用例中，最初有 10000+ 次调用）。确实，下游输出的 tcp packet 的大小应该和上游 mysql 的 tcp packet 的这个"上下文"有关 :) 我已经让 calio 同学在下个月重构 ngx_drizzle 和 ngx_rds_json 的输出组件的内存管理模型。&lt;br&gt; &lt;br&gt;一个好消息是，&lt;a href="http://qunar.com"&gt;qunar.com&lt;/a&gt; 已经在生产上使用 &lt;a href="http://github.com/FRiCKLE/ngx_postgres/"&gt;ngx_postgres&lt;/a&gt; + ngx_rds_json 来访问他们的 PostgreSQL 数据库后端，据他们的报告，单机性能可达 7k ~ 8k q/s，并且已经在线上稳定运行 12 天了，nginx worker 进程从未掉过一个，呵呵，也没有观察到内存泄漏 :D&lt;br&gt; &lt;br&gt;我们自己的&lt;a href="http://lz.taobao.com/"&gt;数据产品&lt;/a&gt;也在紧锣密鼓地准备把 ngx_drizzle 推上线 ;)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7355509839295610948?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7355509839295610948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7355509839295610948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7355509839295610948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7355509839295610948'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/06/ngxopenresty.html' title='ngx_openresty 优化进行时'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5427621012642076220</id><published>2010-05-26T10:33:00.001+08:00</published><updated>2010-05-26T10:33:59.673+08:00</updated><title type='text'>ngx_echo v0.31: more sequential subrequest fixes inspired by  ngx_srcache</title><content type='html'>I&amp;#39;m glad to release ngx_echo v0.31 which include various fixes on sequential subrequests inspired by the ngx_srcache development:&lt;br&gt; &lt;br&gt;     &lt;a href="http://github.com/agentzh/echo-nginx-module/tarball/v0.31" target="_blank"&gt;http://github.com/agentzh/&lt;span&gt;echo&lt;/span&gt;-nginx-module/tarball/v0.31&lt;/a&gt;&lt;br&gt; &lt;br&gt; Here&amp;#39;s the (boring) technical change log:&lt;br&gt;&lt;ul&gt;&lt;li&gt; the echo wev handler should not proceed if it is still waiting  for some sequential subrequest or has just processed one to avoid  bouncing issues. &lt;/li&gt;&lt;li&gt; fixed a segfault for echo_exec for 0.7.x: we should check &lt;code&gt;r-&amp;gt;done&lt;/code&gt;  before proceeding. &lt;/li&gt;&lt;li&gt; no longer explicitly set &lt;code&gt;r-&amp;gt;write_event_handler&lt;/code&gt;  to &lt;code&gt;ngx_http_request_empty_handler&lt;/code&gt; because it&amp;#39;s totally  wrong for the state machine. &lt;/li&gt;&lt;li&gt; fixed the sequential subrequest model bugs: we should ensure  the &lt;code&gt;pr-&amp;gt;write_event_handler&lt;/code&gt; gets called immediately  after the &lt;code&gt;post_subrequest&lt;/code&gt; callback when the subrequest  finalizes. &lt;/li&gt;&lt;/ul&gt; BTW, ngx_srcache is near the corner of its first public release:&lt;br&gt; &lt;br&gt;     &lt;a href="http://github.com/agentzh/srcache-nginx-module" target="_blank"&gt;http://github.com/agentzh/srcache-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt; calio++ is currently working on the last missing bit, i.e., response headers caching :)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5427621012642076220?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5427621012642076220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5427621012642076220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5427621012642076220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5427621012642076220'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/05/ngxecho-v031-more-sequential-subrequest.html' title='ngx_echo v0.31: more sequential subrequest fixes inspired by  ngx_srcache'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2265415237133659872</id><published>2010-05-26T10:08:00.000+08:00</published><updated>2010-05-26T10:09:00.720+08:00</updated><title type='text'>ngx_rds_json v0.07: fixed boolean values for PosgreSQL</title><content type='html'>I&amp;#39;m pleased to announce that ngx_rds_json v0.07 has been released:&lt;br&gt;&lt;br&gt;     &lt;a href="http://github.com/agentzh/rds-json-nginx-module/tarball/v0.07" target="_blank"&gt;http://github.com/agentzh/rds-json-nginx-module/tarball/v0.07&lt;/a&gt;&lt;br&gt;  &lt;br&gt;ngx_rds_json is an output filter module that can format the RDS (Resty DBD Stream) outputs of the ngx_drizzle and ngx_postgres modules to JSON text.&lt;br&gt;&lt;br&gt;This release includes the patch from Tom Tuling, that fixes the boolean values in the result sets emitted by PostgreSQL, i.e., values like &amp;quot;f&amp;quot; and &amp;quot;t&amp;quot;. Thanks Tom Tuling :)&lt;br&gt;  &lt;br&gt;FWIW, my friend xunxin++ has already put ngx_postgres + ngx_rds_json into production :) &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2265415237133659872?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2265415237133659872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2265415237133659872' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2265415237133659872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2265415237133659872'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/05/ngxrdsjson-v007-fixed-boolean-values.html' title='ngx_rds_json v0.07: fixed boolean values for PosgreSQL'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1371568927261079895</id><published>2010-05-18T10:51:00.001+08:00</published><updated>2010-05-18T10:51:48.604+08:00</updated><title type='text'>A Simple ngx_lua Example for the Future</title><content type='html'>One of my nginx module users is asking for a &amp;quot;get_once&amp;quot; command support for the &lt;a href="http://wiki.nginx.org/NginxHttpMemcModule"&gt;ngx_memc&lt;/a&gt; module. But I&amp;#39;d rather do such specific things on the &lt;a href="http://github.com/chaoslawful/lua-nginx-module"&gt;ngx_lua&lt;/a&gt; level. Here&amp;#39;s a quick example for this task:&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   location /get_once {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        content_by_lua &amp;quot;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;             -- read the memcached key from the nginx variable $uri&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             key = ngx.var.uri;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              -- do memcached get&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              res = ngx.location.capture(&amp;#39;/memc?cmd=get&amp;amp;key=&amp;#39; .. key);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              -- forward the memcached get response&lt;/span&gt; to the downstream&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;              ngx.res.status = res.status;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              ngx.res.out(res.body);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              if res.status ~= 404 then&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                  -- delete the key and discard the response&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;                  ngx.location.capture(&amp;#39;/memc?cmd=delete&amp;amp;key=&amp;#39; .. key);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              end&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;              &amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location /memc {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        internal;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;         set $memc_key $arg_key;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         set $memc_cmd $arg_cmd;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;         memc_pass &lt;a href="http://127.0.0.1:11211"&gt;127.0.0.1:11211&lt;/a&gt;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt; &lt;br&gt;Furthermore, we can use the &lt;span style="font-family: courier new,monospace;"&gt;content_by_lua_file&lt;/span&gt; directive if we&amp;#39;d put the lua code into a separate &lt;span style="font-family: courier new,monospace;"&gt;.lua&lt;/span&gt; file ;)&lt;br&gt; &lt;br&gt;It&amp;#39;s worth mentioning that the &lt;span style="font-family: courier new,monospace;"&gt;ngx.location.capture&lt;/span&gt; method runs in completely &lt;i&gt;non-blocking&lt;/i&gt; fashion. Thanks to Lua&amp;#39;s coroutine support :D&lt;br&gt;&lt;br&gt;And yes! At the moment, ngx_lua does &lt;i&gt;not&lt;/i&gt; have &lt;span style="font-family: courier new,monospace;"&gt;content_by_lua&lt;/span&gt; and &lt;span style="font-family: courier new,monospace;"&gt;content_by_lua_file&lt;/span&gt; yet. But we&amp;#39;re already working on them and they&amp;#39;ll come soon.&lt;br&gt; &lt;br&gt;Because Lua can run pretty fast especially when JIT is enabled (even compared to plain C), I think we do not have much performance penalty here :)&lt;br&gt;&lt;br&gt;Do you like it?&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1371568927261079895?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1371568927261079895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1371568927261079895' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1371568927261079895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1371568927261079895'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/05/simple-ngxlua-example-for-future.html' title='A Simple ngx_lua Example for the Future'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1432680004610416840</id><published>2010-05-05T17:25:00.001+08:00</published><updated>2010-05-05T17:25:36.611+08:00</updated><title type='text'>ngx_echo v0.29: major core refactoring and more robust sequential  subrequests</title><content type='html'>I&amp;#39;m happy to announce the v0.29 release of the ngx_echo module:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/echo-nginx-module/tarball/v0.29" target="_blank"&gt;http://github.com/agentzh/echo-nginx-module/tarball/v0.29&lt;/a&gt;&lt;br&gt;  &lt;br&gt;As mentioned in some other threads on the nginx mailing list, I&amp;#39;ve completed the big refactoring of the ngx_echo module&amp;#39;s core in this version to reflect my latest understanding (hopefully being quite&lt;br&gt; complete and correct already) of the nginx internals. &lt;br&gt;&lt;br&gt;Now the implementation of &lt;span style="font-family: courier new,monospace;"&gt;echo_subrequest&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;echo_location&lt;/span&gt;, &lt;span style="font-family: courier new,monospace;"&gt;echo_sleep&lt;/span&gt;, and &lt;span style="font-family: courier new,monospace;"&gt;echo_read_request_body&lt;/span&gt; directives has been massively rewritten. I&amp;#39;m trying to set up a design pattern for nginx content handlers that require to do various kinds of non-blocking I/O during its lifetime (similar to upstream modules but for different tasks like subrequests and others).&lt;br&gt;   &lt;br&gt;For sequential subrequests issued by the echo module&amp;#39;s content handler, we now use a totally different approach.&lt;br&gt;&lt;br&gt;Instead of issuing subrequests directly in our &lt;span style="font-family: courier new,monospace;"&gt;post_subrequest&lt;/span&gt; callback (as fed into the &lt;span style="font-family: courier new,monospace;"&gt;ngx_http_subrequest&lt;/span&gt; call), we now postpone firing the subrequests in a custom write event handler which will be called automatically once the current subrequest in question gets completely finalized (that &lt;span style="font-family: courier new,monospace;"&gt;post_subrequest&lt;/span&gt; callback is called by &lt;span style="font-family: courier new,monospace;"&gt;ngx_http_finalize_request&lt;/span&gt; of the subrequest in question).&lt;br&gt;   &lt;br&gt;This works because the parent request will always be waken up once its subrequest completes. (This is done by &lt;span style="font-family: courier new,monospace;"&gt;ngx_http_finalize_request&lt;/span&gt; via posting the parent request into the &amp;quot;posted requests&amp;quot; queue and the posted requests will be always called at the end of the top-level read/write event handler, i.e., &lt;span style="font-family: courier new,monospace;"&gt;ngx_http_request_handler&lt;/span&gt;).&lt;br&gt;   &lt;br&gt;This solves a lot of issues like mangled &lt;span style="font-family: courier new,monospace;"&gt;r-&amp;gt;main-&amp;gt;count&lt;/span&gt; and the following alert message when ginx is configured with the &lt;span style="font-family: courier new,monospace;"&gt;--with-debug&lt;/span&gt; option, for instance,&lt;br&gt;   &lt;br&gt;  &lt;span style="font-family: courier new,monospace;"&gt;   2010/05/05 16:46:14 [alert] 23853#0: *1 http finalize non-active request: &amp;quot;/main?&amp;quot; ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br&gt;We&amp;#39;ll apply this technique to the upcoming ngx_lua and ngx_srcache modules soon :)&lt;br&gt;  &lt;br&gt;P.S. See the ngx_echo module&amp;#39;s wiki page for more information:&lt;br&gt; &lt;a href="http://wiki.nginx.org/NginxHttpEchoModule" target="_blank"&gt;http://wiki.nginx.org/NginxHttpEchoModule&lt;/a&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1432680004610416840?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1432680004610416840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1432680004610416840' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1432680004610416840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1432680004610416840'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/05/ngxecho-v029-major-core-refactoring-and.html' title='ngx_echo v0.29: major core refactoring and more robust sequential  subrequests'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-239443636079098815</id><published>2010-05-03T17:49:00.001+08:00</published><updated>2010-05-03T17:49:18.019+08:00</updated><title type='text'>ngx_echo v0.28: support for the -n and -- options</title><content type='html'>I&amp;#39;m happy to announce the v0.28 release of our ngx_echo module:&lt;br&gt;&lt;br&gt;     &lt;a href="http://github.com/agentzh/echo-nginx-module/tarball/v0.28"&gt;http://github.com/agentzh/echo-nginx-module/tarball/v0.28&lt;/a&gt;&lt;br&gt;&lt;br&gt;ngx_echo is a powerful nginx module that wraps lots of Nginx internal APIs for streaming input and output, parallel/sequential subrequests, timers and sleeping, as well as various meta data accessing. Basically it provides various utilities that help testing and debugging of other modules by trivially emulating different kinds of faked subrequest locations. &lt;br&gt; &lt;br&gt;The highlight of this version is the introduction of new options &amp;quot;-n&amp;quot; and &amp;quot;--&amp;quot; for the &amp;quot;echo&amp;quot;, &amp;quot;echo_before_body&amp;quot;, and &amp;quot;echo_after_body&amp;quot; directives.&lt;br&gt;&lt;br&gt;Now we can suppress the trailing newline character in the &amp;quot;echo&amp;quot; output by using the -n option, as in&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   location /echo {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        echo -n &amp;quot;hello, &amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        echo &amp;quot;world&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br&gt;&lt;br&gt;Accessing /echo gives&lt;br&gt; &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   $ curl &amp;#39;&lt;a href="http://localhost/echo"&gt;http://localhost/echo&lt;/a&gt;&amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    hello, world&lt;/span&gt;&lt;br&gt; &lt;br&gt;Leading -n in variable values won&amp;#39;t take effect and will be emitted literally, as in&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   location /echo {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        set $opt -n;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        echo $opt &amp;quot;hello, &amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        echo &amp;quot;world&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br&gt;This gives the following output&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   $ curl &amp;#39;&lt;a href="http://localhost/echo"&gt;http://localhost/echo&lt;/a&gt;&amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;    -n hello, world&lt;/span&gt;&lt;br&gt;&lt;br&gt;One can also output leading -n literals and other options using the special -- option like this&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   location /echo {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;        echo -- -n is an option;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br&gt;which yields&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   $ curl &amp;#39;&lt;a href="http://localhost/echo"&gt;http://localhost/echo&lt;/a&gt;&amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    -n is an option&lt;/span&gt;&lt;br&gt; &lt;br&gt;Please see the documentation for more details:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpEchoModule#echo"&gt;http://wiki.nginx.org/NginxHttpEchoModule#echo&lt;/a&gt;&lt;br&gt;&lt;br&gt;I must thank Dylan Stamat and kindy for prompting me to add the -n option. They have even provided patches on their own but their patches required more treatment before merging into the mainstream :)&lt;br&gt; &lt;br&gt;In the next release, i.e., v0.29, I&amp;#39;ll refactor the implementation of the echo_location, echo_subrequest, and echo_sleep as promised on the nginx mailing list.&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-239443636079098815?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/239443636079098815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=239443636079098815' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/239443636079098815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/239443636079098815'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/05/ngxecho-v028-support-for-n-and-options.html' title='ngx_echo v0.28: support for the -n and -- options'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4524532572499174488</id><published>2010-04-20T10:00:00.001+08:00</published><updated>2010-04-20T10:00:52.784+08:00</updated><title type='text'>Looking for nginx C developers</title><content type='html'>We&amp;#39;re looking for (senior) nginx C developers to work with us in Taobao.com&amp;#39;s data department here in Beijing.&lt;br&gt;&lt;br&gt;Now we do have some full-time job headcount (yes, finally!). If you&amp;#39;re interested, please send your resume to agentzh at gmail dot com.&lt;br&gt; &lt;br&gt;We can promise that most of the nginx modules that you write here can be opensourced under the BSD license with the company&amp;#39;s full permissions.&lt;br&gt;&lt;br&gt;Waiting to hear from you ;)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4524532572499174488?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4524532572499174488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4524532572499174488' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4524532572499174488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4524532572499174488'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/04/looking-for-nginx-c-developers.html' title='Looking for nginx C developers'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8507456357305400446</id><published>2010-04-16T16:41:00.001+08:00</published><updated>2010-04-16T16:41:20.748+08:00</updated><title type='text'>ngx_drizzle v0.0.8 and ngx_rds_json v0.05 released</title><content type='html'>On behalf of the ngx_dbd team, I&amp;#39;m happy to announce the new releases of the ngx_drizzle and ngx_rds_json modules.&lt;br&gt;&lt;br&gt;Here&amp;#39;s the download links for these modules:&lt;br&gt;&lt;ul&gt;&lt;li&gt;ngx_drizzle v0.0.8&lt;br&gt;  &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module/tarball/v0.0.8"&gt;http://github.com/chaoslawful/drizzle-nginx-module/tarball/v0.0.8&lt;/a&gt;&lt;/li&gt; &lt;li&gt;ngx_rds_json v0.05&lt;br&gt;  &lt;a href="http://github.com/agentzh/rds-json-nginx-module/tarball/v0.05"&gt;http://github.com/agentzh/rds-json-nginx-module/tarball/v0.05&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;ngx_drizzle is a non-blocking upstream module for mysql, drizzle, and&lt;br&gt; sqlite. Its project page is on GitHub:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;http://github.com/chaoslawful/drizzle-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;ngx_rds_json is an output filter module that can format the Resty DBD&lt;br&gt; Stream (RDS) outputs of ngx_drizzle and other database driver modules&lt;br&gt;to JSON. Its project page is also on GitHub:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/rds-json-nginx-module"&gt;http://github.com/agentzh/rds-json-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;Below is a brief list of (major) changes since their last releases:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Fixed a nasty bug in ngx_drizzle&amp;#39;s connection pool. Now the drizzle_keepalive directive&amp;#39;s overflow=reject option works for real now. Thanks Piotr Sikora for reporting this issue. (agentzh)&lt;/li&gt; &lt;li&gt;Updated the Resty DBD Stream (RDS) format to version 0.0.3 which specifies that SQL NULL field values are represented by setting field length == (uint32_t) -1 and empty trailing data section. Thanks Piotr Sikora for reporting this issue. (agentzh)&lt;/li&gt; &lt;li&gt;ngx_drizzle and ngx_json now both supports RDS v0.0.3 and can differentiate SQL NULL values and SQL empty strings (&amp;quot;&amp;quot;). (agentzh)&lt;/li&gt;&lt;li&gt;Now we postpone the header sending action after we parse the RDS header. So errors in RDS headers can result in proper 500 response headers. Thanks Piotr Sikora for suggesting this. (agentzh)&lt;/li&gt; &lt;li&gt;Fixed a small bug in ngx_rds_json that may cause random hang. (This bug also appeared in my fork of ngx_eval, fixed there as well.) (agentzh)&lt;/li&gt;&lt;li&gt;ngx_drizzle now returns 500 Internal Server Error  instead of 502 Bad Gateway for bad SQL queries, bad tables, DB connection failures. (Piotr Sikora)&lt;/li&gt; &lt;li&gt;Fixed a bug that could cause double free in ngx_drizzle. (Piotr Sikora)&lt;/li&gt;&lt;li&gt;ngx_drizzle now works with libdrizzle 0.7 and 0.8.&lt;/li&gt;&lt;/ul&gt;Piotr Sikora does have more fixes and/or improvements in his ngx_postgres module that is expected to be back-ported to ngx_drizzle some time in the near future :)&lt;br&gt; &lt;br&gt;P.S. The original creator of the ngx_drizzle project, chaoslawful, is currently working on ngx_lua and he&amp;#39;s got something runnable already. We&amp;#39;ll make the first public release of ngx_lua in the near future. Stay tuned!&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8507456357305400446?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8507456357305400446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8507456357305400446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8507456357305400446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8507456357305400446'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/04/ngxdrizzle-v008-and-ngxrdsjson-v005.html' title='ngx_drizzle v0.0.8 and ngx_rds_json v0.05 released'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-1630040326003931935</id><published>2010-04-10T21:56:00.001+08:00</published><updated>2010-04-10T21:56:50.434+08:00</updated><title type='text'>Slides for my talk on nginx.conf scripting</title><content type='html'>I gave a talk on nginx.conf scripting in today&amp;#39;s PerlChina monthly meeting. Here&amp;#39;s the (English) slides that I used:&lt;br&gt;&lt;br&gt;    &lt;a href="http://agentzh.org/misc/slides/nginx-conf-scripting/nginx-conf-scripting.html"&gt;http://agentzh.org/misc/slides/nginx-conf-scripting/nginx-conf-scripting.html&lt;/a&gt;&lt;br&gt; &lt;br&gt;Web browsers other than IE can be used to view these slides. Use your mouse&amp;#39;s left and right keys or the arrow keys on your keyboard to move forwards and backwards.&lt;br&gt;&lt;br&gt;Comments will be highly appreciated as usual ;)&lt;br&gt; &lt;br&gt;Have fun!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-1630040326003931935?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/1630040326003931935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=1630040326003931935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1630040326003931935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/1630040326003931935'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/04/slides-for-my-talk-on-nginxconf.html' title='Slides for my talk on nginx.conf scripting'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2658164551124160100</id><published>2010-03-23T10:44:00.001+08:00</published><updated>2010-03-23T10:44:48.391+08:00</updated><title type='text'>set_encode_base32 and set_decode_base32 for nginx.conf</title><content type='html'>I&amp;#39;ve just implemented the set_encode_base32 and set_decode_base32 in our &lt;a href="http://github.com/agentzh/set-misc-nginx-module"&gt;ngx_set_misc&lt;/a&gt; module.&lt;br&gt;&lt;br&gt;Here&amp;#39;s a small example from its test suite:&lt;br&gt;&lt;br&gt;     location /bar {&lt;br&gt;        set $a &amp;#39;&amp;quot;hello, world!\nhiya&amp;quot;&amp;#39;;&lt;br&gt;        set_encode_base32 $a;&lt;br&gt;        set $b $a;&lt;br&gt;        set_decode_base32 $b;&lt;br&gt;&lt;br&gt;        echo $a;&lt;br&gt;        echo $b;&lt;br&gt;    }&lt;br&gt; &lt;br&gt;Performing GET /bar yields the following response body&lt;br&gt;&lt;br&gt;    49k6ar3cdsm20trfe9m6888ad1knio92&lt;br&gt;    &amp;quot;hello, world!&lt;br&gt;    hiya&amp;quot;&lt;br&gt;&lt;br&gt;The first line is the Base32 form for the text spanning the last two lines. See &lt;a href="http://www.faqs.org/rfcs/rfc3548.html"&gt;RFC 3548&lt;/a&gt; for more details on the Base32 encoding if you&amp;#39;re not familiar with it ;)&lt;br&gt; &lt;br&gt;A lot of thanks go to chaoslawful++ for implementing the encode_base32 and decode_base32 functions.&lt;br&gt;&lt;br&gt;Have fun :)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2658164551124160100?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2658164551124160100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2658164551124160100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2658164551124160100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2658164551124160100'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/03/setencodebase32-and-setdecodebase32-for.html' title='set_encode_base32 and set_decode_base32 for nginx.conf'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5538408672446609695</id><published>2010-03-19T14:20:00.001+08:00</published><updated>2010-03-19T14:20:50.980+08:00</updated><title type='text'>Setting up our pure JS blog app atop ngx_openresty</title><content type='html'>We&amp;#39;ve been working very hard on ngx_openresty in the last few months. For now our blog site written in pure JavaScript has been ported to the new ngx_openresty and it runs *very* fast.&lt;br&gt;&lt;br&gt;It should be first mentioned that there&amp;#39;s not a top-level nginx module named ngx_openresty. Physically ngx_openresty is just a set of loosely coupled nginx modules that can also be used independently.&lt;br&gt;  &lt;br&gt;Here&amp;#39;s a brief explanation on how to set it up on your machine. It has been tested on Linux but should also work on *BSD or Mac. If it does not work for you, just ask in the &lt;a href="http://groups.google.com/group/OpenResty" target="_blank"&gt;OpenResty mailing list&lt;/a&gt; ;)&lt;br&gt;  &lt;br&gt;&lt;ol&gt;&lt;li&gt;Grab the various nginx 3rd-party modules:&lt;br&gt;   ngx_echo  &lt;a href="http://github.com/agentzh/echo-nginx-module" target="_blank"&gt;http://github.com/agentzh/echo-nginx-module&lt;/a&gt;&lt;br&gt;   ngx_xss  &lt;a href="http://github.com/agentzh/xss-nginx-module" target="_blank"&gt;http://github.com/agentzh/xss-nginx-module&lt;/a&gt;&lt;br&gt;     NDK  &lt;a href="http://github.com/agentzh/ngx_devel_kit" target="_blank"&gt;http://github.com/agentzh/ngx_devel_kit&lt;/a&gt;&lt;br&gt;   ngx_set_misc  &lt;a href="http://github.com/agentzh/set-misc-nginx-module" target="_blank"&gt;http://github.com/agentzh/set-misc-nginx-module&lt;/a&gt;&lt;br&gt;     ngx_rds_json  &lt;a href="http://github.com/agentzh/rds-json-nginx-module" target="_blank"&gt;http://github.com/agentzh/rds-json-nginx-module&lt;/a&gt;&lt;br&gt;   ngx_drizzle  &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module" target="_blank"&gt;http://github.com/chaoslawful/drizzle-nginx-module&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;Grab the latest nginx core:&lt;br&gt;   &lt;a href="http://nginx.org/" target="_blank"&gt;http://nginx.org/&lt;/a&gt;&lt;br&gt;(Last tested version is 0.8.33.)&lt;/li&gt;&lt;li&gt;Build the nginx executable with these modules enabled:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;   ./configure \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/eval-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/echo-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/xss-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/ndk-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/set-misc-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/rds-json-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         --add-module=/path/to/drizzle-nginx-module&lt;/span&gt;&lt;br&gt;&lt;br&gt;Please note that the order of the --add-module option is very important for those filter modules among them.&lt;/li&gt;  &lt;li&gt;Set up your mysql database for the blog app using the following SQL file:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/ngx_openresty/blob/master/demo/Blog/misc/mysql/init-db.sql" target="_blank"&gt;http://github.com/agentzh/ngx_openresty/blob/master/demo/Blog/misc/mysql/init-db.sql&lt;/a&gt;&lt;br&gt;  &lt;br&gt;I assume you use the following command to execute the sql against your mysql instance:&lt;br&gt;&lt;br&gt;   mysql -h localhost -p -u monty test &amp;lt; init-db.sql&lt;br&gt;&lt;br&gt;where your db user name is &amp;quot;monty&amp;quot; and the test db name is &amp;quot;test&amp;quot;.&lt;br&gt;  &lt;br&gt;There&amp;#39;s some row data for the posts and comments tables that you can import into your &amp;quot;test&amp;quot; database:&lt;br&gt;&lt;br&gt;   &lt;a href="http://agentzh.org/misc/blog-rows.sql" target="_blank"&gt;http://agentzh.org/misc/blog-rows.sql&lt;/a&gt;&lt;br&gt;  &lt;br&gt;This is a mysqldump on my side. (Be careful with charsets.)&lt;/li&gt;&lt;li&gt;Grab the following nginx.conf file from my site:&lt;br&gt;&lt;br&gt;    &lt;a href="http://agentzh.org/misc/nginx.conf" target="_blank"&gt;http://agentzh.org/misc/nginx.conf&lt;/a&gt;&lt;br&gt; &lt;br&gt; Edit the following snippet if your mysql database has a different set of connection option:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;   upstream backend {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;        drizzle_server &lt;a href="http://127.0.0.1:3306" target="_blank"&gt;127.0.0.1:3306&lt;/a&gt; dbname=test&lt;/span&gt; &lt;span style="font-family: courier new,monospace;"&gt;        password=some_pass user=monty protocol=mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;        drizzle_keepalive max=400 overflow=ignore;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br&gt;Here I assume your test database is listening to &lt;a href="http://127.0.0.1:3306" target="_blank"&gt;127.0.0.1:3306&lt;/a&gt; and your db name is &amp;quot;test&amp;quot;, your user is &amp;quot;monty&amp;quot; and your password is &amp;quot;some_pass&amp;quot;.&lt;br&gt; &lt;br&gt; Start your nginx compiled earlier using this config file.&lt;/li&gt;&lt;li&gt;Download the blog site written in pure JavaScript and HTML&lt;br&gt;&lt;br&gt;   &lt;a href="http://agentzh.org/misc/blog-site-for-ngx-openresty.tar.gz" target="_blank"&gt;http://agentzh.org/misc/blog-site-for-ngx-openresty.tar.gz&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Unpack it and edit the following line in blog.js if your nginx is not listening to localhost:8080:&lt;br&gt;&lt;br&gt;    &lt;span style="font-family: courier new,monospace;"&gt;var host = &amp;#39;&lt;a href="http://localhost:8080" target="_blank"&gt;http://localhost:8080&lt;/a&gt;&amp;#39;;&lt;/span&gt;&lt;br&gt;  &lt;br&gt;&lt;/li&gt;&lt;li&gt;Open the index.html in the blog site directory with your favorite web browser and it should get alive ;)&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;For now, blog post search and rss feed are not implemented. But the former is coming soon because my &lt;a href="http://github.com/agentzh/array-var-nginx-module" target="_blank"&gt;ngx_array_var&lt;/a&gt; module is mostly ready now ;)&lt;br&gt;  &lt;br&gt;There&amp;#39;s also plans to port this site over to the PostgreSQL backend. Piotr Sikora has completed the ngx_postgres module and it&amp;#39;s compatible with ngx_openresty :)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5538408672446609695?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5538408672446609695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5538408672446609695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5538408672446609695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5538408672446609695'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/03/setting-up-our-pure-js-blog-app-atop.html' title='Setting up our pure JS blog app atop ngx_openresty'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3867560131603237067</id><published>2010-03-16T09:57:00.001+08:00</published><updated>2010-03-16T09:57:14.313+08:00</updated><title type='text'>Companion.JS rocks in IE JS debugging</title><content type='html'>I was having a hard time in debugging JavaScript for Internet Explorer (IE). Luckily I&amp;#39;ve found the &lt;a href="http://www.my-debugbar.com/wiki/CompanionJS/HomePage"&gt;Companion.JS&lt;/a&gt; addon and it works great in at least IE 7 and very easy to install on a plain Windows :D&lt;br&gt; &lt;br&gt;The following article gives a detailed explanation on this handy tool&amp;#39;s motivation and installation:&lt;br&gt;&lt;br&gt;    &lt;a href="http://www.grepsedia.com/development/debugging-javascript-in-ie-without-visual-studios"&gt;http://www.grepsedia.com/development/debugging-javascript-in-ie-without-visual-studios&lt;/a&gt;&lt;br&gt; &lt;br&gt;With this addon, I quicky located a nasty issue in jQuery&amp;#39;s $.html method that fails to construct DOM subtrees in IE yesterday. By setting a node&amp;#39;s innerHTML attribute directly, I finally got my web app running happily in both IE 7 and IE 6 :D&lt;br&gt; &lt;br&gt;No pain any more.&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3867560131603237067?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3867560131603237067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3867560131603237067' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3867560131603237067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3867560131603237067'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/03/companionjs-rocks-in-ie-js-debugging.html' title='Companion.JS rocks in IE JS debugging'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6252192783101587925</id><published>2010-02-05T14:25:00.001+08:00</published><updated>2010-02-05T14:25:26.737+08:00</updated><title type='text'>Start tweeting</title><content type='html'>I&amp;#39;ve just registered a twitter account and here&amp;#39;s my page&lt;br&gt;&lt;br&gt;    &lt;a href="http://twitter.com/agentzh"&gt;http://twitter.com/agentzh&lt;/a&gt;&lt;br&gt;&lt;br&gt;Fee free to follow me. And I&amp;#39;ll try sticking to English in my messages ;)&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6252192783101587925?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6252192783101587925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6252192783101587925' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6252192783101587925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6252192783101587925'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/02/start-tweeting.html' title='Start tweeting'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3818586566148961537</id><published>2010-02-03T12:20:00.001+08:00</published><updated>2010-02-03T12:20:28.240+08:00</updated><title type='text'>一个关于动态应用单核千级 rps 的传说</title><content type='html'>我们在过去的四个月中，已经开发了 8 个 nginx C 模块（第 8 个这两天刚放到 GitHub 上面，名为 &lt;a href="http://github.com/agentzh/set-misc-nginx-module" target="_blank"&gt;ngx_set_misc&lt;/a&gt; ），后面还会有更多更精彩的模块甚至应用面世。这些模块的功能看起来很碎很零散，但其实是一个更宏伟的项目的组成部分。这个项目叫做 ngx_openresty.&lt;br&gt; &lt;br&gt;我们的一个方向是几个客户端 .js 文件 + 几个 .html/.css 文件 + nginx.conf 搞定一个完整的交互式 web 应用，或者至少是一个很复杂应用的比较大的一部分。&lt;br&gt; &lt;br&gt;不幸的是，业界的一些同仁对这种应用开发模式产生了质疑，认为我们对 nginx 的各种应用层面的扩展让 nginx 自身变得臃肿和低效。本文旨对这些质疑进行一次非正式的驳斥。目的不在于驳人面子和树己威风，而是为了争取更多的朋友加入我们在 nginx 领域的努力。&lt;br&gt;&lt;br&gt;我们已经在 ngx_openresty 原型的基础上，使用 nginx.conf 和纯客户端 JavaScript 开发了一个比较完整的 blog 应用（源码在这里： &lt;a href="http://github.com/agentzh/ngx_openresty/tree/master/demo/Blog/"&gt;http://github.com/agentzh/ngx_openresty/tree/master/demo/Blog/&lt;/a&gt; ）&lt;br&gt; &lt;br&gt;在我们的高并发实测中，单核能扛千级 rps，小请求在 keepalive 下几百并发也可以扛到 ~ 6000 rps，且禁用了 nginx 级别的结果集 cache，内存、CPU 等资源的占用只是 php 等传统应用的一个零头，呵呵。其主要原因是：&lt;br&gt;&lt;br&gt;&lt;ol&gt;&lt;li&gt;都是认真书写的 C 代码来完成原先 PHP 等代码来完成的事情，&lt;/li&gt;&lt;li&gt;绝大部分应用都是 I/O 密集型的，所以让 nginx 的高效的事件模型来统一调度整个应用的所有网络 I/O 操作（包括到 DB 等后端的），只会进一步提高性能，而非降低。相比之下，用 PHP 等脚本语言访问 mysql，一定会阻塞当前 PHP 进程或者线程，而 PHP 解释器的阻塞开销是非常大的。&lt;/li&gt; &lt;li&gt;我们总是可以通过 LVS + 多机 nginx 来线性 scale. 总体资源是一个常量，不会因为多启几个进程和线程就会增加，只要不是浪费。阻塞在 I/O 操作上、在多进程多线程间无谓地切换和争用、在后端应用和 nginx 之间通过 socket 复制请求和应答数据，等等等等，这些才是浪费。&lt;br&gt;&lt;/li&gt;&lt;li&gt;通过 fastcgi 等协议，PHP 这些脚本语言不免要自己再解析一遍 HTTP 头和 URL 参数啥的，还要自己做 URL 分发；而 nginx 其实一般都已经解析和处理过了。&lt;/li&gt; &lt;li&gt;根据模版渲染 HTML 展现的工作现改由客户浏览器去做了，又进一步节约了服务器端的计算。如果一秒有几千请求，在 cache miss 的情况下，就可以节约几千次 HTML 渲染，这累积起来，相比生成 JSON 是相当可观的，呵呵。&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;如果还有我没有想到的理由，请来信补充，呵呵。&lt;br&gt;&lt;br&gt;其实我们的方向不算特别新奇，Apache 2.2 早在几年前就提供了强大的 apr-dbd API 和 mod_dbd 模块来提供从 server 到 mysql/pgsql/oracle/odbc 这些数据库后端的直连服务。&lt;br&gt; &lt;br&gt;我们在雅虎工作的时候，也曾经通过 Apache 2.2 mod_dbd + PostgreSQL 后端搭建过单机几千 rps 的服务。即使在那个 DB I/O 阻塞 apache worker 线程的场景中，我们也没觉得 Apache 在线上的性能差到哪儿去了，呵呵。&lt;br&gt;&lt;br&gt;当然，我们有机会在 nginx 世界中做得比 Apache dbd 更好 ;) nginx 的内部架构比 Apache2 优秀多了，这是真的，呵呵。&lt;br&gt; &lt;br&gt;所以还是面对现实，让我们一起拥抱高简洁和高性能吧！呵呵！&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3818586566148961537?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3818586566148961537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3818586566148961537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3818586566148961537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3818586566148961537'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/02/rps.html' title='一个关于动态应用单核千级 rps 的传说'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7292065935150392265</id><published>2010-02-01T17:17:00.001+08:00</published><updated>2010-02-01T17:17:25.716+08:00</updated><title type='text'>ngx_drizzle v0.0.7: now running on *BSD</title><content type='html'>We&amp;#39;re proud to announce the v0.0.7 release for the &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module" target="_blank"&gt;ngx_drizzle&lt;/a&gt; module.&lt;br&gt;&lt;br&gt;ngx_drizzle is an upstream nginx module that can help nginx talk directly to mysql and other RDBMS backends that support the mysql or drizzle TCP protocol.&lt;br&gt;  &lt;br&gt;This release includes patches from our new contributor Piotr Sikora to make this module work with kqueue and other event models on *BSD systems. (Now select/poll/epoll/kqueue all have been tested, but for rgsig, the server will hang.)&lt;br&gt;  &lt;br&gt;Also, this release fixed a long-standing bug captured by Piotr that the nginx process may crash when DB queries complete in a single run of upstream function calls under high traffic.&lt;br&gt;&lt;br&gt;We have also tested this module with the recent new release of &lt;a href="https://launchpad.net/libdrizzle" target="_blank"&gt;libdrizzle&lt;/a&gt;, v0.7.&lt;br&gt;  &lt;br&gt;Release tarballs can be downloaded below&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module/downloads" target="_blank"&gt;http://github.com/chaoslawful/drizzle-nginx-module/downloads&lt;/a&gt;&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7292065935150392265?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7292065935150392265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7292065935150392265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7292065935150392265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7292065935150392265'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/02/ngxdrizzle-v007-now-running-on-bsd.html' title='ngx_drizzle v0.0.7: now running on *BSD'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5120599578109972798</id><published>2010-01-29T15:28:00.001+08:00</published><updated>2010-01-29T15:28:08.873+08:00</updated><title type='text'>ngx_memc v0.06: new directive memc_flags_to_last_modified</title><content type='html'>I&amp;#39;m pleased to announce the v0.06 release of the ngx_memc module:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpMemcModule"&gt;http://wiki.nginx.org/NginxHttpMemcModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;This release has the highlight of a new directive named &amp;quot;memc_flags_to_last_modified&amp;quot;.&lt;br&gt; &lt;br&gt;If this directive is turned on, then for memcached get operations, ngx_memc will read the memcached flags as epoch seconds and set it as the value of the Last-Modified header.&lt;br&gt;&lt;br&gt;For conditional GET requests, it will signal nginx&amp;#39;s not_modified_filter module to return the &amp;quot;304 Not Modified&amp;quot; response to save bandwidth.&lt;br&gt; &lt;br&gt;Here&amp;#39;s a small sample config that I&amp;#39;ve tested with ngx_memc v0.06:&lt;br&gt;&lt;br&gt;   # read the memcached flags into the Last-Modified header&lt;br&gt;   # to respond 304 to conditional GET&lt;br&gt;   location /memc {&lt;br&gt;       set $memc_key $arg_key;&lt;br&gt; &lt;br&gt;       memc_pass &lt;a href="http://127.0.0.1:11984"&gt;127.0.0.1:11984&lt;/a&gt;;&lt;br&gt;&lt;br&gt;       memc_flags_to_last_modified on;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;My GET request sets the following header:&lt;br&gt;&lt;br&gt;    If-Modified-Since: Thu, 28 Jan 2010 12:09:23 GMT&lt;br&gt; &lt;br&gt;And the key stored in memcached has the flags 1264680563. Then we get&lt;br&gt;&lt;br&gt;  $ curl -H &amp;#39;If-Modified-Since: Thu, 28 Jan 2010 12:09:23 GMT&amp;#39; \&lt;br&gt;                                       -I &amp;#39;&lt;a href="http://localhost:1984/memc?key=foo"&gt;http://localhost:1984/memc?key=foo&lt;/a&gt;&amp;#39;&lt;br&gt;   HTTP/1.1 304 Not Modified&lt;br&gt;  Server: nginx/0.8.32&lt;br&gt;  Date: Fri, 29 Jan 2010 07:10:52 GMT&lt;br&gt;  Last-Modified: Thu, 28 Jan 2010 12:09:23 GMT&lt;br&gt;  Connection: keep-alive&lt;br&gt;&lt;br&gt;How about setting the flag with ngx_memc too? Well, I&amp;#39;m going to implement the $echo_time and $echo_http_time variables in our ngx_echo module so that we can have&lt;br&gt; &lt;br&gt;      set $memc_flags $echo_time;&lt;br&gt;      add_header Last-Modified $echo_http_time;&lt;br&gt;&lt;br&gt;for memcached storage operations set/add/etc. That is, $echo_time will return the epoch seconds while $echo_http_time returns the textual representation in the HTTP date format. Patches welcome! Volunteers welcome!&lt;br&gt; &lt;br&gt;Have fun! &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5120599578109972798?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5120599578109972798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5120599578109972798' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5120599578109972798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5120599578109972798'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/ngxmemc-v006-new-directive.html' title='ngx_memc v0.06: new directive memc_flags_to_last_modified'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7799780265413052766</id><published>2010-01-26T18:33:00.000+08:00</published><updated>2010-01-26T18:34:01.255+08:00</updated><title type='text'>ngx_xss: Native support for cross-site scripting in an nginx</title><content type='html'>I&amp;#39;m delighted to announce the first release of our new module, &lt;a href="http://github.com/agentzh/xss-nginx-module" target="_blank"&gt;ngx_xss&lt;/a&gt;. This output filter module adds native support for simple cross-site AJAX to the nginx server. Currently only cross-site GET is implemented, but cross-site POST support is on our TODO list.&lt;br&gt;  &lt;br&gt;Here&amp;#39;s a small example using our &lt;a href="http://wiki.nginx.org/NginxHttpEchoModule" target="_blank"&gt;ngx_echo&lt;/a&gt; module together:&lt;br&gt;&lt;br&gt;   &lt;span style="font-family: courier new,monospace;"&gt;location /foo {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     default_type &amp;quot;application/json&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     echo &amp;#39;{&amp;quot;errcode&amp;quot;:400,&amp;quot;errstr&amp;quot;:&amp;quot;Bad Request&amp;quot;}&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     xss_get on; # enable cross-site GET support&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     xss_callback_arg callback; # use $arg_callback&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt; }&lt;/span&gt;&lt;br&gt;&lt;br&gt;Then accessing /foo?callback=blah gives the following response:&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  blah({&amp;quot;errcode&amp;quot;:400,&amp;quot;errstr&amp;quot;:&amp;quot;Bad Request&amp;quot;}&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;   );&lt;/span&gt;&lt;br&gt;&lt;br&gt;And the ultimate response Content-Type is set to &amp;quot;application/x-javascript&amp;quot;, which can be overridden by the &amp;quot;xss_output_type&amp;quot; directive like this&lt;br&gt;  &lt;br&gt;    &lt;span style="font-family: courier new,monospace;"&gt;xss_output_type text/javascript;&lt;/span&gt;&lt;br&gt;&lt;br&gt;By default, the ngx_xss module filter will skip responses with Content-Type set to anything other than &amp;quot;application/json&amp;quot;. If that&amp;#39;s not what you want, you can use the &amp;quot;xss_input_types&amp;quot; directive to override that:&lt;br&gt;  &lt;br&gt;   &lt;span style="font-family: courier new,monospace;"&gt;xss_input_types text/plain text/css;&lt;/span&gt;&lt;br&gt;&lt;br&gt;This module can also be chained with other output filters like &lt;a href="http://github.com/agentzh/rds-json-nginx-module" target="_blank"&gt;ngx_rds_json&lt;/a&gt;:&lt;br&gt;  &lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;  xss_get             on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   xss_callback_arg    _callback;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   location /query {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;      drizzle_query &amp;quot;select name from products limit 0, 10&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;      drizzle_backend my_mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;      rds_json on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;   }&lt;/span&gt;&lt;br&gt;&lt;br&gt;Then you can expect something like this when doing GET /query?_callback=OpenResty.callback[32]&lt;br&gt;&lt;br&gt;    &lt;span style="font-family: courier new,monospace;"&gt;OpenResty.callback[32]([{&amp;quot;name&amp;quot;:&amp;quot;Bike&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;Book&amp;quot;}]);&lt;/span&gt;&lt;br&gt;  &lt;br&gt;Be careful with the order of output filters while building nginx. The ngx_rds_json filter expects a valid binary stream in the RDS format while the ngx_xss filter expects some JSON text. If you don&amp;#39;t take the order right, you&amp;#39;ll see your ngx_xss settings get completely ingored in the final responses. Because the ngx_xss filter sees RDS first and it ignores it due to its &amp;quot;application/x-resty-dbd-stream&amp;quot; content type.&lt;br&gt;  &lt;br&gt;Below is the correct nginx configure command if you want to use ngx_xss and ngx_rds_json together:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt; ./configure \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;    --add-module=/path/to/xss-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    --add-module=/path/to/rds-json-nginx-module \&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;    # more options omitted here...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br&gt;You see, the order of adding output filters on the configure time is just the &lt;i&gt;reversed&lt;/i&gt; order that the output filters are actually applied at runtime. Generally speaking, the nginx output filter chain is a stack, not a queue ;)&lt;br&gt;  &lt;br&gt;Only a very limited set of callback values is allowed to prevent JavaScript injection. Valid callback values can be expressed using the following (Ragel) grammar:&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;  identifier = [$A-Za-z] [$A-Za-z0-9_]*;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;   index = [0-9]* &amp;#39;.&amp;#39; [0-9]+&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         | [0-9]+&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         ;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&lt;br&gt;  main := identifier ( &amp;#39;.&amp;#39; identifier )*&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;               (&amp;#39;[&amp;#39; index &amp;#39;]&amp;#39;)?&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;This is exactly the Ragel grammar used to generate the C validator used by the ngx_xss module itself.&lt;br&gt;  &lt;br&gt;Here goes the project home page &amp;amp; code repository:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/xss-nginx-module" target="_blank"&gt;http://github.com/agentzh/xss-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;as well as the download page for release tarballs:&lt;br&gt;  &lt;br&gt;   &lt;a href="http://github.com/agentzh/xss-nginx-module/downloads" target="_blank"&gt;http://github.com/agentzh/xss-nginx-module/downloads&lt;/a&gt;&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7799780265413052766?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7799780265413052766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7799780265413052766' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7799780265413052766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7799780265413052766'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/ngxxss-native-support-for-cross-site.html' title='ngx_xss: Native support for cross-site scripting in an nginx'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3841969844341796717</id><published>2010-01-19T16:18:00.001+08:00</published><updated>2010-01-19T16:18:40.379+08:00</updated><title type='text'>ngx_rds_json: help ngx_drizzle and other DBD modules to emit JSON  data</title><content type='html'>I&amp;#39;m happy to announce the first release of our ngx_rds_json module that can convert Resty DBD Streams (RDS) to JSON.&lt;br&gt;&lt;br&gt;As some of you might have noticed, the mysql/drizzle DBD driver module &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module" target="_blank"&gt;ngx_drizzle&lt;/a&gt; generates a specific binary stream in a format known as RDS that is defined by ourselves. We introduced RDS just because we don&amp;#39;t want to bind to a specific textual format and makes internal data exchange or conversion unnecessarily hard.&lt;br&gt;  &lt;br&gt;As web app developers, we&amp;#39;re certainly more interested in more popular textual formats like JSON, YAML, CSV, or even HTML. This module does the job of formating RDS to JSON in a truly streaming fashion.&lt;br&gt;&lt;br&gt;The project is hosted on GitHub as our other nginx modules:&lt;br&gt;  &lt;br&gt;     &lt;a href="http://github.com/agentzh/rds-json-nginx-module/" target="_blank"&gt;http://github.com/agentzh/rds-json-nginx-module/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Release tarballs can be downloaded from here&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/rds-json-nginx-module/downloads" target="_blank"&gt;http://github.com/agentzh/rds-json-nginx-module/downloads&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Just as the ngx_drizzle module, this module is now considered highly experimental, but it&amp;#39;s maturing very rapidly because it&amp;#39;s part of our Taobao.com&amp;#39;s company $project. If you have found any bugs, or any wishlist, please send us mails or create tickets on GitHub.&lt;br&gt;  &lt;br&gt;Here&amp;#39;s some typical use cases drawn from ngx_rds_json&amp;#39;s test suite ( &lt;a href="http://github.com/agentzh/rds-json-nginx-module/blob/master/test/t/sanity.t" target="_blank"&gt;http://github.com/agentzh/rds-json-nginx-module/blob/master/test/t/sanity.t&lt;/a&gt; ):&lt;br&gt;  &lt;br&gt;&lt;ul&gt;&lt;li&gt;Use Case 1&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;    mysql db init&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    create table cats (id integer, name text);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     insert into cats (id) values (2);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     insert into cats (id, name) values (3, &amp;#39;bob&amp;#39;);&lt;/span&gt;&lt;br&gt;&lt;br&gt;    nginx.conf&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    upstream backend {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         drizzle_server &lt;a href="http://127.0.0.1:3306" target="_blank"&gt;127.0.0.1:3306&lt;/a&gt; dbname=test&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;              password=some_pass user=monty&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;              protocol=mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     server {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         location /mysql {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             drizzle_pass backend;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;             drizzle_query &amp;#39;select * from cats&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             rds_json on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br&gt;&lt;br&gt;    request&lt;br&gt;&lt;br&gt;        GET /mysql&lt;br&gt;  &lt;br&gt;    response&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   [{&amp;quot;id&amp;quot;:2,&amp;quot;name&amp;quot;:null},{&amp;quot;id&amp;quot;:3,&amp;quot;name&amp;quot;:&amp;quot;bob&amp;quot;}]&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;Use Case 2&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;    mysql db init&lt;br&gt;  &lt;br&gt;        (ditto)&lt;br&gt;&lt;br&gt;    nginx.conf&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    upstream backend {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         # ditto&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     server {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         location /mysql {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;             if ($arg_name ~ &amp;#39;[^A-Za-z0-9]&amp;#39;) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                 return 400;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;             }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             drizzle_pass backend;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;             drizzle_query &amp;quot;update cats set name=&amp;#39;$arg_name&amp;#39; where name=&amp;#39;$arg_name&amp;#39;&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             rds_json on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br&gt;&lt;br&gt;    request&lt;br&gt;&lt;br&gt;        GET /mysql?name=bob&lt;br&gt;  &lt;br&gt;    response&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    {&amp;quot;errcode&amp;quot;:0,&amp;quot;errstr&amp;quot;:&amp;quot;Rows matched: 1  Changed: 0  Warnings: 0&amp;quot;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;Use Case 3&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;      mysql db init&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;    create table foo (id serial, flag bit);&lt;/span&gt;&lt;br&gt;&lt;br&gt;    nginx.conf&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;    upstream backend {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         # ditto&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     server {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         location /mysql {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             if ($arg_bit !~ &amp;#39;^[01]$&amp;#39;) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;                 return 400;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;             drizzle_pass backend;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;             drizzle_query &amp;quot;insert into foo (flag) values ($arg_bit);&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;             rds_json on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;         }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     }&lt;/span&gt;&lt;br&gt;&lt;br&gt;    request&lt;br&gt;&lt;br&gt;        GET /mysql?bit=1&lt;br&gt;&lt;br&gt;    response&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   {&amp;quot;errcode&amp;quot;:0,&amp;quot;insert_id&amp;quot;:1,&amp;quot;affected_rows&amp;quot;:1}&lt;/span&gt;&lt;br&gt;  &lt;br&gt;You&amp;#39;ll see fancier (working) use cases in the test suite, by combining ngx_echo module&amp;#39;s echo_location or echo_location_async directive. Parallel SQL queries can be very useful for certain applications.&lt;br&gt;&lt;br&gt;  As a side note, chaoslawful++ is working on ngx_rds_tt2 module which will allow us to use Perl TT2&amp;#39;s template language to specify custom output formater for RDSs. Here&amp;#39;s a quick example that will work very soon:&lt;br&gt;  &lt;br&gt;  &lt;span style="font-family: courier new,monospace;"&gt;location /myxml {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;      drizzle_query &amp;#39;select * from products&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;      drizzle_pass my_mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;      echo_before_body &amp;#39;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;      echo_before_body &amp;#39;&amp;lt;pie&amp;gt;&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;      rds_tt2_line_template &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         &amp;#39;&amp;lt;slice title=&amp;quot;[% title | xml %]&amp;quot; color=&amp;quot;[% color | xml %]&amp;gt;&amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            &amp;#39;[% count %]&amp;#39;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;         &amp;#39;&amp;lt;/slice&amp;gt;&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;      echo_after_body &amp;#39;&amp;lt;/pie&amp;gt;&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;   &lt;span style="font-family: courier new,monospace;"&gt; }&lt;/span&gt;&lt;br&gt;&lt;br&gt;And you will get streaming output as well, just buffered on the data line level. (in contrast, ngx_json_rds does not buffer data for large fields like BLOBs).&lt;br&gt;  &lt;br&gt;And there will be ngx_srcache that can allow you to buffer database output by ngx_memc + memcached as well ;)&lt;br&gt;&lt;br&gt;Stay tuned!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3841969844341796717?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3841969844341796717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3841969844341796717' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3841969844341796717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3841969844341796717'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/ngxrdsjson-help-ngxdrizzle-and-other.html' title='ngx_rds_json: help ngx_drizzle and other DBD modules to emit JSON  data'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6981373879883032288</id><published>2010-01-15T16:26:00.001+08:00</published><updated>2010-01-15T16:26:05.850+08:00</updated><title type='text'>更多的关于咱们 nginx 新模块的有趣想法。。。</title><content type='html'>今天我和 Marcus Clyne 一直在讨论 ngx_list_var 模块的界面，我建义的最新的版本是这样的：&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; list_map &amp;quot;name=&amp;#39;$it&amp;#39;&amp;quot; $arg_names --to $names --sep &amp;quot;,&amp;quot;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; list_join &amp;quot; or &amp;quot; $names --sep &amp;quot;,&amp;quot; --to $condition;&lt;/span&gt;&lt;br&gt;&lt;br&gt;这样对于 arg_names=dog,cat,tiger 的情形，我们可以在 $condition 里组出 SQL 条件&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; name=&amp;#39;dog&amp;#39; or name=&amp;#39;cat&amp;#39; or name=&amp;#39;tiger&amp;#39;&lt;/span&gt;&lt;br&gt;  &lt;br&gt;其他模块还可以注册新的算子，以用于 list_map，比如 ngx_drizzle 模块可以按 mysql 常量的 quote 规则，提供一个 &amp;quot;drizzle_quote&amp;quot; 算子，于是用户可以这么用：&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; list_map_op drizzle_quote $names --args type=string;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br&gt;这里 --args 可以指定 map 算子的额外的参数。所以我们这里也等于实现了一个简单的 currying，用 Haskell 记法表示就是&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; map (drizzle_quote string) names&lt;/span&gt;&lt;br&gt;&lt;br&gt;这样，nginx 变量能当 list 使，并能玩 lambda，就对 ngx_lua 和 php 的诉求更少了一些。当然，我们不希望自己再做出一个 lua 或者一个 php，平衡很重要 ;)&lt;br&gt;  &lt;br&gt;我一直觉得咱们还缺一个 ngx_urlencode 模块，比如 $arg_xxx 里的都是没有 unescape 的。nginx 核心中虽然提供了 C API，但在 config 文件里并没有暴露出接口来。我希望我们以后可以在 nginx.conf 里这么写：&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; set_url_unescape $names $arg_names;&lt;/span&gt;&lt;br&gt;  &lt;br&gt;或者逆运算：&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; set_url_escape $escaped_url $url;&lt;/span&gt;&lt;br&gt;&lt;br&gt;ngx_urlencode 模块也可以向 ngx_list_var 注册一个 map 算子，这样就爽了：&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp; list_map_op url_unescape $arg_names --to $names;&lt;/span&gt;&lt;br&gt;  &lt;br&gt;这样，即使 $arg_names 里有 %xx 也可以搞定，比如值中有汉字的场合。&lt;br&gt;&lt;br&gt;chaoslawful 先生又想到了一种 nginx 宏结构，可以把若干条重复出现的 nginx 配置指令序列，组合为一个参数化的宏，然后在配置文件要用到的地方展开。比如&lt;br&gt;&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; marco_define drizzle {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; drizzle_query $query;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; drizzle_pass mysql_cluster;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp; };&lt;/span&gt;&lt;br&gt;&lt;br&gt;然后在每次要用的 location 中写成 drizzle; 就可以展开成那两条配置了。这可以通过咱们未来的 ngx_macro 模块来实现，实现细节上应当可以仿照 ngx_eval 模块的做法，即 macro_define 不过是一个参数类型为 block 的指令而已。标准的 map 和 if 指令，还有 geo 也是这么玩的，比如&lt;br&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp; geo $var { ... }&lt;/span&gt;&lt;br&gt;&lt;br&gt;进一步地，define 定义的&amp;ldquo;宏&amp;rdquo;还可以带参数，就像 C 宏那样。。。&lt;br&gt;&lt;br&gt;ngx_macro 的想法，其实是刚刚被一个实际需要驱动的。Marcus 认为 list_split, list_map 和 list_join 经常是组合在一起使用，所以他提议了一个单条指令，以封装了此三种操作。而我和阿哲则认为 lambda 的灵活性因此损失了，于是我们想到了宏定义的方式应当可以两全。&lt;br&gt;  &lt;br&gt;macro_define 和 macro_apply 指令反正是在 config time 完成的，所以没有请求时开销，请求时的效果等价于手写宏定义体中的那些指令。&lt;br&gt;&lt;br&gt;另外还有一个很常见的应用场景，那就是受限于目前 ngx_rewrite 的 if 的制约，经常需要在多个 if 分支中重复相同或者相近的 handler 配置。此时宏可以简化配置文件中的重复的片段。if 虽然被认为 ugly，但确实可以满足不少很具体的业务逻辑的需求，可以少写不少 C 或者 PHP 啥的。if + 正则 + return 的表达力真的已经很强了。目前的 if 有较大制约就是&amp;ldquo;一旦进去了就出不来了&amp;rdquo;，所以才不得不重复书写 handler 的配置。这便是另一个 ngx_macro 模块可以用得着的地方。&lt;br&gt;  &lt;br&gt;这样下去，我们可以让 nginx 配置文件大变样，复杂度肯定是要跑到某个地方的，不在客户端 JS 里写，又不想在 PHP 或者 C &amp;nbsp;或者 Lua 或者 Perl 里写，就只好在 nginx.conf 里写了。&lt;br&gt;&lt;br&gt;在后面的日子里，我们就要开始着手实现这些模块。在此过程中，我们会尽量享用 Marcus 在他的 ngx_devel_kit (NDK) 模块中提供的便利接口和功能。（直接编码 nginx core API 是很痛苦的一件事情呢，哈哈！）&lt;br&gt;  &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6981373879883032288?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6981373879883032288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6981373879883032288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6981373879883032288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6981373879883032288'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/nginx.html' title='更多的关于咱们 nginx 新模块的有趣想法。。。'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4620655448952972385</id><published>2010-01-06T18:38:00.001+08:00</published><updated>2010-01-06T18:38:21.804+08:00</updated><title type='text'>实例分享：利用 Erlang 编写的 TCP Proxy 工具 etcproxy 定位 ngx_drizzle 模块的一个 bug</title><content type='html'>阿哲老师（chaoslawful）的 Erlang 版 TCP proxy 工具 &lt;a href="http://github.com/chaoslawful/etcproxy"&gt;etcproxy&lt;/a&gt;，刚刚成功地帮我定位了 &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; 模块中的几处隐秘的 bug，哈哈！&lt;br&gt;&lt;br&gt;原来我在 &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module/blob/master/src/ngx_http_drizzle_output.c"&gt;ngx_http_drizzle_output.c&lt;/a&gt; 的函数组中的 size 局部变量都忘了初始化为 0 了，哈哈！这种未初始的情形只有在 field 的 packet 被拆分时才会出现。我不用在测试 DB 里准备很大的 blob 数据来测试此种情况，而且非常可靠，每次都能精确复现场景。&lt;br&gt; &lt;br&gt;定位 bug 的具体过程是这样的：我启动 etcproxy，让它的上游是本地 mysql server 监听的 3307，它自己监听 3306 端口，然后我让 nginx 去连 3306. 这样 etcproxy 就会开始作连接和数据流中传。它提供了一些选项（目前是写在代码内部的宏定义）。我是这样使用的，先设置了按每字节来拆分 packet 数据，即 mysql 发送的 packet 都被强制拆成了一个字节一个 packet. 同时我设置了相邻发送的 packet 之间的延时为 1ms，这样这些小 packet 在 localhost 方式发送时，不会被 kernel 自动合并。于是 nginx 得到的 packet 也是一个字节，再一个字节的。&lt;br&gt; &lt;br&gt;于是这就触发了 libdrizzle 这个流式 mysql 客户端的 field 分割逻辑，即对于结果集中的一个 field，会分多份返回给我的 ngx_drizzle 模块，而我的模块对于多片的 offset + len 的 field 值接收代码，正好有刚才提到的 size 未初始化为 0 的 bug，于是出现了 size 为 4 这样的随机数的情形。这样最终导致 buffer 使用发生错误，并被我自己的一个 buffer 指针断言给捕捉到了，抛到了 nginx 的 error.log 里；与此同时，我的 Test::Nginx 测试台也发现 nginx 的输出发生了截断，结果不是期望，并在终端上向我报了错误，我也就第一时间看到了。&lt;br&gt; &lt;br&gt;其实它还有一个功能，我还没有及使用。那就是在指定的读或者写的 data 偏移量处发生超时或者关闭上下游的 TCP 连接。这个也可以精确地测试我的非阻塞客户端的状态机的一些特殊方面，主要就是在特定状态下，超时和连接出错的处理代码，是否如期望那般运行了，哈哈哈。比如在接受 SQL 查询结果的 columns 部分的超时定时器是否如期望的工作，接受 rows 时的超时定时器是否也如期望般的工作了。&lt;br&gt;&lt;br&gt;今晚我决定给自己做点好吃的，庆祝一下这个 bug 的顺利定位和修复，呵呵！&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4620655448952972385?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4620655448952972385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4620655448952972385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4620655448952972385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4620655448952972385'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/erlang-tcp-proxy-etcproxy-ngxdrizzle.html' title='实例分享：利用 Erlang 编写的 TCP Proxy 工具 etcproxy 定位 ngx_drizzle 模块的一个 bug'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-128519714760440200</id><published>2010-01-06T12:39:00.001+08:00</published><updated>2010-01-06T12:39:57.257+08:00</updated><title type='text'>关于 ngx_drizzle 和 ngx_rds 的一些随机的想法。。。</title><content type='html'>我终于想到了为我的 &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle 模块&lt;/a&gt;再添加一条 drizzle_type 指令，这样用户可以自定义嵌入 SQL 的参数类型和正则约束，比如：&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; drizzle_type email &amp;#39;^[-A-Za-z0-9._]+\@\w+\.(?:com|cn|net)&amp;#39; quote=on;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace;"&gt;drizzle_quote $arg_email email;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace;"&gt;drizzle_query &amp;quot;select * from users where email=$arg_email&amp;quot;;&lt;/span&gt;&lt;br&gt; &lt;br&gt;这样内建类型 column, table, int, bool 啥的也可以让用户自己覆盖了，哈哈！ngx_drizzle 其实已经拥有了 OpenResty View API 的主要功能了，哈哈哈，而且更灵活，更高效！&lt;br&gt;&lt;br&gt;我刚才吃早饭的时候，还想到可以为咱的二进制的 Resty DBD Stream (RDS) 格式再引入两种非结构化的查询结果类型&lt;br&gt;&lt;ul&gt;&lt;li&gt;一是结果是单个 field value 的，&lt;/li&gt; &lt;li&gt;二是结果是多个 field value 的线性列表&lt;/li&gt;&lt;/ul&gt;这样可以在 ngx_rds 模块中通过 output filter 对 RDS 结果集进行 Excel 风格的&amp;ldquo;单元格&amp;rdquo;或者&amp;ldquo;单元格区域&amp;rdquo;的 pick 操作。只要我们的 ngx_rds_json 等数据格式化器也支持这两种新类型，就可以生成更直接的 JSON 表示，从而简化在 ngx_eval 这样的 subrequest in memory 的上下文中的 if + 正则等判断处理。&lt;br&gt; &lt;br&gt;我同时还想到了通过更高层的 merger 来融合多个 RDS 流。比如每个流分别来自不同 mysql 机器的 select + order by 查询，然后 merger 再把这些 RDS 结果进行流式的全局的 order by. 在牺牲流处理并限定各个 RDS 支流的情况下，还可以进行多 RDS 支流的全局 join/group by 等操作。&lt;br&gt;&lt;br&gt;这些都将是 &amp;nbsp;ngx_rds 模块的功能，同时支持 RDS picker 和 merger :D&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-128519714760440200?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/128519714760440200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=128519714760440200' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/128519714760440200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/128519714760440200'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/ngxdrizzle-ngxrds.html' title='关于 ngx_drizzle 和 ngx_rds 的一些随机的想法。。。'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4183406892132483219</id><published>2010-01-04T11:48:00.001+08:00</published><updated>2010-01-04T11:48:53.010+08:00</updated><title type='text'>为 nginx 正名，为 Igor 申冤</title><content type='html'>刚才在和 cnhackTNT 聊到 ngx_drizzle 模块未来的若干种极酷的玩法的时候，不由地开始感慨 nginx 社区大部分用户其实并没有真正理解 nginx 的设计真谛。包括目前网上流行的那些 nginx 的玩法，本身都是直接违反作者 &lt;a href="http://sysoev.ru/en/"&gt;Igor Sysoev&lt;/a&gt; 老大的设计初衷和本意的。&lt;br&gt;&lt;br&gt;所以从这个意义上讲，Igor 是孤独的。这也是为什么 Igor 有时终于忍不住在 nginx 列表里揭斯底里地说他压根原本就不想支持 fastcgi，他压根就不想把 nginx 的 proxy 模块做成第二个 Squid。当然了，Igor 自己玩的 ngx_perl 模块也违反了 nginx 的设计原则，包括他自己说要做的 ngx_v8 模块。不过我相信 Igor 这两个模块只是玩玩而已，耍酷之类。&lt;br&gt; &lt;br&gt;真正对 nginx 有意义的脚本语言引擎，是那些支持 C 级别的 coroutine 的解释器，perl 和 v8 都不满足这一基本条件。（ coco lua 是可以的！）nginx 的核心是非阻塞，是的，再说一遍，非阻塞。Fastcgi 协议的另一边永远是阻塞的，ngx_perl 和 ngx_v8 中的脚本代码运行时永远是阻塞的，ngx_proxy 协议的另一头经常也是阻塞的，所以说它们没有本质的意义和价值，不会带来性能的真正飞跃 。&lt;br&gt; &lt;br&gt;Igor 在 nginx core 中设计了极为精巧的非阻塞的编程模型，无论是 subrequest, 还是 upstream，但极少有人了解这些，&lt;br&gt;极少人有欣赏这些，更少有人懂得去利用好这些。在非阻塞和并发 I/O 的上下文中，编程模型和传统的代码是很不一样的&lt;br&gt;就像 JS 的许多写法和 perl 里极不相同一样，其道理本身倒不难理解，但对于"精巧"的感悟，则需要对 core 的更多了解 ;)&lt;br&gt;基于此，所以我说 Igor 是孤独的，所以我说 nginx 社区许多朋友其实不懂高并发，不懂高性能，不懂 &lt;a href="http://www.kegel.com/c10k.html"&gt;C10K&lt;/a&gt;，呵呵。&lt;br&gt; &lt;br&gt;当然了，这一切我也是在晓哲老师过去几个月每日一课的耐心点拨下，在我手抄了 nginx core 中的大量 C 源之后，我才开悟的。需要我们的更多教程，我们需要向世人揭示这种力量，这种神奇。Igor 老大的表达能力貌似非常有限，至少在英语表达方面，这不得不说是一件憾事。但幸运的是他还是可以用很漂亮的 C 代码来传递和实践他的那些极好的 idea. 我必须说这些 idea 是我在 openresty 中的一些引以为豪的想法的高级发展形式。所以我第一眼看到，我就有着某种强烈的共鸣&lt;br&gt; 即使当时我还没有足够了解其细节，呵呵。Igor 万岁！阿哲万岁！&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4183406892132483219?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4183406892132483219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4183406892132483219' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4183406892132483219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4183406892132483219'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2010/01/nginx-igor.html' title='为 nginx 正名，为 Igor 申冤'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2705595218255708931</id><published>2009-12-31T19:13:00.000+08:00</published><updated>2009-12-31T19:14:02.890+08:00</updated><title type='text'>ngx_drizzle: make nginx talk directly to mysql, drizzle, and sqlite3  by libdrizzle</title><content type='html'>This is the last day in 2009 and I&amp;#39;m too impatient to hold the first release (version v0.0.1) of our ngx_drizzle module, an upstream module that talks directly to RDBMS backends like mysql, drizzle, and the drizzle server shipped with libdrizzle for sqlite3.&lt;br&gt;  &lt;br&gt;This module is initially started by my friend and colleague, chaoslawful. His Chinese name is 王晓哲 :) He did the initial (most difficult) work all in his own time :) I also shamelessly borrowed a lot of code from Igor&amp;#39;s ngx_http_upstream.c and ngx_http_memcached_module.c in the nginx 0.8.30 core, as well as Maxim Dounin&amp;#39;s excellent upstream_keepalive module. These parts of code are copyrighted by these authors, respectively.&lt;br&gt;  &lt;br&gt;This module is still at its very early phase of development and considered highly experimental. But you&amp;#39;re encouraged to test it out on your side and report any quirks that you experience :)&lt;br&gt;&lt;br&gt;Here&amp;#39;s some sample configurations:&lt;br&gt;  &lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;   http {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        upstream cluster {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            # simple round-robin&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;            drizzle_server &lt;a href="http://127.0.0.1:3306" target="_blank"&gt;127.0.0.1:3306&lt;/a&gt; dbname=test&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                 password=some_pass user=monty protocol=mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;            drizzle_server &lt;a href="http://127.0.0.1:1234" target="_blank"&gt;127.0.0.1:1234&lt;/a&gt; dbname=test2&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                 password=pass user=bob protocol=drizzle;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;        }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        upstream backend {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;            drizzle_server &lt;a href="http://127.0.0.1:3306" target="_blank"&gt;127.0.0.1:3306&lt;/a&gt; dbname=test&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                 password=some_pass user=monty protocol=mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;        }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;        server {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;            location /mysql {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                set $my_sql &amp;#39;select * from cats&amp;#39;;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;                drizzle_query $my_sql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;                drizzle_pass backend;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;            }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;            ...&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;        }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br&gt;&lt;br&gt;Essentially it provides a very efficient and flexible way for nginx internals to access mysql, drizzle, sqlite3, as well as other RDBMS&amp;#39;s that support the drizzle protocol or mysql protocol. Also it can serve as a direct REST interface to those RDBMS backends.&lt;br&gt;  &lt;br&gt;It also has a builtin per-worker connection pool mechanism borrowed from Maxim Dounin&amp;#39;s upstream_keepalive module.&lt;br&gt;&lt;br&gt;Here&amp;#39;s a sample configuration:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new,monospace;"&gt;  upstream backend {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     drizzle_server &lt;a href="http://127.0.0.1:3306" target="_blank"&gt;127.0.0.1:3306&lt;/a&gt; dbname=test&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;           password=some_pass user=monty protocol=mysql;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;span style="font-family: courier new,monospace;"&gt;     drizzle_keepalive max=100 mode=single overflow=reject;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;  &lt;br&gt;You may wonder why it will be useful for your PHP/Python/Perl/Java applications fastcgi&amp;#39;d or proxied by nginx. Well, we&amp;#39;ll work out an ngx_accel_subrequest module some time in the future to allow these backend apps directly issue subrequests by means of the special &lt;span style="font-family: courier new,monospace;"&gt;X-Accel-Subrequest&lt;/span&gt; header and continuation passing style.&lt;br&gt;  &lt;br&gt;Unlike the current &lt;span style="font-family: courier new,monospace;"&gt;X-Accel-Redirect&lt;/span&gt; trick we&amp;#39;re already familiar with, &lt;span style="font-family: courier new,monospace;"&gt;X-Accel-Subrequest&lt;/span&gt; is more like a function invocation that issues one (or multiple parallel subrequests), and eventually *returns* back when the resulting data the subrequest obtains is ready and gives control back to your backend apps to go on processing the data.&lt;br&gt;  &lt;br&gt;Sadly this mdoule does not have a wiki page yet, just the source repository on GitHub:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module" target="_blank"&gt;http://github.com/chaoslawful/drizzle-nginx-module&lt;/a&gt;&lt;br&gt;  &lt;br&gt;I&amp;#39;ve done some work in the README file there. I promise I&amp;#39;ll work on the wiki doc in another day ;)&lt;br&gt;&lt;br&gt;Release tarballs can be downloaded from the page below&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module/downloads" target="_blank"&gt;http://github.com/chaoslawful/drizzle-nginx-module/downloads&lt;/a&gt;&lt;br&gt;  &lt;br&gt;I&amp;#39;ve also cc&amp;#39;d the nginx-devel mailing list in hope to get interested developers to join this project&amp;#39;s development. __YOU__ are always welcomed!&lt;br&gt;&lt;br&gt;Happily, we&amp;#39;ve already got a working framework for integrating third-party libraries like libdrizzle and libpq into nginx&amp;#39;s upstream system as long as the libraries meet the following prerequisites:&lt;br&gt;  &lt;ul&gt;&lt;li&gt;It exposes the underlying socket fd.&lt;/li&gt;&lt;li&gt;It has a truly non-blocking API for its operations.&lt;/li&gt;&lt;/ul&gt;libdrizzle and libpq meet these conditions while oracle&amp;#39;s OCI library needs some hack for the requirement #1. So, you can expect ngx_oracle and even ngx_pgsql to be announced here in the next few weeks or so, and you&amp;#39;ll see even more! If you&amp;#39;d join the fun, please don&amp;#39;t hesitate to drop us a line :)&lt;br&gt;  &lt;br&gt;Happy new year!&lt;br&gt;&lt;br&gt;P.S. I was hoping to release v0.0.1 by this Christmas, but missed the deadline because I had spent too much time on fixing weird bugs in the ngx_chunkin module :P&lt;br&gt;&lt;br&gt;The year 2009 is my first year in the nginx community. It&amp;#39;s really live and has a lot of fun. I&amp;#39;m going to do more nginx C hacking in the next year! :D&lt;br&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2705595218255708931?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2705595218255708931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2705595218255708931' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2705595218255708931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2705595218255708931'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/12/ngxdrizzle-make-nginx-talk-directly-to.html' title='ngx_drizzle: make nginx talk directly to mysql, drizzle, and sqlite3  by libdrizzle'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4233661581671052893</id><published>2009-12-08T13:36:00.001+08:00</published><updated>2009-12-08T13:36:30.269+08:00</updated><title type='text'>Test::Nginx::LWP and Test::Nginx::Socket are now on CPAN</title><content type='html'>I&amp;#39;ve just released the Perl modules Test::Nginx::LWP and Test::Nginx::Socket as a single Test-Nginx distribution to CPAN (it may still require some more time to reach the CPAN mirror near you):&lt;br&gt;&lt;br&gt;    &lt;a href="http://search.cpan.org/perldoc?Test::Nginx::LWP"&gt;http://search.cpan.org/perldoc?Test::Nginx::LWP&lt;/a&gt;&lt;br&gt; &lt;br&gt;    &lt;a href="http://search.cpan.org/perldoc?Test::Nginx::Socket"&gt;http://search.cpan.org/perldoc?Test::Nginx::Socket&lt;/a&gt;&lt;br&gt;&lt;br&gt;The latter is still a hack using while (1) with non-blocking sysread/syswrite. I&amp;#39;ll rewrite it using IO::Select at some point in the future.&lt;br&gt; &lt;br&gt;These two Test::Base-style modules are driving the test suites of the following Nginx C modules:&lt;br&gt;&lt;dl&gt;&lt;dt&gt;&lt;a name="ngx_echo"&gt;ngx_echo&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt; &lt;p&gt;&lt;a href="http://wiki.nginx.org/NginxHttpEchoModule" class="podlinkurl"&gt;http://wiki.nginx.org/NginxHttpEchoModule&lt;/a&gt;&lt;/p&gt;  &lt;/dd&gt;&lt;dt&gt;&lt;a name="ngx_headers_more"&gt;ngx_headers_more&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt; &lt;p&gt;&lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule" class="podlinkurl"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule&lt;/a&gt;&lt;/p&gt;  &lt;/dd&gt;&lt;dt&gt;&lt;a name="ngx_chunkin"&gt;ngx_chunkin&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt; &lt;p&gt;&lt;a href="http://wiki.nginx.org/NginxHttpChunkinModule" class="podlinkurl"&gt;http://wiki.nginx.org/NginxHttpChunkinModule&lt;/a&gt;&lt;/p&gt;  &lt;/dd&gt;&lt;dt&gt;&lt;a name="ngx_memc"&gt;ngx_memc&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt; &lt;p&gt;&lt;a href="http://wiki.nginx.org/NginxHttpMemcModule" class="podlinkurl"&gt;http://wiki.nginx.org/NginxHttpMemcModule&lt;/a&gt;&lt;/p&gt; &lt;/dd&gt;&lt;/dl&gt;&lt;br&gt;And our &lt;a href="http://github.com/chaoslawful/drizzle-nginx-module"&gt;ngx_drizzle&lt;/a&gt; module, started by my friend and colleague, chaoslawful++, will soon be on that list as well ;)&lt;br&gt;&lt;br&gt;Happy testing nginx modules with Perl!&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4233661581671052893?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4233661581671052893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4233661581671052893' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4233661581671052893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4233661581671052893'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/12/testnginxlwp-and-testnginxsocket-are.html' title='Test::Nginx::LWP and Test::Nginx::Socket are now on CPAN'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-649715160688234062</id><published>2009-12-06T18:27:00.001+08:00</published><updated>2009-12-06T18:27:15.800+08:00</updated><title type='text'>ngx_memc: an extended version of ngx_memcached that supports set,  add, delete, and many more commands</title><content type='html'>I&amp;#39;m happy to announce the first release of the ngx_memc module, an extended version of the standard &amp;quot;memcached&amp;quot; module that supports almost the whole memcached TCP protocol:&lt;br&gt;&lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpMemcModule"&gt;http://wiki.nginx.org/NginxHttpMemcModule&lt;/a&gt;&lt;br&gt; &lt;br&gt;I know the state of the art in the nginx community is to manipulate contents in memcached from within a backend (fastcgi) application while just use the nginx memcached module as a frontend that simply &amp;quot;serves&amp;quot; the content to the outside world. But read on...&lt;br&gt; &lt;br&gt;Our motivation here, however, is to build an efficient and flexible memcached TCP client component for nginx itself  so that we can reuse it in an non-blocking way by means of an nginx subrequest or a &amp;quot;fakerequest&amp;quot; [1].&lt;br&gt; &lt;br&gt;As always, special thanks go to Igor Sysoev for all his heavy lifting work already done in ngx_http_upstream and ngx_http_memcached_module in the nginx core.&lt;br&gt;&lt;br&gt;At last but not least, thanks my current employer, Taobao.com, for allowing me to opensource this work, as well as other nginx modules I have already announced or am going to announce here ;)&lt;br&gt; &lt;br&gt;Enjoy!&lt;br&gt;&lt;br&gt;References&lt;br&gt;[1] See &lt;a href="http://github.com/srlindsay/nginx-independent-subrequest"&gt;http://github.com/srlindsay/nginx-independent-subrequest&lt;/a&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-649715160688234062?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/649715160688234062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=649715160688234062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/649715160688234062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/649715160688234062'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/12/ngxmemc-extended-version-of.html' title='ngx_memc: an extended version of ngx_memcached that supports set,  add, delete, and many more commands'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6186690034720782497</id><published>2009-12-04T18:13:00.000+08:00</published><updated>2009-12-04T18:14:03.509+08:00</updated><title type='text'>Major updates to ngx_chunkin: lots of bug fixes and beginning of  keep-alive support</title><content type='html'>Prompted by the bug reports from one of my users, the J guy, I&amp;#39;ve made lots of improvements into the ngx_chunkin module:&lt;br&gt;&lt;br&gt;   &lt;a href="http://wiki.nginx.org/NginxHttpChunkinModule" target="_blank"&gt;http://wiki.nginx.org/NginxHttpChunkinModule&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Please see the change log for the new v0.07 release:&lt;br&gt;&lt;br&gt;   &lt;a href="http://wiki.nginx.org/NginxHttpChunkinModule#v0.07" target="_blank"&gt;http://wiki.nginx.org/NginxHttpChunkinModule#v0.07&lt;/a&gt;&lt;br&gt;&lt;br&gt;It&amp;#39;s worth special mentioning that it&amp;#39;s really a shame that older versions do not work with chunked data with non-ascii octets. This was caused by incorrect alphtype definition in my Ragel spec. Thanks J for reporting it.&lt;br&gt;  &lt;br&gt;Also, I&amp;#39;ve introduced a new directive spelled &amp;quot;chunkin_keepalive&amp;quot;, which will make ngx_chunkin work in the non-pipelined keep-alive context. Preliminary support for HTTP 1.1 pipelining is also introduced but has not been tested very well. (For technical details, see &lt;a href="http://nginx.org/pipermail/nginx-devel/2009-December/000021.html" target="_blank"&gt;this nginx-devel thread&lt;/a&gt; )&lt;br&gt;  &lt;br&gt;As before, this module is still considered experimental but you&amp;#39;re encouraged to try it out and report any issues that you encounter. I promise I&amp;#39;ll fix bugs as fast as I can :)&lt;br&gt;&lt;br&gt;Happy chunking nginx!&lt;br&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6186690034720782497?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6186690034720782497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6186690034720782497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6186690034720782497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6186690034720782497'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/12/major-updates-to-ngxchunkin-lots-of-bug.html' title='Major updates to ngx_chunkin: lots of bug fixes and beginning of  keep-alive support'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-3310830639494117033</id><published>2009-11-18T18:09:00.001+08:00</published><updated>2009-11-18T18:09:07.404+08:00</updated><title type='text'>The "headers more" module: scripting input and output filters in your  Nginx config file</title><content type='html'>I&amp;#39;ve been working madly on the &amp;quot;headers more&amp;quot; module:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/headers-more-nginx-module"&gt;http://github.com/agentzh/headers-more-nginx-module&lt;/a&gt;&lt;br&gt;&lt;br&gt;And got everything I want working now. It also has a nice wiki page (which also has brief explanation of the underlying implementation):&lt;br&gt; &lt;br&gt;    &lt;a href="http://wiki.nginx.org/NginxHttpHeadersMoreModule"&gt;http://wiki.nginx.org/NginxHttpHeadersMoreModule&lt;/a&gt;&lt;br&gt;&lt;br&gt;Our buzzword is that it can rewrite the &amp;quot;Server&amp;quot; output header dynamically! See this:&lt;br&gt; &lt;br&gt;   location /foo {&lt;br&gt;        more_set_headers   &amp;quot;Server: $arg_server&amp;quot;;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;Then GET /foo?server=Foo will get a response with the &amp;quot;Server: Foo&amp;quot; header set ;)&lt;br&gt;&lt;br&gt;Input headers can be trivially rewritten as well, including the &amp;quot;Host&amp;quot; header:&lt;br&gt; &lt;br&gt;    more_set_input_headers   &amp;quot;Host: some-other-host&amp;quot;;&lt;br&gt;&lt;br&gt;Well, the full practical power of this module is out of my current imagination. If you have some crazy uses, please drop me a line ;)&lt;br&gt;&lt;br&gt;Happy Nginx hacking!&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-3310830639494117033?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/3310830639494117033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=3310830639494117033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3310830639494117033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/3310830639494117033'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/11/headers-more-module-scripting-input-and.html' title='The &quot;headers more&quot; module: scripting input and output filters in your  Nginx config file'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-6463428279930720324</id><published>2009-11-15T18:25:00.001+08:00</published><updated>2009-11-15T18:25:19.223+08:00</updated><title type='text'>The "chunkin" module: Experimental chunked input support for Nginx</title><content type='html'>Pushed by those cutting-edge users on the list, I&amp;#39;ve quickly worked out &amp;quot;chunkin&amp;quot; module which adds HTTP 1.1 chunked input support for Nginx without the need to patching the core:&lt;br&gt;&lt;br&gt;     &lt;a href="http://github.com/agentzh/chunkin-nginx-module"&gt;http://github.com/agentzh/chunkin-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;This module registers an access-phase handler that will eagerly read and decode incoming request bodies when a &amp;quot;Transfer-Encoding: chunked&amp;quot; header triggers a 411 error page in Nginx (hey, that&amp;#39;s what you have to pay for avoiding patching the core ;)). For requests that are not in the &amp;quot;chunked&amp;quot; transfer encoding, this module is a &amp;quot;no-op&amp;quot;.&lt;br&gt; &lt;br&gt;To enable the magic, just turn on the &amp;quot;chunkin&amp;quot; config option like this:&lt;br&gt;&lt;br&gt;   chunkin on;&lt;br&gt;   location /foo { ... }&lt;br&gt;   ....&lt;br&gt;&lt;br&gt;No other modification is required in your nginx.conf file. (The &amp;quot;chunkin&amp;quot; directive is not allowed to use in the location block BTW.)&lt;br&gt; &lt;br&gt;This module is still considered highly experimental and there must be some serious bugs lurking somewhere. But you&amp;#39;re encouraged to play and test it in your non-production environment and report any quirks to me :)&lt;br&gt; &lt;br&gt;Efforts have been made to reduce data copying, dynamic memory allocation, and other performance tuning, thus unfortunately raising the risk of potential buffer handling bugs caused by premature optimizations :P&lt;br&gt;&lt;br&gt; This module is not supposed to be merged into the Nginx core because I&amp;#39;ve used Ragel to generate the chunked encoding parser for joy :)&lt;br&gt;&lt;br&gt;The following Nginx versions have been successfully tested by this module&amp;#39;s (very limited) test suite:&lt;br&gt; &lt;br&gt;    0.8.0 ~ 0.8.24&lt;br&gt;    0.7.21 ~ 0.7.63&lt;br&gt;&lt;br&gt;The test suite definitely needs more test cases and the code is hacky in various places. If you&amp;#39;re willing to contribute, feel free to ask me for a commit bit in a private email :)&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-6463428279930720324?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/6463428279930720324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=6463428279930720324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6463428279930720324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/6463428279930720324'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/11/chunkin-module-experimental-chunked.html' title='The &quot;chunkin&quot; module: Experimental chunked input support for Nginx'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-341622318024255861</id><published>2009-10-15T11:01:00.001+08:00</published><updated>2009-10-15T11:01:03.208+08:00</updated><title type='text'>Hacking on the Nginx echo module</title><content type='html'>Over the recent weeks, I&amp;#39;ve been reading a lot of Nginx and its modules&amp;#39; C source code and it&amp;#39;s really enjoyable. I&amp;#39;ve got lots of good ideas in implementing the next generation of OpenResty server based on the Nginx architecture. Well, it&amp;#39;s currently my full-time $work anyway.&lt;br&gt; &lt;br&gt;For the sake of testing other modules, experimenting the Nginx internals, and for fun, I&amp;#39;ve started my first Nginx module named &amp;quot;echo&amp;quot;:&lt;br&gt;&lt;br&gt;   &lt;a href="http://github.com/agentzh/echo-nginx-module"&gt;http://github.com/agentzh/echo-nginx-module&lt;/a&gt;&lt;br&gt; &lt;br&gt;It&amp;#39;s already quite usable, and it also has a declarative test suite based on Perl&amp;#39;s Test::Base. At the moment, LWP is used for simplicity and it&amp;#39;s rather weak in testing streaming behavior of Nginx (I&amp;#39;m using &amp;quot;curl&amp;quot; to test these aspects manually for now). I&amp;#39;m considering coding up my own Perl HTTP client library based on IO::Select and IO::Socket (there might be already one around?).&lt;br&gt; &lt;br&gt;I&amp;#39;m intentionally heavily commenting my C source in this &amp;quot;echo&amp;quot; module in the hope that newcomers would find it a &amp;quot;live tutorial&amp;quot; or something like that. I&amp;#39;ll write more about the details here in subsequent posts. After all, it&amp;#39;s able to do a lot more thingies other than just &amp;quot;echo&amp;quot; stuffs directly, such as sleeping and flushing output buffer. And it will be capable of outputing subrequests&amp;#39; responses as well.&lt;br&gt; &lt;br&gt;Happy hacking Nginx C modules and stay tuned!&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-341622318024255861?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/341622318024255861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=341622318024255861' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/341622318024255861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/341622318024255861'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/10/hacking-on-nginx-echo-module.html' title='Hacking on the Nginx echo module'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4093928641328967271</id><published>2009-09-20T23:40:00.001+08:00</published><updated>2009-09-20T23:40:15.022+08:00</updated><title type='text'>Slides for my perl testing &amp; VDOM.pm talks in Beijing Perl Workshop  2009</title><content type='html'>I really enjoyed the talks in &lt;a href="http://conference.perlchina.org/bjpw2009/talks"&gt;BJPW2009&lt;/a&gt;. Here&amp;#39;s the slides for my two talks in this conference:&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&amp;quot;A Tour of Perl Testing&amp;quot;:&lt;br&gt;Browse URL (Firefox required):        &lt;a href="http://agentzh.org/misc/slides/BJPW2009/perl-testing.xul"&gt;http://agentzh.org/misc/slides/BJPW2009/perl-testing.xul&lt;/a&gt;&lt;br&gt; Download URL (Open perl-testing.xul after extraction):    &lt;a href="http://agentzh.org/misc/slides/BJPW2009.tar.gz"&gt;http://agentzh.org/misc/slides/BJPW2009.tar.gz&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&amp;quot;Introduction to our VDOM &amp;amp; vdom-webkit cluster&amp;quot;&lt;br&gt; Browse URL (Firefox required):           &lt;a href="http://agentzh.org/misc/slides/taobao-fe/vdomwebkit.xul"&gt;http://agentzh.org/misc/slides/taobao-fe/vdomwebkit.xul&lt;/a&gt;&lt;br&gt;Download URL (Open vdomwebkit.xul after extration):       &lt;a href="http://agentzh.org/misc/slides/taobao-fe.tar.gz"&gt;http://agentzh.org/misc/slides/taobao-fe.tar.gz&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;Hopefully you&amp;#39;ll find them interesting ;)&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4093928641328967271?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4093928641328967271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4093928641328967271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4093928641328967271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4093928641328967271'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/09/slides-for-my-perl-testing-vdompm-talks.html' title='Slides for my perl testing &amp; VDOM.pm talks in Beijing Perl Workshop  2009'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-8792519871934955014</id><published>2009-09-14T18:30:00.001+08:00</published><updated>2009-09-14T18:30:55.751+08:00</updated><title type='text'>A plan for nginx-openresty</title><content type='html'>&lt;div class="gmail_quote"&gt;Now that I&amp;#39;ve joined Taobao.com&amp;#39;s SDS department and will be able to work on OpenResty in a full time fashion, I&amp;#39;ve just worked out a (somewhat) detailed plan for the next generation of the OpenResty server. Well, sorry, this draft is in Chinese since my $manager reads Chinese better:&lt;br&gt;   &lt;br&gt;    &lt;a href="http://www.pgsqldb.org/mwiki/index.php/Nginx_openresty_plan" target="_blank"&gt;http://www.pgsqldb.org/mwiki/index.php/Nginx_openresty_plan&lt;/a&gt;  (still being actively updated)&lt;br&gt;&lt;br&gt;After discussing with my friend and colleague &lt;a href="http://github.com/chaoslawful" target="_blank"&gt;chaoslawful++&lt;/a&gt; for possible designs of a high performance implementation of the OpenResty server, we finally decided to rewrite OpenResty.pm in pure C in the form of an nginx module.&lt;br&gt;   &lt;br&gt;Here&amp;#39;s some highlights of the Chinese project plan given above:&lt;br&gt;&lt;br&gt;* Nginx-openresty will remain fully opensource.&lt;br&gt;* We want to take full advantage of Nginx&amp;#39;s event modle and asynchronous I/O and we don&amp;#39;t want backend requests blocking as well.&lt;br&gt;   * We want to integrate Coco Lua into nginx&amp;#39;s event model leveraging coco&amp;#39;s C level coroutines, thus leading to transparent asynchronous I/O on the Lua land. For example, consider the following Lua code&lt;br&gt;&lt;br&gt;          res = http.get(&amp;#39;&lt;a href="http://www.taobao.com" target="_blank"&gt;http://www.taobao.com&lt;/a&gt;&amp;#39;)&lt;br&gt;&lt;br&gt;will automatically yield the current &amp;quot;lua thread&amp;quot; and register a socket fd to nginx&amp;#39;s underlying epoll/kqueue/select/etc model and return control to nginx to do other things. Once data arrives at the socket fd, nginx will get informed and accumulated the response data. When the requested data is completely ready, nginx will resume the pending lua session and the Lua function &amp;quot;http.get&amp;quot; will successfully return.&lt;br&gt;* We want Lua to become the first-class embedded langauge on the service level and we&amp;#39;d abandon the restyscript language.&lt;br&gt;* The first two backends we want to implement for nginx-openresty are mysql and Oracle (and Hive afterwards) because these are heavily used in our department&amp;#39;s production.&lt;br&gt;   * We&amp;#39;ll only allow the HTTP POST method to emulate modification methods like PUT and DELETE. GET will no longer be allowed here to reduce XSS attach risk.&lt;br&gt;* Password login method will require the client to request a random number from the OpenResty server and use it as a salt to encrypt her password using multi-pass MD5, as in &lt;br&gt;   &lt;pre&gt; passwd = md5(passwd)&lt;br&gt; for 1..2 do&lt;br&gt;    passwd = md5(passwd + salt)&lt;br&gt; done&lt;br&gt;&lt;/pre&gt;* For the REST interfce, we will introduce Type API to allow user use Lua snippet to define new parameter types for Views and Actions.&lt;br&gt;   * For RDBMS backends, Views and Actions can use the &amp;quot;map_to&amp;quot; attribute to map automatically to underlying DB functions and stored procedures.&lt;br&gt;* Views and Actions&amp;#39; definitions (ako &amp;quot;queries&amp;quot;) will specify in the backend&amp;#39;s own query language (like PL/SQL, PL/PgSQL, and etc.). OpenResty willl only recognize special interpolated parameters in the form of $(param_name type=xxx checker=xxx default=xxx ...).&lt;br&gt;   * Views and Actions will support &amp;quot;cached&amp;quot; and &amp;quot;expire&amp;quot; attributes to allow caching of result data set, and &amp;quot;async&amp;quot; attribute to allow time-consuming backend queries to submit to remote queues like memcacheq and eventually run by async daemon workers. The original View invoker will immediately get a job ID for his request (unless the task queue is full) and poll OpenResty&amp;#39;s Job API for the status of his task and get the final results when the task is marked &amp;quot;done&amp;quot;.&lt;br&gt;   * View/Action parameters can specify types, Lua-specified checkers, and default values. For example:&lt;br&gt;&lt;br&gt;     {&amp;quot;name&amp;quot;:&amp;quot;my_view&amp;quot;,&amp;quot;query&amp;quot;:&lt;br&gt;          &amp;quot;select * from animals where age &amp;gt; $(age type=integer checker=&amp;#39;return age &amp;gt;= 0 and age &amp;lt;= 100&amp;#39;)&amp;quot;}&lt;br&gt;   &lt;br&gt;* Filter, Template, and Trigger APIs will also be introduced :)&lt;br&gt;&lt;br&gt;I&amp;#39;ll create a git repository on GitHub for the nginx-openresty&amp;#39;s development. Participation will always be appreciated :) I&amp;#39;ll keep you posted.&lt;br&gt;   &lt;/div&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-8792519871934955014?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/8792519871934955014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=8792519871934955014' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8792519871934955014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/8792519871934955014'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/09/plan-for-nginx-openresty.html' title='A plan for nginx-openresty'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-7964940678468328272</id><published>2009-09-04T16:04:00.001+08:00</published><updated>2009-09-04T16:04:37.141+08:00</updated><title type='text'>Slides for my VDOM + WebKit talk</title><content type='html'>I gave a presentation on VDOM + WebKit to the Taobao.com Search Frontend Team this morning. The slides are based on my talk in April&amp;#39;s Beijing Perl Workshop, but with notable updates to reflect recent changes in the last few months:&lt;br&gt; &lt;br&gt;   &lt;a href="http://agentzh.org/misc/slides/taobao-fe/vdomwebkit.xul"&gt;http://agentzh.org/misc/slides/taobao-fe/vdomwebkit.xul&lt;/a&gt;   (Firefox required to open this link)&lt;br&gt;&lt;br&gt;Be patient when it&amp;#39;s downloading big images while browsing the slides, or you can download the whole tarball to your local side, unpack the package, open the vdomwebkit.xul in it, and browse the slides locally:&lt;br&gt; &lt;br&gt;   &lt;a href="http://agentzh.org/misc/slides/taobao-fe.tar.gz"&gt;http://agentzh.org/misc/slides/taobao-fe.tar.gz&lt;/a&gt;&lt;br&gt;&lt;br&gt;Recent major development regarding our browser-based web scraping clusters are:&lt;br&gt;&lt;ul&gt;&lt;li&gt;We&amp;#39;ve switched from the Visual DOM Firefox extension completely to the VDOM Browser based on QtWebKit for hunter development.&lt;/li&gt; &lt;li&gt;We&amp;#39;ve switched from OpenResty + Pg to our queue-size-ware version of memcacheq to coordinate the whole cluster.&lt;/li&gt;&lt;li&gt;We&amp;#39;ve extensively used our new &amp;quot;VDOM spectroscapy algorithm&amp;quot; to establish corronspondence between text nodes in similar page regions.&lt;/li&gt; &lt;/ul&gt;I&amp;#39;ll use almost the same slides for my 3rd (lightening) talk at the annual Beijing Perl Workshop conference weeks later :)&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-7964940678468328272?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/7964940678468328272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=7964940678468328272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7964940678468328272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/7964940678468328272'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/09/slides-for-my-vdom-webkit-talk.html' title='Slides for my VDOM + WebKit talk'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5885307105635589791</id><published>2009-09-03T18:19:00.001+08:00</published><updated>2009-09-03T18:19:57.646+08:00</updated><title type='text'>Our queue-size-aware version of memcacheq</title><content type='html'>Xunxin++ and I have been working on a fork of memcacheq (originally just within the company), adding support for queue length constraint.&lt;br&gt;&lt;br&gt;In our scenario, a pipelined webpage information extraction cluster based on apple&amp;#39;s WebKit core, it&amp;#39;s important to limit the queue&amp;#39;s length and to make the queue &amp;quot;inform&amp;quot; the queue item producers by some way in case the queue is full.&lt;br&gt; &lt;br&gt;We&amp;#39;re not sure if it&amp;#39;s worth merging back to the mainstream version because this new addition adds some cost (though the cost is low).&lt;br&gt;&lt;br&gt;Here goes the project page on GitHub, with more explanation of the details (I won&amp;#39;t repeat them here ;)):&lt;br&gt; &lt;br&gt;  &lt;a href="http://github.com/agentzh/memcacheq/tree/master"&gt;http://github.com/agentzh/memcacheq/tree/master&lt;/a&gt;&lt;br&gt;&lt;br&gt;The newly added code is also licensed under the same license as the mainstream memcacheq.&lt;br&gt;&lt;br&gt;Enjoy :)&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5885307105635589791?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5885307105635589791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5885307105635589791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5885307105635589791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5885307105635589791'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/09/our-queue-size-aware-version-of.html' title='Our queue-size-aware version of memcacheq'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-926984222119824661</id><published>2009-09-02T17:29:00.001+08:00</published><updated>2009-09-02T17:29:51.776+08:00</updated><title type='text'>I'll talk in the upcoming Beijing Perl Workshop 2009 event</title><content type='html'>I&amp;#39;ve submitted 3 talk proposals to this year&amp;#39;s upcoming Beijing Perl Workshop conference scheduled at Sep 19. I&amp;#39;ll publish my slides for my talks later here for your preview :)&lt;br&gt;&lt;br&gt;The 3 talks are&lt;br&gt;&lt;ol&gt;&lt;li&gt; Wonders of Perl automated testing&lt;/li&gt;&lt;li&gt;Inventing mini languages in Perl&lt;/li&gt;&lt;li&gt;Web Scraping based on Perl + WebKit + VDOM&lt;/li&gt;&lt;/ol&gt;If you feel like attending the conference, please register in the conference site below:&lt;br&gt; &lt;br&gt;   &lt;a href="http://conference.perlchina.org/bjpw2009/"&gt;http://conference.perlchina.org/bjpw2009/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Don&amp;#39;t forget to specify a T-shirt size in your profile setting there so that we can prepare a T-shirt for you in this event (well, it&amp;#39;s for free!).&lt;br&gt; &lt;br&gt;See you there ;)&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-926984222119824661?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/926984222119824661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=926984222119824661' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/926984222119824661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/926984222119824661'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/09/ill-talk-in-upcoming-beijing-perl.html' title='I&apos;ll talk in the upcoming Beijing Perl Workshop 2009 event'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4203237245005546820</id><published>2009-05-11T16:02:00.001+08:00</published><updated>2009-05-11T16:02:36.669+08:00</updated><title type='text'>OpenResty.pm has been moved to GitHub</title><content type='html'>As some of you may have already noticed, I&amp;#39;ve moved the source repository of OpenResty.pm from the good old OpenFoundry to GitHub:&lt;br&gt;&lt;br&gt;    &lt;a href="http://github.com/agentzh/openresty/tree/master" target="_blank"&gt;http://github.com/agentzh/openresty/tree/master&lt;/a&gt;&lt;br&gt;  &lt;br&gt;Feel free to branch it or ask me for a commit bit if you don&amp;#39;t have one ;)&lt;br&gt;&lt;br&gt;I&amp;#39;ll destroy the stuffs in the old &amp;quot;openapi&amp;quot; repository on openfoundry and leave a note there to avoid potential confusion. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4203237245005546820?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4203237245005546820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4203237245005546820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4203237245005546820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4203237245005546820'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/05/openrestypm-has-been-moved-to-github.html' title='OpenResty.pm has been moved to GitHub'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-4901184822901220372</id><published>2009-05-11T14:51:00.001+08:00</published><updated>2009-05-11T14:51:16.143+08:00</updated><title type='text'>Mailing list for OpenResty</title><content type='html'>After releasing several new releases of OpenResty.pm to CPAN, I created a mailing list for OpenResty users/developers on Google Groups:&lt;br&gt;&lt;br&gt;    &lt;a href="http://groups.google.com/group/openresty?hl=en"&gt;http://groups.google.com/group/openresty?hl=en&lt;/a&gt;&lt;br&gt; &lt;br&gt;This is for both OpenResty.pm and mod_openresty. You&amp;#39;re very welcome to join us there ;) There&amp;#39;s also a #openresty on freenode but it&amp;#39;s been very quiet :P&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-4901184822901220372?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/4901184822901220372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=4901184822901220372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4901184822901220372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/4901184822901220372'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/05/mailing-list-for-openresty.html' title='Mailing list for OpenResty'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-2632772226314017257</id><published>2009-04-28T14:05:00.001+08:00</published><updated>2009-04-28T14:05:38.886+08:00</updated><title type='text'>Text::SmartLinks: The Perl 6 love for Perl 5</title><content type='html'>I&amp;#39;m so glad to find this blog post while browsing the &lt;a href="http://ironman.enlightenedperl.org/"&gt;Iron Man planet&lt;/a&gt;:&lt;br&gt;&lt;br&gt;   &lt;a href="http://szabgab.com/blog/2009/04/1240827553.html"&gt;http://szabgab.com/blog/2009/04/1240827553.html&lt;/a&gt;&lt;br&gt; &lt;br&gt;Three years ago, I wrote the smartlinks.pl script to &lt;a href="http://pugs.blogs.com/pugs/2006/08/integrating_the.html"&gt;integrate&lt;/a&gt; the Pugs test suite with the Perl 6 Synopses documentation.&lt;br&gt;&lt;br&gt;&lt;a href="http://search.cpan.org/%7Eszabgab/"&gt;Gábor Szabó&lt;/a&gt; now has done an excellent job in refactoring and packaging the tool into a general-purpose CPAN module. It had been my TODO until I was caught by accumulated schoolwork :P&lt;br&gt; &lt;br&gt;Enjoy his (well, also our) Text::SmartLinks module!&lt;br&gt;&lt;br&gt;   &lt;a href="http://search.cpan.org/perldoc?Text::SmartLinks"&gt;http://search.cpan.org/perldoc?Text::SmartLinks&lt;/a&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-2632772226314017257?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/2632772226314017257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=2632772226314017257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2632772226314017257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/2632772226314017257'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/04/textsmartlinks-perl-6-love-for-perl-5.html' title='Text::SmartLinks: The Perl 6 love for Perl 5'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5021990479196781773</id><published>2009-04-23T10:23:00.001+08:00</published><updated>2009-04-23T10:23:17.895+08:00</updated><title type='text'>SSH::Batch: Treating clusters as maths sets and intervals</title><content type='html'>System administration is also part of my $work. Playing with a (big) bunch of  machines without a handy tool is painful. So I refactored some of our old scripts and released SSH::Batch, a collection of useful parallel ssh scripts, to CPAN:&lt;br&gt; &lt;br&gt;    &lt;a href="http://search.cpan.org/dist/SSH-Batch/"&gt;http://search.cpan.org/dist/SSH-Batch/&lt;/a&gt;&lt;br&gt;&lt;br&gt;SSH::Batch allows you to name your clusters using variables and interval/set syntax in your ~/.fornodesrc config file. For instance:&lt;br&gt; &lt;br&gt;    $ cat ~/.fornodesrc&lt;br&gt;    A=foo[01-03].com &lt;a href="http://bar.org"&gt;bar.org&lt;/a&gt;&lt;br&gt;    B=&lt;a href="http://bar.org"&gt;bar.org&lt;/a&gt; baz[a-b,d,e-g].cn &lt;a href="http://foo02.com"&gt;foo02.com&lt;/a&gt;&lt;br&gt;    C={A} * {B}&lt;br&gt;    D={A} - {B}&lt;br&gt; &lt;br&gt;where cluster C is the intersection set of cluster A and B while D is those machines in A but not in B.&lt;br&gt;&lt;br&gt;And then you can query machine host list by using SSH::Batch&amp;#39;s fornodes script:&lt;br&gt;&lt;br&gt;   $ fornodes &amp;#39;{C}&amp;#39;&lt;br&gt;    &lt;a href="http://bar.org"&gt;bar.org&lt;/a&gt;&lt;br&gt;   &lt;a href="http://foo02.com"&gt;foo02.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;   $ fornodes &amp;#39;{D}&amp;#39;&lt;br&gt;   &lt;a href="http://foo01.com"&gt;foo01.com&lt;/a&gt;&lt;br&gt;   &lt;a href="http://foo03.com"&gt;foo03.com&lt;/a&gt;&lt;br&gt;&lt;br&gt; Furthermore, to run a command on a cluster by the concurrency of 6:&lt;br&gt;&lt;br&gt;   atnodes &amp;#39;ls -lh&amp;#39; &amp;#39;{A} + {B}&amp;#39; &lt;a href="http://my.more.com"&gt;my.more.com&lt;/a&gt; -c 6&lt;br&gt;&lt;br&gt;Or upload a local file to the remote cluster:&lt;br&gt; &lt;br&gt;  tonodes ~/my.tar.gz &amp;#39;{A} / {B}&amp;#39; :/tmp/&lt;br&gt;&lt;br&gt;There&amp;#39;s also a key2nodes script to push SSH public keys to remote machines ;) &lt;br&gt;&lt;br&gt;A colleague in Alibaba B2B is already using it. And one of my teammates is going to use it to operate on those thousands of machines in our instance of the YST (Yahoo! Search Technology) cluster and I&amp;#39;m ready to receive more feedback from him ;)&lt;br&gt; &lt;br&gt;Have fun :)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5021990479196781773?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5021990479196781773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5021990479196781773' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5021990479196781773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5021990479196781773'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/04/sshbatch-treating-clusters-as-maths.html' title='SSH::Batch: Treating clusters as maths sets and intervals'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29252337.post-5999552566215471607</id><published>2009-04-10T11:51:00.001+08:00</published><updated>2009-04-10T11:51:34.336+08:00</updated><title type='text'>My VDOM.pm &amp; WebKit Cluster Talk at the April Meeting of Beijing Perl  Workshop</title><content type='html'>Last night I gave a talk to our PerlChina folks at the April meeting in the Flow Bar. Here&amp;#39;s the slides that I used:&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;Firefox XUL format: &lt;a href="http://agentzh.org/misc/slides/BJPW200904/vdomwebkit.xul" class="external text" title="http://agentzh.org/misc/slides/BJPW200904/vdomwebkit.xul" rel="nofollow"&gt;Browse in Firefox&lt;/a&gt;, &lt;a href="http://agentzh.org/misc/slides/BJPW200904.tar.gz" class="external text" title="http://agentzh.org/misc/slides/BJPW200904.tar.gz" rel="nofollow"&gt;Download tarball&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://agentzh.org/misc/slides/vdomwebkit.pdf" class="external text" title="http://agentzh.org/misc/slides/vdomwebkit.pdf" rel="nofollow"&gt;PDF format&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://agentzh.org/misc/slides/vdomwebkit.ppt" class="external text" title="http://agentzh.org/misc/slides/vdomwebkit.ppt" rel="nofollow"&gt;PPT format&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;The XUL format is the best among the three ;)&lt;br&gt;&lt;br&gt;Just as the topic of the talk suggests, we&amp;#39;re migrating from Firefox clusters to WebKit ones. I&amp;#39;ll post more details here in the near future.&lt;br&gt;&lt;br&gt;Enjoy!&lt;br&gt; &lt;br&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29252337-5999552566215471607?l=agentzh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agentzh.blogspot.com/feeds/5999552566215471607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=29252337&amp;postID=5999552566215471607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5999552566215471607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29252337/posts/default/5999552566215471607'/><link rel='alternate' type='text/html' href='http://agentzh.blogspot.com/2009/04/my-vdompm-webkit-cluster-talk-at-april.html' title='My VDOM.pm &amp; WebKit Cluster Talk at the April Meeting of Beijing Perl  Workshop'/><author><name>agentzh</name><uri>http://www.blogger.com/profile/02055547961274080974</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
