accompanying ap_version_t structure (minor MMN bump).
[André Malo]
+ *) worker mpm: don't take down the whole server for a transient
+ thread creation failure. PR 34514 [Greg Ames]
+
+ *) mod_rewrite: use buffered I/O to improve performance with large
+ RewriteMap txt: files. [Greg Ames]
+
+ *) proxy HTTP: Rework the handling of request bodies to handle
+ chunked input and input filters which modify content length, and
+ avoid spooling arbitrary-sized request bodies in memory.
+ PR 15859. [Jeff Trawick]
+
Changes with Apache 2.0.54
*) mod_cache: Add CacheIgnoreHeaders directive. PR 30399.
*) Prevent hang writing to piped logger at graceful restart time.
PR: 26467
http://svn.apache.org/viewcvs?rev=170281&view=rev
+ http://svn.apache.org/viewcvs.cgi?rev=171093&view=rev
+1: trawick, jorton
-0: pquerna: This adds a new public function. It should be either a
minor MMN bump, or be put under CORE_PRIVATE.
+ trawick: I resolved this via second commit above. Thanks!
*) Fix fd leak in piped logging code, fix error handling, and remove
dead errno handling.
have already. *shrug* Regardless, patch looks okay...
+1: nd, jerenkrantz
- * Rewrite how proxy sends its request to allow input bodies to
- morph the request bodies. Previously, if an input filter
- changed the request body, the original C-L would be sent which
- would be incorrect.
-
- Due to HTTP compliance, we must either send the body T-E: chunked
- or include a C-L for the request body. Connection: Close is not
- an option.
-
- A newer version of this fix that acts even better (spools to disk) has
- been committed to trunk. The equivalent patch for 2.0.x is at:
- http://www.apache.org/~trawick/20reqbody.txt
-
- +1: trawick, jerenkrantz, +1
- Previous votes (before trawick's recent 2.1 commits):
- +1: stoddard, striker, jim
- -1: brianp (we need a more robust solution than what's in 2.1 right now),
-
* support/check_forensic: Fix tempfile usage
svn rev 125495, 126224
jerenkrantz says: r126224 fixes brokenness with r125495 on Solaris.
* mod_version: New Module, Backport from trunk. Requires Minor MMN Bump.
http://svn.apache.org/repos/asf/httpd/httpd/branches/mod_version_for_2.0.x
- +1: pquerna
+ +1: pquerna, nd
Votes from before the integration branch:
+1: jerenkrantz, wrowe (trivial, would even be cool in 1.3)
*) mod_userdir: fix to palloc(sizeof struct) not palloc(sizeof pointer)
http://svn.apache.org/viewcvs?rev=165151&view=rev
PR: 34588
- +1: jorton, trawick (isn't it worth a CHANGES entry for a storage
+ +1: jorton, bnicholes, trawick (isn't it worth a CHANGES entry for a storage
corruption fix?)
-
- *) mod_ldap: Change the LDAP connection timeout to per-connection rather
- than global. Fixes PR: 34618
- http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ldap/util_ldap.c?rev=164919&r1=164918&r2=164919&view=diff
- or 2.0 view patch
- http://issues.apache.org/bugzilla/attachment.cgi?id=14873
- +1: bnicholes, minfrin, pquerna
-
- *) Have configure refuse to build with doomed combinations of
- internal/external APR/APR-util.
- http://svn.apache.org/viewcvs?rev=170029&view=rev
- +1: jorton, nd, trawick, pquerna
+ *) fix z/OS annoyance with pathname on debug messages in error log
+ http://svn.apache.org/viewcvs?rev=178299&view=rev
+ +1: trawick
+
+ *) EBCDIC: Handle chunked input from client or, with proxy, origin
+ server.
+ http://svn.apache.org/viewcvs?rev=178262&view=rev
+ (With 2.0.x it is the same code in the same function, but in
+ a different source file.)
+ +1: trawick
+
+ *) Support the suppress-error-charset setting, as with Apache 1.3.x.
+ PR 31274. (current docs say it works with Apache from 2.0.40 ;) )
+ http://svn.apache.org/viewcvs?rev=170354&view=rev
+ +1: trawick
PATCHES TO BACKPORT THAT ARE ON HOLD OR NOT GOING ANYWHERE SOON:
AC_MSG_ERROR([APR-util not found. Please read the documentation.])
fi
+# Catch some misconfigurations:
+case ${apr_found}.${apu_found} in
+reconfig.yes)
+ AC_MSG_ERROR([Cannot use an external APR-util with the bundled APR])
+ ;;
+yes.reconfig)
+ AC_MSG_ERROR([Cannot use an external APR with the bundled APR-util])
+ ;;
+esac
+
if test "$apu_found" = "reconfig"; then
APR_SUBDIR_CONFIG(srclib/apr-util,
[--with-apr=../apr --prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir],
# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
-# ErrorDocument 406 /error/HTTP_NOT_ACCEPTABLE.html.var
# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
# ErrorDocument 410 /error/HTTP_GONE.html.var
# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
+++ /dev/null
-Content-language: cs
-Content-type: text/html; charset=ISO-8859-2
-Body:----------cs--
-<!--#set var="CONTENT_LANGUAGE" value="cs"
---><!--#set var="CHARACTER_ENCODING" value="ISO-8859-2"
---><!--#set var="TITLE" value="Nenalezen ¾ádný akceptovatelný objekt!"
---><!--#include virtual="include/top.html" -->
-
- Adekvátní reprezentace po¾adoveného zdroje
- nebyla na tomto serveru nalezena.
-
-<!--#include virtual="include/bottom.html" -->
-----------cs--
-
-Content-language: de
-Content-type: text/html; charset=ISO-8859-1
-Body:----------de--
-<!--#set var="CONTENT_LANGUAGE" value="de"
---><!--#set var="TITLE" value="Kein passendes Objekt gefunden!"
---><!--#include virtual="include/top.html" -->
-
- Unter dem angeforderten URL konnte kein geeignetes Objekt
- auf dem Server gefunden werden, das dem vom Browser
- geforderten Format entsprechen würde.
-
-<!--#include virtual="include/bottom.html" -->
-----------de--
-
-Content-language: en
-Content-type: text/html; charset=ISO-8859-1
-Body:----------en--
-<!--#set var="TITLE" value="No acceptable object found!"
---><!--#include virtual="include/top.html" -->
-
- An appropriate representation of the requested resource
- could not be found on this server.
-
-<!--#include virtual="include/bottom.html" -->
-----------en--
-
-Content-language: es
-Content-type: text/html; charset=ISO-8859-1
-Body:----------es--
-<!--#set var="CONTENT_LANGUAGE" value="es"
---><!--#set var="TITLE" value="¡No se encontró ningú objeto aceptable!"
---><!--#include virtual="include/top.html" -->
-
- Una representación apropiada de los recursos
- solicitados no ha podido ser localizada en
- este servidor.
-
-<!--#include virtual="include/bottom.html" -->
-----------es--
-
-Content-language: fr
-Content-type: text/html; charset=ISO-8859-1
-Body:----------fr--
-<!--#set var="CONTENT_LANGUAGE" value="fr"
---><!--#set var="TITLE" value="L'objet trouvé n'est pas acceptable!"
---><!--#include virtual="include/top.html" -->
-
- Une représentation appropriée de la ressource requise
- n'a pu être trouvée sur ce serveur.
-
-<!--#include virtual="include/bottom.html" -->
-----------fr--
-
-Content-language: it
-Content-type: text/html; charset=ISO-8859-1
-Body:----------it--
-<!--#set var="CONTENT_LANGUAGE" value="it"
---><!--#set var="TITLE" value="Nessun oggetto accettabile!"
---><!--#include virtual="include/top.html" -->
-
- Questo server non riesce a trovare una rappresentazione
- appropriata per la risorsa richiesta.
-
-<!--#include virtual="include/bottom.html" -->
-----------it--
-
-Content-language: ja
-Content-type: text/html; charset=ISO-2022-JP
-Body:----------ja--
-<!--#set var="CONTENT_LANGUAGE" value="ja"
---><!--#set var="CHARACTER_ENCODING" value="iso-2022-jp"
---><!--#set var="TITLE" value="No acceptable object found!"
---><!--#include virtual="include/top.html" -->
-
- \e$BMW5a$5$l$?%j%=!<%9$NE,@Z$JI=8=$O!"\e(B
- \e$BK\%5!<%P$K$O8+$D$+$j$^$;$s$G$7$?!#\e(B
-
-<!--#include virtual="include/bottom.html" -->
-----------ja--
-
-Content-language: ko
-Content-type: text/html; charset=EUC-KR
-Body:----------ko--
-<!--#set var="CONTENT_LANGUAGE" value="ko"
---><!--#set var="TITLE" value="Àû´çÇÑ °´Ã¼ ¾øÀ½!"
---><!--#set var="CHARACTER_ENCODING" value="EUC-KR"
---><!--#include virtual="include/top.html" -->
-
- ¿äûÇÑ °´Ã¼ÀÇ Àû´çÇÑ ÇüŸ¦ ÀÌ ¼¹ö¿¡¼ ãÀ» ¼ö ¾ø½À´Ï´Ù.
-
-<!--#include virtual="include/bottom.html" -->
-----------ko--
-
-Content-language: nl
-Content-type: text/html; charset=ISO-8859-1
-Body:----------nl--
-<!--#set var="CONTENT_LANGUAGE" value="nl"
---><!--#set var="TITLE" value="Geen acceptabel object gevonden!"
---><!--#include virtual="include/top.html" -->
-
- Een toereikende representatie van het gevraagde object
- kon niet gevonden worden op deze server.
-
-<!--#include virtual="include/bottom.html" -->
-----------nl--
-
-Content-language: pl
-Content-type: text/html; charset=ISO-8859-2
-Body:----------pl--
-<!--#set var="CONTENT_LANGUAGE" value="pl"
---><!--#set var="TITLE" value="Brak akceptowalnego obiektu!"
---><!--#set var="CHARACTER_ENCODING" value="ISO-8859-2"
---><!--#include virtual="include/top.html" -->
-
- Nie znaleziono akceptowalnego obiektu reprezentuj±cego
- ¿±dany zasób.
-
-<!--#include virtual="include/bottom.html" -->
-----------pl--
-
-Content-language: pt-br
-Content-type: text/html; charset=ISO-8859-1
-Body:-------pt-br--
-<!--#set var="CONTENT_LANGUAGE" value="pt-br"
---><!--#set var="TITLE" value="Objeto apropriado não encontrado!"
---><!--#include virtual="include/top.html" -->
-
- Não existe uma representação apropriada
- para o recurso requisitado neste servidor.
-
-<!--#include virtual="include/bottom.html" -->
--------pt-br--
-
-Content-language: ro
-Content-type: text/html; charset=ISO-8859-1
-Body:----------ro--
-<!--#set var="CONTENT_LANGUAGE" value="ro"
---><!--#set var="TITLE" value="Nici un obiect acceptabil gasit!"
---><!--#include virtual="include/top.html" -->
-
- Nici o reprezentare potrivita a resursei cerute
- nu a putut fi gasita pe acest server.
-
-<!--#include virtual="include/bottom.html" -->
-----------ro--
-
-Content-language: sv
-Content-type: text/html; charset=ISO-8859-1
-Body:----------sv--
-<!--#set var="CONTENT_LANGUAGE" value="sv"
---><!--#set var="TITLE" value="Inget acceptabelt objekt hittat!"
---><!--#include virtual="include/top.html" -->
-
- En lämplig representation av den efterfrågade
- resursen kunde inte hittas på denna server.
-
-<!--#include virtual="include/bottom.html" -->
-----------sv--
-
-Content-language: tr
-Content-type: text/html; charset=ISO-8859-9
-Body:----------tr--
-<!--#set var="CONTENT_LANGUAGE" value="tr"
---><!--#set var="CHARACTER_ENCODING" value="ISO-8859-9"
---><!--#set var="TITLE" value="No acceptable object found!"
---><!--#include virtual="include/top.html" -->
-
- Sunucu üzerinde, talep ettiğiniz kaynağın
- uygun bir karşılığı bulunamadı.
-
-<!--#include virtual="include/bottom.html" -->
-----------tr--
<a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> |
<a href="./ru/install.html" hreflang="ru" rel="alternate" title="Russian"> ru </a></p>
</div>
+<div class="outofdate">Diese Übersetzung ist möglicherweise
+ nicht mehr aktuell. Bitte prüfen Sie die englische Version auf
+ die neuesten Änderungen.</div>
<p>Dieses Dokument umfaßt nur die Kompilierung und Installation des
Apache auf Unix und Unix-ähnlichen Systemen. Für die
work. (This is only valid for versions after 2.0.41; earlier
versions have incompatible changes.)</p>
- <p>If you kept the source tree from your last installation,
- upgrading is even easier. The file <code>config.nice</code> in
- the root of the old source tree contains the exact
- <code class="program"><a href="./programs/configure.html">configure</a></code> command line that you used to configure the
- source tree. Then to upgrade from one version to the next, you
- need only copy the <code>config.nice</code> file to the source
- tree of the new version, edit it to make any desired changes, and
- then run:</p>
+ <p>To upgrade across minor versions, start by finding the file
+ <code>config.nice</code> in the <code>build</code> directory of
+ your installed server or at the root of the source tree for your
+ old install. This will contain the exact
+ <code class="program"><a href="./programs/configure.html">configure</a></code> command line that you used to
+ configure the source tree. Then to upgrade from one version to
+ the next, you need only copy the <code>config.nice</code> file to
+ the source tree of the new version, edit it to make any desired
+ changes, and then run:</p>
<div class="example"><p><code>
$ ./config.nice<br />
<a href="./ko/install.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> |
<a href="./ru/install.html" hreflang="ru" rel="alternate" title="Russian"> ru </a></p>
</div>
+<div class="outofdate">Esta traducción podría estar
+ obsoleta. Consulte la versión en inglés de la
+ documentación para comprobar si se han producido cambios
+ recientemente.</div>
<p>Este documento explica cómo compilar e instalar Apache en
work. (This is only valid for versions after 2.0.41; earlier
versions have incompatible changes.)</p>
- <p>If you kept the source tree from your last installation,
- upgrading is even easier. The file <code>config.nice</code> in
- the root of the old source tree contains the exact
- <program>configure</program> command line that you used to configure the
- source tree. Then to upgrade from one version to the next, you
- need only copy the <code>config.nice</code> file to the source
- tree of the new version, edit it to make any desired changes, and
- then run:</p>
+ <p>To upgrade across minor versions, start by finding the file
+ <code>config.nice</code> in the <code>build</code> directory of
+ your installed server or at the root of the source tree for your
+ old install. This will contain the exact
+ <program>configure</program> command line that you used to
+ configure the source tree. Then to upgrade from one version to
+ the next, you need only copy the <code>config.nice</code> file to
+ the source tree of the new version, edit it to make any desired
+ changes, and then run:</p>
<example>
$ ./config.nice<br />
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.de.xsl"?>
-<!-- English Revision: 151405 -->
+<!-- English Revision: 151405:178522 (outdated) -->
<!--
Copyright 2002-2004 The Apache Software Foundation
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.es.xsl"?>
-<!-- English Revision: 151405 -->
+<!-- English Revision: 151405:178522 (outdated) -->
<!--
Copyright 2004-2005 The Apache Software Foundation
<?xml version='1.0' encoding='iso-2022-jp' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.ja.xsl"?>
-<!-- English Revision: 106090:151405 (outdated) -->
+<!-- English Revision: 106090:178522 (outdated) -->
<!--
Copyright 2002-2004 The Apache Software Foundation
<?xml version='1.0' encoding='EUC-KR' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.ko.xsl"?>
-<!-- English Revision: 106090:151405 (outdated) -->
+<!-- English Revision: 106090:178522 (outdated) -->
<!--
Copyright 2003-2004 The Apache Software Foundation
<relpath>.</relpath>
<variants>
- <variant>de</variant>
+ <variant outdated="yes">de</variant>
<variant>en</variant>
- <variant>es</variant>
+ <variant outdated="yes">es</variant>
<variant outdated="yes">ja</variant>
<variant outdated="yes">ko</variant>
<variant outdated="yes">ru</variant>
<?xml version='1.0' encoding='KOI8-R' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.ru.xsl"?>
-<!-- English Revision: 97974:151405 (outdated) -->
+<!-- English Revision: 97974:178522 (outdated) -->
<!--
Copyright 2002-2004 The Apache Software Foundation
<div class="directive-section"><h2><a name="AuthDBMAuthoritative" id="AuthDBMAuthoritative">AuthDBMAuthoritative</a> <a name="authdbmauthoritative" id="authdbmauthoritative">Directive</a></h2>
<table class="directive">
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>AuthDBMAuthoritative On|Off</code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>AuthDBMAuthoritative On</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>directory, .htaccess</td></tr>
<directivesynopsis>
<name>AuthDBMAuthoritative</name>
<description>Sets whether authentication and authorization will be
-passwed on to lower level modules</description>
+passed on to lower level modules</description>
<syntax>AuthDBMAuthoritative On|Off</syntax>
<default>AuthDBMAuthoritative On</default>
<contextlist><context>directory</context><context>.htaccess</context>
<tr><td><a href="mod_auth.html#authauthoritative">AuthAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets whether authorization and authentication are
passed to lower level modules</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmauthoritative">AuthDBMAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><td><a href="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile <var>file-path</var></a></td><td></td><td>dh</td><td>E</td></tr><tr><td class="descr" colspan="4">Sets the name of the database file containing the list
of user groups for authentication</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmtype">AuthDBMType default|SDBM|GDBM|NDBM|DB</a></td><td> default </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the type of database file that is used to
<tr><td><a href="mod_auth.html#authauthoritative">AuthAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets whether authorization and authentication are
passed to lower level modules</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmauthoritative">AuthDBMAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><td><a href="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile <var>file-path</var></a></td><td></td><td>dh</td><td>E</td></tr><tr><td class="descr" colspan="4">Sets the name of the database file containing the list
of user groups for authentication</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmtype">AuthDBMType default|SDBM|GDBM|NDBM|DB</a></td><td> default </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the type of database file that is used to
<tr><td><a href="mod_auth.html#authauthoritative">AuthAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets whether authorization and authentication are
passed to lower level modules</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmauthoritative">AuthDBMAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><td><a href="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile <var>file-path</var></a></td><td></td><td>dh</td><td>E</td></tr><tr><td class="descr" colspan="4">Sets the name of the database file containing the list
of user groups for authentication</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmtype">AuthDBMType default|SDBM|GDBM|NDBM|DB</a></td><td> default </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the type of database file that is used to
<tr><td><a href="mod_auth.html#authauthoritative">AuthAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>B</td></tr><tr><td class="descr" colspan="4">ǧ¾Ú¤È¾µÇ§¥×¥í¥»¥¹¤ò¡¢
¤è¤êÄ㤤¥ì¥Ù¥ë¤Î¥â¥¸¥å¡¼¥ë¤Ë°Ü¹Ô¤µ¤»¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmauthoritative">AuthDBMAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><td><a href="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile <var>file-path</var></a></td><td></td><td>dh</td><td>E</td></tr><tr><td class="descr" colspan="4">Sets the name of the database file containing the list
of user groups for authentication</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmtype">AuthDBMType default|SDBM|GDBM|NDBM|DB</a></td><td> default </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the type of database file that is used to
<tr><td><a href="mod_auth.html#authauthoritative">AuthAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets whether authorization and authentication are
passed to lower level modules</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmauthoritative">AuthDBMAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><td><a href="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile <var>file-path</var></a></td><td></td><td>dh</td><td>E</td></tr><tr><td class="descr" colspan="4">Sets the name of the database file containing the list
of user groups for authentication</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmtype">AuthDBMType default|SDBM|GDBM|NDBM|DB</a></td><td> default </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the type of database file that is used to
<tr><td><a href="mod_auth.html#authauthoritative">AuthAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets whether authorization and authentication are
passed to lower level modules</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmauthoritative">AuthDBMAuthoritative On|Off</a></td><td> On </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets whether authentication and authorization will be
-passwed on to lower level modules</td></tr>
+passed on to lower level modules</td></tr>
<tr><td><a href="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile <var>file-path</var></a></td><td></td><td>dh</td><td>E</td></tr><tr><td class="descr" colspan="4">Sets the name of the database file containing the list
of user groups for authentication</td></tr>
<tr class="odd"><td><a href="mod_auth_dbm.html#authdbmtype">AuthDBMType default|SDBM|GDBM|NDBM|DB</a></td><td> default </td><td>dh</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the type of database file that is used to
int result = 0;
int failures = 0;
int version = LDAP_VERSION3;
+ int rc = LDAP_SUCCESS;
+ struct timeval timeOut = {10,0}; /* 10 second connection timeout */
util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
r->server->module_config, &ldap_module);
/* always default to LDAP V3 */
ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ if (st->connectionTimeout > 0) {
+ timeOut.tv_sec = st->connectionTimeout;
+ }
+
+ if (st->connectionTimeout >= 0) {
+ rc = ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, (void *)&timeOut);
+ if (APR_SUCCESS != rc) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "LDAP: Could not set the connection timeout" );
+ }
+ }
+#endif
}
void *data;
const char *userdata_key = "util_ldap_init";
- struct timeval timeOut = {10,0}; /* 10 second connection timeout */
/* util_ldap_post_config() will be called twice. Don't bother
* going through all of the initialization on the first call
"LDAP: SSL support unavailable" );
}
-#ifdef LDAP_OPT_NETWORK_TIMEOUT
- if (st->connectionTimeout > 0) {
- timeOut.tv_sec = st->connectionTimeout;
- }
-
- if (st->connectionTimeout >= 0) {
- rc = ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, (void *)&timeOut);
- if (APR_SUCCESS != rc) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "LDAP: Could not set the connection timeout" );
- }
- }
-#endif
-
return(OK);
}
typedef const char *ap_log_handler_fn_t(request_rec *r, char *a);
/**
- * callback function prototype for a external writer initilization.
+ * callback function prototype for external writer initialization.
*/
typedef void *ap_log_writer_init(apr_pool_t *p, server_rec *s,
const char *name);
char *curkey;
char *curval;
- rc = apr_file_open(&fp, file, APR_READ, APR_OS_DEFAULT, r->pool);
+ rc = apr_file_open(&fp, file, APR_READ|APR_BUFFERED, APR_OS_DEFAULT, r->pool);
if (rc != APR_SUCCESS) {
return NULL;
}
return OK;
}
+static void add_te_chunked(apr_pool_t *p,
+ apr_bucket_alloc_t *bucket_alloc,
+ apr_bucket_brigade *header_brigade)
+{
+ apr_bucket *e;
+ char *buf;
+ const char te_hdr[] = "Transfer-Encoding: chunked" CRLF;
+
+ buf = apr_pmemdup(p, te_hdr, sizeof(te_hdr)-1);
+ ap_xlate_proto_to_ascii(buf, sizeof(te_hdr)-1);
+
+ e = apr_bucket_pool_create(buf, sizeof(te_hdr)-1, p, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+}
+
+static void add_cl(apr_pool_t *p,
+ apr_bucket_alloc_t *bucket_alloc,
+ apr_bucket_brigade *header_brigade,
+ const char *cl_val)
+{
+ apr_bucket *e;
+ char *buf;
+
+ buf = apr_pstrcat(p, "Content-Length: ",
+ cl_val,
+ CRLF,
+ NULL);
+ ap_xlate_proto_to_ascii(buf, strlen(buf));
+ e = apr_bucket_pool_create(buf, strlen(buf), p, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+}
+
+#define ASCII_CRLF "\015\012"
+#define ASCII_ZERO "\060"
+
+static void terminate_headers(apr_bucket_alloc_t *bucket_alloc,
+ apr_bucket_brigade *header_brigade)
+{
+ apr_bucket *e;
+
+ /* add empty line at the end of the headers */
+ e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+}
+
+static apr_status_t pass_brigade(apr_bucket_alloc_t *bucket_alloc,
+ request_rec *r, proxy_http_conn_t *p_conn,
+ conn_rec *origin, apr_bucket_brigade *b,
+ int flush)
+{
+ apr_status_t status;
+
+ if (flush) {
+ apr_bucket *e = apr_bucket_flush_create(bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ }
+ status = ap_pass_brigade(origin->output_filters, b);
+ if (status != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+ "proxy: pass request data failed to %pI (%s)",
+ p_conn->addr, p_conn->name);
+ return status;
+ }
+ apr_brigade_cleanup(b);
+ return APR_SUCCESS;
+}
+
+static apr_status_t stream_reqbody_chunked(apr_pool_t *p,
+ request_rec *r,
+ proxy_http_conn_t *p_conn,
+ conn_rec *origin,
+ apr_bucket_brigade *header_brigade)
+{
+ int seen_eos = 0;
+ apr_size_t hdr_len;
+ apr_off_t bytes;
+ apr_status_t status;
+ apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc;
+ apr_bucket_brigade *b, *input_brigade;
+ apr_bucket *e;
+
+ input_brigade = apr_brigade_create(p, bucket_alloc);
+
+ do {
+ char chunk_hdr[20]; /* must be here due to transient bucket. */
+
+ status = ap_get_brigade(r->input_filters, input_brigade,
+ AP_MODE_READBYTES, APR_BLOCK_READ,
+ HUGE_STRING_LEN);
+
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ /* If this brigade contains EOS, either stop or remove it. */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
+ seen_eos = 1;
+
+ /* As a shortcut, if this brigade is simply an EOS bucket,
+ * don't send anything down the filter chain.
+ */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) {
+ break;
+ }
+
+ /* We can't pass this EOS to the output_filters. */
+ e = APR_BRIGADE_LAST(input_brigade);
+ apr_bucket_delete(e);
+ }
+
+ apr_brigade_length(input_brigade, 1, &bytes);
+
+ hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr),
+ "%" APR_UINT64_T_HEX_FMT CRLF,
+ (apr_uint64_t)bytes);
+
+ ap_xlate_proto_to_ascii(chunk_hdr, hdr_len);
+ e = apr_bucket_transient_create(chunk_hdr, hdr_len,
+ bucket_alloc);
+ APR_BRIGADE_INSERT_HEAD(input_brigade, e);
+
+ /*
+ * Append the end-of-chunk CRLF
+ */
+ e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(input_brigade, e);
+
+ if (header_brigade) {
+ /* we never sent the header brigade, so go ahead and
+ * take care of that now
+ */
+ add_te_chunked(p, bucket_alloc, header_brigade);
+ terminate_headers(bucket_alloc, header_brigade);
+ b = header_brigade;
+ APR_BRIGADE_CONCAT(b, input_brigade);
+ header_brigade = NULL;
+ }
+ else {
+ b = input_brigade;
+ }
+
+ status = pass_brigade(bucket_alloc, r, p_conn, origin, b, 0);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+ } while (!seen_eos);
+
+ if (header_brigade) {
+ /* we never sent the header brigade because there was no request body;
+ * send it now without T-E
+ */
+ terminate_headers(bucket_alloc, header_brigade);
+ b = header_brigade;
+ }
+ else {
+ if (!APR_BRIGADE_EMPTY(input_brigade)) {
+ /* input brigade still has an EOS which we can't pass to the output_filters. */
+ e = APR_BRIGADE_LAST(input_brigade);
+ AP_DEBUG_ASSERT(APR_BUCKET_IS_EOS(e));
+ apr_bucket_delete(e);
+ }
+ e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF
+ /* <trailers> */
+ ASCII_CRLF,
+ 5, bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(input_brigade, e);
+ b = input_brigade;
+ }
+
+ status = pass_brigade(bucket_alloc, r, p_conn, origin, b, 1);
+ return status;
+}
+
+static apr_status_t stream_reqbody_cl(apr_pool_t *p,
+ request_rec *r,
+ proxy_http_conn_t *p_conn,
+ conn_rec *origin,
+ apr_bucket_brigade *header_brigade,
+ const char *old_cl_val)
+{
+ int seen_eos = 0;
+ apr_status_t status;
+ apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc;
+ apr_bucket_brigade *b, *input_brigade;
+ apr_bucket *e;
+
+ input_brigade = apr_brigade_create(p, bucket_alloc);
+
+ do {
+ status = ap_get_brigade(r->input_filters, input_brigade,
+ AP_MODE_READBYTES, APR_BLOCK_READ,
+ HUGE_STRING_LEN);
+
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ /* If this brigade contains EOS, either stop or remove it. */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
+ seen_eos = 1;
+
+ /* As a shortcut, if this brigade is simply an EOS bucket,
+ * don't send anything down the filter chain.
+ */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) {
+ break;
+ }
+
+ /* We can't pass this EOS to the output_filters. */
+ e = APR_BRIGADE_LAST(input_brigade);
+ apr_bucket_delete(e);
+ }
+
+ if (header_brigade) {
+ /* we never sent the header brigade, so go ahead and
+ * take care of that now
+ */
+ add_cl(p, bucket_alloc, header_brigade, old_cl_val);
+ terminate_headers(bucket_alloc, header_brigade);
+ b = header_brigade;
+ APR_BRIGADE_CONCAT(b, input_brigade);
+ header_brigade = NULL;
+ }
+ else {
+ b = input_brigade;
+ }
+
+ status = pass_brigade(bucket_alloc, r, p_conn, origin, b, 0);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+ } while (!seen_eos);
+
+ if (header_brigade) {
+ /* we never sent the header brigade since there was no request
+ * body; send it now, and only specify C-L if client specified
+ * C-L: 0
+ */
+ if (!strcmp(old_cl_val, "0")) {
+ add_cl(p, bucket_alloc, header_brigade, old_cl_val);
+ }
+ terminate_headers(bucket_alloc, header_brigade);
+ b = header_brigade;
+ }
+ else {
+ /* need to flush any pending data */
+ b = input_brigade; /* empty now; pass_brigade() will add flush */
+ }
+ status = pass_brigade(bucket_alloc, r, p_conn, origin, b, 1);
+ return status;
+}
+
+#define MAX_MEM_SPOOL 16384
+
+static apr_status_t spool_reqbody_cl(apr_pool_t *p,
+ request_rec *r,
+ proxy_http_conn_t *p_conn,
+ conn_rec *origin,
+ apr_bucket_brigade *header_brigade)
+{
+ int seen_eos = 0;
+ apr_status_t status;
+ apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc;
+ apr_bucket_brigade *body_brigade, *input_brigade;
+ apr_bucket *e;
+ apr_off_t bytes, bytes_spooled = 0, fsize = 0;
+ apr_file_t *tmpfile = NULL;
+
+ body_brigade = apr_brigade_create(p, bucket_alloc);
+ input_brigade = apr_brigade_create(p, bucket_alloc);
+
+ do {
+ status = ap_get_brigade(r->input_filters, input_brigade,
+ AP_MODE_READBYTES, APR_BLOCK_READ,
+ HUGE_STRING_LEN);
+
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ /* If this brigade contains EOS, either stop or remove it. */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
+ seen_eos = 1;
+
+ /* As a shortcut, if this brigade is simply an EOS bucket,
+ * don't send anything down the filter chain.
+ */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) {
+ break;
+ }
+
+ /* We can't pass this EOS to the output_filters. */
+ e = APR_BRIGADE_LAST(input_brigade);
+ apr_bucket_delete(e);
+ }
+
+ apr_brigade_length(input_brigade, 1, &bytes);
+
+ if (bytes_spooled + bytes > MAX_MEM_SPOOL) {
+ /* can't spool any more in memory; write latest brigade to disk */
+ if (tmpfile == NULL) {
+ const char *temp_dir;
+ char *template;
+
+ status = apr_temp_dir_get(&temp_dir, p);
+ if (status != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+ "proxy: search for temporary directory failed");
+ return status;
+ }
+ apr_filepath_merge(&template, temp_dir,
+ "modproxy.tmp.XXXXXX",
+ APR_FILEPATH_NATIVE, p);
+ status = apr_file_mktemp(&tmpfile, template, 0, p);
+ if (status != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+ "proxy: creation of temporary file in directory %s failed",
+ temp_dir);
+ return status;
+ }
+ }
+ for (e = APR_BRIGADE_FIRST(input_brigade);
+ e != APR_BRIGADE_SENTINEL(input_brigade);
+ e = APR_BUCKET_NEXT(e)) {
+ const char *data;
+ apr_size_t bytes_read, bytes_written;
+
+ apr_bucket_read(e, &data, &bytes_read, APR_BLOCK_READ);
+ status = apr_file_write_full(tmpfile, data, bytes_read, &bytes_written);
+ if (status != APR_SUCCESS) {
+ const char *tmpfile_name;
+
+ if (apr_file_name_get(&tmpfile_name, tmpfile) != APR_SUCCESS) {
+ tmpfile_name = "(unknown)";
+ }
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+ "proxy: write to temporary file %s failed",
+ tmpfile_name);
+ return status;
+ }
+ AP_DEBUG_ASSERT(bytes_read == bytes_written);
+ fsize += bytes_written;
+ }
+ apr_brigade_cleanup(input_brigade);
+ }
+ else {
+ APR_BRIGADE_CONCAT(body_brigade, input_brigade);
+ }
+
+ bytes_spooled += bytes;
+
+ } while (!seen_eos);
+
+ if (bytes_spooled) {
+ add_cl(p, bucket_alloc, header_brigade, apr_off_t_toa(p, bytes_spooled));
+ }
+ terminate_headers(bucket_alloc, header_brigade);
+ APR_BRIGADE_CONCAT(header_brigade, body_brigade);
+ if (tmpfile) {
+ /* For platforms where the size of the file may be larger than
+ * that which can be stored in a single bucket (where the
+ * length field is an apr_size_t), split it into several
+ * buckets: */
+ if (sizeof(apr_off_t) > sizeof(apr_size_t)
+ && fsize > AP_MAX_SENDFILE) {
+ e = apr_bucket_file_create(tmpfile, 0, AP_MAX_SENDFILE, p,
+ bucket_alloc);
+ while (fsize > AP_MAX_SENDFILE) {
+ apr_bucket *ce;
+ apr_bucket_copy(e, &ce);
+ APR_BRIGADE_INSERT_TAIL(header_brigade, ce);
+ e->start += AP_MAX_SENDFILE;
+ fsize -= AP_MAX_SENDFILE;
+ }
+ e->length = (apr_size_t)fsize; /* Resize just the last bucket */
+ }
+ else {
+ e = apr_bucket_file_create(tmpfile, 0, (apr_size_t)fsize, p,
+ bucket_alloc);
+ }
+ APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+ }
+ status = pass_brigade(bucket_alloc, r, p_conn, origin, header_brigade, 1);
+ return status;
+}
+
+static apr_status_t send_request_body(apr_pool_t *p,
+ request_rec *r,
+ proxy_http_conn_t *p_conn,
+ conn_rec *origin,
+ apr_bucket_brigade *header_brigade,
+ int force10)
+{
+ enum {RB_INIT, RB_STREAM_CL, RB_STREAM_CHUNKED, RB_SPOOL_CL} rb_method = RB_INIT;
+ const char *old_cl_val, *te_val;
+ int cl_zero; /* client sent "Content-Length: 0", which we forward on to server */
+ apr_status_t status;
+
+ /* send CL or use chunked encoding?
+ *
+ * . CL is the most friendly to the origin server since it is the
+ * most widely supported
+ * . CL stinks if we don't know the length since we have to buffer
+ * the data in memory or on disk until we get the entire data
+ *
+ * special cases to check for:
+ * . if we're using HTTP/1.0 to origin server, then we must send CL
+ * . if client sent C-L and there are no input resource filters, the
+ * the body size can't change so we send the same CL and stream the
+ * body
+ * . if client used chunked or proxy-sendchunks is set, we'll also
+ * use chunked
+ *
+ * normal case:
+ * we have to compute content length by reading the entire request
+ * body; if request body is not small, we'll spool the remaining input
+ * to a temporary file
+ *
+ * special envvars to override the normal decision:
+ * . proxy-sendchunks
+ * use chunked encoding; not compatible with force-proxy-request-1.0
+ * . proxy-sendcl
+ * spool the request body to compute C-L
+ * . proxy-sendunchangedcl
+ * use C-L from client and spool the request body
+ */
+ old_cl_val = apr_table_get(r->headers_in, "Content-Length");
+ cl_zero = old_cl_val && !strcmp(old_cl_val, "0");
+
+ if (!force10
+ && !cl_zero
+ && apr_table_get(r->subprocess_env, "proxy-sendchunks")) {
+ rb_method = RB_STREAM_CHUNKED;
+ }
+ else if (!cl_zero
+ && apr_table_get(r->subprocess_env, "proxy-sendcl")) {
+ rb_method = RB_SPOOL_CL;
+ }
+ else {
+ if (old_cl_val &&
+ (r->input_filters == r->proto_input_filters
+ || cl_zero
+ || apr_table_get(r->subprocess_env, "proxy-sendunchangedcl"))) {
+ rb_method = RB_STREAM_CL;
+ }
+ else if (force10) {
+ rb_method = RB_SPOOL_CL;
+ }
+ else if ((te_val = apr_table_get(r->headers_in, "Transfer-Encoding"))
+ && !strcasecmp(te_val, "chunked")) {
+ rb_method = RB_STREAM_CHUNKED;
+ }
+ else {
+ rb_method = RB_SPOOL_CL;
+ }
+ }
+
+ switch(rb_method) {
+ case RB_STREAM_CHUNKED:
+ status = stream_reqbody_chunked(p, r, p_conn, origin, header_brigade);
+ break;
+ case RB_STREAM_CL:
+ status = stream_reqbody_cl(p, r, p_conn, origin, header_brigade, old_cl_val);
+ break;
+ case RB_SPOOL_CL:
+ status = spool_reqbody_cl(p, r, p_conn, origin, header_brigade);
+ break;
+ default:
+ ap_assert(1 != 1);
+ }
+
+ return status;
+}
+
static
apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r,
proxy_http_conn_t *p_conn, conn_rec *origin,
apr_bucket *e;
const apr_array_header_t *headers_in_array;
const apr_table_entry_t *headers_in;
- int counter, seen_eos;
+ int counter;
apr_status_t status;
+ int force10;
/*
* Send the HTTP/1.1 request to the remote server
if ( apr_table_get(r->subprocess_env,"force-proxy-request-1.0")) {
buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.0" CRLF, NULL);
+ force10 = 1;
} else {
buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.1" CRLF, NULL);
+ force10 = 0;
}
if ( apr_table_get(r->subprocess_env,"proxy-nokeepalive")) {
apr_table_unset(r->headers_in, "Connection");
|| !apr_strnatcasecmp(headers_in[counter].key, "Transfer-Encoding")
|| !apr_strnatcasecmp(headers_in[counter].key, "Upgrade")
+ /* We'll add appropriate Content-Length later, if appropriate.
+ */
+ || !apr_strnatcasecmp(headers_in[counter].key, "Content-Length")
+
/* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be
* suppressed if THIS server requested the authentication,
* not when a frontend proxy requested it!
APR_BRIGADE_INSERT_TAIL(bb, e);
}
- /* add empty line at the end of the headers */
-#if APR_CHARSET_EBCDIC
- e = apr_bucket_immortal_create("\015\012", 2, c->bucket_alloc);
-#else
- e = apr_bucket_immortal_create(CRLF, sizeof(CRLF)-1, c->bucket_alloc);
-#endif
- APR_BRIGADE_INSERT_TAIL(bb, e);
- e = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, e);
-
- status = ap_pass_brigade(origin->output_filters, bb);
-
+ /* send the request data, if any. */
+ status = send_request_body(p, r, p_conn, origin, bb, force10);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
"proxy: request failed to %pI (%s)",
return status;
}
- /* send the request data, if any. */
- seen_eos = 0;
- do {
- status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
- APR_BLOCK_READ, HUGE_STRING_LEN);
-
- if (status != APR_SUCCESS) {
- return status;
- }
-
- /* If this brigade contain EOS, either stop or remove it. */
- if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
- /* As a shortcut, if this brigade is simply an EOS bucket,
- * don't send anything down the filter chain.
- */
- if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
- break;
- }
-
- /* We can't pass this EOS to the output_filters. */
- e = APR_BRIGADE_LAST(bb);
- apr_bucket_delete(e);
- seen_eos = 1;
- }
-
- e = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, e);
-
- status = ap_pass_brigade(origin->output_filters, bb);
- if (status != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
- "proxy: pass request data failed to %pI (%s)",
- p_conn->addr, p_conn->name);
- return status;
- }
- apr_brigade_cleanup(bb);
- } while (!seen_eos);
-
return APR_SUCCESS;
}
static fd_queue_t *worker_queue;
static fd_queue_info_t *worker_queue_info;
static int mpm_state = AP_MPMQ_STARTING;
+static int sick_child_detected;
/* The structure used to pass unique initialization info to each thread */
typedef struct {
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
"apr_thread_create: unable to create listener thread");
- /* In case system resources are maxxed out, we don't want
- * Apache running away with the CPU trying to fork over and
- * over and over again if we exit.
- * XXX Jeff doesn't see how Apache is going to try to fork again since
- * the exit code is APEXIT_CHILDFATAL
- */
- apr_sleep(apr_time_from_sec(10));
- clean_child_exit(APEXIT_CHILDFATAL);
+ /* let the parent decide how bad this really is */
+ clean_child_exit(APEXIT_CHILDSICK);
}
apr_os_thread_get(&listener_os_thread, ts->listener);
}
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
"apr_thread_create: unable to create worker thread");
- /* In case system resources are maxxed out, we don't want
- Apache running away with the CPU trying to fork over and
- over and over again if we exit. */
- apr_sleep(apr_time_from_sec(10));
- clean_child_exit(APEXIT_CHILDFATAL);
+ /* let the parent decide how bad this really is */
+ clean_child_exit(APEXIT_CHILDSICK);
}
threads_created++;
}
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
"apr_thread_create: unable to create worker thread");
- /* In case system resources are maxxed out, we don't want
- Apache running away with the CPU trying to fork over and
- over and over again if we exit. */
- apr_sleep(apr_time_from_sec(10));
- clean_child_exit(APEXIT_CHILDFATAL);
+ /* let the parent decide how bad this really is */
+ clean_child_exit(APEXIT_CHILDSICK);
}
mpm_state = AP_MPMQ_RUNNING;
int free_slots[MAX_SPAWN_RATE];
int last_non_dead;
int total_non_dead;
+ int active_thread_count = 0;
/* initialize the free_list */
free_length = 0;
* So we hopefully won't need to fork more if we count it.
* This depends on the ordering of SERVER_READY and SERVER_STARTING.
*/
- if (status <= SERVER_READY && status != SERVER_DEAD &&
- !ps->quiescing &&
- ps->generation == ap_my_generation &&
- /* XXX the following shouldn't be necessary if we clean up
- * properly after seg faults, but we're not yet GLA
- */
- ps->pid != 0) {
- ++idle_thread_count;
+ if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for
+ loop if no pid? not much else matters */
+ if (status <= SERVER_READY && status != SERVER_DEAD &&
+ !ps->quiescing &&
+ ps->generation == ap_my_generation) {
+ ++idle_thread_count;
+ }
+ if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
+ ++active_thread_count;
+ }
}
}
if (any_dead_threads && totally_free_length < idle_spawn_rate
++total_non_dead;
}
}
+
+ if (sick_child_detected) {
+ if (active_thread_count > 0) {
+ /* some child processes appear to be working. don't kill the
+ * whole server.
+ */
+ sick_child_detected = 0;
+ }
+ else {
+ /* looks like a basket case. give up.
+ */
+ shutdown_pending = 1;
+ child_fatal = 1;
+ ap_log_error(APLOG_MARK, APLOG_ALERT, 0,
+ ap_server_conf,
+ "No active workers found..."
+ " Apache is exiting!");
+ /* the child already logged the failure details */
+ return;
+ }
+ }
+
ap_max_daemons_limit = last_non_dead + 1;
if (idle_thread_count > max_spare_threads) {
child_fatal = 1;
return;
}
+ else if (processed_status == APEXIT_CHILDSICK) {
+ /* tell perform_idle_server_maintenance to check into this
+ * on the next timer pop
+ */
+ sick_child_detected = 1;
+ }
/* non-fatal death... note that it's gone in the scoreboard. */
child_slot = find_child_by_pid(&pid);
if (child_slot >= 0) {