<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
<<toolbar permalink>>

This bundle is maintained by us, [[agentzh|http://agentzh.org]], [[chaoslawful|https://github.com/chaoslawful]], [[Kindy Lin|https://github.com/kindy61]], [[Liseen Wan|https://github.com/liseen]], and Jiale Zhi. It was originally sponsored by [[Taobao.com|http://www.taobao.com]], Alibaba Group.

Because most of the nginx modules are developed by the bundle maintainers, it can ensure
that all these modules are played well together.

The bundled software components are copyrighted by the respective copyright holders.

This web site is a [[TiddlyWiki|http://www.tiddlywiki.com/]] page that is under the version control of a repository on GitHub:

http://github.com/agentzh/openresty.org

Feel free to fork it or just [[contact us|ContactUs]] to obtain a git commit bit if you want to edit and improve this site.
<<toolbar permalink>>

This [[Nginx]] module adds support for array variables to nginx config files.

Project page: https://github.com/agentzh/array-var-nginx-module
<<toolbar permalink>>

Introduction: http://www.ruby-forum.com/topic/205063

Project page: http://mdounin.ru/hg/ngx_http_auth_request_module/
<<toolbar permalink>>
!~HelloWorld
Testing the performance of a ~HelloWorld server does not mean many things but it does tell us where the ceiling is.

The ~HelloWorld server based on OpenResty is described in the [[GettingStarted]] document.

Below is the result using the command {{{http_load -p 10 -s 5 http://localhost:8080/}}} on my ~ThinkPad T400 laptop with ngx_openresty 1.0.10.1:
{{{
139620 fetches, 10 max parallel, 1.67544e+06 bytes, in 5.00001 seconds
12 mean bytes/connection
27923.9 fetches/sec, 335087 bytes/sec
msecs/connect: 0.0531258 mean, 4.076 max, 0.014 min
msecs/first-response: 0.258796 mean, 5.353 max, 0.067 min
HTTP response codes:
  code 200 -- 139620
}}}

So on my laptop, for only a single worker nginx server, we've got ~28k r/s. The memory footprint of the {{{node}}} process under load is 38.0m VIRT, 2.5m RES.

For comparison, ~HelloWorld servers using nginx + php-fpm 5.2.8 gives ~6k r/s:
{{{
http_load -p 10 -s 5 url
29703 fetches, 10 max parallel, 326733 bytes, in 5 seconds
11 mean bytes/connection
5940.6 fetches/sec, 65346.6 bytes/sec
msecs/connect: 0.0394686 mean, 1.172 max, 0.02 min
msecs/first-response: 1.62616 mean, 6.744 max, 0.719 min
HTTP response codes:
  code 200 -- 29703
}}}
And [[node.js|http://nodejs.org/]] v0.6.1 yields 10k r/s:
{{{
51206 fetches, 10 max parallel, 614472 bytes, in 5 seconds
12 mean bytes/connection
10241.2 fetches/sec, 122894 bytes/sec
msecs/connect: 0.0356567 mean, 1.316 max, 0.019 min
msecs/first-response: 0.916395 mean, 14.236 max, 0.077 min
HTTP response codes:
  code 200 -- 51206
}}}
The memory footprint of the {{{node}}} process under load is 629m  VIRT, 50m RES.

!! For Mac OS X Lion Users
Note that Mac OS X Lion has known issues that need to be fixed on your system before attempting to replicate our benchmark results.

In brief, raise the number of  available ephemeral ports using [[this fix|http://serverfault.com/questions/145907/does-mac-os-x-throttle-the-rate-of-socket-creation]].

Compile an up-to-date version of ab (Apache's benchmark tool) according to [[this post|http://superuser.com/questions/323840/apache-bench-test-erroron-os-x-apr-socket-recv-connection-reset-by-peer-54]].

Then, {{{ab -k -c10 -n10000 -t1 -r 'http://127.0.0.1:8080/'}}} will deliver benchmark results.

Otherwise use an alternative lightweight HTTP load-testing tool [[weighttp|http://redmine.lighttpd.net/projects/weighttp/wiki]] and the invocation {{{weighttp -k -c10 -n10000 'http://127.0.0.1:8080/'}}} for benchmarking.
<<toolbar permalink>>
! Stable Release 1.0.4.2 - 9 August 2011
This release is the same as  1.0.4.2rc13.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1rc3
* echo-nginx-module-0.37rc1
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.15
* iconv-nginx-module-0.10rc4
* lua-5.1.4
* memc-nginx-module-0.12
* nginx-1.0.4
* ngx_devel_kit-0.2.17
* ngx_lua-0.2.1rc4
* ngx_postgres-0.9rc1
* rds-json-nginx-module-0.12rc1
* redis2-nginx-module-0.07
* set-misc-nginx-module-0.22rc2
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.4.2rc13 - 8 August 2011
* now we bundle a Perl 5 script to serve as the {{{install}}} script for LuaJIT 2.0 on Solaris. now OpenResty builds successfully on Solaris 11 with LuaJIT enabled!
! Devel Release 1.0.4.2rc12 - 8 August 2011
* bundled {{{gcc}}}'s {{{unwind-generic.h}}} for BSD because {{{unwind.h}}} is missing at least on ~FreeBSD.
! Devel Release 1.0.4.2rc11 - 8 August 2011
* use absoluate paths in Makefile to prevent {{{-jN}}} errors when using bsdmake on ~FreeBSD.
! Devel Release 1.0.4.2rc10 - 7 August 2011
* upgraded ngx_lua to v0.2.1rc4.
** worked-around the "stack overflow" issue while using luarocks.loader and disabling {{{lua_code_cache}}}, as described as [[github issue #27|https://github.com/chaoslawful/lua-nginx-module/issues/27]]. thanks Patrick Crosby.
! Devel Release 1.0.4.2rc9 - 7 August 2011
* now we use {{{gmake}}} if it is available in {{{PATH}}} during {{{./configure}}}; also added the {{{--with-make=PATH}}} option to allow the user to specify a custom {{{make}}} utility.
! Devel Release 1.0.4.2rc8 - 6 August 2011
* fixed a regression that we should use the {{{CC}}} variable instead of {{{HOST_CC}}} while passing the {{{--with-cc}}} option to the LuaJIT 2.0 build system. thanks @姜大炮 for reporting this issue.
! Devel Release 1.0.4.2rc7 - 5 August 2011
*  upgraded ngx_lua to v0.2.1rc3.
** fixed the {{{zero size buf in output}}} alert while combining {{{lua_need_request_body on}}} + {{{access_by_lua/rewrite_by_lua}}} + {{{proxy_pass/fastcgi_pass}}}. thanks 万珣新.
! Devel Release 1.0.4.2rc6 - 5 August 2011
* added the {{{--with-pg_config}}} option to the {{{./configure}}} script as per 罗翼's request.
! Devel Release 1.0.4.2rc5 - 5 August 2011
* added the {{{--with-no-pool-patch}}} option to the {{{./configure}}} script, to allow enabling the no-pool patch for debugging memory issues with valgrind, for example.
! Devel Release 1.0.4.2rc4 - 4 August 2011
* added the {{{--with-libpq=DIR}}} option to the {{{./configure}}} script. thanks 郭颖 for suggesting this.
! Devel Release 1.0.4.2rc3 - 4 August 2011
* upgraded ngx_drizzle to v0.1.1rc3.
** fixed segmentation faults on Linux i386. thanks @魏世江 and @stefanli for reporting this issue.
! Devel Release 1.0.4.2rc2 - 4 August 2011
* fixed a regression while specifying {{{--with-http_iconv_module}}} during {{{./configure}}}. thanks 冯新国 for reporting this issue.
! Devel Release 1.0.4.2rc1 - 30 July 2011
* upgraded ngx_set_misc to 0.22rc2.
** added the set_misc_base32_padding directive.
! Stable Release 1.0.4.1 - 30 July 2011
This release is the same as  1.0.4.1rc6.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1rc2
* echo-nginx-module-0.37rc1
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.15
* iconv-nginx-module-0.10rc4
* lua-5.1.4
* memc-nginx-module-0.12
* nginx-1.0.4
* ngx_devel_kit-0.2.17
* ngx_lua-0.2.1rc2
* ngx_postgres-0.9rc1
* rds-json-nginx-module-0.12rc1
* redis2-nginx-module-0.07
* set-misc-nginx-module-0.22rc1
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.4.1rc6 - 28 July 2011
* fixed a regression in {{{./configure}}} when enabling luajit in 1.0.4.1rc5. thanks @Lance.
! Devel Release 1.0.4.1rc5 - 26 July 2011
* upgraded ngx_iconv to 0.10rc3, ngx_form_input to 0.07rc5, ngx_array_var to 0.03rc1, and ngx_set_misc to 0.22rc1.
* now {{{--with-debug}}} option also enables the {{{gcc -g}}} compilation option for LuaJIT.
* disabled target stripping in LuaJIT.
! Devel Release 1.0.4.1rc4 - 25 July 2011
* applied the official hotfix #1 patch for LuaJIT 2.0.0 beta8.
! Devel Release 1.0.4.1rc3 - 23 July 2011
* now the {{{--with-cc}}} option of {{{./configure}}} also controls the C compiler used by Lua and LuaJIT. thanks @姜大炮 for reporting the issue.
! Devel Release 1.0.4.1rc2 - 23 July 2011
* upgraded ngx_lua to v0.2.1rc2 and ngx_redis2 to v0.07.
! Devel Release 1.0.4.1rc1 - 14 July 2011
* upgraded ngx_rds_json to v0.12rc1, ngx_drizzle to v0.1.1rc2, ngx_lua to v0.2.1rc1, ngx_postgres to v0.9rc1, ngx_redis2 to v0.07rc6.
* now we no longer enable {{{gcc -O2}}} by default, because it's bad for debugging issues.
* fixed linking issues when doing {{{./configure --with-cc-opt=-fast}}} on Mac OS X. thanks @姜大炮.
! Stable Release 1.0.4.0 - 12 July 2011
This release is the same as  1.0.4.0rc5.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.02
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1rc1
* echo-nginx-module-0.37rc1
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc4
* headers-more-nginx-module-0.15
* iconv-nginx-module-0.10rc3
* lua-5.1.4
* memc-nginx-module-0.12
* nginx-1.0.4
* ngx_devel_kit-0.2.17
* ngx_lua-0.2.0
* ngx_postgres-0.8
* rds-json-nginx-module-0.11
* redis2-nginx-module-0.07rc5
* set-misc-nginx-module-0.21
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.4.0rc5 - 12 July 2011
* upgraded ngx_drizzle to v0.1.1rc1.
! Devel Release 1.0.4.0rc4 - 11 July 2011
* upgraded ngx_echo to v0.37rc1.
* we no longer require ~ExtUtils::~MakeMaker and Config because they're not standard packages and are missing on a default ~CentOS 6 build. thanks Lance for reporting it.
! Devel Release 1.0.4.0rc2 - 11 July 2011
* upgraded ngx_srcache to v0.12.
! Devel Release 1.0.4.0rc1 - 8 July 2011
* based on ngx_openresty 0.8.54.9, but with nginx core upgraded to nginx 1.0.4.

See [[ChangeLog8054]] for change log for ngx_openresty 0.8.54.x.
<<toolbar permalink>>
! Stable Release 1.0.5.1 - 4 September 2011
This release is almost the same as 1.0.5.1rc14, but upgraded LuaNginxModule to v0.3.0.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1rc4
* echo-nginx-module-0.37rc2
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.15
* iconv-nginx-module-0.10rc4
* lua-5.1.4
* lua-cjson-1.0.2
* lua-rds-parser-0.03
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.12
* nginx-1.0.5
* ngx_devel_kit-0.2.17
* ngx_lua-0.3.0
* ngx_postgres-0.9rc1
* rds-csv-nginx-module-0.02
* rds-json-nginx-module-0.12rc2
* redis2-nginx-module-0.07
* set-misc-nginx-module-0.22rc2
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.5.1rc14 - 2 September 2011
* upgraded LuaNginxModule to v0.2.1rc22.
** fixed an issue with {{{header_filter_by_lua}}} directive: it was not supported in scopes other than the location scope.
! Devel Release 1.0.5.1rc13 - 1 September 2011
* upgraded LuaNginxModule to 0.2.1rc21.
** added the {{{header_filter_by_lua}}} and {{{header_filter_by_lua_file}}} directives: http://wiki.nginx.org/HttpLuaModule#header_filter_by_lua
** fixed issues with HTTP 1.0 HEAD requests.
* upgraded EchoNginxModule to 0.37rc2
** fixed issues when errors happen in a downstream output filter.
** fixed issues with HTTP HEAD requests.
! Devel Release 1.0.5.1rc12 - 31 August 2011
* now we bundle LuaRdsParserLibrary and enable it by default.
* added the {{{--without-lua_rds_parser}}} option to disable the LuaRdsParserLibrary bundled.
* now we bundle RdsCsvNginxModule and enable it by default.
* added the {{{--without-http_rds_csv_module}}} option to disable RdsCsvNginxModule.
! Devel Release 1.0.5.1rc11 - 30 August 2011
* upgraded RdsJsonNginxModule to v0.12rc2
** fixed a bug in compact JSON mode: the column name in the resultset might not be escaped for JSON encoding.
! Devel Release 1.0.5.1rc10 - 29 August 2011
* upgraded LuaRedisParserLibrary to 0.09rc5.
** added wiki documentation page for this Lua library: http://wiki.nginx.org/LuaRedisParser
** added the {{{typename}}} method for converting the numeric type values returned by {{{parse_reply}}} and {{{parse_replies}}} to textual type names: http://wiki.nginx.org/LuaRedisParser#typename
! Devel Release 1.0.5.1rc9 - 27 August 2011
* upgraded LuaNginxModule to v0.2.1rc19.
** implemented the {{{o}}} regex option (i.e., the compile-once flag as Perl's {{{/o}}} modifier) for all the {{{ngx.re.*}}} API.
** added new directive {{{lua_regex_cache_max_entries}}} to control the upper limit of the worker-process-level compiled-regex cache enabled by the {{{o}}} regex option: http://wiki.nginx.org/HttpLuaModule#lua_regex_cache_max_entries
** now we add {{{ngx}}} and {{{ndk}}} table into {{{package.loaded}}} such that the user can write {{{local ngx = require 'ngx'}}} and {{{local ndk = require 'ndk'}}}. thanks @Lance.
! Devel Release 1.0.5.1rc8 - 26 August 2011
* upgraded LuaNginxModule to v0.2.1rc18.
** fixed a bug in the {{{ngx.re.*}}} regex API that look-behind assertions in PCRE regexes did not work properly.
! Devel Release 1.0.5.1rc7 - 26 August 2011
* upgraded LuaNginxModule to v0.2.1rc17.
** now we enable {{{ngx.re.*}}} regex API in {{{set_by_lua*}}} too.
! Devel Release 1.0.5.1rc6 - 25 August 2011
* upgraded LuaNginxModule to v0.2.1rc16.
** fixed github issue #52: compile error with nginx 1.0.5 on Ubuntu natty.
** fixed issues found by gcc 4.6 {{{-Wunused-but-set-variable}}} warnings.
! Devel Release 1.0.5.1rc5 - 24 August 2011
* upgraded LuaNginxModule to v0.2.1rc15.
** implemented the {{{ngx.re.gsub()}}} regex API for Lua: http://wiki.nginx.org/NginxHttpLuaModule#ngx.re.gsub
! Devel Release 1.0.5.1rc4 - 24 August 2011
* upgraded LuaNginxModule to v0.2.1rc14.
** added support for the optional {{{ctx}}} argument to {{{ngx.re.match}}}.
! Devel Release 1.0.5.1rc3 - 24 August 2011
* upgraded LuaNginxModule to v0.2.1rc13.
** implemented the {{{ngx.re.sub()}}} regex API for Lua: http://wiki.nginx.org/NginxHttpLuaModule#ngx.re.sub
** added support for anchored match modifier {{{a}}} to {{{ngx.re.match}}}, {{{ngx.re.gmatch}}}, and {{{ngx.re.sub}}}.
* upgraded DrizzleNginxModule to v0.1.1rc4
** added new wiki documentation page: http://wiki.nginx.org/NginxHttpDrizzleModule
** documented the {{{$drizzle_thread_id}}} variable.
** added lots of debug outputs (enabled by the {{{--with-debug}}} option while building Nginx or OpenResty), inspired by github issue #10.
! Devel Release 1.0.5.1rc2 - 18 August 2011
* upgraded LuaNginxModule to v0.2.1rc12.
** implemented the {{{ngx.re.gmatch()}}} regex API for Lua: http://wiki.nginx.org/NginxHttpLuaModule#ngx.re.gmatch
! Devel Release 1.0.5.1rc1 - 17 August 2011
* upgraded LuaNginxModule to v0.2.1rc11.
** now {{{ngx.ctx = {...} }}} assignment is supported.
** made setting {{{ngx.header.HEADER}}} after sending out response headers throw out a Lua exception to help debugging issues like github issue #49. thanks Bill Donahue (ikhoyo).
** implemented the {{{ngx.re.match()}}} regex API for Lua: http://wiki.nginx.org/NginxHttpLuaModule#ngx.re.match
! Stable Release 1.0.5.0 - 16 August 2011
This release is the same as 1.0.5.0rc7.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1rc3
* echo-nginx-module-0.37rc1
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.15
* iconv-nginx-module-0.10rc4
* lua-5.1.4
* lua-cjson-1.0.2
* lua-redis-parser-0.09rc4
* memc-nginx-module-0.12
* nginx-1.0.5
* ngx_devel_kit-0.2.17
* ngx_lua-0.2.1rc9
* ngx_postgres-0.9rc1
* rds-json-nginx-module-0.12rc1
* redis2-nginx-module-0.07
* set-misc-nginx-module-0.22rc2
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.5.0rc7 - 13 August 2011
* upgraded LuaNginxModule to v0.2.1rc9.
** implemented the special {{{ngx.ctx}}} Lua table for user programmers to store per-request Lua context data for their applications. thanks 欧远宁 for suggesting this feature.
! Devel Release 1.0.5.0rc6 - 12 August 2011
* upgraded LuaNginxModule to v0.2.1rc8.
** now {{{ngx.print}}} and {{{ngx.say}}} allow (nested) array-like table arguments. the array elements in them will be sent piece by piece. this will avoid string concatenation for templating engines like [[ltp|http://www.savarese.com/software/ltp/]].
! Devel Release 1.0.5.0rc5 - 12 August 2011
* upgraded LuaNginxModule to v0.2.1rc7.
** implemented the {{{ngx.req.get_post_args()}}} method for fetching urlencoded POST query arguments from within Lua.
** renamed {{{ngx.req.get_query_args}}} to {{{ngx.req.get_uri_args}}}. the former is now deprecated.
** fixed a bug in {{{ngx.req.get_uri_args}}}: it could not be used more than once in a single request.
! Devel Release 1.0.5.0rc4 - 12 August 2011
* upgraded LuaNginxModule to v0.2.1rc5.
** implemented the {{{ngx.req.get_query_args()}}} method to fetch parsed URL query arguments from within Lua. thanks Bertrand Mansion (golgote).
** now we allow Lua boolean and {{{nil}}} values in arguments to {{{ngx.say()}}}, {{{ngx.print()}}}, {{{ngx.log()}}} and {{{print()}}}.
! Devel Release 1.0.5.0rc3 - 11 August 2011
* now we bundle the LuaRedisParserLibrary with us and it is enabled by default. tested on Linux i386, Linux x86_64, Mac OS X, ~FreeBSD 8.2 i386, and Solaris 11.
* added the new option {{{--without-lua_redis_parser}}} to the {{{./configure}}} script.
! Devel Release 1.0.5.0rc2 - 10 August 2011
* now we bundle the LuaCjsonLibrary with us and it is enabled by default. tested on Linux i386, Linux x86_64, Mac OS X, ~FreeBSD 8.2 i386, and Solaris 11.
* added the new option {{{--without-lua_cjson}}} to the {{{./configure}}} script.
* added {{{<prefix>/lualib}}} to the default {{{path}}} and {{{cpath}}} settings of the ngx_lua's Lua VM.
! Devel Release 1.0.5.0rc1 - 9 August 2011
* based on ngx_openresty 1.0.4.2, but with nginx core upgraded to nginx 1.0.5.

See [[ChangeLog1000004]] for change log for ngx_openresty 1.0.4.x.
<<toolbar permalink>>
! Stable Release 1.0.6.22 - 7 October 2011
This release is exactly the same as the devel release 1.0.6.21.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1
* echo-nginx-module-0.37rc4
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.16rc2
* iconv-nginx-module-0.10rc4
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.03
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.12
* nginx-1.0.6
* ngx_devel_kit-0.2.17
* ngx_lua-0.3.1rc8
* ngx_postgres-0.9rc1
* rds-csv-nginx-module-0.03
* rds-json-nginx-module-0.12rc5
* redis2-nginx-module-0.07
* set-misc-nginx-module-0.22rc2
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.6.21 - 23 September 2011
* added new option {{{-jN}}} (e.g., {{{-j8}}}, {{{-j10}}}, and etc.) to OpenResty's {{{./configure}}} script to allow parallel build of the dependencies like LuaJIT; thanks @Lance.
! Devel Release 1.0.6.19 - 23 September 2011
* upgraded LuaNginxModule to v0.3.1rc8.
** exposes the {{{CRC-32}}} API of the Nginx core to the Lua land, in the form of the {{{ngx.crc32_short}}} and {{{ngx.crc32_long}}} methods. thanks @Lance.
! Devel Release 1.0.6.17 - 23 September 2011
* upgraded LuaNginxModule to v0.3.1rc7.
** now {{{ngx.exec()}}} supports lua table as the second {{{args}}} argument value. thanks sexybabes.
** implemented the {{{ngx.headers_sent}}} API to check if response headers are sent (by ngx_lua). thanks @hugozhu.
! Devel Release 1.0.6.15 - 22 September 2011
* upgraded LuaNginxModule to v0.3.1rc5.
** now we also return the {{{Last-Modified}}} header (if any) for the subrequest response object. thanks @cyberty and sexybabes.
! Devel Release 1.0.6.13 - 21 September 2011
* upgraded LuaNginxModule to v0.3.1rc4.
** fixed an issue in {{{ngx.redirect}}}, {{{ngx.exit}}}, and {{{ngx.exec}}}: these function calls would be intercepted by Lua {{{pcall}}}/{{{xpcall}}} because they used lua exceptions; now they use lua yield just as {{{ngx.location.capture}}}. thanks @hugozhu for reporting this.
! Stable Release 1.0.6.12 - 21 September 2011
This release is exactly the same as the devel release 1.0.6.11.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.1
* echo-nginx-module-0.37rc4
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.16rc2
* iconv-nginx-module-0.10rc4
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.03
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.12
* nginx-1.0.6
* ngx_devel_kit-0.2.17
* ngx_lua-0.3.1rc3
* ngx_postgres-0.9rc1
* rds-csv-nginx-module-0.03
* rds-json-nginx-module-0.12rc5
* redis2-nginx-module-0.07
* set-misc-nginx-module-0.22rc2
* srcache-nginx-module-0.12
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.6.11 - 20 September 2011
* upgraded RdsJsonNginxModule to v0.12rc4.
** made {{{rds_json_ret}}} honor {{{rds_json_success_property}}} and {{{rds_json_user_property}}}. thanks Liseen Wan (万珣新)
** only register our output filters when the {{{rds_json}}} directive is actually used in {{{nginx.conf}}}.
* upgraded RdsCsvNginxModule to v0.03.
** only register our output filters when the {{{rds_csv}}} directive is actually used in {{{nginx.conf}}}.
! Devel Release 1.0.6.9 - 19 September 2011
* upgraded LuaCjsonLibrary to v1.0.3.
! Devel Release 1.0.6.7 - 18 September 2011
* added new options {{{--with-luajit=PATH}}} and {{{--with-lua51=PATH}}} to the {{{./configure}}} script. thanks ~NginxUser.
* upgraded DrizzleNginxModule to v0.1.1.
! Devel Release 1.0.6.5 - 15 September 2011
* upgraded RdsJsonNginxModule to 0.12rc3.
** implemented new directive {{{rds_json_root}}}.
** implemented new directive {{{rds_json_success_property}}}.
** implemented new directive {{{rds_json_user_property}}}.
! Devel Release 1.0.6.3 - 14 September 2011
* upgraded LuaNginxModule to 0.3.1rc3.
** implemented and documented the API for reading response headers from within Lua: {{{value = ngx.header.HEADER}}}.
** fixed a bug when setting a multi-value response header to a single value (via writing to {{{ngx.header.HEADER}}}): the single value will be repeated on each old value.
* upgraded EchoNginxModule to 0.37rc4.
** fixed a bug in {{{echo_after_body}}}: when network is not perfect, data truncation might occur. we should have taken into account {{{NGX_AGAIN}}} returned by the downstream output filters. thanks Sparsh Gupta.
* upgraded HeadersMoreNginxModule to v0.16rc2.
** fixed a bug when setting a multi-value response header to a single value: the single value will be repeated on each old value.
* applied the patch from Maxim Dounin to fix a bug in the standard ngx_gzip module when dealing with empty flush buffers: http://mailman.nginx.org/pipermail/nginx-devel/2011-February/000730.html
* updated the no-pool-patch to eliminate the {{{-Wset-but-not-used}}} warnings issued by gcc 4.6.0.
! Devel Release 1.0.6.1 - 8 September 2011
* upgraded LuaNginxModule to 0.3.1rc1.
** 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's {{{Content-Length}}} headers to the user subrequests. thanks 朱峰.
! Devel Release 1.0.6.0rc2 - 4 September 2011
* upgraded HeadersMoreNginxModule to 0.16rc1.
** fixed on-demand hander/filter registration trick for {{{HUP}}} signal restarts.
** added some debugging outputs that can be enabled by the {{{--with-debug}}} option when building Nginx or OpenResty.
! Devel Release 1.0.6.0rc1 - 4 September 2011
* based on ngx_openresty 1.0.5.1, but with nginx core upgraded to nginx 1.0.6.

See [[ChangeLog1000005]] for change log for ngx_openresty 1.0.5.x.
<<toolbar permalink>>
! Stable Release 1.0.8.26 - 3 November 2011
* now we require {{{gmake}}} ({{{Gnu make}}}) for {{{*BSD}}} systems even if LuaJIT is not enabled. thanks [[@lhmwzy|http://weibo.com/lhmwzy]].
* upgraded the official [[hotfix patch #4|http://www.lua.org/ftp/patch-lua-5.1.4-4]] for the standard Lua 5.1.4 interpreter.
Components bundled in this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.2rc2
* echo-nginx-module-0.37rc7
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.16rc3
* iconv-nginx-module-0.10rc5
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.03
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.13rc1
* nginx-1.0.8
* ngx_devel_kit-0.2.17
* ngx_lua-0.3.1rc23
* ngx_postgres-0.9rc1
* rds-csv-nginx-module-0.04
* rds-json-nginx-module-0.12rc6
* redis2-nginx-module-0.08rc1
* set-misc-nginx-module-0.22rc3
* srcache-nginx-module-0.13rc2
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 1.0.8.25 - 27 October 2011
* upgraded LuaNginxModule to 0.3.1rc23.
** bugfix: {{{ndk.set_var.DIRECTIVE}}} had a memory issue and might pass empty argument values to the directive being called. thanks dannynoonan.
! Devel Release 1.0.8.23 - 27 October 2011
* upgraded LuaNginxModule to 0.3.1rc22.
** feature: implemented new methods {{{add}}}, {{{replace}}}, {{{incr}}}, and {{{delete}}} for {{{ngx.shared.DICT}}}.
** bugfix: made the {{{set}}} method of {{{ngx.shared.DICT}}} return 3 values: {{{success}}}, {{{err}}}, and {{{forcible}}}.
** bugfix: fixed spots of {{{-Werror=unused-but-set-variable}}} warning issued by gcc 4.6.0.
! Devel Release 1.0.8.21 - 26 October 2011
* upgraded LuaNginxModule to 0.3.1rc21.
** feature: added new directive {{{lua_shared_dict}}}: http://wiki.nginx.org/HttpLuaModule#lua_shared_dict
** feature: added Lua API for the shm-based dictionary: http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT
* upgraded EchoNginxModule to 0.37rc7.
** bugfix: fixed a memory issue in both {{{echo_sleep}}} and {{{echo_blocking_sleep}}}: we should not pass {{{ngx_str_t}}} strings to {{{atof()}}} which expects C strings.
! Devel Release 1.0.8.19 - 24 October 2011
* upgraded LuaNginxModule to 0.3.1rc20.
** bugfix: no longer free request body buffers that are not allocated by ourselves.
** bugfix: now we allow setting {{{ngx.var.VARIABLE}}} to {{{nil}}}.
! Devel Release 1.0.8.17 - 22 October 2011
* upgraded LuaNginxModule to 0.3.1rc19.
** feature: now we apply the patch to the nginx core so as to allow main request body modifications: https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.8-allow_request_body_updating.patch
** feature: added new Lua API {{{ngx.req.set_body_file()}}}: http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_file
** feature: added new Lua API {{{ngx.req.set_body_data()}}}: http://wiki.nginx.org/HttpLuaModule#ngx.req.set_body_data
** bugfix: {{{lua_need_request_body}}} should not skip requests with methods other than {{{POST}}} and {{{PUT}}}. thanks Nginx User.
! Devel Release 1.0.8.15 - 19 October 2011
* upgraded LuaNginxModule to 0.3.1rc17.
** feature: added new Lua functions {{{ngx.req.read_body()}}}, {{{ngx.req.discard_body()}}}, {{{ngx.req.get_body_data()}}}, and {{{ngx.req.get_body_file()}}}. see the docs here: http://wiki.nginx.org/HttpLuaModule#ngx.req.read_body
** bugfix: fixed hanging issues when using {{{ngx.exec()}}} within {{{rewrite_by_lua}}} and {{{access_by_lua}}}. thanks Nginx User for reporting it.
! Devel Release 1.0.8.13 - 16 October 2011
* upgraded LuaNginxModule to 0.3.1rc16.
** fixed compilation failures when {{{--with-debug}}} is turned off.
** now we prohibit use of {{{true}}} jump argument in {{{ngx.req.set_uri()}}} in contexts other than {{{rewrite_by_lua}}} and {{{rewrite_by_lua_file}}}. a lua exception will be thrown if the context is incorrect.
! Devel Release 1.0.8.11 - 16 October 2011
* upgraded LuaNginxModule to 0.3.1rc14.
** now we change the {{{ngx.req.set_uri()}}} API a bit by changing the optional argument {{{break_cycle}}} to {{{jump}}}. so now it will not trigger location jump by default (because the {{{jump}}} argument is false by default) and in case {{{jump}}} is given true, the function will re-search locations and jump to the new location and never return.
! Devel Release 1.0.8.9 - 16 October 2011
* upgraded LuaNginxModule to 0.3.1rc13.
** now we implemented {{{ngx.req.set_uri()}}} and {{{ngx.req.set_uri_args()}}} to emulate {{{ngx_rewrite}}}'s {{{rewrite}}} directive (without {{{redirect}}} or {{{permanent}}} modifiers). thanks Vladimir Protasov (utros) and Nginx User.
** now we skip rewrite phase Lua handlers altogether if {{{ngx_rewrite}}}'s {{{rewrite}}} directive issue a location re-lookup by changing ~URIs (but not including rewrite ... break). thanks Nginx User.
** added constant {{{ngx.HTTP_METHOD_NOT_IMPLEMENTED}}} (501). thanks Nginx User.
! Devel Release 1.0.8.7 - 15 October 2011
* upgraded SrcacheNginxModule to 0.13rc2.
** bugfix: we now only cache 200, 301, and 302 responses by default.
** feature: implemented new directive {{{srcache_store_statuses}}} to allow the user to specify the response status code list that is to be stored into the cache.
! Devel Release 1.0.8.5 - 13 October 2011
* upgraded LuaNginxModule to 0.3.1rc11.
** bugfix: now we explicitly clear all the modules' contexts before dump to named location with {{{ngx.exec}}}.
* upgraded EchoNginxModule to 0.37rc6.
** bugfix: now we explicitly clear all the modules' contexts before dump to named location with {{{echo_exec}}}.
** bugfix: bugfix: {{{echo_exec}}} may hang when running after {{{echo_sleep}}} (or other I/O interruption calls): we should have called {{{ngx_http_finalize_request}}} on {{{NGX_DONE}}} to decrement {{{r->main->count}}} anyway.
* applied the patch to the Nginx core that always clears all modules' contexts in {{{ngx_http_named_location}}}.
! Devel Release 1.0.8.3 - 13 October 2011
* upgraded LuaNginxModule to 0.3.1rc10.
** bugfix: calling {{{ngx.exec()}}} to jump to a named location did not clear the context object of LuaNginxModule properly and might cause evil problems. thanks Nginx User.
* upgraded IconvNginxModule to 0.10rc5.
** bugfix: fixed {{{-Wset-but-not-used}}} warnings issued by gcc 4.6.0. thanks 支家乐 (Calio).
! Devel Release 1.0.8.1 - 10 October 2011
* upgraded EchoNginxModule to 0.37rc5.
** bugfix: now we properly set the {{{Content-Length}}} request header for subrequests.
* upgraded LuaNginxModule to 0.3.1rc9.
** feature: now for HTTP 1.0 requests, we disable the automatic full buffering mode if the user sets the {{{Content-Length}}} 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 李子义.
** bugfix: now we properly support setting the {{{Cache-Control}}} response header via the {{{ngx.header.HEADER}}} interface.
** bugfix: no longer set header hash to 1. use the {{{ngx_hash_key_lc}}} instead.
* upgraded HeadersMoreNginxModule to 0.16rc3.
** bugfix: we should set header hash using {{{ngx_hash_key_lc}}}, not simply to 1.
** bugfix: fixed setting {{{Cache-Control}}} response headers. we should properly prepare the {{{r->cache_control}}} array as well.
* upgraded SrcacheNginxModule to 0.13rc1.
** implemented response status line and general response header caching and added new directives {{{srcache_store_hide_header}}} and {{{srcache_store_pass_header}}} to control which headers to cache and which not.
** added new directive {{{srcache_response_cache_control}}} to control whether honor response headers {{{Cache-Control}}} and {{{Expires}}}, default {{{on}}}.
** we disable {{{srcache_store}}} automatically by default when {{{Cache-Control: max-age=0}}} and {{{Expires: <date no more recently than now>}}} are seen.
** implemented builtin nginx variable {{{$srcache_expire}}} for automatic expiration time calculation based on response headers {{{Cache-Control}}} ({{{max-age}}}) and {{{Expires}}}; also added new directives {{{srcache_max_expire}}} and {{{srcache_default_expire}}}.
** implemented the {{{srcache_store_no_cache}}} directive; now by default, we do not store responses with the header {{{Cache-Control: no-cache}}} into the cache.
** implemented {{{the srcache_store_no_store directive}}} (default {{{off}}}). Now by default, responses with the header {{{Cache-Control: no-store}}} will not be stored into the cache.
** implemented the {{{srcache_store_private}}} directive to control whether to store responses with the header {{{Cache-Control: private}}}.
** implemented the {{{srcache_request_cache_control}}} directive to allow request headers {{{Cache-Control: no-cache}}} or {{{Pragma: no-cache}}} to force bypassing cache lookup. it also honors the request header {{{Cache-Control: no-store}}}. this directive is turned off by default.
** now we check response header {{{Content-Encoding}}} by default and a non-empty header value will {{{skip srcache_store}}}; also introduced a new directive named {{{srcache_ignore_content_encoding}}} to ignore this response header.
** implemented the {{{srcache_methods}}} directive to specify request methods that are cacheable, by default, only {{{GET}}} and {{{HEAD}}} are cacheable.
** bugfix: we no longer set header hash to 1; we use {{{ngx_hash_key_lc}}} instead.
** bugfix: when we skip {{{srcache_fetch}}} by means of {{{srcache_fetch_skip}}}, we should not automatically skip {{{srcache_store}}}.
** bugfix: now we ignore the {{{Content-Length}}} header (if any) of the main request for the subrequests.
** bugfix: there might be a segfault when failing to allocate memory in {{{ngx_http_srcache_add_copy_chain}}}. thanks Shaun savage.
* upgraded RdsJsonNginxModule to 0.12rc6.
** bugfix: fixed compatibility with nginx 1.1.4+.
* upgraded RdsCsvNginxModule to 0.04.
** bugfix: fixed compatibility issues with nginx 1.1.4+.
** optimization: now we only register our filters when {{{rds_csv}}} is actually used in {{{nginx.conf}}}.
* upgraded Redis2NginxModule to 0.08rc1.
** bugfix: fixed compatibility with nginx 1.1.4+.
* upgraded DrizzleNginxModule to 0.1.2rc2.
** bugfix: fixed compatibility with nginx 1.1.4+
* upgraded MemcNginxModule to 0.13rc1.
** bugfix: fixed compatibility with nginx 1.1.4+.
* upgraded SetMiscNginxModule to v0.22rc3.
** minor code cleanup.
* applied the patch for the variable-header-ignore-no-hash issue. see http://forum.nginx.org/read.php?29,216062 for details.
* based on OpenResty 1.0.6.22 and upgraded the Nginx core to 1.0.8.

See [[ChangeLog1000006]] for change log for ngx_openresty 1.0.6.x.
<<toolbar permalink>>
! Stable Release 1.0.9.10 - 16 November 2011
* bugfix: fixed the error message length while the {{{./configure}}} script fails.

Components bundled in this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.2rc4
* echo-nginx-module-0.37rc7
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.16rc4
* iconv-nginx-module-0.10rc5
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.04
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.13rc1
* nginx-1.0.9
* ngx_devel_kit-0.2.17
* ngx_lua-0.3.1rc28
* ngx_postgres-0.9rc2
* rds-csv-nginx-module-0.04
* rds-json-nginx-module-0.12rc6
* redis2-nginx-module-0.08rc1
* set-misc-nginx-module-0.22rc3
* srcache-nginx-module-0.13rc2
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc5
! Devel Release 1.0.9.9 - 13 November 2011
* upgraded DrizzleNginxModule to 0.1.2rc4.
** bugfix: it might prematurly remove a write event when still busily connecting to the database from the event model.
! Devel Release 1.0.9.7 - 10 November 2011
* applied [[a patch|https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.9-log_escape_non_ascii.patch]] to add new directives {{{log_escape_non_ascii}}} to prevent escaping non-ascii bytes in access log variable values. requested by [[@姜大炮|http://weibo.com/egis]]. It can be turned {{{on}}} and {{{off}}}, and default to {{{on}}} just as the standard Nginx version.
! Devel Release 1.0.9.5 - 9 November 2011
* upgraded LuaNginxModule to 0.3.1rc28.
** bugfix: {{{Cache-Control}}} header modification might introduce empty value headers when using with the standard [[ngx_headers|http://wiki.nginx.org/HttpHeadersModule]] module.
* upgraded HeadersMoreNginxModule to 0.16rc4.
** bugfix: {{{Cache-Control}}} header modification might introduce empty value headers when using with the standard [[ngx_headers|http://wiki.nginx.org/HttpHeadersModule]] module.
! Devel Release 1.0.9.3 - 9 November 2011
* upgraded LuaNginxModule to 0.3.1rc27.
** feature: added the [[ngx.encode_args|http://wiki.nginx.org/HttpLuaModule#ngx.encode_args]] method to encode a Lua code to a URI query string. thanks 郭颖 ([[0597虾|http://weibo.com/shrimp0597]]).
** feature: [[ngx.location.capture|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture]] and [[ngx.exec|http://wiki.nginx.org/HttpLuaModule#ngx.exec]] now supports the same Lua args table format as in [[ngx.encode_args|http://wiki.nginx.org/HttpLuaModule#ngx.encode_args]]. thanks 郭颖 ([[0597虾|http://weibo.com/shrimp0597]]).
* upgraded DrizzleNginxModule to 0.1.2rc3.
** bugfix: fixed issues with {{{poll}}}, {{{rtsig}}}, and {{{select}}} used by the Nginx event model by eliminating the {{{poll}}} syscall performed by {{{libdrizzle}}}. This also gives rise to a nice speedup (about 10% in simple cases).
* bugfix: [[nginx-1.0.9-variable_header_ignore_no_hash.patch|https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.9-variable_header_ignore_no_hash.patch]] might introduce a memory overflow issue in multi-header variables. thanks Markus Linnala.
! Devel Release 1.0.9.1 - 8 November 2011
* upgraded the Nginx core to 1.0.9.
* applied the [[epoll_check_stale_wev patch|http://mailman.nginx.org/pipermail/nginx-devel/2011-November/001408.html]] to the Nginx 1.0.9 core. thanks [[@晓旭XX|http://weibo.com/u/1878897190]].
* upgraded LuaNginxModule to 0.3.1rc26.
** feature: added the {{{ctx}}} option to [[ngx.location.capture|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture]]: you can now specify a custom Lua table to pass to the subrequest as its [[ngx.ctx|http://wiki.nginx.org/HttpLuaModule#ngx.ctx]]. thanks [[@hugozhu|http://weibo.com/hugozhu]].
** bugfix: fixed compatibility with nginx 0.8.54. thanks [[@0579虾|http://weibo.com/shrimp0597]].
* upgraded PostgresNginxModule to 0.9rc2
** bugfix: now we log an error message when the {{{postgres_pass}}} target is not found at all and returns 500 in this case instead of returning empty response.
**  bugfix: we should no longer return {{{NGX_AGAIN}}} when the re-polling returns IO WAIT in case of the "connection made" state.
** feature: added some debugging outputs which be enabled by passing the {{{--with-debug}}} option while building Nginx or OpenResty.
** bugfix: fixed compatibility issues with Nginx 1.1.4+: {{{ngx_chain_update_chains}}} now requires a pool argument.
* upgraded LuaRdsParserLibrary to 0.04.
** bugfix: fixed a serious memory leak reported by bearnard.
* upgraded XssNginxModule to 0.03rc5.
** bugfix: the callback argument value parser did not accept ~JavaScript identifier names started with underscores. thanks Sam Mulube.
See [[ChangeLog1000008]] for change log for ngx_openresty 1.0.8.x.
<<toolbar permalink>>
! Stable Release 1.0.10.48 - 1 February 2012
* upgraded LuaNginxModule to 0.4.1.
Components bundled with this release:
* ~LuaJIT-2.0.0-beta9
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.2rc6
* echo-nginx-module-0.38rc1
* encrypted-session-nginx-module-0.02
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.17rc1
* iconv-nginx-module-0.10rc5
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.04
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.13rc3
* nginx-1.0.10
* ngx_devel_kit-0.2.17
* ngx_lua-0.4.1
* ngx_postgres-0.9rc2
* rds-csv-nginx-module-0.04
* rds-json-nginx-module-0.12rc7
* redis2-nginx-module-0.08rc2
* set-misc-nginx-module-0.22rc5
* srcache-nginx-module-0.13rc3
* upstream-keepalive-nginx-module-0.7
* xss-nginx-module-0.03rc8
! Devel Release 1.0.10.47 - 29 January 2012
* upgraded LuaNginxModule to 0.4.1rc4.
** bugfix: {{{ngx_http_lua_header_filter_init}}} 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 [[issue #80|http://github.com/chaoslawful/lua-nginx-module/issues/80]]. thanks bigplum (Simon).
! Devel Release 1.0.10.45 - 19 January 2012
* upgraded LuaNginxModule to 0.4.1rc3.
** bugfix: fixed all the warnings from the {{{clang}}} static analyzer.
** bugfix: [[ngx.exit|http://wiki.nginx.org/HttpLuaModule#ngx.exit]], [[ngx.redirect|http://wiki.nginx.org/HttpLuaModule#ngx.redirect]], [[ngx.exec|http://wiki.nginx.org/HttpLuaModule#ngx.exec]], and [[ngx.req.set_uri(uri, true)|http://wiki.nginx.org/HttpLuaModule#ngx.req.set_uri]] 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 [[@cyberty|http://weibo.com/cyberty]] for reporting it.
** feature: allow use of the {{{DDEBUG}}} macro from the outside (via the {{{-D DDEBUG=1}}} cc opton).
* upgraded DrizzleNginxModule to v0.1.2rc6.
** bugfix: fixed all the warnings from the {{{clang}}} static analyzer.
** feature: allow use of the {{{DDEBUG}}} macro from the outside (via the {{{-D DDEBUG=1}}} cc opton).
* upgraded EchoNginxModule to 0.38rc1, SetMiscNginxModule to 0.22rc5, HeadersMoreNginxModule to 0.17rc1, and MemcNginxModule to 0.13rc3, to allow use of the {{{DDEBUG}}} macro from the outside (via the {{{-D DDEBUG=1}}} cc opton).
! Stable Release 1.0.10.44 - 16 January 2012
* upgraded EchoNginxModule to 0.37.
* upgraded HeadersMoreNginxModule to 0.16.
* bugfix: fixed compatibility of the packaging scripts on Darwin and *BSD. thanks nightsailer and Piotr Sikora.
Components bundled with this release:
* ~LuaJIT-2.0.0-beta9
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.2rc4
* echo-nginx-module-0.37
* encrypted-session-nginx-module-0.02
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.16
* iconv-nginx-module-0.10rc5
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.04
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.13rc2
* nginx-1.0.10
* ngx_devel_kit-0.2.17
* ngx_lua-0.4.0
* ngx_postgres-0.9rc2
* rds-csv-nginx-module-0.04
* rds-json-nginx-module-0.12rc7
* redis2-nginx-module-0.08rc2
* set-misc-nginx-module-0.22rc4
* srcache-nginx-module-0.13rc3
* upstream-keepalive-nginx-module-0.7
* xss-nginx-module-0.03rc8
! Devel Release 1.0.10.43 - 12 January 2012
* upgraded LuaNginxModule to 0.4.0.
* upgraded EncryptedSessionNginxModule to 0.02.
** bugfix: the {{{-lssl}}} option broke nginx linking when {{{--with-openssl=DIR}}} is specified. thanks charlieyang for reporting this issue.
* bugfix: fixed issues with relative path DIR in the {{{--with-openssl=DIR}}} option for {{{./configure}}}.
! Devel Release 1.0.10.41 - 9 January 2012
* upgraded UpstreamKeepaliveNginxModule to 0.7.
** Bugfix: unbuffered connection might not be kept alive under Linux.
** Bugfix: module could not be built on Windows.
** Bugfix: module could not be built without the ngx_http_ssl_module.
** Feature: https connections support (requires patches).
** Bugfix: invalid connections might be cached.
** Bugfix: the "[alert] ... open socket ... left in connection ..." messages were logged on nginx worker process gracefull exit for each cached connection; the bug had appeared in version 0.3.
* upgraded EchoNginxModule to 0.37rc8.
** bugfix: fixed two spots that we did not check null pointers returned by the memory allocator.
** bugfix: attempt to fix places where {{{ngx_time_update}}} might not be compiled properly.
! Devel Release 1.0.10.39 - 4 January 2012
* upgraded LuaNginxModule to v0.3.1rc45.
** bugfix: [[ngx.req.get_uri_args|http://wiki.nginx.org/HttpLuaModule#ngx.req.get_uri_args]] and [[ngx.req.get_post_args|http://wiki.nginx.org/HttpLuaModule#ngx.req.get_post_args]] 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.
** bugfix:  [[ngx.req.get_headers|http://wiki.nginx.org/HttpLuaModule#ngx.req.get_headers]] 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.
! Devel Release 1.0.10.37 - 30 December 2011
* upgraded LuaNginxModule to v0.3.1rc43.
** bugfix: removing builtin headers via [[ngx.req.clear_header|http://wiki.nginx.org/HttpLuaModule#ngx.req.clear_header]] and its equivalent in huge request headers with 20+ entries could result in data loss. thanks Chris Dumoulin for the patch in [[github issue #6|https://github.com/agentzh/headers-more-nginx-module/issues/6]].
** 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 {{{ngx.re}}} API (since PCRE 8.20 had a bug in its JIT engine that it did not honor {{{pcre_malloc}}} and {{{pcre_free}}} at all).
! Devel Release 1.0.10.35 - 30 December 2011
* upgraded HeadersMoreNginxModule to v0.16rc7.
** bugfix: removing builtin headers in huge request headers with 20+ entries could result in data loss. thanks Chris Dumoulin for the patch in [[github issue #6|https://github.com/agentzh/headers-more-nginx-module/issues/6]].
* bugfix: the {{{install}}} phony target did not depend on the {{{all}}} phony target in the Makefile generated by {{{./configure}}}. thanks [[姚伟斌|http://weibo.com/yaoweibin]] for reporting this issue.
! Devel Release 1.0.10.33 - 29 December 2011
* bugfix: the {{{./configure}}} script's  {{{--add-module}}} option did not accept relative path values. thanks [[姚伟斌|http://weibo.com/yaoweibin]] for the patch.
! Devel Release 1.0.10.31 - 25 December 2011
* upgraded LuaJIT to 2.0.0beta9.
** changes: http://luajit.org/changes.html
* upgraded LuaNginxModule to v0.3.1rc42.
** bugfix: [[ngx.req.set_header|http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header]] might cause invalid memory reads because Nginx request header values must be null terminated. thanks Maxim Dounin.
** bugfix: {{{ngx.var.VARIABLE}}} might evaluate to nil even if there is a valid value because the Nginx variable value's {{{valid}}} flag might not be initialized properly. this bad had appeared in v0.3.1rc40.
* upgraded HeadersMoreNginxModule to v0.16rc6.
** bugfix: the [[more_set_input_headers|http://wiki.nginx.org/HttpHeadersMoreModule#more_set_headers]] directive might cause invalid memory reads because Nginx request header values must be null terminated. thanks Maxim Dounin.
! Devel Release 1.0.10.29 - 17 December 2011
* upgraded LuaNginxModule to v0.3.1rc41.
** bugfix: [[ngx.req.set_header|http://wiki.nginx.org/HttpLuaModule#ngx.req.set_header]] and [[ngx.req.clear_header|http://wiki.nginx.org/HttpLuaModule#ngx.req.clear_header]] did not handle the {{{Accept-Encoding}}} request headers properly. thanks 天街夜色.
* upgraded HeadersMoreNginxModule to 0.16rc5.
** bugfix: [[more_set_input_headers|http://wiki.nginx.org/HttpHeadersMoreModule#more_set_input_headers]] and [[more_clear_input_headers|http://wiki.nginx.org/HttpHeadersMoreModule#more_clear_input_headers]] did not handle the {{{Accept-Encoding}}} request headers properly. thanks 天街夜色.
! Devel Release 1.0.10.27 - 16 December 2011
* upgraded LuaNginxModule to v0.3.1rc40.
** bugfix: {{{ngx.flush(true)}}} could not be used before I/O calls like [[ngx.location.capture|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture]]. this bug had appeared in v0.3.1rc34.
** bugfix: {{{ngx.var.VARIABLE}}} did not evaluate to {{{nil}}} when the Nginx variable's {{{valid}}} flag is {{{0}}}.
** docs: various documentation improvements. thanks Nginx User.
** bugfix: there were various places where we did not check the pointer returned by the memory allocator.
* upgraded SetMiscNginxModule to v0.22rc4.
** bugfix: fixed one place that does not check the pointer returned by the memory allocator.
** src: converted {{{CRLF}}} in the source files and test files to {{{LF}}}.
* bugfix: some old version of shell {{{cp}}} command does not support trailing slashes in the destination argument and could break our {{{./configure}}} script. thanks [[姚伟斌|http://weibo.com/yaoweibin]] for reporting it.
! Devel Release 1.0.10.25 - 14 December 2011
* upgraded SrcacheNginxModule to v0.13rc3.
** bugfix: fixed a regression with XssNginxModule for cache hits. this bug had appeared in v0.13rc1. thanks [[万珣新|http://weibo.com/liseen]].
** bugfix: we did not cache the {{{Location}}} response header at all for {{{301}}}/{{{302}}} responses.
** bugfix: we should not blindly cache the {{{Accept-Ranges: bytes}}} response headers regardless of the actual current requests.
* upgraded XssNginxModule to v0.03rc8.
** bugfix: fixed a few debug-level log messages; the old text was misleading.
! Stable Release 1.0.10.24 - 11 December 2011
Same as the devel version 1.0.10.23.

Components bundled with this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.2rc4
* echo-nginx-module-0.37rc7
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.16rc4
* iconv-nginx-module-0.10rc5
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.04
* lua-redis-parser-0.09rc5
* memc-nginx-module-0.13rc2
* nginx-1.0.10
* ngx_devel_kit-0.2.17
* ngx_lua-0.3.1rc38
* ngx_postgres-0.9rc2
* rds-csv-nginx-module-0.04
* rds-json-nginx-module-0.12rc7
* redis2-nginx-module-0.08rc2
* set-misc-nginx-module-0.22rc3
* srcache-nginx-module-0.13rc2
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc7
! Devel Release 1.0.10.23 - 5 December 2011
* upgraded RdsJsonNginxModule to v0.12rc7.
** added more debug level error log outputs to ease debugging (as discussed in [[github issue #2|https://github.com/agentzh/rds-json-nginx-module/issues/2]]).
* upgraded XssNginxModule to v0.03rc7.
** now we use the {{{ngx_log_debugN}}} macros to emit debugging outputs instead of {{{info}}} level error logging because the latter is costly in production.
* upgraded LuaNginxModule to 0.3.1rc38.
** added constant {{{ngx.HTTP_GATEWAY_TIMEOUT}}} (504) per Fry-kun in [[github issue #73|https://github.com/chaoslawful/lua-nginx-module/issues/73]].
! Devel Release 1.0.10.21 - 30 November 2011
* fixed a serious regression for Linux AIO in [[nginx-1.0.10-epoll_check_stale_wev.patch|https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.10-epoll_check_stale_wev.patch]], thanks Maxim Dounin for the patch's patch.
! Devel Release 1.0.10.19 - 29 November 2011
* upgraded LuaNginxModule to 0.3.1rc37.
** bugfix: use of the ngx.re API might lead to errors like {{{pcre_compile() failed: failed to get memory in ...}}} due to incorrect {{{pcre_malloc}}} and {{{pcre_free}}} handling. thanks Vittly for reporting this as [[github issue #72|https://github.com/chaoslawful/lua-nginx-module/issues/72]].
** docs: massive documentation improvements. thanks Nginx User.
! Devel Release 1.0.10.17 - 26 November 2011
* upgraded LuaNginxModule to 0.3.1rc36.
** bugfix: fixed the {{{ngx_log_debugN}}} macros which failed to compile without {{{--with-debug}}}. thanks [[@ldmiao|http://weibo.com/ldmiao]] for reporting it.
! Devel Release 1.0.10.15 - 26 November 2011
* upgraded LuaNginxModule to 0.3.1rc35.
** bugfix: now we check timed out downstream connections in our write event handler.
! Devel Release 1.0.10.13 - 25 November 2011
* upgraded LuaNginxModule to 0.3.1rc34.
** feature: added {{{wait}}} boolean argument to [[ngx.flush()|http://wiki.nginx.org/HttpLuaModule#ngx.flush]] to support synchronous flushing; {{{ngx.flush(true)}}} will not return until all the data has been flushed into the system send buffer or the send timeout has expired.
! Devel Release 1.0.10.11 - 24 November 2011
* upgraded LuaNginxModule to 0.3.1rc33.
** feature: added new Lua API [[ngx.now|http://wiki.nginx.org/HttpLuaModule#ngx.now]] to return the current time (including the ms part as the decimal part). thanks 林青.
** feature: added new Lua API [[ngx.update_time|http://wiki.nginx.org/HttpLuaModule#ngx.update_time]] to forcibly updating nginx's time cache.
** docs: massive documentation improvement done by Nginx User.
! Devel Release 1.0.10.9 - 24 November 2011
* upgraded XssNginxModule to 0.03rc6.
** bugfix: now we use {{{signed char}}} explicitly instead of the vague {{{char}}} type which could be unsigned by default in certain systems like ~PowerPC. thanks Dmitry E. Oboukhov.
* upgraded MemcNginxModule to 0.13rc2.
** bugfix: now we use {{{signed char}}} explicitly instead of the vague {{{char}}} type which could be unsigned by default in certain systems like ~PowerPC. thanks Dmitry E. Oboukhov.
* upgraded Redis2NginxModule to 0.08rc2.
** bugfix: when {{{char}}} defaults to {{{unsigned char}}}, the Ragel-based Redis response parser could not accept non-ascci bytes. thanks Dmitry E. Oboukhov.
! Devel Release 1.0.10.7 - 23 November 2011
* upgraded LuaNginxModule to 0.3.1rc31.
** feature: added opions {{{copy_all_vars}}} and {{{vars}}} to [[ngx.location.capture|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture]] and [[ngx.location.capture_multi|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi]]. thanks Marcus Clyne for the patch.
** bugfix: fixed a bad regression in [[ngx.location.capture_multi|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi]] when the request option table is specified. this bug had appeared in ngx_lua 0.3.1rc26 and ngx_openresty 1.0.9.1.
! Devel Release 1.0.10.5 - 21 November 2011
* upgraded LuaNginxModule to 0.3.1rc30.
** feature: added new regex options {{{"j"}}} and {{{"d"}}} to [[ngx.re.match|http://wiki.nginx.org/HttpLuaModule#ngx.re.match]], [[ngx.re.gmatch|http://wiki.nginx.org/HttpLuaModule#ngx.re.gmatch]], [[ngx.re.sub|http://wiki.nginx.org/HttpLuaModule#ngx.re.sub]], and [[ngx.re.gsub|http://wiki.nginx.org/HttpLuaModule#ngx.re.gsub]]  so as to enable the PCRE [[JIT mode|http://www.manpagez.com/man/3/pcrejit/]] and DFA mode, respectively. thanks [[@姜大炮|http://weibo.com/egis]] for providing the patch.
! Devel Release 1.0.10.3 - 17 November 2011
* upgraded LuaNginxModule to 0.3.1rc29.
** feature: added [[ngx.hmac_sha1|http://wiki.nginx.org/HttpLuaModule#ngx.hmac_sha1]]. thanks [[drdrxp|http://weibo.com/drdrxp]].
** docs: documented the long-existent [[ngx.md5|http://wiki.nginx.org/HttpLuaModule#ngx.md5]] and [[ngx.md5_bin|http://wiki.nginx.org/HttpLuaModule#ngx.md5_bin]] ~APIs.
** docs: massive documentation improvements. thanks Nginx User.
! Devel Release 1.0.10.1 - 16 November 2011
* upgraded the Nginx core to 1.0.10.

See [[ChangeLog1000009]] for change log for ngx_openresty 1.0.9.x.
<<toolbar permalink>>
! Stable Release 1.0.11.28 - 25 March 2012
Same as the devel release 1.0.11.27.

Components bundled with this release:
* ~LuaJIT-2.0.0-beta9 (hotfix #1)
* array-var-nginx-module-0.03rc1
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.2rc6
* echo-nginx-module-0.38rc2
* encrypted-session-nginx-module-0.02
* form-input-nginx-module-0.07rc5
* headers-more-nginx-module-0.17rc1
* iconv-nginx-module-0.10rc7
* lua-5.1.4
* lua-cjson-1.0.3
* lua-rds-parser-0.04
* lua-redis-parser-0.09rc7
* lua-resty-memcached-0.06
* lua-resty-mysql-0.06
* lua-resty-redis-0.08
* lua-resty-string-0.05
* lua-resty-upload-0.02
* memc-nginx-module-0.13rc3
* nginx-1.0.11
* ngx_coolkit-0.2rc1
* ngx_devel_kit-0.2.17
* ngx_lua-0.5.0rc21
* ngx_postgres-0.9
* rds-csv-nginx-module-0.05rc1
* rds-json-nginx-module-0.12rc7
* redis2-nginx-module-0.08rc4
* set-misc-nginx-module-0.22rc5
* srcache-nginx-module-0.13rc6
* upstream-keepalive-nginx-module-0.7
* xss-nginx-module-0.03rc9
! Devel Release 1.0.11.27 - 22 March 2012
* upgraded LuaNginxModule to 0.5.0rc21.
** bugfix: made the sha1 library (or ~OpenSSL) an optional dependency, as suggested by runner-mei in [[github issue #94|https://github.com/chaoslawful/lua-nginx-module/issues/94]].
** bugfix: we did not declare C variables at the beginning of the current code block in {{{ngx_http_lua_del_thread}}}, reported by runner-mei in [[github issue #93|https://github.com/chaoslawful/lua-nginx-module/issues/93]].
** bugfix: incorrectly used {{{ngx_conf_log_error}}} by feeding {{{NGX_ERROR}}} as the first argument, as reported by runner-mei in [[github issue #92|https://github.com/chaoslawful/lua-nginx-module/issues/92]].
** bugfix: spelling errors in Lua exception message text.
* upgraded EchoNginxModule to 0.38rc2.
** bugfix: [[$echo_request_body|http://wiki.nginx.org/HttpEchoModule#.24echo_request_body]] variable was not able to work on arbitrary request body chains (i.e., more than 2 chain links), just like the standard [[$request_body|http://wiki.nginx.org/HttpCoreModule#.24request_body]] variable that only processes the first two chain links. now [[$echo_request_body|http://wiki.nginx.org/HttpEchoModule#.24echo_request_body]] no longer has this limitation.
* applied the upstream_pipelining patch to the nginx core, as discussed here: http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html this patch is required at least for the pipelined requests support in nginx upstream modules.
! Devel Release 1.0.11.25 - 16 March 2012
* applied the null-character-fixes patch from the mainstream. The bug did result in a disclosure of previously freed memory if upstream server returned specially crafted response, potentially exposing sensitive information.
* upgraded SrcacheNginxModule to 0.13rc6.
** bugfix: fixed a typo in an error message text for response truncation check in [[srcache_store|http://wiki.nginx.org/HttpSRCacheModule#srcache_store]].
! Devel Release 1.0.11.23 - 15 March 2012
* upgraded LuaNginxModule to 0.5.0rc19.
** feature: added new directive [[lua_http10_buffering|http://wiki.nginx.org/HttpLuaModule#lua_http10_buffering]] which is {{{on}}} by default.
** feature: added new constant {{{ngx.DECLINED}}}.
** bugfix: [[access_by_lua|http://wiki.nginx.org/HttpLuaModule#access_by_lua]] could not work with the {{{satisfy any}}} configuration.
** bugfix: now we recycle the special flush buffer and chain link for [[ngx.flush|http://wiki.nginx.org/HttpLuaModule#ngx.flush]] to prevent request-scoped memory leaks when emitting long data streams to the downstream.
* upgraded SrcacheNginxModule to 0.13rc5.
** feature: now [[srcache_store|http://wiki.nginx.org/HttpSRCacheModule#srcache_store]] discards responses that are obviously truncated when the actual output data is shorter than what is declared in its {{{Content-Length}}} response header. thanks Greg Grensteiner.
** bugfix: the access phase handler actually ran in a phase later than the {{{access}}} phase.
** bugfix: HTTP HEAD requests that lead to a cache hits would cause memory issues like invalid reads.
* upgraded LuaRestyRedisLibrary to 0.08.
** feature: implemened redis pipelining API by adding new methods {{{init_pipeline}}}, {{{commit_pipeline}}}, and {{{cancel_pipeline}}}.
! Devel Release 1.0.11.21 - 7 March 2012
* upgraded LuaRestyRedisLibrary to 0.07.
** feature: added the [[evalsha|http://redis.io/commands/eval]] command to the redis command table. thanks Chris Love.
* upgraded LuaRestyStringLibrary to 0.05.
** feature: added new modules {{{resty.sha224}}}, {{{resty.sha256}}}, {{{resty.sha384}}}, and {{{resty.sha512}}} to exposes the ~OpenSSL API for the complete {{{SHA-2}}} hash function set. thanks @lhmwzy.
* upgraded LuaNginxModule to 0.5.0rc17.
** bugfix: time stamps could overflow on 32-bit systems in the shared dict API; now we explicitly use 64-bit integers.
** feature: added new method {{{flush_all}}} to the shared dict. thanks Weiqiang Li.
** docs: documented the max concurrent subrequest count limitation and max error log line size limit.
! Devel Release 1.0.11.19 - 1 March 2012
* upgraded Redis2NginxModule to 0.08rc4.
** bugfix: redis "nil multi bulk replies" did not parse at all. thanks 郭颖 for reporting this issue.
* upgraded LuaRedisParserLibrary to 0.09rc7.
** bugfix: redis "nil multi bulk replies" did not parse at all. thanks 郭颖 for reporting this issue.
! Devel Release 1.0.11.17 - 29 February 2012
* feature: bundle LuaRestyMySQLLibrary 0.06, which is enabled by default.
* feature: bundle LuaRestyRedisLibrary 0.06, which is enabled by default.
* feature: bundle LuaRestyMemcachedLibrary 0.06, which is enabled by default.
* feature: bundle LuaRestyUploadLibrary 0.02, which is enabled by default.
* feature: bundle LuaRestyStringLibrary 0.04, which is enabled by default.
* bugfix: no longer enable {{{-DLUAJIT_USE_VALGRIND}}} for LuaJIT when {{{--with-debug}}} option is specified.
* bugfix: applied the official [[hotfix #1 patch|http://luajit.org/download/beta9_hotfix1.patch]] for LuaJIT 2.0.0 beta9.
* feature: raised the default {{{NGX_HTTP_MAX_SUBREQUESTS}}} to 200, in sync with the official repository.
* upgraded LuaNginxModule to 0.5.0rc16.
** bugfix: the shared dict storage might leak memory in the store: {{{ngx_http_lua_shdict_lookup}}} incorrectly assumed that nodes with identical keys are linked together, which might not be true after tree re-balancing. thanks the patch from Lanshun Zhou.
** optimize: removed a redundant piece of code for subrequest {{{headers_in}}} fixes in {{{ngx_http_lua_adjust_subrequest}}}.
! Devel Release 1.0.11.15 - 24 February 2012
* now we enable the {{{-DLUAJIT_USE_VALGRIND -DLUA_USE_APICHECK -DLUA_USE_ASSERT}}} flags for LuaJIT when the {{{--with-debug}}} option is specified.
* apply the [[max_subrequests patch|https://github.com/agentzh/ngx_openresty/blob/master/patches/nginx-1.0.11-max_subrequests.patch]] to allow the {{{NGX_HTTP_MAX_SUBREQUESTS}}} macro to be overridden from the outside and adjusted the default value from 50 to 100 because 50 is a little too conservative.
* upgraded XssNginxModule to 0.03rc9, RdsCsvNginxModule to 0.05rc1, and Redis2NginxModule to 0.08rc3, allowing enabling {{{DDEBUG=1}}} globally.
* upgraded IconvNginxModule to 0.10rc7.
** bugfix: enabling {{{DDEBUG=1}}} globally lead to compilation errors.
** bugfix: could not work with HTTP 1.0 requests.
** optimize: only register output filters when the {{{iconv_filter}}} is actually used in the config file.
* upgraded LuaNginxModule to 0.5.0rc15.
** bugfix: the {{{exptime}}} argument to {{{shdict:set/add/etc}}} methods was incorrectly ignored when the {{{flags}}} argument is also specified. thanks the patch from Brian Akins.
** docs: fixed various typos in docs. thanks 王斌.
** bugfix: for big input data, the cosocket reading methods could result in crashes due to incorrect use of {{{luaL_Buffer}}}. now we eliminate {{{luaL_Buffer}}} altogether by managing the recv buffers ourselves. the recv buffers can also be recycled.
** bugfix: now we avoid using {{{luaL_checkstring}}} which could do another {{{long jump}}} on its own. thanks 王斌.
** bugfix: {{{tcpsocket:setkeepalive()}}} did not return errors when the current connection has readable data or there is still unread data in the LuaNginxModule upstream buffer.
** bugfix: cosocket methods no longer explicitly return {{{nil}}} error strings upon success.
** bugfix: when the parent request takes a request body, the subrequest does not take any bodies, and the subrequest's method is neither {{{PUT}}} nor {{{POST}}}, then the subrequest will no longer inherit the parent request's request body. thanks 欧远宁 for reporting this issue.
** bugfix: data might be accidentally read into the Lua space on idle sockets when the last operation is a read operation *and* a read event suddenly arrives for edge-triggered event models. the same might also apply to write operations too.
** bugfix: invalid reads might happen in the reading iterators returned by the {{{receiveuntil()}}} method which could lead to segfaults. this was a bug in the DFA minimizer's optimized code path.
** bugfix: the {{{closed}}} error would occur for long-running requests that hold the idle cosocket object for a period of time that is longer than the read timeout setting: we should delete the read event timer in time when the {{{receive}}} call has already got a read event. thanks 欧远宁 for reporting this issue.
** logs: added error logs for cosocket timeout errors.
** logs: added detailed error logs for cosocket {{{closed}}} errors.
** optimize: introduced a minor optimization that we can save one {{{recv}}} call when the read event is active *and* the read event is not ready.
** optimize: now we recycle the downstream output buffers to save memory and dynamic allocation times for long-running requests with huge outputs.
** bugfix: C macro directives were used inside a C macro argument which made (at least) gcc 3.2.3 unhappy. thanks Feng Bin.
! Devel Release 1.0.11.11 - 14 February 2012
* upgraded LuaNginxModule to 0.5.0rc7.
** bugfix: cosocket API could not be used before [[ngx.location.capture|http://wiki.nginx.org/HttpLuaModule#ngx.location.capture]] and its friends for fast network access: [[tcpsock:send()|http://wiki.nginx.org/HttpLuaModule#tcpsock:send]] method did not reset {{{u->waiting}}} properly. thanks 欧远宁.
! Devel Release 1.0.11.9 - 13 February 2012
* upgraded LuaNginxModule to 0.5.0rc6.
** bugfix: could not compile with nginx 0.8.x. thanks 欧远宁. this bug had appeared in LuaNginxModule v0.5.0rc1.
** feature: added the [[ngx.sha1_bin|http://wiki.nginx.org/HttpLuaModule#ngx.sha1_bin]] method which returns the binary form of the {{{SHA-1}}} digest.
** bugfix: we incorrectly allowed {{{ngx.null}}} in the string table argument to [[cosocket:send()|http://wiki.nginx.org/HttpLuaModule#tcpsock:send]] method.
** feature: allow use of ngx.null in [[ngx.log()|http://wiki.nginx.org/HttpLuaModule#ngx.log]] and [[print()|http://wiki.nginx.org/HttpLuaModule#print]] arguments.
* added Piotr Sikora's CoolkitNginxModule 0.2rc1 to the bundle, which is also enabled by default.
! Devel Release 1.0.11.7 - 7 February 2012
* upgraded LuaNginxModule to 0.5.0rc5.
** feature: added constant {{{ngx.null}}} which is a {{{NULL}}} light userdata to represent {{{nil}}} values in Lua tables and etc. this is compatible with at least [[lua-cjson|http://www.kyne.com.au/~mark/software/lua-cjson.php]] library's {{{cjson.null}}} constant.
! Devel Release 1.0.11.5 - 7 February 2012
* upgraded LuaNginxModule to 0.5.0rc4.
** bugfix: setting {{{ngx.header.last_modified}}} was not implemented fully. thanks Brian Akins.
! Devel Release 1.0.11.3 - 6 February 2012
* upgraded LuaNginxModule to 0.5.0rc3.
** feature: now [[tcpsocket:send()|http://wiki.nginx.org/HttpLuaModule#tcpsock:send]] method supports lua tables of string fragments which can save unnecessary string concatenation operations on the Lua land that are usually quite expensive.
** bugfix: fixed issues in debugging logs for the cosocket API.
** feature: added user flags support to the [[shared dictionary API|http://wiki.nginx.org/HttpLuaModule#ngx.shared.DICT]]. thanks Brian Akins.
* upgraded LuaRedisParserLibrary to 0.09rc6.
** bugfix: remove unneeded string push operations. thanks Brian Akins.
! Devel Release 1.0.11.1 - 2 February 2012
* upgraded the Nginx core to 1.0.11.
** see the changes here: http://nginx.org/en/CHANGES-1.0
* upgraded LuaNginxModule to 0.5.0rc1.
** feature: implemented the coroutine-based TCP and Unix Domain client socket API (aka the "cosocket" API) that is mostly compatible with the [[LuaSocket|http://w3.impa.br/~diego/software/luasocket/tcp.html]] library.
** feature: implemented built-in connection pool support for the cosocket API.
** feature: added new function [[ngx.req.socket()|http://wiki.nginx.org/HttpLuaModule#ngx.req.socket]] to return a cosocket object for the downstream connection so as to do streaming request body reading. thanks Taylor Weibley for sponsoring the development work.
** optimization: optimized the chain-link and buf recycle logic for the subrequest API and make it share free buffers with the cosocket API.
* upgraded PostgresNginxModule to 0.9.
** bugfix: Fix compatibility with poll, select and /dev/poll event models.
** bugfix: Fix compatibility with ~PostgreSQL 9.x.
** bugfix: Fix compatibility with nginx-1.1.4+.

See ChangeLog1000010 for change log for ngx_openresty 1.0.10.x.
<<toolbar permalink>>
! Devel Release 1.0.15.5 - 16 May 2012
* upgraded LuaJIT to 2.0.0beta10.
** see changes here: http://luajit.org/changes.html
* feature: added the {{{--with-luajit-xcflags=FLAGS}}} option to {{{./configure}}} to add more C compiler options to LuaJIT's build system.
* upgraded LuaNginxModule to 0.5.0rc28.
** bugfix: [[ngx.req.socket()|http://wiki.nginx.org/HttpLuaModule#ngx.req.socket]] did not honor the {{{Expect: 100-continue}}} request header and could hang. thanks Matthieu Tourne for the patch in [[pull request #107|https://github.com/chaoslawful/lua-nginx-module/pull/107]].
** bugfix: the [[ngx.req.socket()|http://wiki.nginx.org/HttpLuaModule#ngx.req.socket]] object (i.e., the downstream cosocket object) did not work with HTTP 1.1 pipelined requests at all.
** bugfix: the [[ngx.req.socket()|http://wiki.nginx.org/HttpLuaModule#ngx.req.socket]] object might lose the last part of the request body when receiving data. this regression had appeared in v0.5.0rc25. thanks Matthieu Tourne for reporting it.
** feature: detailed backtraces (Lua callstack) will be automatically printed to {{{error.log}}} when the user Lua code is interrupted by Lua exceptions. thanks Matthieu Tourne for the patch in [[pull request #107|https://github.com/chaoslawful/lua-nginx-module/pull/107]].
** optimize: removed dead code found by Simon Liu via scan-build.
* upgraded RdsCsvNginxModule to 0.05rc2.
** bugfix: the output buffer size would get wrong when the {{{affected_rows}}} field is larger than a single-digit number. thanks Wendal Chen for reporting this by using clang.
* upgraded LuaRestyStringLibrary to 0.06.
** feature: added new Lua module {{{resty.random}}} that implements secure random and pseudo-random string generators. thanks Chase Colman for the patch.
** feature: added new Lua module {{{resty.aes}}} that exposes the AES submodule of ~OpenSSL via LuaJIT FFI. thanks Chase Colman for the patch.
! Devel Release 1.0.15.3 - 13 May 2012
* now we bundle Sergey A. Osokin's RedisNginxModule, 0.3.6, which is also enabled by default. thanks Zhu Feng for requesting this.
* upgraded LuaNginxModule to 0.5.0rc27.
** bugfix: nginx could crash on request finalization when running the cosocket cleanup handle due to the lack of check of the {{{ctx}}} pointer. thanks shaneeb for reporting this in [[github issue #110|https://github.com/chaoslawful/lua-nginx-module/issues/110]].
** bugfix: [[ngx.req.get_body_data()|http://wiki.nginx.org/HttpLuaModule#ngx.req.get_body_data]] could not handle multi-buffer request bodies and discarded the body data after the first buffer.
** bugfix: [[ngx.ctx|http://wiki.nginx.org/HttpLuaModule#ngx.ctx]] was not accessible at all in {{{set_by_lua*}}}. thanks Pierre.
** bugfix: fixed typo "on-array", which should be "non-array", in an error message.
** optimize: now [[ngx.log|http://wiki.nginx.org/HttpLuaModule#ngx.log]] is much faster when the log level argument is lower than the actual [[error_log|http://wiki.nginx.org/CoreModule#error_log]] level specified in nginx.conf. thanks Matthieu Tourne for providing the patch.
** optimize: now we call {{{ngx_http_lua_socket_finalize}}} in {{{cosocket:setkeepalive()}}} to help buffer reuse.
* upgraded SetMiscNginxModule to 0.22rc8.
** feature: added new directives [[set_secure_random_alphanum|http://wiki.nginx.org/HttpSetMiscModule#set_secure_random_alphanum]] and [[set_secure_random_lcalpha|http://wiki.nginx.org/HttpSetMiscModule#set_secure_random_lcalpha|]] for generating cryptographically strong random strings based on the {{{/dev/urandom}}} device. thanks Jeremy Wohl for the patch.
* upgraded SrcacheNginxModule to 0.13rc8.
** bugfix: the {{{Content-Length}}} response header for HEAD requests should leave intact when cache hits happen.
** bugfix: the [[srcache_store|http://wiki.nginx.org/HttpSRCacheModule#srcache_store]] subrequest did not set the {{{Content-Length}}} request header properly for multi-buffer request bodies. thanks Feibo Lee for submitting the patch.
** feature: HTTP conditional GET requests are now supported (both {{{If-Modified-Since}}} and {{{If-Unmodified-Since}}} request headers are properly handled). thanks ~Nginx_User777.
* upgraded LuaRedisParserLibrary to v0.09.
** feature: added {{{redis.parser._VERSION}}}.
** bugfix: now we use Lua userdata to allocate memory used on the C side to prevent potential leaks caused by malloc/free, as discussed in [[github issue #6|https://github.com/agentzh/lua-redis-parser/issues/6]].
* upgraded LuaRdsParserLibrary to 0.05.
** feature: added {{{redis.parser._VERSION}}}.
** bugfix: now we use Lua userdata to allocate memory used on the C side to prevent potential leaks caused by malloc/free, as discussed in [[github issue #6|https://github.com/agentzh/lua-redis-parser/issues/6]].
* upgraded LuaRestyMemcachedLibrary to 0.07.
** feature: now the methods for the Memcached storage commands now accept Lua tables as the {{{value}}} argument. thanks Brian Akins for the patch.
* upgraded LuaRestyUploadLibrary to 0.03.
** feature: now the raw headers for each part are also returned, as suggested by zou2062 in [[github issue #1|https://github.com/agentzh/lua-resty-upload/issues/1]].
* applied the patch for a bug in {{{ngx_http_named_location}}} to the nginx core: http://mailman.nginx.org/pipermail/nginx-devel/2012-May/002166.html
* applied the patch for a bug in the filter finalizer to the nginx core: http://mailman.nginx.org/pipermail/nginx-devel/2012-May/002190.html
! Devel Release 1.0.15.1 - 29 April 2012
* upgraded the Nginx core to 1.0.15.
* bugfix: now we also add {{{<openresty_prefix>/lualib/?/init.lua}}} to the default {{{package.path}}} search list. thanks bigplum for reporting this issue.
* upgraded LuaNginxModule to 0.5.0rc25.
** bugfix: cosocket connections from the connection pool might lead to segfaults if it is not used immediately. thanks xukaifu for reporting this as [[github issue #108|https://github.com/chaoslawful/lua-nginx-module/issues/108]].
** bugfix: debug logging in the cosocket receive line method could lead to invalid memory reads under extreme network conditions. this issue was caught by [[mockeagain|https://github.com/agentzh/mockeagain]] in reading mode.
** bugfix: downstream cosockets might hang on the receive(size) method call for slow connections. [[mockeagain|https://github.com/agentzh/mockeagain]] in reading mode caught this issue.
** bugfix: we no longer forcibly quit the lua threads by clearing out its environment and running it blindly to the end because Lua GC will collect all those unfinished coroutines anyway.
** bugfix: improved the longjmp handling when Lua panic happens.
** bugfix: certain compilers might complain about missing declarations for types like {{{int8_t}}}. now we explicitly included {{{stdint.h}}}. thanks runner-mei for reporting it in [[github issue #98|https://github.com/chaoslawful/lua-nginx-module/issues/98]].
** feature: added new constant {{{ngx.HTTP_OPTIONS}}} for the HTTP OPTIONS method.
** feature: added support for OPTIONS method in the subrequest capture ~APIs. thanks Jónas Tryggvi Jóhannsson for requesting this in [[github issue #102|https://github.com/chaoslawful/lua-nginx-module/issues/102]].
** feature: added publich C functions {{{ngx_http_lua_add_package_preload}}}, {{{ngx_http_lua_get_global_state}}}, and {{{ngx_http_lua_get_request}}} to help other Nginx C modules expose new functionalities to LuaNginxModule. thanks Brian Akins for suggesting them in [[github pull request #101|https://github.com/chaoslawful/lua-nginx-module/pull/101]].
** feature: made {{{ngx_http_lua_api.h}}} visible to other Nginx modules by adding {{{src/api/}}} to the {{{CORE_INCS}}} config variable value in the config file. thanks Brian Akins for suggesting this in [[github pull request #105|https://github.com/chaoslawful/lua-nginx-module/pull/105]].
** feature: add the {{{gdbinit}}} script to ease Lua user code debugging (Wang Xiaozhe).
** optimize: various optimizations in cosocket's timeout handling. this gives about 2.5+% performance boost in some benchmarks using LuaRestyRedisLibrary and LuaRestyMySQLLibrary.
* upgraded RdsJsonNginxModule to v0.12rc8.
** bugfix: Microsoft C compilers complained about missing declarations of the type {{{int8_t}}}. now we explicitly include {{{stdint.h}}}. thanks runner-mei for reporting this issue in [[github issue #3|https://github.com/agentzh/rds-json-nginx-module/issues/3]].
* upgraded SetMiscNginxModule to 0.22rc7.
** bugfix: we should omit the [[set_sha1|http://wiki.nginx.org/HttpSetMiscModule#set_sha1]] directive when we do not have any ~SHA1 libraries (including ~OpenSSL) installed. thanks runner-mei for reporting this in [[github issue #9|https://github.com/agentzh/set-misc-nginx-module/issues/9]].
** feature: added new config directive [[set_rotate|http://wiki.nginx.org/HttpSetMiscModule#set_rotate]].
* upgraded DrizzleNginxModule to 0.1.2rc7.
** bugfix: reading data on a reused ~MySQL connection (coming from the connection pool) could hang due to the inactive read event when {{{poll}}} event API is used in nginx.
* upgraded LuaRestyMySQLLibrary to 0.07.
** fixed a typo in error messages.
** skipped parsing those column fields that we do not use (yet). this makes things noticeably faster.

See ChangeLog1000011 for change log for ngx_openresty 1.0.11.x.
<<toolbar permalink>>
! Stable Release 0.8.54.9 - 8 July 2011
This release is the same as  0.8.54.9rc6.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.02
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.1.0
* echo-nginx-module-0.36
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc4
* headers-more-nginx-module-0.15
* iconv-nginx-module-0.10rc3
* lua-5.1.4
* memc-nginx-module-0.12
* nginx-0.8.54
* ngx_devel_kit-0.2.17
* ngx_lua-0.2.0
* ngx_postgres-0.8
* rds-json-nginx-module-0.11
* redis2-nginx-module-0.07rc5
* set-misc-nginx-module-0.21
* srcache-nginx-module-0.12rc6
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 0.8.54.9rc6 - 8 July 2011
* upgraded ngx_echo to v0.36 and ngx_memc to v0.12.
! Devel Release 0.8.54.9rc5 - 7 July 2011
* applied the subrequest loop fix patch from Maxim Dounin.
! Devel Release 0.8.54.9rc4 - 6 July 2011
* upgraded ngx_rds_json to v0.11, ngx_headers_more to v0.15, and ngx_drizzle to v0.1.0.
! Devel Release 0.8.54.9rc3 - 5 July 2011
* upgraded ngx_drizzle to 0.0.15rc14 and ngx_lua to 0.2.0.
! Devel Release 0.8.54.9rc2 - 4 July 2011
* upgraded ngx_lua to 0.1.6rc18.
! Devel Release 0.8.54.9rc1 - 3 July 2011
* upgraded ngx_redis2 to 0.07rc5.
! Stable Release 0.8.54.8 - 1 July 2011
This release is the same as  0.8.54.8rc2.

The following components are bundled by this release:
* ~LuaJIT-2.0.0-beta8
* array-var-nginx-module-0.02
* auth-request-nginx-module-0.2
* drizzle-nginx-module-0.0.15rc13
* echo-nginx-module-0.36rc6
* encrypted-session-nginx-module-0.01
* form-input-nginx-module-0.07rc4
* headers-more-nginx-module-0.15rc3
* iconv-nginx-module-0.10rc3
* lua-5.1.4
* memc-nginx-module-0.12rc2
* nginx-0.8.54
* ngx_devel_kit-0.2.17
* ngx_lua-0.1.6rc17
* ngx_postgres-0.8
* rds-json-nginx-module-0.11rc2
* redis2-nginx-module-0.07rc4
* set-misc-nginx-module-0.21
* srcache-nginx-module-0.12rc6
* upstream-keepalive-nginx-module-0.3
* xss-nginx-module-0.03rc3
! Devel Release 0.8.54.8rc2 - 1 July 2011
* upgraded ngx_echo to 0.36rc6, ngx_lua to 0.1.6rc17, ngx_srcache to 0.12rc6, and ngx_redis2 to 0.07rc4.
! Devel Release 0.8.54.8rc1 - 28 June 2011
* we no longer bundle libdrizzle because [[libdrizzle 1.0|https://launchpad.net/libdrizzle]] is distributed with the drizzle server and hard to separate.
* now ngx_drizzle is disabled by default. you need to enable it via the {{{--with-http_drizzle_module}}} option.
* added {{{--with-libdrizzle}}} option to specify the (lib)drizzle installation prefix.
! Stable Release 0.8.54.7 - 27 June 2011
* identical to 0.8.54.7rc5.
! Devel Release 0.8.54.7rc5 - 27 June 2011
* we should preserve timestamps when copying bundle/ to build/ in ./configure script. this should fix luajit build on some systems.
! Devel Release 0.8.54.7rc4 - 27 June 2011
upgraded ngx_xss to 0.03rc3, ngx_drizzle to 0.0.15rc11, ngx_memc to 0.12rc2, ngx_srcache to 0.12rc5, ngx_redis2 to 0.07rc3.
! Devel Release 0.8.54.7rc3 - 27 June 2011
* upgraded LuaJIT to 2.0.0beta8, ngx_lua to 0.1.6rc15, and ngx_echo to 0.36rc4.
! Devel Release 0.8.54.7rc2
* Upgraded [[LuaNginxModule]] to v0.1.6rc14 and [[HeadersMoreNginxModule]] to v0.15rc3.
! Devel Release 0.8.54.7rc1
* Upgraded [[HeadersMoreNginxModule]] to v0.15rc2 and [[LuaNginxModule]] to v0.1.6rc13.
! Release 0.8.54.6
* Upgraded [[DrizzleNginxModule]] to 0.0.15rc10.
* Upgraded [[LuaNginxModule]] to 0.1.6rc12.
* Upgraded [[Redis2NginxModule]] to 0.07rc2.
! Release 0.8.54.5
* Upgraded [[EchoNginxModule]] to 0.36rc3.
* Upgraded [[LuaNginxModule]] to 0.1.6rc9.
Background: #fff
Foreground: #000
PrimaryPale: #effa72
PrimaryLight: #007E00
PrimaryMid: #007E00
PrimaryDark: #145D00
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #bd4
SecondaryDark: #04859d
TertiaryPale: #c9f76f
TertiaryLight: #60d5ac
TertiaryMid: #00a383
TertiaryDark: #666
Error: #f88
<<toolbar permalink>>

Below lists all the components bundled in OpenResty. All of the components can be enabled or disabled on need.

Most of the components are enabled by default, some are not.

[[LuaJIT]], [[DrizzleNginxModule]], [[PostgresNginxModule]], and [[IconvNginxModule]] are not enabled by default. You need to specify the {{{--with-luajit}}}, {{{--with-http_drizzle_module}}}, {{{--with-http_postgres_module}}}, and {{{--with-http_iconv_module}}} options, respectively, to enable them while [[building OpenResty|Installation]].

* [[LuaJIT]]
* [[ArrayVarNginxModule]]
* [[AuthRequestNginxModule]]
* [[DrizzleNginxModule]]
* [[EchoNginxModule]]
* [[EncryptedSessionNginxModule]]
* [[FormInputNginxModule]]
* [[HeadersMoreNginxModule]]
* [[IconvNginxModule]]
* [[StandardLuaInterpreter]]
* [[MemcNginxModule]]
* [[Nginx]]
* [[NginxDevelKit]]
* [[LuaCjsonLibrary]]
* [[LuaNginxModule]]
* [[LuaRdsParserLibrary]]
* [[LuaRedisParserLibrary]]
* [[LuaRestyMemcachedLibrary]]
* [[LuaRestyMySQLLibrary]]
* [[LuaRestyRedisLibrary]]
* [[LuaRestyStringLibrary]]
* [[LuaRestyUploadLibrary]]
* [[PostgresNginxModule]]
* [[RdsCsvNginxModule]]
* [[RdsJsonNginxModule]]
* [[RedisNginxModule]]
* [[Redis2NginxModule]]
* [[SetMiscNginxModule]]
* [[SrcacheNginxModule]]
* [[UpstreamKeepaliveNginxModule]]
* [[XssNginxModule]]
<<toolbar permalink>>

You're encouraged to send general questions regarding OpenResty and Nginx to the [[nginx mailing list|http://nginx.org/mailman/listinfo/nginx]].

Reporting bugs are encouraged to file tickets for the ngx_openresty project on GitHub:

https://github.com/agentzh/ngx_openresty/issues

Alternatively you can send mails privately to [[agentzh|http://agentzh.org]]: agentzh at gmail dot com.

You're encouraged to send general questions to the [[Nginx English mailing list|http://mailman.nginx.org/mailman/listinfo/nginx]].

For Chinese users, you're encouraged to send mails to the OpenResty mailing list to benefit more people:
* Subscribing: send an empty email to {{{openresty+subscribe@googlegroups.com}}}
* Posting: send emails to {{{openresty@googlegroups.com}}}
* Unsuscribing: send emails to {{{openresty+unsubscribe@googlegroups.com}}}
* Post Archive: http://groups.google.com/group/openresty
* Code Repository: https://github.com/agentzh/ngx_openresty
* Issues tracking: https://github.com/agentzh/ngx_openresty/issues
* Chinese home: http://openresty.org/cn/
This module is collection of small and useful Nginx add-ons.

Project homepage and documentation: https://github.com/FRiCKLE/ngx_coolkit/

This module is enabled by default and could be disabled by passing {{{--without-http_coolkit_module}}} option to OpenResty's {{{./configure}}} script.
[[OpenResty]] [[About]]
<<toolbar permalink>>

! Donate With ~PayPal

If you'd like to make a one-time donation to OpenResty, you can use ~PayPal to make it fast and easy.

* ~PayPal members can donate directly from their ~PayPal accounts by logging in via the ~PayPal website and clicking "send money" to {{{agentzh@gmail.com}}}, or just click the button below.
* ~Non-PayPal members can still pay with a credit card without signing up for ~PayPal. Click the button below then follow the instructions at the bottom of the page for non-~PayPal members.

Either way, it's a convenient way to support ocean wildlife.

<html>
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="agentzh@gmail.com">
<input type="hidden" name="item_name" value="OpenResty Donation (in USD)">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="amount" value="">
<input type="image" src="donate_button_paypal_01.gif" border="0" name="submit" alt="Donate with PayPal">
</form>
</html>

! Donate with ~AliPay (支付宝)

If you're in China, it's usually more convenient to send donation is to send money via the [[AliPay|http://www.alipay.com/]] to my account {{{agentzh@yahoo.cn}}} or just click the following button:

<html>
<a href="http://me.alipay.com/agentzh" target="_blank"><img src="donate-with-alipay.png"></a>
</html>

Any amount will be highly appreciated!
<<toolbar permalink>>
!Releases
!! Stable release
Most of the users should use the current release, i.e., the latest stable release.
* [[ngx_openresty-1.0.11.28.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.11.28.tar.gz]] 2.7MB [[Changes|ChangeLog1000011]] - 25 March 2012
!! Development release
Development releases are for developers or brave users to try out new bug fixes and new features.
* [[ngx_openresty-1.0.15.5.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.15.5.tar.gz]] 2.8MB [[Changes|ChangeLog1000015]] - 16 May 2012
!! Legacy releases
Sometimes, users may want to download old releases.
* [[ngx_openresty-1.0.10.48.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.10.48.tar.gz]] 2.6MB [[Changes|ChangeLog1000010]] - 1 February 2012
* [[ngx_openresty-1.0.10.44.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.10.44.tar.gz]] 2.5MB [[Changes|ChangeLog1000010]] - 16 January 2012
* [[ngx_openresty-1.0.10.24.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.10.24.tar.gz]] 2.5MB [[Changes|ChangeLog1000010]] - 11 December 2011
* [[ngx_openresty-1.0.9.10.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.9.10.tar.gz]] 2.5MB [[Changes|ChangeLog1000009]] - 16 November 2011
* [[ngx_openresty-1.0.8.26.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.8.26.tar.gz]] 2.5MB [[Changes|ChangeLog1000008]] - 3 November 2011
* [[ngx_openresty-1.0.6.22.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.6.22.tar.gz]] 2.4MB [[Changes|ChangeLog1000006]] - 7 October 2011
* [[ngx_openresty-1.0.6.12.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.6.12.tar.gz]] 2.4MB [[Changes|ChangeLog1000006]] - 21 September 2011
* [[ngx_openresty-1.0.5.1.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.5.1.tar.gz]] 2.4MB [[Changes|ChangeLog1000005]] - 4 September 2011
* [[ngx_openresty-1.0.4.2.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.4.2.tar.gz]] 2.2MB [[Changes|ChangeLog1000004]] - 9 August 2011
* [[ngx_openresty-1.0.4.1.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.4.1.tar.gz]] 2.3MB [[Changes|ChangeLog1000004]] - 30 July 2011
* [[ngx_openresty-1.0.4.0.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-1.0.4.0.tar.gz]] 2.3MB [[Changes|ChangeLog1000004]] - 12 July 2011
* [[ngx_openresty-0.8.54.9.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-0.8.54.9.tar.gz]] 2.2MB [[Changes|ChangeLog8054]] - 8 July 2011
* [[ngx_openresty-0.8.54.8.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-0.8.54.8.tar.gz]] 2.2MB [[Changes|ChangeLog8054]] - 1 July 2011
* [[ngx_openresty-0.8.54.7.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-0.8.54.7.tar.gz]] 2.7MB [[Changes|ChangeLog8054]] - 27 June 2011
* [[ngx_openresty-0.8.54.6.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-0.8.54.6.tar.gz]] 2.7MB [[Changes|ChangeLog8054]]
* [[ngx_openresty-0.8.54.5.tar.gz|http://agentzh.org/misc/nginx/ngx_openresty-0.8.54.5.tar.gz]] 2.7MB [[Changes|ChangeLog8054]]
See [[Installation]] for installation instructions.
<<toolbar permalink>>

This is an nginx upstream module that talks to ~MySQL and/or Drizzle database servers by [[libdrizzle]].

This ngx_drizzle module is not enabled by default. You should specify the {{{--with-http_drizzle_module}}} optiotn while configuring OpenResty.

The [[libdrizzle]] C library is no longer bundled by OpenResty. You need to download the drizzle server tarball from https://launchpad.net/drizzle.

Latest drizzle7 release does not support building libdrizzle 1.0 separately and requires a lot of external dependencies like Boost and Protobuf which are painful to install. The last version supporting building libdrizzle 1.0 separately is {{{2011.07.21}}}. You can download it from here:

http://agentzh.org/misc/nginx/drizzle7-2011.07.21.tar.gz

When you get the drizzle7 2011.07.21 release tarball, you can install libdrizzle-1.0 like this:
{{{
tar xzvf drizzle7-2011.07.21.tar.gz
cd drizzle7-2011.07.21/
./configure --without-server
make libdrizzle-1.0
make install-libdrizzle-1.0
}}}

Please ensure that you have the {{{python}}} command point to a {{{python2}}} interpreter. It's known that on recent Arch Linux distribution, {{{python}}} is linked to {{{python3}}} by default, and while running {{{make libdrizzle-1.0}}} will yield the following error:
{{{
  File "config/pandora-plugin", line 185
    print "Dependency loop detected with %s" % plugin['name']
                                           ^
SyntaxError: invalid syntax
make: *** [.plugin.scan] Error 1
}}}
You can fix this by pointing {{{python}}} temporarily to {{{python2}}}.

When you install the libdrizzle-1.0 library to a custom path prefix, you can specify the libdrizzle prefix to OpenResty like this:
{{{
cd /path/to/ngx_openresty-VERSION/
./configure --with-libdrizzle=/path/to/drizzle --with-http_drizzle_module
}}}

Documentation page: http://wiki.nginx.org/HttpDrizzleModule

Project page: https://github.com/chaoslawful/drizzle-nginx-module
<<toolbar permalink>>

This sample demonstrates how to use Redis to route incoming requests to different HTTP backends based on the requests' {{{User-Agent}}} header.

This demo uses the modules Redis2NginxModule, LuaNginxModule, LuaRedisParserLibrary, and SetMiscNginxModule bundled by OpenResty.

Here's the complete code listing for our {{{nginx.conf}}}:

{{{
worker_processes  2;
error_log logs/error.log info;

events {
    worker_connections 1024;
}

http {
    upstream apache.org {
        server apache.org;
    }

    upstream nginx.org {
        server nginx.org;
    }

    server {
        listen 8080;

        location = /redis {
            internal;
            set_unescape_uri $key $arg_key;
            redis2_query get $key;
            redis2_pass 127.0.0.1:6379;
        }

        location / {
            set $target '';
            access_by_lua '
                local key = ngx.var.http_user_agent
                local res = ngx.location.capture(
                    "/redis", { args = { key = key } }
                )

                print("key: ", key)

                if res.status ~= 200 then
                    ngx.log(ngx.ERR, "redis server returned bad status: ",
                        res.status)
                    ngx.exit(res.status)
                end

                if not res.body then
                    ngx.log(ngx.ERR, "redis returned empty body")
                    ngx.exit(500)
                end

                local parser = require "redis.parser"
                local server, typ = parser.parse_reply(res.body)
                if typ ~= parser.BULK_REPLY or not server then
                    ngx.log(ngx.ERR, "bad redis response: ", res.body)
                    ngx.exit(500)
                end

                print("server: ", server)

                ngx.var.target = server
            ';

            proxy_pass http://$target;
        }
    }
}
}}}

And then let's start the redis server on the localhost:6379:
{{{
$ ./redis-server  # default port is 6379
}}}

and feed some keys into this using the redis-cli utility:
{{{
   $ ./redis-cli
   redis> set foo apache.org
   OK
   redis> set bar nginx.org
   OK
}}}
And then let's test our nginx app!
{{{
   $ curl --user-agent foo localhost:8080
   <apache.org home page goes here>

   $ curl --user-agent bar localhost:8080
   <nginx.org home page goes here>
}}}
To further tune the performance, one could enable the connection pool for the redis connections, as documented in Redis2NginxModule's README.

Before you benchmarking your interface defined here, please ensure that you've raised the error log level to {{{warn}}} in your {{{nginx.conf}}} file like this:
{{{
error_log logs/error.log warn;
}}}
because flushing error log is a very expensive operation and can hurt performance a lot.
<<toolbar permalink>>

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.

Documentation: http://wiki.nginx.org/HttpEchoModule

Project page: https://github.com/agentzh/echo-nginx-module
<<toolbar permalink>>

This module provides encryption and decryption support for [[Nginx]] variables based on ~AES-256 with Mac.

This module is usually used with [[SetMiscNginxModule]] and the standard [[rewrite module|http://wiki.nginx.org/NginxHttpRewriteModule]]'s directives.

This module can be used to implement simple user login and access control of web applications.

Project page: http://github.com/agentzh/encrypted-session-nginx-module
<<toolbar permalink>>

This is an [[Nginx]] module that reads HTTP POST and PUT request body encoded in "application/x-www-form-urlencoded", and parse the arguments in request body into [[Nginx]] variables.

Project page: https://github.com/calio/form-input-nginx-module
<<toolbar permalink>>

First of all, please go to the [[Download]] page to get the source code tarball of OpenResty, and see the [[Installation]] page for how to build and install it into your system.

!~HelloWorld
!!Prepare directory layout
We first create a separate directory for our experiments. You can use an arbitrary directory. Here for simplicity, we just use {{{~/work}}}:
{{{
mkdir ~/work
cd ~/work
mkdir logs/ conf/
}}}
Note that we've also created the {{{logs/}}} directory for logging files and {{{conf/}}} for our config files.
!!Prepare the nginx.conf config file
Create a simple plain text file named {{{conf/nginx.conf}}} with the following contents in it:
{{{
worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 8080;
        location / {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>hello, world</p>")
            ';
        }
    }
}
}}}
If you're familiar with Nginx configuration, it should look very familiar to you. OpenResty is just an enhanced version of Nginx by means of addon modules anyway. You can take advantage of all the exisitng goodies in the Nginx world.
!!Start the Nginx server
Assuming you have installed OpenResty into {{{/usr/local/openresty}}} (this is the default), we make our {{{nginx}}} executable of our OpenResty installation available in our {{{PATH}}} environment:
{{{
PATH=/usr/local/openresty/nginx/sbin:$PATH
export PATH
}}}
Then we start the nginx server with our config file this way:
{{{
nginx -p `pwd`/ -c conf/nginx.conf
}}}
Error messages will go to the stderr device or the default error log files {{{logs/error.log}}} in the current working directory.
!!Access our ~HelloWorld web service
We can use curl to access our new web service that says ~HelloWorld:
{{{
curl http://localhost:8080/
}}}
If everything is okay, we should get the output
{{{
<p>hello, world</p>
}}}
You can surely point your favorite web browser to the location {{{http://localhost:8080/}}}.
!!Test performance
See [[Benchmark]] for details.

!Where to go from here

View the documentation of each component at the [[Components]] page and find Nginx related stuffs on the [[Nginx Wiki site|http://wiki.nginx.org/]].
~GitHub is social coding network based on git, a very popular version control system. See its homepage: http://github.com.
This module allows you to add, set, or clear any response or request headers that you specify.

This is an enhanced version of the standard headers module because it provides more utilities like resetting or clearing "builtin headers" like ~Content-Type, ~Content-Length, and Server. 

Documentation: http://wiki.nginx.org/HttpHeadersMoreModule
Project page: http://github.com/agentzh/headers-more-nginx-module
<<toolbar permalink>>

This is an [[Nginx]] module that uses libiconv to convert characters of different encoding. It brings the {{{set_iconv}}} and {{{iconv_filter}}} commands to [[Nginx]].

It can either process Nginx variables or process response bodies as an output filter.

This module is not enabled by default, and you need to specify the {{{--with-http_iconv_module}}} option while [[building OpenResty|Installation]]. This Nginx module requires libiconv to be installed into your system.

Use cases: http://forum.nginx.org/read.php?2,206658,207119

Project page: https://github.com/calio/iconv-nginx-module
<<toolbar permalink>>
If you haven't downloaded the OpenResty source code tarball, please go to the [[Download]] page first.

Basically, building and installing OpenResty is as simple as
{{{
tar xzvf ngx_openresty-VERSION.tar.gz
cd ngx_openresty-VERSION/
./configure --with-luajit
make
make install
}}}
where {{{VERSION}}} should be replaced by a concrete version number of OpenResty, like {{{0.8.54.6}}}.
If you have problems while building or want finer control over the building process, please read on.
!Prerequisites
You should have {{{perl 5.6.1+}}}, {{{libreadline}}}, {{{libpcre}}}, {{{libssl}}} installed into your system. For Linux, you should also ensure that {{{ldconfig}}} is in your PATH environment.
!!Debian and Ubuntu users
You're recommended to install the following packages using apt-get:
{{{
apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl
}}}
!!Fedora and ~RedHat users
You're recommended to install the following packages using yum:
{{{
yum install readline-devel pcre-devel openssl-devel
}}}
!!Mac OS X (Darwin) users
You're recommended to install prerequisites PCRE using some package management tool, like [[Homebrew|http://mxcl.github.com/homebrew/]]:
{{{
brew install pcre
}}}
Alternatively you can install PCRE from source all by yourself :)

After installing PCRE, you may need to specify the paths for PCRE's headers and libraries to your C compiler and linker:
{{{
$ ./configure \
             --with-cc-opt="-I/usr/local/Cellar/pcre/8.21/include" \
             --with-ld-opt="-L/usr/local/Cellar/pcre/8.21/lib" \
             ...
}}}
See also [[Issue #3: |https://github.com/agentzh/ngx_openresty/issues/3]]

!!~FreeBSD users
You need to install the following ports:
* devel/gmake
* security/openssl
* devel/pcre
!!Solaris 11 users
You need to install the following packages from the official repository:
* gcc-3
* ~SUNWlibm
Usually it's just as simple as
{{{
pfexec pkg install gcc-3 SUNWlibm
}}}
!Build ~OpenResty
!!Download
download the latest ngx_openresty tarball can be fetched from the [[Download]] page and unpack it like this:
{{{
tar xzvf ngx_openresty-VERSION.tar.gz
}}}
where {{{VERSION}}} should be replaced by real version numbers like {{{0.8.54.6}}}.
!!./configure
Then enter the {{{ngx_openresty-VERSION/}}} directory, and type the following command to configure:
{{{
./configure --with-luajit
}}}
By default, {{{--prefix=/usr/local/openresty}}} is assumed. The {{{--with-luajit}}} option is strongly recommended because LuaJIT 2.0 can give a nice performance boost in terms of both CPU time and memory footprint and its VM is also fully resume-able, unlike the default standard Lua 5.1 interpreter. Enabling LuaJIT 2.0 should work on Linux, Mac OS X, FreeBSD, Solaris, and others. You should only disable LuaJIT 2.0 when your platform does not support LuaJIT.

You can specify various options, as in
{{{
./configure --prefix=/opt/openresty \
            --with-luajit \
            --without-http_redis2_module \
            --with-http_iconv_module \
            --with-http_postgres_module \
            -j2
}}}
All of the Nginx configure file options can be used here, including {{{--add-module=PATH}}}. Try {{{./configure --help}}} to see more options available.

Errors in running the ./configure script can be found in the file {{{build/nginx-VERSION/objs/autoconf.err}}} where {{{VERSION}}} should be replaced by a concrete version number of OpenResty, like {{{0.8.54.6}}}.
!!!Notes for Solaris users
For Solaris, it's common to install libraries like ~OpenSSL to {{{/lib}}}, so when it complaints about missing ~OpenSSL and you have indeed already installed it, specify the {{{--with-ld-opt='-L/lib'}}} option.
!!make
Now you can compile everything up using the command
{{{
make
}}}
If your machine has multiple cores and your {{{make}}} supports the jobserver feature, you can compile things in parallel like this:
{{{
make -j2
}}}
assuming you have 2 CPU cores.
!!make install
If all the previous steps go without problems, you can install OpenResty into your system by typing the command
{{{
make install
}}}
On Linux, it often requires {{{sudo}}} to gain root access.
<<toolbar permalink>>

Lua CJSON is a Lua C module that provides fast JSON parsing and encoding support for Lua.

Project homepage: http://www.kyne.com.au/~mark/software/lua-cjson.php

This library is enabled by default. You can specify the {{{--without-lua_cjson}}} option to OpenResty's {{{./configure}}} script to explicitly disable it.
<<toolbar permalink>>

LuaJIT is a ~Just-In-Time Compiler for the Lua programming language. 

Homepage: http://luajit.org/luajit.html

LuaJIT is not enabled by default. Please specify the {{{--with-luajit}}} option while configuring OpenResty while building it. See [[Installation]] for details.
<<toolbar permalink>>

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.

Unlike Apache's mod_lua and Lighttpd'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, upstream http web services, and etc etc etc (see ngx_drizzle, ngx_postgres, ngx_memc, and ngx_proxy modules for details).

The Lua interpreter instance is shared across all the requests in a single nginx worker process.

Request contexts are isolated from each other by means of Lua (lightweight) threads (aka Lua coroutines). And Lua modules loaded are persistent on the nginx worker process level. So the memory footprint is quite small even when your nginx worker process is handling 10K requests at the same time.

Documentation: http://wiki.nginx.org/HttpLuaModule

Project page: http://github.com/chaoslawful/lua-nginx-module
<<toolbar permalink>>

This Lua library can be used to parse the ~Resty-DBD-Stream formatted data generated by DrizzleNginxModule and PostgresNginxModule into Lua data structures. In the past, we have to use JSON as the intermediate data format which is quite inefficient in terms of both memory and CPU time.

To maximize speed and minimize memory footprint, this library is implemented in pure C.

This library is enabled by default; use the {{{--without-lua_rds_parser}}} option to disable it when running {{{./configure}}} to build OpenResty.

Project homepage: https://github.com/agentzh/lua-rds-parser
<<toolbar permalink>>

The lua-redis-parser library implements a thin and fast redis raw response parser that constructs corresponding lua data strucutres, as well as a function that constructs redis raw requests.

Documentation page: http://wiki.nginx.org/LuaRedisParser

Project homepage: https://github.com/agentzh/lua-redis-parser
<<toolbar permalink>>

Lua [[Memcached|http://memcached.org/]] client driver for LuaNginxModule based on the cosocket API.

Project homepage: https://github.com/agentzh/lua-resty-memcached

This library is enabled by default. You can specify the {{{--without-lua_resty_memcached}}} option to OpenResty's {{{./configure}}} script to explicitly disable it.
<<toolbar permalink>>

Lua [[MySQL|http://en.wikipedia.org/wiki/MySQL]] client driver for LuaNginxModule based on the cosocket API.

Project homepage: https://github.com/agentzh/lua-resty-mysql

This library is enabled by default. You can specify the {{{--without-lua_resty_mysql}}} option to OpenResty's {{{./configure}}} script to explicitly disable it.
<<toolbar permalink>>

Lua [[Redis|http://redis.io/]] client driver for LuaNginxModule based on the cosocket API.

Project homepage: https://github.com/agentzh/lua-resty-redis

This library is enabled by default. You can specify the {{{--without-lua_resty_redis}}} option to OpenResty's {{{./configure}}} script to explicitly disable it.
<<toolbar permalink>>

A Lua library that provides string utilities and common hash functions for LuaNginxModule.

Project homepage: https://github.com/agentzh/lua-resty-string

This library is enabled by default. You can specify the {{{--without-lua_resty_string}}} option to OpenResty's {{{./configure}}} script to explicitly disable it.
<<toolbar permalink>>

Streaming reader and parser for HTTP file uploading based on LuaNginxModule's cosocket API.

Project homepage: https://github.com/agentzh/lua-resty-upload

This library is enabled by default. You can specify the {{{--without-lua_resty_upload}}} option to OpenResty's {{{./configure}}} script to explicitly disable it.
[[Overview|OpenResty]]
[[Components]]
[[Getting started|GettingStarted]]
[[Samples]]
[[Benchmark]]
[[Presentations]]
[[eBooks]]
[[Resources]]
[[Download]]
[[Installation]]
[[Quality Assurance|QualityAssurance]]
[[Contact us|ContactUs]]
[[About]]
[[Donate Online|DonateOnline]]
[[中文维基|http://openresty.org/cn]]

[img[feed-icon-14x14.png]] [[RSS feed|RSSFeed]]

<html>
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="agentzh@gmail.com">
<input type="hidden" name="item_name" value="OpenResty Donation (in USD)">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="amount" value="">
<input type="image" src="donate_button_paypal_01.gif" border="0" name="submit" alt="Donate with PayPal">
</form>
</html>
<html>
<a href="http://me.alipay.com/agentzh" target="_blank"><img src="donate-with-alipay.png"></a>
</html>
<p/><p/>
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-24724965-1']);
  _gaq.push(['_trackPageview']);

  var ga_f = function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  };
  setTimeout(ga_f, 200);

</script>

<<toolbar permalink>>

This module extends the standard memcached module  to support almost the whole memcached ascii protocol.

It allows you to define a custom REST interface to your memcached servers or access memcached in a very efficient way from within the nginx server by means of subrequests or independent fake requests. 

Documentation: http://wiki.nginx.org/HttpMemcModule
Project page: http://github.com/agentzh/memc-nginx-module
<<toolbar permalink>>

Nginx is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/~POP3 proxy server. See its homepage: http://nginx.org.
<<toolbar permalink>>

The NDK is an Nginx module that is designed to extend the core functionality of the    excellent Nginx webserver in a way that can be used as a basis of other Nginx modules.

Project page: https://github.com/simpl/ngx_devel_kit
<<toolbar permalink>>

~OpenResty (aka. ngx_openresty) is a full-fledged web application server by bundling the standard [[Nginx]] core, lots of [[3rd-party Nginx modules|http://wiki.nginx.org/3rdPartyModules]], as well as most of their external dependencies.

By taking advantage 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.

~OpenResty 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.

See [[Components]] for the complete list of software bundled in ~OpenResty.

See [[GettingStarted]] on how to quickly setup an ~OpenResty server that can say hello world over HTTP. Or you can go to the [[Download]] section to grab ~OpenResty's source code tarball directly.
<<toolbar permalink>>

ngx_postgres is an upstream module that allows [[Nginx]] to communicate directly with ~PostgreSQL database.

Response is generated in RDS format, so it's compatible with RdsJsonNginxModule and DrizzleNginxModule modules.

This module is not enabled by default, and you need to specify the {{{--with-http_postgres_module}}} option while [[building OpenResty|Installation]]. This Nginx module requires libpq to be installed into your system.

Project page: http://github.com/FRiCKLE/ngx_postgres
<<toolbar permalink>>

Here goes a list of slides that I used in my talks regarding OpenResty.

These slides are powered by the [[slides.htm|https://github.com/kindy61/slides.htm]] slide-making engine based on AJAX.

''//Note: Please use the arrow keys or pageup/pagedown keys on your keyboard to switch pages.//''
! Year 2012
!! ngx_openresty: an Nginx ecosystem glued by Lua
This talk was given at [[Tech-Club Technical Salon|http://event.weibo.com/351359]] held in the Xiamen city.

View in your web browser: http://agentzh.org/misc/slides/ngx-openresty-ecosystem/

Download the slides as PDF: http://agentzh.org/misc/slides/ngx-openresty-ecosystem.pdf

!! Scripting libdrizzle with Lua inside Nginx
This presentation was given at [[Percona Live MySQL Conference 2012|http://www.percona.com/live/mysql-conference-2012/sessions/scripting-mysql-lua-and-libdrizzle-inside-nginx]] held in Santa Clara, CA, USA.

View in your web browser: http://agentzh.org/misc/slides/libdrizzle-lua-nginx/#2

Download the slides as PDF: http://agentzh.org/misc/slides/libdrizzle-lua-nginx.pdf

! Year 2011
!! Applications of ngx_openresty and perl in lz.taobao.com

This talk was given at [[Beijing Perl Workshop 2011|http://conference.perlchina.org/bjpw2011/talks]].

Watch the video online: http://v.ku6.com/show/TY8Vre59guTE_C8o.html

View in your web browser: http://agentzh.org/misc/slides/perl-lz-apps/

Download the slides as PDF: http://agentzh.org/misc/slides/perl-lz-apps.pdf

! Year 2010
!! Introduction to nginx.conf scripting
This talk was given at the [[Beijing Perl Workshop|http://conference.perlchina.org]] 2010 April meeting and the [[Beijing OpenParty 2010 June event|http://www.beijing-open-party.org/event/2]].

View in your web browser: http://agentzh.org/misc/slides/nginx-conf-scripting/

Download the slides as PDF: http://agentzh.org/misc/slides/nginx-conf-scripting.pdf

Please note that ngx_eval module is no longer recommended because we're in more favor of ngx_lua nowadays.

!! Recent developments in nginx.conf scripting
This talk was given at the [[Beijing OpenParty 2010 June event|http://www.beijing-open-party.org/event/2]].

View in your web browser: http://agentzh.org/misc/slides/recent-dev-nginx-conf/

Download the slides as PDF: http://agentzh.org/misc/slides/recent-dev-nginx-conf.pdf

!! The state of the art of nginx.conf scripting
This talk was given at the [[ECUG 2010 event|http://agentzh.org/misc/slides/nginx-state-of-the-art/]].

Watch the (Chinese-speech) video online: http://v.ku6.com/show/D00rqtnRwKzJdIsB.html

View the (English) slides in your web browser: http://agentzh.org/misc/slides/nginx-state-of-the-art/

Download the slides as PDF: http://agentzh.org/misc/slides/nginx-state-of-the-art.pdf
<<toolbar permalink>>

We run extensive regression testing for all our components (as well as other 3rd-party Nginx modules) on an Amazon ~EC2 cluster. The latest test report can always be viewed here:

http://qa.openresty.org/
<<toolbar permalink>>

This site's RSS  feed is available at http://openresty.org/index.xml [img[feed-icon-28x28.png]].
<<toolbar permalink>>

This Nginx module implements an efficient output filter that converts ~Resty-DBD-Streams (RDS) generated by DrizzleNginxModule and PostgresNginxModule to ~Comma-Separated Values (CSV) format in a streaming fashion.

By default, the CSV format is in compliance with RFC 4180:

        http://tools.ietf.org/html/rfc4180

This module is enabled by default in OpenResty. You can specify the {{{--without-http_rds_csv_module}}} option to disable this module while running {{{./configure}}} to build OpenResty.

Project homepage: https://github.com/agentzh/rds-csv-nginx-module
<<toolbar permalink>>

This is an output filter module that formats Resty DBD Streams (RDS) generated by ngx_drizzle and others to JSON streams.

Project page: http://github.com/agentzh/rds-json-nginx-module
<<toolbar permalink>>

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.

This module returns the raw TCP response from the Redis server.

This module is enabled by default and can be disabled by passing the {{{--without-http_redis2_module}}} option to the {{{./configure}}} script for OpenResty.

Documentation wiki page: http://wiki.nginx.org/HttpRedis2Module

Project page: https://github.com/agentzh/redis2-nginx-module
<<toolbar permalink>>

This is an [[Nginx]] upstream module that makes nginx talk to a redis 2.x server in a non-blocking way. It has a similar interface with the standard [[ngx_memcached module|http://wiki.nginx.org/HttpMemcachedModule]], but only Redis {{{GET}}} and {{{SELECT}}} commands are supported.

This module returns the decoded result from the Redis server.

This module is written by Sergey A. Osokin.

This module is enabled by default and can be disabled by passing the {{{--without-http_redis_module}}} option to the {{{./configure}}} script for OpenResty.

Documentation wiki page: http://wiki.nginx.org/HttpRedisModule

<<toolbar permalink>>
! English Articles
* My beautiful dark twisted reverse-proxy LRU cache
: http://mikeferrier.com/2011/05/14/my-beautiful-dark-twisted-reverse-proxy-LRU-cache/
* Day 41 - Setting up ngx_openresty (WAS: testing Test::Nginx) 
: http://www.nginx-discovery.com/2011/03/day-41-setting-up-ngxopenresty-was.html
! Chinese Articles
* An introduction to OpenResty
: http://wdicc.com/intro-openresty/
* Nginx 3rd-Party Module Experiments Journal
: http://chenxiaoyu.org/2011/10/30/nginx-modules.html
* Recommending OpenResty - An Nginx Version with Fully Capable Addons
: http://wendal.net/338.html
* Constructing Efficient and Transparent Caching Mechanism with MemcNginxModule and SrcacheNginxModule
: http://www.codinglabs.org/html/nginx-memc-and-srcache.html
* The Nginx Session Module
: http://chenxiaoyu.org/2011/11/09/nginx-session.html
* ~Nginx-Lua HTTP 401 Basic Authentication
: http://chenxiaoyu.org/2012/02/08/nginx-lua-401-auth.html
* Use ngx_openresty to create an ~AJAX-style pager for data listing
: http://blog.163.com/lhmwzy@126/blog/static/64215736201212384413704/
* Nginx Variable Tutorials
: http://blog.sina.com.cn/openresty
<<toolbar permalink>>

This sample demonstrates how to route incoming requests to different ~MySQL queries based on different combinations of URI query arguments, preserving streaming output capabilities provided by DrizzleNginxModule and RdsJsonNginxModule.

This demo uses the modules DrizzleNginxModule, LuaNginxModule, RdsJsonNginxModule, and SetMiscNginxModule bundled by OpenResty.

Here's the complete code listing for our {{{nginx.conf}}}:

{{{
worker_processes  2;
error_log logs/error.log warn;

events {
    worker_connections 1024;
}

http {
    upstream backend {
        drizzle_server 127.0.0.1:3306 protocol=mysql
                       dbname=ngx_test user=ngx_test password=ngx_test;
        drizzle_keepalive max=10 overflow=ignore mode=single;
    }

    server {
        listen 8080;

        location @cats-by-name {
            set_unescape_uri $name $arg_name;
            set_quote_sql_str $name;
            drizzle_query 'select * from cats where name=$name';
            drizzle_pass backend;
            rds_json on;
        }

        location @cats-by-id {
            set_quote_sql_str $id $arg_id;
            drizzle_query 'select * from cats where id=$id';
            drizzle_pass backend;
            rds_json on;
        }

        location = /cats {
            access_by_lua '
                if ngx.var.arg_name then
                    return ngx.exec("@cats-by-name")
                end

                if ngx.var.arg_id then
                    return ngx.exec("@cats-by-id")
                end
            ';

            rds_json_ret 400 "expecting \"name\" or \"id\" query arguments";
        }
    }
}
}}}

And then we start our Nginx server with this configure file and test with our {{{/cats}}} service like this:
{{{
$ curl 'localhost:8080/cats'
{"errcode":400,"errstr":"expecting \"name\" or \"id\" query arguments"}

$ curl 'localhost:8080/cats?name=bob'
[{"id":3,"name":"bob"}]

$ curl 'localhost:8080/cats?id=2'
[{"id":2,"name":null}]
}}}
The actual output rows may vary depending on the actual contents in your {{{cats}}} table anyway.
<<toolbar permalink>>
* [[Routing requests to different MySQL queries based on URI arguments|RoutingMySQLQueriesBasedOnURIArgs]]
* [[Dynamic Request Routing Based on Redis|DynamicRoutingBasedOnRedis]]
* [[Using LuaRocks|UsingLuaRocks]]
<<toolbar permalink>>

This module adds various {{{set_xxx}}} directives added to [[Nginx]]'s [[rewrite module|http://wiki.nginx.org/NginxHttpRewriteModule]] (~MD5/~SHA1, SQL/JSON quoting, and many more).

Every directive provided by this module can be mixed freely with other nginx rewrite module's
  directives, like {{{if}}} and {{{set}}}.

Documentation: http://wiki.nginx.org/HttpSetMiscModule

Project page: http://github.com/agentzh/set-misc-nginx-module
a powerful web app server by extending nginx 
OpenResty
<<toolbar permalink>>

This module provides a transparent caching layer for arbitrary nginx locations (like those use an upstream or even serve static disk files).

Usually, the MemcNginxModule 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 this module.

Documentation page: http://wiki.nginx.org/HttpSRCacheModule

Project page: http://github.com/agentzh/srcache-nginx-module
<<toolbar permalink>>

The standard Lua interpreter is enabled by default. If [[LuaJIT]] is enabled, this interpreter will be disabled automatically.

See Lua's homepage: http://www.lua.org/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:2.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:2.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
<<toolbar permalink>>

This is a keepalive balancer module for nginx that implements cache for backend connections.

Documentation: http://wiki.nginx.org/HttpUpstreamKeepaliveModule

Project page: http://mdounin.ru/hg/ngx_http_upstream_keepalive/
<<toolbar permalink>>

This sample demonstrates usage of [[LuaRocks|http://www.luarocks.org/]] with OpenResty. It's been tested on Linux and Mac OS X, with the standard Lua interpreter or with LuaJIT.

~LuaRocks is a deployment and management system for Lua modules. ~LuaRocks allows one to install Lua modules as self-contained packages called "rocks", which also contain version dependency  information.

We assume that you have installed OpenResty into the default location, i.e., {{{/usr/local/openresty}}}. You can adjust the paths in this sample according to the actual installation prefix of your OpenResty installation. If you haven't installed ~OpenResty yet, check out the [[Download]] and [[Installation]] pages.

! Install ~LuaRocks
First of all, let's install ~LuaRocks:

Download the latest ~LuaRocks tarball from [[http://www.luarocks.org/en/Download]]. As of this writing, the latest version is {{{2.0.4.1}}}, and we'll use this version throughout this sample.
{{{
wget http://luarocks.org/releases/luarocks-2.0.4.1.tar.gz
tar -xzvf luarocks-2.0.4.1.tar.gz
cd luarocks-2.0.4.1/
./configure
make
sudo make install
}}}
! Install the Lua ~MD5 library with ~LuaRocks
In this sample, we'll use the Lua ~MD5 library to serve as an example, so let's install it with ~LuaRocks:
{{{
sudo luarocks install md5
}}}
! Configuring our ~OpenResty application
Let's change the current directory to {{{/usr/local/openresty/nginx/}}}:
{{{
cd /usr/local/openresty/nginx/
}}}
Next, edit the {{{conf/nginx.conf}}} file to the following contents with your favorite text editor (like vim or emacs):
{{{
worker_processes  1;   # we could enlarge this setting on a multi-core machine
error_log  logs/error.log warn;

events {
    worker_connections  1024;
}

http {
    lua_package_path 'conf/?.lua;;';

    server {
        listen       80;
        server_name  localhost;

        location = /luarocks {
            content_by_lua '
                local foo = require("foo")
                foo.say("hello, luarocks!")
            ';
        }
    }
}
}}}
Finally, create the following two Lua module files {{{conf/foo.lua}}}
{{{
-- conf/foo.lua

module("foo", package.seeall)

local bar = require "bar"

ngx.say("bar loaded")

function say (var)
    bar.say(var)
end
}}}
and {{{conf/bar.lua}}}
{{{
-- conf/bar.lua

module("bar", package.seeall)

local rocks = require "luarocks.loader"
local md5 = require "md5"

ngx.say("rocks and md5 loaded")

function say (a)
    ngx.say(md5.sumhexa(a))
end
}}}
! Start the Nginx server
Now we start the Nginx server with our app:
{{{
ulimit -n1024   # increase the maximal fd count limit per process
./sbin/nginx
}}}
If you have already started the Nginx server, then stop it before starting it:
{{{
./sbin/nginx -s stop
}}}
! Test our app
Now we can test our app via the {{{curl}}} utility or any HTTP compliant clients like a web browser:
{{{
curl http://localhost/luarocks
}}}
we could get the following outputs at the first run:
{{{
rocks and md5 loaded
bar loaded
85e73df5c41378f830c031b81e4453d2
}}}
then at the second run:
{{{
85e73df5c41378f830c031b81e4453d2
}}}
The output changed because LuaNginxModule by default caches already loaded Lua modules and those outputing code run at Lua module loading time will no longer be run.

Now let's do some benchmark:
{{{
ab -c10 -n50000 http://127.0.0.1/luarocks
}}}
On my Thinkpad T400 laptop (~Core2Duo T9600 CPU), it yields
{{{
Server Software:        ngx_openresty/1.0.4.2rc10
Server Hostname:        localhost
Server Port:            80

Document Path:          /luarocks
Document Length:        33 bytes

Concurrency Level:      10
Time taken for tests:   3.052 seconds
Complete requests:      50000
Failed requests:        0
Write errors:           0
Total transferred:      9400188 bytes
HTML transferred:       1650033 bytes
Requests per second:    16380.48 [#/sec] (mean)
Time per request:       0.610 [ms] (mean)
Time per request:       0.061 [ms] (mean, across all concurrent requests)
Transfer rate:          3007.41 [Kbytes/sec] received
}}}
Note that the throughput is achieved by a single nginx worker process. While doing such benchmark on your own, just be careful about error log level settings in your nginx.conf and not to run out of dynamic port range on your local machine, or it'll be significantly slow after a short of period of time.
! Known issues
Pior to OpenResty 1.0.4.2rc10, it's known that turning {{{lua_code_cache}}} on will cause ~LuaRocks atop LuaNginxModule to throw out the following exception in {{{error.log}}}:
{{{
lua handler aborted: runtime error: stack overflow
}}}
If you're using any version of OpenResty before 1.0.4.2rc10, please consider upgrading.
<<toolbar permalink>>

This module adds cross-site AJAX support to nginx. Currently only cross-site GET is supported.

The cross-site GET is currently implemented as JSONP (or "JSON with padding"). See http://en.wikipedia.org/wiki/JSON#JSONP for more details.

Project page: http://github.com/agentzh/xss-nginx-module
agentzh, 章亦春, one of the main authors of this ~OpenResty bundle.

Homepage: http://agentzh.org
<<toolbar permalink>>

! eBook "agentzh's Nginx Tutorials" (version 2012.04.18)
* English Edition
** [[HTML Single-Page Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-enuk.html]] (Web browser users)
** [[MOBI Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-enuk.mobi]] (Kindle users)
** [[EPUB Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-enuk.epub]] (Sony, Apple and other users)
** [[PDF Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-enuk.pdf]] (PC users)
* Chinese Edition
** [[HTML Single-Page Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.html]] (Web browser users)
** [[MOBI Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.mobi]] (Kindle users)
** [[EPUB Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.epub]] (Sony, Apple and other users)
** [[PDF Format|http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.pdf]] (PC users)
* Git Repository
** https://github.com/agentzh/nginx-tutorials
<<toolbar permalink>>

This is the the client and protocol library for the Drizzle project. This library is now distributed with the Drizzle server release.

Project page: https://launchpad.net/drizzle