diff options
Diffstat (limited to '')
99 files changed, 2404 insertions, 1578 deletions
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ddacd4a..1a883c8 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -21,6 +21,8 @@ on: env: MARGS: "-j2" CFLAGS: "-g" + # This will need updating as the ubuntu-latest image changes: + PHP_FPM: "/usr/sbin/php-fpm8.1" jobs: build: @@ -48,11 +50,11 @@ jobs: - name: Shared MPMs, all-modules config: --enable-mods-shared=reallyall --enable-mpms-shared=all # ------------------------------------------------------------------------- - - name: Event MPM, all-modules, mod_cgid only - config: --enable-mods-shared=reallyall --with-mpm=event --disable-cgi + - name: Event MPM, all-modules, mod_cgid fdpassing + config: --enable-mods-shared=reallyall --with-mpm=event --disable-cgi --enable-cgid-fdpassing # ------------------------------------------------------------------------- - - name: Event MPM, all-modules, no CMSG_DATA - config: --enable-mods-shared=reallyall --with-mpm=event ac_cv_have_decl_CMSG_DATA=no + - name: Event MPM, all-modules, mod_cgid w/o fdpassing + config: --enable-mods-shared=reallyall --with-mpm=event --disable-cgi # ------------------------------------------------------------------------- - name: Default, all-modules + install config: --enable-mods-shared=reallyall @@ -215,7 +217,7 @@ jobs: APR_VERSION=1.7.4 APU_VERSION=1.6.3 APU_CONFIG="--with-crypto" - RUSTLS_VERSION="v0.10.0" + RUSTLS_VERSION="v0.13.0" NO_TEST_FRAMEWORK=1 TEST_INSTALL=1 TEST_MOD_TLS=1 @@ -1,6 +1,79 @@ -*- coding: utf-8 -*- +Changes with Apache 2.4.60 + + *) mod_proxy: Fix DNS requests and connections closed before the + configured addressTTL. BZ 69126. [Yann Ylavic] + + *) core: On Linux, log the real thread ID in error logs. [Joe Orton] + + *) core: Support zone/scope in IPv6 link-local addresses in Listen and + VirtualHost directives (requires APR 1.7.x or later). PR 59396 + [Joe Orton] + + *) mod_ssl: Reject client-initiated renegotiation with a TLS alert + (rather than connection closure). [Joe Orton, Yann Ylavic] + + *) Updated mime.types. [Mohamed Akram <mohd.akram outlook.com>, + Adam Silverstein <adamsilverstein earthboundhosting.com>] + + *) mod_ssl: Fix a regression that causes the default DH parameters for a key + no longer set and thus effectively disabling DH ciphers when no explicit + DH parameters are set. PR 68863 [Ruediger Pluem] + + *) mod_cgid: Optional support for file descriptor passing, fixing + error log handling (configure --enable-cgid-fdpassing) on Unix + platforms. PR 54221. [Joe Orton] + + *) mod_cgid/mod_cgi: Distinguish script stderr output clearly in + error logs. PR 61980. [Hank Ibell <hwibell gmail.com>] + + *) mod_tls: update version of rustls-ffi to v0.13.0. + [Daniel McCarney (@cpu}] + + *) mod_md: + - Using OCSP stapling information to trigger certificate renewals. Proposed + by @frasertweedale. + - Added directive `MDCheckInterval` to control how often the server checks + for detected revocations. Added proposals for configurations in the + README.md chapter "Revocations". + - OCSP stapling: accept OCSP responses without a `nextUpdate` entry which is + allowed in RFC 6960. Treat those as having an update interval of 12 hours. + Added by @frasertweedale. + - Adapt OpenSSL usage to changes in their API. By Yann Ylavic. + Changes with Apache 2.4.59 + *) SECURITY: CVE-2024-27316: Apache HTTP Server: HTTP/2 DoS by + memory exhaustion on endless continuation frames (cve.mitre.org) + HTTP/2 incoming headers exceeding the limit are temporarily + buffered in nghttp2 in order to generate an informative HTTP 413 + response. If a client does not stop sending headers, this leads + to memory exhaustion. + Credits: Bartek Nowotarski (https://nowotarski.info/) + + *) SECURITY: CVE-2024-24795: Apache HTTP Server: HTTP Response + Splitting in multiple modules (cve.mitre.org) + HTTP Response splitting in multiple modules in Apache HTTP + Server allows an attacker that can inject malicious response + headers into backend applications to cause an HTTP + desynchronization attack. + + After this change, CGI-like scripts cannot set Transfer-Encoding + or Content-Length headers. To restore the ability to set Content-Length + header, set per-request environment variable 'ap_trust_cgilike_cl' to any + non-empty value. + + Credits: Keran Mu, Tsinghua University and Zhongguancun + Laboratory. + + *) SECURITY: CVE-2023-38709: Apache HTTP Server: HTTP response + splitting (cve.mitre.org) + Faulty input validation in the core of Apache allows malicious + or exploitable backend/content generators to split HTTP + responses. + This issue affects Apache HTTP Server: through 2.4.58. + Credits: Orange Tsai (@orange_8361) from DEVCORE + *) mod_deflate: Fixes and better logging for handling various error and edge cases. [Eric Covener, Yann Ylavic, Joe Orton, Eric Norris <enorris etsy.com>] @@ -1160,6 +1160,7 @@ enable_info enable_suexec enable_cgid enable_cgi +enable_cgid_fdpassing enable_dav_fs enable_dav_lock with_module @@ -2048,6 +2049,7 @@ Optional Features: --enable-cgid CGI scripts. Enabled by default with threaded MPMs --enable-cgi CGI scripts. Enabled by default with non-threaded MPMs + --enable-cgid-fdpassing Enable experimental mod_cgid support for fd passing --enable-dav-fs DAV provider for the filesystem. --enable-dav also enables mod_dav_fs. --enable-dav-lock DAV provider for generic locking @@ -8774,6 +8776,14 @@ printf "%s\n" "#define HAVE_SYS_GETTID 1" >>confdefs.h fi fi +case ${host}X${ac_cv_func_gettid}X${ap_cv_gettid} in +*linux-*XyesX* | *linux-*XnoXyes) + +printf "%s\n" "#define DEFAULT_LOG_TID \"g\"" >>confdefs.h + + ;; +esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff in struct tm" >&5 printf %s "checking for tm_gmtoff in struct tm... " >&6; } if test ${ac_cv_struct_tm_gmtoff+y} @@ -39903,6 +39913,28 @@ fi fi +# Check whether --enable-cgid-fdpassing was given. +if test ${enable_cgid_fdpassing+y} +then : + enableval=$enable_cgid_fdpassing; if test "$enableval" = "yes"; then + ac_fn_check_decl "$LINENO" "CMSG_DATA" "ac_cv_have_decl_CMSG_DATA" " +#include <sys/types.h> +#include <sys/socket.h> +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_CMSG_DATA" = xyes +then : + +printf "%s\n" "#define HAVE_CGID_FDPASSING 1" >>confdefs.h + +else case e in #( + e) as_fn_error $? "cannot support mod_cgid fd-passing on this system" "$LINENO" 5 ;; +esac +fi + fi + +fi + + echo "DISTCLEAN_TARGETS = modules.mk" >> $modpath_current/modules.mk echo "static = $modpath_static" >> $modpath_current/modules.mk diff --git a/configure.in b/configure.in index 8134a69..d2a009d 100644 --- a/configure.in +++ b/configure.in @@ -545,6 +545,12 @@ pid_t t = syscall(SYS_gettid); return t == -1 ? 1 : 0; }, fi fi +case ${host}X${ac_cv_func_gettid}X${ap_cv_gettid} in +*linux-*XyesX* | *linux-*XnoXyes) + AC_DEFINE(DEFAULT_LOG_TID, ["g"], [Define as default argument for thread id in error logging]) + ;; +esac + dnl ## Check for the tm_gmtoff field in struct tm to get the timezone diffs AC_CACHE_CHECK([for tm_gmtoff in struct tm], ac_cv_struct_tm_gmtoff, [AC_TRY_COMPILE([#include <sys/types.h> diff --git a/docs/conf/mime.types b/docs/conf/mime.types index 1b92ee1..98a8e84 100644 --- a/docs/conf/mime.types +++ b/docs/conf/mime.types @@ -1538,6 +1538,7 @@ font/otf otf font/ttf ttf font/woff woff font/woff2 woff2 +image/avif avif image/bmp bmp image/cgm cgm # image/dicom-rle @@ -1645,7 +1646,7 @@ model/vnd.gdl gdl # model/vnd.gs.gdl model/vnd.gtw gtw # model/vnd.moml+xml -model/vnd.mts mts +# model/vnd.mts # model/vnd.opengex # model/vnd.parasolid.transmit.binary # model/vnd.parasolid.transmit.text @@ -1784,7 +1785,7 @@ video/jpm jpm jpgm video/mj2 mj2 mjp2 # video/mp1s # video/mp2p -# video/mp2t +video/mp2t ts m2t m2ts mts video/mp4 mp4 mp4v mpg4 # video/mp4v-es video/mpeg mpeg mpg mpe m1v m2v diff --git a/docs/manual/env.html.en b/docs/manual/env.html.en index af064d8..e0481a7 100644 --- a/docs/manual/env.html.en +++ b/docs/manual/env.html.en @@ -399,6 +399,14 @@ documentation for more details.</p> + <h3><a name="cgilike" id="cgilike">ap_trust_cgilike_cl</a></h3> + <p><em>Available in 2.4.59 and later</em></p> + <p> This variable allows a script running in CGI-like module to supply it's + own Content-Length HTTP response header. It should + only be set on configuration sections that contain trusted scripts. + </p> + + </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div> <div class="section"> <h2><a name="examples" id="examples">Examples</a></h2> diff --git a/docs/manual/env.html.fr.utf8 b/docs/manual/env.html.fr.utf8 index 4863d3b..71cb0e1 100644 --- a/docs/manual/env.html.fr.utf8 +++ b/docs/manual/env.html.fr.utf8 @@ -427,6 +427,14 @@ <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> et <code class="module"><a href="./mod/mod_proxy_http.html">mod_proxy_http</a></code> pour plus de détails.</p> + <h3><a name="cgilike" id="cgilike">ap_trust_cgilike_cl</a></h3> + <p><em>Disponible à partir de la version 2.4.59 du serveur HTTP Apache</em></p> + <p>Cette variable permet à un script qui s’exécute dans un module de type CGI + de fournir son propre en-tête de réponse HTTP Content-Length. Elle ne doit + être définie que dans les sections de configuration qui contiennent des + scripts de confiance.</p> + + </div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div> <div class="section"> <h2><a name="examples" id="examples">Exemples</a></h2> diff --git a/docs/manual/mod/core.html.de b/docs/manual/mod/core.html.de index 511cc1f..a025992 100644 --- a/docs/manual/mod/core.html.de +++ b/docs/manual/mod/core.html.de @@ -132,6 +132,7 @@ Servers</td></tr> <li><img alt="" src="../images/down.gif" /> <a href="#stricthostcheck">StrictHostCheck</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#timeout">TimeOut</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#traceenable">TraceEnable</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#unclist">UNCList</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#undefine">UnDefine</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalname">UseCanonicalName</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></li> @@ -3619,6 +3620,20 @@ bevor er die Anfrage abbricht</td></tr> </div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="directive-section"><h2><a name="UNCList" id="UNCList">UNCList</a>-<a name="unclist" id="unclist">Direktive</a></h2> +<table class="directive"> +<tr><th><a href="directive-dict.html#Description">Beschreibung:</a></th><td>Controls what UNC host names can be accessed by the server +</td></tr> +<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>UNCList<var>hostname</var> ...</code></td></tr> +<tr><th><a href="directive-dict.html#Default">Voreinstellung:</a></th><td><code>unset</code></td></tr> +<tr><th><a href="directive-dict.html#Context">Kontext:</a></th><td>Serverkonfiguration</td></tr> +<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Core</td></tr> +<tr><th><a href="directive-dict.html#Module">Modul:</a></th><td>core</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Kompatibilität:</a></th><td>Added in 2.4.60, Windows only.</td></tr> +</table><p>Die Dokumentation zu dieser Direktive wurde + noch nicht übersetzt. Bitte schauen Sie in die englische + Version.</p></div> +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="directive-section"><h2><a name="UnDefine" id="UnDefine">UnDefine</a>-<a name="undefine" id="undefine">Direktive</a></h2> <table class="directive"> <tr><th><a href="directive-dict.html#Description">Beschreibung:</a></th><td>Undefine the existence of a variable</td></tr> diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en index 3c3765d..ba049f3 100644 --- a/docs/manual/mod/core.html.en +++ b/docs/manual/mod/core.html.en @@ -129,6 +129,7 @@ available</td></tr> <li><img alt="" src="../images/down.gif" /> <a href="#stricthostcheck">StrictHostCheck</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#timeout">TimeOut</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#traceenable">TraceEnable</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#unclist">UNCList</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#undefine">UnDefine</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalname">UseCanonicalName</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></li> @@ -4995,6 +4996,29 @@ certain events before failing a request</td></tr> </div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="directive-section"><h2><a name="UNCList" id="UNCList">UNCList</a> <a name="unclist" id="unclist">Directive</a></h2> +<table class="directive"> +<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Controls what UNC host names can be accessed by the server +</td></tr> +<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>UNCList<var>hostname</var> ...</code></td></tr> +<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>unset</code></td></tr> +<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config</td></tr> +<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Core</td></tr> +<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>core</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Added in 2.4.60, Windows only.</td></tr> +</table> + <p> During request processing, requests to access a filesystem path that + resolves to a UNC path will fail unless the hostname in the UNC path + has been specified by this directive. The intent is to limit access to + paths derived from untrusted inputs.</p> + +<div class="warning"><h3>Security</h3> +<p>UNC paths accessed outside of request processing, such as during startup, +are not checked against the hosts configured with this directive.</p> +</div> + +</div> +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="directive-section"><h2><a name="UnDefine" id="UnDefine">UnDefine</a> <a name="undefine" id="undefine">Directive</a></h2> <table class="directive"> <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Undefine the existence of a variable</td></tr> diff --git a/docs/manual/mod/core.html.es b/docs/manual/mod/core.html.es index 50b2510..a563573 100644 --- a/docs/manual/mod/core.html.es +++ b/docs/manual/mod/core.html.es @@ -132,6 +132,7 @@ <li><img alt="" src="../images/down.gif" /> <a href="#stricthostcheck">StrictHostCheck</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#timeout">TimeOut</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#traceenable">TraceEnable</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#unclist">UNCList</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#undefine">UnDefine</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalname">UseCanonicalName</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></li> @@ -4318,6 +4319,20 @@ certain events before failing a request</td></tr> </div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="directive-section"><h2><a name="unclist" id="unclist">Directiva</a> <a name="UNCList" id="UNCList">UNCList</a></h2> +<table class="directive"> +<tr><th><a href="directive-dict.html#Description">Descripción:</a></th><td>Controls what UNC host names can be accessed by the server +</td></tr> +<tr><th><a href="directive-dict.html#Syntax">Sintaxis:</a></th><td><code>UNCList<var>hostname</var> ...</code></td></tr> +<tr><th><a href="directive-dict.html#Default">Valor por defecto:</a></th><td><code>unset</code></td></tr> +<tr><th><a href="directive-dict.html#Context">Contexto:</a></th><td>server config</td></tr> +<tr><th><a href="directive-dict.html#Status">Estado:</a></th><td>Core</td></tr> +<tr><th><a href="directive-dict.html#Module">Módulo:</a></th><td>core</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Compatibilidad:</a></th><td>Added in 2.4.60, Windows only.</td></tr> +</table><p>The documentation for this directive has + not been translated yet. Please have a look at the English + version.</p></div> +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="directive-section"><h2><a name="undefine" id="undefine">Directiva</a> <a name="UnDefine" id="UnDefine">UnDefine</a></h2> <table class="directive"> <tr><th><a href="directive-dict.html#Description">Descripción:</a></th><td>Undefine the existence of a variable</td></tr> diff --git a/docs/manual/mod/core.html.fr.utf8 b/docs/manual/mod/core.html.fr.utf8 index 40b654d..4ca5ec6 100644 --- a/docs/manual/mod/core.html.fr.utf8 +++ b/docs/manual/mod/core.html.fr.utf8 @@ -33,6 +33,8 @@ <a href="../ja/mod/core.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> | <a href="../tr/mod/core.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a></p> </div> +<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version + anglaise pour les changements récents.</div> <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Fonctionnalités de base du serveur HTTP Apache toujours disponibles</td></tr> <tr><th><a href="module-dict.html#Status">Statut:</a></th><td>Noyau httpd</td></tr></table> @@ -129,6 +131,7 @@ disponibles</td></tr> <li><img alt="" src="../images/down.gif" /> <a href="#stricthostcheck">StrictHostCheck</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#timeout">TimeOut</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#traceenable">TraceEnable</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#unclist">UNCList</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#undefine">UnDefine</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalname">UseCanonicalName</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></li> @@ -5353,6 +5356,20 @@ dernière. </div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="directive-section"><h2><a name="unclist" id="unclist">Directive</a> <a name="UNCList" id="UNCList">UNCList</a></h2> +<table class="directive"> +<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Controls what UNC host names can be accessed by the server +</td></tr> +<tr><th><a href="directive-dict.html#Syntax">Syntaxe:</a></th><td><code>UNCList<var>hostname</var> ...</code></td></tr> +<tr><th><a href="directive-dict.html#Default">Défaut:</a></th><td><code>unset</code></td></tr> +<tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale</td></tr> +<tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Noyau httpd</td></tr> +<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>core</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Added in 2.4.60, Windows only.</td></tr> +</table><p>La documentation de cette directive + n'a pas encore t traduite. Veuillez vous reporter la version + en langue anglaise.</p></div> +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="directive-section"><h2><a name="undefine" id="undefine">Directive</a> <a name="UnDefine" id="UnDefine">UnDefine</a></h2> <table class="directive"> <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Invalide la définition d'une variable</td></tr> diff --git a/docs/manual/mod/core.html.ja.utf8 b/docs/manual/mod/core.html.ja.utf8 index 5a294e4..e807744 100644 --- a/docs/manual/mod/core.html.ja.utf8 +++ b/docs/manual/mod/core.html.ja.utf8 @@ -132,6 +132,7 @@ <li><img alt="" src="../images/down.gif" /> <a href="#stricthostcheck">StrictHostCheck</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#timeout">TimeOut</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#traceenable">TraceEnable</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#unclist">UNCList</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#undefine">UnDefine</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalname">UseCanonicalName</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></li> @@ -3547,6 +3548,20 @@ of a request or the last 63, assuming the request itself is greater than </div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="directive-section"><h2><a name="UNCList" id="UNCList">UNCList</a> <a name="unclist" id="unclist">ディレクティブ</a></h2> +<table class="directive"> +<tr><th><a href="directive-dict.html#Description">説明:</a></th><td>Controls what UNC host names can be accessed by the server +</td></tr> +<tr><th><a href="directive-dict.html#Syntax">構文:</a></th><td><code>UNCList<var>hostname</var> ...</code></td></tr> +<tr><th><a href="directive-dict.html#Default">デフォルト:</a></th><td><code>unset</code></td></tr> +<tr><th><a href="directive-dict.html#Context">コンテã‚スト:</a></th><td>サーãƒè¨å®šãƒ•ã‚¡ã‚¤ãƒ«</td></tr> +<tr><th><a href="directive-dict.html#Status">ステータス:</a></th><td>Core</td></tr> +<tr><th><a href="directive-dict.html#Module">モジュール:</a></th><td>core</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">互æ›æ€§:</a></th><td>Added in 2.4.60, Windows only.</td></tr> +</table><p>ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒ†ã‚£ãƒ–ã®è§£èª¬æ–‡æ›¸ã¯ + ã¾ã 翻訳ã•ã‚Œã¦ã„ã¾ã›ã‚“。英語版をã”覧ãã ã•ã„。 + </p></div> +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="directive-section"><h2><a name="UnDefine" id="UnDefine">UnDefine</a> <a name="undefine" id="undefine">ディレクティブ</a></h2> <table class="directive"> <tr><th><a href="directive-dict.html#Description">説明:</a></th><td>Undefine the existence of a variable</td></tr> diff --git a/docs/manual/mod/core.html.tr.utf8 b/docs/manual/mod/core.html.tr.utf8 index 11932a4..c3743b8 100644 --- a/docs/manual/mod/core.html.tr.utf8 +++ b/docs/manual/mod/core.html.tr.utf8 @@ -130,6 +130,7 @@ <li><img alt="" src="../images/down.gif" /> <a href="#stricthostcheck">StrictHostCheck</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#timeout">TimeOut</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#traceenable">TraceEnable</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#unclist">UNCList</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#undefine">UnDefine</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalname">UseCanonicalName</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#usecanonicalphysicalport">UseCanonicalPhysicalPort</a></li> @@ -4966,6 +4967,19 @@ gerçekleÅŸmesi için sunucunun geçmesini bekleyeceÄŸi süre.</td></tr> </div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="directive-section"><h2><a name="UNCList" id="UNCList">UNCList</a> <a name="unclist" id="unclist">Yönergesi</a></h2> +<table class="directive"> +<tr><th><a href="directive-dict.html#Description">Açıklama:</a></th><td>Controls what UNC host names can be accessed by the server +</td></tr> +<tr><th><a href="directive-dict.html#Syntax">Sözdizimi:</a></th><td><code>UNCList<var>hostname</var> ...</code></td></tr> +<tr><th><a href="directive-dict.html#Default">Öntanımlı:</a></th><td><code>unset</code></td></tr> +<tr><th><a href="directive-dict.html#Context">BaÄŸlam:</a></th><td>sunucu geneli</td></tr> +<tr><th><a href="directive-dict.html#Status">Durum:</a></th><td>Çekirdek</td></tr> +<tr><th><a href="directive-dict.html#Module">Modül:</a></th><td>core</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Uyumluluk:</a></th><td>Added in 2.4.60, Windows only.</td></tr> +</table><p>Bu yönergenin belgesi henüz Türkçeye çevrilmedi. + Lütfen Ä°ngilizce sürümüne bakınız.</p></div> +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="directive-section"><h2><a name="UnDefine" id="UnDefine">UnDefine</a> <a name="undefine" id="undefine">Yönergesi</a></h2> <table class="directive"> <tr><th><a href="directive-dict.html#Description">Açıklama:</a></th><td>Bir deÄŸiÅŸkeni tanımsız yapar</td></tr> diff --git a/docs/manual/mod/directives.html.de b/docs/manual/mod/directives.html.de index 2bb06ef..876ec34 100644 --- a/docs/manual/mod/directives.html.de +++ b/docs/manual/mod/directives.html.de @@ -758,7 +758,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.en b/docs/manual/mod/directives.html.en index 07767f1..5462e48 100644 --- a/docs/manual/mod/directives.html.en +++ b/docs/manual/mod/directives.html.en @@ -759,7 +759,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.es b/docs/manual/mod/directives.html.es index 9237b3c..dd79c46 100644 --- a/docs/manual/mod/directives.html.es +++ b/docs/manual/mod/directives.html.es @@ -761,7 +761,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.fr.utf8 b/docs/manual/mod/directives.html.fr.utf8 index 0e6bd66..66686a9 100644 --- a/docs/manual/mod/directives.html.fr.utf8 +++ b/docs/manual/mod/directives.html.fr.utf8 @@ -759,7 +759,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.ja.utf8 b/docs/manual/mod/directives.html.ja.utf8 index 9a0da55..4466637 100644 --- a/docs/manual/mod/directives.html.ja.utf8 +++ b/docs/manual/mod/directives.html.ja.utf8 @@ -756,7 +756,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.ko.euc-kr b/docs/manual/mod/directives.html.ko.euc-kr index 948fac1..d7705ab 100644 --- a/docs/manual/mod/directives.html.ko.euc-kr +++ b/docs/manual/mod/directives.html.ko.euc-kr @@ -756,7 +756,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.tr.utf8 b/docs/manual/mod/directives.html.tr.utf8 index 97fb3da..974d38d 100644 --- a/docs/manual/mod/directives.html.tr.utf8 +++ b/docs/manual/mod/directives.html.tr.utf8 @@ -755,7 +755,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/directives.html.zh-cn.utf8 b/docs/manual/mod/directives.html.zh-cn.utf8 index 9fca514..de61046 100644 --- a/docs/manual/mod/directives.html.zh-cn.utf8 +++ b/docs/manual/mod/directives.html.zh-cn.utf8 @@ -754,7 +754,8 @@ <li><a href="core.html#traceenable">TraceEnable</a></li> <li><a href="mod_log_config.html#transferlog">TransferLog</a></li> <li><a href="mod_mime.html#typesconfig">TypesConfig</a></li> -<li><a href="core.html#undefine" id="U" name="U">UnDefine</a></li> +<li><a href="core.html#unclist" id="U" name="U">UNCList</a></li> +<li><a href="core.html#undefine">UnDefine</a></li> <li><a href="mod_macro.html#undefmacro">UndefMacro</a></li> <li><a href="mod_env.html#unsetenv">UnsetEnv</a></li> <li><a href="mod_macro.html#use">Use</a></li> diff --git a/docs/manual/mod/mod_alias.html.fr.utf8 b/docs/manual/mod/mod_alias.html.fr.utf8 index cf2e298..5e82940 100644 --- a/docs/manual/mod/mod_alias.html.fr.utf8 +++ b/docs/manual/mod/mod_alias.html.fr.utf8 @@ -32,8 +32,6 @@ <a href="../ko/mod/mod_alias.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> | <a href="../tr/mod/mod_alias.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a></p> </div> -<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.</div> <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Permet d'atteindre différentes parties du système de fichiers depuis l'arborescence des documents du site web, ainsi que la redirection d'URL</td></tr> @@ -322,7 +320,7 @@ en faisant intervenir les expressions rationnelles</td></tr> <tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale, serveur virtuel, répertoire</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Base</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_alias</td></tr> -<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.5.1 du serveur HTTP Apache</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.4.58 du serveur HTTP Apache.</td></tr> </table> <p>Lorsqu'on utilise la version à deux paramètres de la directive <code class="directive">Alias</code>, le chemin complet après l'alias est préservé. diff --git a/docs/manual/mod/mod_cgi.html.fr.utf8 b/docs/manual/mod/mod_cgi.html.fr.utf8 index 5b6c3fa..0edcf50 100644 --- a/docs/manual/mod/mod_cgi.html.fr.utf8 +++ b/docs/manual/mod/mod_cgi.html.fr.utf8 @@ -31,8 +31,6 @@ <a href="../ja/mod/mod_cgi.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a> | <a href="../ko/mod/mod_cgi.html" hreflang="ko" rel="alternate" title="Korean"> ko </a></p> </div> -<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.</div> <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Exécution des scripts CGI</td></tr> <tr><th><a href="module-dict.html#Status">Statut:</a></th><td>Base</td></tr> <tr><th><a href="module-dict.html#ModuleIdentifier">Identificateur de Module:</a></th><td>cgi_module</td></tr> @@ -210,6 +208,7 @@ CGI</a></li> <tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale, serveur virtuel, répertoire, .htaccess</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Base</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_cgi</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.4.59 du serveur HTTP Apache.</td></tr> </table> <p>Cette directive permet de limiter le temps d'attente jusqu'à une prochaine sortie du programme CGI. Si ce temps est dépassé, le traitement de diff --git a/docs/manual/mod/mod_http2.html.fr.utf8 b/docs/manual/mod/mod_http2.html.fr.utf8 index 5b69e27..28864b0 100644 --- a/docs/manual/mod/mod_http2.html.fr.utf8 +++ b/docs/manual/mod/mod_http2.html.fr.utf8 @@ -29,8 +29,6 @@ <p><span>Langues Disponibles: </span><a href="../en/mod/mod_http2.html" hreflang="en" rel="alternate" title="English"> en </a> | <a href="../fr/mod/mod_http2.html" title="Français"> fr </a></p> </div> -<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.</div> <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Support de la couche transport HTTP/2</td></tr> <tr><th><a href="module-dict.html#Status">Statut:</a></th><td>Extension</td></tr> <tr><th><a href="module-dict.html#ModuleIdentifier">Identificateur de Module:</a></th><td>http2_module</td></tr> @@ -634,7 +632,7 @@ <tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale, serveur virtuel</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Extension</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_http2</td></tr> -<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.5.1 du serveur HTTP +<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.4.58 du serveur HTTP Apache</td></tr> </table> <p> @@ -1158,7 +1156,7 @@ H2PushPriority text/css interleaved # poids de 256 par défaut</pre> <tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale, serveur virtuel</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Extension</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_http2</td></tr> -<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.5.1 du serveur HTTP +<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Disponible à partir de la version 2.4.58 du serveur HTTP Apache</td></tr> </table> <p> diff --git a/docs/manual/mod/mod_proxy.html.fr.utf8 b/docs/manual/mod/mod_proxy.html.fr.utf8 index d05e64e..515a795 100644 --- a/docs/manual/mod/mod_proxy.html.fr.utf8 +++ b/docs/manual/mod/mod_proxy.html.fr.utf8 @@ -30,8 +30,6 @@ <a href="../fr/mod/mod_proxy.html" title="Français"> fr </a> | <a href="../ja/mod/mod_proxy.html" hreflang="ja" rel="alternate" title="Japanese"> ja </a></p> </div> -<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.</div> <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Serveur mandataire/passerelle multi-protocole</td></tr> <tr><th><a href="module-dict.html#Status">Statut:</a></th><td>Extension</td></tr> <tr><th><a href="module-dict.html#ModuleIdentifier">Identificateur de Module:</a></th><td>proxy_module</td></tr> @@ -2216,7 +2214,7 @@ requêtes</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Extension</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy</td></tr> <tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Le troisième argument facultatif est disponible depuis la version -2.5.1 du serveur HTTP Apache.</td></tr> +2.4.59 du serveur HTTP Apache.</td></tr> </table> <p>Cette directive permet de définir des mandataires distants pour ce mandataire. <var>match</var> est soit le nom d'un protocole @@ -2264,10 +2262,12 @@ ProxyRemote "ftp" "http://ftpproxy.mydomain:8080"</pre> <table class="directive"> <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Le mandataire distant à utiliser pour traiter les requêtes correspondant à une expression rationnelle</td></tr> -<tr><th><a href="directive-dict.html#Syntax">Syntaxe:</a></th><td><code>ProxyRemoteMatch <var>regex</var> <var>serveur-distant</var></code></td></tr> +<tr><th><a href="directive-dict.html#Syntax">Syntaxe:</a></th><td><code>ProxyRemoteMatch <var>regex</var> <var>remote-server</var> [<var>username:password</var>]</code></td></tr> <tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale, serveur virtuel</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Extension</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy</td></tr> +<tr><th><a href="directive-dict.html#Compatibility">Compatibilité:</a></th><td>Le troisième argument facultatif est disponible à partir de la +version 2.4.59 du serveur HTTP Apache.</td></tr> </table> <p>La directive <code class="directive">ProxyRemoteMatch</code> est identique à la directive <code class="directive"><a href="#proxyremote">ProxyRemote</a></code>, à l'exception du diff --git a/docs/manual/mod/mod_remoteip.html.en b/docs/manual/mod/mod_remoteip.html.en index 077e5c4..8d69612 100644 --- a/docs/manual/mod/mod_remoteip.html.en +++ b/docs/manual/mod/mod_remoteip.html.en @@ -134,6 +134,7 @@ via the request headers. <table class="directive"> <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Declare the header field which should be parsed for useragent IP addresses</td></tr> <tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>RemoteIPHeader <var>header-field</var></code></td></tr> +<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>none</code></td></tr> <tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr> <tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Base</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_remoteip</td></tr> diff --git a/docs/manual/mod/mod_remoteip.html.fr.utf8 b/docs/manual/mod/mod_remoteip.html.fr.utf8 index 44b3fe8..5655a91 100644 --- a/docs/manual/mod/mod_remoteip.html.fr.utf8 +++ b/docs/manual/mod/mod_remoteip.html.fr.utf8 @@ -142,6 +142,7 @@ Spec</a></li> <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Définit le champ d'en-tête qui contiendra les adresses IP du client</td></tr> <tr><th><a href="directive-dict.html#Syntax">Syntaxe:</a></th><td><code>RemoteIPHeader <var>en-tête</var></code></td></tr> +<tr><th><a href="directive-dict.html#Default">Défaut:</a></th><td><code>none</code></td></tr> <tr><th><a href="directive-dict.html#Context">Contexte:</a></th><td>configuration globale, serveur virtuel</td></tr> <tr><th><a href="directive-dict.html#Status">Statut:</a></th><td>Base</td></tr> <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_remoteip</td></tr> diff --git a/docs/manual/mod/mod_rewrite.html.en b/docs/manual/mod/mod_rewrite.html.en index a46bb22..83bce1b 100644 --- a/docs/manual/mod/mod_rewrite.html.en +++ b/docs/manual/mod/mod_rewrite.html.en @@ -1451,6 +1451,18 @@ cannot use <code>$N</code> in the substitution string! <td>Force the <a class="glossarylink" href="../glossary.html#mime-type" title="see glossary">MIME-type</a> of the target file to be the specified type. <em><a href="../rewrite/flags.html#flag_t">details ...</a></em></td> </tr> +<tr class="odd"> + <td>UnsafeAllow3F</td> + <td>Allows substitutions from URL's that may be unsafe. + <em><a href="../rewrite/flags.html#flag_unsafe_allow_3f">details ...</a></em> + </td> + </tr> +<tr> + <td>UnsafePrefixStat</td> + <td>Allows potentially unsafe substitutions from a leading variable or backreference to a filesystem path. + <em><a href="../rewrite/flags.html#flag_unsafe_prefix_stat">details ...</a></em> + </td> + </tr> </table> <div class="note"><h3>Home directory expansion</h3> diff --git a/docs/manual/mod/mod_rewrite.html.fr.utf8 b/docs/manual/mod/mod_rewrite.html.fr.utf8 index 8a5eaf0..621d369 100644 --- a/docs/manual/mod/mod_rewrite.html.fr.utf8 +++ b/docs/manual/mod/mod_rewrite.html.fr.utf8 @@ -29,6 +29,8 @@ <p><span>Langues Disponibles: </span><a href="../en/mod/mod_rewrite.html" hreflang="en" rel="alternate" title="English"> en </a> | <a href="../fr/mod/mod_rewrite.html" title="Français"> fr </a></p> </div> +<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version + anglaise pour les changements récents.</div> <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Ce module fournit un moteur de réécriture à base de règles permettant de réécrire les URLs des requêtes à la volée</td></tr> diff --git a/docs/manual/mod/quickreference.html.de b/docs/manual/mod/quickreference.html.de index b4edcfc..eb417c0 100644 --- a/docs/manual/mod/quickreference.html.de +++ b/docs/manual/mod/quickreference.html.de @@ -1197,48 +1197,50 @@ bevor er die Anfrage abbricht</td></tr> <tr class="odd"><td><a href="core.html#traceenable">TraceEnable <var>[on|off|extended]</var></a></td><td> on </td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Legt das Verhalten von <code>TRACE</code>-Anfragen fest</td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>file</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Specify location of a log file</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The location of the <code>mime.types</code> file</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Removes variables from the environment</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Bestimmt, wie der Server seinen eigenen Namen und Port +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server +</td></tr> +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Removes variables from the environment</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Bestimmt, wie der Server seinen eigenen Namen und Port ermittelt</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Bestimmt, wie der Server seinen eigenen Namen und Port +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Bestimmt, wie der Server seinen eigenen Namen und Port ermittelt</td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">The userid under which the server will answer +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The userid under which the server will answer requests</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... -</a></td><td></td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Location of the user-specific directories</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... +</a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Location of the user-specific directories</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>Adresse</var>[:<var>Port</var>] [<var>Adresse</var>[:<var>Port</var>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Enthält Direktiven, die nur auf bestimmte Hostnamen oder + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Enthält Direktiven, die nur auf bestimmte Hostnamen oder IP-Adressen angewendet werden</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Parse SSI directives in files with the execute bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Parse SSI directives in files with the execute bit set</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>Verfügbare Sprachen: </span><a href="../de/mod/quickreference.html" title="Deutsch"> de </a> | diff --git a/docs/manual/mod/quickreference.html.en b/docs/manual/mod/quickreference.html.en index 3e7f812..9da6b32 100644 --- a/docs/manual/mod/quickreference.html.en +++ b/docs/manual/mod/quickreference.html.en @@ -1183,47 +1183,49 @@ certain events before failing a request</td></tr> <tr class="odd"><td><a href="core.html#traceenable">TraceEnable <var>[on|off|extended]</var></a></td><td> on </td><td>sv</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Determines the behavior on <code>TRACE</code> requests</td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>file</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Specify location of a log file</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The location of the <code>mime.types</code> file</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Removes variables from the environment</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own name and +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server +</td></tr> +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Removes variables from the environment</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own name and port</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own port</td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">The userid under which the server will answer +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own port</td></tr> +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The userid under which the server will answer requests</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... -</a></td><td></td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Location of the user-specific directories</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... +</a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Location of the user-specific directories</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>addr</var>[:<var>port</var>] [<var>addr</var>[:<var>port</var>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Contains directives that apply only to a specific + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Contains directives that apply only to a specific hostname or IP address</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Parse SSI directives in files with the execute bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Parse SSI directives in files with the execute bit set</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>Available Languages: </span><a href="../de/mod/quickreference.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | diff --git a/docs/manual/mod/quickreference.html.es b/docs/manual/mod/quickreference.html.es index 276a868..84d952f 100644 --- a/docs/manual/mod/quickreference.html.es +++ b/docs/manual/mod/quickreference.html.es @@ -1186,48 +1186,50 @@ certain events before failing a request</td></tr> <tr class="odd"><td><a href="core.html#traceenable">TraceEnable <var>[on|off|extended]</var></a></td><td> on </td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Determines the behaviour on <code>TRACE</code> requests</td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>file</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Specify location of a log file</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The location of the <code>mime.types</code> file</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Removes variables from the environment</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own name and +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server +</td></tr> +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Removes variables from the environment</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own name and port</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own name and +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own name and port</td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">The userid under which the server will answer +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The userid under which the server will answer requests</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... -</a></td><td></td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Location of the user-specific directories</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... +</a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Location of the user-specific directories</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>addr</var>[:<var>port</var>] [<var>addr</var>[:<var>port</var>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Contains directives that apply only to a specific + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Contains directives that apply only to a specific hostname or IP address</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Parse SSI directives in files with the execute bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Parse SSI directives in files with the execute bit set</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>Idiomas disponibles: </span><a href="../de/mod/quickreference.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | diff --git a/docs/manual/mod/quickreference.html.fr.utf8 b/docs/manual/mod/quickreference.html.fr.utf8 index 69d928c..4b795fa 100644 --- a/docs/manual/mod/quickreference.html.fr.utf8 +++ b/docs/manual/mod/quickreference.html.fr.utf8 @@ -1095,7 +1095,7 @@ du mandataire</td></tr> et FTP</td></tr> <tr><td><a href="mod_proxy.html#proxyremote">ProxyRemote <var>match</var> <var>remote-server</var> [<var>username:password</var>]</a></td><td></td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Mandataire distant à utiliser pour traiter certaines requêtes</td></tr> -<tr class="odd"><td><a href="mod_proxy.html#proxyremotematch">ProxyRemoteMatch <var>regex</var> <var>serveur-distant</var></a></td><td></td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Le mandataire distant à utiliser pour traiter les requêtes +<tr class="odd"><td><a href="mod_proxy.html#proxyremotematch">ProxyRemoteMatch <var>regex</var> <var>remote-server</var> [<var>username:password</var>]</a></td><td></td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Le mandataire distant à utiliser pour traiter les requêtes correspondant à une expression rationnelle</td></tr> <tr><td><a href="mod_proxy.html#proxyrequests">ProxyRequests On|Off</a></td><td> Off </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Active la fonctionnalité (standard) de mandataire direct</td></tr> @@ -1516,53 +1516,55 @@ traitent les connexions clients</td></tr> <code>TRACE</code></td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>fichier</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Spécifie l'emplacement d'un fichier journal</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>chemin-fichier</var></a></td><td> conf/mime.types </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Le chemin du fichier <code>mime.types</code></td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>nom-variable</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Invalide la définition d'une variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>nom</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Supprime une macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>var-env</var> [<var>var-env</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Supprime des variables de l'environnement</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>nom</var> [<var>valeur1</var> ... <var>valeurN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Utilisation d'une macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Définit la manière dont le serveur détermine son propre nom +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server +</td></tr> +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>nom-variable</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Invalide la définition d'une variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>nom</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Supprime une macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>var-env</var> [<var>var-env</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Supprime des variables de l'environnement</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>nom</var> [<var>valeur1</var> ... <var>valeurN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Utilisation d'une macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Définit la manière dont le serveur détermine son propre nom et son port</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Définit la manière dont le serveur +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Définit la manière dont le serveur détermine son propre port</td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>utilisateur unix</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">L'utilisateur sous lequel le serveur va traiter les +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>utilisateur unix</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">L'utilisateur sous lequel le serveur va traiter les requêtes</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>nom-répertoire</em> [<em>nom-répertoire</em>] ... -</a></td><td></td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Chemin des répertoires propres à un +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>nom-répertoire</em> [<em>nom-répertoire</em>] ... +</a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Chemin des répertoires propres à un utilisateur</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Détermine si le serveur virtuel peut exécuter des +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Détermine si le serveur virtuel peut exécuter des sous-processus, et définit les privilèges disponibles pour ces dernier.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assigne des privilèges au choix aux sous-processus créés +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assigne des privilèges au choix aux sous-processus créés par un serveur virtuel.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>identifiant-groupe-unix</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Définit l'identifiant du groupe sous lequel s'exécute un +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>identifiant-groupe-unix</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Définit l'identifiant du groupe sous lequel s'exécute un serveur virtuel.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>nom-privilège</var> [[+-]?nom-privilège] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assigne des privilèges à un serveur virtuel.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Détermine si le serveur s'exécute avec une sécurité avancée +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>nom-privilège</var> [[+-]?nom-privilège] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assigne des privilèges à un serveur virtuel.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Détermine si le serveur s'exécute avec une sécurité avancée pour les serveurs virtuels.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>identifiant-utilisateur-unix</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Définit l'identifiant utilisateur sous lequel s'exécute un +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>identifiant-utilisateur-unix</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Définit l'identifiant utilisateur sous lequel s'exécute un serveur virtuel.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Permet une configuration dynamique de la racine des +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Permet une configuration dynamique de la racine des documents d'un serveur virtuel donné</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Configuration dynamique de la racine des documents pour un +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Configuration dynamique de la racine des documents pour un serveur virtuel donné</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>adresse IP</var>[:<var>port</var>] [<var>adresse IP</var>[:<var>port</var>]] ...> ... - </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Contient des directives qui ne s'appliquent qu'à un nom + </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Contient des directives qui ne s'appliquent qu'à un nom d'hôte spécifique ou à une adresse IP</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Configuration dynamique du répertoire des scripts CGI pour +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Configuration dynamique du répertoire des scripts CGI pour un serveur virtuel donné</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Configuration dynamique du répertoire des scripts CGI pour +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>répertoire-interpolé</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Configuration dynamique du répertoire des scripts CGI pour un serveur virtuel donné</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Intervalle Watchdog en secondes</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Interprète les directives SSI dans les fichiers dont le bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Intervalle Watchdog en secondes</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Interprète les directives SSI dans les fichiers dont le bit d'exécution est positionné</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>jeu-de-caractères alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Définit des alias pour les valeurs d'encodage</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>nom</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Définit un encodage par défaut à utiliser lorsqu'aucune +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>jeu-de-caractères alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Définit des alias pour les valeurs d'encodage</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>nom</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Définit un encodage par défaut à utiliser lorsqu'aucune information ne peut être <a href="#sniffing">automatiquement détectée</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>élément [élément ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Indique à l'interpréteur à partir de quelle balise il doit +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>élément [élément ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Indique à l'interpréteur à partir de quelle balise il doit commencer son traitement.</td></tr> </table></div> <div class="bottomlang"> diff --git a/docs/manual/mod/quickreference.html.ja.utf8 b/docs/manual/mod/quickreference.html.ja.utf8 index 0bc3af4..fa80388 100644 --- a/docs/manual/mod/quickreference.html.ja.utf8 +++ b/docs/manual/mod/quickreference.html.ja.utf8 @@ -1114,46 +1114,48 @@ Certificate verification</td></tr> </td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>file</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">ãƒã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã®ä½ç½®ã‚’指定</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td /></tr><tr class="odd"><td class="descr" colspan="4"><code>mime.types</code> ファイルã®ä½ç½®</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">環境ã‹ã‚‰å¤‰æ•°ã‚’å–り除ã</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|Dns</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">サーãƒãŒè‡ªåˆ†è‡ªèº«ã®åå‰ã¨ãƒãƒ¼ãƒˆã‚’決定ã™ã‚‹æ–¹æ³•ã‚’è¨å®šã™ã‚‹</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">自分自身ã®åå‰ã¨ãƒãƒ¼ãƒˆç•ªå·ã‚’解決ã™ã‚‹æ–¹æ³•ã‚’è¨å®šã™ã‚‹ +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server </td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">The userid under which the server will answer +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">環境ã‹ã‚‰å¤‰æ•°ã‚’å–り除ã</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|Dns</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">サーãƒãŒè‡ªåˆ†è‡ªèº«ã®åå‰ã¨ãƒãƒ¼ãƒˆã‚’決定ã™ã‚‹æ–¹æ³•ã‚’è¨å®šã™ã‚‹</td></tr> +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">自分自身ã®åå‰ã¨ãƒãƒ¼ãƒˆç•ªå·ã‚’解決ã™ã‚‹æ–¹æ³•ã‚’è¨å®šã™ã‚‹ +</td></tr> +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The userid under which the server will answer requests</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ...</a></td><td></td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">ユーザ専用ディレクトリã®ä½ç½®</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ...</a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">ユーザ専用ディレクトリã®ä½ç½®</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>addr</var>[:<var>port</var>] [<var>addr</var>[:<var>port</var>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">特定ã®ãƒ›ã‚¹ãƒˆåã‚„ IP アドレスã®ã¿ã«é©ç”¨ã•ã‚Œã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒ†ã‚£ãƒ–ã‚’ + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">特定ã®ãƒ›ã‚¹ãƒˆåã‚„ IP アドレスã®ã¿ã«é©ç”¨ã•ã‚Œã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒ†ã‚£ãƒ–ã‚’ 囲む</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">実行ビットãŒè¨å®šã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã® SSI ディレクティブを +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">実行ビットãŒè¨å®šã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã® SSI ディレクティブを 解æžã™ã‚‹</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>翻訳済ã¿è¨€èªž: </span><a href="../de/mod/quickreference.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | diff --git a/docs/manual/mod/quickreference.html.ko.euc-kr b/docs/manual/mod/quickreference.html.ko.euc-kr index 1d0cc89..60a7ae2 100644 --- a/docs/manual/mod/quickreference.html.ko.euc-kr +++ b/docs/manual/mod/quickreference.html.ko.euc-kr @@ -1142,46 +1142,48 @@ certain events before failing a request</td></tr> <tr class="odd"><td><a href="core.html#traceenable">TraceEnable <var>[on|off|extended]</var></a></td><td> on </td><td>sv</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Determines the behavior on <code>TRACE</code> requests</td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>file</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">·Î±×ÆÄÀÏ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The location of the <code>mime.types</code> file</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">ȯ°æº¯¼ö¸¦ Á¦°ÅÇÑ´Ù</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own name and +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server +</td></tr> +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">ȯ°æº¯¼ö¸¦ Á¦°ÅÇÑ´Ù</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own name and port</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own port</td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">The userid under which the server will answer +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own port</td></tr> +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The userid under which the server will answer requests</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em></a></td><td> public_html </td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">»ç¿ëÀÚº° µð·ºÅ丮 À§Ä¡</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em></a></td><td> public_html </td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">»ç¿ëÀÚº° µð·ºÅ丮 À§Ä¡</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>addr</var>[:<var>port</var>] [<var>addr</var>[:<var>port</var>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Contains directives that apply only to a specific + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Contains directives that apply only to a specific hostname or IP address</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Parse SSI directives in files with the execute bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Parse SSI directives in files with the execute bit set</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>°¡´ÉÇÑ ¾ð¾î: </span><a href="../de/mod/quickreference.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | diff --git a/docs/manual/mod/quickreference.html.tr.utf8 b/docs/manual/mod/quickreference.html.tr.utf8 index f639b7d..2c5261e 100644 --- a/docs/manual/mod/quickreference.html.tr.utf8 +++ b/docs/manual/mod/quickreference.html.tr.utf8 @@ -1181,46 +1181,48 @@ gerçekleÅŸmesi için sunucunun geçmesini bekleyeceÄŸi süre.</td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>dosya</var>|<var>borulu-süreç</var> [<var>takma-ad</var>]</a></td><td></td><td>sk</td><td>T</td></tr><tr><td class="descr" colspan="4">Bir günlük dosyasının yerini belirtir.</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">The location of the <code>mime.types</code> file</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <code>deÄŸiÅŸken-ismi</code></a></td><td></td><td>s</td><td>Ç</td></tr><tr><td class="descr" colspan="4">Bir deÄŸiÅŸkeni tanımsız yapar</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>skd</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>ortam-deÄŸiÅŸkeni</var> [<var>ortam-deÄŸiÅŸkeni</var>] -...</a></td><td></td><td>skdh</td><td>T</td></tr><tr><td class="descr" colspan="4">Ortamdaki deÄŸiÅŸkenleri tanımsız hale getirir.</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>skd</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>skd</td><td>Ç</td></tr><tr><td class="descr" colspan="4">Sunucunun kendi adını ve portunu nasıl belirleyeceÄŸini ayarlar +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>Ç</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server </td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>skd</td><td>Ç</td></tr><tr class="odd"><td class="descr" colspan="4">Sunucunun kendi adını ve portunu nasıl belirleyeceÄŸini ayarlar +<tr class="odd"><td><a href="core.html#undefine">UnDefine <code>deÄŸiÅŸken-ismi</code></a></td><td></td><td>s</td><td>Ç</td></tr><tr class="odd"><td class="descr" colspan="4">Bir deÄŸiÅŸkeni tanımsız yapar</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>skd</td><td>T</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>ortam-deÄŸiÅŸkeni</var> [<var>ortam-deÄŸiÅŸkeni</var>] +...</a></td><td></td><td>skdh</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Ortamdaki deÄŸiÅŸkenleri tanımsız hale getirir.</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>skd</td><td>T</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>skd</td><td>Ç</td></tr><tr class="odd"><td class="descr" colspan="4">Sunucunun kendi adını ve portunu nasıl belirleyeceÄŸini ayarlar </td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-kullanıcısı</var></a></td><td> #-1 </td><td>s</td><td>T</td></tr><tr><td class="descr" colspan="4">Ä°steklere yanıt verecek sunucunun ait olacağı kullanıcıyı +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>skd</td><td>Ç</td></tr><tr><td class="descr" colspan="4">Sunucunun kendi adını ve portunu nasıl belirleyeceÄŸini ayarlar +</td></tr> +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-kullanıcısı</var></a></td><td> #-1 </td><td>s</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Ä°steklere yanıt verecek sunucunun ait olacağı kullanıcıyı belirler.</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>dizin</em> [<em>dizin</em>] ...</a></td><td></td><td>sk</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Kullanıcıya özel dizinlerin yeri</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>k</td><td>D</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>dizin</em> [<em>dizin</em>] ...</a></td><td></td><td>sk</td><td>T</td></tr><tr><td class="descr" colspan="4">Kullanıcıya özel dizinlerin yeri</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>k</td><td>D</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>k</td><td>D</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>k</td><td>D</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>k</td><td>D</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>k</td><td>D</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>k</td><td>D</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>k</td><td>D</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>k</td><td>D</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>k</td><td>D</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>k</td><td>D</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr><td class="descr" colspan="4">Bir sanal konağın belge kök dizinini devingen olarak yapılandırır. +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>k</td><td>D</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Bir sanal konağın belge kök dizinini devingen olarak yapılandırır. </td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Bir sanal konağın belge kök dizinini devingen olarak yapılandırır. +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr><td class="descr" colspan="4">Bir sanal konağın belge kök dizinini devingen olarak yapılandırır. </td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <code>adres</code>[:<code>port</code>] [<code>adres</code>[:<code>port</code>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>Ç</td></tr><tr><td class="descr" colspan="4">Sadece belli bir konak ismine ve porta uygulanacak yönergeleri barındırır.</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Bir sanal konağın CGI dizinini devingen olarak yapılandırır. + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>Ç</td></tr><tr class="odd"><td class="descr" colspan="4">Sadece belli bir konak ismine ve porta uygulanacak yönergeleri barındırır.</td></tr> +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr><td class="descr" colspan="4">Bir sanal konağın CGI dizinini devingen olarak yapılandırır. </td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr><td class="descr" colspan="4">Bir sanal konağın CGI dizinini devingen olarak yapılandırır. +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>hesaplanan-dizin</em>|none</a></td><td> none </td><td>sk</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Bir sanal konağın CGI dizinini devingen olarak yapılandırır. </td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>skdh</td><td>T</td></tr><tr><td class="descr" colspan="4">Parse SSI directives in files with the execute bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>T</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>skdh</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Parse SSI directives in files with the execute bit set</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>skdh</td><td>T</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>T</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>skdh</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>skdh</td><td>T</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>skdh</td><td>T</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>Mevcut Diller: </span><a href="../de/mod/quickreference.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | diff --git a/docs/manual/mod/quickreference.html.zh-cn.utf8 b/docs/manual/mod/quickreference.html.zh-cn.utf8 index 3d310fe..a358a1a 100644 --- a/docs/manual/mod/quickreference.html.zh-cn.utf8 +++ b/docs/manual/mod/quickreference.html.zh-cn.utf8 @@ -1178,47 +1178,49 @@ certain events before failing a request</td></tr> <tr class="odd"><td><a href="core.html#traceenable">TraceEnable <var>[on|off|extended]</var></a></td><td> on </td><td>sv</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Determines the behavior on <code>TRACE</code> requests</td></tr> <tr><td><a href="mod_log_config.html#transferlog">TransferLog <var>file</var>|<var>pipe</var></a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Specify location of a log file</td></tr> <tr class="odd"><td><a href="mod_mime.html#typesconfig">TypesConfig <var>file-path</var></a></td><td> conf/mime.types </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The location of the <code>mime.types</code> file</td></tr> -<tr><td><a href="core.html#undefine" id="U" name="U">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> -<tr class="odd"><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine a macro</td></tr> -<tr><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] -...</a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Removes variables from the environment</td></tr> -<tr class="odd"><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] -</a></td><td></td><td>svd</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Use a macro</td></tr> -<tr><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own name and +<tr><td><a href="core.html#unclist" id="U" name="U">UNCList<var>hostname</var> ...</a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Controls what UNC host names can be accessed by the server +</td></tr> +<tr class="odd"><td><a href="core.html#undefine">UnDefine <var>parameter-name</var></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Undefine the existence of a variable</td></tr> +<tr><td><a href="mod_macro.html#undefmacro">UndefMacro <var>name</var></a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Undefine a macro</td></tr> +<tr class="odd"><td><a href="mod_env.html#unsetenv">UnsetEnv <var>env-variable</var> [<var>env-variable</var>] +...</a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Removes variables from the environment</td></tr> +<tr><td><a href="mod_macro.html#use">Use <var>name</var> [<var>value1</var> ... <var>valueN</var>] +</a></td><td></td><td>svd</td><td>B</td></tr><tr><td class="descr" colspan="4">Use a macro</td></tr> +<tr class="odd"><td><a href="core.html#usecanonicalname">UseCanonicalName On|Off|DNS</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own name and port</td></tr> -<tr class="odd"><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Configures how the server determines its own port</td></tr> -<tr><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">The userid under which the server will answer +<tr><td><a href="core.html#usecanonicalphysicalport">UseCanonicalPhysicalPort On|Off</a></td><td> Off </td><td>svd</td><td>C</td></tr><tr><td class="descr" colspan="4">Configures how the server determines its own port</td></tr> +<tr class="odd"><td><a href="mod_unixd.html#user">User <var>unix-userid</var></a></td><td> #-1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">The userid under which the server will answer requests</td></tr> -<tr class="odd"><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... -</a></td><td></td><td>sv</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Location of the user-specific directories</td></tr> -<tr><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the virtualhost can run +<tr><td><a href="mod_userdir.html#userdir">UserDir <em>directory-filename</em> [<em>directory-filename</em>] ... +</a></td><td></td><td>sv</td><td>B</td></tr><tr><td class="descr" colspan="4">Location of the user-specific directories</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostcgimode" id="V" name="V">VHostCGIMode On|Off|Secure</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the virtualhost can run subprocesses, and the privileges available to subprocesses.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created +<tr><td><a href="mod_privileges.html#vhostcgiprivs">VHostCGIPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to subprocesses created by a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> -<tr><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Determines whether the server runs with enhanced security +<tr class="odd"><td><a href="mod_privileges.html#vhostgroup">VHostGroup <var>unix-groupid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the Group ID under which a virtual host runs.</td></tr> +<tr><td><a href="mod_privileges.html#vhostprivs">VHostPrivs [+-]?<var>privilege-name</var> [[+-]?privilege-name] ...</a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Assign arbitrary privileges to a virtual host.</td></tr> +<tr class="odd"><td><a href="mod_privileges.html#vhostsecure">VHostSecure On|Off</a></td><td> On </td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Determines whether the server runs with enhanced security for the virtualhost.</td></tr> -<tr class="odd"><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr class="odd"><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_privileges.html#vhostuser">VHostUser <var>unix-userid</var></a></td><td></td><td>v</td><td>X</td></tr><tr><td class="descr" colspan="4">Sets the User ID under which a virtual host runs.</td></tr> +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the document root +<tr><td><a href="mod_vhost_alias.html#virtualdocumentrootip">VirtualDocumentRootIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the document root for a given virtual host</td></tr> -<tr><td><a href="core.html#virtualhost"><VirtualHost +<tr class="odd"><td><a href="core.html#virtualhost"><VirtualHost <var>addr</var>[:<var>port</var>] [<var>addr</var>[:<var>port</var>]] - ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr><td class="descr" colspan="4">Contains directives that apply only to a specific + ...> ... </VirtualHost></a></td><td></td><td>s</td><td>C</td></tr><tr class="odd"><td class="descr" colspan="4">Contains directives that apply only to a specific hostname or IP address</td></tr> -<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr><td><a href="mod_vhost_alias.html#virtualscriptalias">VirtualScriptAlias <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for +<tr class="odd"><td><a href="mod_vhost_alias.html#virtualscriptaliasip">VirtualScriptAliasIP <em>interpolated-directory</em>|none</a></td><td> none </td><td>sv</td><td>E</td></tr><tr class="odd"><td class="descr" colspan="4">Dynamically configure the location of the CGI directory for a given virtual host</td></tr> -<tr class="odd"><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> -<tr><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Parse SSI directives in files with the execute bit +<tr><td><a href="mod_watchdog.html#watchdoginterval" id="W" name="W">WatchdogInterval <var>time-interval</var>[s]</a></td><td> 1 </td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Watchdog interval in seconds</td></tr> +<tr class="odd"><td><a href="mod_include.html#xbithack" id="X" name="X">XBitHack on|off|full</a></td><td> off </td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Parse SSI directives in files with the execute bit set</td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> -<tr><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information +<tr><td><a href="mod_xml2enc.html#xml2encalias">xml2EncAlias <var>charset alias [alias ...]</var></a></td><td></td><td>s</td><td>B</td></tr><tr><td class="descr" colspan="4">Recognise Aliases for encoding values</td></tr> +<tr class="odd"><td><a href="mod_xml2enc.html#xml2encdefault">xml2EncDefault <var>name</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Sets a default encoding to assume when absolutely no information can be <a href="#sniffing">automatically detected</a></td></tr> -<tr class="odd"><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr class="odd"><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> +<tr><td><a href="mod_xml2enc.html#xml2startparse">xml2StartParse <var>element [element ...]</var></a></td><td></td><td>svdh</td><td>B</td></tr><tr><td class="descr" colspan="4">Advise the parser to skip leading junk.</td></tr> </table></div> <div class="bottomlang"> <p><span>å¯ç”¨è¯è¨€: </span><a href="../de/mod/quickreference.html" hreflang="de" rel="alternate" title="Deutsch"> de </a> | diff --git a/docs/manual/programs/htpasswd.html.fr.utf8 b/docs/manual/programs/htpasswd.html.fr.utf8 index feeb1e8..f673b77 100644 --- a/docs/manual/programs/htpasswd.html.fr.utf8 +++ b/docs/manual/programs/htpasswd.html.fr.utf8 @@ -30,8 +30,6 @@ l'authentification de base</h1> <a href="../ko/programs/htpasswd.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> | <a href="../tr/programs/htpasswd.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a></p> </div> -<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.</div> <p><code>htpasswd</code> permet de créer et de maintenir les fichiers textes où sont stockés les noms d'utilisateurs et mots de @@ -50,14 +48,6 @@ l'authentification de base</h1> données. Pour utiliser une base de données DBM, voir le programme <code class="program"><a href="../programs/dbmmanage.html">dbmmanage</a></code> ou <code class="program"><a href="../programs/htdbm.html">htdbm</a></code>.</p> - <p><code>htpasswd</code> chiffre les mots de passe en utilisant soit - bcrypt, - une version de MD5 modifiée pour Apache, soit SHA1, soit la routine - <code>crypt()</code> du système. Les fichiers gérés par - <code>htpasswd</code> peuvent contenir deux types de mots de passe ; - certaines entrées peuvent contenir des mots de passe chiffrés en - MD5 ou bcrypt, alors que d'autres entrées du même fichier contiendront des - mots de passe chiffrés avec <code>crypt()</code>.</p> <p><code>htpasswd</code> hache les mots de passe en utilisant bcrypt, une version de MD5 modifiée pour Apache, SHA-1 ou la routine système <code>crypt()</code>. Les hachages de type SHA-2 (SHA-256 and SHA-512) sont @@ -90,9 +80,12 @@ support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></di [ -<strong>i</strong> ] [ -<strong>m</strong> | -<strong>B</strong> | + -<strong>2</strong> | + -<strong>5</strong> | -<strong>d</strong> | -<strong>s</strong> | -<strong>p</strong> ] + [ -<strong>r</strong> <var>rounds</var> ] [ -<strong>C</strong> <var>cost</var> ] [ -<strong>D</strong> ] [ -<strong>v</strong> ] <var>fichier-mots-de-passe</var> <var>nom-utilisateur</var></code></p> @@ -101,9 +94,12 @@ support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></di [ -<strong>c</strong> ] [ -<strong>m</strong> | -<strong>B</strong> | + -<strong>2</strong> | + -<strong>5</strong> | -<strong>d</strong> | -<strong>s</strong> | -<strong>p</strong> ] + [ -<strong>r</strong> <var>rounds</var> ] [ -<strong>C</strong> <var>cost</var> ] [ -<strong>D</strong> ] [ -<strong>v</strong> ] <var>fichier-mots-de-passe</var> <var>nom-utilisateur</var> @@ -113,17 +109,23 @@ support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></di [ -<strong>i</strong> ] [ -<strong>m</strong> | -<strong>B</strong> | + -<strong>2</strong> | + -<strong>5</strong> | -<strong>d</strong> | -<strong>s</strong> | -<strong>p</strong> ] + [ -<strong>r</strong> <var>rounds</var> ] [ -<strong>C</strong> <var>cost</var> ] <var>nom-utilisateur</var></code></p> <p><code><strong>htpasswd</strong> -<strong>nb</strong> [ -<strong>m</strong> | -<strong>B</strong> | + -<strong>2</strong> | + -<strong>5</strong> | -<strong>d</strong> | -<strong>s</strong> | -<strong>p</strong> ] + [ -<strong>r</strong> <var>rounds</var> ] [ -<strong>C</strong> <var>cost</var> ] <var>nom-utilisateur</var> <var>mot-de-passe</var></code></p> </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> @@ -163,6 +165,14 @@ support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></di <dd>Utilise le hachage MD5 pour les mots de passe. C'est le comportement par défaut (depuis la version 2.2.18).</dd> + <dt><code>-2</code></dt> + <dd>Utilise les hachages SHA-256 basés sur <code>crypt()</code> pour les + mots de passe. Pris en charge sur la plupart des plateformes de style Unix.</dd> + + <dt><code>-5</code></dt> + <dd>Utilise les hachages SHA-512 basés sur <code>crypt()</code> pour les + mots de passe. Pris en charge sur la plupart des plateformes de style Unix.</dd> + <dt><code>-B</code></dt> <dd>Utilise bcrypt pour hacher les mots de passe. c'est un algorythme de chiffrement actuellement considéré comme sûr.</dd> @@ -174,6 +184,11 @@ support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></di meilleure sera la sécurité, mais inférieure la rapidité). La valeur par défaut est 5 et les valeurs autorisées vont de 4 à 17.</dd> + <dt><code>-r</code></dt> + <dd>Ce drapeau n’est autorisé qu’en combinaison avec les drapeaux + <code>-2</code> ou <code>-5</code>. Il permet de définir le nombre de passes + de hachage utilisé pour les algorithmes SHA-2 (un nombre élevé améliore la + sécurité mais le traitement est plus lent ; la valeur par défaut est 5000.</dd> <dt><code>-d</code></dt> <dd>Utilise le hachage <code>crypt()</code> pour les mots de @@ -298,10 +313,14 @@ support/SHA1.</li><li><a href="#comments_section">Commentaires</a></li></ul></di aléatoire, afin de rendre les attaques de mots de passe à base de dictionnaires plus difficiles.</p> - <p>Les algorithmes de chiffrement SHA et <code>crypt()</code> + <p>Les algorithmes de chiffrement SHA-1 et <code>crypt()</code> sont considérés comme <strong>non surs</strong> du point de vue des standards actuels.</p> -</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> + + <p>Les formats de <code>crypt()</code> basés sur SHA-2 (SHA-256 et SHA-512) + sont pris en charge sur la plupart des systèmes de style Unix récents et + respectent la spécification de <a href="https://www.akkadia.org/drepper/SHA-crypt.txt">https://www.akkadia.org/drepper/SHA-crypt.txt</a>.</p> + </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="section"> <h2><a name="restrictions" id="restrictions">Restrictions</a></h2> <p>Sur les plates-formes Windows, la taille des mots de passe diff --git a/docs/manual/rewrite/flags.html.en b/docs/manual/rewrite/flags.html.en index bfb5656..604e278 100644 --- a/docs/manual/rewrite/flags.html.en +++ b/docs/manual/rewrite/flags.html.en @@ -57,6 +57,8 @@ providing detailed explanations and examples.</p> <li><img alt="" src="../images/down.gif" /> <a href="#flag_r">R|redirect</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#flag_s">S|skip</a></li> <li><img alt="" src="../images/down.gif" /> <a href="#flag_t">T|type</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_allow_3f">UnsafeAllow3F</a></li> +<li><img alt="" src="../images/down.gif" /> <a href="#flag_unsafe_prefix_status">UnsafePrefixStat</a></li> </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="access.html">Controlling access</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="proxy.html">Proxying</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="advanced.html">Advanced techniques</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="#comments_section">Comments</a></li></ul></div> <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> <div class="section"> @@ -820,7 +822,22 @@ otherwise the MIME-type set with this flag is lost due to an internal re-processing (including subsequent rounds of mod_rewrite processing). The <code>L</code> flag can be useful in this context to end the <em>current</em> round of mod_rewrite processing.</p> - +</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="section"> +<h2><a name="flag_unsafe_allow_3f" id="flag_unsafe_allow_3f">UnsafeAllow3F</a></h2> + <p> Setting this flag is required to allow a rewrite to continue If the + HTTP request being written has an encoded question mark, '%3f', and the + rewritten result has a '?' in the substiution. This protects from a malicious + URL taking advantage of a capture and re-substitution of the encoded + question mark.</p> +</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> +<div class="section"> +<h2><a name="flag_unsafe_prefix_status" id="flag_unsafe_prefix_status">UnsafePrefixStat</a></h2> + <p> Setting this flag is required in server-scoped substitutions + start with a variable or backreference and resolve to a filesystem path. + These substitutions are not prefixed with the document root. + This protects from a malicious URL causing the expanded substitution to + map to an unexpected filesystem location.</p> </div></div> <div class="bottomlang"> <p><span>Available Languages: </span><a href="../en/rewrite/flags.html" title="English"> en </a> | diff --git a/docs/manual/rewrite/flags.html.fr.utf8 b/docs/manual/rewrite/flags.html.fr.utf8 index 073e46d..1e07037 100644 --- a/docs/manual/rewrite/flags.html.fr.utf8 +++ b/docs/manual/rewrite/flags.html.fr.utf8 @@ -26,6 +26,8 @@ <p><span>Langues Disponibles: </span><a href="../en/rewrite/flags.html" hreflang="en" rel="alternate" title="English"> en </a> | <a href="../fr/rewrite/flags.html" title="Français"> fr </a></p> </div> +<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version + anglaise pour les changements récents.</div> <p>Ce document décrit les drapeaux disponibles dans la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>, en fournissant diff --git a/docs/manual/style/version.ent b/docs/manual/style/version.ent index c0ad4ed..45ce7c1 100644 --- a/docs/manual/style/version.ent +++ b/docs/manual/style/version.ent @@ -19,6 +19,6 @@ <!ENTITY httpd.major "2"> <!ENTITY httpd.minor "4"> -<!ENTITY httpd.patch "59"> +<!ENTITY httpd.patch "60"> <!ENTITY httpd.docs "2.4"> @@ -4,7 +4,7 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.59 +Version: 2.4.60 Release: 1 URL: http://httpd.apache.org/ Vendor: Apache Software Foundation diff --git a/include/ap_config_auto.h.in b/include/ap_config_auto.h.in index b4de75a..7c23964 100644 --- a/include/ap_config_auto.h.in +++ b/include/ap_config_auto.h.in @@ -52,6 +52,9 @@ /* Using autoconf to configure Apache */ #undef AP_USING_AUTOCONF +/* Define as default argument for thread id in error logging */ +#undef DEFAULT_LOG_TID + /* Define to 1 if you have the 'arc4random_buf' function. */ #undef HAVE_ARC4RANDOM_BUF @@ -61,6 +64,9 @@ /* Define to 1 if you have the <bstring.h> header file. */ #undef HAVE_BSTRING_H +/* Enable FD passing support in mod_cgid */ +#undef HAVE_CGID_FDPASSING + /* Define if crypt() supports SHA-2 hashes */ #undef HAVE_CRYPT_SHA2 diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 6f80ab3..00475bf 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -599,6 +599,10 @@ * 20120211.129 (2.4.58-dev) Add ap_get_pollfd_from_conn() * 20120211.130 (2.4.59-dev) Add ap_proxy_determine_address() * 20120211.131 (2.4.59-dev) Add DAV_WALKTYPE_TOLERANT + * 20120211.132 (2.4.60-dev) Add ap_set_content_type_ex(), ap_filepath_merge(), + * and AP_REQUEST_TRUSTED_CT BNOTE. + * 20120211.133 (2.4.60-dev) Add ap_proxy_fixup_uds_filename() + * 20120211.134 (2.4.60-dev) AP_SLASHES and AP_IS_SLASH */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -606,7 +610,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 131 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 134 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/ap_release.h b/include/ap_release.h index 827dfc0..635bdfd 100644 --- a/include/ap_release.h +++ b/include/ap_release.h @@ -43,7 +43,7 @@ #define AP_SERVER_MAJORVERSION_NUMBER 2 #define AP_SERVER_MINORVERSION_NUMBER 4 -#define AP_SERVER_PATCHLEVEL_NUMBER 59 +#define AP_SERVER_PATCHLEVEL_NUMBER 60 #define AP_SERVER_DEVBUILD_BOOLEAN 0 /* Synchronize the above with docs/manual/style/version.ent */ diff --git a/include/http_core.h b/include/http_core.h index 948034f..9fb9f51 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -756,6 +756,9 @@ typedef struct { apr_size_t flush_max_threshold; apr_int32_t flush_max_pipelined; unsigned int strict_host_check; +#ifdef WIN32 + apr_array_header_t *unc_list; +#endif } core_server_config; /* for AddOutputFiltersByType in core.c */ diff --git a/include/http_protocol.h b/include/http_protocol.h index 94c481e..f2c99c9 100644 --- a/include/http_protocol.h +++ b/include/http_protocol.h @@ -439,6 +439,17 @@ AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l); AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct); /** + * Set the content type for this request (r->content_type). + * @param r The current request + * @param ct The new content type + * @param trusted If non-zero, The content-type should come from a + * trusted source such as server configuration rather + * than application output. + * for the AddOutputFilterByType directive to work correctly. + */ +AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted); + +/** * Set the Accept-Ranges header for this response * @param r The current request */ diff --git a/include/httpd.h b/include/httpd.h index 799cf97..3aa05ba 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -667,6 +667,7 @@ typedef apr_uint64_t ap_request_bnotes_t; * */ #define AP_REQUEST_STRONG_ETAG 1 >> 0 +#define AP_REQUEST_TRUSTED_CT 1 << 1 /** * This is a convenience macro to ease with getting specific request @@ -689,6 +690,12 @@ typedef apr_uint64_t ap_request_bnotes_t; AP_REQUEST_GET_BNOTE((r), AP_REQUEST_STRONG_ETAG) /** @} */ +/** + * Returns true if the content-type field is from a trusted source + */ +#define AP_REQUEST_IS_TRUSTED_CT(r) \ + (!!AP_REQUEST_GET_BNOTE((r), AP_REQUEST_TRUSTED_CT)) +/** @} */ /** * @defgroup module_magic Module Magic mime types @@ -2656,6 +2663,42 @@ AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path, */ AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line); + +/** + * apr_filepath_merge with an allow-list + * Merge additional file path onto the previously processed rootpath + * @param newpath the merged paths returned + * @param rootpath the root file path (NULL uses the current working path) + * @param addpath the path to add to the root path + * @param flags the desired APR_FILEPATH_ rules to apply when merging + * @param p the pool to allocate the new path string from + * @remark if the flag APR_FILEPATH_TRUENAME is given, and the addpath + * contains wildcard characters ('*', '?') on platforms that don't support + * such characters within filenames, the paths will be merged, but the + * result code will be APR_EPATHWILD, and all further segments will not + * reflect the true filenames including the wildcard and following segments. + */ +AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath, + const char *rootpath, + const char *addpath, + apr_int32_t flags, + apr_pool_t *p); + +#ifdef WIN32 +#define apr_filepath_merge ap_filepath_merge +#endif + +/* Win32/NetWare/OS2 need to check for both forward and back slashes + * in ap_normalize_path() and ap_escape_url(). + */ +#ifdef CASE_BLIND_FILESYSTEM +#define AP_IS_SLASH(s) ((s == '/') || (s == '\\')) +#define AP_SLASHES "/\\" +#else +#define AP_IS_SLASH(s) (s == '/') +#define AP_SLASHES "/" +#endif + #ifdef __cplusplus } #endif diff --git a/modules/generators/cgi_common.h b/modules/generators/cgi_common.h new file mode 100644 index 0000000..66f9418 --- /dev/null +++ b/modules/generators/cgi_common.h @@ -0,0 +1,639 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_lib.h" +#include "apr_poll.h" + +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "util_filter.h" +#include "util_script.h" + +static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv; +static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps; + +/* These functions provided by mod_cgi.c/mod_cgid.c still. */ +static int log_script(request_rec *r, cgi_server_conf * conf, int ret, + char *dbuf, const char *sbuf, apr_bucket_brigade *bb, + apr_file_t *script_err); +static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, char *s); +static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, const char *command); + +/* Read and discard all output from the brigade. Note that with the + * CGI bucket, the brigade will become empty once the script's stdout + * is closed (or on error/timeout), but the stderr output may not have + * been entirely captured at this point. */ +static void discard_script_output(apr_bucket_brigade *bb) +{ + apr_bucket *e; + const char *buf; + apr_size_t len; + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); + e = APR_BRIGADE_FIRST(bb)) + { + if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { + break; + } + apr_bucket_delete(e); + } +} + +static int log_scripterror(request_rec *r, cgi_server_conf *conf, int ret, + apr_status_t rv, const char *logno, + const char *error) +{ + apr_file_t *f = NULL; + apr_finfo_t finfo; + char time_str[APR_CTIME_LEN]; + + /* Intentional no APLOGNO */ + /* Callee provides APLOGNO in error text */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "%sstderr from %s: %s", logno ? logno : "", r->filename, error); + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ + if (!conf->logname || + ((apr_stat(&finfo, conf->logname, + APR_FINFO_SIZE, r->pool) == APR_SUCCESS) && + (finfo.size > conf->logbytes)) || + (apr_file_open(&f, conf->logname, + APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, + r->pool) != APR_SUCCESS)) { + return ret; + } + + /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ + apr_ctime(time_str, apr_time_now()); + apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + /* "%% 500 /usr/local/apache/cgi-bin */ + apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); + + apr_file_printf(f, "%%error\n%s\n", error); + + apr_file_close(f); + return ret; +} + +/* Soak up stderr from a script and redirect it to the error log. + */ +static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) +{ + char argsbuffer[HUGE_STRING_LEN]; + char *newline; + apr_status_t rv; + cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module); + + while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err)) == APR_SUCCESS) { + + newline = strchr(argsbuffer, '\n'); + if (newline) { + char *prev = newline - 1; + if (prev >= argsbuffer && *prev == '\r') { + newline = prev; + } + + *newline = '\0'; + } + log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer); + } + + return rv; +} + +static apr_status_t cgi_handle_exec(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *tag = NULL; + char *tag_val = NULL; + request_rec *r = f->r; + char *file = r->filename; + char parsed_string[MAX_STRING_LEN]; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, APLOGNO(03195) + "missing argument for exec element in %s", r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (ctx->flags & SSI_FLAG_NO_EXEC) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01228) "exec used but not allowed " + "in %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "cmd")) { + apr_status_t rv; + + cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_LEAVE_NAME); + + rv = include_cmd(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01229) "execution failure " + "for parameter \"%s\" to tag exec in file %s", + tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else if (!strcmp(tag, "cgi")) { + apr_status_t rv; + + cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_DROP_NAME); + + rv = include_cgi(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01230) "invalid CGI ref " + "\"%s\" in %s", tag_val, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01231) "unknown parameter " + "\"%s\" to tag exec in %s", tag, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* Hook to register exec= handling with mod_include. */ +static void cgi_optfns_retrieve(void) +{ + APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi; + + cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); + cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); + cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); + + if (cgi_pfn_reg_with_ssi && cgi_pfn_gtv && cgi_pfn_ps) { + /* Required by mod_include filter. This is how mod_cgi registers + * with mod_include to provide processing of the exec directive. + */ + cgi_pfn_reg_with_ssi("exec", cgi_handle_exec); + } +} + +#ifdef WANT_CGI_BUCKET +/* A CGI bucket type is needed to catch any output to stderr from the + * script; see PR 22030. */ +static const apr_bucket_type_t bucket_type_cgi; + +struct cgi_bucket_data { + apr_pollset_t *pollset; + request_rec *r; + apr_interval_time_t timeout; +}; + +/* Create a CGI bucket using pipes from script stdout 'out' + * and stderr 'err', for request 'r'. */ +static apr_bucket *cgi_bucket_create(request_rec *r, + apr_interval_time_t timeout, + apr_file_t *out, apr_file_t *err, + apr_bucket_alloc_t *list) +{ + apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); + apr_status_t rv; + apr_pollfd_t fd; + struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data); + + /* Disable APR timeout handling since we'll use poll() entirely. */ + apr_file_pipe_timeout_set(out, 0); + apr_file_pipe_timeout_set(err, 0); + + APR_BUCKET_INIT(b); + b->free = apr_bucket_free; + b->list = list; + b->type = &bucket_type_cgi; + b->length = (apr_size_t)(-1); + b->start = -1; + + /* Create the pollset */ + rv = apr_pollset_create(&data->pollset, 2, r->pool, 0); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217) + "apr_pollset_create(); check system or user limits"); + return NULL; + } + + fd.desc_type = APR_POLL_FILE; + fd.reqevents = APR_POLLIN; + fd.p = r->pool; + fd.desc.f = out; /* script's stdout */ + fd.client_data = (void *)1; + rv = apr_pollset_add(data->pollset, &fd); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218) + "apr_pollset_add(); check system or user limits"); + return NULL; + } + + fd.desc.f = err; /* script's stderr */ + fd.client_data = (void *)2; + rv = apr_pollset_add(data->pollset, &fd); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219) + "apr_pollset_add(); check system or user limits"); + return NULL; + } + + data->r = r; + data->timeout = timeout; + b->data = data; + return b; +} + +/* Create a duplicate CGI bucket using given bucket data */ +static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data, + apr_bucket_alloc_t *list) +{ + apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); + APR_BUCKET_INIT(b); + b->free = apr_bucket_free; + b->list = list; + b->type = &bucket_type_cgi; + b->length = (apr_size_t)(-1); + b->start = -1; + b->data = data; + return b; +} + +/* Handle stdout from CGI child. Duplicate of logic from the _read + * method of the real APR pipe bucket implementation. */ +static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, + const char **str, apr_size_t *len) +{ + char *buf; + apr_status_t rv; + + *str = NULL; + *len = APR_BUCKET_BUFF_SIZE; + buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ + + rv = apr_file_read(out, buf, len); + + if (rv != APR_SUCCESS && rv != APR_EOF) { + apr_bucket_free(buf); + return rv; + } + + if (*len > 0) { + struct cgi_bucket_data *data = a->data; + apr_bucket_heap *h; + + /* Change the current bucket to refer to what we read */ + a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); + h = a->data; + h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ + *str = buf; + APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); + } + else { + apr_bucket_free(buf); + a = apr_bucket_immortal_make(a, "", 0); + *str = a->data; + } + return rv; +} + +/* Read method of CGI bucket: polls on stderr and stdout of the child, + * sending any stderr output immediately away to the error log. */ +static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str, + apr_size_t *len, apr_read_type_e block) +{ + struct cgi_bucket_data *data = b->data; + apr_interval_time_t timeout = 0; + apr_status_t rv; + int gotdata = 0; + + if (block != APR_NONBLOCK_READ) { + timeout = data->timeout > 0 ? data->timeout : data->r->server->timeout; + } + + do { + const apr_pollfd_t *results; + apr_int32_t num; + + rv = apr_pollset_poll(data->pollset, timeout, &num, &results); + if (APR_STATUS_IS_TIMEUP(rv)) { + if (timeout) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220) + "Timeout waiting for output from CGI script %s", + data->r->filename); + return rv; + } + else { + return APR_EAGAIN; + } + } + else if (APR_STATUS_IS_EINTR(rv)) { + continue; + } + else if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221) + "poll failed waiting for CGI child"); + return rv; + } + + for (; num; num--, results++) { + if (results[0].client_data == (void *)1) { + /* stdout */ + rv = cgi_read_stdout(b, results[0].desc.f, str, len); + if (APR_STATUS_IS_EOF(rv)) { + rv = APR_SUCCESS; + } + gotdata = 1; + } else { + /* stderr */ + apr_status_t rv2 = log_script_err(data->r, results[0].desc.f); + if (APR_STATUS_IS_EOF(rv2)) { + apr_pollset_remove(data->pollset, &results[0]); + } + } + } + + } while (!gotdata); + + return rv; +} + +static const apr_bucket_type_t bucket_type_cgi = { + "CGI", 5, APR_BUCKET_DATA, + apr_bucket_destroy_noop, + cgi_bucket_read, + apr_bucket_setaside_notimpl, + apr_bucket_split_notimpl, + apr_bucket_copy_notimpl +}; + +#endif /* WANT_CGI_BUCKET */ + +/* Handle the CGI response output, having set up the brigade with the + * CGI or PIPE bucket as appropriate. */ +static int cgi_handle_response(request_rec *r, int nph, apr_bucket_brigade *bb, + apr_interval_time_t timeout, cgi_server_conf *conf, + char *logdata, apr_file_t *script_err) +{ + apr_status_t rv; + + /* Handle script return... */ + if (!nph) { + const char *location; + char sbuf[MAX_STRING_LEN]; + int ret; + + ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, + APLOG_MODULE_INDEX); + + /* xCGI has its own body framing mechanism which we don't + * match against any provided Content-Length, so let the + * core determine C-L vs T-E based on what's actually sent. + */ + if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR)) + apr_table_unset(r->headers_out, "Content-Length"); + apr_table_unset(r->headers_out, "Transfer-Encoding"); + + if (ret != OK) { + /* In the case of a timeout reading script output, clear + * the brigade to avoid a second attempt to read the + * output. */ + if (ret == HTTP_GATEWAY_TIME_OUT) { + apr_brigade_cleanup(bb); + } + + ret = log_script(r, conf, ret, logdata, sbuf, bb, script_err); + + /* + * ret could be HTTP_NOT_MODIFIED in the case that the CGI script + * does not set an explicit status and ap_meets_conditions, which + * is called by ap_scan_script_header_err_brigade, detects that + * the conditions of the requests are met and the response is + * not modified. + * In this case set r->status and return OK in order to prevent + * running through the error processing stack as this would + * break with mod_cache, if the conditions had been set by + * mod_cache itself to validate a stale entity. + * BTW: We circumvent the error processing stack anyway if the + * CGI script set an explicit status code (whatever it is) and + * the only possible values for ret here are: + * + * HTTP_NOT_MODIFIED (set by ap_meets_conditions) + * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) + * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the + * processing of the response of the CGI script, e.g broken headers + * or a crashed CGI process). + */ + if (ret == HTTP_NOT_MODIFIED) { + r->status = ret; + return OK; + } + + return ret; + } + + location = apr_table_get(r->headers_out, "Location"); + + if (location && r->status == 200) { + /* For a redirect whether internal or not, discard any + * remaining stdout from the script, and log any remaining + * stderr output, as normal. */ + discard_script_output(bb); + apr_brigade_destroy(bb); + + if (script_err) { + apr_file_pipe_timeout_set(script_err, timeout); + log_script_err(r, script_err); + } + } + + if (location && location[0] == '/' && r->status == 200) { + /* This redirect needs to be a GET no matter what the original + * method was. + */ + r->method = "GET"; + r->method_number = M_GET; + + /* We already read the message body (if any), so don't allow + * the redirected request to think it has one. We can ignore + * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. + */ + apr_table_unset(r->headers_in, "Content-Length"); + + ap_internal_redirect_handler(location, r); + return OK; + } + else if (location && r->status == 200) { + /* XXX: Note that if a script wants to produce its own Redirect + * body, it now has to explicitly *say* "Status: 302" + */ + discard_script_output(bb); + apr_brigade_destroy(bb); + return HTTP_MOVED_TEMPORARILY; + } + + rv = ap_pass_brigade(r->output_filters, bb); + } + else /* nph */ { + struct ap_filter_t *cur; + + /* get rid of all filters up through protocol... since we + * haven't parsed off the headers, there is no way they can + * work + */ + + cur = r->proto_output_filters; + while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { + cur = cur->next; + } + r->output_filters = r->proto_output_filters = cur; + + rv = ap_pass_brigade(r->output_filters, bb); + } + + /* don't soak up script output if errors occurred writing it + * out... otherwise, we prolong the life of the script when the + * connection drops or we stopped sending output for some other + * reason */ + if (script_err && rv == APR_SUCCESS && !r->connection->aborted) { + apr_file_pipe_timeout_set(script_err, timeout); + log_script_err(r, script_err); + } + + if (script_err) apr_file_close(script_err); + + return OK; /* NOT r->status, even if it has changed. */ +} + +/* Read the request body and write it to fd 'script_out', using 'bb' + * as temporary bucket brigade. If 'logbuf' is non-NULL, the first + * logbufbytes of stdout are stored in logbuf. */ +static apr_status_t cgi_handle_request(request_rec *r, apr_file_t *script_out, + apr_bucket_brigade *bb, + char *logbuf, apr_size_t logbufbytes) +{ + int seen_eos = 0; + int child_stopped_reading = 0; + apr_status_t rv; + int dbpos = 0; + + do { + apr_bucket *bucket; + + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, HUGE_STRING_LEN); + + if (rv != APR_SUCCESS) { + return rv; + } + + for (bucket = APR_BRIGADE_FIRST(bb); + bucket != APR_BRIGADE_SENTINEL(bb); + bucket = APR_BUCKET_NEXT(bucket)) + { + const char *data; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(bucket)) { + seen_eos = 1; + break; + } + + /* We can't do much with this. */ + if (APR_BUCKET_IS_FLUSH(bucket)) { + continue; + } + + /* If the child stopped, we still must read to EOS. */ + if (child_stopped_reading) { + continue; + } + + /* read */ + rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + if (rv) { + return rv; + } + + if (logbufbytes && dbpos < logbufbytes) { + int cursize; + + if ((dbpos + len) > logbufbytes) { + cursize = logbufbytes - dbpos; + } + else { + cursize = len; + } + memcpy(logbuf + dbpos, data, cursize); + dbpos += cursize; + } + + /* Keep writing data to the child until done or too much time + * elapses with no progress or an error occurs. + */ + rv = apr_file_write_full(script_out, data, len, NULL); + + if (rv != APR_SUCCESS) { + /* silly script stopped reading, soak up remaining message */ + child_stopped_reading = 1; + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651) + "Error writing request body to script %s", + r->filename); + } + } + apr_brigade_cleanup(bb); + } + while (!seen_eos); + + if (logbuf) { + logbuf[dbpos] = '\0'; + } + + return APR_SUCCESS; +} diff --git a/modules/generators/config5.m4 b/modules/generators/config5.m4 index bf29521..0863553 100644 --- a/modules/generators/config5.m4 +++ b/modules/generators/config5.m4 @@ -78,4 +78,15 @@ fi APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) +AC_ARG_ENABLE(cgid-fdpassing, + [APACHE_HELP_STRING(--enable-cgid-fdpassing,Enable experimental mod_cgid support for fd passing)], + [if test "$enableval" = "yes"; then + AC_CHECK_DECL(CMSG_DATA, + [AC_DEFINE([HAVE_CGID_FDPASSING], 1, [Enable FD passing support in mod_cgid])], + [AC_MSG_ERROR([cannot support mod_cgid fd-passing on this system])], [ +#include <sys/types.h> +#include <sys/socket.h>]) + fi +]) + APACHE_MODPATH_FINISH diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index 1f77786..3799b06 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -48,7 +48,6 @@ #include "http_protocol.h" #include "http_main.h" #include "http_log.h" -#include "util_script.h" #include "ap_mpm.h" #include "mod_core.h" #include "mod_cgi.h" @@ -61,9 +60,6 @@ module AP_MODULE_DECLARE_DATA cgi_module; -static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi; -static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv; -static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps; static APR_OPTIONAL_FN_TYPE(ap_cgi_build_command) *cgi_build_command; /* Read and discard the data in the brigade produced by a CGI script */ @@ -96,6 +92,11 @@ typedef struct { apr_interval_time_t timeout; } cgi_dirconf; +#if APR_FILES_AS_SOCKETS +#define WANT_CGI_BUCKET +#endif +#include "cgi_common.h" + static void *create_cgi_config(apr_pool_t *p, server_rec *s) { cgi_server_conf *c = @@ -185,64 +186,6 @@ AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_C {NULL} }; -static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, - apr_status_t rv, char *logno, char *error) -{ - apr_file_t *f = NULL; - apr_finfo_t finfo; - char time_str[APR_CTIME_LEN]; - int log_flags = rv ? APLOG_ERR : APLOG_ERR; - - /* Intentional no APLOGNO */ - /* Callee provides APLOGNO in error text */ - ap_log_rerror(APLOG_MARK, log_flags, rv, r, - "%s%s: %s", logno ? logno : "", error, r->filename); - - /* XXX Very expensive mainline case! Open, then getfileinfo! */ - if (!conf->logname || - ((apr_stat(&finfo, conf->logname, - APR_FINFO_SIZE, r->pool) == APR_SUCCESS) && - (finfo.size > conf->logbytes)) || - (apr_file_open(&f, conf->logname, - APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, - r->pool) != APR_SUCCESS)) { - return ret; - } - - /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ - apr_ctime(time_str, apr_time_now()); - apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, - r->args ? "?" : "", r->args ? r->args : "", r->protocol); - /* "%% 500 /usr/local/apache/cgi-bin */ - apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); - - apr_file_printf(f, "%%error\n%s\n", error); - - apr_file_close(f); - return ret; -} - -/* Soak up stderr from a script and redirect it to the error log. - */ -static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) -{ - char argsbuffer[HUGE_STRING_LEN]; - char *newline; - apr_status_t rv; - cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module); - - while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, - script_err)) == APR_SUCCESS) { - newline = strchr(argsbuffer, '\n'); - if (newline) { - *newline = '\0'; - } - log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer); - } - - return rv; -} - static int log_script(request_rec *r, cgi_server_conf * conf, int ret, char *dbuf, const char *sbuf, apr_bucket_brigade *bb, apr_file_t *script_err) @@ -563,230 +506,23 @@ static apr_status_t default_build_command(const char **cmd, const char ***argv, return APR_SUCCESS; } -static void discard_script_output(apr_bucket_brigade *bb) -{ - apr_bucket *e; - const char *buf; - apr_size_t len; - - for (e = APR_BRIGADE_FIRST(bb); - e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); - e = APR_BRIGADE_FIRST(bb)) - { - if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { - break; - } - apr_bucket_delete(e); - } -} - -#if APR_FILES_AS_SOCKETS - -/* A CGI bucket type is needed to catch any output to stderr from the - * script; see PR 22030. */ -static const apr_bucket_type_t bucket_type_cgi; - -struct cgi_bucket_data { - apr_pollset_t *pollset; - request_rec *r; -}; - -/* Create a CGI bucket using pipes from script stdout 'out' - * and stderr 'err', for request 'r'. */ -static apr_bucket *cgi_bucket_create(request_rec *r, - apr_file_t *out, apr_file_t *err, - apr_bucket_alloc_t *list) -{ - apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); - apr_status_t rv; - apr_pollfd_t fd; - struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data); - - APR_BUCKET_INIT(b); - b->free = apr_bucket_free; - b->list = list; - b->type = &bucket_type_cgi; - b->length = (apr_size_t)(-1); - b->start = -1; - - /* Create the pollset */ - rv = apr_pollset_create(&data->pollset, 2, r->pool, 0); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217) - "apr_pollset_create(); check system or user limits"); - return NULL; - } - - fd.desc_type = APR_POLL_FILE; - fd.reqevents = APR_POLLIN; - fd.p = r->pool; - fd.desc.f = out; /* script's stdout */ - fd.client_data = (void *)1; - rv = apr_pollset_add(data->pollset, &fd); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218) - "apr_pollset_add(); check system or user limits"); - return NULL; - } - - fd.desc.f = err; /* script's stderr */ - fd.client_data = (void *)2; - rv = apr_pollset_add(data->pollset, &fd); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219) - "apr_pollset_add(); check system or user limits"); - return NULL; - } - - data->r = r; - b->data = data; - return b; -} - -/* Create a duplicate CGI bucket using given bucket data */ -static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data, - apr_bucket_alloc_t *list) -{ - apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); - APR_BUCKET_INIT(b); - b->free = apr_bucket_free; - b->list = list; - b->type = &bucket_type_cgi; - b->length = (apr_size_t)(-1); - b->start = -1; - b->data = data; - return b; -} - -/* Handle stdout from CGI child. Duplicate of logic from the _read - * method of the real APR pipe bucket implementation. */ -static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, - const char **str, apr_size_t *len) -{ - char *buf; - apr_status_t rv; - - *str = NULL; - *len = APR_BUCKET_BUFF_SIZE; - buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ - - rv = apr_file_read(out, buf, len); - - if (rv != APR_SUCCESS && rv != APR_EOF) { - apr_bucket_free(buf); - return rv; - } - - if (*len > 0) { - struct cgi_bucket_data *data = a->data; - apr_bucket_heap *h; - - /* Change the current bucket to refer to what we read */ - a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); - h = a->data; - h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ - *str = buf; - APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); - } - else { - apr_bucket_free(buf); - a = apr_bucket_immortal_make(a, "", 0); - *str = a->data; - } - return rv; -} - -/* Read method of CGI bucket: polls on stderr and stdout of the child, - * sending any stderr output immediately away to the error log. */ -static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str, - apr_size_t *len, apr_read_type_e block) -{ - struct cgi_bucket_data *data = b->data; - apr_interval_time_t timeout = 0; - apr_status_t rv; - int gotdata = 0; - cgi_dirconf *dc = ap_get_module_config(data->r->per_dir_config, &cgi_module); - - if (block != APR_NONBLOCK_READ) { - timeout = dc->timeout > 0 ? dc->timeout : data->r->server->timeout; - } - - do { - const apr_pollfd_t *results; - apr_int32_t num; - - rv = apr_pollset_poll(data->pollset, timeout, &num, &results); - if (APR_STATUS_IS_TIMEUP(rv)) { - if (timeout) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220) - "Timeout waiting for output from CGI script %s", - data->r->filename); - return rv; - } - else { - return APR_EAGAIN; - } - } - else if (APR_STATUS_IS_EINTR(rv)) { - continue; - } - else if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221) - "poll failed waiting for CGI child"); - return rv; - } - - for (; num; num--, results++) { - if (results[0].client_data == (void *)1) { - /* stdout */ - rv = cgi_read_stdout(b, results[0].desc.f, str, len); - if (APR_STATUS_IS_EOF(rv)) { - rv = APR_SUCCESS; - } - gotdata = 1; - } else { - /* stderr */ - apr_status_t rv2 = log_script_err(data->r, results[0].desc.f); - if (APR_STATUS_IS_EOF(rv2)) { - apr_pollset_remove(data->pollset, &results[0]); - } - } - } - - } while (!gotdata); - - return rv; -} - -static const apr_bucket_type_t bucket_type_cgi = { - "CGI", 5, APR_BUCKET_DATA, - apr_bucket_destroy_noop, - cgi_bucket_read, - apr_bucket_setaside_notimpl, - apr_bucket_split_notimpl, - apr_bucket_copy_notimpl -}; - -#endif - static int cgi_handler(request_rec *r) { int nph; - apr_size_t dbpos = 0; + apr_size_t dbufsize; const char *argv0; const char *command; const char **argv; char *dbuf = NULL; apr_file_t *script_out = NULL, *script_in = NULL, *script_err = NULL; - apr_bucket_brigade *bb; + conn_rec *c = r->connection; + apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); apr_bucket *b; int is_included; - int seen_eos, child_stopped_reading; apr_pool_t *p; cgi_server_conf *conf; apr_status_t rv; cgi_exec_info_t e_info; - conn_rec *c; cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; @@ -794,8 +530,6 @@ static int cgi_handler(request_rec *r) return DECLINED; } - c = r->connection; - is_included = !strcmp(r->protocol, "INCLUDED"); p = r->main ? r->main->pool : r->pool; @@ -864,83 +598,24 @@ static int cgi_handler(request_rec *r) return HTTP_INTERNAL_SERVER_ERROR; } - /* Transfer any put/post args, CERN style... - * Note that we already ignore SIGPIPE in the core server. - */ - bb = apr_brigade_create(r->pool, c->bucket_alloc); - seen_eos = 0; - child_stopped_reading = 0; + /* Buffer for logging script stdout. */ if (conf->logname) { - dbuf = apr_palloc(r->pool, conf->bufbytes + 1); - dbpos = 0; + dbufsize = conf->bufbytes; + dbuf = apr_palloc(r->pool, dbufsize + 1); } - do { - apr_bucket *bucket; - - rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, - APR_BLOCK_READ, HUGE_STRING_LEN); - - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01225) - "Error reading request entity data"); - return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); - } - - for (bucket = APR_BRIGADE_FIRST(bb); - bucket != APR_BRIGADE_SENTINEL(bb); - bucket = APR_BUCKET_NEXT(bucket)) - { - const char *data; - apr_size_t len; - - if (APR_BUCKET_IS_EOS(bucket)) { - seen_eos = 1; - break; - } - - /* We can't do much with this. */ - if (APR_BUCKET_IS_FLUSH(bucket)) { - continue; - } - - /* If the child stopped, we still must read to EOS. */ - if (child_stopped_reading) { - continue; - } - - /* read */ - apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); - - if (conf->logname && dbpos < conf->bufbytes) { - int cursize; - - if ((dbpos + len) > conf->bufbytes) { - cursize = conf->bufbytes - dbpos; - } - else { - cursize = len; - } - memcpy(dbuf + dbpos, data, cursize); - dbpos += cursize; - } - - /* Keep writing data to the child until done or too much time - * elapses with no progress or an error occurs. - */ - rv = apr_file_write_full(script_out, data, len, NULL); - - if (rv != APR_SUCCESS) { - /* silly script stopped reading, soak up remaining message */ - child_stopped_reading = 1; - } - } - apr_brigade_cleanup(bb); + else { + dbufsize = 0; + dbuf = NULL; } - while (!seen_eos); - if (conf->logname) { - dbuf[dbpos] = '\0'; + /* Read the request body. */ + rv = cgi_handle_request(r, script_out, bb, dbuf, dbufsize); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01225) + "Error reading request entity data"); + return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); } + /* Is this flush really needed? */ apr_file_flush(script_out); apr_file_close(script_out); @@ -948,10 +623,7 @@ static int cgi_handler(request_rec *r) AP_DEBUG_ASSERT(script_in != NULL); #if APR_FILES_AS_SOCKETS - apr_file_pipe_timeout_set(script_in, 0); - apr_file_pipe_timeout_set(script_err, 0); - - b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc); + b = cgi_bucket_create(r, dc->timeout, script_in, script_err, c->bucket_alloc); if (b == NULL) return HTTP_INTERNAL_SERVER_ERROR; #else @@ -961,120 +633,7 @@ static int cgi_handler(request_rec *r) b = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); - /* Handle script return... */ - if (!nph) { - const char *location; - char sbuf[MAX_STRING_LEN]; - int ret; - - ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, - APLOG_MODULE_INDEX); - - /* xCGI has its own body framing mechanism which we don't - * match against any provided Content-Length, so let the - * core determine C-L vs T-E based on what's actually sent. - */ - if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR)) - apr_table_unset(r->headers_out, "Content-Length"); - apr_table_unset(r->headers_out, "Transfer-Encoding"); - - if (ret != OK) { - ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err); - - /* - * ret could be HTTP_NOT_MODIFIED in the case that the CGI script - * does not set an explicit status and ap_meets_conditions, which - * is called by ap_scan_script_header_err_brigade, detects that - * the conditions of the requests are met and the response is - * not modified. - * In this case set r->status and return OK in order to prevent - * running through the error processing stack as this would - * break with mod_cache, if the conditions had been set by - * mod_cache itself to validate a stale entity. - * BTW: We circumvent the error processing stack anyway if the - * CGI script set an explicit status code (whatever it is) and - * the only possible values for ret here are: - * - * HTTP_NOT_MODIFIED (set by ap_meets_conditions) - * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) - * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the - * processing of the response of the CGI script, e.g broken headers - * or a crashed CGI process). - */ - if (ret == HTTP_NOT_MODIFIED) { - r->status = ret; - return OK; - } - - return ret; - } - - location = apr_table_get(r->headers_out, "Location"); - - if (location && r->status == 200) { - /* For a redirect whether internal or not, discard any - * remaining stdout from the script, and log any remaining - * stderr output, as normal. */ - discard_script_output(bb); - apr_brigade_destroy(bb); - apr_file_pipe_timeout_set(script_err, timeout); - log_script_err(r, script_err); - } - - if (location && location[0] == '/' && r->status == 200) { - /* This redirect needs to be a GET no matter what the original - * method was. - */ - r->method = "GET"; - r->method_number = M_GET; - - /* We already read the message body (if any), so don't allow - * the redirected request to think it has one. We can ignore - * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. - */ - apr_table_unset(r->headers_in, "Content-Length"); - - ap_internal_redirect_handler(location, r); - return OK; - } - else if (location && r->status == 200) { - /* XXX: Note that if a script wants to produce its own Redirect - * body, it now has to explicitly *say* "Status: 302" - */ - return HTTP_MOVED_TEMPORARILY; - } - - rv = ap_pass_brigade(r->output_filters, bb); - } - else /* nph */ { - struct ap_filter_t *cur; - - /* get rid of all filters up through protocol... since we - * haven't parsed off the headers, there is no way they can - * work - */ - - cur = r->proto_output_filters; - while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { - cur = cur->next; - } - r->output_filters = r->proto_output_filters = cur; - - rv = ap_pass_brigade(r->output_filters, bb); - } - - /* don't soak up script output if errors occurred writing it - * out... otherwise, we prolong the life of the script when the - * connection drops or we stopped sending output for some other - * reason */ - if (rv == APR_SUCCESS && !r->connection->aborted) { - apr_file_pipe_timeout_set(script_err, timeout); - log_script_err(r, script_err); - } - - apr_file_close(script_err); - - return OK; /* NOT r->status, even if it has changed. */ + return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); } /*============================================================================ @@ -1188,107 +747,9 @@ static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f, return APR_SUCCESS; } -static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb) -{ - char *tag = NULL; - char *tag_val = NULL; - request_rec *r = f->r; - char *file = r->filename; - char parsed_string[MAX_STRING_LEN]; - - if (!ctx->argc) { - ap_log_rerror(APLOG_MARK, - (ctx->flags & SSI_FLAG_PRINTING) - ? APLOG_ERR : APLOG_WARNING, - 0, r, APLOGNO(03195) - "missing argument for exec element in %s", r->filename); - } - - if (!(ctx->flags & SSI_FLAG_PRINTING)) { - return APR_SUCCESS; - } - - if (!ctx->argc) { - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - if (ctx->flags & SSI_FLAG_NO_EXEC) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01228) "exec used but not allowed " - "in %s", r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - while (1) { - cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); - if (!tag || !tag_val) { - break; - } - - if (!strcmp(tag, "cmd")) { - apr_status_t rv; - - cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_LEAVE_NAME); - - rv = include_cmd(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01229) "execution failure " - "for parameter \"%s\" to tag exec in file %s", - tag, r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else if (!strcmp(tag, "cgi")) { - apr_status_t rv; - - cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_DROP_NAME); - - rv = include_cgi(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01230) "invalid CGI ref " - "\"%s\" in %s", tag_val, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01231) "unknown parameter " - "\"%s\" to tag exec in %s", tag, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - - return APR_SUCCESS; -} - - -/*============================================================================ - *============================================================================ - * This is the end of the cgi filter code moved from mod_include. - *============================================================================ - *============================================================================*/ - - static int cgi_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); - cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); - cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); - - if ((cgi_pfn_reg_with_ssi) && (cgi_pfn_gtv) && (cgi_pfn_ps)) { - /* Required by mod_include filter. This is how mod_cgi registers - * with mod_include to provide processing of the exec directive. - */ - cgi_pfn_reg_with_ssi("exec", handle_exec); - } - /* This is the means by which unusual (non-unix) os's may find alternate * means to run a given command (e.g. shebang/registry parsing on Win32) */ @@ -1304,6 +765,7 @@ static void register_hooks(apr_pool_t *p) static const char * const aszPre[] = { "mod_include.c", NULL }; ap_hook_handler(cgi_handler, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(cgi_post_config, aszPre, NULL, APR_HOOK_REALLY_FIRST); + ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(cgi) = diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 4bab59f..1d55b8d 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -57,7 +57,6 @@ #include "http_protocol.h" #include "http_main.h" #include "http_log.h" -#include "util_script.h" #include "ap_mpm.h" #include "mpm_common.h" #include "mod_suexec.h" @@ -80,11 +79,6 @@ module AP_MODULE_DECLARE_DATA cgid_module; static int cgid_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew); static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server); -static int handle_exec(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb); - -static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgid_pfn_reg_with_ssi; -static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgid_pfn_gtv; -static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgid_pfn_ps; static apr_pool_t *pcgi = NULL; static pid_t daemon_pid; @@ -220,6 +214,15 @@ typedef struct { #endif } cgid_req_t; +#define cgi_server_conf cgid_server_conf +#define cgi_module cgid_module + +#ifdef HAVE_CGID_FDPASSING +/* Pull in CGI bucket implementation. */ +#define WANT_CGI_BUCKET +#endif +#include "cgi_common.h" + /* This routine is called to create the argument list to be passed * to the CGI script. When suexec is enabled, the suexec path, user, and * group are the first three arguments to be passed; if not, all three @@ -342,15 +345,19 @@ static apr_status_t close_unix_socket(void *thefd) return close(fd); } -/* deal with incomplete reads and signals - * assume you really have to read buf_size bytes - */ -static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) +/* Read from the socket dealing with incomplete messages and signals. + * Returns 0 on success or errno on failure. Stderr fd passed as + * auxiliary data from other end is written to *errfd, or else stderr + * fileno if not present. */ +static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size) { - char *buf = vbuf; int rc; +#ifndef HAVE_CGID_FDPASSING + char *buf = vbuf; size_t bytes_read = 0; + if (errfd) *errfd = 0; + do { do { rc = read(fd, buf + bytes_read, buf_size - bytes_read); @@ -365,9 +372,60 @@ static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) } } while (bytes_read < buf_size); + +#else /* with FD passing */ + struct msghdr msg = {0}; + struct iovec vec = {vbuf, buf_size}; + struct cmsghdr *cmsg; + union { /* union to ensure alignment */ + struct cmsghdr cm; + char buf[CMSG_SPACE(sizeof(int))]; + } u; + + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + + if (errfd) { + msg.msg_control = u.buf; + msg.msg_controllen = sizeof(u.buf); + *errfd = 0; + } + + /* use MSG_WAITALL to skip loop on truncated reads */ + do { + rc = recvmsg(fd, &msg, MSG_WAITALL); + } while (rc < 0 && errno == EINTR); + + if (rc == 0) { + return ECONNRESET; + } + else if (rc < 0) { + return errno; + } + else if (rc != buf_size) { + /* MSG_WAITALL should ensure the recvmsg blocks until the + * entire length is read, but let's be paranoid. */ + return APR_INCOMPLETE; + } + + if (errfd + && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL + && cmsg->cmsg_len == CMSG_LEN(sizeof(*errfd)) + && cmsg->cmsg_level == SOL_SOCKET + && cmsg->cmsg_type == SCM_RIGHTS) { + *errfd = *((int *) CMSG_DATA(cmsg)); + } +#endif + return APR_SUCCESS; } +/* As sock_readhdr but without auxiliary fd passing. */ +static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) +{ + return sock_readhdr(fd, NULL, vbuf, buf_size); +} + /* deal with signals */ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) @@ -384,7 +442,7 @@ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) return APR_SUCCESS; } -static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) +static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count, ...) { va_list ap; int rc; @@ -399,9 +457,39 @@ static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) } va_end(ap); +#ifndef HAVE_CGID_FDPASSING do { rc = writev(fd, vec, count); } while (rc < 0 && errno == EINTR); +#else + { + struct msghdr msg = { 0 }; + struct cmsghdr *cmsg; + union { /* union for alignment */ + char buf[CMSG_SPACE(sizeof(int))]; + struct cmsghdr align; + } u; + + msg.msg_iov = vec; + msg.msg_iovlen = count; + + if (auxfd) { + msg.msg_control = u.buf; + msg.msg_controllen = sizeof(u.buf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + *((int *) CMSG_DATA(cmsg)) = auxfd; + } + + do { + rc = sendmsg(fd, &msg, 0); + } while (rc < 0 && errno == EINTR); + } +#endif + if (rc < 0) { return errno; } @@ -410,7 +498,7 @@ static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) } static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, - cgid_req_t *req) + int *errfd, cgid_req_t *req) { int i; char **environ; @@ -421,7 +509,7 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, r->server = apr_pcalloc(r->pool, sizeof(server_rec)); /* read the request header */ - stat = sock_read(fd, req, sizeof(*req)); + stat = sock_readhdr(fd, errfd, req, sizeof(*req)); if (stat != APR_SUCCESS) { return stat; } @@ -431,6 +519,14 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, return APR_SUCCESS; } + /* Sanity check the structure received. */ + if (req->env_count < 0 || req->uri_len == 0 + || req->filename_len > APR_PATH_MAX || req->filename_len == 0 + || req->argv0_len > APR_PATH_MAX || req->argv0_len == 0 + || req->loglevel > APLOG_TRACE8) { + return APR_EINVAL; + } + /* handle module indexes and such */ rconf = (void **)ap_create_request_config(r->pool); @@ -479,14 +575,15 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, return APR_SUCCESS; } -static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, - int req_type) +static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r, + const char *argv0, char **env, int req_type) { int i; cgid_req_t req = {0}; apr_status_t stat; ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config); + int errfd; if (ugid == NULL) { @@ -507,16 +604,21 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, req.args_len = r->args ? strlen(r->args) : 0; req.loglevel = r->server->log.level; + if (errpipe) + apr_os_file_get(&errfd, errpipe); + else + errfd = 0; + /* Write the request header */ if (req.args_len) { - stat = sock_writev(fd, r, 5, + stat = sock_writev(fd, errfd, r, 5, &req, sizeof(req), r->filename, req.filename_len, argv0, req.argv0_len, r->uri, req.uri_len, r->args, req.args_len); } else { - stat = sock_writev(fd, r, 4, + stat = sock_writev(fd, errfd, r, 4, &req, sizeof(req), r->filename, req.filename_len, argv0, req.argv0_len, @@ -531,7 +633,7 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, for (i = 0; i < req.env_count; i++) { apr_size_t curlen = strlen(env[i]); - if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen), + if ((stat = sock_writev(fd, 0, r, 2, &curlen, sizeof(curlen), env[i], curlen)) != APR_SUCCESS) { return stat; } @@ -582,20 +684,34 @@ static void daemon_signal_handler(int sig) } } +/* Callback executed in the forked child process if exec of the CGI + * script fails. For the fd-passing case, output to stderr goes to + * the client (request handling thread) and is logged via + * ap_log_rerror there. For the non-fd-passing case, the "fake" + * request_rec passed via userdata is used to log. */ static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, const char *description) { - request_rec *r; void *vr; apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool); - r = vr; - - /* sure we got r, but don't call ap_log_rerror() because we don't - * have r->headers_in and possibly other storage referenced by - * ap_log_rerror() - */ - ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); + if (vr) { + request_rec *r = vr; + + /* sure we got r, but don't call ap_log_rerror() because we don't + * have r->headers_in and possibly other storage referenced by + * ap_log_rerror() + */ + ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); + } + else { + const char *logstr; + + logstr = apr_psprintf(pool, APLOGNO(01241) "error spawning CGI child: %s (%pm)\n", + description, &err); + fputs(logstr, stderr); + fflush(stderr); + } } static int cgid_server(void *data) @@ -670,7 +786,7 @@ static int cgid_server(void *data) } while (!daemon_should_exit) { - int errfileno = STDERR_FILENO; + int errfileno; char *argv0 = NULL; char **env = NULL; const char * const *argv; @@ -710,7 +826,7 @@ static int cgid_server(void *data) r = apr_pcalloc(ptrans, sizeof(request_rec)); procnew = apr_pcalloc(ptrans, sizeof(*procnew)); r->pool = ptrans; - stat = get_req(sd2, r, &argv0, &env, &cgid_req); + stat = get_req(sd2, r, &argv0, &env, &errfileno, &cgid_req); if (stat != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, stat, main_server, APLOGNO(01248) @@ -742,6 +858,16 @@ static int cgid_server(void *data) continue; } + if (errfileno == 0) { + errfileno = STDERR_FILENO; + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server, + "using passed fd %d as stderr", errfileno); + /* Limit the received fd lifetime to pool lifetime */ + apr_pool_cleanup_register(ptrans, (void *)((long)errfileno), + close_unix_socket, close_unix_socket); + } apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool); apr_os_file_put(&inout, &sd2, 0, r->pool); @@ -801,7 +927,10 @@ static int cgid_server(void *data) close(sd2); } else { - apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); + if (errfileno == STDERR_FILENO) { + /* Used by cgid_child_errfn without fd-passing. */ + apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); + } argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args); @@ -946,16 +1075,6 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, if (ret != OK ) { return ret; } - cgid_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); - cgid_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); - cgid_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); - - if ((cgid_pfn_reg_with_ssi) && (cgid_pfn_gtv) && (cgid_pfn_ps)) { - /* Required by mod_include filter. This is how mod_cgid registers - * with mod_include to provide processing of the exec directive. - */ - cgid_pfn_reg_with_ssi("exec", handle_exec); - } } return ret; } @@ -1066,41 +1185,6 @@ static const command_rec cgid_cmds[] = {NULL} }; -static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret, - apr_status_t rv, char *error) -{ - apr_file_t *f = NULL; - struct stat finfo; - char time_str[APR_CTIME_LEN]; - int log_flags = rv ? APLOG_ERR : APLOG_ERR; - - /* Intentional no APLOGNO */ - /* Callee provides APLOGNO in error text */ - ap_log_rerror(APLOG_MARK, log_flags, rv, r, - "%s: %s", error, r->filename); - - /* XXX Very expensive mainline case! Open, then getfileinfo! */ - if (!conf->logname || - ((stat(conf->logname, &finfo) == 0) - && (finfo.st_size > conf->logbytes)) || - (apr_file_open(&f, conf->logname, - APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) { - return ret; - } - - /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */ - apr_ctime(time_str, apr_time_now()); - apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, - r->args ? "?" : "", r->args ? r->args : "", r->protocol); - /* "%% 500 /usr/local/apache/cgid-bin */ - apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); - - apr_file_printf(f, "%%error\n%s\n", error); - - apr_file_close(f); - return ret; -} - static int log_script(request_rec *r, cgid_server_conf * conf, int ret, char *dbuf, const char *sbuf, apr_bucket_brigade *bb, apr_file_t *script_err) @@ -1221,7 +1305,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r, ++connect_tries; if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, - APLOGNO(01255) "unable to create socket to cgi daemon"); + APLOGNO(01255), "unable to create socket to cgi daemon"); } if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) { /* Save errno for later */ @@ -1242,7 +1326,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r, } else { close(sd); - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257), "unable to connect to cgi daemon after multiple tries"); } } @@ -1258,13 +1342,15 @@ static int connect_to_daemon(int *sdptr, request_rec *r, if (connect_errno == ENOENT && apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) > DEFAULT_CONNECT_STARTUP_DELAY) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, - apr_pstrcat(r->pool, APLOGNO(02833) "ScriptSock ", sockname, " does not exist", NULL)); + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, + APLOGNO(02833), + apr_pstrcat(r->pool, + "ScriptSock ", sockname, " does not exist", NULL)); } /* gotta try again, but make sure the cgid daemon is still around */ if (connect_errno != ENOENT && kill(daemon_pid, 0) != 0) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258), "cgid daemon is gone; is Apache terminating?"); } } @@ -1272,23 +1358,6 @@ static int connect_to_daemon(int *sdptr, request_rec *r, return OK; } -static void discard_script_output(apr_bucket_brigade *bb) -{ - apr_bucket *e; - const char *buf; - apr_size_t len; - - for (e = APR_BRIGADE_FIRST(bb); - e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); - e = APR_BRIGADE_FIRST(bb)) - { - if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { - break; - } - apr_bucket_delete(e); - } -} - /**************************************************************** * * Actual cgid handling... @@ -1374,7 +1443,9 @@ static apr_status_t get_cgi_pid(request_rec *r, cgid_server_conf *conf, pid_t * return stat; } - if (pid == 0) { + /* Don't accept zero as a pid here, calling kill(0, SIGTERM) etc + * later is unpleasant. */ + if (*pid == 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01261) "daemon couldn't find CGI process for connection %lu", r->connection->id); @@ -1393,19 +1464,21 @@ static apr_status_t cleanup_script(void *vptr) static int cgid_handler(request_rec *r) { - int retval, nph, dbpos; + conn_rec *c = r->connection; + int retval, nph; char *argv0, *dbuf; - apr_bucket_brigade *bb; + apr_size_t dbufsize; + apr_bucket_brigade *bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); apr_bucket *b; cgid_server_conf *conf; int is_included; - int seen_eos, child_stopped_reading; int sd; char **env; - apr_file_t *tempsock; + apr_file_t *tempsock, *script_err, *errpipe_out; struct cleanup_script_info *info; apr_status_t rv; cgid_dirconf *dc; + apr_interval_time_t timeout; if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { return DECLINED; @@ -1414,7 +1487,7 @@ static int cgid_handler(request_rec *r) conf = ap_get_module_config(r->server->module_config, &cgid_module); dc = ap_get_module_config(r->per_dir_config, &cgid_module); - + timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; is_included = !strcmp(r->protocol, "INCLUDED"); if ((argv0 = strrchr(r->filename, '/')) != NULL) { @@ -1429,12 +1502,12 @@ static int cgid_handler(request_rec *r) argv0 = r->filename; if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r)) { - return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262), "Options ExecCGI is off in this directory"); } if (nph && is_included) { - return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263), "attempt to include NPH CGI script"); } @@ -1443,12 +1516,12 @@ static int cgid_handler(request_rec *r) #error at mod_cgi.c for required code in this path. #else if (r->finfo.filetype == APR_NOFILE) { - return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264) + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264), "script not found or unable to stat"); } #endif if (r->finfo.filetype == APR_DIR) { - return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265), "attempt to invoke directory as script"); } @@ -1456,7 +1529,7 @@ static int cgid_handler(request_rec *r) r->path_info && *r->path_info) { /* default to accept */ - return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01266) + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01266), "AcceptPathInfo off disallows user's path"); } /* @@ -1467,6 +1540,17 @@ static int cgid_handler(request_rec *r) } */ +#ifdef HAVE_CGID_FDPASSING + rv = apr_file_pipe_create(&script_err, &errpipe_out, r->pool); + if (rv) { + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176), + "could not create pipe for stderr"); + } +#else + script_err = NULL; + errpipe_out = NULL; +#endif + /* * httpd core function used to add common environment variables like * DOCUMENT_ROOT. @@ -1479,24 +1563,28 @@ static int cgid_handler(request_rec *r) return retval; } - rv = send_req(sd, r, argv0, env, CGI_REQ); + rv = send_req(sd, errpipe_out, r, argv0, env, CGI_REQ); if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01268) - "write to cgi daemon process"); + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10245), + "could not send request to cgi daemon"); } + /* The write-end of the pipe is only used by the server, so close + * it here. */ + if (errpipe_out) apr_file_close(errpipe_out); + info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); info->conf = conf; info->r = r; rv = get_cgi_pid(r, conf, &(info->pid)); - if (APR_SUCCESS == rv){ + if (rv == APR_SUCCESS) { apr_pool_cleanup_register(r->pool, info, - cleanup_script, - apr_pool_cleanup_null); + cleanup_script, apr_pool_cleanup_null); } else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi PID"); + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10246), + "failed reading PID from cgi daemon"); } /* We are putting the socket discriptor into an apr_file_t so that we can @@ -1506,95 +1594,25 @@ static int cgid_handler(request_rec *r) */ apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); - if (dc->timeout > 0) { - apr_file_pipe_timeout_set(tempsock, dc->timeout); - } - else { - apr_file_pipe_timeout_set(tempsock, r->server->timeout); - } + apr_file_pipe_timeout_set(tempsock, timeout); apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); - /* Transfer any put/post args, CERN style... - * Note that we already ignore SIGPIPE in the core server. - */ - bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - seen_eos = 0; - child_stopped_reading = 0; - dbuf = NULL; - dbpos = 0; + /* Buffer for logging script stdout. */ if (conf->logname) { - dbuf = apr_palloc(r->pool, conf->bufbytes + 1); + dbufsize = conf->bufbytes; + dbuf = apr_palloc(r->pool, dbufsize + 1); } - do { - apr_bucket *bucket; - - rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, - APR_BLOCK_READ, HUGE_STRING_LEN); - - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01270) - "Error reading request entity data"); - return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); - } - - for (bucket = APR_BRIGADE_FIRST(bb); - bucket != APR_BRIGADE_SENTINEL(bb); - bucket = APR_BUCKET_NEXT(bucket)) - { - const char *data; - apr_size_t len; - - if (APR_BUCKET_IS_EOS(bucket)) { - seen_eos = 1; - break; - } - - /* We can't do much with this. */ - if (APR_BUCKET_IS_FLUSH(bucket)) { - continue; - } - - /* If the child stopped, we still must read to EOS. */ - if (child_stopped_reading) { - continue; - } - - /* read */ - apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); - - if (conf->logname && dbpos < conf->bufbytes) { - int cursize; - - if ((dbpos + len) > conf->bufbytes) { - cursize = conf->bufbytes - dbpos; - } - else { - cursize = len; - } - memcpy(dbuf + dbpos, data, cursize); - dbpos += cursize; - } - - /* Keep writing data to the child until done or too much time - * elapses with no progress or an error occurs. - */ - rv = apr_file_write_full(tempsock, data, len, NULL); - - if (rv != APR_SUCCESS) { - /* silly script stopped reading, soak up remaining message */ - child_stopped_reading = 1; - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651) - "Error writing request body to script %s", - r->filename); - - } - } - apr_brigade_cleanup(bb); + else { + dbuf = NULL; + dbufsize = 0; } - while (!seen_eos); - if (conf->logname) { - dbuf[dbpos] = '\0'; + /* Read the request body. */ + rv = cgi_handle_request(r, tempsock, bb, dbuf, dbufsize); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01270) + "Error reading request entity data"); + return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); } /* we're done writing, or maybe we didn't write at all; @@ -1603,134 +1621,22 @@ static int cgid_handler(request_rec *r) */ shutdown(sd, 1); - /* Handle script return... */ - if (!nph) { - conn_rec *c = r->connection; - const char *location; - char sbuf[MAX_STRING_LEN]; - int ret; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - - ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, - APLOG_MODULE_INDEX); - - /* xCGI has its own body framing mechanism which we don't - * match against any provided Content-Length, so let the - * core determine C-L vs T-E based on what's actually sent. - */ - if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR)) - apr_table_unset(r->headers_out, "Content-Length"); - apr_table_unset(r->headers_out, "Transfer-Encoding"); - - if (ret != OK) { - ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL); - - /* - * ret could be HTTP_NOT_MODIFIED in the case that the CGI script - * does not set an explicit status and ap_meets_conditions, which - * is called by ap_scan_script_header_err_brigade, detects that - * the conditions of the requests are met and the response is - * not modified. - * In this case set r->status and return OK in order to prevent - * running through the error processing stack as this would - * break with mod_cache, if the conditions had been set by - * mod_cache itself to validate a stale entity. - * BTW: We circumvent the error processing stack anyway if the - * CGI script set an explicit status code (whatever it is) and - * the only possible values for ret here are: - * - * HTTP_NOT_MODIFIED (set by ap_meets_conditions) - * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) - * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the - * processing of the response of the CGI script, e.g broken headers - * or a crashed CGI process). - */ - if (ret == HTTP_NOT_MODIFIED) { - r->status = ret; - return OK; - } - - return ret; - } - - location = apr_table_get(r->headers_out, "Location"); - - if (location && location[0] == '/' && r->status == 200) { - - /* Soak up all the script output */ - discard_script_output(bb); - apr_brigade_destroy(bb); - /* This redirect needs to be a GET no matter what the original - * method was. - */ - r->method = "GET"; - r->method_number = M_GET; - - /* We already read the message body (if any), so don't allow - * the redirected request to think it has one. We can ignore - * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. - */ - apr_table_unset(r->headers_in, "Content-Length"); - - ap_internal_redirect_handler(location, r); - return OK; - } - else if (location && r->status == 200) { - /* XXX: Note that if a script wants to produce its own Redirect - * body, it now has to explicitly *say* "Status: 302" - */ - discard_script_output(bb); - apr_brigade_destroy(bb); - return HTTP_MOVED_TEMPORARILY; - } - - rv = ap_pass_brigade(r->output_filters, bb); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, - "Failed to flush CGI output to client"); - } - } - - if (nph) { - conn_rec *c = r->connection; - struct ap_filter_t *cur; - - /* get rid of all filters up through protocol... since we - * haven't parsed off the headers, there is no way they can - * work - */ - - cur = r->proto_output_filters; - while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { - cur = cur->next; - } - r->output_filters = r->proto_output_filters = cur; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); - b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - ap_pass_brigade(r->output_filters, bb); - } + bb = apr_brigade_create(r->pool, c->bucket_alloc); +#ifdef HAVE_CGID_FDPASSING + b = cgi_bucket_create(r, dc->timeout, tempsock, script_err, c->bucket_alloc); + if (b == NULL) + return HTTP_INTERNAL_SERVER_ERROR; /* should call log_scripterror() w/ _UNAVAILABLE? */ +#else + b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); +#endif + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); - return OK; /* NOT r->status, even if it has changed. */ + return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); } - - - -/*============================================================================ - *============================================================================ - * This is the beginning of the cgi filter code moved from mod_include. This - * is the code required to handle the "exec" SSI directive. - *============================================================================ - *============================================================================*/ +/* Handling include= for mod_include. */ static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb, char *s) { @@ -1815,7 +1721,7 @@ static void add_ssi_vars(request_rec *r) } static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb, char *command) + apr_bucket_brigade *bb, const char *command) { char **env; int sd; @@ -1836,7 +1742,7 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, return retval; } - send_req(sd, r, command, env, SSI_REQ); + send_req(sd, NULL, r, command, env, SSI_REQ); info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); info->conf = conf; @@ -1881,91 +1787,6 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, return APR_SUCCESS; } -static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb) -{ - char *tag = NULL; - char *tag_val = NULL; - request_rec *r = f->r; - char *file = r->filename; - char parsed_string[MAX_STRING_LEN]; - - if (!ctx->argc) { - ap_log_rerror(APLOG_MARK, - (ctx->flags & SSI_FLAG_PRINTING) - ? APLOG_ERR : APLOG_WARNING, - 0, r, APLOGNO(03196) - "missing argument for exec element in %s", r->filename); - } - - if (!(ctx->flags & SSI_FLAG_PRINTING)) { - return APR_SUCCESS; - } - - if (!ctx->argc) { - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - if (ctx->flags & SSI_FLAG_NO_EXEC) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01271) "exec used but not allowed " - "in %s", r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - while (1) { - cgid_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); - if (!tag || !tag_val) { - break; - } - - if (!strcmp(tag, "cmd")) { - apr_status_t rv; - - cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_LEAVE_NAME); - - rv = include_cmd(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01272) - "execution failure for parameter \"%s\" " - "to tag exec in file %s", tag, r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else if (!strcmp(tag, "cgi")) { - apr_status_t rv; - - cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_DROP_NAME); - - rv = include_cgi(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01273) "invalid CGI ref " - "\"%s\" in %s", tag_val, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01274) "unknown parameter " - "\"%s\" to tag exec in %s", tag, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - - return APR_SUCCESS; -} -/*============================================================================ - *============================================================================ - * This is the end of the cgi filter code moved from mod_include. - *============================================================================ - *============================================================================*/ - - static void register_hook(apr_pool_t *p) { static const char * const aszPre[] = { "mod_include.c", NULL }; @@ -1973,6 +1794,7 @@ static void register_hook(apr_pool_t *p) ap_hook_pre_config(cgid_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(cgid_init, aszPre, NULL, APR_HOOK_MIDDLE); ap_hook_handler(cgid_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(cgid) = { diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index d031f24..c31e873 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -1097,8 +1097,14 @@ AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct) } else if (!r->content_type || strcmp(r->content_type, ct)) { r->content_type = ct; + AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, 0); } } +AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted) +{ + ap_set_content_type(r, ct); + AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, trusted ? AP_REQUEST_TRUSTED_CT : 0); +} AP_DECLARE(void) ap_set_accept_ranges(request_rec *r) { diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c index 700f824..51095a0 100644 --- a/modules/http/mod_mime.c +++ b/modules/http/mod_mime.c @@ -759,7 +759,7 @@ static int find_ct(request_rec *r) int found_metadata = 0; if (r->finfo.filetype == APR_DIR) { - ap_set_content_type(r, DIR_MAGIC_TYPE); + ap_set_content_type_ex(r, DIR_MAGIC_TYPE, 1); return OK; } @@ -850,7 +850,7 @@ static int find_ct(request_rec *r) if (exinfo == NULL || !exinfo->forced_type) { if ((type = apr_hash_get(mime_type_extensions, ext, APR_HASH_KEY_STRING)) != NULL) { - ap_set_content_type(r, (char*) type); + ap_set_content_type_ex(r, (char*) type, 1); found = 1; } } @@ -859,7 +859,7 @@ static int find_ct(request_rec *r) /* empty string is treated as special case for RemoveType */ if (exinfo->forced_type && *exinfo->forced_type) { - ap_set_content_type(r, exinfo->forced_type); + ap_set_content_type_ex(r, exinfo->forced_type, 1); found = 1; } @@ -964,33 +964,33 @@ static int find_ct(request_rec *r) memcpy(tmp, ctp->subtype, ctp->subtype_len); tmp += ctp->subtype_len; *tmp = 0; - ap_set_content_type(r, base_content_type); + ap_set_content_type_ex(r, base_content_type, AP_REQUEST_IS_TRUSTED_CT(r)); while (pp != NULL) { if (charset && !strcmp(pp->attr, "charset")) { if (!override) { - ap_set_content_type(r, + ap_set_content_type_ex(r, apr_pstrcat(r->pool, r->content_type, "; charset=", charset, - NULL)); + NULL), AP_REQUEST_IS_TRUSTED_CT(r)); override = 1; } } else { - ap_set_content_type(r, + ap_set_content_type_ex(r, apr_pstrcat(r->pool, r->content_type, "; ", pp->attr, "=", pp->val, - NULL)); + NULL), AP_REQUEST_IS_TRUSTED_CT(r)); } pp = pp->next; } if (charset && !override) { - ap_set_content_type(r, apr_pstrcat(r->pool, r->content_type, + ap_set_content_type_ex(r, apr_pstrcat(r->pool, r->content_type, "; charset=", charset, - NULL)); + NULL), AP_REQUEST_IS_TRUSTED_CT(r)); } } } diff --git a/modules/http2/h2_c2.c b/modules/http2/h2_c2.c index a955200..c65a521 100644 --- a/modules/http2/h2_c2.c +++ b/modules/http2/h2_c2.c @@ -370,6 +370,13 @@ static apr_status_t h2_c2_filter_out(ap_filter_t* f, apr_bucket_brigade* bb) h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c); apr_status_t rv; + if (bb == NULL) { +#if !AP_MODULE_MAGIC_AT_LEAST(20180720, 1) + f->c->data_in_output_filters = 0; +#endif + return APR_SUCCESS; + } + ap_assert(conn_ctx); #if AP_HAS_RESPONSE_BUCKETS if (!conn_ctx->has_final_response) { diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index ebf8f61..e5cb0ba 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -317,7 +317,7 @@ static int proxy_http2_handler(request_rec *r, apr_port_t proxyport) { const char *proxy_func; - char *locurl = url, *u; + char *locurl, *u; apr_size_t slen; int is_ssl = 0; apr_status_t status; @@ -382,6 +382,7 @@ run_connect: goto cleanup; } + locurl = url; ctx->p_conn->is_ssl = ctx->is_ssl; /* Step One: Determine the URL to connect to (might be a proxy), diff --git a/modules/mappers/mod_actions.c b/modules/mappers/mod_actions.c index ac9c3b7..5e398b5 100644 --- a/modules/mappers/mod_actions.c +++ b/modules/mappers/mod_actions.c @@ -182,8 +182,10 @@ static int action_handler(request_rec *r) return DECLINED; /* Second, check for actions (which override the method scripts) */ - action = r->handler ? r->handler : - ap_field_noparam(r->pool, r->content_type); + action = r->handler; + if (!action && AP_REQUEST_IS_TRUSTED_CT(r)) { + action = ap_field_noparam(r->pool, r->content_type); + } if (action && (t = apr_table_get(conf->action_types, action))) { int virtual = (*t++ == '0' ? 0 : 1); diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index c056b28..a528f81 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -1167,7 +1167,7 @@ static int read_types_multi(negotiation_state *neg) * might be doing. */ if (sub_req->handler && !sub_req->content_type) { - ap_set_content_type(sub_req, CGI_MAGIC_TYPE); + ap_set_content_type_ex(sub_req, CGI_MAGIC_TYPE, 1); } /* @@ -3003,14 +3003,14 @@ static int handle_map_file(request_rec *r) /* set MIME type and charset as negotiated */ if (best->mime_type && *best->mime_type) { if (best->content_charset && *best->content_charset) { - ap_set_content_type(r, apr_pstrcat(r->pool, + ap_set_content_type_ex(r, apr_pstrcat(r->pool, best->mime_type, "; charset=", best->content_charset, - NULL)); + NULL), 1); } else { - ap_set_content_type(r, apr_pstrdup(r->pool, best->mime_type)); + ap_set_content_type_ex(r, apr_pstrdup(r->pool, best->mime_type), 1); } } diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index bbcc11b..3fc2baf 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -177,6 +177,8 @@ static const char* really_last_key = "rewrite_really_last"; #define RULEFLAG_QSLAST (1<<19) #define RULEFLAG_QSNONE (1<<20) /* programattic only */ #define RULEFLAG_ESCAPECTLS (1<<21) +#define RULEFLAG_UNSAFE_PREFIX_STAT (1<<22) +#define RULEFLAG_UNSAFE_ALLOW3F (1<<23) /* return code of the rewrite rule * the result may be escaped - or not @@ -184,7 +186,7 @@ static const char* really_last_key = "rewrite_really_last"; #define ACTION_NORMAL (1<<0) #define ACTION_NOESCAPE (1<<1) #define ACTION_STATUS (1<<2) - +#define ACTION_STATUS_SET (1<<3) #define MAPTYPE_TXT (1<<0) #define MAPTYPE_DBM (1<<1) @@ -208,6 +210,7 @@ static const char* really_last_key = "rewrite_really_last"; #define OPTION_IGNORE_INHERIT (1<<8) #define OPTION_IGNORE_CONTEXT_INFO (1<<9) #define OPTION_LEGACY_PREFIX_DOCROOT (1<<10) +#define OPTION_UNSAFE_PREFIX_STAT (1<<12) #ifndef RAND_MAX #define RAND_MAX 32767 @@ -301,6 +304,14 @@ typedef enum { CONDPAT_AP_EXPR } pattern_type; +typedef enum { + RULE_RC_NOMATCH = 0, /* the rule didn't match */ + RULE_RC_MATCH = 1, /* a matching rule w/ substitution */ + RULE_RC_NOSUB = 2, /* a matching rule w/ no substitution */ + RULE_RC_STATUS_SET = 3 /* a matching rule that has set an HTTP error + to be returned in r->status */ +} rule_return_type; + typedef struct { char *input; /* Input string of RewriteCond */ char *pattern; /* the RegExp pattern string */ @@ -642,6 +653,16 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) return 0; } +static int is_absolute_path(const char *path) +{ +#ifndef CASE_BLIND_FILESYSTEM + return (path[0] == '/'); +#else + return ((AP_IS_SLASH(path[0]) && path[1] == path[0]) + || (apr_isalpha(path[0]) && path[1] == ':' && AP_IS_SLASH(path[2]))); +#endif +} + static const char c2x_table[] = "0123456789abcdef"; static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix, @@ -927,10 +948,15 @@ static void fully_qualify_uri(request_rec *r) return; } +static int startsWith(request_rec *r, const char *haystack, const char *needle) { + int rc = (ap_strstr_c(haystack, needle) == haystack); + rewritelog((r, 5, NULL, "prefix_stat startsWith(%s, %s) %d", haystack, needle, rc)); + return rc; +} /* - * stat() only the first segment of a path + * stat() only the first segment of a path, and only if it matches the output of the last matching rule */ -static int prefix_stat(const char *path, apr_pool_t *pool) +static int prefix_stat(request_rec *r, const char *path, apr_pool_t *pool, rewriterule_entry *lastsub) { const char *curpath = path; const char *root; @@ -964,10 +990,36 @@ static int prefix_stat(const char *path, apr_pool_t *pool) apr_finfo_t sb; if (apr_stat(&sb, statpath, APR_FINFO_MIN, pool) == APR_SUCCESS) { - return 1; + if (!lastsub) { + rewritelog((r, 3, NULL, "prefix_stat no lastsub subst prefix %s", statpath)); + return 1; + } + + rewritelog((r, 3, NULL, "prefix_stat compare statpath %s and lastsub output %s STATOK %d ", + statpath, lastsub->output, lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT)); + if (lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT) { + return 1; + } + else { + const char *docroot = ap_document_root(r); + const char *context_docroot = ap_context_document_root(r); + /* + * As an example, path (r->filename) is /var/foo/bar/baz.html + * even if the flag is not set, we can accept a rule that + * began with a literal /var (stapath), or if the entire path + * starts with the docroot or context document root + */ + if (startsWith(r, lastsub->output, statpath) || + startsWith(r, path, docroot) || + ((docroot != context_docroot) && + startsWith(r, path, context_docroot))) { + return 1; + } + } } } + /* prefix will be added */ return 0; } @@ -3072,6 +3124,9 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd, else if (!strcasecmp(w, "legacyprefixdocroot")) { options |= OPTION_LEGACY_PREFIX_DOCROOT; } + else if (!strcasecmp(w, "UnsafePrefixStat")) { + options |= OPTION_UNSAFE_PREFIX_STAT; + } else { return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '", w, "'", NULL); @@ -3780,6 +3835,18 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg, ++error; } break; + case 'u': + case 'U': + if (!strcasecmp(key, "nsafePrefixStat")){ + cfg->flags |= (RULEFLAG_UNSAFE_PREFIX_STAT); + } + else if(!strcasecmp(key, "nsafeAllow3F")) { + cfg->flags |= RULEFLAG_UNSAFE_ALLOW3F; + } + else { + ++error; + } + break; default: ++error; break; @@ -4138,7 +4205,8 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p, /* * Apply a single RewriteRule */ -static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) +static rule_return_type apply_rewrite_rule(rewriterule_entry *p, + rewrite_ctx *ctx) { ap_regmatch_t regmatch[AP_MAX_REG_MATCH]; apr_array_header_t *rewriteconds; @@ -4189,7 +4257,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) rc = !ap_regexec(p->regexp, ctx->uri, AP_MAX_REG_MATCH, regmatch, 0); if (! (( rc && !(p->flags & RULEFLAG_NOTMATCH)) || (!rc && (p->flags & RULEFLAG_NOTMATCH)) ) ) { - return 0; + return RULE_RC_NOMATCH; } /* It matched, wow! Now it's time to prepare the context structure for @@ -4240,7 +4308,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) } } else if (!rc) { - return 0; + return RULE_RC_NOMATCH; } /* If some HTTP header was involved in the condition, remember it @@ -4260,6 +4328,15 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) newuri = do_expand(p->output, ctx, p); rewritelog((r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri, newuri)); + if (!(p->flags & RULEFLAG_UNSAFE_ALLOW3F) && + ap_strcasestr(r->unparsed_uri, "%3f") && + ap_strchr_c(newuri, '?')) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10508) + "Unsafe URL with %%3f URL rewritten without " + "UnsafeAllow3F"); + r->status = HTTP_FORBIDDEN; + return RULE_RC_STATUS_SET; + } } /* expand [E=var:val] and [CO=<cookie>] */ @@ -4277,7 +4354,35 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) r->status = p->forced_responsecode; } - return 2; + return RULE_RC_NOSUB; + } + + /* Add the previously stripped per-directory location prefix, unless + * (1) it's an absolute URL path and + * (2) it's a full qualified URL + */ + if (!is_proxyreq + && !is_absolute_path(newuri) + && !AP_IS_SLASH(*newuri) + && !is_absolute_uri(newuri, NULL)) { + if (ctx->perdir) { + rewritelog((r, 3, ctx->perdir, "add per-dir prefix: %s -> %s%s", + newuri, ctx->perdir, newuri)); + newuri = apr_pstrcat(r->pool, ctx->perdir, newuri, NULL); + } + else if (!(p->flags & (RULEFLAG_PROXY | RULEFLAG_FORCEREDIRECT))) { + /* Not an absolute URI-path and the scheme (if any) is unknown, + * and it won't be passed to fully_qualify_uri() below either, + * so add an implicit '/' prefix. This avoids potentially a common + * rule like "RewriteRule ^/some/path(.*) $1" that is given a path + * like "/some/pathscheme:..." to produce the fully qualified URL + * "scheme:..." which could be misinterpreted later. + */ + rewritelog((r, 3, ctx->perdir, "add root prefix: %s -> /%s", + newuri, newuri)); + + newuri = apr_pstrcat(r->pool, "/", newuri, NULL); + } } /* Now adjust API's knowledge about r->filename and r->args */ @@ -4289,18 +4394,6 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) splitout_queryargs(r, p->flags); - /* Add the previously stripped per-directory location prefix, unless - * (1) it's an absolute URL path and - * (2) it's a full qualified URL - */ - if ( ctx->perdir && !is_proxyreq && *r->filename != '/' - && !is_absolute_uri(r->filename, NULL)) { - rewritelog((r, 3, ctx->perdir, "add per-dir prefix: %s -> %s%s", - r->filename, ctx->perdir, r->filename)); - - r->filename = apr_pstrcat(r->pool, ctx->perdir, r->filename, NULL); - } - /* If this rule is forced for proxy throughput * (`RewriteRule ... ... [P]') then emulate mod_proxy's * URL-to-filename handler to be sure mod_proxy is triggered @@ -4329,7 +4422,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) r->filename)); r->filename = apr_pstrcat(r->pool, "proxy:", r->filename, NULL); - return 1; + return RULE_RC_MATCH; } /* If this rule is explicitly forced for HTTP redirection @@ -4344,7 +4437,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) r->filename)); r->status = p->forced_responsecode; - return 1; + return RULE_RC_MATCH; } /* Special Rewriting Feature: Self-Reduction @@ -4366,7 +4459,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) "with %s", p->forced_responsecode, r->filename)); r->status = p->forced_responsecode; - return 1; + return RULE_RC_MATCH; } /* Finally remember the forced mime-type */ @@ -4375,7 +4468,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) /* Puuhhhhhhhh... WHAT COMPLICATED STUFF ;_) * But now we're done for this particular rule. */ - return 1; + return RULE_RC_MATCH; } /* @@ -4383,13 +4476,13 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) * i.e. a list of rewrite rules */ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules, - char *perdir) + char *perdir, rewriterule_entry **lastsub) { rewriterule_entry *entries; rewriterule_entry *p; int i; int changed; - int rc; + rule_return_type rc; int s; rewrite_ctx *ctx; int round = 1; @@ -4397,6 +4490,7 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules, ctx = apr_palloc(r->pool, sizeof(*ctx)); ctx->perdir = perdir; ctx->r = r; + *lastsub = NULL; /* * Iterate over all existing rules @@ -4424,7 +4518,12 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules, ctx->vary = NULL; rc = apply_rewrite_rule(p, ctx); - if (rc) { + if (rc != RULE_RC_NOMATCH) { + + if (!(p->flags & RULEFLAG_NOSUB)) { + rewritelog((r, 2, perdir, "setting lastsub to rule with output %s", p->output)); + *lastsub = p; + } /* Catch looping rules with pathinfo growing unbounded */ if ( strlen( r->filename ) > 2*r->server->limit_req_line ) { @@ -4444,6 +4543,12 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules, apr_table_merge(r->headers_out, "Vary", ctx->vary); } + + /* Error while evaluating rule, r->status set */ + if (RULE_RC_STATUS_SET == rc) { + return ACTION_STATUS_SET; + } + /* * The rule sets the response code (implies match-only) */ @@ -4454,7 +4559,7 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules, /* * Indicate a change if this was not a match-only rule. */ - if (rc != 2) { + if (rc != RULE_RC_NOSUB) { changed = ((p->flags & RULEFLAG_NOESCAPE) ? ACTION_NOESCAPE : ACTION_NORMAL); } @@ -4643,6 +4748,7 @@ static int hook_uri2file(request_rec *r) int rulestatus; void *skipdata; const char *oargs; + rewriterule_entry *lastsub = NULL; /* * retrieve the config structures @@ -4754,7 +4860,7 @@ static int hook_uri2file(request_rec *r) /* * now apply the rules ... */ - rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL); + rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL, &lastsub); apr_table_setn(r->notes, "mod_rewrite_rewritten", apr_psprintf(r->pool,"%d",rulestatus)); } @@ -4792,6 +4898,9 @@ static int hook_uri2file(request_rec *r) r->status = HTTP_OK; return n; } + else if (ACTION_STATUS_SET == rulestatus) { + return r->status; + } if (to_proxyreq) { /* it should be go on as an internal proxy request */ @@ -4911,23 +5020,29 @@ static int hook_uri2file(request_rec *r) return HTTP_BAD_REQUEST; } - /* if there is no valid prefix, we call - * the translator from the core and - * prefix the filename with document_root + /* We have r->filename as a path in a server-context rewrite without + * the PT flag. The historical behavior is to treat it as a verbatim + * filesystem path iff the first component of the path exists and is + * readable by httpd. Otherwise, it is interpreted as DocumentRoot + * relative. * * NOTICE: * We cannot leave out the prefix_stat because - * - when we always prefix with document_root - * then no absolute path can be created, e.g. via - * emulating a ScriptAlias directive, etc. - * - when we always NOT prefix with document_root + * - If we always prefix with document_root + * then no absolute path can could ever be used in + * a substitution. e.g. emulating an Alias. + * - If we never prefix with document_root * then the files under document_root have to * be references directly and document_root * gets never used and will be a dummy parameter - - * this is also bad + * this is also bad. + * - Later addition: This part is questionable. + * If we had never prefixed, users would just + * need %{DOCUMENT_ROOT} in substitutions or the + * [PT] flag. * * BUT: - * Under real Unix systems this is no problem, + * Under real Unix systems this is no perf problem, * because we only do stat() on the first directory * and this gets cached by the kernel for along time! */ @@ -4936,7 +5051,9 @@ static int hook_uri2file(request_rec *r) uri_reduced = apr_table_get(r->notes, "mod_rewrite_uri_reduced"); } - if (!prefix_stat(r->filename, r->pool) || uri_reduced != NULL) { + if (!prefix_stat(r, r->filename, r->pool, + conf->options & OPTION_UNSAFE_PREFIX_STAT ? NULL : lastsub) + || uri_reduced != NULL) { int res; char *tmp = r->uri; @@ -4981,6 +5098,7 @@ static int hook_fixup(request_rec *r) char *ofilename, *oargs; int is_proxyreq; void *skipdata; + rewriterule_entry *lastsub; dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config, &rewrite_module); @@ -5065,7 +5183,7 @@ static int hook_fixup(request_rec *r) /* * now apply the rules ... */ - rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory); + rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory, &lastsub); if (rulestatus) { unsigned skip_absolute = is_absolute_uri(r->filename, NULL); int to_proxyreq = 0; @@ -5094,6 +5212,9 @@ static int hook_fixup(request_rec *r) r->status = HTTP_OK; return n; } + else if (ACTION_STATUS_SET == rulestatus) { + return r->status; + } if (to_proxyreq) { /* it should go on as an internal proxy request */ @@ -5333,7 +5454,7 @@ static int hook_mimetype(request_rec *r) rewritelog((r, 1, NULL, "force filename %s to have MIME-type '%s'", r->filename, t)); - ap_set_content_type(r, t); + ap_set_content_type_ex(r, t, 1); } /* handler */ diff --git a/modules/md/md_crypt.c b/modules/md/md_crypt.c index 4b2af89..ca44fab 100644 --- a/modules/md/md_crypt.c +++ b/modules/md/md_crypt.c @@ -57,21 +57,11 @@ #include <process.h> #endif -#if defined(LIBRESSL_VERSION_NUMBER) -/* Missing from LibreSSL */ -#define MD_USE_OPENSSL_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f) -#else /* defined(LIBRESSL_VERSION_NUMBER) */ -#define MD_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) -#endif - -#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x3050000fL)) || (OPENSSL_VERSION_NUMBER < 0x10100000L) +#if !defined(OPENSSL_NO_CT) \ + && OPENSSL_VERSION_NUMBER >= 0x10100000L \ + && (!defined(LIBRESSL_VERSION_NUMBER) \ + || LIBRESSL_VERSION_NUMBER >= 0x3050000fL) /* Missing from LibreSSL < 3.5.0 and only available since OpenSSL v1.1.x */ -#ifndef OPENSSL_NO_CT -#define OPENSSL_NO_CT -#endif -#endif - -#ifndef OPENSSL_NO_CT #include <openssl/ct.h> #endif @@ -955,12 +945,9 @@ apr_status_t md_pkey_gen(md_pkey_t **ppkey, apr_pool_t *p, md_pkey_spec_t *spec) } } -#if MD_USE_OPENSSL_PRE_1_1_API || (defined(LIBRESSL_VERSION_NUMBER) && \ - LIBRESSL_VERSION_NUMBER < 0x2070000f) - -#ifndef NID_tlsfeature -#define NID_tlsfeature 1020 -#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L \ + || (defined(LIBRESSL_VERSION_NUMBER) \ + && LIBRESSL_VERSION_NUMBER < 0x2070000f) static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) diff --git a/modules/md/md_ocsp.c b/modules/md/md_ocsp.c index 8cbf05b..8276137 100644 --- a/modules/md/md_ocsp.c +++ b/modules/md/md_ocsp.c @@ -32,13 +32,6 @@ #include <openssl/pem.h> #include <openssl/x509v3.h> -#if defined(LIBRESSL_VERSION_NUMBER) -/* Missing from LibreSSL */ -#define MD_USE_OPENSSL_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f) -#else /* defined(LIBRESSL_VERSION_NUMBER) */ -#define MD_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) -#endif - #include "md.h" #include "md_crypt.h" #include "md_event.h" @@ -563,7 +556,9 @@ static const char *single_resp_summary(OCSP_SINGLERESP* resp, apr_pool_t *p) ASN1_GENERALIZEDTIME *bup = NULL, *bnextup = NULL; md_timeperiod_t valid; -#if MD_USE_OPENSSL_PRE_1_1_API +#if OPENSSL_VERSION_NUMBER < 0x10100000L \ + || (defined(LIBRESSL_VERSION_NUMBER) \ + && LIBRESSL_VERSION_NUMBER < 0x2070000f) certid = resp->certId; #else certid = OCSP_SINGLERESP_get0_id(resp); @@ -683,12 +678,6 @@ static apr_status_t ostat_on_resp(const md_http_response_t *resp, void *baton) md_result_log(update->result, MD_LOG_DEBUG); goto cleanup; } - if (!bnextup) { - rv = APR_EINVAL; - md_result_set(update->result, rv, "OCSP basicresponse reports not valid dates"); - md_result_log(update->result, MD_LOG_DEBUG); - goto cleanup; - } /* Coming here, we have a response for our certid and it is either GOOD * or REVOKED. Both cases we want to remember and use in stapling. */ @@ -703,7 +692,14 @@ static apr_status_t ostat_on_resp(const md_http_response_t *resp, void *baton) new_der.free_data = md_openssl_free; nstat = (bstatus == V_OCSP_CERTSTATUS_GOOD)? MD_OCSP_CERT_ST_GOOD : MD_OCSP_CERT_ST_REVOKED; valid.start = bup? md_asn1_generalized_time_get(bup) : apr_time_now(); - valid.end = md_asn1_generalized_time_get(bnextup); + if (bnextup) { + valid.end = md_asn1_generalized_time_get(bnextup); + } + else { + /* nextUpdate not set; default to 12 hours. + * Refresh attempts will be started some time earlier. */ + valid.end = valid.start + apr_time_from_sec(MD_SECS_PER_DAY / 2); + } /* First, update the instance with a copy */ apr_thread_mutex_lock(ostat->reg->mutex); diff --git a/modules/md/md_reg.c b/modules/md/md_reg.c index 8bceb0e..6aa7d78 100644 --- a/modules/md/md_reg.c +++ b/modules/md/md_reg.c @@ -31,6 +31,7 @@ #include "md_json.h" #include "md_result.h" #include "md_reg.h" +#include "md_ocsp.h" #include "md_store.h" #include "md_status.h" #include "md_tailscale.h" @@ -1321,3 +1322,38 @@ md_job_t *md_reg_job_make(md_reg_t *reg, const char *mdomain, apr_pool_t *p) { return md_job_make(p, reg->store, MD_SG_STAGING, mdomain, reg->min_delay); } + +static int get_cert_count(const md_t *md) +{ + if (md->cert_files && md->cert_files->nelts) { + return md->cert_files->nelts; + } + return md_pkeys_spec_count(md->pks); +} + +int md_reg_has_revoked_certs(md_reg_t *reg, struct md_ocsp_reg_t *ocsp, + const md_t *md, apr_pool_t *p) +{ + const md_pubcert_t *pubcert; + const md_cert_t *cert; + md_timeperiod_t ocsp_valid; + md_ocsp_cert_stat_t cert_stat; + apr_status_t rv = APR_SUCCESS; + int i; + + if (!md->stapling || !ocsp) + return 0; + + for (i = 0; i < get_cert_count(md); ++i) { + if (APR_SUCCESS != md_reg_get_pubcert(&pubcert, reg, md, i, p)) + continue; + cert = APR_ARRAY_IDX(pubcert->certs, 0, const md_cert_t*); + if(!cert) + continue; + rv = md_ocsp_get_meta(&cert_stat, &ocsp_valid, ocsp, cert, p, md); + if (APR_SUCCESS == rv && cert_stat == MD_OCSP_CERT_ST_REVOKED) { + return 1; + } + } + return 0; +} diff --git a/modules/md/md_reg.h b/modules/md/md_reg.h index 58ee16a..191b026 100644 --- a/modules/md/md_reg.h +++ b/modules/md/md_reg.h @@ -23,6 +23,7 @@ struct md_pkey_t; struct md_cert_t; struct md_result_t; struct md_pkey_spec_t; +struct md_ocsp_reg_t; #include "md_store.h" @@ -310,4 +311,10 @@ apr_status_t md_reg_lock_global(md_reg_t *reg, apr_pool_t *p); */ void md_reg_unlock_global(md_reg_t *reg, apr_pool_t *p); +/** + * @return != 0 iff `md` has any certificates known to be REVOKED. + */ +int md_reg_has_revoked_certs(md_reg_t *reg, struct md_ocsp_reg_t *ocsp, + const md_t *md, apr_pool_t *p); + #endif /* mod_md_md_reg_h */ diff --git a/modules/md/md_version.h b/modules/md/md_version.h index 86a1821..cefbb8d 100644 --- a/modules/md/md_version.h +++ b/modules/md/md_version.h @@ -27,7 +27,7 @@ * @macro * Version number of the md module as c string */ -#define MOD_MD_VERSION "2.4.25" +#define MOD_MD_VERSION "2.4.26" /** * @macro @@ -35,7 +35,7 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define MOD_MD_VERSION_NUM 0x020419 +#define MOD_MD_VERSION_NUM 0x02041a #define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory" #define MD_TAILSCALE_DEF_URL "file://localhost/var/run/tailscale/tailscaled.sock" diff --git a/modules/md/mod_md_config.c b/modules/md/mod_md_config.c index 31d06b4..cdd1e29 100644 --- a/modules/md/mod_md_config.c +++ b/modules/md/mod_md_config.c @@ -84,6 +84,7 @@ static md_mod_conf_t defmc = { "crt.sh", /* default cert checker site name */ "https://crt.sh?q=", /* default cert checker site url */ NULL, /* CA cert file to use */ + apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */ apr_time_from_sec(5), /* minimum delay for retries */ 13, /* retry_failover after 14 errors, with 5s delay ~ half a day */ 0, /* store locks, disabled by default */ @@ -624,6 +625,24 @@ static const char *md_config_set_base_server(cmd_parms *cmd, void *dc, const cha return set_on_off(&config->mc->manage_base_server, value, cmd->pool); } +static const char *md_config_set_check_interval(cmd_parms *cmd, void *dc, const char *value) +{ + md_srv_conf_t *config = md_config_get(cmd->server); + const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD); + apr_time_t interval; + + (void)dc; + if (err) return err; + if (md_duration_parse(&interval, value, "s") != APR_SUCCESS) { + return "unrecognized duration format"; + } + if (interval < apr_time_from_sec(1)) { + return "check interval cannot be less than one second"; + } + config->mc->check_interval = interval; + return NULL; +} + static const char *md_config_set_min_delay(cmd_parms *cmd, void *dc, const char *value) { md_srv_conf_t *config = md_config_get(cmd->server); @@ -1304,7 +1323,8 @@ const command_rec md_cmds[] = { "Configure locking of store for updates."), AP_INIT_TAKE1("MDMatchNames", md_config_set_match_mode, NULL, RSRC_CONF, "Determines how DNS names are matched to vhosts."), - + AP_INIT_TAKE1("MDCheckInterval", md_config_set_check_interval, NULL, RSRC_CONF, + "Time between certificate checks."), AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL) }; diff --git a/modules/md/mod_md_config.h b/modules/md/mod_md_config.h index 7e87440..1ce2375 100644 --- a/modules/md/mod_md_config.h +++ b/modules/md/mod_md_config.h @@ -75,6 +75,7 @@ struct md_mod_conf_t { const char *cert_check_name; /* name of the linked certificate check site */ const char *cert_check_url; /* url "template for" checking a certificate */ const char *ca_certs; /* root certificates to use for connections */ + apr_time_t check_interval; /* duration between cert renewal checks */ apr_time_t min_delay; /* minimum delay for retries */ int retry_failover; /* number of errors to trigger CA failover */ int use_store_locks; /* use locks when updating store */ diff --git a/modules/md/mod_md_drive.c b/modules/md/mod_md_drive.c index 5565f44..d2655b8 100644 --- a/modules/md/mod_md_drive.c +++ b/modules/md/mod_md_drive.c @@ -100,7 +100,7 @@ static void process_drive_job(md_renew_ctx_t *dctx, md_job_t *job, apr_pool_t *p } if (md_will_renew_cert(md)) { - /* Renew the MDs credentials in a STAGING area. Might be invoked repeatedly + /* Renew the MDs credentials in a STAGING area. Might be invoked repeatedly * without discarding previous/intermediate results. * Only returns SUCCESS when the renewal is complete, e.g. STAGING has a * complete set of new credentials. @@ -108,7 +108,12 @@ static void process_drive_job(md_renew_ctx_t *dctx, md_job_t *job, apr_pool_t *p ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10052) "md(%s): state=%d, driving", job->mdomain, md->state); - if (!md_reg_should_renew(dctx->mc->reg, md, dctx->p)) { + if (md->stapling && dctx->mc->ocsp && + md_reg_has_revoked_certs(dctx->mc->reg, dctx->mc->ocsp, md, dctx->p)) { + ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10500) + "md(%s): has revoked certificates", job->mdomain); + } + else if (!md_reg_should_renew(dctx->mc->reg, md, dctx->p)) { ap_log_error( APLOG_MARK, APLOG_DEBUG, 0, dctx->s, APLOGNO(10053) "md(%s): no need to renew", job->mdomain); goto expiry; @@ -180,10 +185,13 @@ int md_will_renew_cert(const md_t *md) return 1; } -static apr_time_t next_run_default(void) +static apr_time_t next_run_default(md_renew_ctx_t *dctx) { - /* we'd like to run at least twice a day by default */ - return apr_time_now() + apr_time_from_sec(MD_SECS_PER_DAY / 2); + unsigned char c; + apr_time_t delay = dctx->mc->check_interval; + + md_rand_bytes(&c, sizeof(c), dctx->p); + return apr_time_now() + delay + (delay * (c - 128) / 256); } static apr_status_t run_watchdog(int state, void *baton, apr_pool_t *ptemp) @@ -211,7 +219,7 @@ static apr_status_t run_watchdog(int state, void *baton, apr_pool_t *ptemp) * and we schedule ourself at the earliest of all. A job may specify 0 * as next_run to indicate that it wants to participate in the normal * regular runs. */ - next_run = next_run_default(); + next_run = next_run_default(dctx); for (i = 0; i < dctx->jobs->nelts; ++i) { job = APR_ARRAY_IDX(dctx->jobs, i, md_job_t *); diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index ef812cd..4838bd6 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -783,14 +783,14 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers, break; case hdr_set: if (!ap_cstr_casecmp(hdr->header, "Content-Type")) { - ap_set_content_type(r, process_tags(hdr, r)); + ap_set_content_type_ex(r, process_tags(hdr, r), 1); } apr_table_setn(headers, hdr->header, process_tags(hdr, r)); break; case hdr_setifempty: if (NULL == apr_table_get(headers, hdr->header)) { if (!ap_cstr_casecmp(hdr->header, "Content-Type")) { - ap_set_content_type(r, process_tags(hdr, r)); + ap_set_content_type_ex(r, process_tags(hdr, r), 1); } apr_table_setn(headers, hdr->header, process_tags(hdr, r)); } @@ -809,7 +809,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers, const char *repl = process_regexp(hdr, r->content_type, r); if (repl == NULL) return 0; - ap_set_content_type(r, repl); + ap_set_content_type_ex(r, repl, 1); } if (apr_table_get(headers, hdr->header)) { edit_do ed; diff --git a/modules/metadata/mod_mime_magic.c b/modules/metadata/mod_mime_magic.c index 7dac4fd..1c96db4 100644 --- a/modules/metadata/mod_mime_magic.c +++ b/modules/metadata/mod_mime_magic.c @@ -788,7 +788,7 @@ static int magic_rsl_to_request(request_rec *r) /* XXX: this could be done at config time I'm sure... but I'm * confused by all this magic_rsl stuff. -djg */ ap_content_type_tolower(tmp); - ap_set_content_type(r, tmp); + ap_set_content_type_ex(r, tmp, 1); if (state == rsl_encoding) { tmp = rsl_strdup(r, encoding_frag, @@ -2326,7 +2326,7 @@ static int revision_suffix(request_rec *r) /* extract content type/encoding/language from sub-request */ if (sub->content_type) { - ap_set_content_type(r, apr_pstrdup(r->pool, sub->content_type)); + ap_set_content_type_ex(r, apr_pstrdup(r->pool, sub->content_type), 1); #if MIME_MAGIC_DEBUG ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01557) MODNAME ": subrequest %s got %s", diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index c9cef7c..ad0c031 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -1245,6 +1245,7 @@ static int proxy_fixup(request_rec *r) return OK; /* otherwise; we've done the best we can */ } + /* Send a redirection if the request contains a hostname which is not */ /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */ /* servers like Netscape's allow this and access hosts from the local */ @@ -1298,7 +1299,7 @@ static int proxy_handler(request_rec *r) ap_get_module_config(sconf, &proxy_module); apr_array_header_t *proxies = conf->proxies; struct proxy_remote *ents = (struct proxy_remote *) proxies->elts; - int i, rc, access_status; + int rc = DECLINED, access_status, i; int direct_connect = 0; const char *str; apr_int64_t maxfwd; @@ -1313,19 +1314,28 @@ static int proxy_handler(request_rec *r) return DECLINED; } - if (!r->proxyreq) { - /* We may have forced the proxy handler via config or .htaccess */ - if (r->handler && - strncmp(r->handler, "proxy:", 6) == 0 && - strncmp(r->filename, "proxy:", 6) != 0) { - r->proxyreq = PROXYREQ_REVERSE; - r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL); + /* We may have forced the proxy handler via config or .htaccess */ + if (!r->proxyreq && r->handler && strncmp(r->handler, "proxy:", 6) == 0) { + char *old_filename = r->filename; + + r->proxyreq = PROXYREQ_REVERSE; + r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL); + + /* Still need to fixup/canonicalize r->filename */ + rc = ap_proxy_fixup_uds_filename(r); + if (rc <= OK) { + rc = proxy_fixup(r); } - else { - return DECLINED; + if (rc != OK) { + r->filename = old_filename; + r->proxyreq = 0; } - } else if (strncmp(r->filename, "proxy:", 6) != 0) { - return DECLINED; + } + else if (r->proxyreq && strncmp(r->filename, "proxy:", 6) == 0) { + rc = OK; + } + if (rc != OK) { + return rc; } /* handle max-forwards / OPTIONS / TRACE */ diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 51a55f8..59572bf 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -1003,6 +1003,14 @@ PROXY_DECLARE(proxy_balancer_shared *) ap_proxy_find_balancershm(ap_slotmem_prov proxy_balancer *balancer, unsigned int *index); +/* + * Strip the UDS part of r->filename if any, and put the UDS path in + * r->notes ("uds_path") + * @param r current request + * @return OK if fixed up, DECLINED if not UDS, or an HTTP_XXX error + */ +PROXY_DECLARE(int) ap_proxy_fixup_uds_filename(request_rec *r); + /** * Get the most suitable worker and/or balancer for the request * @param worker worker used for processing request diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index a54a4fa..e71cbd8 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1512,8 +1512,9 @@ static void socket_cleanup(proxy_conn_rec *conn) apr_pool_clear(conn->scpool); } -static void address_cleanup(proxy_conn_rec *conn) +static void conn_cleanup(proxy_conn_rec *conn) { + socket_cleanup(conn); conn->address = NULL; conn->addr = NULL; conn->hostname = NULL; @@ -1522,9 +1523,6 @@ static void address_cleanup(proxy_conn_rec *conn) if (conn->uds_pool) { apr_pool_clear(conn->uds_pool); } - if (conn->sock) { - socket_cleanup(conn); - } } static apr_status_t conn_pool_cleanup(void *theworker) @@ -2431,7 +2429,7 @@ static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worke * were passed a UDS url (eg: from mod_proxy) and adjust uds_path * as required. */ -static int fix_uds_filename(request_rec *r, char **url) +PROXY_DECLARE(int) ap_proxy_fixup_uds_filename(request_rec *r) { char *uds_url = r->filename + 6, *origin_url; @@ -2439,7 +2437,6 @@ static int fix_uds_filename(request_rec *r, char **url) !ap_cstr_casecmpn(uds_url, "unix:", 5) && (origin_url = ap_strchr(uds_url + 5, '|'))) { char *uds_path = NULL; - apr_size_t url_len; apr_uri_t urisock; apr_status_t rv; @@ -2454,20 +2451,20 @@ static int fix_uds_filename(request_rec *r, char **url) if (!uds_path) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10292) "Invalid proxy UDS filename (%s)", r->filename); - return 0; + return HTTP_BAD_REQUEST; } apr_table_setn(r->notes, "uds_path", uds_path); - /* Remove the UDS path from *url and r->filename */ - url_len = strlen(origin_url); - *url = apr_pstrmemdup(r->pool, origin_url, url_len); - memcpy(uds_url, *url, url_len + 1); - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, - "*: rewrite of url due to UDS(%s): %s (%s)", - uds_path, *url, r->filename); + "*: fixup UDS from %s: %s (%s)", + r->filename, origin_url, uds_path); + + /* Overwrite the UDS part in place */ + memmove(uds_url, origin_url, strlen(origin_url) + 1); + return OK; } - return 1; + + return DECLINED; } PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, @@ -2486,9 +2483,6 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "%s: found worker %s for %s", (*worker)->s->scheme, (*worker)->s->name_ex, *url); - if (!forward && !fix_uds_filename(r, url)) { - return HTTP_INTERNAL_SERVER_ERROR; - } access_status = OK; } else if (forward) { @@ -2518,9 +2512,6 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, * regarding the Connection header in the request. */ apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1"); - if (!fix_uds_filename(r, url)) { - return HTTP_INTERNAL_SERVER_ERROR; - } } } } @@ -2530,6 +2521,20 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, "all workers are busy. Unable to serve %s", *url); access_status = HTTP_SERVICE_UNAVAILABLE; } + + if (access_status == OK && r->proxyreq == PROXYREQ_REVERSE) { + int rc = ap_proxy_fixup_uds_filename(r); + if (ap_is_HTTP_ERROR(rc)) { + return rc; + } + /* If the URL has changed in r->filename, take everything after + * the "proxy:" prefix. + */ + if (rc == OK) { + *url = apr_pstrdup(r->pool, r->filename + 6); + } + } + return access_status; } @@ -2784,8 +2789,8 @@ static apr_status_t worker_address_resolve(proxy_worker *worker, apr_sockaddr_t *addr = *paddr; for (; addr; addr = addr->next) { addrs = apr_psprintf(pool, "%s%s%pI", - addrs ? ", " : "", addrs ? addrs : "", + addrs ? ", " : "", addr); } if (r) { @@ -2959,15 +2964,16 @@ PROXY_DECLARE(apr_status_t) ap_proxy_determine_address(const char *proxy_functio */ address->expiry = apr_atomic_read32(&worker->s->address_expiry); if (address->expiry <= now) { - apr_uint32_t new_expiry = address->expiry + ttl; - while (new_expiry <= now) { - new_expiry += ttl; - } - new_expiry = apr_atomic_cas32(&worker->s->address_expiry, - new_expiry, address->expiry); - /* race lost? well the expiry should grow anyway.. */ - AP_DEBUG_ASSERT(new_expiry > now); - address->expiry = new_expiry; + apr_uint32_t prev, next = (now + ttl) - (now % ttl); + do { + prev = apr_atomic_cas32(&worker->s->address_expiry, + next, address->expiry); + if (prev == address->expiry) { + address->expiry = next; + break; + } + address->expiry = prev; + } while (prev <= now); } } else { @@ -3008,13 +3014,40 @@ PROXY_DECLARE(apr_status_t) ap_proxy_determine_address(const char *proxy_functio PROXY_THREAD_UNLOCK(worker); - /* Kill any socket using the old address */ - if (conn->sock) { - if (r ? APLOGrdebug(r) : APLOGdebug(s)) { - /* XXX: this requires the old conn->addr[ess] to still - * be alive since it's not copied by apr_socket_connect() - * in ap_proxy_connect_backend(). - */ + /* Release the old conn address */ + if (conn->address) { + /* On Windows and OS/2, apr_socket_connect() called from + * ap_proxy_connect_backend() does a simple pointer copy of + * its given conn->addr[->next] into conn->sock->remote_addr. + * Thus conn->addr cannot be freed if the conn->sock should be + * kept alive (same new and old addresses) and the old address + * is still in conn->sock->remote_addr. In this case we rather + * delay the release of the old address by moving the cleanup + * to conn->scpool such that it runs when the socket is closed. + * In any other case, including other platforms, just release + * the old address now since conn->sock->remote_addr is either + * obsolete (socket forcibly closed) or a copy on conn->scpool + * already (not a dangling pointer). + */ + int keep_addr_alive = 0, + keep_conn_alive = (conn->sock && conn->addr && + proxy_addrs_equal(conn->addr, + address->addr)); + if (keep_conn_alive) { +#if defined(WIN32) || defined(OS2) + apr_sockaddr_t *remote_addr = NULL; + apr_socket_addr_get(&remote_addr, APR_REMOTE, conn->sock); + for (addr = conn->addr; addr; addr = addr->next) { + if (addr == remote_addr) { + keep_addr_alive = 1; + break; + } + } +#else + /* Nothing to do, keep_addr_alive = 0 */ +#endif + } + else if (conn->sock && (r ? APLOGrdebug(r) : APLOGdebug(s))) { apr_sockaddr_t *local_addr = NULL; apr_sockaddr_t *remote_addr = NULL; apr_socket_addr_get(&local_addr, APR_LOCAL, conn->sock); @@ -3032,18 +3065,26 @@ PROXY_DECLARE(apr_status_t) ap_proxy_determine_address(const char *proxy_functio local_addr, remote_addr); } } - socket_cleanup(conn); + if (keep_addr_alive) { + apr_pool_cleanup_kill(conn->pool, conn->address, + proxy_address_cleanup); + apr_pool_cleanup_register(conn->scpool, conn->address, + proxy_address_cleanup, + apr_pool_cleanup_null); + } + else { + apr_pool_cleanup_run(conn->pool, conn->address, + proxy_address_cleanup); + if (!keep_conn_alive) { + conn_cleanup(conn); + } + } } - /* Kill the old address (if any) and use the new one */ - if (conn->address) { - apr_pool_cleanup_run(conn->pool, conn->address, - proxy_address_cleanup); - } + /* Use the new address */ apr_pool_cleanup_register(conn->pool, address, proxy_address_cleanup, apr_pool_cleanup_null); - address_cleanup(conn); conn->address = address; conn->hostname = address->hostname; conn->port = address->hostport; @@ -3079,6 +3120,13 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, apr_pstrcat(p,"URI cannot be parsed: ", *url, NULL)); } + + if (!uri->hostname) { + return ap_proxyerror(r, HTTP_BAD_REQUEST, + apr_pstrcat(p,"URI has no hostname: ", *url, + NULL)); + } + if (!uri->port) { uri->port = ap_proxy_port_of_scheme(uri->scheme); } @@ -3125,7 +3173,7 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, if (!conn->uds_path || strcmp(conn->uds_path, uds_path) != 0) { apr_pool_t *pool = conn->pool; if (conn->uds_path) { - address_cleanup(conn); + conn_cleanup(conn); if (!conn->uds_pool) { apr_pool_create(&conn->uds_pool, worker->cp->dns_pool); } @@ -3226,7 +3274,7 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, if (conn->hostname && (conn->port != hostport || ap_cstr_casecmp(conn->hostname, hostname) != 0)) { - address_cleanup(conn); + conn_cleanup(conn); } /* Resolve the connection address with the determined hostname/port */ @@ -4462,6 +4510,10 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, /* Compute Host header */ if (dconf->preserve_host == 0) { + if (!uri->hostname) { + rc = HTTP_BAD_REQUEST; + goto cleanup; + } if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */ if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { host = apr_pstrcat(r->pool, "[", uri->hostname, "]:", diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index c2ec048..443eac4 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -844,6 +844,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, } #endif +#ifdef SSL_OP_NO_RENEGOTIATION + /* For server-side SSL_CTX, disable renegotiation by default.. */ + if (!mctx->pkp) { + SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION); + } +#endif + #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* For server-side SSL_CTX, enable ignoring unexpected EOF */ /* (OpenSSL 1.1.1 behavioural compatibility).. */ @@ -872,6 +879,14 @@ static void ssl_init_ctx_session_cache(server_rec *s, } } +#ifdef SSL_OP_NO_RENEGOTIATION +/* OpenSSL-level renegotiation protection. */ +#define MODSSL_BLOCKS_RENEG (0) +#else +/* mod_ssl-level renegotiation protection. */ +#define MODSSL_BLOCKS_RENEG (1) +#endif + static void ssl_init_ctx_callbacks(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, @@ -885,7 +900,13 @@ static void ssl_init_ctx_callbacks(server_rec *s, SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); #endif - SSL_CTX_set_info_callback(ctx, ssl_callback_Info); + /* The info callback is used for debug-level tracing. For OpenSSL + * versions where SSL_OP_NO_RENEGOTIATION is not available, the + * callback is also used to prevent use of client-initiated + * renegotiation. Enable it in either case. */ + if (APLOGdebug(s) || MODSSL_BLOCKS_RENEG) { + SSL_CTX_set_info_callback(ctx, ssl_callback_Info); + } #ifdef HAVE_TLS_ALPN SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL); @@ -1346,6 +1367,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s, const char *vhost_id = mctx->sc->vhost_id, *key_id, *certfile, *keyfile; int i; EVP_PKEY *pkey; + int custom_dh_done = 0; #ifdef HAVE_ECC EC_GROUP *ecgroup = NULL; int curve_nid = 0; @@ -1518,14 +1540,14 @@ static apr_status_t ssl_init_server_certs(server_rec *s, */ certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *); if (certfile && !modssl_is_engine_id(certfile)) { - int done = 0, num_bits = 0; + int num_bits = 0; #if OPENSSL_VERSION_NUMBER < 0x30000000L DH *dh = modssl_dh_from_file(certfile); if (dh) { num_bits = DH_bits(dh); SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dh); DH_free(dh); - done = 1; + custom_dh_done = 1; } #else pkey = modssl_dh_pkey_from_file(certfile); @@ -1535,18 +1557,18 @@ static apr_status_t ssl_init_server_certs(server_rec *s, EVP_PKEY_free(pkey); } else { - done = 1; + custom_dh_done = 1; } } #endif - if (done) { + if (custom_dh_done) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540) "Custom DH parameters (%d bits) for %s loaded from %s", num_bits, vhost_id, certfile); } } #if !MODSSL_USE_OPENSSL_PRE_1_1_API - else { + if (!custom_dh_done) { /* If no parameter is manually configured, enable auto * selection. */ SSL_CTX_set_dh_auto(mctx->ssl_ctx, 1); diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index b91f784..9c7d216 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -208,11 +208,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl) BIO_clear_retry_flags(bio); +#ifndef SSL_OP_NO_RENEGOTIATION /* Abort early if the client has initiated a renegotiation. */ if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) { outctx->rc = APR_ECONNABORTED; return -1; } +#endif ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c, "bio_filter_out_write: %i bytes", inl); @@ -473,11 +475,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen) BIO_clear_retry_flags(bio); +#ifndef SSL_OP_NO_RENEGOTIATION /* Abort early if the client has initiated a renegotiation. */ if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) { inctx->rc = APR_ECONNABORTED; return -1; } +#endif if (!inctx->bb) { inctx->rc = APR_EOF; diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index fe0496f..fa1b3a8 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -992,7 +992,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo /* Toggle the renegotiation state to allow the new * handshake to proceed. */ - sslconn->reneg_state = RENEG_ALLOW; + modssl_set_reneg_state(sslconn, RENEG_ALLOW); SSL_renegotiate(ssl); SSL_do_handshake(ssl); @@ -1019,7 +1019,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo */ SSL_peek(ssl, peekbuf, 0); - sslconn->reneg_state = RENEG_REJECT; + modssl_set_reneg_state(sslconn, RENEG_REJECT); if (!SSL_is_init_finished(ssl)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261) @@ -1078,7 +1078,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) { int vmode_inplace, vmode_needed; int change_vmode = FALSE; - int old_state, n, rc; + int n, rc; vmode_inplace = SSL_get_verify_mode(ssl); vmode_needed = SSL_VERIFY_NONE; @@ -1180,8 +1180,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon return HTTP_FORBIDDEN; } - old_state = sslconn->reneg_state; - sslconn->reneg_state = RENEG_ALLOW; modssl_set_app_data2(ssl, r); SSL_do_handshake(ssl); @@ -1191,7 +1189,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon */ SSL_peek(ssl, peekbuf, 0); - sslconn->reneg_state = old_state; modssl_set_app_data2(ssl, NULL); /* @@ -2263,8 +2260,8 @@ static void log_tracing_state(const SSL *ssl, conn_rec *c, /* * This callback function is executed while OpenSSL processes the SSL * handshake and does SSL record layer stuff. It's used to trap - * client-initiated renegotiations, and for dumping everything to the - * log. + * client-initiated renegotiations (where SSL_OP_NO_RENEGOTIATION is + * not available), and for dumping everything to the log. */ void ssl_callback_Info(const SSL *ssl, int where, int rc) { @@ -2276,14 +2273,12 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) return; } - /* With TLS 1.3 this callback may be called multiple times on the first - * negotiation, so the below logic to detect renegotiations can't work. - * Fortunately renegotiations are forbidden starting with TLS 1.3, and - * this is enforced by OpenSSL so there's nothing to be done here. - */ -#if SSL_HAVE_PROTOCOL_TLSV1_3 - if (SSL_version(ssl) < TLS1_3_VERSION) -#endif +#ifndef SSL_OP_NO_RENEGOTIATION + /* With OpenSSL < 1.1.1 (implying TLS v1.2 or earlier), this + * callback is used to block client-initiated renegotiation. With + * TLSv1.3 it is unnecessary since renegotiation is forbidden at + * protocol level. Otherwise (TLSv1.2 with OpenSSL >=1.1.1), + * SSL_OP_NO_RENEGOTIATION is used to block renegotiation. */ { SSLConnRec *sslconn; @@ -2308,6 +2303,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) sslconn->reneg_state = RENEG_REJECT; } } +#endif s = mySrvFromConn(c); if (s && APLOGdebug(s)) { diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 859e932..25d79ce 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -549,6 +549,16 @@ typedef struct { apr_time_t source_mtime; } ssl_asn1_t; +typedef enum { + RENEG_INIT = 0, /* Before initial handshake */ + RENEG_REJECT, /* After initial handshake; any client-initiated + * renegotiation should be rejected */ + RENEG_ALLOW, /* A server-initiated renegotiation is taking + * place (as dictated by configuration) */ + RENEG_ABORT /* Renegotiation initiated by client, abort the + * connection */ +} modssl_reneg_state; + /** * Define the mod_ssl per-module configuration structure * (i.e. the global configuration for each httpd process) @@ -580,18 +590,13 @@ typedef struct { NON_SSL_SET_ERROR_MSG /* Need to set the error message */ } non_ssl_request; - /* Track the handshake/renegotiation state for the connection so - * that all client-initiated renegotiations can be rejected, as a - * partial fix for CVE-2009-3555. */ - enum { - RENEG_INIT = 0, /* Before initial handshake */ - RENEG_REJECT, /* After initial handshake; any client-initiated - * renegotiation should be rejected */ - RENEG_ALLOW, /* A server-initiated renegotiation is taking - * place (as dictated by configuration) */ - RENEG_ABORT /* Renegotiation initiated by client, abort the - * connection */ - } reneg_state; +#ifndef SSL_OP_NO_RENEGOTIATION + /* For OpenSSL < 1.1.1, track the handshake/renegotiation state + * for the connection to block client-initiated renegotiations. + * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in + * the SSL * options state with equivalent effect. */ + modssl_reneg_state reneg_state; +#endif server_rec *server; SSLDirConfigRec *dc; @@ -1198,6 +1203,9 @@ int ssl_is_challenge(conn_rec *c, const char *servername, * the configured ENGINE. */ int modssl_is_engine_id(const char *name); +/* Set the renegotation state for connection. */ +void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state); + #endif /* SSL_PRIVATE_H */ /** @} */ diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c index 44930b7..8bd9c8a 100644 --- a/modules/ssl/ssl_util_ssl.c +++ b/modules/ssl/ssl_util_ssl.c @@ -612,3 +612,19 @@ cleanup: } return rv; } + +void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state) +{ +#ifdef SSL_OP_NO_RENEGOTIATION + switch (state) { + case RENEG_ALLOW: + SSL_clear_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION); + break; + default: + SSL_set_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION); + break; + } +#else + sslconn->reneg_state = state; +#endif +} diff --git a/modules/tls/tls_cert.c b/modules/tls/tls_cert.c index 624535a..ffb941c 100644 --- a/modules/tls/tls_cert.c +++ b/modules/tls/tls_cert.c @@ -331,11 +331,12 @@ const char *tls_cert_reg_get_id(tls_cert_reg_t *reg, const rustls_certified_key } apr_status_t tls_cert_load_root_store( - apr_pool_t *p, const char *store_file, rustls_root_cert_store **pstore) + apr_pool_t *p, const char *store_file, const rustls_root_cert_store **pstore) { const char *fpath; tls_data_t pem; - rustls_root_cert_store *store = NULL; + rustls_root_cert_store_builder *store_builder = NULL; + const rustls_root_cert_store *store = NULL; rustls_result rr = RUSTLS_RESULT_OK; apr_pool_t *ptemp = NULL; apr_status_t rv; @@ -353,11 +354,17 @@ apr_status_t tls_cert_load_root_store( rv = tls_util_file_load(ptemp, fpath, 0, 1024*1024, &pem); if (APR_SUCCESS != rv) goto cleanup; - store = rustls_root_cert_store_new(); - rr = rustls_root_cert_store_add_pem(store, pem.data, pem.len, 1); + store_builder = rustls_root_cert_store_builder_new(); + rr = rustls_root_cert_store_builder_add_pem(store_builder, pem.data, pem.len, 1); + if (RUSTLS_RESULT_OK != rr) goto cleanup; + + rr = rustls_root_cert_store_builder_build(store_builder, &store); if (RUSTLS_RESULT_OK != rr) goto cleanup; cleanup: + if (store_builder != NULL) { + rustls_root_cert_store_builder_free(store_builder); + } if (RUSTLS_RESULT_OK != rr) { const char *err_descr; rv = tls_util_rustls_error(p, rr, &err_descr); @@ -378,7 +385,7 @@ cleanup: typedef struct { const char *id; - rustls_root_cert_store *store; + const rustls_root_cert_store *store; } tls_cert_root_stores_entry_t; static int stores_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val) @@ -421,14 +428,14 @@ void tls_cert_root_stores_clear(tls_cert_root_stores_t *stores) apr_status_t tls_cert_root_stores_get( tls_cert_root_stores_t *stores, const char *store_file, - rustls_root_cert_store **pstore) + const rustls_root_cert_store **pstore) { apr_status_t rv = APR_SUCCESS; tls_cert_root_stores_entry_t *entry; entry = apr_hash_get(stores->file2store, store_file, APR_HASH_KEY_STRING); if (!entry) { - rustls_root_cert_store *store; + const rustls_root_cert_store *store; rv = tls_cert_load_root_store(stores->pool, store_file, &store); if (APR_SUCCESS != rv) goto cleanup; entry = apr_pcalloc(stores->pool, sizeof(*entry)); @@ -449,8 +456,8 @@ cleanup: typedef struct { const char *id; - const rustls_client_cert_verifier *client_verifier; - const rustls_client_cert_verifier_optional *client_verifier_opt; + rustls_client_cert_verifier *client_verifier; + rustls_client_cert_verifier *client_verifier_opt; } tls_cert_verifiers_entry_t; static int verifiers_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val) @@ -462,7 +469,7 @@ static int verifiers_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, entry->client_verifier = NULL; } if (entry->client_verifier_opt) { - rustls_client_cert_verifier_optional_free(entry->client_verifier_opt); + rustls_client_cert_verifier_free(entry->client_verifier_opt); entry->client_verifier_opt = NULL; } return 1; @@ -511,23 +518,44 @@ static tls_cert_verifiers_entry_t * verifiers_get_or_make_entry( return entry; } -apr_status_t tls_cert_client_verifiers_get( - tls_cert_verifiers_t *verifiers, - const char *store_file, - const rustls_client_cert_verifier **pverifier) +static apr_status_t tls_cert_client_verifiers_get_internal( + tls_cert_verifiers_t *verifiers, + const char *store_file, + const rustls_client_cert_verifier **pverifier, + bool allow_unauthenticated) { apr_status_t rv = APR_SUCCESS; tls_cert_verifiers_entry_t *entry; + rustls_result rr = RUSTLS_RESULT_OK; + struct rustls_web_pki_client_cert_verifier_builder *verifier_builder = NULL; entry = verifiers_get_or_make_entry(verifiers, store_file); if (!entry->client_verifier) { - rustls_root_cert_store *store; + const rustls_root_cert_store *store; rv = tls_cert_root_stores_get(verifiers->stores, store_file, &store); if (APR_SUCCESS != rv) goto cleanup; - entry->client_verifier = rustls_client_cert_verifier_new(store); + verifier_builder = rustls_web_pki_client_cert_verifier_builder_new(store); + + if (allow_unauthenticated) { + rr = rustls_web_pki_client_cert_verifier_builder_allow_unauthenticated(verifier_builder); + if (rr != RUSTLS_RESULT_OK) { + goto cleanup; + } + } + + rr = rustls_web_pki_client_cert_verifier_builder_build(verifier_builder, &entry->client_verifier); + if (rr != RUSTLS_RESULT_OK) { + goto cleanup; + } } cleanup: + if (verifier_builder != NULL) { + rustls_web_pki_client_cert_verifier_builder_free(verifier_builder); + } + if (rr != RUSTLS_RESULT_OK) { + rv = tls_util_rustls_error(verifiers->pool, rr, NULL); + } if (APR_SUCCESS == rv) { *pverifier = entry->client_verifier; } @@ -537,28 +565,19 @@ cleanup: return rv; } -apr_status_t tls_cert_client_verifiers_get_optional( + +apr_status_t tls_cert_client_verifiers_get( tls_cert_verifiers_t *verifiers, const char *store_file, - const rustls_client_cert_verifier_optional **pverifier) + const rustls_client_cert_verifier **pverifier) { - apr_status_t rv = APR_SUCCESS; - tls_cert_verifiers_entry_t *entry; - - entry = verifiers_get_or_make_entry(verifiers, store_file); - if (!entry->client_verifier_opt) { - rustls_root_cert_store *store; - rv = tls_cert_root_stores_get(verifiers->stores, store_file, &store); - if (APR_SUCCESS != rv) goto cleanup; - entry->client_verifier_opt = rustls_client_cert_verifier_optional_new(store); - } + return tls_cert_client_verifiers_get_internal(verifiers, store_file, pverifier, false); +} -cleanup: - if (APR_SUCCESS == rv) { - *pverifier = entry->client_verifier_opt; - } - else { - *pverifier = NULL; - } - return rv; +apr_status_t tls_cert_client_verifiers_get_optional( + tls_cert_verifiers_t *verifiers, + const char *store_file, + const rustls_client_cert_verifier **pverifier) +{ + return tls_cert_client_verifiers_get_internal(verifiers, store_file, pverifier, true); } diff --git a/modules/tls/tls_cert.h b/modules/tls/tls_cert.h index 6ab3f48..3326f0e 100644 --- a/modules/tls/tls_cert.h +++ b/modules/tls/tls_cert.h @@ -128,7 +128,7 @@ const char *tls_cert_reg_get_id(tls_cert_reg_t *reg, const rustls_certified_key * @param pstore the loaded root store on success */ apr_status_t tls_cert_load_root_store( - apr_pool_t *p, const char *store_file, rustls_root_cert_store **pstore); + apr_pool_t *p, const char *store_file, const rustls_root_cert_store **pstore); typedef struct tls_cert_root_stores_t tls_cert_root_stores_t; struct tls_cert_root_stores_t { @@ -157,7 +157,7 @@ void tls_cert_root_stores_clear(tls_cert_root_stores_t *stores); apr_status_t tls_cert_root_stores_get( tls_cert_root_stores_t *stores, const char *store_file, - rustls_root_cert_store **pstore); + const rustls_root_cert_store **pstore); typedef struct tls_cert_verifiers_t tls_cert_verifiers_t; struct tls_cert_verifiers_t { @@ -206,6 +206,6 @@ apr_status_t tls_cert_client_verifiers_get( apr_status_t tls_cert_client_verifiers_get_optional( tls_cert_verifiers_t *verifiers, const char *store_file, - const rustls_client_cert_verifier_optional **pverifier); + const rustls_client_cert_verifier **pverifier); -#endif /* tls_cert_h */
\ No newline at end of file +#endif /* tls_cert_h */ diff --git a/modules/tls/tls_core.c b/modules/tls/tls_core.c index 2547939..1cef254 100644 --- a/modules/tls/tls_core.c +++ b/modules/tls/tls_core.c @@ -764,8 +764,10 @@ static apr_status_t init_outgoing_connection(conn_rec *c) tls_conf_proxy_t *pc; const apr_array_header_t *ciphersuites = NULL; apr_array_header_t *tls_versions = NULL; + rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL; + struct rustls_server_cert_verifier *verifier = NULL; rustls_client_config_builder *builder = NULL; - rustls_root_cert_store *ca_store = NULL; + const rustls_root_cert_store *ca_store = NULL; const char *hostname = NULL, *alpn_note = NULL; rustls_result rr = RUSTLS_RESULT_OK; apr_status_t rv = APR_SUCCESS; @@ -809,7 +811,10 @@ static apr_status_t init_outgoing_connection(conn_rec *c) if (pc->proxy_ca && strcasecmp(pc->proxy_ca, "default")) { rv = tls_cert_root_stores_get(pc->global->stores, pc->proxy_ca, &ca_store); if (APR_SUCCESS != rv) goto cleanup; - rustls_client_config_builder_use_roots(builder, ca_store); + verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(ca_store); + rr = rustls_web_pki_server_cert_verifier_builder_build(verifier_builder, &verifier); + if (RUSTLS_RESULT_OK != rr) goto cleanup; + rustls_client_config_builder_set_server_verifier(builder, verifier); } #if TLS_MACHINE_CERTS @@ -881,6 +886,7 @@ static apr_status_t init_outgoing_connection(conn_rec *c) rustls_connection_set_userdata(cc->rustls_connection, c); cleanup: + if (verifier_builder != NULL) rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); if (builder != NULL) rustls_client_config_builder_free(builder); if (RUSTLS_RESULT_OK != rr) { const char *err_descr = NULL; @@ -1125,10 +1131,10 @@ static apr_status_t build_server_connection(rustls_connection **pconnection, rustls_server_config_builder_set_client_verifier(builder, verifier); } else { - const rustls_client_cert_verifier_optional *verifier; + const rustls_client_cert_verifier *verifier; rv = tls_cert_client_verifiers_get_optional(sc->global->verifiers, sc->client_ca, &verifier); if (APR_SUCCESS != rv) goto cleanup; - rustls_server_config_builder_set_client_verifier_optional(builder, verifier); + rustls_server_config_builder_set_client_verifier(builder, verifier); } } diff --git a/modules/tls/tls_version.h b/modules/tls/tls_version.h index 811d6f1..bc9fb0b 100644 --- a/modules/tls/tls_version.h +++ b/modules/tls/tls_version.h @@ -26,7 +26,7 @@ * @macro * Version number of the md module as c string */ -#define MOD_TLS_VERSION "0.8.3" +#define MOD_TLS_VERSION "0.9.0" /** * @macro @@ -34,6 +34,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define MOD_TLS_VERSION_NUM 0x000802 +#define MOD_TLS_VERSION_NUM 0x000900 #endif /* mod_md_md_version_h */ diff --git a/server/config.c b/server/config.c index 3d11ff5..635b65d 100644 --- a/server/config.c +++ b/server/config.c @@ -418,7 +418,7 @@ AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r) } if (!r->handler) { - if (r->content_type) { + if (r->content_type && AP_REQUEST_IS_TRUSTED_CT(r)) { handler = r->content_type; if ((p=ap_strchr_c(handler, ';')) != NULL) { char *new_handler = (char *)apr_pmemdup(r->pool, handler, diff --git a/server/core.c b/server/core.c index e5e059e..843b973 100644 --- a/server/core.c +++ b/server/core.c @@ -4426,6 +4426,25 @@ static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg) return NULL; } +#ifdef WIN32 +static const char *set_unc_list(cmd_parms *cmd, void *d_, int argc, char *const argv[]) +{ + core_server_config *sconf = ap_get_core_module_config(cmd->server->module_config); + int i; + const char *err; + + if ((err = ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST)) != NULL) + return err; + + sconf->unc_list = apr_array_make(cmd->pool, argc, sizeof(char *)); + + for (i = 0; i < argc; i++) { + *(char **)apr_array_push(sconf->unc_list) = apr_pstrdup(cmd->pool, argv[i]); + } + + return NULL; +} +#endif /* Note --- ErrorDocument will now work from .htaccess files. * The AllowOverride of Fileinfo allows webmasters to turn it off */ @@ -4527,6 +4546,10 @@ AP_INIT_TAKE1("FlushMaxThreshold", set_flush_max_threshold, NULL, RSRC_CONF, AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF, "Maximum number of pipelined responses (pending) above which they are " "flushed to the network"), +#ifdef WIN32 +AP_INIT_TAKE_ARGV("UNCList", set_unc_list, NULL, RSRC_CONF, + "Controls what UNC hosts may be looked up"), +#endif /* Old server config file commands */ @@ -4812,7 +4835,7 @@ static int core_override_type(request_rec *r) /* Check for overrides with ForceType / SetHandler */ if (conf->mime_type && strcmp(conf->mime_type, "none")) - ap_set_content_type(r, (char*) conf->mime_type); + ap_set_content_type_ex(r, (char*) conf->mime_type, 1); if (conf->expr_handler) { const char *err; @@ -5632,6 +5655,84 @@ AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c, return ap_run_get_pollfd_from_conn(c, pfd, ptimeout); } +#ifdef WIN32 +static apr_status_t check_unc(const char *path, apr_pool_t *p) +{ + int i; + char *s, *teststring; + apr_status_t rv = APR_EACCES; + core_server_config *sconf = NULL; + + if (!ap_server_conf) { + return APR_SUCCESS; /* this early, if we have a UNC, it's specified by an admin */ + } + + if (!path || (path != ap_strstr_c(path, "\\\\") && + path != ap_strstr_c(path, "//"))) { + return APR_SUCCESS; /* not a UNC */ + } + + sconf = ap_get_core_module_config(ap_server_conf->module_config); + s = teststring = apr_pstrdup(p, path); + *s++ = '/'; + *s++ = '/'; + + ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, + "ap_filepath_merge: check converted path %s allowed %d", + teststring, + sconf->unc_list ? sconf->unc_list->nelts : 0); + + for (i = 0; sconf->unc_list && i < sconf->unc_list->nelts; i++) { + char *configured_unc = ((char **)sconf->unc_list->elts)[i]; + apr_uri_t uri; + if (APR_SUCCESS == apr_uri_parse(p, teststring, &uri) && + (uri.hostinfo == NULL || + !ap_cstr_casecmp(uri.hostinfo, configured_unc))) { + rv = APR_SUCCESS; + ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, + "ap_filepath_merge: match %s %s", + uri.hostinfo, configured_unc); + break; + } + else { + ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf, + "ap_filepath_merge: no match %s %s", uri.hostinfo, + configured_unc); + } + } + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(10504) + "ap_filepath_merge: UNC path %s not allowed by UNCList", teststring); + } + + return rv; +} +#endif + +AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath, + const char *rootpath, + const char *addpath, + apr_int32_t flags, + apr_pool_t *p) +{ +#ifdef WIN32 + apr_status_t rv; + + if (APR_SUCCESS != (rv = check_unc(rootpath, p))) { + return rv; + } + if (APR_SUCCESS != (rv = check_unc(addpath, p))) { + return rv; + } +#undef apr_filepath_merge +#endif + return apr_filepath_merge(newpath, rootpath, addpath, flags, p); +#ifdef WIN32 +#define apr_filepath_merge ap_filepath_merge +#endif +} + + static void register_hooks(apr_pool_t *p) { errorlog_hash = apr_hash_make(p); diff --git a/server/listen.c b/server/listen.c index 5242c2a..9577d60 100644 --- a/server/listen.c +++ b/server/listen.c @@ -19,6 +19,7 @@ #define APR_WANT_STRFUNC #include "apr_want.h" +#include "apr_version.h" #include "ap_config.h" #include "httpd.h" @@ -277,8 +278,32 @@ static apr_status_t close_listeners_on_exec(void *v) return APR_SUCCESS; } +/* Returns non-zero if socket address SA matches hostname, port and + * scope_id. p is used for temporary allocations. */ +static int match_address(const apr_sockaddr_t *sa, + const char *hostname, apr_port_t port, + const char *scope_id, apr_pool_t *p) +{ + const char *old_scope = NULL; + +#if APR_VERSION_AT_LEAST(1,7,0) + /* To be clever here we could correctly match numeric and + * non-numeric zone ids. Ignore failure, old_scope will be left + * as NULL. */ + (void) apr_sockaddr_zone_get(sa, &old_scope, NULL, p); +#endif + + return port == sa->port + && ((!hostname && !sa->hostname) + || (hostname && sa->hostname && !strcmp(sa->hostname, hostname))) + && ((!scope_id && !old_scope) + || (scope_id && old_scope && !strcmp(scope_id, old_scope))); +} + +/* ### This logic doesn't cope with DNS changes across a restart. */ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, - const char *addr, apr_port_t port) + const char *addr, apr_port_t port, + const char *scope_id, apr_pool_t *temp_pool) { int found = 0; @@ -288,15 +313,10 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, /* Some listeners are not real so they will not have a bind_addr. */ if (sa) { ap_listen_rec *new; - apr_port_t oldport; - oldport = sa->port; - /* If both ports are equivalent, then if their names are equivalent, - * then we will re-use the existing record. - */ - if (port == oldport && - ((!addr && !sa->hostname) || - ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { + /* Re-use the existing record if it matches completely + * against an existing listener. */ + if (match_address(sa, addr, port, scope_id, temp_pool)) { found = 1; if (!to) { break; @@ -317,19 +337,21 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, static const char *alloc_listener(process_rec *process, const char *addr, apr_port_t port, const char* proto, - void *slave) + const char *scope_id, void *slave, + apr_pool_t *temp_pool) { ap_listen_rec *last; apr_status_t status; apr_sockaddr_t *sa; /* see if we've got a listener for this address:port, which is an error */ - if (find_listeners(&ap_listeners, NULL, addr, port)) { + if (find_listeners(&ap_listeners, NULL, addr, port, scope_id, temp_pool)) { return "Cannot define multiple Listeners on the same IP:port"; } /* see if we've got an old listener for this address:port */ - if (find_listeners(&old_listeners, &ap_listeners, addr, port)) { + if (find_listeners(&old_listeners, &ap_listeners, addr, port, + scope_id, temp_pool)) { if (ap_listeners->slave != slave) { return "Cannot define a slave on the same IP:port as a Listener"; } @@ -383,6 +405,18 @@ static const char *alloc_listener(process_rec *process, const char *addr, return "Listen setup failed"; } +#if APR_VERSION_AT_LEAST(1,7,0) + if (scope_id) { + status = apr_sockaddr_zone_set(new->bind_addr, scope_id); + if (status) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, APLOGNO(10102) + "alloc_listener: failed to set scope for %pI to %s", + new->bind_addr, scope_id); + return "Listen step failed"; + } + } +#endif + /* We need to preserve the order returned by getaddrinfo() */ if (last == NULL) { ap_listeners = last = new; @@ -835,10 +869,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, host = NULL; } +#if !APR_VERSION_AT_LEAST(1,7,0) if (scope_id) { - /* XXX scope id support is useful with link-local IPv6 addresses */ - return "Scope id is not supported"; + return apr_pstrcat(cmd->pool, + "Scope ID in address '", argv[0], + "' not supported with APR " APR_VERSION_STRING, + NULL); } +#endif if (!port) { return "Port must be specified"; @@ -856,7 +894,8 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, ap_str_tolower(proto); } - return alloc_listener(cmd->server->process, host, port, proto, NULL); + return alloc_listener(cmd->server->process, host, port, proto, + scope_id, NULL, cmd->temp_pool); } AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, diff --git a/server/log.c b/server/log.c index 22d2f8d..9576d07 100644 --- a/server/log.c +++ b/server/log.c @@ -64,6 +64,10 @@ #undef APLOG_MODULE_INDEX #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX +#ifndef DEFAULT_LOG_TID +#define DEFAULT_LOG_TID NULL +#endif + typedef struct { const char *t_name; int t_val; @@ -990,7 +994,7 @@ static int do_errorlog_default(const ap_errorlog_info *info, char *buf, #if APR_HAS_THREADS field_start = len; len += cpystrn(buf + len, ":tid ", buflen - len); - item_len = log_tid(info, NULL, buf + len, buflen - len); + item_len = log_tid(info, DEFAULT_LOG_TID, buf + len, buflen - len); if (!item_len) len = field_start; else diff --git a/server/util.c b/server/util.c index 45502b8..11d0e40 100644 --- a/server/util.c +++ b/server/util.c @@ -75,17 +75,6 @@ */ #include "test_char.h" -/* Win32/NetWare/OS2 need to check for both forward and back slashes - * in ap_normalize_path() and ap_escape_url(). - */ -#ifdef CASE_BLIND_FILESYSTEM -#define IS_SLASH(s) ((s == '/') || (s == '\\')) -#define SLASHES "/\\" -#else -#define IS_SLASH(s) (s == '/') -#define SLASHES "/" -#endif - /* we know core's module_index is 0 */ #undef APLOG_MODULE_INDEX #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX @@ -492,7 +481,7 @@ AP_DECLARE(apr_status_t) ap_pregsub_ex(apr_pool_t *p, char **result, /* Forward declare */ static char x2c(const char *what); -#define IS_SLASH_OR_NUL(s) (s == '\0' || IS_SLASH(s)) +#define IS_SLASH_OR_NUL(s) (s == '\0' || AP_IS_SLASH(s)) /* * Inspired by mod_jk's jk_servlet_normalize(). @@ -504,7 +493,7 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags) int decode_unreserved = (flags & AP_NORMALIZE_DECODE_UNRESERVED) != 0; int merge_slashes = (flags & AP_NORMALIZE_MERGE_SLASHES) != 0; - if (!IS_SLASH(path[0])) { + if (!AP_IS_SLASH(path[0])) { /* Besides "OPTIONS *", a request-target should start with '/' * per RFC 7230 section 5.3, so anything else is invalid. */ @@ -545,12 +534,12 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags) } } - if (w == 0 || IS_SLASH(path[w - 1])) { + if (w == 0 || AP_IS_SLASH(path[w - 1])) { /* Collapse ///// sequences to / */ - if (merge_slashes && IS_SLASH(path[l])) { + if (merge_slashes && AP_IS_SLASH(path[l])) { do { l++; - } while (IS_SLASH(path[l])); + } while (AP_IS_SLASH(path[l])); continue; } @@ -579,7 +568,7 @@ AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags) if (w > 1) { do { w--; - } while (w && !IS_SLASH(path[w - 1])); + } while (w && !AP_IS_SLASH(path[w - 1])); } else { /* Already at root, ignore and return a failure @@ -1915,7 +1904,7 @@ static int unescape_url(char *url, const char *forbid, const char *reserved, char decoded; decoded = x2c(y + 1); if ((decoded == '\0') - || (forbid_slashes && IS_SLASH(decoded)) + || (forbid_slashes && AP_IS_SLASH(decoded)) || (forbid && ap_strchr_c(forbid, decoded))) { badpath = 1; *x = decoded; @@ -1923,7 +1912,7 @@ static int unescape_url(char *url, const char *forbid, const char *reserved, } else if ((keep_unreserved && TEST_CHAR(decoded, T_URI_UNRESERVED)) - || (keep_slashes && IS_SLASH(decoded)) + || (keep_slashes && AP_IS_SLASH(decoded)) || (reserved && ap_strchr_c(reserved, decoded))) { *x++ = *y++; *x++ = *y++; @@ -1950,7 +1939,7 @@ static int unescape_url(char *url, const char *forbid, const char *reserved, AP_DECLARE(int) ap_unescape_url(char *url) { /* Traditional */ - return unescape_url(url, SLASHES, NULL, 0); + return unescape_url(url, AP_SLASHES, NULL, 0); } AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes) { @@ -1960,7 +1949,7 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes) return unescape_url(url, NULL, NULL, 0); } else { /* reserve (do not decode) encoded slashes */ - return unescape_url(url, NULL, SLASHES, 0); + return unescape_url(url, NULL, AP_SLASHES, 0); } } AP_DECLARE(int) ap_unescape_url_ex(char *url, unsigned int flags) diff --git a/server/vhost.c b/server/vhost.c index 489c141..ee93481 100644 --- a/server/vhost.c +++ b/server/vhost.c @@ -23,6 +23,7 @@ #include "apr.h" #include "apr_strings.h" #include "apr_lib.h" +#include "apr_version.h" #define APR_WANT_STRFUNC #include "apr_want.h" @@ -182,9 +183,14 @@ static const char *get_addresses(apr_pool_t *p, const char *w_, if (!host) { return "Missing address for VirtualHost"; } +#if !APR_VERSION_AT_LEAST(1,7,0) if (scope_id) { - return "Scope ids are not supported"; + return apr_pstrcat(p, + "Scope ID in address '", w, + "' not supported with APR " APR_VERSION_STRING, + NULL); } +#endif if (!port && !wild_port) { port = default_port; } @@ -203,6 +209,17 @@ static const char *get_addresses(apr_pool_t *p, const char *w_, "Could not resolve host name %s -- ignoring!", host); return NULL; } +#if APR_VERSION_AT_LEAST(1,7,0) + if (scope_id) { + rv = apr_sockaddr_zone_set(my_addr, scope_id); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(10103) + "Could not set scope ID %s for %pI -- ignoring!", + scope_id, my_addr); + return NULL; + } + } +#endif } /* Remember all addresses for the host */ diff --git a/test/modules/http2/test_009_timing.py b/test/modules/http2/test_009_timing.py index 2c62bb0..2784f9a 100644 --- a/test/modules/http2/test_009_timing.py +++ b/test/modules/http2/test_009_timing.py @@ -7,6 +7,7 @@ from .env import H2Conf, H2TestEnv @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here") +@pytest.mark.skipif(not H2TestEnv().h2load_is_at_least('1.41.0'), reason="h2load misses --connect-to option") class TestTiming: LOGFILE = "" diff --git a/test/modules/http2/test_800_websockets.py b/test/modules/http2/test_800_websockets.py index 5b46da8..52af1a3 100644 --- a/test/modules/http2/test_800_websockets.py +++ b/test/modules/http2/test_800_websockets.py @@ -168,14 +168,14 @@ class TestWebSockets: def test_h2_800_03_not_found(self, env: H2TestEnv, ws_server): r, infos, frames = ws_run(env, path='/does-not-exist') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 404', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 404', '[1] EOF'] or infos == ['[1] :status: 404', '[1] EOF', '[1] RST'], f'{r}' # CONNECT to a URL path that is a normal HTTP file resource # we do not want to receive the body of that def test_h2_800_04_non_ws_resource(self, env: H2TestEnv, ws_server): r, infos, frames = ws_run(env, path='/alive.json') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 502', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 502', '[1] EOF'] or infos == ['[1] :status: 502', '[1] EOF', '[1] RST'], f'{r}' assert frames == b'' # CONNECT to a URL path that sends a delayed HTTP response body @@ -183,7 +183,7 @@ class TestWebSockets: def test_h2_800_05_non_ws_delay_resource(self, env: H2TestEnv, ws_server): r, infos, frames = ws_run(env, path='/h2test/error?body_delay=100ms') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 502', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 502', '[1] EOF'] or infos == ['[1] :status: 502', '[1] EOF', '[1] RST'], f'{r}' assert frames == b'' # CONNECT missing the sec-webSocket-version header @@ -215,7 +215,7 @@ class TestWebSockets: r, infos, frames = ws_run(env, path='/ws/echo/', authority=f'test1.{env.http_tld}:{env.http_port}') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 501', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 501', '[1] EOF'] or infos == ['[1] :status: 501', '[1] EOF', '[1] RST'], f'{r}' # CONNECT and exchange a PING def test_h2_800_10_ws_ping(self, env: H2TestEnv, ws_server): diff --git a/test/modules/md/dns01_v2.py b/test/modules/md/dns01_v2.py new file mode 100755 index 0000000..908b4f8 --- /dev/null +++ b/test/modules/md/dns01_v2.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +import subprocess +import sys + +curl = "curl" +challtestsrv = "localhost:8055" + + +def run(args): + sys.stderr.write(f"run: {' '.join(args)}\n") + p = subprocess.Popen(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output, errput = p.communicate(None) + rv = p.wait() + if rv != 0: + sys.stderr.write(errput.decode()) + sys.stdout.write(output.decode()) + return rv + + +def teardown(domain): + rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}"}}', + f'{challtestsrv}/clear-txt']) + if rv == 0: + rv = run([curl, '-s', '-d', f'{{"host":"{domain}"}}', + f'{challtestsrv}/set-txt']) + return rv + + +def setup(domain, challenge): + teardown(domain) + rv = run([curl, '-s', '-d', f'{{"host":"{domain}", "addresses":["127.0.0.1"]}}', + f'{challtestsrv}/set-txt']) + if rv == 0: + rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}.", "value":"{challenge}"}}', + f'{challtestsrv}/set-txt']) + return rv + + +def main(argv): + if len(argv) > 1: + if argv[1] == 'setup': + if len(argv) != 4: + sys.stderr.write("wrong number of arguments: dns01.py setup <domain> <challenge>\n") + sys.exit(2) + rv = setup(argv[2], argv[3]) + elif argv[1] == 'teardown': + if len(argv) != 4: + sys.stderr.write("wrong number of arguments: dns01.py teardown <domain> <challenge>\n") + sys.exit(1) + rv = teardown(argv[2]) + else: + sys.stderr.write(f"unknown option {argv[1]}\n") + rv = 2 + else: + sys.stderr.write("dns01.py wrong number of arguments\n") + rv = 2 + sys.exit(rv) + + +if __name__ == "__main__": + main(sys.argv) diff --git a/test/modules/md/md_cert_util.py b/test/modules/md/md_cert_util.py index 8cd99aa..abcd36b 100755 --- a/test/modules/md/md_cert_util.py +++ b/test/modules/md/md_cert_util.py @@ -166,10 +166,10 @@ class MDCertUtil(object): def get_san_list(self): text = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_TEXT, self.cert).decode("utf-8") - m = re.search(r"X509v3 Subject Alternative Name:\s*(.*)", text) + m = re.search(r"X509v3 Subject Alternative Name:(\s+critical)?\s*(.*)", text) sans_list = [] if m: - sans_list = m.group(1).split(",") + sans_list = m.group(2).split(",") def _strip_prefix(s): return s.split(":")[1] if s.strip().startswith("DNS:") else s.strip() diff --git a/test/modules/md/md_env.py b/test/modules/md/md_env.py index e8e36e5..1936519 100755 --- a/test/modules/md/md_env.py +++ b/test/modules/md/md_env.py @@ -73,7 +73,11 @@ class MDTestEnv(HttpdTestEnv): @classmethod def has_acme_eab(cls): - return cls.get_acme_server() == 'pebble' + return False + # Pebble, since v2.5.0 no longer supports HS256 for EAB, which + # is the only thing mod_md supports. Issue opened at pebble: + # https://github.com/letsencrypt/pebble/issues/455 + # return cls.get_acme_server() == 'pebble' @classmethod def is_pebble(cls) -> bool: @@ -356,13 +360,14 @@ class MDTestEnv(HttpdTestEnv): MDCertUtil.validate_privkey(self.store_domain_file(domain, 'privkey.pem')) cert = MDCertUtil(self.store_domain_file(domain, 'pubcert.pem')) cert.validate_cert_matches_priv_key(self.store_domain_file(domain, 'privkey.pem')) - # check SANs and CN - assert cert.get_cn() == domain + # No longer check CN, it may not be set or is not trusted anyway + # assert cert.get_cn() == domain, f'CN: expected "{domain}", got {cert.get_cn()}' + # check SANs # compare lists twice in opposite directions: SAN may not respect ordering san_list = list(cert.get_san_list()) assert len(san_list) == len(domains) - assert set(san_list).issubset(domains) - assert set(domains).issubset(san_list) + assert set(san_list).issubset(domains), f'{san_list} not subset of {domains}' + assert set(domains).issubset(san_list), f'{domains} not subset of {san_list}' # check valid dates interval not_before = cert.get_not_before() not_after = cert.get_not_after() diff --git a/test/modules/tls/test_08_vars.py b/test/modules/tls/test_08_vars.py index f1bd9b4..a8df99a 100644 --- a/test/modules/tls/test_08_vars.py +++ b/test/modules/tls/test_08_vars.py @@ -51,7 +51,7 @@ class TestVars: @pytest.mark.parametrize("name, pattern", [ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'), - ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'), + ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'), ]) def test_tls_08_vars_match(self, env, name: str, pattern: str): r = env.tls_get(env.domain_b, f"/vars.py?name={name}") diff --git a/test/modules/tls/test_14_proxy_ssl.py b/test/modules/tls/test_14_proxy_ssl.py index 79b2fb4..cefcbf6 100644 --- a/test/modules/tls/test_14_proxy_ssl.py +++ b/test/modules/tls/test_14_proxy_ssl.py @@ -69,7 +69,7 @@ class TestProxySSL: @pytest.mark.parametrize("name, pattern", [ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'), - ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'), + ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'), ]) def test_tls_14_proxy_ssl_vars_match(self, env, name: str, pattern: str): r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}") diff --git a/test/pyhttpd/curl.py b/test/pyhttpd/curl.py index 5a215cd..3d7993f 100644 --- a/test/pyhttpd/curl.py +++ b/test/pyhttpd/curl.py @@ -112,7 +112,7 @@ class CurlPiper: recv_times = [] for line in "".join(recv_err).split('\n'): m = re.match(r'^\s*(\d+:\d+:\d+(\.\d+)?) <= Recv data, (\d+) bytes.*', line) - if m: + if m and int(m.group(3)) > 0: recv_times.append(datetime.time.fromisoformat(m.group(1))) # received as many chunks as we sent assert len(chunks) == len(recv_times), "received response not in {0} chunks, but {1}".format( diff --git a/test/pyhttpd/nghttp.py b/test/pyhttpd/nghttp.py index 43721f5..e857e95 100644 --- a/test/pyhttpd/nghttp.py +++ b/test/pyhttpd/nghttp.py @@ -224,7 +224,7 @@ class Nghttp: if 0 == r.exit_code: lines = re.findall(r'[^\n]*\n', r.stdout, re.MULTILINE) for lidx, l in enumerate(lines): - m = re.match(r'\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+/(.*)', l) + m = re.match(r'\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+/*(/.*)', l) if m: assets.append({ "path": m.group(7), diff --git a/test/travis_Dockerfile_slapd.centos b/test/travis_Dockerfile_slapd.centos new file mode 100644 index 0000000..713e5de --- /dev/null +++ b/test/travis_Dockerfile_slapd.centos @@ -0,0 +1,5 @@ +FROM quay.io/centos/centos:stream9 +RUN dnf install -y epel-release && \ + dnf install -y openldap openldap-clients openldap-servers openldap-devel && \ + dnf -y clean all --enablerepo='*' +CMD /usr/sbin/slapd -u ldap -d1 '-h ldap:// ldapi:///' diff --git a/test/travis_Dockerfile_slapd.centos7 b/test/travis_Dockerfile_slapd.centos7 deleted file mode 100644 index 85bcf0a..0000000 --- a/test/travis_Dockerfile_slapd.centos7 +++ /dev/null @@ -1,5 +0,0 @@ -FROM quay.io/centos/centos:7 -RUN yum install -y yum-utils && \ - yum install -y openldap openldap-clients openldap-servers openldap-devel && \ - yum -y clean all --enablerepo='*' -CMD /usr/sbin/slapd -u ldap -d1 '-h ldap:// ldapi:///' diff --git a/test/travis_before_linux.sh b/test/travis_before_linux.sh index 2722c6a..59aea2f 100755 --- a/test/travis_before_linux.sh +++ b/test/travis_before_linux.sh @@ -21,42 +21,13 @@ if grep ip6-localhost /etc/hosts; then cat /etc/hosts fi -# Use a rudimental retry workflow as workaround to svn export hanging for minutes. -# Travis automatically kills a build if one step takes more than 10 minutes without -# reporting any progress. -function run_svn_export() { - local url=$1 - local revision=$2 - local dest_dir=$3 - local max_tries=$4 - - # Disable -e to allow fail/retry - set +e - - for i in $(seq 1 $max_tries) - do - timeout 60 svn export -r ${revision} --force -q $url $dest_dir - if [ $? -eq 0 ]; then - break - else - if [ $i -eq $max_tries ]; then - exit 1 - else - sleep $((100 * i)) - fi - fi - done - - # Restore -e behavior after fail/retry - set -e -} - function install_apx() { local name=$1 local version=$2 local root=https://svn.apache.org/repos/asf/apr/${name} local prefix=${HOME}/root/${name}-${version} local build=${HOME}/build/${name}-${version} + local giturl=https://github.com/apache/${name}.git local config=$3 local buildconf=$4 @@ -76,7 +47,7 @@ function install_apx() { return 0 fi - svn export -q -r ${revision} ${url} ${build} + git clone -q --depth=1 --branch=$version ${giturl} ${build} pushd $build ./buildconf ${buildconf} ./configure --prefix=${prefix} ${config} @@ -113,13 +84,13 @@ if ! test -v SKIP_TESTING -o -v NO_TEST_FRAMEWORK; then unset pkgs # Make a shallow clone of httpd-tests git repo. - git clone --depth=1 https://github.com/apache/httpd-tests.git test/perl-framework + git clone -q --depth=1 https://github.com/apache/httpd-tests.git test/perl-framework fi # For LDAP testing, run slapd listening on port 8389 and populate the # directory as described in t/modules/ldap.t in the test framework: if test -v TEST_LDAP -a -x test/perl-framework/scripts/ldap-init.sh; then - docker build -t httpd_ldap -f test/travis_Dockerfile_slapd.centos7 test/ + docker build -t httpd_ldap -f test/travis_Dockerfile_slapd.centos test/ pushd test/perl-framework ./scripts/ldap-init.sh popd |