nginx-0.1.1-RELEASE import

    *) Feature: the gzip_types directive.

    *) Feature: the tcp_nodelay directive.

    *) Feature: the send_lowat directive is working not only on OSes that
       support kqueue NOTE_LOWAT, but also on OSes that support SO_SNDLOWAT.

    *) Feature: the setproctitle() emulation for Linux and Solaris.

    *) Bugfix: the "Location" header rewrite bug fixed while the proxying.

    *) Bugfix: the ngx_http_chunked_module module may get caught in an
       endless loop.

    *) Bugfix: the /dev/poll module bugs fixed.

    *) Bugfix: the responses were corrupted when the temporary files were
       used while the proxying.

    *) Bugfix: the unescaped requests were passed to the backend.

    *) Bugfix: while the build configuration on Linux 2.4 the
       --with-poll_module parameter was required.
diff --git a/auto/init b/auto/init
index ebca444..bc4d8bb 100644
--- a/auto/init
+++ b/auto/init
@@ -36,3 +36,29 @@
     ngx_n=
     ngx_c='\c'
 fi
+
+
+
+if test ! -f Makefile; then
+
+    cat << END > Makefile
+
+build:
+	\$(MAKE) -f $OBJS/Makefile
+
+install:
+	\$(MAKE) -f $OBJS/Makefile install
+
+clean:
+	rm -rf Makefile $OBJS
+
+upgrade:
+	$SBIN_PATH -t
+	kill -USR2 \`cat $PID_PATH\`
+	sleep 1
+	test -f $PID_PATH.newbin
+	kill -WINCH \`cat $PID_PATH\`
+
+END
+
+fi
diff --git a/auto/install b/auto/install
index b838b9b..57e3019 100644
--- a/auto/install
+++ b/auto/install
@@ -38,28 +38,3 @@
 END
 
 fi
-
-
-if test ! -f Makefile; then
-
-    cat << END > Makefile
-
-build:
-	\$(MAKE) -f $OBJS/Makefile
-
-install:
-	\$(MAKE) -f $OBJS/Makefile install
-
-clean:
-	rm -rf Makefile $OBJS
-
-upgrade:
-	$SBIN_PATH -t
-	kill -USR2 \`cat $PID_PATH\`
-	sleep 1
-	test -f $PID_PATH.newbin
-	kill -WINCH \`cat $PID_PATH\`
-
-END
-
-fi
diff --git a/auto/sources b/auto/sources
index 40fbad2..6e21a41 100644
--- a/auto/sources
+++ b/auto/sources
@@ -138,6 +138,7 @@
             src/os/unix/ngx_shared.c \
             src/os/unix/ngx_process.c \
             src/os/unix/ngx_daemon.c \
+            src/os/unix/ngx_setproctitle.c \
             src/os/unix/ngx_posix_init.c \
             src/os/unix/ngx_process_cycle.c"
 
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index a277595..a43cd46 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -1,979 +1,123 @@
-<?xml version="1.0" encoding="KOI8-R" ?>
-<!DOCTYPE change_log SYSTEM "../dtd/changes.dtd" >
+<?xml version="1.0" encoding="koi8-r" ?>
+<!DOCTYPE change_log SYSTEM "../../dtd/changes.dtd" >
 
 
-<change_log title="mod_accel">
+<change_log link="/nginx/changes.html" path="/nginx/" root=".."
+            title="nginx">
 
 
-<changes ver="1.0.29" date="15.06.2003">
+<changes ver="0.1.1" date="11.10.2004">
 
-<change type="bugfix">
+<change type="feature">
 <para lang="ru">
-mod_accel ÎÅ ÏÐÒÅÄÅÌÑÌ É ÎÅ ÐÁÔÞÉÌ EAPI, ÅÓÌÉ ÓÏÂÉÒÁÌÓÑ ×ÍÅÓÔÅ
-Ó mod_ssl-2.8.13-1.3.27+.
+ÄÉÒÅËÔÉ×Á gzip_types.
 </para>
 <para lang="en">
-mod_accel did not detect and patch broken EAPI when built with
-mod_ssl-2.8.13-1.3.27+.
+the gzip_types directive.
 </para>
 </change>
 
 <change type="feature">
 <para lang="ru">
-ÐÒÉ ÐÒÏËÓÉÒÏ×ÁÎÉÉ Ó ÐÏÍÏÝØÀ ÍÏÄÕÌÑ mod_rewrite mod_accel
-ÐÏÄÄÅÒÖÉ×ÁÅÔ ÐÅÒÅÐÉÓÙ×ÁÎÉÅ ÚÁÇÏÌÏ×ËÏ× "Location" É "Refresh" Ó ÐÏÍÏÝØÀ
-ÜÔÏÇÏ ÖÅ ÍÏÄÕÌÑ É
-ÄÌÑ ÜÔÏÇÏ <!-- ÜÔÉ Ä×Á ÌÉÛÎÉÈ ÓÌÏ×Á ÎÁÐÉÓÁÎÙ ÄÌÑ ÔÕÐÏÇÏ xsltproc -->
-ÕËÁÚÙ×ÁÅÔ ÉÍÑ ÂÜËÅÎÄÁ × ÐÅÒÅÍÅÎÎÏÊ
-ÓÒÅÄÙ "ACCEL_REWRITE".
+ÄÉÒÅËÔÉ×Á tcp_nodelay.
 </para>
 <para lang="en">
-when request is proxied with the help of mod_rewrite module mod_accel
-set the backend name in the "ACCEL_RWRITE" enviroment variable and
-supports the rewriting of "Location" and "Refresh" headers with the help of
-mod_rewrite module.
+the tcp_nodelay directive.
 </para>
 </change>
 
 <change type="feature">
 <para lang="ru">
-mod_accel ÐÅÒÅÐÉÓÙ×ÁÅÔ ÓÏÄÅÒÖÉÍÏÅ ÚÁÇÏÌÏ×ËÁ "Destination",
-ÅÓÌÉ ÉÍÑ ÈÏÓÔÁ × ÜÔÏÍ ÚÁÇÏÌÏ×ËÅ ÓÏ×ÐÁÄÁÅÔ Ó ÓÏÄÅÒÖÉÍÙÍ
-ÚÁÇÏÌÏ×ËÁ "Host", ÉÌÉ ÖÅ ÅÓÌÉ URI ÎÅ ÁÂÓÏÌÀÔÎÙÊ.
+ÄÉÒÅËÔÉ×Á send_lowat ÒÁÂÏÔÁÅÔ ÎÅ ÔÏÌØËÏ ÎÁ ÐÌÁÔÆÏÒÍÁÈ, ÐÏÄÄÅÒÖÉ×ÁÀÝÉÈ
+kqueue NOTE_LOWAT, ÎÏ É ÎÁ ×ÓÅÈ, ÐÏÄÄÅÒÖÉ×ÁÀÝÉÈ SO_SNDLOWAT.
 </para>
 <para lang="en">
-mod_accel now rewrites "Destination" header if the host name in this header
-is as in "Host" header or if the destination URI is not absolute.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-mod_accel ÚÁÃÉËÌÉ×ÁÌÓÑ × ÓÌÕÞÁÅ, ÅÓÌÉ ËÌÉÅÎÔ ÚÁÐÒÁÛÉ×ÁÌ byte range,
-Á ÂÜËÅÎÄ ÎÅ ÐÅÒÅÄÁ×ÁÌ ËÜÛÉÒÕÅÍÙÊ ÏÔ×ÅÔ ÐÏÌÎÏÓÔØÀ.
-</para>
-<para lang="en">
-mod_accel went into an endless loop if the client requested the byte range
-and the backend did not send the full cachable response.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.28" date="02.05.2003">
-
-<change type="bugfix">
-<para lang="ru">
-ÓÄÅÌÁÎÁ ÐÒÏ×ÅÒËÁ É ÐÁÔÞ ÄÌÑ EAPI ÉÚ mod_ssl-2.8.13-1.3.27+.
-</para>
-<para lang="en">
-broken EAPI from mod_ssl-2.8.13-1.3.27+ now is checked and patched.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelSetXURI ÎÅ ÒÁÂÏÔÁÌÁ.
-</para>
-<para lang="en">
-AccelSetXURI directive did not work.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.27" date="26.02.2003">
-
-<change type="bugfix">
-<para lang="ru">
-ÂÜËÅÎÄÙ, ÉÓÐÏÌØÚÕÀÝÉÅ named-based ×ÉÒÕÔÁÌØÎÙÅ ÈÏÓÔÙ, ÎÅ ÂÙÌÉ ÄÏÓÔÕÐÎÙ
-ÞÅÒÅÚ _the_same_host_.
-</para>
-<para lang="en">
-backends that use named-based virtual hosts can not be accessed via
-_the_same_host_.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.26" date="20.12.2002">
-
-<change type="change">
-<para lang="ru">
-AccelReverse ÒÁÂÏÔÁÅÔ É ÄÌÑ ÚÁÐÒÏÓÏ×, ÐÒÏËÓÉÒÏ×ÁÎÎÙÈ ÞÅÒÅÚ AccelPass.
-</para>
-<para lang="en">
-AccelReverse works for AccelPass'ed requests too.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-action remove × accel-cachemgr ÎÅ ÒÁÂÏÔÁÌ Ó URL, × ËÏÔÏÒÙÈ ÓÉÍ×ÏÌÙ
-ËÏÄÉÒÏ×ÁÌÉÓØ × ×ÉÄÅ %XX.
-</para>
-<para lang="en">
-accel-cachemgr's remove action did not work with URLs with characters
-endcoded as %XX.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.25" date="20.11.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÆÌÁÇÉ ÄÏÐÏÌÎÉÔÅÌØÎÙÈ ÍÏÄÕÌÅÊ R, Q É F ÚÁÌÉÐÁÌÉ × ËÜÛÅ ÄÏ ÔÅÈ ÐÏÒ, ÐÏËÁ
-ÆÁÊÌ ÎÅ ÕÄÁÌÑÌÓÑ ÉÚ ËÜÛÁ.
-</para>
-<para lang="en">
-additional modules R, Q and F flags were sticky until cache file was
-not removed from cache.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÎÅ ÒÁÂÏÔÁÌ action remove × accel-cachemgr.
-</para>
-<para lang="en">
-accel-cachemgr's remove action did not work.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÄÁ×ÎÏ ÎÅÍÅÎÑÅÍÙÅ ÄÏËÕÍÅÎÔÙ ÎÅ ËÜÛÉÒÏ×ÁÌÉÓØ, ÅÓÌÉ ÄÌÑ ËÜÛÉÒÏ×ÁÎÉÑ
-ÉÓÐÏÌØÚÏ×ÁÌÓÑ AccelLastModifiedFactor.
-</para>
-<para lang="en">
-long invariable documents were not cached if AccelLastModifiedFactor
-was used to choose cache time.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.24" date="21.10.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ × URL, ÓÏÚÄÁÎÎÙÍ ÍÏÄÕÌÅÍ mod_rewrite, ÎÁÈÏÄÉÌÉÓØ
-ÓÉÍ×ÏÌÙ <nobr>× ×ÉÄÅ %XX,</nobr>
-ÔÏ ÏÎÉ ÐÅÒÅÄÁ×ÁÌÉÓØ ÂÜËÅÎÄÕ × ÒÁÓËÒÙÔÏÍ ×ÉÄÅ.
-</para>
-<para lang="en">
-if mod_rewrite created URL contained characters encoded as %XX then
-they was passed to backend unescaped.
-</para>
-</change>
-
-<change type="change">
-<para lang="ru">
-ËÌÀÞ -DMOD_REWRITE_DISABLE_TO_PROXY_SUBREQ.
-</para>
-<para lang="en">
--DMOD_REWRITE_DISABLE_TO_PROXY_SUBREQ switch was added.
+the send_lowat directive is working not only on OSes that support
+kqueue NOTE_LOWAT, but also on OSes that support SO_SNDLOWAT.
 </para>
 </change>
 
 <change type="feature">
 <para lang="ru">
-ÐÅÒÅÍÅÎÎÁÑ ÓÒÅÄÙ ACCEL_NOCACHE.
+ÜÍÕÌÑÃÉÑ setproctitle() ÄÌÑ Linux É Solaris.
 </para>
 <para lang="en">
-ACCEL_NOCACHE enviroment variable was added.
+the setproctitle() emulation for Linux and Solaris.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÏÛÉÂËÁ ÐÒÉ ÐÅÒÅÐÉÓÙ×ÁÎÉÉ ÚÁÇÏÌÏ×ËÁ "Location" ÐÒÉ ÐÒÏËÓÉÒÏ×ÁÎÉÉ.
+</para>
+<para lang="en">
+the "Location" header rewrite bug fixed while the proxing.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÏÛÉÂËÁ × ÍÏÄÕÌÅ ngx_http_chunked_module, ÐÒÉ×ÏÄÉ×ÛÁÑ Ë ÚÁÃÉËÌÉ×ÁÎÉÀ.
+</para>
+<para lang="en">
+the ngx_http_chunked_module module bug fixed that caused an endless loop.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÏÛÉÂËÉ × ÍÏÄÕÌÅ /dev/poll.
+</para>
+<para lang="en">
+the /dev/poll module bugs fixed.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÐÒÉ ÐÒÏËÓÉÒÏ×ÁÎÉÉ É ÉÓÐÏÌØÚÏ×ÁÎÉÉ ×ÒÅÍÅÎÎÙÈ ÆÁÊÌÏ× ÏÔ×ÅÔÙ ÐÏÒÔÉÌÉÓØ.
+</para>
+<para lang="en">
+the responses were corrupted when the temporary files were used
+while the proxing.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÂÜËÅÎÄÕ ÐÅÒÅÄÁ×ÁÌÉÓØ ÚÁÐÒÏÓÙ Ó ÎÅÐÅÒÅËÏÄÉÒÏ×ÁÎÎÙÍÉ ÓÉÍ×ÏÌÁÍÉ.
+</para>
+<para lang="en">
+the unescaped requests were passed to the backend.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÎÁ Linux 2.4 ÐÒÉ ËÏÎÆÉÇÕÒÁÃÉÉ ÓÂÏÒËÉ ÎÕÖÎÏ ÂÙÌÏ ÏÂÑÚÁÔÅÌØÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ
+ÐÁÒÁÍÅÔÒ --with-poll_module.
+</para>
+<para lang="en">
+while the build configuration on Linux 2.4 the --with-poll_module parameter
+was required.
 </para>
 </change>
 
 </changes>
 
 
-<changes ver="1.0.23" date="30.08.2002">
-
-<change type="change">
-<para lang="ru">
-× ÄÉÒÅËÔÉ×Å FreezeStart.
-</para>
-<para lang="en">
-in FreezeStart directive.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelCacheSetCookie.
-</para>
-<para lang="en">
-AccelCacheSetCookie directive.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-AccelCacheRoot ÎÅ ÐÏÎÉÍÁÌ ÐÁÒÁÍÅÔÒÙ × ËÁ×ÙÞËÁÈ.
-</para>
-<para lang="en">
-AccelCacheRoot did not understand quoted parameters.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÍÏÄÕÌØ mod_freeze ÎÅ ÚÁÍÏÒÁÖÉ×ÁÌ ÓÈÅÍÙ, ÅÓÌÉ ÏÎÉ ÕËÁÚÁÎÙ ×
-ÏÄÉÎÁÒÎÙÈ ËÁ×ÙÞËÁÈ.
-</para>
-<para lang="en">
-mod_freeze did not freeze schemas if they was quoted in apostrophes.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÍÏÄÕÌØ mod_freeze ÎÅ ÚÁÍÏÒÁÖÉ×ÁÌ ÔÜÇ style, ÐÁÒÁÍÅÔÒ style É
-ÓÈÅÍÕ behavior:.
-</para>
-<para lang="en">
-mod_freeze did not freeze style tag, style parameter and behavior: schema.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ×ÉÄÁ &lt;&lt;script ÎÅ ÚÁÍÏÒÁÖÉ×ÁÌÁÓØ ÍÏÄÕÌÅÍ mod_freeze.
-</para>
-<para lang="en">
-&lt;&lt;script sequence was not frozen by mod_freeze.
-</para>
-</change>
-
-<change type="change">
-<para lang="ru">
-ÏÐÔÉÍÉÚÉÒÏ×ÁÎ ÁÌÇÏÒÉÔÍ ÐÏÉÓËÁ × ÍÏÄÕÌÅ mod_freeze.
-</para>
-<para lang="en">
-mod_freeze's search algorithm was optimized.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.22" date="12.08.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÆÌÁÇÉ ÄÏÐÏÌÎÉÔÅÌØÎÙÈ ÍÏÄÕÌÅÊ R, Q É F ÎÅ ×ÙÓÔÁ×ÌÑÌÉÓØ,
-ÅÓÌÉ ÚÁÐÒÏÓ ÂÙÌ ÎÅËÜÛÉÒÕÅÍÙÍ.
-</para>
-<para lang="en">
-additional modules R, Q and F flags were not set
-if request was not cachable.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelPassXAccel.
-</para>
-<para lang="en">
-AccelPassXAccel directive.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÍÏÄÕÌØ mod_freeze.
-</para>
-<para lang="en">
-mod_freeze module.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.21" date="04.07.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á "AccelPassServer off" × Apache-1.3.26 ×ÏÏÂÝÅ ÎÅ ×ÙÄÁ×ÁÌÁ
-ÚÁÇÏÌÏ×ÏË "Server".
-</para>
-<para lang="en">
-"AccelPassServer off" did not send any "Server" header in Apache-1.3.26.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÄÏËÕÍÅÎÔÁÃÉÑ ÐÏ mod_accel ËÏÐÉÒÕÅÔÓÑ × /manual/mod/mod_accel.html.
-</para>
-<para lang="en">
-mod_accel Russian documentation is copied in /manual/mod/mod_accel.html.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.20" date="24.06.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÐÁÒÁÍÅÔÒ MP × ÄÉÒÅËÔÉ×Å AccelPass ÒÁÂÏÔÁÌ ÎÅËÏÒÒÅËÔÎÏ, ÅÓÌÉ ÔÁËÖÅ
-ÂÙÌ ÚÁÄÁÌ ÐÁÒÁÍÅÔÒ PH ÉÌÉ ÉÓÐÏÌØÚÏ×ÁÌÏÓØ ÓÐÅÃÉÁÌØÎÏÅ ÉÍÑ _the_same_host_.
-</para>
-<para lang="en">
-AccelPass MP parameter was worked incorrectly if used with PH parameter
-or with special _the_same_host_ host name.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.19" date="29.05.2002">
-
-<change type="bugfix">
-<para lang="ru">
-×Ï ×ÒÅÍÑ ÐÌÁ×ÎÏÇÏ (graceful) ÒÅÓÔÁÒÔÁ ÍÏÇ ÐÒÏÉÚÏÊÔÉ segmentation fault
-× ÏÓÎÏ×ÎÏÍ ÐÒÏÃÅÓÓÅ, ÅÓÌÉ ×ÓÅ ÒÁÂÏÞÉÅ ÓÌÏÔÙ ÂÙÌÉ ÚÁÎÑÔÙ.
-</para>
-<para lang="en">
-segmentation fault can occur in main process while graceful restart
-when all child slots were busy.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.18" date="12.04.2002">
-
-<change type="feature">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Ù AccelRetry5XX É AccelSetXURI.
-</para>
-<para lang="en">
-AccelRetry5XX and AccelSetXURI directives were added.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÚÁÍÅÔËÉ accel_request_body É accel_rewrite_response.
-</para>
-<para lang="en">
-accel_request_body and accel_rewrite_response notes were added.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-mod_accel ÎÅ ÓÏÂÉÒÁÌÓÑ ËÏÍÐÉÌÑÔÏÒÏÍ aCC ÎÁ ÐÌÁÔÆÏÒÍÅ HP-UX.
-óÐÁÓÉÂÏ Marko Asplund, aspa<at/>kronodoc.fi.
-</para>
-<para lang="en">
-mod_accel is not built by aCC on HP-UX.<br/>
-Thanks to Marko Asplund, aspa<at/>kronodoc.fi.
-</para>
-</change>
-
-<change type="change">
-<para lang="ru">
-ËÏÓÍÅÔÉÞÅÓËÉÅ ÐÒÁ×ËÉ.
-</para>
-<para lang="en">
-code clean up.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.17" date="29.03.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ × URL ÐÅÒÅÄ ÁÒÇÕÍÅÎÔÁÍÉ ÎÁÈÏÄÉÌÉÓØ ÓÉÍ×ÏÌÙ <nobr>× ×ÉÄÅ %XX,</nobr>
-ÔÏ ÏÎÉ ÐÅÒÅÄÁ×ÁÌÉÓØ ÂÜËÅÎÄÕ × ÒÁÓËÒÙÔÏÍ ×ÉÄÅ.
-</para>
-<para lang="en">
-if URL before arguments contained characters encoded as %XX then
-they was passed to backend unescaped.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.16" date="27.03.2002">
-
-<change type="feature">
-<para lang="ru">
-× ÄÉÒÅËÔÉ×Å AccelPass ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÓÐÅÃÉÁÌØÎÏÅ
-ÉÍÑ ÈÏÓÔÁ _the_same_host_.
-</para>
-<para lang="en">
-special hostname _the_same_host_ can be used in AccelPass directive.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÎÅ ÒÁÂÏÔÁÌÏ ÏÇÒÁÎÉÞÅÎÉÅ ËÏÌÉÞÅÓÔ×Á ÓÏÅÄÉÎÅÎÉÊ É ÖÄÕÝÉÈ ÐÒÏÃÅÓÓÏ×
-ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÆÌÁÇÁ PH × ÄÉÒÅËÔÉ×Å AccelPass.
-</para>
-<para lang="en">
-limition of connections and waiting processes does not work
-if PH flag in AccelPass directive was used.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelPassServer.
-</para>
-<para lang="en">
-AccelPassServer directive was added.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.15" date="12.03.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ ÍÏÄÕÌÉ mod_quoted ÉÌÉ mod_randban ÂÙÌÉ ÓÏÂÒÁÎÙ ÓÔÁÔÉÞÅÓËÉ
-ÉÌÉ ÐÏÄÇÒÕÖÁÌÉÓØ Ó ÐÏÍÏÝØÀ LoadModule, ÎÏ ÎÅ ÂÙÌÉ ÄÏÂÁ×ÌÅÎÙ
-ÄÉÒÅËÔÉ×ÏÊ AddModule ÐÏÓÌÅ ÄÉÒÅËÔÉ×Ù ClearModuleList, ÔÏ
-ÄÉÒÅËÔÉ×Ù ÜÔÉÈ ÍÏÄÕÌÅÊ ÎÅ ×ÏÓÐÒÉÎÉÍÁÌÉÓØ.
-åÓÌÉ ÖÅ ÄÉÒÅËÔÉ×Ù ÜÔÉÈ ÍÏÄÕÌÅÊ ÎÅ ÉÓÐÏÌØÚÏ×ÁÌÉÓØ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÈ ÆÁÊÌÁÈ,
-ÔÏ ÐÒÉ ÌÀÂÙÈ ÚÁÐÒÏÓÁÈ, ÏÂÒÁÂÁÔÙ×ÁÅÍÙÈ ÍÏÄÕÌÅÍ mod_accel,
-ÐÒÏÉÓÈÏÄÉÌ segmentation fault.
-</para>
-<para lang="en">
-if mod_quoted or mod_randban modules were statically build 
-or were loaded with LoadModule directive and were not added
-with AddModule directive after ClearModuleList directive then
-their directives were unrecognized.
-If their directives were not used in configration files
-then any request handled by mod_accel caused segmentation fault.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.14" date="26.02.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÎÅËÏÒÒÅËÔÎÏ ÏÂÒÁÂÁÔÙ×ÁÌÉÓØ ÏÔ×ÅÔÙ ÂÜËÅÎÄÁ Ó ÂÏÌØÛÉÍÉ ÚÁÇÏÌÏ×ËÁÍÉ.
-</para>
-<para lang="en">
-backend response with big header was incorrectly handled.
-</para>
-</change>
-
-<change type="workaround">
-<para lang="ru">
-ÉÇÎÏÒÉÒÕÀÔÓÑ ÓÔÒÏËÉ ÔÉÐÁ "HTTP/1.0 200 OK" × ÓÅÒÅÄÉÎÅ ÚÁÇÏÌÏ×ËÁ ÏÔ×ÅÔÁ
-ÂÜËÅÎÄÁ. äÏÂÁ×ÌÅÎÁ ÚÁÐÉÓØ × ErrorLog ÎÅËÏÒÒÅËÔÎÙÈ ÚÁÇÏÌÏ×ËÏ× × ÏÔ×ÅÔÅ
-ÂÜËÅÎÄÁ.
-</para>
-<para lang="en">
-lines like "HTTP/1.0 200 OK" are ignored in middle of backend response header.
-Incorrect backend header lines are logged in ErrorLog.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelInvalidate, accel-cachemgr É ÚÁÇÏÌÏ×ËÉ ÔÉÐÁ
-<nobr>"Pragma: no-cache"</nobr> ÎÅ ÏÂÎÏ×ÌÑÌÉ ËÜÛ,
-ÅÓÌÉ ÚÁÄÁÎÁ ÄÉÒÅËÔÉ×Á "AccelUnlinkNoCached off".
-</para>
-<para lang="en">
-AccelInvalidate directive, accel-cachemgr and headers like
-<nobr>"Pragma: no-cache"</nobr> did not refresh cache
-if AccelUnlinkNoCached directive was off.
-</para>
-</change>
-
-<change type="change">
-<para lang="ru">
-ÐÏÒÑÄÏË ÎÁÓÌÅÄÏ×ÁÎÉÑ AccelPass ÉÚÍÅΣÎ, ÓÎÁÞÁÌÁ ÐÒÏ×ÅÒÑÀÔÓÑ
-ÄÉÒÅËÔÉ×Ù ÉÚ ×ÉÒÔÕÁÌØÎÏÇÏ ÓÅÒ×ÅÒÁ, Á ÚÁÔÅÍ ÉÚ ÏÓÎÏ×ÎÏÇÏ.
-</para>
-<para lang="en">
-merge order of AccelPass directive is changed. Virtual server direcitves
-are checked first.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.13" date="12.02.2002">
-
-<change type="bugfix">
-<para lang="ru">
-ÎÅ ËÏÒÒÅËÔÉÒÏ×ÁÌÓÑ ÐÏÒÔ × ÚÁÇÏÌÏ×ËÁÈ "Location" É "Refresh"
-ÅÓÌÉ ÉÓÐÏÌØÚÏ×ÁÌÓÑ ÆÌÁÇ PH × ÄÉÒÅËÔÉ×Å AccelPass É ÎÏÍÅÒÁ ÐÏÒÔÏ×
-ÆÒÏÎÔÅÎÄÁ É ÂÜËÅÎÄÁ ÏÔÌÉÞÁÌÉÓØ.
-</para>
-<para lang="en">
-port was not corrected in "Location" and "Refresh" headers
-if PH flag in AccelPass directive was used and frontend and backend
-port numbers were not the same.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.12" date="10.02.2002">
-
-<change type="feature">
-<para lang="ru">
-ÆÌÁÇ PH × ÄÉÒÅËÔÉ×Å AccelPass.
-</para>
-<para lang="en">
-PH flag was added in AccelPass directive.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.11" date="01.02.2002">
-
-<change type="change">
-<para lang="ru">
-ÕÐÒÁÚÄÎÅÎÁ ÄÉÒÅËÔÉ×Á AccelContentTail.
-</para>
-<para lang="en">
-AccelContentTail directive was removed.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ ÐÅÒÅÚÁÐÉÓÙ×ÁÅÍÁÑ ÓÔÒÏËÁ ÐÏÐÁÄÁÌÁ ÎÁ ÇÒÁÎÉÃÕ ÂÕÆÅÒÁ, mod_randban
-ÍÏÇ ÎÅËÏÒÒÅËÔÎÏ ÐÏÍÅÎÑÔØ ÓÌÕÞÁÊÎÏÅ ÞÉÓÌÏ.
-</para>
-<para lang="en">
-mod_randban can incorrectly change random value if string to rewrite
-was on buffer edge.
-</para>
-</change>
+<changes ver="0.1.0" date="04.10.2004">
 
 <change>
 <para lang="ru">
-óÏ×ÍÅÓÔÉÍÏÓÔØ Ó Apache 1.3.23.
+ðÅÒ×ÁÑ ÐÕÂÌÉÞÎÏ ÄÏÓÔÕÐÎÁÑ ×ÅÒÓÉÑ.
 </para>
 <para lang="en">
-Apache 1.3.23 compatibility.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÅÓÌÉ × ËÏÎÆÉÇÕÒÁÃÉÉ AccelPass ÏÐÉÓÁÎ Location × ×ÉÄÅ /proxied/,
-ÔÏ ÐÒÉ ÚÁÐÒÏÓÅ /proxied ×ÏÚ×ÒÁÝÁÅÔÓÑ ÒÅÄÉÒÅËÔ ÎÁ URL Ó ÄÏÂÁ×ÌÅÎÎÙÍ
-ÓÌÜÛÏÍ - /proxied/.
-</para>
-<para lang="en">
-if Location is specified in AccelPass as /proxied/ then
-on request /proxied redirect is returned to URL with slash added - /proxied/.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÎÅ ×ÏÚ×ÒÁÝÁÌÁÓØ ÏÛÉÂËÁ, ÅÓÌÉ ÎÅ ÕÄÁ×ÁÌÏÓØ ÓÏÚÄÁÔØ ×ÒÅÍÅÎÎÙÊ ÆÁÊÌ
-ÄÌÑ ÈÒÁÎÅÎÉÑ ÔÅÌÁ ÚÁÐÒÏÓÁ POST.
-</para>
-<para lang="en">
-error was not returned if POST request body temporary file creation was failed.
+The first public version.
 </para>
 </change>
 
 </changes>
 
 
-<changes ver="1.0.10" date="28.12.2001">
-
-<change type="feature">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelReverse.
-</para>
-<para lang="en">
-AccelReverse directive was added.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.9" date="24.12.2001">
-
-<change type="bugfix">
-<para lang="ru">
-ÎÁ Solaris 7 É FreeBSD 2.x ÂÏÌØÛÉÅ ÏÔ×ÅÔÙ ÐÅÒÅÄÁ×ÁÌÉÓØ ÎÅ ÄÏ ËÏÎÃÁ.
-</para>
-<para lang="en">   
-big repsonses was truncated on Solaris 7 and FreeBSD 2.x.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.8" date="19.12.2001">
-
-<change type="bugfix">
-<para lang="ru">
-ÓËÏÒÒÅËÔÉÒÏ×ÁÎÙ ÎÅËÏÔÏÒÙÅ ÓÏÏÂÝÅÎÉÑ Ï ÏÛÉÂËÁÈ.
-</para>
-<para lang="en">
-some error messages was corrected.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ ËÌÉÅÎÔ × ÚÁÐÒÏÓÅ POST ÏÂÒÙ×ÁÌ ÓÏÅÄÉÎÅÎÉÅ,
-ÔÏ ÂÜËÅÎÄÕ ÐÅÒÅÄÁ×ÁÌÏÓØ ÎÅÐÏÌÎÏÅ ÔÅÌÏ ÚÁÐÒÏÓÁ.
-ôÅÐÅÒØ mod_accel × ÔÁËÏÊ ÓÉÔÕÁÃÉÉ ÎÅ ÓÏÅÄÉÎÑÅÔÓÑ Ó ÂÜËÅÎÄÏÍ.
-</para>
-<para lang="en">
-if client aborted connection while POST
-then backend received incompleted request body.
-Now mod_accel doesn't connect to backend in this situation.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-mod_accel ÎÅ ÓÏÂÉÒÁÌÓÑ ÂÅÚ ÂÉÂÌÉÏÔÅËÉ mm.
-</para>
-<para lang="en">
-mod_accel did not build without mm library.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.7" date="06.12.2001">
-
-<change type="feature">
-<para lang="ru">
-× ÓÏÏÂÝÅÎÉÑ Ï ÏÛÉÂËÁÈ ÄÏÂÁ×ÌÅÎ URL, ËÏÔÏÒÙÊ ÐÅÒÅÄÁ£ÔÓÑ ÂÜËÅÎÄÕ.
-</para>
-<para lang="en">
-backend URL was added in error messages.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÔÒÅÔÉÊ ÐÁÒÁÍÅÔÒ × ÄÉÒÅËÔÉ×Å AccelBusyLock.
-</para>
-<para lang="en">
-third parameter was added in AccelBusyLock directory.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÐÏÒÑÄÏË ÚÁÇÒÕÚËÉ ÍÏÄÕÌÅÊ mod_accel, mod_randban, mod_quoted
-É mod_ssl ÎÅ ×ÁÖÅÎ.
-</para>
-<para lang="en">
-load order of mod_accel, mod_randban, mod_quoted and mod_ssl
-has no meaning now.
-</para>
-</change>
-
-<change type="change">
-<para lang="ru">
-ÄÏÂÁ×ÌÅÎ ÐÁÒÁÍÅÔÒ --with-patch × configure.<br/>
-õÐÒÁÚÄÎÅÎÙ ÐÁÒÁÍÅÔÒÙ --without-mod_charset É --without-mod_ssl.
-</para>
-<para lang="en">
---with-patch directive was added in configure.<br/>
---without-mod_charset and --without-mod_ssl directives is removed.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÕÌÕÞÛÅÎÉÅ ÐÏÒÔÁÂÉÌØÎÏÓÔÉ.
-</para>
-<para lang="en">
-portability enhancement.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.6" date="02.11.2001">
-
-<change type="feature">
-<para lang="ru">
-×Ï ÆÌÁÇÅ MP ÄÉÒÅËÔÉ×Ù AccelPass ÍÏÖÎÏ ÕËÁÚÙ×ÁÔØ ÔÜÇ.
-</para>
-<para lang="en">
-MP flag of AccelPass directive can have tag.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÐÒÏËÓÉÒÏ×ÁÎÉÑ (ÆÌÁÇ P) × ÄÉÒÅËÔÉ×Å
-RewriteRule ÍÏÄÕÌÑ mod_rewrite ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÆÌÁÇ MP.
-</para>
-<para lang="en">
-MP flag can be used in mod_rewrite module RewriteRule
-directive when proxing is specified (P flag).
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÐÒÉ ÕËÁÚÁÎÉÉ ×ÒÅÍÅÎÉ ËÜÛÉÒÏ×ÁÎÉÑ Ó ÐÏÍÏÝØÀ ÄÉÒÅËÔÉ×
-AccelDefaultExpire ÉÌÉ AccelLastModifiedFactor ÏÔ×ÅÔ ÎÅ ÓÏÈÒÁÎÑÌÓÑ
-× ËÜÛ, ÅÓÌÉ ÒÁÚÎÉÃÁ ×Ï ×ÒÅÍÅÎÉ ÍÅÖÄÕ ÆÒÏÎÔÅÎÄÏÍ É ÂÜËÅÎÄÏÍ ÂÙÌÁ
-ÂÏÌØÛÅ ×ÒÅÍÑ ËÜÛÉÒÏ×ÁÎÉÑ.
-</para>
-<para lang="en">
-if time to cache is specified in AccelDefaultExpire or
-AccelLastModifiedFactor directive and time difference between
-frontend and backend is more then specified time then answer
-was not saved in cache.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.5" date="18.10.2001">
-
-<change type="feature">
-<para lang="ru">   
-ÄÉÒÅËÔÉ×Á AccelIgnoreAuth.
-</para>
-<para lang="en">
-AccelIgnoreAuth directive was added.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÐÒÏËÓÉÒÏ×ÁÎÉÑ (ÆÌÁÇ P) × ÄÉÒÅËÔÉ×Å
-RewriteRule ÍÏÄÕÌÑ mod_rewrite ÍÏÄÕÌØ mod_proxy ÄÕÂÌÉÒÏ×ÁÌ
-ÓÔÒÏËÕ ÁÒÇÕÍÅÎÔÏ×.
-</para>
-<para lang="en">  
-mod_proxy module duplicated argument string when proxing
-is specified in mod_rewrite module RewriteRule directive (P flag).
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.4" date="16.10.2001">
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ ÂÜËÅÎÄÏ× ÎÅÓËÏÌØËÏ É Ó ÏÄÎÉÍ ÉÚ ÎÉÈ ÓÏÅÄÉÎÅÎÉÅ
-ÎÅ ÂÙÌÏ ÕÓÔÁÎÏ×ÌÅÎÏ, ÔÏ ÉÎÆÏÒÍÁÃÉÑ Ï ÜÔÏÊ ÐÏÐÙÔËÅ × ÚÁÍÅÔËÉ
-%{accel*}x ÎÅ ÄÏÂÁ×ÌÑÌÁÓØ.
-</para>
-<para lang="en">
-if there are several backends and connection with one of them
-was not established then %{accel*}x notes did not contain state of it.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÐÒÉ ÐÏÌÕÞÅÎÉÉ ÏÔ ÂÜËÅÎÄÁ ÂÏÌØÛÏÇÏ ÚÁÇÏÌÏ×ËÁ ÐÒÏÉÓÈÏÄÉÌ
-segmentation fault.
-</para>
-<para lang="en">
-backend big header caused segmentation fault.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-× accel-cachemgr ÄÏÂÁ×ÌÅÎÙ Ä×Á ÓÏÓÔÏÑÎÉÑ - invalid
-É no_accelerated.
-</para>
-<para lang="en">
-two status codes - invalid and no_accelerated was added
-in accel-cachemgr.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á RewriteRule ÍÏÄÕÌÑ mod_rewrite Ó ÆÌÁÇÏÍ [P]
-ÒÁÂÏÔÁÌÁ ÔÏÌØËÏ ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ × SSI.
-</para>
-<para lang="en">
-mod_rewrite module RewriteRule directive with flag [P]
-worked in SSI enviroment only.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.3" date="10.10.2001">
-
-<change>
-<para lang="ru">
-éÚÍÅÎÅÎÉÑ × ÄÉÒÅËÔÉ×Å AccelCacheCookie:
-äÏÂÁ×ÌÅÎÙ ÐÁÒÁÍÅÔÒ "all", ÚÁÐÒÅÝÁÀÝÉÅ ÐÁÒÁÍÅÔÒÙ É ÒÅÇÕÌÑÒÎÙÅ ×ÙÒÁÖÅÎÉÑ.
-÷ ÏÄÎÏÊ ÄÉÒÅËÔÉ×Å ÍÏÖÅÔ ÂÙÔØ ÕËÁÚÁÎÏ ÎÅÓËÏÌØËÏ ÐÁÒÁÍÅÔÒÏ×.
-äÉÒÅËÔÉ×Ù ÉÚ ×ÌÏÖÅÎÎÙÈ ÂÌÏËÏ× ÎÅ ÏÂßÅÄÉÎÑÀÔÓÑ.
-éÍÅÎÁ cookie ÓÏÒÔÉÒÕÀÔÓÑ × ÁÌÆÁ×ÉÔÎÏÍ ÐÏÒÑÄËÅ.
-</para>
-<para lang="en">
-Changes in AccelCacheCookie directive:
-"all" parameter, supressing parameters and regular expressions was added.
-There can be several parameters in one directive.
-Directives is not merged.
-Cookie names is sorted in alphabetical order.
-</para>
-</change>
-
-<change>
-<para lang="ru">
-éÚÍÅÎÅÎÉÑ × ÄÉÒÅËÔÉ×Å AccelNoPass:
-òÅÇÕÌÑÒÎÏÅ ×ÙÒÁÖÅÎÉÅ ÍÏÖÅÔ ÂÙÔØ ÎÅÞÕÓÔ×ÉÔÅÌØÎÏ Ë ÒÅÇÉÓÔÒÕ.
-íÅÖÄÕ ÓÉÍ×ÏÌÏÍ "~" É ÒÅÇÕÌÑÒÎÙÍ ×ÙÒÁÖÅÎÉÅÍ ÎÅ ÄÏÌÖÎÏ ÂÙÔØ ÐÒÏÂÅÌÁ.
-÷ ÏÄÎÏÊ ÄÉÒÅËÔÉ×Å ÍÏÖÅÔ ÂÙÔØ ÕËÁÚÁÎÏ ÎÅÓËÏÌØËÏ ÐÁÒÁÍÅÔÒÏ×.
-</para>
-<para lang="en">
-Changes in AccelNoPass directive:
-Regular expression can be case-insensitive.
-There should not be space between "~" symbol and regular expression.
-There can be several parameters in one directive.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.2" date="04.10.2001">
-
-<change type="feature">
-<para lang="ru">
-ÄÉÒÅËÔÉ×Á AccelCacheCookie.
-</para>
-<para lang="en">
-AccelCacheCookie directive was added.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÚÁÍÅÔËÁ accel_nocache.
-</para>
-<para lang="en">
-accel_nocache note was added.
-</para>
-</change>
-
-<change type="feature">
-<para lang="ru">
-ÏÂÒÁÂÏÔÞÉË accel-cachemgr.
-</para>
-<para lang="en">
-accel-cachemgr handler was added.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÐÒÉ ÚÁÐÒÏÓÅ ÎÅÓËÏÌØËÉÈ ÎÅ×ÏÚÒÁÓÔÁÀÝÉÈ byteranges ÍÏÇ
-×ÙÄÁ×ÁÔØÓÑ ÎÅ×ÅÒÎÙÊ ÏÔ×ÅÔ.
-</para>
-<para lang="en">
-answer may be wrong if request contains several non-growing
-byteranges.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÚÁÍÅÔËÁ %{accel_r}x ÎÅ ÚÁÐÉÓÙ×ÁÌÁÓØ × ÌÏÇ.
-</para>
-<para lang="en">
-%{accel_r}x note was not logged.
-</para>
-</change>
-
-<change type="bugfix">
-<para lang="ru">
-ÅÓÌÉ ÏÔ×ÅÔ ÎÅËÜÛÉÒÕÅÍÙÊ, ÔÏ ÐÒÉ ÐÒÅÖÄÅ×ÒÅÍÅÎÎÏÍ ÏÂÒÙ×Å
-ÓÏÅÄÉÎÅÎÉÑ Ó ËÌÉÅÎÔÏÍ ÓÏÅÄÉÎÅÎÉÅ Ó ÂÜËÅÎÄÏÍ ÎÅ ÚÁËÒÙ×ÁÌÏÓØ ÓÒÁÚÕ.
-</para>
-<para lang="en">
-if response is not cachable and client prematurely closes
-connection then connection to backend was not closed at once.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.1" date="29.08.2001">
-
-<change type="bugfix">
-<para lang="ru">
-ÏÛÉÂËÁ × accel_read_and_check_writable() ×ÙÚÙ×ÁÌÁ ÎÁÇÒÕÚËÕ ÎÁ ÐÒÏÃÅÓÓÏÒ.
-</para>
-<para lang="en">
-bug in accel_read_and_check_writable() caused high CPU usage.
-</para>
-</change>
-
-</changes>
-
-
-<changes ver="1.0.0" date="28.08.2001">
-
-<change>
-<para lang="ru">
-ðÅÒ×ÁÑ ×ÅÒÓÉÑ.<br/>
-ôÅÓÔÉÒÏ×ÁÌÁÓØ ÎÁ Apache 1.3.14, 1.3.17, 1.3.19, 1.3.20 ÎÁ
-<nobr>FreeBSD 3.4, 4.2.</nobr>
-</para>
-<para lang="en">
-First release.<br/>
-Tested with Apache 1.3.14, 1.3.17, 1.3.19, 1.3.20 on FreeBSD 3.4, 4.2.
-</para>
-</change>
-
-</changes>
-
 </change_log>
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 18f3ccc..9d91080 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -11,7 +11,8 @@
 
 
 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
-static ngx_int_t ngx_getopt(ngx_master_ctx_t *ctx, ngx_cycle_t *cycle);
+static ngx_int_t ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv);
+static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
 static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -96,13 +97,12 @@
 ngx_uint_t  ngx_max_module;
 
 
-int main(int argc, char *const *argv)
+int main(int argc, char *const *argv, char *const *envp)
 {
-    ngx_int_t          i;
-    ngx_log_t         *log;
-    ngx_cycle_t       *cycle, init_cycle;
-    ngx_core_conf_t   *ccf;
-    ngx_master_ctx_t   ctx;
+    ngx_int_t         i;
+    ngx_log_t        *log;
+    ngx_cycle_t      *cycle, init_cycle;
+    ngx_core_conf_t  *ccf;
 
 #if defined __FreeBSD__
     ngx_debug_init();
@@ -132,15 +132,15 @@
     init_cycle.log = log;
     ngx_cycle = &init_cycle;
 
-    ngx_memzero(&ctx, sizeof(ngx_master_ctx_t));
-    ctx.argc = argc;
-    ctx.argv = argv;
-
     if (!(init_cycle.pool = ngx_create_pool(1024, log))) {
         return 1;
     }
 
-    if (ngx_getopt(&ctx, &init_cycle) == NGX_ERROR) {
+    if (ngx_getopt(&init_cycle, argc, argv) == NGX_ERROR) {
+        return 1;
+    }
+
+    if (ngx_save_argv(&init_cycle, argc, argv) == NGX_ERROR) {
         return 1;
     }
 
@@ -219,10 +219,10 @@
 #endif
 
     if (ngx_process == NGX_PROCESS_MASTER) {
-        ngx_master_process_cycle(cycle, &ctx);
+        ngx_master_process_cycle(cycle);
 
     } else {
-        ngx_single_process_cycle(cycle, &ctx);
+        ngx_single_process_cycle(cycle);
     }
 
     return 0;
@@ -276,7 +276,7 @@
 
 ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
 {
-    char             *env[2], *var, *p;
+    char             *env[3], *var, *p;
     ngx_uint_t        i;
     ngx_pid_t         pid;
     ngx_exec_ctx_t    ctx;
@@ -300,7 +300,25 @@
     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "inherited: %s", var);
 
     env[0] = var;
+
+#if (NGX_SETPROCTITLE_USES_ENV)
+
+    /* allocate spare 300 bytes for the new binary process title */
+
+    env[1] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+             "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+             "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+             "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+             "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+
+    env[2] = NULL;
+
+#else
+
     env[1] = NULL;
+
+#endif
+
     ctx.envp = (char *const *) &env;
 
     pid = ngx_execute(cycle, &ctx);
@@ -311,38 +329,38 @@
 }
 
 
-static ngx_int_t ngx_getopt(ngx_master_ctx_t *ctx, ngx_cycle_t *cycle)
+static ngx_int_t ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
 {
     ngx_int_t  i;
 
-    for (i = 1; i < ctx->argc; i++) {
-        if (ctx->argv[i][0] != '-') {
+    for (i = 1; i < argc; i++) {
+        if (argv[i][0] != '-') {
             ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                          "invalid option: \"%s\"", ctx->argv[i]);
+                          "invalid option: \"%s\"", argv[i]);
             return NGX_ERROR;
         }
 
-        switch (ctx->argv[i][1]) {
+        switch (argv[i][1]) {
 
         case 't':
             ngx_test_config = 1;
             break;
 
         case 'c':
-            if (ctx->argv[i + 1] == NULL) {
+            if (argv[i + 1] == NULL) {
                 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                               "the option: \"%s\" requires file name",
-                              ctx->argv[i]);
+                              argv[i]);
                 return NGX_ERROR;
             }
 
-            cycle->conf_file.data = (u_char *) ctx->argv[++i];
+            cycle->conf_file.data = (u_char *) argv[++i];
             cycle->conf_file.len = ngx_strlen(cycle->conf_file.data);
             break;
 
         default:
             ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                          "invalid option: \"%s\"", ctx->argv[i]);
+                          "invalid option: \"%s\"", argv[i]);
             return NGX_ERROR;
         }
     }
@@ -360,6 +378,43 @@
 }
 
 
+static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
+{
+    size_t     len;
+    ngx_int_t  i;
+
+    ngx_os_argv = (char **) argv;
+
+    ngx_argc = argc;
+
+#if __FreeBSD__
+
+    ngx_argv = (char **) argv;
+
+#else
+
+    if (!(ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log))) {
+        return NGX_ERROR;
+    }
+
+    for (i = 0; i < argc; i++) {
+        len = ngx_strlen(argv[i]) + 1;
+
+        if (!(ngx_argv[i] = ngx_alloc(len, cycle->log))) {
+            return NGX_ERROR;
+        }
+
+        ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len);
+    }
+
+    ngx_argv[i] = NULL;
+
+#endif
+
+    return NGX_OK;
+}
+
+
 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle)
 {
     ngx_core_conf_t  *ccf;
@@ -407,6 +462,7 @@
 
 #if !(WIN32)
 
+#if 0
     if (ccf->user == (uid_t) NGX_CONF_UNSET) {
 
         pwd = getpwnam("nobody");
@@ -427,10 +483,11 @@
 
         ccf->group = grp->gr_gid;
     }
+#endif
 
     if (ccf->pid.len == 0) {
         ccf->pid.len = sizeof(NGX_PID_PATH) - 1;
-        ccf->pid.data = NGX_PID_PATH;
+        ccf->pid.data = (u_char *) NGX_PID_PATH;
     }
 
     if (ngx_conf_full_name(cycle, &ccf->pid) == NGX_ERROR) {
@@ -478,7 +535,7 @@
     pwd = getpwnam((const char *) value[1].data);
     if (pwd == NULL) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
-                           "getpwnam(%s) failed", value[1].data);
+                           "getpwnam(\"%s\") failed", value[1].data);
         return NGX_CONF_ERROR;
     }
 
@@ -491,7 +548,7 @@
     grp = getgrnam((const char *) value[2].data);
     if (grp == NULL) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
-                           "getgrnam(%s) failed", value[1].data);
+                           "getgrnam(\"%s\") failed", value[2].data);
         return NGX_CONF_ERROR;
     }
 
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 66b5c33..82545e5 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.0"
+#define NGINX_VER          "nginx/0.1.1"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
diff --git a/src/core/ngx_buf.c b/src/core/ngx_buf.c
index 72b558b..a536c04 100644
--- a/src/core/ngx_buf.c
+++ b/src/core/ngx_buf.c
@@ -152,7 +152,8 @@
             continue;
         }
 
-        (*busy)->buf->pos = (*busy)->buf->last = (*busy)->buf->start;
+        (*busy)->buf->pos = (*busy)->buf->start;
+        (*busy)->buf->last = (*busy)->buf->start;
 
         tl = *busy;
         *busy = (*busy)->next;
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index fc05337..3a3db52 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -57,7 +57,7 @@
 
 
 #define NGX_CONF_OK          NULL
-#define NGX_CONF_ERROR       (void *) -1
+#define NGX_CONF_ERROR       (char *) -1
 
 #define NGX_CONF_BLOCK_DONE  1
 #define NGX_CONF_FILE_DONE   2
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 698342f..19f5629 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -313,18 +313,6 @@
         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
         return;
     }
-    
-#if (NGX_OPENSSL)
-
-    if (c->ssl) {
-        if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
-            c->read->event_handler = ngx_ssl_close_handler;
-            c->write->event_handler = ngx_ssl_close_handler;
-            return;
-        }
-    }
-    
-#endif
 
     if (c->read->timer_set) {
         ngx_del_timer(c->read);
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 7a03450..57c7a33 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -120,7 +120,12 @@
     unsigned            single_connection:1;
     unsigned            unexpected_eof:1;
     unsigned            timedout:1;
+
+    unsigned            sendfile:1;
+    unsigned            sndlowat:1;
+    unsigned            tcp_nodelay:1;
     signed              tcp_nopush:2;
+
 #if (HAVE_IOCP)
     unsigned            accept_context_updated:1;
 #endif
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index ed4d60f..38f4ad5 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -615,6 +615,9 @@
     ngx_uint_t        i;
     ngx_list_part_t  *part;
     ngx_open_file_t  *file;
+#if !(WIN32)
+    ngx_file_info_t   fi;
+#endif
 
     part = &cycle->open_files.part;
     file = part->elts;
@@ -672,6 +675,35 @@
                                   file[i].name.data);
                 }
             }
+
+            if (ngx_file_info((const char *) file[i].name.data, &fi) == -1) {
+                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                              ngx_file_info_n " \"%s\" failed",
+                              file[i].name.data);
+
+                if (ngx_close_file(fd) == NGX_FILE_ERROR) {
+                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                                  ngx_close_file_n " \"%s\" failed",
+                                  file[i].name.data);
+                }
+            }
+
+            if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) {
+
+                fi.st_mode |= (S_IRUSR|S_IWUSR);
+
+                if (chmod((const char *) file[i].name.data, fi.st_mode) == -1) {
+                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                                  "chmod \"%s\" failed",
+                                  file[i].name.data);
+
+                    if (ngx_close_file(fd) == NGX_FILE_ERROR) {
+                        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                                      ngx_close_file_n " \"%s\" failed",
+                                      file[i].name.data);
+                    }
+                }
+            }
         }
 
         if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index f0d66cb..74e38e1 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -228,8 +228,15 @@
         src->pos += size;
         dst->last += size;
 
-        if (src->in_file) {
+        if (src->in_file && sendfile) {
+            dst->in_file = 1;
+            dst->file = src->file;
+            dst->file_pos = src->file_pos;
             src->file_pos += size;
+            dst->file_last = src->file_pos;
+
+        } else {
+            dst->in_file = 0;
         }
 
         if (src->last_buf && src->pos == src->last) {
@@ -258,11 +265,18 @@
             }
         }
 
-        src->file_pos += n;
         dst->last += n;
 
-        if (!sendfile) {
+        if (sendfile) {
+            dst->in_file = 1;
+            dst->file = src->file;
+            dst->file_pos = src->file_pos;
+            src->file_pos += size;
+            dst->file_last = src->file_pos;
+
+        } else {
             dst->in_file = 0;
+            src->file_pos += n;
         }
 
         if (src->last_buf && src->file_pos == src->file_last) {
diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c
index ee4d224..e41e971 100644
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -77,13 +77,14 @@
     ngx_pool_large_t  *large, *last;
 
     if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL
-        && size <= (size_t) (pool->end - (char *) pool) - sizeof(ngx_pool_t))
+        && size <= (size_t) (pool->end - (char *) pool)
+                                     - (size_t) ngx_align(sizeof(ngx_pool_t)))
     {
         for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
             m = ngx_align(p->last);
 
             if ((size_t) (p->end - m) >= size) {
-                p->last = m + size ;
+                p->last = m + size;
 
                 return m;
             }
@@ -100,8 +101,8 @@
         }
 
         p->next = n;
-        m = n->last;
-        n->last += size;
+        m = ngx_align(n->last);
+        n->last = m + size;
 
         return m;
     }
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 3d6a9eb..32a4079 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -128,7 +128,7 @@
 }
 
 
-void ngx_encode_base64(ngx_str_t *src, ngx_str_t *dst)
+void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
 {
     u_char         *d, *s;
     size_t          len;
@@ -168,7 +168,7 @@
 }
 
 
-ngx_int_t ngx_decode_base64(ngx_str_t *src, ngx_str_t *dst)
+ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
 {
     size_t          len;
     u_char         *d, *s;
@@ -231,54 +231,55 @@
 }
 
 
-#if 0
-char *ngx_psprintf(ngx_pool_t *p, const char *fmt, ...)
+ngx_int_t ngx_escape_uri(u_char *dst, u_char *src, size_t size)
 {
-    va_list    args;
+    ngx_int_t         n;
+    ngx_uint_t        i;
+    static u_char     hex[] = "0123456789abcdef";
+    static uint32_t   escape[] =
+        { 0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
-    va_start(args, fmt);
+                      /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
+          0x80000021, /* 1000 0000 0000 0000  0000 0000 0010 0001 */
 
-    while (*fmt) {
-         switch(*fmt++) {
-         case '%':
-             switch(*fmt++) {
-             case 's':
-                 s = va_arg(args, char *);
-                 n += ngx_strlen(s);
-                 break;
+                      /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
+          0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
 
-             default:
-                 n++;
-         }
-         default:
-             n++;
-         }
+                      /*  ~}| {zyx wvut srqp  onml kjih gfed cba` */
+          0x80000000, /* 1000 0000 0000 0000  0000 0000 0000 0000 */
+
+          0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+          0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+          0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+          0xffffffff  /* 1111 1111 1111 1111  1111 1111 1111 1111 */ };
+
+    if (dst == NULL) {
+
+        /* find the number of the characters to be escaped */
+
+        n  = 0;
+
+        for (i = 0; i < size; i++) {
+            if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+                n++;
+            }
+            src++;
+        }
+
+        return n;
     }
 
-    str = ngx_palloc(p, n);
+    for (i = 0; i < size; i++) {
+        if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+            *dst++ = '%';
+            *dst++ = hex[*src >> 4];
+            *dst++ = hex[*src & 0xf];
+            src++;
 
-    va_start(args, fmt);
-
-    for (i = 0; i < n; i++) {
-         switch(*fmt++) {
-         case '%':
-             switch(*fmt++) {
-             case 's':
-                 s = va_arg(args, char *);
-                 while (str[i++] = s);
-                 break;
-
-             default:
-                 n++;
-         }
-         default:
-             str[i] = *fmt;
-         }
+        } else {
+            *dst++ = *src++;
+        }
     }
 
-    len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args);
-
-    va_end(args);
-
+    return NGX_OK;
 }
-#endif
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index fbc8875..e8e69c0 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -60,6 +60,7 @@
  * icc may also inline several mov's of a zeroed register for small blocks.
  */
 #define ngx_memzero(buf, n)       memset(buf, 0, n)
+#define ngx_memset(buf, c, n)     memset(buf, c, n)
 
 /* msvc and icc compile memcpy() to the inline "rep movs" */
 #define ngx_memcpy(dst, src, n)   memcpy(dst, src, n)
@@ -80,8 +81,9 @@
 #define ngx_base64_encoded_length(len)  (((len + 2) / 3) * 4)
 #define ngx_base64_decoded_length(len)  (((len + 3) / 4) * 3)
 
-void ngx_encode_base64(ngx_str_t *src, ngx_str_t *dst);
-ngx_int_t ngx_decode_base64(ngx_str_t *src, ngx_str_t *dst);
+void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src);
+ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src);
+ngx_int_t ngx_escape_uri(u_char *dst, u_char *src, size_t size);
 
 
 #define  ngx_qsort                qsort
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 7d68884..ea1d19b 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -202,13 +202,7 @@
 #endif
 
 #if (NGX_READ_EVENT != POLLIN)
-    if (event == NGX_READ_EVENT) {
-        event = POLLOUT;
-#if (NGX_WRITE_EVENT != POLLOUT)
-    } else {
-        event = POLLIN;
-#endif
-    }
+    event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
 #endif
 
 #if (NGX_DEBUG)
@@ -218,6 +212,7 @@
 #endif
 
     ev->active = 1;
+
     return ngx_devpoll_set_event(ev, event, 0);
 }
 
@@ -229,6 +224,10 @@
 
     c = ev->data;
 
+#if (NGX_READ_EVENT != POLLIN)
+    event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
+#endif
+
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                    "devpoll del event: fd:%d ev:%04X", c->fd, event);
 
@@ -242,13 +241,9 @@
         return NGX_OK;
     }
 
-    /* we need to restore the second event if it exists */
+    /* restore the paired event if it exists */
 
-    if (event == NGX_READ_EVENT) {
-        if (ev->accept) {
-            return NGX_OK;
-        }
-
+    if (event == POLLIN) {
         e = c->write;
         event = POLLOUT;
 
@@ -257,7 +252,7 @@
         event = POLLIN;
     }
 
-    if (e) {
+    if (e && e->active) {
         return ngx_devpoll_set_event(e, event, 0);
     }
 
@@ -273,7 +268,7 @@
     c = ev->data;
 
     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                   "devpoll fd:%d ev:%d fl:%d", c->fd, event, flags);
+                   "devpoll fd:%d ev:%04X fl:%04X", c->fd, event, flags);
 
     if (nchanges >= max_changes) {
         ngx_log_error(NGX_LOG_WARN, ev->log, 0,
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index 26b2c81..72c5b7c 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -131,10 +131,6 @@
 {
     ngx_rtsig_conf_t  *rtscf;
 
-    if (ngx_poll_module_ctx.actions.init(cycle) == NGX_ERROR) {
-        return NGX_ERROR;
-    }
-
     rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
 
     sigemptyset(&set);
@@ -170,7 +166,9 @@
 
 static void ngx_rtsig_done(ngx_cycle_t *cycle)
 {
-    ngx_poll_module_ctx.actions.done(cycle);
+    ngx_free(overflow_list);
+
+    overflow_list = NULL;
 }
 
 
@@ -697,7 +695,7 @@
                  * the new overflow.
                  *
                  * Learn the /proc/sys/kernel/rtsig-max value because
-                 * it can be changed sisnce the last checking.
+                 * it can be changed since the last checking.
                  */
 
                 name[0] = CTL_KERN;
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 3d7e15c..4718dcd 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -461,6 +461,39 @@
 }
 
 
+ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat)
+{
+    int  sndlowat;
+
+#if (HAVE_LOWAT_EVENT)
+
+    if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+        c->write->available = lowat;
+        return NGX_OK;
+    }
+
+#endif
+    
+    if (lowat == 0 || c->sndlowat) {
+        return NGX_OK;
+    }
+
+    sndlowat = (int) lowat;
+
+    if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
+                                  (const void *) &sndlowat, sizeof(int)) == -1)
+    {
+        ngx_connection_error(c, ngx_socket_errno,
+                             "setsockopt(SO_SNDLOWAT) failed");
+        return NGX_ERROR;
+    }
+
+    c->sndlowat = 1;
+
+    return NGX_OK;
+}
+
+
 static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     int                    m;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 7237bd4..c173adc 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -207,7 +207,7 @@
     ngx_int_t  (*add_conn)(ngx_connection_t *c);
     ngx_int_t  (*del_conn)(ngx_connection_t *c, u_int flags);
 
-    ngx_int_t  (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t try);
+    ngx_int_t  (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
     ngx_int_t  (*process_events)(ngx_cycle_t *cycle);
 
     ngx_int_t  (*init)(ngx_cycle_t *cycle);
@@ -479,6 +479,9 @@
 #endif
 
 
+ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
+
+
 /* used in ngx_log_debugX() */
 #define ngx_event_ident(p)  ((ngx_connection_t *) (p))->fd
 
@@ -497,7 +500,7 @@
 {
     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
 
-        /* kqueue */
+        /* kqueue, epoll */
 
         if (!rev->active && !rev->ready) {
             if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
@@ -531,7 +534,7 @@
         }
     }
 
-    /* aio, iocp, epoll, rtsig */
+    /* aio, iocp, rtsig */
 
     return NGX_OK;
 }
@@ -563,14 +566,25 @@
 }
 
 
-ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, u_int flags)
+ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
 {
+    ngx_connection_t  *c;
+
+    if (lowat) {
+        c = wev->data;
+
+        if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
+            return NGX_ERROR;
+        }
+    }
+
     if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
 
-        /* kqueue */
+        /* kqueue, epoll */
 
         if (!wev->active && !wev->ready) {
-            if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
+            if (ngx_add_event(wev, NGX_WRITE_EVENT,
+                              NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
                                                                   == NGX_ERROR)
             {
                 return NGX_ERROR;
@@ -602,7 +616,7 @@
         }
     }
 
-    /* aio, iocp, epoll, rtsig */
+    /* aio, iocp, rtsig */
 
     return NGX_OK;
 }
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 8c48a7a..151cc42 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -72,6 +72,13 @@
         return n;
     }
 
+    if (!SSL_is_init_finished(c->ssl->ssl)) {
+        handshake = "in SSL handshake";
+
+    } else {
+        handshake = "";
+    }
+
     sslerr = SSL_get_error(c->ssl->ssl, n);
 
     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
@@ -91,13 +98,6 @@
 #endif
     }
 
-    if (!SSL_is_init_finished(c->ssl->ssl)) {
-        handshake = "in SSL handshake";
-
-    } else {
-        handshake = "";
-    }
-
     c->ssl->no_rcv_shut = 1;
 
     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
@@ -240,8 +240,9 @@
 
 static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
 {
-    int        n, sslerr;
-    ngx_err_t  err;
+    int         n, sslerr;
+    ngx_err_t   err;
+    char       *handshake;
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
 
@@ -265,13 +266,21 @@
     }
 
     if (sslerr == SSL_ERROR_WANT_READ) {
+
+        if (!SSL_is_init_finished(c->ssl->ssl)) {
+            handshake = "in SSL handshake";
+
+        } else {
+            handshake = "";
+        }
+
         ngx_log_error(NGX_LOG_ALERT, c->log, err,
                       "SSL wants to read%s", handshake);
         return NGX_ERROR;
 #if 0
         return NGX_AGAIN;
-    }
 #endif
+    }
 
     c->ssl->no_rcv_shut = 1;
 
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index c1982fd..71fc500 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -64,8 +64,7 @@
 
     if (p->downstream->fd != -1) {
         wev = p->downstream->write;
-        wev->available = p->send_lowat;
-        if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+        if (ngx_handle_write_event(wev, p->send_lowat) == NGX_ERROR) {
             return NGX_ABORT;
         }
 
@@ -302,16 +301,41 @@
         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe buf");
     }
 
-    for (cl = p->in; cl; cl = cl->next) {
+    for (cl = p->busy; cl; cl = cl->next) {
         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
-                       "pipe buf in " PTR_FMT ", pos " PTR_FMT ", size: %d",
+                       "pipe buf busy " PTR_FMT ", pos " PTR_FMT ", size: %d",
                        cl->buf->start, cl->buf->pos,
                        cl->buf->last - cl->buf->pos);
     }
 
-    for (cl = p->busy; cl; cl = cl->next) {
+    for (cl = p->out; cl; cl = cl->next) {
+        if (cl->buf->in_file && cl->buf->temporary) {
+            ngx_log_debug5(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                           "pipe buf out shadow "
+                           PTR_FMT ", pos " PTR_FMT ", size: %d "
+                           "file: " OFF_T_FMT ", size: %d",
+                           cl->buf->start, cl->buf->pos,
+                           cl->buf->last - cl->buf->pos,
+                           cl->buf->file_pos,
+                           cl->buf->file_last - cl->buf->file_pos);
+
+        } else if (cl->buf->in_file) {
+            ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                           "pipe buf out file " OFF_T_FMT ", size: %d",
+                           cl->buf->file_pos,
+                           cl->buf->file_last - cl->buf->file_pos);
+        } else {
+            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                           "pipe buf out " PTR_FMT ", pos " PTR_FMT
+                           ", size: %d",
+                           cl->buf->start, cl->buf->pos,
+                           cl->buf->last - cl->buf->pos);
+        }
+    }
+
+    for (cl = p->in; cl; cl = cl->next) {
         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
-                       "pipe buf busy " PTR_FMT ", pos " PTR_FMT ", size: %d",
+                       "pipe buf in " PTR_FMT ", pos " PTR_FMT ", size: %d",
                        cl->buf->start, cl->buf->pos,
                        cl->buf->last - cl->buf->pos);
     }
@@ -337,7 +361,9 @@
 
         if (p->free_bufs) {
             for (cl = p->free_raw_bufs; cl; cl = cl->next) {
-                ngx_pfree(p->pool, cl->buf->start); 
+                if (cl->buf->shadow == NULL) {
+                    ngx_pfree(p->pool, cl->buf->start); 
+                }
             }
         }
     }
@@ -597,8 +623,11 @@
         ngx_chain_add_link(p->out, p->last_out, cl);
 
         if (b->last_shadow) {
-            b->shadow->last = b->shadow->pos = b->shadow->start;
+            b->shadow->pos = b->shadow->start;
+            b->shadow->last = b->shadow->start;
+
             ngx_alloc_link_and_set_buf(tl, b->shadow, p->pool, NGX_ABORT);
+
             *last_free = tl;
             last_free = &tl->next;
         }
@@ -650,28 +679,24 @@
 {
     ngx_buf_t  *b, *next;
 
-    if (buf->shadow == NULL) {
+    b = buf->shadow;
+
+    if (b == NULL) {
         return;
     }
 
-    b = buf->shadow;
-
     while (!b->last_shadow) {
         next = b->shadow;
 
-        b->in_file = 0;
-        b->temp_file = 0;
-        b->flush = 0;
-        b->zerocopy_busy = 0;
+        b->temporary = 0;
+        b->recycled = 0;
 
         b->shadow = NULL;
         b = next;
     }
 
-    b->in_file = 0;
-    b->temp_file = 0;
-    b->flush = 0;
-    b->zerocopy_busy = 0;
+    b->temporary = 0;
+    b->recycled = 0;
     b->last_shadow = 0;
 
     b->shadow = NULL;
diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c
index a71839a..2112461 100644
--- a/src/http/modules/ngx_http_chunked_filter.c
+++ b/src/http/modules/ngx_http_chunked_filter.c
@@ -83,10 +83,12 @@
 
         size += ngx_buf_size(cl->buf);
 
-        ngx_test_null(tl, ngx_alloc_chain_link(r->pool), NGX_ERROR);
-        tl->buf = cl->buf;
-        *ll = tl;
-        ll = &tl->next;
+        if (cl->buf->flush || ngx_buf_in_memory(cl->buf) || cl->buf->in_file) {
+            ngx_test_null(tl, ngx_alloc_chain_link(r->pool), NGX_ERROR);
+            tl->buf = cl->buf;
+            *ll = tl;
+            ll = &tl->next;
+        }
 
         if (cl->next == NULL) {
             break;
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c
index 72ccb0a..4089ffb 100644
--- a/src/http/modules/ngx_http_gzip_filter.c
+++ b/src/http/modules/ngx_http_gzip_filter.c
@@ -15,6 +15,8 @@
     ngx_flag_t           enable;
     ngx_flag_t           no_buffer;
 
+    ngx_array_t         *types;     /* array of ngx_http_gzip_type_t */
+
     ngx_bufs_t           bufs;
 
     ngx_uint_t           http_version;
@@ -27,6 +29,12 @@
 } ngx_http_gzip_conf_t;
 
 
+typedef struct {
+    ngx_str_t            name;
+    ngx_uint_t           enable;
+} ngx_http_gzip_type_t;
+
+
 #define NGX_HTTP_GZIP_PROXIED_OFF       0x0002
 #define NGX_HTTP_GZIP_PROXIED_EXPIRED   0x0004
 #define NGX_HTTP_GZIP_PROXIED_NO_CACHE  0x0008
@@ -57,10 +65,6 @@
     unsigned             flush:4;
     unsigned             redo:1;
     unsigned             done:1;
-#if 0
-    unsigned             pass:1;
-    unsigned             blocked:1;
-#endif
 
     size_t               zin;
     size_t               zout;
@@ -86,6 +90,8 @@
 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
                                       void *parent, void *child);
+static char *ngx_http_gzip_set_types(ngx_conf_t *cf, ngx_command_t *cmd,
+                                     void *conf);
 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data);
 static char *ngx_http_gzip_set_hash(ngx_conf_t *cf, void *post, void *data);
 
@@ -138,6 +144,13 @@
       offsetof(ngx_http_gzip_conf_t, bufs),
       NULL },
 
+    { ngx_string("gzip_types"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+      ngx_http_gzip_set_types,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      0,
+      NULL },
+
     { ngx_string("gzip_comp_level"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_num_slot,
@@ -211,7 +224,7 @@
     ngx_http_gzip_filter_commands,         /* module directives */
     NGX_HTTP_MODULE,                       /* module type */
     ngx_http_gzip_filter_init,             /* init module */
-    NULL                                   /* init child */
+    NULL                                   /* init process */
 };
 
 
@@ -247,15 +260,20 @@
 
 static ngx_int_t ngx_http_gzip_header_filter(ngx_http_request_t *r)
 {
+    ngx_uint_t             i, found;
     ngx_http_gzip_ctx_t   *ctx;
     ngx_http_gzip_conf_t  *conf;
+    ngx_http_gzip_type_t  *type;
 
     conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
 
     if (!conf->enable
-        || r->headers_out.status != NGX_HTTP_OK
+        || (r->headers_out.status != NGX_HTTP_OK
+            && r->headers_out.status != NGX_HTTP_FORBIDDEN
+            && r->headers_out.status != NGX_HTTP_NOT_FOUND)
         || r->header_only
         || r->http_version < conf->http_version
+        || r->headers_out.content_type == NULL
         || (r->headers_out.content_encoding
             && r->headers_out.content_encoding->value.len)
         || r->headers_in.accept_encoding == NULL
@@ -267,11 +285,21 @@
         return ngx_http_next_header_filter(r);
     }
 
-    /* TODO: "text/html" -> custom types */
-    if (r->headers_out.content_type
-        && ngx_strncasecmp(r->headers_out.content_type->value.data,
-                                                          "text/html", 9) != 0)
-    {
+
+    found = 0;
+    type = conf->types->elts;
+
+    for (i = 0; i < conf->types->nelts; i++) {
+        if (r->headers_out.content_type->value.len >= type[i].name.len
+            && ngx_strncasecmp(r->headers_out.content_type->value.data, 
+                               type[i].name.data, type[i].name.len) == 0)
+        {
+            found = 1;
+            break;
+        }
+    }
+
+    if (!found) {
         return ngx_http_next_header_filter(r);
     }
 
@@ -572,15 +600,9 @@
                     ctx->bufs++;
 
                 } else {
-#if 0
-                    ctx->blocked = 1;
-#endif
                     break;
                 }
 
-#if 0
-                ctx->blocked = 0;
-#endif
                 ctx->zstream.next_out = ctx->out_buf->pos;
                 ctx->zstream.avail_out = conf->bufs.size;
             }
@@ -646,10 +668,6 @@
                 *ctx->last_out = cl;
                 ctx->last_out = &cl->next;
 
-#if 0
-                ctx->pass = 1;
-#endif
-
                 break;
             }
 
@@ -712,9 +730,6 @@
                 ctx->zstream.avail_out = 0;
 
                 ctx->done = 1;
-#if 0
-                ctx->pass = 1;
-#endif
 
                 break;
             }
@@ -725,47 +740,10 @@
                 *ctx->last_out = cl;
                 ctx->last_out = &cl->next;
 
-#if 0
-                ctx->pass = 1;
-#endif
-
                 break;
             }
         }
 
-#if 0
-
-        /* OLD CODE */
-
-        if (ctx->out) {
-            if (ctx->pass) {
-                ctx->pass = 0;
-
-            } else if (last == NGX_AGAIN) {
-                return last;
-            }
-
-        } else if (ctx->busy->buf && ngx_buf_size(ctx->busy->buf)) {
-            if (last != NGX_NONE) {
-                return last;
-            }
-
-        } else if (ctx->blocked) {
-            if (last != NGX_NONE) {
-                return last;
-            }
-
-        } else {
-            if (last == NGX_NONE) {
-                return NGX_OK;
-            }
-
-            return last;
-        }
-#endif
-
-        /* NEW CODE */
-
         if (last == NGX_AGAIN) {
             return NGX_AGAIN;
         }
@@ -774,8 +752,6 @@
             return NGX_OK;
         }
 
-        /**/
-
         last = ngx_http_next_body_filter(r, ctx->out);
 
         /*
@@ -866,7 +842,7 @@
                               (float) ctx->zin / ctx->zout);
 #endif
 
-    /* we prefer do not use FPU */
+    /* we prefer do not use the FPU */
 
     zint = (ngx_uint_t) (ctx->zin / ctx->zout);
     zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100);
@@ -947,6 +923,8 @@
     conf->bufs.num = 0;
     conf->proxied = 0;
 
+    conf->types = NULL;
+
      */
 
     conf->enable = NGX_CONF_UNSET;
@@ -969,6 +947,8 @@
     ngx_http_gzip_conf_t *prev = parent;
     ngx_http_gzip_conf_t *conf = child;
 
+    ngx_http_gzip_type_t  *type;
+
     ngx_conf_merge_value(conf->enable, prev->enable, 0);
 
     ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
@@ -986,6 +966,77 @@
     ngx_conf_merge_value(conf->min_length, prev->min_length, 0);
     ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
 
+    if (conf->types == NULL) {
+        if (prev->types == NULL) {
+            conf->types = ngx_array_create(cf->pool, 1,
+                                           sizeof(ngx_http_gzip_type_t));
+            if (conf->types == NULL) {
+                return NGX_CONF_ERROR;
+            }
+
+            if (!(type = ngx_array_push(conf->types))) {
+                return NGX_CONF_ERROR;
+            }
+
+            type->name.len = sizeof("text/html") - 1;
+            type->name.data = (u_char *) "text/html";
+            type->enable = 1;
+
+        } else {
+            conf->types = prev->types;
+        }
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+static char *ngx_http_gzip_set_types(ngx_conf_t *cf, ngx_command_t *cmd,
+                                     void *conf)
+{
+    ngx_http_gzip_conf_t *gcf = conf;
+
+    ngx_str_t             *value;
+    ngx_uint_t             i;
+    ngx_http_gzip_type_t  *type;
+
+    if (gcf->types == NULL) {
+        gcf->types = ngx_array_create(cf->pool, 5,
+                                       sizeof(ngx_http_gzip_type_t));
+        if (gcf->types == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        if (!(type = ngx_array_push(gcf->types))) {
+            return NGX_CONF_ERROR;
+        }
+
+        type->name.len = sizeof("text/html") - 1;
+        type->name.data = (u_char *) "text/html";
+        type->enable = 1;
+    }
+
+    value = cf->args->elts;
+
+    for (i = 1; i < cf->args->nelts; i++) {
+
+        if (ngx_strcmp(value[i].data, "text/html") == 0) {
+            continue;
+        }
+
+        if (!(type = ngx_array_push(gcf->types))) {
+            return NGX_CONF_ERROR;
+        }
+
+        type->name.len = value[i].len;
+
+        if (!(type->name.data = ngx_palloc(cf->pool, type->name.len + 1))) {
+            return NGX_CONF_ERROR;
+        }
+
+        ngx_cpystrn(type->name.data, value[i].data, type->name.len + 1);
+    }
+
     return NGX_CONF_OK;
 }
 
diff --git a/src/http/modules/ngx_http_userid_filter.c b/src/http/modules/ngx_http_userid_filter.c
index 6cbad26..5f8e452 100644
--- a/src/http/modules/ngx_http_userid_filter.c
+++ b/src/http/modules/ngx_http_userid_filter.c
@@ -257,7 +257,7 @@
             src.data = start;
             dst.data = (u_char *) ctx->uid_got;
 
-            if (ngx_decode_base64(&src, &dst) == NGX_ERROR) {
+            if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
                 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                               "client sent invalid userid cookie \"%s\"",
                               cookies[i]->value.data);
@@ -358,7 +358,7 @@
     src.data = (u_char *) ctx->uid_set;
     dst.data = p;
 
-    ngx_encode_base64(&src, &dst);
+    ngx_encode_base64(&dst, &src);
 
     p += dst.len;
 
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index 3fa2e0b..f0794f3 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -29,6 +29,11 @@
 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
                                            ngx_http_proxy_upstream_conf_t *u);
 
+static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
+
+static ngx_conf_post_t  ngx_http_proxy_lowat_post =
+                                               { ngx_http_proxy_lowat_check } ;
+
 
 static ngx_conf_bitmask_t  next_upstream_masks[] = {
     { ngx_string("error"), NGX_HTTP_PROXY_FT_ERROR },
@@ -79,6 +84,13 @@
       offsetof(ngx_http_proxy_loc_conf_t, send_timeout),
       NULL },
 
+    { ngx_string("proxy_send_lowat"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_proxy_loc_conf_t, send_lowat),
+      &ngx_http_proxy_lowat_post },
+
     { ngx_string("proxy_preserve_host"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -877,6 +889,7 @@
 
     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
     conf->send_timeout = NGX_CONF_UNSET_MSEC;
+    conf->send_lowat = NGX_CONF_UNSET_SIZE;
 
     conf->preserve_host = NGX_CONF_UNSET;
     conf->set_x_real_ip = NGX_CONF_UNSET;
@@ -920,6 +933,7 @@
     ngx_conf_merge_msec_value(conf->connect_timeout,
                               prev->connect_timeout, 60000);
     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
+    ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
 
     ngx_conf_merge_value(conf->preserve_host, prev->preserve_host, 0);
     ngx_conf_merge_value(conf->set_x_real_ip, prev->set_x_real_ip, 0);
@@ -1073,17 +1087,21 @@
     value = cf->args->elts;
 
     if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) {
-        return "invalid URL prefix";
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix");
+        return NGX_CONF_ERROR;
     }
 
-    ngx_test_null(lcf->upstream,
-                  ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_upstream_conf_t)),
-                  NGX_CONF_ERROR);
+    lcf->upstream = ngx_pcalloc(cf->pool,
+                                sizeof(ngx_http_proxy_upstream_conf_t));
+    if (lcf->upstream == NULL) {
+        return NGX_CONF_ERROR;
+    }
 
     lcf->upstream->url.len = value[1].len;
     if (!(lcf->upstream->url.data = ngx_palloc(cf->pool, value[1].len + 1))) {
         return NGX_CONF_ERROR;
     }
+
     ngx_cpystrn(lcf->upstream->url.data, value[1].data, value[1].len + 1);
 
     value[1].data += 7;
@@ -1092,11 +1110,14 @@
     err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream);
 
     if (err) {
-        return err;
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, err);
+        return NGX_CONF_ERROR;
     }
 
-    ngx_test_null(host, ngx_palloc(cf->pool, lcf->upstream->host.len + 1),
-                  NGX_CONF_ERROR);
+    if (!(host = ngx_palloc(cf->pool, lcf->upstream->host.len + 1))) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1);
 
     /* AF_INET only */
@@ -1115,11 +1136,12 @@
 
         /* MP: ngx_shared_palloc() */
 
-        ngx_test_null(lcf->peers,
-                      ngx_pcalloc(cf->pool,
-                                  sizeof(ngx_peers_t)
-                                  + sizeof(ngx_peer_t) * (i - 1)),
-                      NGX_CONF_ERROR);
+        lcf->peers = ngx_pcalloc(cf->pool,
+                           sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
+
+        if (lcf->peers == NULL) {
+            return NGX_CONF_ERROR;
+        }
 
         lcf->peers->number = i;
 
@@ -1130,9 +1152,12 @@
             lcf->peers->peers[i].port = lcf->upstream->port;
 
             len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1;
-            ngx_test_null(lcf->peers->peers[i].addr_port_text.data,
-                          ngx_palloc(cf->pool, len),
-                          NGX_CONF_ERROR);
+
+            lcf->peers->peers[i].addr_port_text.data =
+                                                     ngx_palloc(cf->pool, len);
+            if (lcf->peers->peers[i].addr_port_text.data == NULL) {
+                return NGX_CONF_ERROR;
+            }
 
             len = ngx_inet_ntop(AF_INET,
                                 &lcf->peers->peers[i].addr,
@@ -1153,8 +1178,9 @@
 
         /* MP: ngx_shared_palloc() */
 
-        ngx_test_null(lcf->peers, ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)),
-                      NGX_CONF_ERROR);
+        if (!(lcf->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)))) {
+            return NGX_CONF_ERROR;
+        }
 
         lcf->peers->number = 1;
 
@@ -1165,9 +1191,11 @@
 
         len = lcf->upstream->host.len + lcf->upstream->port_text.len + 1;
 
-        ngx_test_null(lcf->peers->peers[0].addr_port_text.data,
-                      ngx_palloc(cf->pool, len + 1),
-                      NGX_CONF_ERROR);
+        lcf->peers->peers[0].addr_port_text.data =
+                                                 ngx_palloc(cf->pool, len + 1);
+        if (lcf->peers->peers[0].addr_port_text.data == NULL) {
+            return NGX_CONF_ERROR;
+        }
 
         len = lcf->upstream->host.len;
 
@@ -1278,3 +1306,34 @@
 
     return "invalid port in upstream URL";
 }
+
+
+static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
+{
+#if __FreeBSD__
+
+    ssize_t *np = data;
+
+    if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "\"proxy_send_lowat\" must be less than %d "
+                           "(sysctl net.inet.tcp.sendspace)",
+                           ngx_freebsd_net_inet_tcp_sendspace);
+
+        return NGX_CONF_ERROR;
+    }
+
+
+#else
+
+#if 0
+    ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+                       "\"proxy_send_lowat\" is not supported, ignored");
+
+    *np = 0;
+#endif
+
+#endif
+
+    return NGX_CONF_OK;
+}
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h
index 4dcc653..728259c 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.h
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.h
@@ -54,6 +54,7 @@
 
 
 typedef struct {
+    size_t                           send_lowat;
     size_t                           header_buffer_size;
     size_t                           busy_buffers_size;
     size_t                           max_temp_file_size;
diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c
index 0380012..07722fc 100644
--- a/src/http/modules/proxy/ngx_http_proxy_header.c
+++ b/src/http/modules/proxy/ngx_http_proxy_header.c
@@ -164,24 +164,26 @@
         return NGX_ERROR;
     }
 
-    /*
-     * we do not set r->headers_out.location to avoid the handling
-     * the local redirects without a host name by ngx_http_header_filter()
-     */
-
-#if 0
-    r->headers_out.location = location;
-#endif
-
     if (uc->url.len > loc->value.len
         || ngx_rstrncmp(loc->value.data, uc->url.data, uc->url.len) != 0)
     {
+
+       /*
+        * we do not set r->headers_out.location here to avoid the handling
+        * the local redirects without a host name by ngx_http_header_filter()
+        */
+
         *location = *loc;
         return NGX_OK;
     }
 
     /* TODO: proxy_reverse */
 
+    r->headers_out.location = location;
+
+    location->key.len = 0;
+    location->key.data = NULL;
+
     location->value.len = uc->location->len
                                           + (loc->value.len - uc->url.len) + 1;
     if (!(location->value.data = ngx_palloc(r->pool, location->value.len))) {
diff --git a/src/http/modules/proxy/ngx_http_proxy_parse.c b/src/http/modules/proxy/ngx_http_proxy_parse.c
index 3718ab0..c10cf49 100644
--- a/src/http/modules/proxy/ngx_http_proxy_parse.c
+++ b/src/http/modules/proxy/ngx_http_proxy_parse.c
@@ -155,6 +155,9 @@
             case ' ':
                 state = sw_status_text;
                 break;
+            case '.':                    /* IIS may send 403.1, 403.2, etc */
+                state = sw_status_text;
+                break;
             case CR:
                 state = sw_almost_done;
                 break;
diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c
index c1a8fb6..be5d69a 100644
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -115,6 +115,7 @@
 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
 {
     size_t                           len;
+    ngx_int_t                        escape;
     ngx_uint_t                       i;
     ngx_buf_t                       *b;
     ngx_chain_t                     *chain;
@@ -133,14 +134,20 @@
         len = r->method_name.len;
     }
 
+    if (r->quoted_uri) {
+        escape = 2 * ngx_escape_uri(NULL, r->uri.data + uc->location->len,
+                                    r->uri.len - uc->location->len);
+    } else {
+        escape = 0;
+    }
+
     len += uc->uri.len
-           + r->uri.len - uc->location->len
+           + r->uri.len - uc->location->len + escape
            + 1 + r->args.len                                 /* 1 is for "?" */
            + sizeof(http_version) - 1
            + sizeof(connection_close_header) - 1
            + 2;                         /* 2 is for "\r\n" at the header end */
 
-
     if (p->lcf->preserve_host && r->headers_in.host) {
         len += sizeof(host_header) - 1
                + r->headers_in.host_name_len
@@ -218,9 +225,16 @@
 
     b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len);
 
-    b->last = ngx_cpymem(b->last,
-                         r->uri.data + uc->location->len,
-                         r->uri.len - uc->location->len);
+    if (escape) {
+        ngx_escape_uri(b->last, r->uri.data + uc->location->len,
+                       r->uri.len - uc->location->len);
+        b->last += r->uri.len - uc->location->len + escape;
+
+    } else {
+        b->last = ngx_cpymem(b->last,
+                             r->uri.data + uc->location->len,
+                             r->uri.len - uc->location->len);
+    }
 
     if (r->args.len > 0) {
         *(b->last++) = '?';
@@ -422,7 +436,7 @@
 
     p->upstream->output_chain_ctx = output;
 
-    output->sendfile = r->sendfile;
+    output->sendfile = r->connection->sendfile;
     output->pool = r->pool;
     output->bufs.num = 1;
     output->tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
@@ -737,8 +751,7 @@
     if (rc == NGX_AGAIN) {
         ngx_add_timer(c->write, p->lcf->send_timeout);
 
-        c->write->available = /* STUB: lowat */ 0;
-        if (ngx_handle_write_event(c->write, NGX_LOWAT_EVENT) == NGX_ERROR) {
+        if (ngx_handle_write_event(c->write, p->lcf->send_lowat) == NGX_ERROR) {
             ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
             return;
         }
@@ -1172,6 +1185,7 @@
     r = p->request;
 
     r->headers_out.status = p->upstream->status;
+    r->headers_out.status_line = p->upstream->status_line;
 
 #if 0
     r->headers_out.content_length_n = -1;
@@ -1298,11 +1312,10 @@
          */
 
         ep->cyclic_temp_file = 1;
-        r->sendfile = 0;
+        r->connection->sendfile = 0;
 
     } else {
         ep->cyclic_temp_file = 0;
-        r->sendfile = 1;
     }
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
diff --git a/src/http/ngx_http_copy_filter.c b/src/http/ngx_http_copy_filter.c
index d015c21..10c574f 100644
--- a/src/http/ngx_http_copy_filter.c
+++ b/src/http/ngx_http_copy_filter.c
@@ -79,7 +79,7 @@
         ngx_http_create_ctx(r, ctx, ngx_http_copy_filter_module,
                             sizeof(ngx_output_chain_ctx_t), NGX_ERROR);
 
-        ctx->sendfile = r->sendfile;
+        ctx->sendfile = r->connection->sendfile;
         ctx->need_in_memory = r->filter_need_in_memory;
         ctx->need_in_temp = r->filter_need_temporary;
 
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 6df6edf..58021e8 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -204,6 +204,13 @@
       offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
       NULL },
 
+    { ngx_string("tcp_nodelay"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
+      NULL },
+
     { ngx_string("send_timeout"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
@@ -505,11 +512,11 @@
         r->connection->log->log_level = clcf->err_log->log_level;
     }
 
-    if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
-        r->sendfile = 0;
+    if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
+        r->connection->sendfile = 1;
 
     } else {
-        r->sendfile = 1;
+        r->connection->sendfile = 0;
     }
 
     if (!clcf->tcp_nopush) {
@@ -1387,6 +1394,7 @@
     lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
     lcf->sendfile = NGX_CONF_UNSET;
     lcf->tcp_nopush = NGX_CONF_UNSET;
+    lcf->tcp_nodelay = NGX_CONF_UNSET;
     lcf->send_timeout = NGX_CONF_UNSET_MSEC;
     lcf->send_lowat = NGX_CONF_UNSET_SIZE;
     lcf->postpone_output = NGX_CONF_UNSET_SIZE;
@@ -1477,6 +1485,7 @@
                               prev->client_body_timeout, 60000);
     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
+    ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 0);
     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
@@ -1795,10 +1804,10 @@
 
 static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data)
 {
-#if (HAVE_LOWAT_EVENT)
-
     ssize_t *np = data;
 
+#if __FreeBSD__
+
     if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "\"send_lowat\" must be less than %d "
@@ -1808,11 +1817,13 @@
         return NGX_CONF_ERROR;
     }
 
-#else
+#elif !(HAVE_SO_SNDLOWAT)
 
     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                        "\"send_lowat\" is not supported, ignored");
 
+    *np = 0;
+
 #endif
 
     return NGX_CONF_OK;
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 7468db5..787f8b8 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -172,6 +172,7 @@
 
     ngx_flag_t    sendfile;                /* sendfile */
     ngx_flag_t    tcp_nopush;              /* tcp_nopush */
+    ngx_flag_t    tcp_nodelay;             /* tcp_nodelay */
     ngx_flag_t    reset_timedout_connection; /* reset_timedout_connection */
     ngx_flag_t    msie_padding;            /* msie_padding */
 
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index 9876a05..5b7f3eb 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -150,6 +150,7 @@
     len = sizeof("HTTP/1.x ") - 1 + 2 + 2;
 
     /* status line */
+
     if (r->headers_out.status_line.len) {
         len += r->headers_out.status_line.len;
 #if (NGX_SUPPRESS_WARN)
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index ba77ffb..e70a6ea 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -217,10 +217,13 @@
                 state = sw_http_09;
                 break;
             case '.':
-            case '%':
                 r->complex_uri = 1;
                 state = sw_uri;
                 break;
+            case '%':
+                r->quoted_uri = 1;
+                state = sw_uri;
+                break;
             case '/':
                 r->complex_uri = 1;
                 break;
@@ -259,7 +262,7 @@
                 state = sw_after_slash_in_uri;
                 break;
             case '%':
-                r->complex_uri = 1;
+                r->quoted_uri = 1;
                 state = sw_uri;
                 break;
             case '?':
@@ -522,7 +525,7 @@
                 break;
             }
 
-            /* IIS can send duplicate "HTTP/1.1 ..." lines */
+            /* IIS may send the duplicate "HTTP/1.1 ..." lines */
             if (ch == '/'
                 && r->proxy
                 && p - r->header_start == 5
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index e889449..6069847 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -550,7 +550,7 @@
                 return;
             }
 
-            if (r->complex_uri) {
+            if (r->complex_uri || r->quoted_uri) {
                 rc = ngx_http_parse_complex_uri(r);
 
                 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
@@ -1318,8 +1318,7 @@
         ngx_add_timer(wev, clcf->send_timeout);
     }
 
-    wev->available = clcf->send_lowat;
-    if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+    if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
         ngx_http_close_request(r, 0);
         ngx_http_close_connection(r->connection);
     }
@@ -1354,9 +1353,7 @@
                                                 ngx_http_core_module);
             ngx_add_timer(wev, clcf->send_timeout);
 
-            wev->available = clcf->send_lowat;
-
-            if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+            if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
                 ngx_http_close_request(r, 0);
                 ngx_http_close_connection(r->connection);
             }
@@ -1371,9 +1368,8 @@
 
             clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
                                                 ngx_http_core_module);
-            wev->available = clcf->send_lowat;
 
-            if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+            if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
                 ngx_http_close_request(r, 0);
                 ngx_http_close_connection(r->connection);
             }
@@ -1394,9 +1390,7 @@
             ngx_add_timer(wev, clcf->send_timeout);
         }
 
-        wev->available = clcf->send_lowat;
-
-        if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+        if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
             ngx_http_close_request(r, 0);
             ngx_http_close_connection(r->connection);
         }
@@ -1541,6 +1535,7 @@
 
 static void ngx_http_set_keepalive(ngx_http_request_t *r)
 {
+    int                        tcp_nodelay;
     ngx_int_t                  i;
     ngx_buf_t                 *b, *f;
     ngx_event_t               *rev, *wev;
@@ -1684,7 +1679,26 @@
             ngx_http_close_connection(c);
             return;
         }
+
         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+
+    } else {
+        if (clcf->tcp_nodelay && !c->tcp_nodelay) {
+            tcp_nodelay = 1;
+
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+            if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+                               (const void *) &tcp_nodelay, sizeof(int)) == -1)
+            {
+                ngx_connection_error(c, ngx_socket_errno,
+                                     "setsockopt(TCP_NODELAY) failed");
+                ngx_http_close_connection(c);
+                return;
+            }
+
+            c->tcp_nodelay = 1;
+        }
     }
 
 #if 0
@@ -2055,6 +2069,18 @@
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "close http connection: %d", c->fd);
 
+#if (NGX_OPENSSL)
+
+    if (c->ssl) {
+        if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
+            c->read->event_handler = ngx_ssl_close_handler;
+            c->write->event_handler = ngx_ssl_close_handler;
+            return;
+        }
+    }
+
+#endif
+
 #if (NGX_STAT_STUB)
     (*ngx_stat_active)--;
 #endif
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index ef169f5..022b8a8 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -307,8 +307,10 @@
     /* URI is not started with '/' - "GET http://" */
     unsigned             unusual_uri:1;
 #endif
-    /* URI with "/.", "%" and on Win32 with "//" */
+    /* URI with "/." and on Win32 with "//" */
     unsigned             complex_uri:1;
+    /* URI with "%" */
+    unsigned             quoted_uri:1;
     unsigned             header_timeout_set:1;
 
     unsigned             proxy:1;
@@ -320,9 +322,6 @@
 #endif
     unsigned             pipeline:1;
 
-    /* can we use sendfile ? */
-    unsigned             sendfile:1;
-
     unsigned             plain_http:1;
     unsigned             chunked:1;
     unsigned             header_only:1;
diff --git a/src/imap/ngx_imap_proxy.c b/src/imap/ngx_imap_proxy.c
index 8cd9d0b..d846b0b 100644
--- a/src/imap/ngx_imap_proxy.c
+++ b/src/imap/ngx_imap_proxy.c
@@ -333,8 +333,7 @@
                 }
 
                 if (n == NGX_AGAIN || n < (ssize_t) size) {
-                    dst->write->available = 0;
-                    if (ngx_handle_write_event(dst->write, NGX_LOWAT_EVENT)
+                    if (ngx_handle_write_event(dst->write, /* TODO: LOWAT */ 0)
                                                                   == NGX_ERROR)
                     {
                         ngx_imap_proxy_close_session(s);
diff --git a/src/os/unix/ngx_errno.c b/src/os/unix/ngx_errno.c
index 0d03fa9..2faf63a 100644
--- a/src/os/unix/ngx_errno.c
+++ b/src/os/unix/ngx_errno.c
@@ -49,7 +49,8 @@
     str = strerror_r(err, errstr, size);
 
     if (str != errstr) {
-        return ngx_cpystrn(errstr, str, size) - (u_char *) errstr;
+        return ngx_cpystrn((u_char *) errstr, (u_char *) str, size)
+                                                           - (u_char *) errstr;
     }
 
     for (len = 0; len < size; len++) {
diff --git a/src/os/unix/ngx_freebsd.h b/src/os/unix/ngx_freebsd.h
index 9c89105..7a1e203 100644
--- a/src/os/unix/ngx_freebsd.h
+++ b/src/os/unix/ngx_freebsd.h
@@ -11,7 +11,6 @@
 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
                                         off_t limit);
 
-
 extern int ngx_freebsd_kern_osreldate;
 extern int ngx_freebsd_hw_ncpu;
 extern int ngx_freebsd_net_inet_tcp_sendspace;
diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h
index f4616db..7961a3b 100644
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -34,13 +34,13 @@
 
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>        /* TCP_NODELAY, TCP_NOPUSH */
 #include <arpa/inet.h>
 #include <netdb.h>
 
 #include <libutil.h>            /* setproctitle() before 4.1 */
 #include <osreldate.h>
 #include <sys/sysctl.h>
-#include <netinet/tcp.h>        /* TCP_NOPUSH */
 
 
 #if __FreeBSD_version < 400017
diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c
index dcf432b..39a057b 100644
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -193,6 +193,7 @@
         ngx_ncpu = ngx_freebsd_hw_ncpu;
     }
 
+
     return ngx_posix_init(log);
 }
 
@@ -221,5 +222,6 @@
         }
     }
 
+
     ngx_posix_status(log);
 }
diff --git a/src/os/unix/ngx_linux.h b/src/os/unix/ngx_linux.h
index 24034c0..4a8f8f3 100644
--- a/src/os/unix/ngx_linux.h
+++ b/src/os/unix/ngx_linux.h
@@ -8,6 +8,9 @@
 #define _NGX_LINUX_H_INCLUDED_
 
 
+ngx_int_t  ngx_init_setproctitle(ngx_log_t *log);
+void ngx_setproctitle(char *title);
+
 ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
                                       off_t limit);
 
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
index 2b23702..11427d3 100644
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -39,13 +39,13 @@
 
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>        /* TCP_NODELAY, TCP_CORK */
 #include <arpa/inet.h>
 #include <netdb.h>
 
 #include <time.h>               /* tzset() */
 #include <sys/ioctl.h>
 #include <sys/sysctl.h>
-#include <netinet/tcp.h>        /* TCP_CORK */
 
 
 #include <ngx_auto_config.h>
@@ -94,8 +94,10 @@
 #define HAVE_SELECT_CHANGE_TIMEOUT   1
 #endif
 
-
-#define ngx_setproctitle(title)
+#ifndef NGX_SETPROCTITLE_USES_ENV
+#define NGX_SETPROCTITLE_USES_ENV    1
+#define NGX_SETPROCTITLE_PAD         '\0' 
+#endif
 
 
 #endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_linux_init.c b/src/os/unix/ngx_linux_init.c
index 4946e15..3c7d344 100644
--- a/src/os/unix/ngx_linux_init.c
+++ b/src/os/unix/ngx_linux_init.c
@@ -30,7 +30,8 @@
 
 ngx_int_t ngx_os_init(ngx_log_t *log)
 {
-    int  name[2], len;
+    int     name[2];
+    size_t  len;
 
     name[0] = CTL_KERN;
     name[1] = KERN_OSTYPE;
@@ -63,6 +64,8 @@
 
     }
 
+    ngx_init_setproctitle(log);
+
 
     return ngx_posix_init(log);
 }
@@ -76,5 +79,6 @@
     ngx_log_error(NGX_LOG_INFO, log, 0, "sysctl(KERN_RTSIGMAX): %d",
                   ngx_linux_rtsig_max);
 
+
     ngx_posix_status(log);
 }
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index dba949c..aff242c 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -12,10 +12,15 @@
 
 static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
 
-ngx_int_t      ngx_process_slot;
-ngx_socket_t   ngx_channel;
-ngx_int_t      ngx_last_process;
-ngx_process_t  ngx_processes[NGX_MAX_PROCESSES];
+
+int              ngx_argc;
+char           **ngx_argv;
+char           **ngx_os_argv;
+
+ngx_int_t        ngx_process_slot;
+ngx_socket_t     ngx_channel;
+ngx_int_t        ngx_last_process;
+ngx_process_t    ngx_processes[NGX_MAX_PROCESSES];
 
 
 ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle,
@@ -231,8 +236,23 @@
                 return;
             }
 
+#if (SOLARIS)
+
+            /*
+             * Solaris always calls the signal handler for each exited process
+             * despite waitpid() may be already called for this process
+             */
+
+            if (err == NGX_ECHILD) {
+                ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno,
+                              "waitpid() failed");
+            }
+
+#endif
+
             ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno,
                           "waitpid() failed");
+
             return;
         }
 
diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h
index 816b6a6..0cea302 100644
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -56,6 +56,9 @@
 
 #define ngx_sched_yield()  sched_yield()
 
+extern int            ngx_argc;
+extern char         **ngx_argv;
+extern char         **ngx_os_argv;
 
 extern ngx_pid_t      ngx_pid;
 extern ngx_socket_t   ngx_channel;
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 4d4db54..c43a7eb 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -14,7 +14,7 @@
                                        ngx_int_t type);
 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
 static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle);
-static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
+static void ngx_master_exit(ngx_cycle_t *cycle);
 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
 static void ngx_channel_handler(ngx_event_t *ev);
 #if (NGX_THREADS)
@@ -55,7 +55,7 @@
 u_char  master_process[] = "master process";
 
 
-void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
+void ngx_master_process_cycle(ngx_cycle_t *cycle)
 {
     char              *title;
     u_char            *p;
@@ -90,16 +90,16 @@
 
     size = sizeof(master_process);
 
-    for (i = 0; i < ctx->argc; i++) {
-        size += ngx_strlen(ctx->argv[i]) + 1;
+    for (i = 0; i < ngx_argc; i++) {
+        size += ngx_strlen(ngx_argv[i]) + 1;
     }
 
     title = ngx_palloc(cycle->pool, size);
 
     p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
-    for (i = 0; i < ctx->argc; i++) {
+    for (i = 0; i < ngx_argc; i++) {
         *p++ = ' ';
-        p = ngx_cpystrn(p, (u_char *) ctx->argv[i], size);
+        p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
     }
 
     ngx_setproctitle(title);
@@ -149,7 +149,7 @@
         }
 
         if (!live && (ngx_terminate || ngx_quit)) {
-            ngx_master_exit(cycle, ctx);
+            ngx_master_exit(cycle);
         }
 
         if (ngx_terminate) {
@@ -231,7 +231,7 @@
         if (ngx_change_binary) {
             ngx_change_binary = 0;
             ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "changing binary");
-            ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv);
+            ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
         }
 
         if (ngx_noaccept) {
@@ -244,14 +244,10 @@
 }
 
 
-void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
+void ngx_single_process_cycle(ngx_cycle_t *cycle)
 {
     ngx_uint_t  i;
 
-#if 0
-    ngx_setproctitle("single worker process");
-#endif
-
     ngx_init_temp_number();
 
     for (i = 0; ngx_modules[i]; i++) {
@@ -269,7 +265,7 @@
         ngx_process_events(cycle);
 
         if (ngx_terminate || ngx_quit) {
-            ngx_master_exit(cycle, ctx);
+            ngx_master_exit(cycle);
         }
 
         if (ngx_reconfigure) {
@@ -547,7 +543,7 @@
 }
 
 
-static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
+static void ngx_master_exit(ngx_cycle_t *cycle)
 {
     ngx_delete_pidfile(cycle);
 
diff --git a/src/os/unix/ngx_process_cycle.h b/src/os/unix/ngx_process_cycle.h
index 71aa178..16b981f 100644
--- a/src/os/unix/ngx_process_cycle.h
+++ b/src/os/unix/ngx_process_cycle.h
@@ -19,19 +19,13 @@
 #define NGX_CMD_REOPEN         5
 
 
-typedef struct {
-    int           argc;
-    char *const  *argv;
-} ngx_master_ctx_t;
-
-
 #define NGX_PROCESS_SINGLE   0
 #define NGX_PROCESS_MASTER   1
 #define NGX_PROCESS_WORKER   2
 
 
-void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
-void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
+void ngx_master_process_cycle(ngx_cycle_t *cycle);
+void ngx_single_process_cycle(ngx_cycle_t *cycle);
 
 
 extern ngx_uint_t      ngx_process;
diff --git a/src/os/unix/ngx_setproctitle.c b/src/os/unix/ngx_setproctitle.c
new file mode 100644
index 0000000..6ac8707
--- /dev/null
+++ b/src/os/unix/ngx_setproctitle.c
@@ -0,0 +1,143 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_SETPROCTITLE_USES_ENV)
+
+/*
+ * To change the process title in Linux and Solaris we have to set argv[1]
+ * to NULL and to copy the title to the same place where the argv[0] points to.
+ * However, argv[0] may be too small to hold a new title.  Fortunately, Linux
+ * and Solaris store argv[] and environ[] one after another.  So we should
+ * ensure that is the continuous memory and then we allocate the new memory
+ * for environ[] and copy it.  After this we could use the memory starting
+ * from argv[0] for our process title.
+ *
+ * The Solaris's standard /bin/ps does not show the changed process title.
+ * You have to use "/usr/ucb/ps -w" instead.  Besides, the UCB ps dos not
+ * show a new title if its length less than the origin command line length.
+ * To avoid it we append to a new title the origin command line in the
+ * parenthesis.
+ */
+
+extern char **environ;
+
+static char *ngx_os_argv_last;
+
+ngx_int_t  ngx_init_setproctitle(ngx_log_t *log)
+{
+    char        *p;
+    size_t       size;
+    ngx_uint_t   i;
+
+    size = 0;
+
+    for (i = 0; environ[i]; i++) {
+        size += ngx_strlen(environ[i]) + 1;
+    }
+
+    if (!(p = ngx_alloc(size, log))) {
+        return NGX_ERROR;
+    }
+
+    ngx_os_argv_last = ngx_os_argv[0];
+
+    for (i = 0; ngx_os_argv[i]; i++) {
+        if (ngx_os_argv_last == ngx_os_argv[i]) {
+            ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1;
+        }
+    }
+
+    for (i = 0; environ[i]; i++) {
+        if (ngx_os_argv_last == environ[i]) {
+
+            size = ngx_strlen(environ[i]) + 1;
+            ngx_os_argv_last = environ[i] + size;
+
+            ngx_cpystrn(p, environ[i], size);
+            environ[i] = p;
+            p += size;
+        }
+    }
+
+    ngx_os_argv_last--;
+
+    return NGX_OK;
+}
+
+
+void ngx_setproctitle(char *title)
+{
+    u_char     *p;
+
+#if (SOLARIS)
+
+    ngx_int_t   i;
+    size_t      size;
+
+#endif
+
+    ngx_os_argv[1] = NULL;
+
+    p = ngx_cpystrn((u_char *) ngx_os_argv[0], "nginx: ",
+                    ngx_os_argv_last - ngx_os_argv[0]);
+
+    p = ngx_cpystrn(p, (u_char *) title, ngx_os_argv_last - (char *) p);
+
+#if (SOLARIS)
+
+    size = 0;
+
+    for (i = 0; i < ngx_argc; i++) {
+        size += ngx_strlen(ngx_argv[i]) + 1;
+    }
+
+    if (size > (size_t) ((char *) p - ngx_os_argv[0])) {
+
+        /*
+         * ngx_setproctitle() is too rare operation so we use
+         * the non-optimized copies
+         */
+
+        p = ngx_cpystrn(p, (u_char *) " (", ngx_os_argv_last - (char *) p);
+
+        for (i = 0; i < ngx_argc; i++) {
+            p = ngx_cpystrn(p, (u_char *) ngx_argv[i],
+                            ngx_os_argv_last - (char *) p);
+            p = ngx_cpystrn(p, (u_char *) " ", ngx_os_argv_last - (char *) p);
+        }
+
+        if (*(p - 1) == ' ') {
+            *(p - 1) = ')';
+        }
+    }
+
+#endif
+
+    if (ngx_os_argv_last - (char *) p) {
+        ngx_memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - (char *) p);
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
+                   "setproctitle: \"%s\"", ngx_os_argv[0]);
+}
+
+
+#elif !defined(ngx_setproctitle)
+
+ngx_int_t  ngx_init_setproctitle(ngx_log_t *log)
+{
+    return NGX_OK;
+}
+
+void ngx_setproctitle(char *title)
+{
+}
+
+#endif
diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c
index f97ab41..3e188bd 100644
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -16,7 +16,7 @@
  * ioctl() and fcntl() are syscalls on at least FreeBSD 2.x, Linux 2.2
  * and Solaris 7.
  *
- * ioctl() in Linux 2.4 and 2.6 uses BKL, however fcntl(F_SETFL) uses it too.
+ * ioctl() in Linux 2.4 and 2.6 uses BKL, however, fcntl(F_SETFL) uses it too.
  */
 
 
diff --git a/src/os/unix/ngx_solaris.h b/src/os/unix/ngx_solaris.h
index 36f3cb9..705cd57 100644
--- a/src/os/unix/ngx_solaris.h
+++ b/src/os/unix/ngx_solaris.h
@@ -8,6 +8,10 @@
 #define _NGX_SOLARIS_H_INCLUDED_
 
 
+ngx_int_t  ngx_init_setproctitle(ngx_log_t *log);
+void ngx_setproctitle(char *title);
+
+
 ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
                                          off_t limit);
 
diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h
index 6cbfcc2..96c119c 100644
--- a/src/os/unix/ngx_solaris_config.h
+++ b/src/os/unix/ngx_solaris_config.h
@@ -40,10 +40,10 @@
 
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>        /* TCP_NODELAY */
 #include <arpa/inet.h>
 #include <netdb.h>
 
-#include <sys/sendfile.h>
 #include <sys/systeminfo.h>
 #include <limits.h>             /* IOV_MAX */
 #include <inttypes.h>
@@ -64,6 +64,11 @@
 #endif
 
 
+#if (HAVE_SENDFILE)
+#include <sys/sendfile.h>
+#endif
+
+
 #if (HAVE_AIO)
 #include <aio.h>
 #endif
@@ -80,7 +85,16 @@
 #endif
 
 
-#define ngx_setproctitle(title)
+#ifndef HAVE_SO_SNDLOWAT
+/* setsockopt(SO_SNDLOWAT) returns error "Option not supported by protocol" */
+#define HAVE_SO_SNDLOWAT         0
+#endif
+
+
+#ifndef NGX_SETPROCTITLE_USES_ENV
+#define NGX_SETPROCTITLE_USES_ENV  1
+#define NGX_SETPROCTITLE_PAD       ' '
+#endif
 
 
 #endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_solaris_init.c b/src/os/unix/ngx_solaris_init.c
index a743ab5..c671197 100644
--- a/src/os/unix/ngx_solaris_init.c
+++ b/src/os/unix/ngx_solaris_init.c
@@ -53,6 +53,9 @@
         return NGX_ERROR;
     }
 
+    ngx_init_setproctitle(log);
+
+
     return ngx_posix_init(log);
 }
 
diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c
index a060dac..9430dc0 100644
--- a/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -32,6 +32,10 @@
         return in;
     }
 
+    if (!c->sendfile) {
+        return ngx_writev_chain(c, in, limit);
+    }
+
     send = 0;
     complete = 0;
 
diff --git a/src/os/win32/ngx_process.c b/src/os/win32/ngx_process.c
index 7ec46f6..062c41c 100644
--- a/src/os/win32/ngx_process.c
+++ b/src/os/win32/ngx_process.c
@@ -8,6 +8,11 @@
 #include <ngx_core.h>
 
 
+int            ngx_argc;
+char         **ngx_argv;
+char         **ngx_os_argv;
+
+
 ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
 {
     return /* STUB */ 0;
diff --git a/src/os/win32/ngx_process.h b/src/os/win32/ngx_process.h
index 402f31f..b9b4aeb 100644
--- a/src/os/win32/ngx_process.h
+++ b/src/os/win32/ngx_process.h
@@ -32,8 +32,11 @@
 #define ngx_sched_yield()  Sleep(0)
 
 
+extern int            ngx_argc;
+extern char         **ngx_argv;
+extern char         **ngx_os_argv;
 
-extern ngx_pid_t     ngx_pid;
+extern ngx_pid_t      ngx_pid;
 
 
 #endif /* _NGX_PROCESS_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c
index d597174..843c311 100644
--- a/src/os/win32/ngx_process_cycle.c
+++ b/src/os/win32/ngx_process_cycle.c
@@ -38,7 +38,7 @@
 
 
 
-void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
+void ngx_master_process_cycle(ngx_cycle_t *cycle)
 {
     ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "master mode is not supported");
 
@@ -46,7 +46,7 @@
 }
 
 
-void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
+void ngx_single_process_cycle(ngx_cycle_t *cycle)
 {
     ngx_int_t  i;
 
diff --git a/src/os/win32/ngx_process_cycle.h b/src/os/win32/ngx_process_cycle.h
index 10d6850..e80af0a 100644
--- a/src/os/win32/ngx_process_cycle.h
+++ b/src/os/win32/ngx_process_cycle.h
@@ -12,21 +12,13 @@
 #include <ngx_core.h>
 
 
-typedef struct {
-     ngx_file_t    pid;
-     u_char       *name;
-     int           argc;
-     char *const  *argv;
-} ngx_master_ctx_t;
-
-
 #define NGX_PROCESS_SINGLE   0
 #define NGX_PROCESS_MASTER   1
 #define NGX_PROCESS_WORKER   2
 
 
-void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
-void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
+void ngx_master_process_cycle(ngx_cycle_t *cycle);
+void ngx_single_process_cycle(ngx_cycle_t *cycle);
 
 
 extern ngx_uint_t      ngx_process;