diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index f7473fb4f21..68c34e97460 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -7,6 +7,7 @@ on: - 'docs/**' - STATUS - CHANGES + - README* - '**.md' - changes-entries/* tags: @@ -17,9 +18,13 @@ on: - 'docs/**' - STATUS - CHANGES + - README* - '**.md' - changes-entries/* +permissions: + contents: read + env: MARGS: "-j2" CFLAGS: "-g" @@ -285,7 +290,7 @@ jobs: - name: OpenSSL 3.0 LTS config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto env: | - TEST_OPENSSL3=3.0.18 + TEST_OPENSSL3=3.0.21 APR_VERSION=1.7.6 APU_VERSION=1.6.3 APU_CONFIG="--without-crypto" @@ -295,7 +300,7 @@ jobs: config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto notest-cflags: -Werror -O2 env: | - TEST_OPENSSL3=3.4.4 + TEST_OPENSSL3=3.4.6 APR_VERSION=1.7.6 APU_VERSION=1.6.3 APU_CONFIG="--without-crypto" @@ -304,7 +309,7 @@ jobs: - name: OpenSSL 3.4 no-engine config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto env: | - TEST_OPENSSL3=3.4.4 + TEST_OPENSSL3=3.4.6 OPENSSL_CONFIG=no-engine APR_VERSION=1.7.6 APU_VERSION=1.6.3 @@ -315,7 +320,7 @@ jobs: config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto notest-cflags: -Werror -O2 env: | - TEST_OPENSSL3=3.5.5 + TEST_OPENSSL3=3.5.7 OPENSSL_CONFIG=no-engine APR_VERSION=1.7.6 APU_VERSION=1.6.3 @@ -326,7 +331,7 @@ jobs: config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto notest-cflags: -Werror -O2 env: | - TEST_OPENSSL3=4.0.0 + TEST_OPENSSL3=4.0.1 OPENSSL_CONFIG= APR_VERSION=1.7.6 APU_VERSION=1.6.3 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 5cf01fafe99..7ca926c4dac 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -7,6 +7,8 @@ on: - 'docs/**' - STATUS - CHANGES + - README* + - '**.md' - changes-entries/* tags: - 2.* @@ -16,8 +18,13 @@ on: - 'docs/**' - STATUS - CHANGES + - README* + - '**.md' - changes-entries/* +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 46811e0d87d..985f9dac11a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -521,7 +521,7 @@ SET(mod_md_extra_sources modules/md/md_ocsp.c modules/md/md_util.c modules/md/mod_md_config.c modules/md/mod_md_drive.c modules/md/mod_md_os.c modules/md/mod_md_status.c - modules/md/mod_md_ocsp.c modules/md/md_tailscale.c + modules/md/mod_md_ocsp.c ) SET(mod_optional_hook_export_extra_defines AP_DECLARE_EXPORT) # bogus reuse of core API prefix SET(mod_proxy_extra_defines PROXY_DECLARE_EXPORT) diff --git a/README b/README index 8307fc32d79..6db0c1fc408 100644 --- a/README +++ b/README @@ -3,10 +3,10 @@ ## What is it? -The Apache HTTP Server is a powerful and flexible HTTP/1.1 compliant +The Apache HTTP Server is a powerful, flexible, HTTP/1.1 and HTTP/2 compliant, and widely deployed web server. Originally designed as a replacement for the NCSA HTTP -Server, it has grown to be the most popular web server on the -Internet. As a project of the Apache Software Foundation, the +Server, it has been in continuous development since 1995 and remains +one of the foundational projects of the Apache Software Foundation. The developers aim to collaboratively develop and maintain a robust, commercial-grade, standards-based server with freely available source code. @@ -89,7 +89,7 @@ therefore not subject to this notice. * If you want to be informed about new code releases, bug fixes, security fixes, general news and information about the Apache server - subscribe to the apache-announce mailing list as described under + subscribe to the announce@httpd.apache.org mailing list as described under [https://httpd.apache.org/lists.html#http-announce](https://httpd.apache.org/lists.html#http-announce) * If you want freely available support for running Apache please see the diff --git a/README.CHANGES b/README.CHANGES index 26f8c26197a..bb6de8747a4 100644 --- a/README.CHANGES +++ b/README.CHANGES @@ -1,19 +1,54 @@ -Changes can be documented in two ways now: Either by directly editing the -CHANGES file like it was done until now or by storing each entry for the -CHANGES file correctly formated in a separate file in the changes-entries + +# Documenting User-Visible Changes + +User-visible changes can be documented in two ways: either by directly +editing the CHANGES file, or by storing each entry for the CHANGES +file correctly formatted in a separate file in the changes-entries directory. -The benefit of the single file per change approach is that it eases backporting -the CHANGES entry to a stable branch as it avoids the frequent merge conflicts -as changes are merged in different orders or not at all in the stable branch. +This covers any developer-visible changes such as a new module API, +but e.g. code cleanups which don't have any externally-visible effect +do not need to be documented in CHANGES. + +Changes should be documented by creating a file in changes-entries/ +with the .txt suffix, using the following template: + +``` + *) mod_foo: Fix bug in blah blah. + PR . [Name of Person
, + Other Person , ...] +``` + +Changes to server/*.[ch] use a "core:" prefix rather than "mod_foo:". + +The description should be as concise as possible, a maximum of three +lines but ideally one or two; describe the user-visible effect of the +change rather than simply describing how the code was fixed. New +modules or config directives do NOT need to be explained in detail, +that is covered in the documentation. + +The credit for the change goes to the original patch author(s) and +will usually match the "Submitted by: " tag in the commit message. For +current committers, use only the name and not the e-mail address in +the credit. Replace "@" in any e-mail addresses with a space to +prevent address harvesting. + +Use a Bugzilla bug number in the PR reference. + +# Generating CHANGES from changes-entries/*.txt + +The benefit of the single file per change approach is that it eases +backporting the CHANGES entry to a stable branch as it avoids the +frequent merge conflicts as changes are merged in different orders or +not at all in the stable branch. -In order to keep the current CHANGES file for the users as is there is a new +In order to keep the current CHANGES file for the users as-is, there is a new make target called 'update-changes'. It merges all change files in the changes-entries directory to the top of the CHANGES file and removes them afterwards. -This make target can be seen in a similar way as the scripts to update the -documentation files from its xml sources. It can be executed immediately -after the new file in the changes-entries directory has been created / merged -and committed or it can be executed later. It should be executed at least before -a release gets tagged. +This make target can be seen in a similar way as the scripts to update +the documentation files from the XML sources. It can be executed +immediately after the new file in the changes-entries directory has +been created / merged and committed or it can be executed later. It +should be executed at least before a release gets tagged. diff --git a/SECURITY.md b/SECURITY.md index 90b59c83dbd..78266af1128 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,9 +8,9 @@ demonstrate how an attacker can violate the security model. ## Supported Versions Currently the only supported version is the latest patch release of the -`2.4.x` stable branch. Vulnerabilities which exist *only* in -unreleased branches (such as `trunk`) may be treated as normal bug -reports. +`2.4.x` stable branch. Vulnerabilities which exist *only* in +unreleased branches (such as `trunk`) should be reported as normal bug +reports via . ## Reporting Vulnerabilities @@ -26,7 +26,7 @@ Vulnerabilities](http://httpd.apache.org/security/vulnerabilities_24.html) If an issue is reported against an aspect of the security model which is not documented here, it MUST be accompanied by a clear description -of that aspect the model, showing why a trust boundary exists and how +of that aspect of the model, showing why a trust boundary exists and how it is violated. It is helpful to use references to vulnerabilities previously disclosed by this project, the httpd documentation (see docs/manual), and to demonstrate common usage patterns. @@ -36,18 +36,25 @@ Any security vulnerability SHOULD be reproducible: 1. under a reasonable, supported configuration. 2. without using third-party modules, or modules explicitly designed for debugging. -3. under a standard build on a supported platform. +3. using the *latest* released sources published via . +4. under a standard build, on a supported platform. Issues which are reproducible only using instrumented builds (such as ASAN, or under valgrind) should be clearly explained as such. +Issues which depend on a specially crafted server configuration MUST +include references (such as public documentation) which show why that +is a configuration that would arise naturally in common deployments. +Special considerations also apply to any issues requiring `.htaccess` +files, per the [Delegated Configuration](#delegated-configuration) section. + ## Basic model Processing of requests by remote untrusted users (HTTP clients) MUST NOT crash or prematurely terminate server processes, nor gain code execution privileges. In the default configuration, timeouts are applied to most aspects of HTTP request handling such that a single -client SHOULD NOT tie up a single processing thread or process +idle client connection SHOULD NOT tie up a single processing thread or process indefinitely. It is the responsibility of the server administrator to tune and @@ -74,7 +81,7 @@ configurable limits; e.g. LimitRequestFields limits the RAM consumption by HTTP headers, LimitXMLRequestBody limits the RAM consumption by parsing XML request documents. -Example vulnerabilities which violated the model: CVE-2004-0942 +Example vulnerabilities which violated the model: CVE-2004-0942. ## Privilege separation on Unix platforms @@ -100,18 +107,31 @@ model. Example vulnerabilities which violated the model: CVE-2007-3304, CVE-2012-0031. -## Delegated Configuration +## Delegated Configuration Server configuration can be delegated to trusted local site authors by -allowing use of .htaccess files in non-default configurations. Local -site authors are trusted to not attack the server with malformed or -malicious .htaccess files (for example, files of excessive size). +allowing use of .htaccess files in some configurations (see +https://httpd.apache.org/docs/2.4/howto/htaccess.html). Site authors +gain a significant degree of control over, and access to, the server +at run-time: -In configurations supporting in-process scripting language interpreters -which are not sandboxed, such as `mod_lua` or `mod_php`, local site -authors have equivalent privileges to the less-privileged server user. +* site authors are trusted to not attack the server with malformed or + malicious .htaccess files + +* site authors gain access to some data (such as files or the + environment) which is otherwise restricted. -(### TODO something about AllowOverride) +Examples of malicious `.htaccess` files include, but are not limited +to: + +* configuration files of excessive size +* configurations using deliberately constructed regular expressions + which are expensive to evaluate + +In configurations supporting in-process scripting language interpreters +which are not sandboxed, such as `mod_lua` or `mod_php`, +site authors have exactly equivalent privileges to the user which the +server runs as. ## Dependent Services diff --git a/STATUS b/STATUS index d6422b01b78..9eea5a3a8f9 100644 --- a/STATUS +++ b/STATUS @@ -104,8 +104,9 @@ THINGS THAT SHOULD BE CONSIDERED EARLY IN THE 2.6/3.0 DEVELOPMENT CYCLE: * Candidates to remove: - mod_access_compat - mod_imagemap + - mod_cern_meta - mod_privileges - - mod_dav_lock + - mod_noloris - mod_ssl_ct - OS/2 support - Netware support diff --git a/changes-entries/cern-meta-header-injection.txt b/changes-entries/cern-meta-header-injection.txt new file mode 100644 index 00000000000..2aef1eec926 --- /dev/null +++ b/changes-entries/cern-meta-header-injection.txt @@ -0,0 +1,2 @@ + *) mod_cern_meta: Reject HTTP framing headers in metadata files to prevent + response splitting. [Joe Orton] diff --git a/changes-entries/ldap-url-cache-uaf.txt b/changes-entries/ldap-url-cache-uaf.txt new file mode 100644 index 00000000000..669b188c25d --- /dev/null +++ b/changes-entries/ldap-url-cache-uaf.txt @@ -0,0 +1,2 @@ + *) mod_ldap: Fix intermittent worker crashes under concurrent + LDAP-authenticated requests. [Joe Orton] diff --git a/changes-entries/md-status.txt b/changes-entries/md-status.txt new file mode 100644 index 00000000000..cf6d627658c --- /dev/null +++ b/changes-entries/md-status.txt @@ -0,0 +1,3 @@ + *) mod_md: MDServerStatus is now disabled by default. [Joe Orton] + + diff --git a/changes-entries/mod_ssl-openssl-compat.txt b/changes-entries/mod_ssl-openssl-compat.txt new file mode 100644 index 00000000000..9281eb03bd8 --- /dev/null +++ b/changes-entries/mod_ssl-openssl-compat.txt @@ -0,0 +1,2 @@ + *) mod_ssl: Fix compatibility with OpenSSL < 1.1. + [Craig Lorentzen ] diff --git a/changes-entries/pr68527.txt b/changes-entries/pr68527.txt new file mode 100644 index 00000000000..2a0cd27d126 --- /dev/null +++ b/changes-entries/pr68527.txt @@ -0,0 +1,2 @@ + *) mod_dir: Fix a crash in fixup_dir for a request not mapped to any type. + PR68527. [Eric Covener] diff --git a/changes-entries/remoteip-proxy-v2-local.txt b/changes-entries/remoteip-proxy-v2-local.txt new file mode 100644 index 00000000000..c2b240b7e3c --- /dev/null +++ b/changes-entries/remoteip-proxy-v2-local.txt @@ -0,0 +1,2 @@ + *) mod_remoteip: Fix crash with PROXY v2 LOCAL command and + RemoteIPProxyProtocol enabled. [Joe Orton] diff --git a/changes-entries/substitute-maxlinelength-overflow.txt b/changes-entries/substitute-maxlinelength-overflow.txt new file mode 100644 index 00000000000..7ad53978121 --- /dev/null +++ b/changes-entries/substitute-maxlinelength-overflow.txt @@ -0,0 +1,2 @@ + *) mod_substitute: Fix SubstituteMaxLineLength to reject values too + large for the K/M/G suffix. [Joe Orton] diff --git a/changes-entries/substitute-pattern-oob-read.txt b/changes-entries/substitute-pattern-oob-read.txt new file mode 100644 index 00000000000..55eea6f041b --- /dev/null +++ b/changes-entries/substitute-pattern-oob-read.txt @@ -0,0 +1,2 @@ + *) mod_substitute: Fix crash or misbehaviour when loading a Substitute + directive with a missing closing delimiter. [Joe Orton] diff --git a/configure.in b/configure.in index 3f51b79dc35..124cdb58c39 100644 --- a/configure.in +++ b/configure.in @@ -406,7 +406,7 @@ dnl ### need to move some of the arguments "up here" dnl ## Check for programs AC_PATH_PROG(RM, rm) -AC_PATH_PROG(PKGCONFIG, pkg-config) +AC_PATH_TOOL(PKGCONFIG, pkg-config) AC_PATH_PROG(RSYNC, rsync) AC_PATH_PROG(SVN, svn) AC_PROG_AWK diff --git a/docs/STATUS b/docs/STATUS index 3b1f071a3bf..77b68dff807 100644 --- a/docs/STATUS +++ b/docs/STATUS @@ -9,14 +9,6 @@ http://httpd.apache.org/docs-project/docsformat.html To Do List ======================= -- Update the http://httpd.apache.org/docs-project/docsformat.html - document to be useful. In particular: - - Document the translation process. - - Generally update it to make it reflect the current reality of how - we work. - - Improving the documentation of the documentations' build system - itself (requirements, procedures) - - Continue to enhance the FAQ, which is in the wiki: http://wiki.apache.org/httpd/FAQ @@ -35,13 +27,6 @@ To Do List They both need review and updates to reflect the current state of the art. -- Windows platform docs are in desperate need of rewrites/updates for 2.x. - - Bill Rowe is a good contact for tech questions. - - "using apache" has been done, "compiling apache" is still open - - hints on uninstalling apache (exit monitor, close directories, - registry entries etc) (PR 10154) - - FAQ: UTF-8 config and URL encoding for non-ascii characters. - - New Auth system - Much clean-up and enhancement of aaa howto (Can someone clarify exactly what needs cleaned up and enhanced?) @@ -49,19 +34,8 @@ To Do List - Discussion of DBD auth, and, in particular, examples of how to set up auth using each of the supported databases. -- Expression syntax for , Require expr, SetEnvIfExpr, CustomLog, ... - Start is in expr.xml, igalic is working on this - -- modules docs - - the following modules added since 2.2 lack documentation - - mod_serf - - mpm_simple - the list may be incomplete - maybe some of the modules will not be included in 2.4 - - mod_suexec: very little documentation - - mod_substitute and reverse proxies: Add example using mod_filter - (see: http://marc.info/?l=apache-httpd-users&m=128830729603423&w=2) + (see: http://lists.apache.org/thread/kcdy8hyrqjpyy56bf63fzcgtl33kkblz) -Mod auth spanish doc add the following that a community member has created. https://github.com/valenbg1/auth-example-mod-apache @@ -161,9 +135,3 @@ https://github.com/valenbg1/auth-example-mod-apache of what's broken. For the moment, PDF docs are no longer referenced on the docs site. -- Add example of using -p flag to rotatelogs to do something useful. - -- Log rotation doc - http://httpd.apache.org/docs/2.4/logs.html#rotation - needs to mention rotatelogs as well as fairly standard log rotation - stuff, rather than encouraging people to do this by hand. - diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 4e6347722a5..f847eee1e1f 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -10589 +10599 diff --git a/docs/manual/AGENTS.md b/docs/manual/AGENTS.md index b8b6c0775a0..9e6e9d4f7ea 100644 --- a/docs/manual/AGENTS.md +++ b/docs/manual/AGENTS.md @@ -27,14 +27,33 @@ This is the documentation source for the [Apache HTTP Server](https://httpd.apac ## External Link Conventions +### `` — RFC References -Always link to the IETF Datatracker for RFC references: +Use the `` tag for all RFC references. The element content is the +RFC number (digits only). The rendered output is "RFC NNNN" linked to +the canonical URL. + +```xml +7230 +9110 +``` + +To link to a numbered section, use the `section` attribute: +```xml +2616 ``` -https://datatracker.ietf.org/doc/html/rfcNNNN + +To link to a named anchor (appendix, named heading, etc.), use `anchor`: +```xml +7231 +9110 ``` -For section-specific links, use fragment anchors: `#section-N.N` -Do NOT use `tools.ietf.org`, `www.rfc-editor.org`, `www.ietf.org/rfc/`, `www.w3.org/Protocols/`, `www.faqs.org/rfcs/`, or any other RFC mirror. These are legacy patterns — `datatracker.ietf.org` is the canonical standard for this documentation. +Do **not** use both `section` and `anchor` on the same element. + +Do **not** use `` with RFC URLs when the `` tag can +express the link. Use `` only for non-RFC resources, IETF drafts, or +cases where the display text must differ from "RFC NNNN". ## Directive Syntax Definitions diff --git a/docs/manual/env.html.en.utf8 b/docs/manual/env.html.en.utf8 index 122ad3ce1ed..49e21af060e 100644 --- a/docs/manual/env.html.en.utf8 +++ b/docs/manual/env.html.en.utf8 @@ -271,9 +271,11 @@

CGI environment variables

-

The CGI specification (RFC 3875) defines a number of environment - variables that expand on those defined by the HTTP spec. - These have been adopted more broadly, and are a standard +

The CGI specification (RFC 3875) defines a + number of meta-variables, many of which derive their values from + HTTP request headers. Apache httpd makes these available as + environment variables to CGI scripts and other request-processing + mechanisms. These have been adopted more broadly, and are a standard part of passing information between the browser and the server, and between processes on the server side. Here we discuss a few of these. For the complete list of request diff --git a/docs/manual/env.html.fr.utf8 b/docs/manual/env.html.fr.utf8 index 8358059ecc6..5f8efa3b622 100644 --- a/docs/manual/env.html.fr.utf8 +++ b/docs/manual/env.html.fr.utf8 @@ -292,8 +292,10 @@

La spécification sur les CGIs (RFC 3875) définit un - certain nombre de variables d'environnement qui s'ajoutent à celles définies - par la spécification de HTTP. Elles ont été plus largement adoptées et + certain nombre de méta-variables dont beaucoup sont affectées de leur valeur + à partir des en-têtes HTTP. Apache httpd les met à disposition en tant que + variables d’environnement pour les scripts CGI et d’autres mécanismes de + traitement des requêtes. Elles ont été plus largement adoptées et constituent une méthode standard pour transmettre des informations entre le navigateur et le serveur, et entre les processus au sein du serveur. Nous en décrivons quelques unes ici. Pour une liste complète des variables de diff --git a/docs/manual/env.xml b/docs/manual/env.xml index 55788f0aed4..c8a290ea3a7 100644 --- a/docs/manual/env.xml +++ b/docs/manual/env.xml @@ -303,9 +303,11 @@

CGI environment variables -

The CGI specification (3875) defines a number of environment - variables that expand on those defined by the HTTP spec. - These have been adopted more broadly, and are a standard +

The CGI specification (3875) defines a + number of meta-variables, many of which derive their values from + HTTP request headers. Apache httpd makes these available as + environment variables to CGI scripts and other request-processing + mechanisms. These have been adopted more broadly, and are a standard part of passing information between the browser and the server, and between processes on the server side. Here we discuss a few of these. For the complete list of request diff --git a/docs/manual/env.xml.fr b/docs/manual/env.xml.fr index a9d66468e0d..52a92b4569c 100644 --- a/docs/manual/env.xml.fr +++ b/docs/manual/env.xml.fr @@ -1,7 +1,7 @@ - + @@ -329,8 +329,10 @@ Variables d'environnement de CGI

La spécification sur les CGIs (3875) définit un - certain nombre de variables d'environnement qui s'ajoutent à celles définies - par la spécification de HTTP. Elles ont été plus largement adoptées et + certain nombre de méta-variables dont beaucoup sont affectées de leur valeur + à partir des en-têtes HTTP. Apache httpd les met à disposition en tant que + variables d’environnement pour les scripts CGI et d’autres mécanismes de + traitement des requêtes. Elles ont été plus largement adoptées et constituent une méthode standard pour transmettre des informations entre le navigateur et le serveur, et entre les processus au sein du serveur. Nous en décrivons quelques unes ici. Pour une liste complète des variables de diff --git a/docs/manual/env.xml.ja b/docs/manual/env.xml.ja index b483503eff0..042a36385ba 100644 --- a/docs/manual/env.xml.ja +++ b/docs/manual/env.xml.ja @@ -1,7 +1,7 @@ - + + + + + @@ -46,9 +46,8 @@

Contrôle d'accès en fonction de l'hôte du client

- Si vous souhaitez restreindre l'accès à certaines parties de votre - site web en fonction de l'adresse de l'hôte de vos visiteurs, le - plus simple pour y parvenir consiste à utiliser le module + Si vous souhaitez restreindre l'accès à certaines parties de votre site web + en fonction de l'adresse de l'hôte de vos visiteurs, utilisez le module mod_authz_host.

@@ -75,10 +74,12 @@ client

Les directives Require s'utilisent comme suit :

- + + Require host address Require ip ip.address - + +

Dans la première forme, nom-hôte est un nom de domaine pleinement qualifié (fqdn), ou un nom de domaine partiel ; vous @@ -89,12 +90,29 @@ Require ip ip.address sous-réseau ou une spécification CIDR de la forme réseau/nnn. Il est possible de spécifier des adresses IPv4 ou IPv6.

+Exemples de formats d’adresse IP + +# Adresse IP complète +Require ip 10.2.3.4 +# Adresse IP partielle (correspond à tout hôte dans la tranche 172.20.0.0/16) +Require ip 172.20 +# Paire réseau/masque +Require ip 192.168.1.0/255.255.255.0 +# Spécification réseau/CIDR +Require ip 192.168.1.0/24 +# Adresse IPv6 +Require ip 2001:db8::a00:20ff:fea7:ccea +# Adresse IPv6 avec CIDR +Require ip 2001:db8:1::/48 + + +

Voir la documentation de mod_authz_host pour d'autres exemples de cette syntaxe.

Vous pouvez insérer le mot-clé not pour inverser un - critère particulier. Notez que le mot not réalise la + critère particulier. Le mot not réalise la négation sur la valeur, et ne peut pas être utilisé seul pour autoriser ou interdire une requête, car non vrai ne veut pas ici forcément dire faux. Ainsi, pour interdire la @@ -104,29 +122,37 @@ Require ip ip.address spamer votre forum, vous pouvez ajouter cette ligne pour lui refuser l'accès :

- + + <RequireAll> - Require all granted - Require not ip 10.252.46.165 +Require all granted +Require not ip 10.252.46.165 </RequireAll> - + +

Les visiteurs possédant cette adresse (10.252.46.165) ne pourront pas voir le contenu concerné par cette directive. Si vous voulez interdir l'accès à une machine en fonction de son nom, vous pouvez ajouter ceci :

- Require not host host.example.com + + +Require not host host.example.com + +

Et si vous voulez interdire l'accès à un domaine particulier, vous pouvez spécifier des adresses IP partielles ou des noms de domaine, comme ceci :

- + + Require not ip 192.168.205 -Require not host phishers.example.com moreidiots.example +Require not host phishers.example.com badguys.example Require not host gov - + +

Les directives RequireAll, fonction du user-agent (le type de navigateur), vous pouvez spécifier ceci :

- + + <If "%{HTTP_USER_AGENT} == 'BadBot'"> - Require all denied +Require all denied </If> - + +

En utilisant la syntaxe expr de la directive Require, l'exemple précédent peut aussi s'écrire :

- + + Require expr %{HTTP_USER_AGENT} != 'BadBot' - + + Avertissement :

Contrôler l'accès en fonction de l'en-tête @@ -185,12 +215,14 @@ d'accès

Par exemple, pour bloquer l'accès à une ressources entre 20h et 7h du matin, vous pouvez utiliser mod_rewrite :

- + + RewriteEngine On RewriteCond "%{TIME_HOUR}" ">=20" [OR] RewriteCond "%{TIME_HOUR}" "<07" RewriteRule "^/fridge" "-" [F] - + +

Toute requête arrivant après 20h ou avant 7h du matin provoquera l'envoi d'une réponse de type 403 Forbidden. Vous pouvez utiliser diff --git a/docs/manual/howto/auth.html.en.utf8 b/docs/manual/howto/auth.html.en.utf8 index 1c814055963..d6521d99dce 100644 --- a/docs/manual/howto/auth.html.en.utf8 +++ b/docs/manual/howto/auth.html.en.utf8 @@ -145,8 +145,8 @@ module from each group.

an AllowOverride directive like the following:

-
AllowOverride AuthConfig
- +
AllowOverride AuthConfig
+

Or, if you are just going to put the directives directly in your main server configuration file, you will of course need to @@ -218,13 +218,13 @@ module from each group.

placed in httpd.conf inside a <Directory "/usr/local/apache/htdocs/secret"> section.

-
AuthType Basic
+
AuthType Basic
 AuthName "Restricted Files"
 # (Following line optional)
 AuthBasicProvider file
 AuthUserFile "/usr/local/apache/passwd/passwords"
 Require user rbowen
- +

Let's examine each of those directives individually. The AuthType directive selects the method that is used to authenticate the user. The most @@ -313,14 +313,14 @@ person in

mod_authn_dbm documentation for more details.

@@ -399,15 +399,15 @@ Require group GroupName
scheme that meets your needs. In the following example, both the file and LDAP based authentication providers are being used.

-
<Directory "/www/docs/private">
-    AuthName "Private"
-    AuthType Basic
-    AuthBasicProvider file ldap
-    AuthUserFile "/usr/local/apache/passwd/passwords"
-    AuthLDAPURL ldap://ldaphost/o=yourorg
-    Require valid-user
+
<Directory "/www/docs/private">
+AuthName "Private"
+AuthType Basic
+AuthBasicProvider file ldap
+AuthUserFile "/usr/local/apache/passwd/passwords"
+AuthLDAPURL ldap://ldaphost/o=yourorg
+Require valid-user
 </Directory>
- +

In this example the file provider will attempt to authenticate the user first. If it is unable to authenticate the user, the LDAP @@ -422,17 +422,17 @@ Require group GroupName

authorization methods can also be used. In this example both file group authorization as well as LDAP group authorization is being used.

-
<Directory "/www/docs/private">
-    AuthName "Private"
-    AuthType Basic
-    AuthBasicProvider file
-    AuthUserFile "/usr/local/apache/passwd/passwords"
-    AuthLDAPURL ldap://ldaphost/o=yourorg
-    AuthGroupFile "/usr/local/apache/passwd/groups"
-    Require group GroupName
-    Require ldap-group cn=mygroup,o=yourorg
+
<Directory "/www/docs/private">
+AuthName "Private"
+AuthType Basic
+AuthBasicProvider file
+AuthUserFile "/usr/local/apache/passwd/passwords"
+AuthLDAPURL ldap://ldaphost/o=yourorg
+AuthGroupFile "/usr/local/apache/passwd/groups"
+Require group GroupName
+Require ldap-group cn=mygroup,o=yourorg
 </Directory>
- +

To take authorization a little further, authorization container directives such as @@ -495,73 +495,15 @@ Require group GroupName

Using authorization providers for access control

Authentication by username and password is only part of the - story. Frequently you want to let people in based on something - other than who they are. Something such as where they are - coming from.

- -

The authorization providers all, - env, host and ip let you - allow or deny access based on other host based criteria such as - host name or ip address of the machine requesting a - document.

- -

The usage of these providers is specified through the - Require directive. - This directive registers the authorization providers - that will be called during the authorization stage of the request - processing. For example:

- -
Require ip address
-        
- - -

where address is an IP address (or a partial IP - address) or:

- -
Require host domain_name
-        
- - -

where domain_name is a fully qualified domain name - (or a partial domain name); you may provide multiple addresses or - domain names, if desired.

- -

For example, if you have someone spamming your message - board, and you want to keep them out, you could do the - following:

- -
<RequireAll>
-    Require all granted
-    Require not ip 10.252.46.165
-</RequireAll>
- - -

Visitors coming from that address will not be able to see - the content covered by this directive. If, instead, you have a - machine name, rather than an IP address, you can use that.

- -
<RequireAll>
-    Require all granted
-    Require not host host.example.com
-</RequireAll>
- - -

And, if you'd like to block access from an entire domain, - you can specify just part of an address or domain name:

- -
<RequireAll>
-    Require all granted
-    Require not ip 192.168.205
-    Require not host phishers.example.com moreidiots.example
-    Require not host ke
-</RequireAll>
- - -

Using <RequireAll> - with multiple <Require> directives, each negated with not, - will only allow access, if all of negated conditions are true. In other words, - access will be blocked, if any of the negated conditions fails.

+ story. You can also allow or deny access based on other + criteria, such as the client's IP address or hostname, using + the authorization providers all, env, + host, and ip with the + Require + directive.

+

For full details and examples, see the + Access Control howto.

Access Control backwards compatibility

@@ -592,9 +534,8 @@ Require group GroupName

Authentication Caching

There may be times when authentication puts an unacceptable load on a provider or on your network. This is most likely to affect users - of mod_authn_dbd (or third-party/custom providers). - To deal with this, HTTPD 2.3/2.4 introduces a new caching provider - mod_authn_socache to cache credentials and reduce + of mod_authn_dbd (or third-party/custom providers). The + mod_authn_socache module caches credentials and reduces the load on the origin provider(s).

This may offer a substantial performance boost to some users.

top
diff --git a/docs/manual/howto/auth.html.fr.utf8 b/docs/manual/howto/auth.html.fr.utf8 index ff5a08b7e44..1295a878c46 100644 --- a/docs/manual/howto/auth.html.fr.utf8 +++ b/docs/manual/howto/auth.html.fr.utf8 @@ -147,11 +147,11 @@ module de chaque groupe.

d'une directive AllowOverride du style :

-
AllowOverride AuthConfig
- +
AllowOverride AuthConfig
+

Si vous avez l'intention d'ajouter les directives directement - dans le fichier de configuration principal, vous devrez bien entendu + dans le fichier de configuration principal, vous devrez bien entendu posséder les droits en écriture sur ce fichier.

Vous devrez aussi connaître un tant soit peu la structure des @@ -224,13 +224,13 @@ module de chaque groupe.

fichier httpd.conf à l'intérieur d'une section <Directory "/usr/local/apache/htdocs/secret"> :

-
AuthType Basic
+
AuthType Basic
 AuthName "Restricted Files"
-# (Following line optional)
+# (La ligne suivante est facultative)
 AuthBasicProvider file
 AuthUserFile "/usr/local/apache/passwd/passwords"
 Require user rbowen
- +

Examinons ces directives une à une. La directive AuthType définit la méthode utilisée pour authentifier l'utilisateur. La méthode la plus @@ -326,14 +326,14 @@ plusieurs personnes Maintenant, vous devez modifier votre fichier .htaccess comme suit :

-
AuthType Basic
+
AuthType Basic
 AuthName "By Invitation Only"
-# Optional line:
+# Ligne facultative :
 AuthBasicProvider file
 AuthUserFile "/usr/local/apache/passwd/passwords"
 AuthGroupFile "/usr/local/apache/passwd/groups"
 Require group GroupName
- +

Maintenant, quiconque appartient au groupe Nom-de-groupe, et possède une entrée dans le fichier @@ -344,8 +344,8 @@ Require group GroupName

l'accès à plusieurs personnes. Plutôt que de créer un fichier de groupes, il vous suffit d'ajouter la directive suivante :

-
Require valid-user
- +
Require valid-user
+

Le remplacement de la ligne Require user rbowen par la ligne Require valid-user autorisera l'accès à @@ -397,14 +397,14 @@ passe

Par exemple, pour sélectionner un fichier dbm à la place d'un fichier texte :

-
<Directory "/www/docs/private">
-    AuthName "Private"
-    AuthType Basic
-    AuthBasicProvider dbm
-    AuthDBMUserFile "/www/passwords/passwd.dbm"
-    Require valid-user
+
<Directory "/www/docs/private">
+AuthName "Private"
+AuthType Basic
+AuthBasicProvider dbm
+AuthDBMUserFile "/www/passwords/passwd.dbm"
+Require valid-user
 </Directory>
- +

D'autres options sont disponibles. Consultez la documentation de mod_authn_dbm pour plus de détails.

@@ -422,15 +422,15 @@ d'authentification <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider file ldap - AuthUserFile "/usr/local/apache/passwd/passwords" - AuthLDAPURL ldap://ldaphost/o=yourorg - Require valid-user +
<Directory "/www/docs/private">
+AuthName "Private"
+AuthType Basic
+AuthBasicProvider file ldap
+AuthUserFile "/usr/local/apache/passwd/passwords"
+AuthLDAPURL ldap://ldaphost/o=yourorg
+Require valid-user
 </Directory>
- +

Dans cet exemple, le fournisseur file va tenter d'authentifier l'utilisateur en premier. S'il n'y parvient pas, le fournisseur LDAP @@ -448,17 +448,17 @@ d'authentification <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider file - AuthUserFile "/usr/local/apache/passwd/passwords" - AuthLDAPURL ldap://ldaphost/o=yourorg - AuthGroupFile "/usr/local/apache/passwd/groups" - Require group GroupName - Require ldap-group cn=mygroup,o=yourorg +

Pour un scénario d'autorisation un peu plus avancé, des directives de conteneur d'autorisation comme <RequireAll> et @@ -524,75 +524,14 @@ autorisation

Require. Cette directive - permet d'enregistrer quels fournisseurs d'autorisation - seront appelés dans le processus d'autorisation au cours du - traitement de la requête. Par exemple :

- -
Require ip address
- - -

adresse est une adresse IP (ou une adresse IP - partielle) ou :

- -
Require host domain_name
- - -

nom_domaine est un nom de domaine entièrement - qualifé (ou un nom de domaine partiel) ; vous pouvez indiquer - plusieurs adresses ou noms de domaines, si vous le désirez.

- -

Par exemple, si vous voulez rejeter les spams dont une - machine vous inonde, vous pouvez utiliser ceci :

- -
<RequireAll>
-    Require all granted
-    Require not ip 10.252.46.165
-</RequireAll>
- - -

Ainsi, les visiteurs en provenance de cette adresse ne - pourront pas voir le contenu concerné par cette directive. Si, - par contre, vous connaissez le nom de la machine, vous pouvez - utiliser ceci :

- -
<RequireAll>
-    Require all granted
-    Require not host host.example.com
-</RequireAll>
- - -

Et si vous voulez interdire l'accès à toutes les machines - d'un domaine, vous pouvez spécifier une partie seulement de - l'adresse ou du nom de domaine :

- -
<RequireAll>
-    Require all granted
-    Require not ip 192.168.205
-    Require not host phishers.example.com moreidiots.example
-    Require not host ke
-</RequireAll>
- - -

L'utilisation de la directive <RequireAll> - avec de multiples directives <Require>, toutes avec la négation - not, n'accordera l'accès que si toutes les - conditions négatives sont vérifiées. En d'autres termes, l'accès - sera refusé si au moins une des conditions négatives n'est pas - vérifiée.

+

La vérification du nom d'utilisateur et du mot de passe ne + constituent qu'un aspect des méthodes d'authentification. Vous pouvez + aussi autoriser ou interdire l’accès en fonction d’autres critères tels + que l’adresse IP du client ou le nom d’hôte en utilisant les + fournisseurs d’autorisation all, env, + host et ip avec la directive Require.

+ +

Pour des détails complets et des exemples, voir le tutoriel Access Control.

@@ -622,17 +561,14 @@ autorisation
top

Mise en cache de l'authentification

-

Dans certains cas, l'authentification constitue une charge - inacceptable pour un fournisseur d'authentification ou votre réseau. - Ceci est susceptible d'affecter les utilisateurs du module - mod_authn_dbd (ou les fournisseurs - tiers/personnalisés). Pour résoudre ce problème, HTTPD 2.3/2.4 - propose un nouveau fournisseur de mise en cache, - mod_authn_socache, qui permet de mettre en cache - les données d'authentification, et ainsi réduire la charge du/des - fournisseurs(s) originels.

-

Cette mise en cache apportera un gain en performance substantiel - à certains utilisateurs.

+

Dans certains cas, l'authentification constitue une charge inacceptable + pour un fournisseur d'authentification ou votre réseau. Ceci est + susceptible d'affecter les utilisateurs du module + mod_authn_dbd (ou les fournisseurs tiers/personnalisés). Le + module mod_authn_socache met en cache les données + d'authentification, et réduit ainsi la charge du/des fournisseurs(s) + originels.

Cette mise en cache apportera un gain en performance + substantiel à certains utilisateurs.

top

Pour aller plus loin . . .

diff --git a/docs/manual/howto/auth.xml b/docs/manual/howto/auth.xml index a87a5111550..9185ae665d4 100644 --- a/docs/manual/howto/auth.xml +++ b/docs/manual/howto/auth.xml @@ -127,9 +127,11 @@ module from each group.

an AllowOverride directive like the following:

- + + AllowOverride AuthConfig - + +

Or, if you are just going to put the directives directly in your main server configuration file, you will of course need to @@ -201,14 +203,16 @@ AllowOverride AuthConfig placed in httpd.conf inside a <Directory "/usr/local/apache/htdocs/secret"> section.

- + + AuthType Basic AuthName "Restricted Files" # (Following line optional) AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" Require user rbowen - + +

Let's examine each of those directives individually. The AuthType directive selects @@ -304,7 +308,8 @@ person in

Now, you need to modify your .htaccess file to look like the following:

- + + AuthType Basic AuthName "By Invitation Only" # Optional line: @@ -312,7 +317,8 @@ AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" AuthGroupFile "/usr/local/apache/passwd/groups" Require group GroupName - + +

Now, anyone that is listed in the group GroupName, and has an entry in the password file, will be let in, if @@ -322,9 +328,11 @@ Require group GroupName specific. Rather than creating a group file, you can just use the following directive:

- + + Require valid-user - + +

Using that rather than the Require user rbowen line will allow anyone in that is listed in the password file, @@ -371,15 +379,17 @@ Require valid-user

To select a dbm file rather than a text file, for example:

- + + <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider dbm - AuthDBMUserFile "/www/passwords/passwd.dbm" - Require valid-user +AuthName "Private" +AuthType Basic +AuthBasicProvider dbm +AuthDBMUserFile "/www/passwords/passwd.dbm" +Require valid-user </Directory> - + +

Other options are available. Consult the mod_authn_dbm documentation for more details.

@@ -394,16 +404,18 @@ Require valid-user scheme that meets your needs. In the following example, both the file and LDAP based authentication providers are being used.

- + + <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider file ldap - AuthUserFile "/usr/local/apache/passwd/passwords" - AuthLDAPURL ldap://ldaphost/o=yourorg - Require valid-user +AuthName "Private" +AuthType Basic +AuthBasicProvider file ldap +AuthUserFile "/usr/local/apache/passwd/passwords" +AuthLDAPURL ldap://ldaphost/o=yourorg +Require valid-user </Directory> - + +

In this example the file provider will attempt to authenticate the user first. If it is unable to authenticate the user, the LDAP @@ -418,18 +430,20 @@ Require valid-user authorization methods can also be used. In this example both file group authorization as well as LDAP group authorization is being used.

- + + <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider file - AuthUserFile "/usr/local/apache/passwd/passwords" - AuthLDAPURL ldap://ldaphost/o=yourorg - AuthGroupFile "/usr/local/apache/passwd/groups" - Require group GroupName - Require ldap-group cn=mygroup,o=yourorg +AuthName "Private" +AuthType Basic +AuthBasicProvider file +AuthUserFile "/usr/local/apache/passwd/passwords" +AuthLDAPURL ldap://ldaphost/o=yourorg +AuthGroupFile "/usr/local/apache/passwd/groups" +Require group GroupName +Require ldap-group cn=mygroup,o=yourorg </Directory> - + +

To take authorization a little further, authorization container directives such as @@ -492,77 +506,15 @@ Require valid-user

Using authorization providers for access control

Authentication by username and password is only part of the - story. Frequently you want to let people in based on something - other than who they are. Something such as where they are - coming from.

- -

The authorization providers all, - env, host and ip let you - allow or deny access based on other host based criteria such as - host name or ip address of the machine requesting a - document.

- -

The usage of these providers is specified through the - Require directive. - This directive registers the authorization providers - that will be called during the authorization stage of the request - processing. For example:

- - -Require ip address - - -

where address is an IP address (or a partial IP - address) or:

- - -Require host domain_name - - -

where domain_name is a fully qualified domain name - (or a partial domain name); you may provide multiple addresses or - domain names, if desired.

- -

For example, if you have someone spamming your message - board, and you want to keep them out, you could do the - following:

- - -<RequireAll> - Require all granted - Require not ip 10.252.46.165 -</RequireAll> - - -

Visitors coming from that address will not be able to see - the content covered by this directive. If, instead, you have a - machine name, rather than an IP address, you can use that.

- - -<RequireAll> - Require all granted - Require not host host.example.com -</RequireAll> - - -

And, if you'd like to block access from an entire domain, - you can specify just part of an address or domain name:

- - -<RequireAll> - Require all granted - Require not ip 192.168.205 - Require not host phishers.example.com moreidiots.example - Require not host ke -</RequireAll> - - -

Using RequireAll - with multiple Require directives, each negated with not, - will only allow access, if all of negated conditions are true. In other words, - access will be blocked, if any of the negated conditions fails.

+ story. You can also allow or deny access based on other + criteria, such as the client's IP address or hostname, using + the authorization providers all, env, + host, and ip with the + Require + directive.

+

For full details and examples, see the + Access Control howto.

Access Control backwards compatibility @@ -596,9 +548,8 @@ Require host domain_name
Authentication Caching

There may be times when authentication puts an unacceptable load on a provider or on your network. This is most likely to affect users - of mod_authn_dbd (or third-party/custom providers). - To deal with this, HTTPD 2.3/2.4 introduces a new caching provider - mod_authn_socache to cache credentials and reduce + of mod_authn_dbd (or third-party/custom providers). The + mod_authn_socache module caches credentials and reduces the load on the origin provider(s).

This may offer a substantial performance boost to some users.

diff --git a/docs/manual/howto/auth.xml.es b/docs/manual/howto/auth.xml.es index 458612d6b78..126e3fb07b4 100644 --- a/docs/manual/howto/auth.xml.es +++ b/docs/manual/howto/auth.xml.es @@ -1,7 +1,7 @@ - + + @@ -135,10 +135,14 @@ module de chaque groupe.

d'une directive AllowOverride du style :

- AllowOverride AuthConfig + + +AllowOverride AuthConfig + +

Si vous avez l'intention d'ajouter les directives directement - dans le fichier de configuration principal, vous devrez bien entendu + dans le fichier de configuration principal, vous devrez bien entendu posséder les droits en écriture sur ce fichier.

Vous devrez aussi connaître un tant soit peu la structure des @@ -211,14 +215,16 @@ module de chaque groupe.

fichier httpd.conf à l'intérieur d'une section <Directory "/usr/local/apache/htdocs/secret"> :

- + + AuthType Basic AuthName "Restricted Files" -# (Following line optional) +# (La ligne suivante est facultative) AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" Require user rbowen - + +

Examinons ces directives une à une. La directive AuthType définit la méthode @@ -322,15 +328,17 @@ plusieurs personnes

Maintenant, vous devez modifier votre fichier .htaccess comme suit :

- + + AuthType Basic AuthName "By Invitation Only" -# Optional line: +# Ligne facultative : AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" AuthGroupFile "/usr/local/apache/passwd/groups" Require group GroupName - + +

Maintenant, quiconque appartient au groupe Nom-de-groupe, et possède une entrée dans le fichier @@ -341,7 +349,11 @@ Require group GroupName l'accès à plusieurs personnes. Plutôt que de créer un fichier de groupes, il vous suffit d'ajouter la directive suivante :

- Require valid-user + + +Require valid-user + +

Le remplacement de la ligne Require user rbowen par la ligne Require valid-user autorisera l'accès à @@ -394,15 +406,17 @@ passe

Par exemple, pour sélectionner un fichier dbm à la place d'un fichier texte :

- + + <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider dbm - AuthDBMUserFile "/www/passwords/passwd.dbm" - Require valid-user +AuthName "Private" +AuthType Basic +AuthBasicProvider dbm +AuthDBMUserFile "/www/passwords/passwd.dbm" +Require valid-user </Directory> - + +

D'autres options sont disponibles. Consultez la documentation de mod_authn_dbm pour plus de détails.

@@ -420,16 +434,18 @@ d'authentification conjointement les fournisseurs d'authentification file et LDAP :

- + + <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider file ldap - AuthUserFile "/usr/local/apache/passwd/passwords" - AuthLDAPURL ldap://ldaphost/o=yourorg - Require valid-user +AuthName "Private" +AuthType Basic +AuthBasicProvider file ldap +AuthUserFile "/usr/local/apache/passwd/passwords" +AuthLDAPURL ldap://ldaphost/o=yourorg +Require valid-user </Directory> - + +

Dans cet exemple, le fournisseur file va tenter d'authentifier l'utilisateur en premier. S'il n'y parvient pas, le fournisseur LDAP @@ -447,18 +463,20 @@ d'authentification autorisation à base de fichier de groupes et une autorisation à base de groupes LDAP.

- + + <Directory "/www/docs/private"> - AuthName "Private" - AuthType Basic - AuthBasicProvider file - AuthUserFile "/usr/local/apache/passwd/passwords" - AuthLDAPURL ldap://ldaphost/o=yourorg - AuthGroupFile "/usr/local/apache/passwd/groups" - Require group GroupName - Require ldap-group cn=mygroup,o=yourorg +AuthName "Private" +AuthType Basic +AuthBasicProvider file +AuthUserFile "/usr/local/apache/passwd/passwords" +AuthLDAPURL ldap://ldaphost/o=yourorg +AuthGroupFile "/usr/local/apache/passwd/groups" +Require group GroupName +Require ldap-group cn=mygroup,o=yourorg </Directory> - + +

Pour un scénario d'autorisation un peu plus avancé, des directives de conteneur d'autorisation comme

Utilisation de fournisseurs d'autorisation pour le contrôle d'accès -

La vérification du nom d'utilisateur et du mot de passe ne - constituent qu'un aspect des méthodes d'authentification. - Souvent, le contrôle d'accès à certaines personnes n'est pas - basé sur leur identité ; il peut dépendre, par exemple de leur - provenance.

- -

Les fournisseurs d'autorisation all, - env, host et ip vous - permettent d'accorder ou refuser l'accès en - fonction de critères tels que le nom d'hôte ou l'adresse - IP de la machine qui effectue la requête.

- -

L'utilisation de ces fournisseurs est spécifiée à l'aide de - la directive Require. Cette directive - permet d'enregistrer quels fournisseurs d'autorisation - seront appelés dans le processus d'autorisation au cours du - traitement de la requête. Par exemple :

- - Require ip address - -

adresse est une adresse IP (ou une adresse IP - partielle) ou :

- - Require host domain_name - -

nom_domaine est un nom de domaine entièrement - qualifé (ou un nom de domaine partiel) ; vous pouvez indiquer - plusieurs adresses ou noms de domaines, si vous le désirez.

- -

Par exemple, si vous voulez rejeter les spams dont une - machine vous inonde, vous pouvez utiliser ceci :

- - -<RequireAll> - Require all granted - Require not ip 10.252.46.165 -</RequireAll> - - -

Ainsi, les visiteurs en provenance de cette adresse ne - pourront pas voir le contenu concerné par cette directive. Si, - par contre, vous connaissez le nom de la machine, vous pouvez - utiliser ceci :

- - -<RequireAll> - Require all granted - Require not host host.example.com -</RequireAll> - - -

Et si vous voulez interdire l'accès à toutes les machines - d'un domaine, vous pouvez spécifier une partie seulement de - l'adresse ou du nom de domaine :

- - -<RequireAll> - Require all granted - Require not ip 192.168.205 - Require not host phishers.example.com moreidiots.example - Require not host ke -</RequireAll> - - -

L'utilisation de la directive RequireAll - avec de multiples directives Require, toutes avec la négation - not, n'accordera l'accès que si toutes les - conditions négatives sont vérifiées. En d'autres termes, l'accès - sera refusé si au moins une des conditions négatives n'est pas - vérifiée.

+

La vérification du nom d'utilisateur et du mot de passe ne + constituent qu'un aspect des méthodes d'authentification. Vous pouvez + aussi autoriser ou interdire l’accès en fonction d’autres critères tels + que l’adresse IP du client ou le nom d’hôte en utilisant les + fournisseurs d’autorisation all, env, + host et ip avec la directive Require.

+ +

Pour des détails complets et des exemples, voir le tutoriel Access Control.

@@ -643,17 +598,14 @@ autorisation
Mise en cache de l'authentification -

Dans certains cas, l'authentification constitue une charge - inacceptable pour un fournisseur d'authentification ou votre réseau. - Ceci est susceptible d'affecter les utilisateurs du module - mod_authn_dbd (ou les fournisseurs - tiers/personnalisés). Pour résoudre ce problème, HTTPD 2.3/2.4 - propose un nouveau fournisseur de mise en cache, - mod_authn_socache, qui permet de mettre en cache - les données d'authentification, et ainsi réduire la charge du/des - fournisseurs(s) originels.

-

Cette mise en cache apportera un gain en performance substantiel - à certains utilisateurs.

+

Dans certains cas, l'authentification constitue une charge inacceptable + pour un fournisseur d'authentification ou votre réseau. Ceci est + susceptible d'affecter les utilisateurs du module + mod_authn_dbd (ou les fournisseurs tiers/personnalisés). Le + module mod_authn_socache met en cache les données + d'authentification, et réduit ainsi la charge du/des fournisseurs(s) + originels.

Cette mise en cache apportera un gain en performance + substantiel à certains utilisateurs.

Pour aller plus loin . . . diff --git a/docs/manual/howto/auth.xml.ja b/docs/manual/howto/auth.xml.ja index be59176f6bf..cf9b03da24e 100644 --- a/docs/manual/howto/auth.xml.ja +++ b/docs/manual/howto/auth.xml.ja @@ -1,7 +1,7 @@ - + + + + diff --git a/docs/manual/howto/cgi.xml.fr b/docs/manual/howto/cgi.xml.fr index da80a744a87..c643ea18652 100644 --- a/docs/manual/howto/cgi.xml.fr +++ b/docs/manual/howto/cgi.xml.fr @@ -1,7 +1,7 @@ - + @@ -57,28 +57,42 @@
Configurer httpd pour autoriser CGI -

httpd doit être configuré pour permettre l'exécution des - programmes CGI, pour que vos programmes CGI puissent fonctionner - correctement. Il existe plusieurs méthodes pour y parvenir.

- - Note: si httpd a été compilé avec le support - des modules partagés (DSO), vous devez vous assurer que le module CGI est - chargé ; vous devez pour cela vérifier que la directive LoadModule correspondante n'a pas été - commentée dans votre httpd.conf. Une directive correcte - doit ressembler à ceci : - - - LoadModule cgid_module modules/mod_cgid.so - - - - Sous Windows, ou si l'on utilise un module MPM non-threadé comme prefork, - une directive correctement configurée sera du style : - - - LoadModule cgi_module modules/mod_cgi.so - +

La configuration de httpd doit autoriser l’exécution de CGI pour que les + programmes CGI fonctionnent. Il existe plusieurs manières d’y parvenir, qui + sont décrites ci-après.

+ +

La prise en charge de CGI est assurée par deux modules : + mod_cgid et mod_cgi. + mod_cgid utilise un démon externe dédié pour gérer les + processus CGI et est requis lorsque httpd utilise un MPM threadé (tel que + event ou worker). mod_cgi + exécute les programmes CGI directement depuis le processus du serveur et est + utilisé avec les MPMs non threadés tels que prefork, ou + sous Windows. Du point de vue de la configuration, ils sont interchangeables + — les directives sont les mêmes. Voir les pages de référence de + mod_cgi et mod_cgid pour les détails de + l’implémentation.

+ + Si httpd a été compilé avec le support des modules + partagés (DSO), vous devez vous assurer que le module approprié est chargé ; + vous devez pour cela vérifier que la directive LoadModule correspondante n'a pas été commentée + dans votre httpd.conf. Pour un MPM threadé : + + + +LoadModule cgid_module modules/mod_cgid.so + + + + Pour Windows, ou un MPM non threadé comme prefork : + + + +LoadModule cgi_module modules/mod_cgi.so + + +
@@ -95,9 +109,11 @@ module="mod_alias">ScriptAlias se présente comme suit :

- + + ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/" - + +

Cet exemple est tiré de votre fichier de configuration httpd.conf par défaut, si vous avez installé httpd @@ -120,12 +136,11 @@ tant que programme CGI.

Par exemple, si une requête pour l'URL - http://www.example.com/cgi-bin/test.pl est - effectuée, httpd tentera d'exécuter le fichier - /usr/local/apache2/cgi-bin/test.pl et en renverra la - sortie. Bien entendu, le fichier doit exister, être exécutable, et - retourner sa sortie d'une manière particulière, sinon httpd - renverra un message d'erreur.

+ http://www.example.com/cgi-bin/test.py est effectuée, httpd + tentera d'exécuter le fichier + /usr/local/apache2/cgi-bin/test.py et en renverra la sortie. + Le fichier doit exister, être exécutable, et produire une sortie sous le + format attendu, sinon httpd renverra un message d'erreur.

@@ -168,23 +183,27 @@ l'exécution des programmes CGI est permise depuis un répertoire particulier :

- + + <Directory "/usr/local/apache2/htdocs/somedir"> - Options +ExecCGI +Options +ExecCGI </Directory> - + +

La directive ci-dessus indique à httpd qu'il doit permettre l'exécution des fichiers CGI. Vous devez aussi indiquer au serveur quels fichiers sont des fichiers CGI. La directive AddHandler suivante indique au serveur qu'il doit traiter tous les fichiers possédant une - extension cgi ou pl en tant que + extension cgi ou py en tant que programmes CGI :

- - AddHandler cgi-script .cgi .pl - + + +AddHandler cgi-script .cgi .py + +
@@ -204,23 +223,27 @@ répertoire utilisateur, vous pouvez utiliser la configuration suivante :

- + + <Directory "/home/*/public_html"> - Options +ExecCGI - AddHandler cgi-script .cgi +Options +ExecCGI +AddHandler cgi-script .cgi </Directory> - + +

Pour indiquer un sous-répertoire cgi-bin d'un répertoire utilisateur où tout fichier sera traité en tant que programme CGI, vous pouvez utiliser ceci :

- + + <Directory "/home/*/public_html/cgi-bin"> - Options ExecCGI - SetHandler cgi-script +Options ExecCGI +SetHandler cgi-script </Directory> - + +
@@ -229,8 +252,8 @@
Ecrire un programme CGI -

Il y a deux différences principales entre la programmation - "standard" et la programmation CGI.

+

La programmation CGI diffère de la programmation + "standard" sur deux points.

En premier lieu, toute sortie de votre programme CGI doit être précédée d'un en-tête MIME-type. Il s'agit d'un @@ -244,7 +267,7 @@

En second lieu, votre sortie doit être en HTML, ou tout autre format qu'un navigateur est en mesure d'afficher. La plupart du temps, il s'agira de HTML, mais occasionnellement, vous pouvez être - amené à écrire un programme CGI qui renvoie une image gif, ou un + amené à écrire un programme CGI qui renvoie une image GIF, ou un autre type de contenu non-HTML.

A part ces deux différences, un programme CGI ressemblera à tout @@ -256,33 +279,29 @@

L'exemple suivant est un exemple de programme CGI qui permet d'afficher une ligne de caractères dans votre navigateur. Ecrivez ce qui suit, enregistrez le dans un fichier nommé - premier.pl, et placez le dans votre répertoire + premier.py, et placez le dans votre répertoire cgi-bin.

- -#!/usr/bin/perl -print "Content-type: text/html\n\n"; -print "Hello, World."; - - -

Même si Perl ne vous est pas familier, vous devriez être - capable de comprendre le fonctionnement de ce programme. La - première ligne indique à httpd (ou à toute interface à partir de - laquelle le programme s'exécute) que ce programme peut être - exécuté en fournissant son fichier à l'interpréteur - /usr/bin/perl. La seconde ligne affiche la - déclaration du type de contenu considéré, suivie de deux paires - "Retour chariot - Nouvelle ligne". Ceci a pour effet d'insérer une - ligne vide après l'en-tête pour marquer la fin des en-têtes HTTP, - et le début du corps du document. La troisième ligne affiche la - chaîne de caractères "Bonjour tout le monde . . .". Et c'est tout - ce dont vous avez besoin.

+ + +#!/usr/bin/env python3 +print("Content-type: text/html\n") +print("Hello, World.") + + + +

La première ligne indique au système d’exploitation quel interpréteur + utiliser. La première invocation de print affiche l’en-tête content-type + suivi d’une ligne vide (le \n dans la chaîne et la nouvelle + ligne qu’ajoute print()), qui matérialise la fin des en-têtes + HTTP. La seconde invocation de print affiche le corps. C’est là tout ce + dont un programme CGI a besoin pour produire une réponse.

Si vous ouvrez votre navigateur favori et lui indiquez l'adresse

- http://www.example.com/cgi-bin/premier.pl + http://www.example.com/cgi-bin/premier.py

ou toute autre URL correspondant à votre programme CGI, Vous @@ -297,9 +316,8 @@ print "Hello, World.";

Mais ça ne marche toujours pas ! -

Vous devriez voir au moins une des quatre sorties suivantes dans - votre navigateur lorsque vous essayez d'accéder à votre programme - CGI depuis le web :

+

Quatre sorties basiques pourront apparaître dans votre navigateur lorsque + vous essayez d'accéder à votre programme CGI depuis le web :

Le flux de sortie de votre programme CGI
@@ -345,9 +363,11 @@ print "Hello, World."; nobody, il suffit de lui attribuer des droits d'exécution pour tout le monde :

- - chmod a+x premier.pl - + + +chmod a+x first.py + +

En outre, si votre programme doit pouvoir accéder en lecture et/ou écriture à d'autres fichiers, ces derniers devront avoir les @@ -374,13 +394,15 @@ print "Hello, World."; CGI.

Un exemple typique de spécification de programme est le chemin - vers l'interpréteur de script (souvent perl) que l'on + vers l'interpréteur de script (souvent python3) que l'on trouve à la première ligne de votre programme CGI et qui va ressembler à ceci :

- - #!/usr/bin/perl - + + +#!/usr/bin/env python3 + +

Assurez-vous qu'il s'agit bien du chemin correct vers l'interpréteur.

@@ -425,10 +447,10 @@ print "Hello, World."; cd /usr/local/apache2/cgi-bin
- ./premier.pl + ./premier.py
-

(N'invoquez pas l'interpréteur perl. Le shell et +

(N'invoquez pas l'interpréteur python3. Le shell et httpd doivent être capable de le déterminer à partir de l'information sur le chemin située sur la première ligne du script.)

@@ -476,7 +498,7 @@ print "Hello, World.";

Si vous ne maîtrisez pas le fonctionnement de suexec, il vous est déconseillé de l'utiliser. Pour désactiver suexec, supprimer - simplement (ou renommez) l'exécutable suexec + (ou renommez) l'exécutable suexec pointé par SUEXEC_BIN et redémarrez le serveur. Si après une lecture de suexec, vous décidez quand-même de l'utiliser, tapez la commande suexec @@ -521,7 +543,7 @@ print "Hello, World."; variables requises se trouve dans la 3875 (Common Gateway Interface).

-

Ce programme CGI basique en Perl permet d'afficher toutes les +

Ce programme CGI basique en Python permet d'afficher toutes les variables d'environnement qui sont échangées. Deux programmes similaires sont fournis avec la distribution de httpd et situés dans le répertoire cgi-bin. @@ -533,16 +555,16 @@ print "Hello, World."; variables d'environnement aux variables de base fournies par défaut.

- -#!/usr/bin/perl -use strict; -use warnings; + + +#!/usr/bin/env python3 +import os -print "Content-type: text/html\n\n"; -foreach my $key (keys %ENV) { - print "$key --> $ENV{$key}<br>"; -} - +print("Content-type: text/html\n") +for key, value in os.environ.items(): +print(f"{key} --> {value}<br>") + +
@@ -600,17 +622,13 @@ foreach my $key (keys %ENV) { partie du travail de base pour vous. Ceci vous permettra de diminuer le nombre d'erreurs et d'accélérer le développement.

-

Si vous écrivez des programmes CGI en Perl, des modules sont à - votre disposition à CPAN. A ce - sujet, le module le plus populaire est CGI.pm. Vous - pouvez aussi essayer CGI::Lite, qui implémente les - fonctionnalités strictement nécessaires, mais suffisantes pour - la majorité des programmes.

- -

Si vous écrivez des programmes CGI en C, vous disposez de nombreuses - options. L'une d'elles est la bibliothèque CGIC de https://web.mit.edu/wwwdev/www/cgic.html.

+

Si vous écrivez des programmes CGI en Python, le module cgi + de la bibliothèque standard (obsolète dans Python 3.11, supprimé dans Python + 3.13) prenait en charge l’analyse de formulaire. Avec les versions actuelles + de Python, utilisez le module urllib.parse pour analyser les + chaîne de paramètres et les données de formulaire. Pour des applications + plus complexes, orientez-vous vers un cadriciel WSGI léger, bien que cela + aille au-delà du domaine de la CGI traditionnelle.

@@ -628,10 +646,10 @@ foreach my $key (keys %ENV) { programme CGI a été écrit, et, si possible, son code source. Ceci permettra une résolution plus aisée de votre problème.

-

Notez que les questions à propos de problèmes CGI ne doivent + Les questions à propos de problèmes CGI ne doivent jamais être postées dans la base de données de bogues de httpd, à moins que vous ne soyez sûr d'avoir trouvé un - problème dans le code source de httpd.

+ problème dans le code source de httpd.
diff --git a/docs/manual/howto/cgi.xml.ja b/docs/manual/howto/cgi.xml.ja index bfa687f378c..aac22f2f3b9 100644 --- a/docs/manual/howto/cgi.xml.ja +++ b/docs/manual/howto/cgi.xml.ja @@ -1,7 +1,7 @@ - + + + + @@ -56,7 +56,7 @@ modifier les fichiers de configuration principaux du serveur.

AuthName AuthUserFile AuthGroupFile - Require + Require @@ -81,9 +81,11 @@ modifier les fichiers de configuration principaux du serveur.

.config, vous pouvez mettre ceci dans le fichier de configuration de votre serveur :

- - AccessFileName ".config" - + + +AccessFileName ".config" + +

Les directives dans les fichiers .htaccess utilisent la même @@ -102,7 +104,7 @@ modifier les fichiers de configuration principaux du serveur.

la documentation de cette directive contiendra une section Override, spécifiant quelle valeur doit prendre la directive AllowOverride pour que cette directive - soit traitée.

+ soit autorisée.

La valeur par défaut de la directive AllowOverride est None. Cela signifie @@ -159,26 +161,26 @@ modifier les fichiers de configuration principaux du serveur.

.htaccess est chargé en mémoire chaque fois qu'un document fait l'objet d'une requête.

-

Notez aussi que httpd doit rechercher les fichiers - .htaccess dans tous les répertoires de niveau - supérieur, afin de rassembler toutes les directives qui s'appliquent - au répertoire courant (Voir la section comment sont - appliquées les directives). Ainsi, si un fichier fait l'objet - d'une requête à partir d'un répertoire - /www/htdocs/exemple, httpd doit rechercher les - fichiers suivants :

+

En outre, httpd doit rechercher des fichiers .htaccess dans + tous les répertoires de niveau supérieur pour rassembler la totalité des + directives applicables (Voir la section comment sont + appliquées les directives). Ainsi, si un fichier fait l'objet d'une + requête à partir d'un répertoire /www/htdocs/exemple, httpd + doit rechercher les fichiers suivants :

- + + /.htaccess /www/.htaccess /www/htdocs/.htaccess /www/htdocs/example/.htaccess - + +

En conséquence, chaque accès à un fichier de ce répertoire nécessite 4 accès au système de fichiers supplémentaires pour rechercher des fichiers .htaccess, même si - aucun de ces fichiers n'est présent. Notez que cet exemple ne peut + aucun de ces fichiers n'est présent. Cet exemple ne peut se produire que si les fichiers .htaccess ont été autorisés pour le répertoire /, ce qui est rarement le cas.

@@ -187,7 +189,7 @@ modifier les fichiers de configuration principaux du serveur.

utilisateurs de modifier la configuration du serveur, il peut en résulter des conséquences sur lesquelles vous n'aurez aucun contrôle. Réfléchissez bien avant de donner ce privilège à vos - utilisateurs. Notez aussi que ne pas donner aux utilisateurs les + utilisateurs. Ne pas donner aux utilisateurs les privilèges dont ils ont besoin va entraîner une augmentation des demandes de support technique. Assurez-vous d'avoir informé clairement vos utilisateurs du niveau de privilèges que vous leur @@ -204,46 +206,58 @@ modifier les fichiers de configuration principaux du serveur.

contrôle plus fin que dans le cas de la directive AllowOverride seule :

- + + # N’autoriser que des directives spécifiques, pas des catégories entières de # directives AllowOverride None AllowOverrideList Redirect RedirectMatch RewriteEngine RewriteRule RewriteCond - + +

Avec cette configuration, toute directive non explicitement spécifiée causera une erreur du serveur si elle est rencontrée dans un fichier .htaccess. C’est un bon compromis entre possibilité et impossibilité totales d’outrepasser la configuration globale.

-

Notez que mettre un fichier .htaccess contenant une - directive dans un répertoire /www/htdocs/exemple - revient exactement au même que mettre la même directive dans une - section Directory <Directory "/www/htdocs/exemple"> - du fichier de configuration de votre serveur principal :

+

Placer une directive dans un fichier .htaccess dans un + répertoire /www/htdocs/example équivaut exactement à placer + cette même directive dans une section <Directory + "/www/htdocs/example"> de la configuration globale de votre + serveur :

-

Fichier .htaccess dans - /www/htdocs/exemple :

+

Fichier .htaccess dans /www/htdocs/example + :

Contenu du fichier .htaccess dans - <code>/www/htdocs/exemple</code> - AddType text/example ".exm" + /www/htdocs/example + + +AddType text/example ".exm" + + Section de votre fichier <code>httpd.conf</code> - + + <Directory "/www/htdocs/example"> - AddType text/example ".exm" +AddType text/example ".exm" </Directory> - + +

L'utilisation des fichiers .htaccess peut être entièrement désactivée en définissant la directive AllowOverride à none :

- AllowOverride None + + +AllowOverride None + +
Comment sont appliquées les directives ? @@ -251,7 +265,7 @@ AllowOverrideList Redirect RedirectMatch RewriteEngine RewriteRule RewriteCond

Les directives de configuration situées dans un fichier .htaccess s'appliquent au répertoire dans lequel ce fichier .htaccess se trouve, ainsi qu'à tous ses - sous-répertoires. Cependant, il est important de garder à l'esprit + sous-répertoires. Cependant, souvenez-vous qu'il peut y avoir des fichiers .htaccess dans les répertoires de niveau supérieur. Les directives sont appliquées selon l'ordre dans lequel elles sont rencontrées. Ainsi, les @@ -268,18 +282,26 @@ AllowOverrideList Redirect RedirectMatch RewriteEngine RewriteRule RewriteCond

Dans le répertoire /www/htdocs/exemple1 se trouve un fichier .htaccess contenant ce qui suit :

- Options +ExecCGI + + +Options +ExecCGI + + -

Note : "AllowOverride Options" doit être présent + "AllowOverride Options" doit être présent pour permettre l'utilisation de la directive "Options" dans les fichiers - .htaccess.

+ .htaccess.

Dans le répertoire /www/htdocs/exemple1/exemple2 se trouve un fichier .htaccess contenant ce qui suit :

- Options Includes + + +Options Includes + +

Ainsi, à cause de ce second fichier .htaccess du répertoire /www/htdocs/exemple1/exemple2, l'exécution @@ -304,15 +326,17 @@ AllowOverrideList Redirect RedirectMatch RewriteEngine RewriteRule RewriteCond définition de toute autre option dans les fichiers .htaccess, vous pouvez utiliser :

- + + <Directory "/www/htdocs"> - AllowOverride All +AllowOverride All </Directory> <Location "/"> - Options +IncludesNoExec -ExecCGI +Options +IncludesNoExec -ExecCGI </Location> - + + Dans cet exemple, on considère que le chemin défini par la directive DocumentRoot est @@ -331,16 +355,18 @@ AllowOverrideList Redirect RedirectMatch RewriteEngine RewriteRule RewriteCond

Contenu du fichier .htaccess :

- + + AuthType Basic AuthName "Password Required" AuthUserFile "/www/passwords/password.file" AuthGroupFile "/www/passwords/group.file" Require group admins - + + -

Notez que AllowOverride AuthConfig doit être présent - pour que ces directives produisent leur effet.

+ AllowOverride AuthConfig doit être présent + pour que ces directives produisent leur effet.

Vous pouvez vous référer au tutoriel sur l'authentification pour une description plus détaillée de @@ -355,15 +381,17 @@ Includes - SSI) on utilise les directives de configuration suivantes, placées dans un fichier .htaccess enregistré dans le répertoire considéré :

- + + Options +Includes AddType text/html "shtml" AddHandler server-parsed shtml - + + -

Notez que AllowOverride Options et AllowOverride + AllowOverride Options et AllowOverride FileInfo doivent être tous les deux présents pour que ces - directives puissent produire leur effet.

+ directives puissent produire leur effet.

Vous pouvez vous référer au tutoriel SSI pour une description plus détaillée des SSI.

@@ -377,6 +405,7 @@ différentes dans un contexte de répertoire. En particulier, les règles sont relatives au répertoire courant, et non à l'URI original. Considérez les exemples suivants :

+ # Dans httpd.conf RewriteRule "^/images/(.+)\.jpg" "/images/$1.png" @@ -388,6 +417,7 @@ RewriteRule "^images/(.+)\.jpg" "images/$1.png" # Dans un fichier .htaccess situé dans le répertoire images/ RewriteRule "^(.+)\.jpg" "$1.png" +

On voit que si le fichier .htaccess se situe à la racine de vos documents, le slash de tête est supprimé de la valeur de @@ -398,7 +428,7 @@ la chaîne /images/ disparaît de cette même valeur de remplacement. Il doit donc en être de même dans votre expression rationnelle.

-

Notez aussi que dans un contexte .htaccess, les expressions +

Dans un contexte .htaccess, les expressions rationnelles sont recompilées à chaque requête, alors que dans un contexte de configuration principale, elle ne sont compilées qu’une seule fois et mises en cache.

@@ -422,23 +452,27 @@ pour une étude détaillée de l'utilisation du module l’exécution de programmes CGI dans un répertoire particulier. Pour y parvenir, vous pouvez utiliser la configuration suivante :

- + + Options +ExecCGI AddHandler cgi-script "cgi" "py" - + +

Alternativement, si vous souhaitez que tous les fichiers d'un répertoire donné soient considérés comme des programmes CGI, vous pouvez utiliser la configuration suivante :

- + + Options +ExecCGI SetHandler cgi-script - + + -

Notez que AllowOverride Options et AllowOverride + AllowOverride Options et AllowOverride FileInfo doivent être tous les deux présents pour que ces - directives puissent produire leur effet.

+ directives puissent produire leur effet.

Vous pouvez vous référer au tutoriel CGI pour une description plus détaillée de la configuration et de la @@ -460,9 +494,11 @@ SetHandler cgi-script dénué de sens dans votre ficher .htaccess et de recharger la page :

- + + TestMe - + +

Si aucune erreur (HTTP 500) n'est générée par le serveur, il est pratiquement certain qu'une directive @@ -474,13 +510,15 @@ TestMe utilisée dans votre fichier .htaccess n'est pas permise.

- -[Tue May 06 09:12:31.528374 2025] [core:alert] [pid 12345] [client 192.168.1.50:54321] /var/www/html/.htaccess: DirectoryIndex not allowed here - + + +[Thu Jun 18 09:12:31.528374 2026] [core:alert] [pid 12345] [client 192.168.1.50:54321] /var/www/html/.htaccess: DirectoryIndex not allowed here + +

Cela signifie soit que vous utilisez une directive qui n'est jamais permise dans les fichiers .htaccess, soit - que vous n'avez tout simplement pas défini la directive + que vous n'avez pas défini la directive AllowOverride à un niveau suffisant pour la directive que vous utilisez. Consultez la documentation de cette directive pour déterminer quel cas @@ -489,9 +527,11 @@ TestMe

Le journal des erreurs peut aussi vous signaler une erreur de syntaxe dans l'usage de la directive elle-même.

- -[Tue May 06 09:14:02.946218 2025] [core:alert] [pid 12345] [client 192.168.1.50:54321] /var/www/html/.htaccess: RewriteCond: bad flag delimiters - + + +[Thu Jun 18 09:14:02.946218 2026] [core:alert] [pid 12345] [client 192.168.1.50:54321] /var/www/html/.htaccess: RewriteCond: bad flag delimiters + +

Dans ce cas, le message d'erreur sera spécifique à l'erreur de syntaxe que vous avez commise.

diff --git a/docs/manual/howto/htaccess.xml.ja b/docs/manual/howto/htaccess.xml.ja index 8672a8c445f..016f3922a00 100644 --- a/docs/manual/howto/htaccess.xml.ja +++ b/docs/manual/howto/htaccess.xml.ja @@ -1,7 +1,7 @@ - + + + + + @@ -43,49 +43,48 @@ plus efficace des ressources réseau. Il ne modifie pas les aspects fondamentaux de HTTP (sa sémantique). Entre autres, il y a toujours des requêtes, des réponses et des en-têtes. Par conséquent, si vous connaissez - HTTP/1, vous connaissez déjà 95% de HTTP/2.

-

Beaucoup a déjà été écrit à propos de HTTP/2 et de son fonctionnement. La - documentation la plus officielle est bien entendu sa 7540 (ou cette version au format plus - lisible : YMMV (7540). Vous trouverez ici une description des rouages de HTTP/2 dans - leurs moindres détails.

-

Le premier document à lire lorsqu'on ne connaît pas un mécanisme n'est - cependant pas sa RFC. Il est préférable de comprendre tout d'abord ce - que ce mécanisme est censé faire, et seulement ensuite de lire sa RFC - pour comprendre comment il fonctionne. http2 explained de Daniel Stenberg - (l'auteur de curl) - est un bien meilleur document pour démarrer l'étude de HTTP/2. En outre, de - nouveaux langages s'ajoutent régulièrement à sa liste de traductions - disponibles !

-

Si vous n'avez pas envie de le lire parce que vous le trouvez trop long, - voici certains pièges à éviter et nouveaux termes à connaître avant de lire - ce document :

+ HTTP/1, vous connaissez déjà 95% deHTTP/2.

+ +

Le protocole est définii dans la 9113 (qui rend obsolète la + 7540 originale). Pour une approche plus abordable, voir le + document http2 explained par Daniel + Stenberg, l’auteur de curl. Il couvre les + but et conception de HTTP/2 sans nécessiter d’analyse de la notation RFC + préalable.

+ +

En bref, il y a quelques nouveaux termes et pièges à éviter que vous + devez garder à l’esprit lors de la lecture de ce document :

+
    -
  • A la différence de HTTP/1 qui est en texte pur, HTTP/2 est un - protocole binaire, et alors que le premier est lisible par - un humain (par exemple pour sniffer le trafic réseau), le second ne - l'est pas. Voir la FAQ - officielle pour plus de détails.
  • +
  • À l’opposé de HTTP 1.1 qui est un protocole en texte pur, HTTP/2 est + un protocol binaire. Le premier a été pensé pour être + lisible par un humain (par exemple pour surveiller le trafic réseau), + alors que ce n’est pas le cas pour le second. Vous trouverez plus + d’information dans cette question de + la FAQ officielle.
  • h2 correspond à HTTP/2 sur TLS (négociation de protocole via ALPN).
  • -
  • h2c correspond à HTTP/2 sur TCP.
  • -
  • Une frame ou trame est la plus petite unité de - communication au sein d'une connexion HTTP/2 et comporte une en-tête et - une séquence d'octets de longueur variable dont la structure correspond - au type de trame. Voir la section correspondante de la documentation - officielle pour plus de détails (7540).
  • Un - stream est un flux bidirectionnel de frames au sein - d'une connexion HTTP/2. La notion correspondante dans HTTP/1 est un - échange de messages de type requête et réponse. Voir la section - correspondante de la documentation officielle pour plus de détails - (7540).
  • -
  • HTTP/2 peut gérer plusieurs streams de données sur - la même connexion TCP, ce qui permet d'éviter le point de blocage - classique de HTTP/1 pour les requêtes lentes, et de ne pas avoir à - ouvrir de nouvelles connexions TCP pour chaque requête/réponse (les - connexions persistantes ou KeepAlive avaient contourné le problème dans - HTTP/1 mais ne l'avaient pas entièrement résolu)
  • +
  • h2c correspond à HTTP/2 sur TCP en texte clair + (sans TLS). Notez que h2c a été supprimé de la spécification actuelle + mais que httpd le prend encore en charge.
  • +
  • Une trame (frame) est la plus petite unité de + communication au sein d’une connexion HTTP/2 ; elle comporte un en-tête + et une séquence d’octets de longueur variable structurée en fonction du + type de trame. Vous trouverez plus d’informations dans la documentation + officielle de la 9113.
  • +
  • Un flux (stream) est une circulation + bidirectionnelle de trames au sein d’une connexion HTTP/2. Le concept + correspondant dans HTTP 1.1 est un échange de messages requête/réponse. + Vous trouverez plus d’informations dans la documentation officielle de + la 9113.
  • +
  • HTTP/2 peut gérer plusieurs flux de données sur la + même connexion TCP, évitant le classique blocage en tête de file + des requêtes HTTP 1.1 lentes, ainsi que la nécessité de réinitier des + connexions TCP pour chaque requête/réponse (KeepAlive contournait le + problème dans HTTP 1.1, mais ne le résolvait pas entièrement).
  • +
@@ -93,14 +92,15 @@ HTTP/2 dans Apache httpd

Le protocole HTTP/2 est implémenté dans Apache httpd via un module propre, pertinemment nommé mod_http2. Ce - module implémente toutes les fonctionnalités décrites par la RFC 7540 et + module implémente toutes les fonctionnalités décrites par la RFC 9113 et supporte les connexions en texte pur (http:), ou sécurisées (https:). La variante texte pur se nomme 'h2c', et la variante sécurisée 'h2'. h2c peut être en mode direct ou Upgrade: via une requête initiale en HTTP/1.

-

Server Push est une nouvelle fonctionnalité offerte - aux développeurs web par HTTP/2. La section correspondante de ce document - vous indiquera comment votre application peut en tirer parti.

+

Server Push était une nouvelle fonctionnalité offerte + aux développeurs web par HTTP/2, mais elle est maintenant obsolète. Voir la + section EarlyHints pour l’alternative + recommandée.

@@ -135,36 +135,43 @@

Maintenant que vous disposez d'un binaire httpd compilé avec le module mod_http2, l'activation de ce dernier nécessite un minimum de configuration supplémentaire. En premier lieu, comme pour tout - module Apache, vous devez le charger :

- + module de httpd, vous devez le charger :

+ + LoadModule http2_module modules/mod_http2.so - +
+

La seconde directive que vous devez ajouter à votre fichier de configuration est

- + + Protocols h2 http/1.1 +

Ceci permet de définir h2, la variante sécurisée, comme le protocole préféré pour les connexions à votre serveur. Si vous souhaitez que toutes les variantes soient disponibles, utilisez la directive suivante :

- + + Protocols h2 h2c http/1.1 -

Selon l'endroit où vous placez cette directive, elle affectera l'ensemble - de votre serveur, ou seulement un ou plusieurs serveurs virtuels. Vous + +

Selon l'endroit où vous placez cette directive, elle affectera toute les + connexions, ou seulement celles vers un serveur virtuel spécifique. Vous pouvez aussi l'imbriquer comme dans l'exemple suivant :

- + + Protocols http/1.1 <VirtualHost ...> - ServerName test.example.org - Protocols h2 http/1.1 +ServerName test.example.org +Protocols h2 http/1.1 </VirtualHost> + -

Seules les connexions en HTTP/1 seront alors permises, sauf pour le serveur - virtuel test.example.org qui acceptera aussi les connexions SSL - en HTTP/2.

+

Seules les connexions en HTTP/1 seront alors permises, sauf pour les + connexions SSL vers test.example.org qui propose aussi HTTP/2.

Utilisez une chaîne d'algorithmes de chiffrement forte

La directive SSLCipherSuite doit être définie avec une chaîne d'algorithmes de chiffrement TLS forte. Même si @@ -182,25 +189,32 @@ Protocols http/1.1

L'ordre des protocoles indiqués est aussi important. Par défaut, le premier sera le protocole préféré. Lorsqu'un client offre plusieurs choix, c'est le plus à gauche qui sera sélectionné. Dans

- + + Protocols http/1.1 h2 +

le protocole préféré sera HTTP/1 et il sera toujours sélectionné sauf si un client ne supporte que h2. Comme nous souhaitons communiquer en HTTP/2 avec les clients qui le supportent, la meilleure définition de la directive est

- + + Protocols h2 h2c http/1.1 +

Toujours à propos de l'ordre des protocoles, le client a lui aussi ses propres préférences en la matière. À ce titre, si vous le souhaitez, vous pouvez configurer votre serveur pour qu'il sélectionne non plus son protocole préféré, mais au contraire le protocole préféré du client :

- + + ProtocolsHonorOrder Off - + +
+

Avec cette directive, l'ordre des protocoles que vous avez défini devient caduque et seul l'ordre défini par le client sera pris en compte.

@@ -248,11 +262,10 @@ ProtocolsHonorOrder Off
Clients -

La plupart des navigateurs modernes supportent HTTP/2, mais seulement sur - des connexions SSL : Firefox v43, Chrome v45, Safari v9, iOS Safari v9, - Opera v35, Chrome pour Android v49 et - Internet Explorer v11 sous Windows10 (selon cette source).

+

Tous les navigateurs modernes prennent en charge HTTP/2 sur + des connexions TLS (source). La + prise en charge est devenue universelle sur les navigateurs principaux à peu + près en 2015.

D'autres clients et serveurs sont listés dans le wiki des implémentations ; entre autres des implémentations pour c, c++, common @@ -268,14 +281,19 @@ ProtocolsHonorOrder Off

Le premier d'entre eux est bien entendu curl. Assurez-vous au préalable que votre version supporte HTTP/2 en vérifiant ses Fonctionnalités :

- - $ curl -V - curl 7.45.0 (x86_64-apple-darwin15.0.0) libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8 nghttp2/1.3.4 - Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...] - Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 - - homebrew sous Mac OS : - brew install curl --with-openssl --with-nghttp2 + + +$ curl -V +curl 8.20.0 (x86_64-pc-linux-gnu) libcurl/8.20.0 OpenSSL/3.5.7 zlib/1.3.1 nghttp2/1.69.0 +Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 [...] +Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 + + + Notes à propos de macOS Homebrew +

curl de Homebrew inclut par défaut la prise en charge de + HTTP/2. Installez le avec la commande brew install curl et + suivez les instructions affichées pour le mettre en tête du PATH de votre + système.

Pour une inspection en profondeur : wireshark.

Le paquet nghttp2 inclut aussi des @@ -290,15 +308,22 @@ ProtocolsHonorOrder Off

Chrome fournit des journaux détaillés des connexions HTTP/2 via la page special net-internals page. Il y - a aussi cette extension intéressante pour Chrome + a aussi cette extension intéressante pour Chrome et Firefox + href="https://addons.mozilla.org/en-us/firefox/addon/http2-indicator/">Firefox qui permet d'indiquer que votre navigateur utilise HTTP/2.

Push serveur + Notification d’obsolescence +

Server Push est obsolète dans la 9113. Les + navigateurs principaux (Chrome 106+, Edge 106+) ont supprimé sa prise en + charge. Bien que mod_http2 implémente encore push, les + nouveaux déploiements doivent utiliser 103 Early + Hints à titre de méthode plus fiable pour informer les clients à propos + des ressources nécessaires.

+

Le protocole HTTP/2 permet au serveur de proposer (PUSH) des réponses pour lesquelles le client n'a rien demandé. La communication autour de ces réponses est du style : "voici une requête que vous n'avez jamais @@ -323,29 +348,37 @@ ProtocolsHonorOrder Off procéder vous-même à ces expérimentations :

mod_http2 inspecte l'en-tête de la réponse et recherche les en-têtes Link sous un certain format :

- + + Link </xxx.css>;rel=preload, </xxx.js>; rel=preload - + +

Si la connexion supporte PUSH, ces deux ressources seront envoyées au client. En tant que développeur web vous pouvez définir ces en-têtes soit directement au niveau de la réponse de votre application, soit en configurant votre serveur via

- + + <Location /xxx.html> - Header add Link "</xxx.css>;rel=preload" - Header add Link "</xxx.js>;rel=preload" +Header add Link "</xxx.css>;rel=preload" +Header add Link "</xxx.js>;rel=preload" </Location> - + +

Si vous souhaitez utiliser des liens preload sans déclencher de PUSH, vous pouvez utiliser le paramètre nopush comme suit :

- + + Link </xxx.css>;rel=preload;nopush - + +

Vous pouvez aussi désactiver les PUSHes pour l'ensemble de votre serveur via la directive

- + + H2Push Off - + +

À savoir aussi :

Le module maintient un journal des ressources ayant fait l'objet d'un PUSH pour chaque connexion (en général des condensés hash des URLs), et @@ -353,14 +386,13 @@ H2Push Off lorsque la connexion est fermée, le journal de ses PUSHes est supprimé.

Certains développeurs planchent sur la manière de permettre au client d'informer le serveur des ressources qu'il possède déjà dans son cache afin - d'éviter les PUSHes pour ces dernières, mais ceci n'en est actuellement qu'à - un stade très expérimental.

+ d'éviter les PUSHes pour ces dernières, mais aucune norme n’a émergé avant + que push ne devienne obsolète.

L' - en-tête Accept-Push-Policy est un autre dispositif expérimental + en-tête Accept-Push-Policy est un dispositif expérimental implémenté dans mod_http2 ; il permet au client de définir pour - chaque requête quels genres de PUSHes il accepte.

- - + chaque requête quels genres de PUSHes il accepte. Ce dispositif a été + abandonné et n’a jamais été adopté.

La fonctionnalité PUSH n'apportera pas toujours le gain de performances dans l'obtention de réponses aux requêtes. Vous trouverez plusieurs études sur ce @@ -385,27 +417,31 @@ H2Push Off

- Suggestions précoces + EarlyHints

A l'instar des ressources PUSHées, une autre méthode consiste à envoyer des en-têtes Link au client avant même que la réponse ne soit prête. Cette méthode utilise la fonctionnalité appelée "Suggestions précoces" (Early Hints) décrite dans la 8297.

Pour utiliser cette fonctionnalité, vous devez l'activer explicitement sur le serveur via :

- + + H2EarlyHints on - + +

Elle n'est en effet pas activée par défaut car certains navigateurs anciens perdent pied avec de telles réponses.

Une fois cette fonctionnalité activée, vous pouvez utiliser la directive H2PushResource pour déclencher les suggestions précoces et les PUSHes de ressources :

- + + <Location /xxx.html> - H2PushResource /xxx.css - H2PushResource /xxx.js +H2PushResource /xxx.css +H2PushResource /xxx.js </Location> - + +

Le serveur enverra alors au client une réponse "103 Early Hints" dès qu'il commencera à traiter la requête. Selon votre application web, cet envoi peut intervenir beaucoup plus tôt que le diff --git a/docs/manual/howto/public_html.html.en.utf8 b/docs/manual/howto/public_html.html.en.utf8 index a46efd91e9d..1ea435e5bfc 100644 --- a/docs/manual/howto/public_html.html.en.utf8 +++ b/docs/manual/howto/public_html.html.en.utf8 @@ -36,14 +36,20 @@ to a URL http://example.com/~username/ will get content out of the home directory of the user "username", out of the subdirectory specified by the UserDir directive.

-

Note that, by default, access to these directories is not +

By default, access to these directories is not enabled. You can enable access when using UserDir by uncommenting the line:

-
#Include conf/extra/httpd-userdir.conf
- +
#Include conf/extra/httpd-userdir.conf
+

in the default config file conf/httpd.conf, and adapting the httpd-userdir.conf file as necessary, or by including the appropriate directives in a <Directory> block within the main config file.

+ +
Third-party distributions of httpd (from your OS vendor or + package manager) often place the mod_userdir + configuration in a separate file, and may enable it by default. + Check your distribution's documentation for specifics. The examples + in this document assume a default source build of httpd.
  • Per-user web directories
  • Setting the file path with UserDir
  • @@ -71,8 +77,8 @@ assumed to be a directory path relative to the home directory of the specified user. Given this configuration:

    -
    UserDir public_html
    - +
    UserDir public_html
    +

    the URL http://example.com/~rbowen/file.html will be translated to the file path @@ -82,8 +88,8 @@ constructed using that path, plus the username specified. Given this configuration:

    -
    UserDir /var/html
    - +
    UserDir /var/html
    +

    the URL http://example.com/~rbowen/file.html will be translated to the file path /var/html/rbowen/file.html

    @@ -92,8 +98,8 @@ in which the asterisk is replaced with the username. Given this configuration:

    -
    UserDir /var/www/*/docs
    - +
    UserDir /var/www/*/docs
    +

    the URL http://example.com/~rbowen/file.html will be translated to the file path @@ -101,14 +107,14 @@

    Multiple directories or directory paths can also be set.

    -
    UserDir public_html /var/html
    - +
    UserDir public_html /var/html
    +
    -

    For the URL http://example.com/~rbowen/file.html, - Apache will search for ~rbowen. If it isn't found, - Apache will search for rbowen in /var/html. If - found, the above URL will then be translated to the file path - /var/html/rbowen/file.html

    +

    The arguments are considered in the order they appear. + For the URL http://example.com/~rbowen/file.html, + httpd will search for ~rbowen. If it isn't found, + httpd will then search for rbowen in /var/html. + The file will be served from whichever location is found first.

top
@@ -117,8 +123,8 @@

The UserDir directive can be used to redirect user directory requests to external URLs.

-
UserDir http://example.org/users/*/
- +
UserDir http://example.org/users/*/
+

The above example will redirect a request for http://example.com/~bob/abc.html to @@ -132,17 +138,17 @@

Using the syntax shown in the UserDir documentation, you can restrict what users are permitted to use this functionality:

-
UserDir disabled root jro fish
- +
UserDir disabled root jro fish
+

The configuration above will enable the feature for all users except for those listed in the disabled statement. You can, likewise, disable the feature for all but a few users by using a configuration like the following:

-
UserDir disabled
+
UserDir disabled
 UserDir enabled rbowen krietz
- +

See UserDir documentation for additional examples.

@@ -152,16 +158,16 @@ UserDir enabled rbowen krietz

Enabling a cgi directory for each user

-

In order to give each user their own cgi-bin directory, you can use +

To give each user their own cgi-bin directory, you can use a <Directory> directive to make a particular subdirectory of a user's home directory cgi-enabled.

-
<Directory "/home/*/public_html/cgi-bin/">
-    Options ExecCGI
-    SetHandler cgi-script
+
<Directory "/home/*/public_html/cgi-bin/">
+Options ExecCGI
+SetHandler cgi-script
 </Directory>
- +

Then, presuming that UserDir is set to public_html, a cgi program example.cgi @@ -176,7 +182,7 @@ UserDir enabled rbowen krietz

Allowing users to alter configuration

-

If you want to allows users to modify the server configuration in +

If you want to allow users to modify the server configuration in their web space, they will need to use .htaccess files to make these changes. Ensure that you have set AllowOverride to a value sufficient for the directives that you want to permit the users diff --git a/docs/manual/howto/public_html.html.es.utf8 b/docs/manual/howto/public_html.html.es.utf8 index da0883672b5..d47e6f0a024 100644 --- a/docs/manual/howto/public_html.html.es.utf8 +++ b/docs/manual/howto/public_html.html.es.utf8 @@ -30,6 +30,10 @@  ko  |  tr 

+
Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.

En sistemas con múltiples usuarios, cada usuario puede tener un website en su directorio home usando la directiva UserDir. Los visitantes de una URL diff --git a/docs/manual/howto/public_html.html.fr.utf8 b/docs/manual/howto/public_html.html.fr.utf8 index c1171a977a4..5cbd9a5e11d 100644 --- a/docs/manual/howto/public_html.html.fr.utf8 +++ b/docs/manual/howto/public_html.html.fr.utf8 @@ -38,18 +38,25 @@ visiteurs de l'URL http://example.com/~nom_utilisateur/ recevront un contenu situé dans le répertoire home de l'utilisateur "nom_utilisateur", et dans le sous-répertoire spécifié par la directive UserDir.

-

Notez que par défaut, l'accès à ces répertoires n'est +

Par défaut, l'accès à ces répertoires n'est pas permis. Vous pouvez en permettre l'accès à l'aide de la directive UserDir en décommentant la ligne :

-
#Include conf/extra/httpd-userdir.conf
- +
#Include conf/extra/httpd-userdir.conf
+

dans le fichier de configuration par défaut conf/httpd.conf, et en adaptant le fichier httpd-userdir.conf selon vos besoins, ou en incluant les directives appropriées dans une section <Directory> du fichier de configuration principal.

+ +
Les distributions tierces de httpd (fournies par le fabricant de votre + OS ou par le gestionnaire de paquets) placent souvent la configuration de + mod_userdir dans un fichier séparé, et peuvent l’activer + par défaut. Consultez la documentation de votre distribution pour les + spécificités. Les exemples de ce document présupposent une construction par + défaut à partir des sources de httpd.
interprété comme chemin relatif au répertoire home de l'utilisateur considéré. Par exemple, avec cette configuration :

-
UserDir public_html
- +
UserDir public_html
+

l'URL http://example.com/~rbowen/fichier.html correspondra au chemin fichier @@ -91,9 +98,8 @@ avec le système de fichiers sera construit en utilisant ce chemin, suivi du nom de l'utilisateur considéré. Par exemple, avec cette configuration :

-
UserDir /var/html
- - +
UserDir /var/html
+

l'URL http://example.com/~rbowen/fichier.html correspondra au chemin fichier /var/html/rbowen/fichier.html

@@ -102,8 +108,8 @@ avec le système de fichiers remplacé par le nom de l'utilisateur dans le chemin du fichier correspondant. Par exemple, avec cette configuration :

-
UserDir /var/www/*/docs
- +
UserDir /var/www/*/docs
+

l'URL http://example.com/~rbowen/fichier.html correspondra au chemin fichier @@ -112,14 +118,14 @@ avec le système de fichiers

On peut aussi définir plusieurs répertoires ou chemins de répertoires.

-
UserDir public_html /var/html
- +
UserDir public_html /var/html
+
-

Avec l'URL http://example.com/~rbowen/fichier.html, - Apache va rechercher ~rbowen. S'il ne le trouve pas, - Apache va rechercher rbowen dans - /var/html. S'il le trouve, l'URL ci-dessus correspondra - au chemin fichier /var/html/rbowen/file.html

+

Les arguments sont pris en compte selon l’ordre dans lequel ils + apparaissent. Pour l’URL http://example.com/~rbowen/file.html, + httpd recherchera d’abord ~rbowen. Si ce dernier n’est pas + trouvé, httpd cherchera rbowen dans /var/html. Le + fichier sera servi depuis le premier emplacement trouvé.

top
@@ -128,8 +134,8 @@ avec le système de fichiers

On peut utiliser la directive UserDir pour rediriger les requêtes relatives aux répertoires utilisateurs vers des URLs externes.

-
UserDir http://example.org/users/*/
- +
UserDir http://example.org/users/*/
+

L'exemple ci-dessus va rediriger une requête pour http://example.com/~bob/abc.html vers @@ -144,8 +150,8 @@ avec le système de fichiers vous pouvez définir quels utilisateurs sont autorisés à utiliser cette fonctionnalité :

-
UserDir disabled root jro fish
- +
UserDir disabled root jro fish
+

La configuration ci-dessus va autoriser l'utilisation de la fonctionnalité pour tous les utilisateurs, à l'exception de ceux @@ -154,10 +160,9 @@ avec le système de fichiers utilisateurs sauf certains d'entre eux en utilisant une configuration du style :

-
UserDir disabled
+
UserDir disabled
 UserDir enabled rbowen krietz
- - +

Vous trouverez d'autres exemples dans la documentation de UserDir.

@@ -170,12 +175,11 @@ UserDir enabled rbowen krietz
vous pouvez utiliser une section <Directory> pour activer CGI dans un sous-répertoire particulier d'un répertoire home utilisateur.

-
<Directory "/home/*/public_html/cgi-bin/">
-    Options ExecCGI
-    SetHandler cgi-script
+
<Directory "/home/*/public_html/cgi-bin/">
+Options ExecCGI
+SetHandler cgi-script
 </Directory>
- - +

Avec la configuration ci-dessus, et en supposant que UserDir est défini à public_html, un programme CGI exemple.cgi pourra être chargé depuis ce diff --git a/docs/manual/howto/public_html.xml b/docs/manual/howto/public_html.xml index 16d05ce1030..82ed2de686f 100644 --- a/docs/manual/howto/public_html.xml +++ b/docs/manual/howto/public_html.xml @@ -33,17 +33,25 @@ out of the home directory of the user "username", out of the subdirectory specified by the UserDir directive.

-

Note that, by default, access to these directories is not +

By default, access to these directories is not enabled. You can enable access when using UserDir by uncommenting the line:

- - #Include conf/extra/httpd-userdir.conf - + + +#Include conf/extra/httpd-userdir.conf + +

in the default config file conf/httpd.conf, and adapting the httpd-userdir.conf file as necessary, or by including the appropriate directives in a Directory block within the main config file.

+ + Third-party distributions of httpd (from your OS vendor or + package manager) often place the mod_userdir + configuration in a separate file, and may enable it by default. + Check your distribution's documentation for specifics. The examples + in this document assume a default source build of httpd. Mapping URLs to the Filesystem @@ -73,9 +81,11 @@ assumed to be a directory path relative to the home directory of the specified user. Given this configuration:

- + + UserDir public_html - + +

the URL http://example.com/~rbowen/file.html will be translated to the file path @@ -85,9 +95,11 @@ UserDir public_html constructed using that path, plus the username specified. Given this configuration:

- + + UserDir /var/html - + +

the URL http://example.com/~rbowen/file.html will be translated to the file path /var/html/rbowen/file.html

@@ -96,9 +108,11 @@ UserDir /var/html in which the asterisk is replaced with the username. Given this configuration:

- + + UserDir /var/www/*/docs - + +

the URL http://example.com/~rbowen/file.html will be translated to the file path @@ -106,15 +120,17 @@ UserDir /var/www/*/docs

Multiple directories or directory paths can also be set.

- + + UserDir public_html /var/html - + + -

For the URL http://example.com/~rbowen/file.html, - Apache will search for ~rbowen. If it isn't found, - Apache will search for rbowen in /var/html. If - found, the above URL will then be translated to the file path - /var/html/rbowen/file.html

+

The arguments are considered in the order they appear. + For the URL http://example.com/~rbowen/file.html, + httpd will search for ~rbowen. If it isn't found, + httpd will then search for rbowen in /var/html. + The file will be served from whichever location is found first.

@@ -123,9 +139,11 @@ UserDir public_html /var/html

The UserDir directive can be used to redirect user directory requests to external URLs.

- + + UserDir http://example.org/users/*/ - + +

The above example will redirect a request for http://example.com/~bob/abc.html to @@ -139,19 +157,23 @@ UserDir http://example.org/users/*/

Using the syntax shown in the UserDir documentation, you can restrict what users are permitted to use this functionality:

- + + UserDir disabled root jro fish - + +

The configuration above will enable the feature for all users except for those listed in the disabled statement. You can, likewise, disable the feature for all but a few users by using a configuration like the following:

- + + UserDir disabled UserDir enabled rbowen krietz - + +

See UserDir documentation for additional examples.

@@ -161,17 +183,19 @@ UserDir enabled rbowen krietz
Enabling a cgi directory for each user -

In order to give each user their own cgi-bin directory, you can use +

To give each user their own cgi-bin directory, you can use a Directory directive to make a particular subdirectory of a user's home directory cgi-enabled.

- + + <Directory "/home/*/public_html/cgi-bin/"> - Options ExecCGI - SetHandler cgi-script +Options ExecCGI +SetHandler cgi-script </Directory> - + +

Then, presuming that UserDir is set to public_html, a cgi program example.cgi @@ -186,7 +210,7 @@ UserDir enabled rbowen krietz

Allowing users to alter configuration -

If you want to allows users to modify the server configuration in +

If you want to allow users to modify the server configuration in their web space, they will need to use .htaccess files to make these changes. Ensure that you have set AllowOverride to a diff --git a/docs/manual/howto/public_html.xml.es b/docs/manual/howto/public_html.xml.es index e0a374cab24..1088f3f58f0 100644 --- a/docs/manual/howto/public_html.xml.es +++ b/docs/manual/howto/public_html.xml.es @@ -1,7 +1,7 @@ - + diff --git a/docs/manual/howto/public_html.xml.fr b/docs/manual/howto/public_html.xml.fr index c871f645339..b32d9db513b 100644 --- a/docs/manual/howto/public_html.xml.fr +++ b/docs/manual/howto/public_html.xml.fr @@ -1,7 +1,7 @@ - + @@ -35,19 +35,28 @@ visiteurs de l'URL http://example.com/~nom_utilisateur/ recevront un contenu situé dans le répertoire home de l'utilisateur "nom_utilisateur", et dans le sous-répertoire spécifié par la directive UserDir.

-

Notez que par défaut, l'accès à ces répertoires n'est +

Par défaut, l'accès à ces répertoires n'est pas permis. Vous pouvez en permettre l'accès à l'aide de la directive UserDir en décommentant la ligne :

- - #Include conf/extra/httpd-userdir.conf - + + +#Include conf/extra/httpd-userdir.conf + +

dans le fichier de configuration par défaut conf/httpd.conf, et en adaptant le fichier httpd-userdir.conf selon vos besoins, ou en incluant les directives appropriées dans une section Directory du fichier de configuration principal.

+ + Les distributions tierces de httpd (fournies par le fabricant de votre + OS ou par le gestionnaire de paquets) placent souvent la configuration de + mod_userdir dans un fichier séparé, et peuvent l’activer + par défaut. Consultez la documentation de votre distribution pour les + spécificités. Les exemples de ce document présupposent une construction par + défaut à partir des sources de httpd. Mise en correspondance des URLs @@ -79,7 +88,11 @@ avec le système de fichiers interprété comme chemin relatif au répertoire home de l'utilisateur considéré. Par exemple, avec cette configuration :

- UserDir public_html + + +UserDir public_html + +

l'URL http://example.com/~rbowen/fichier.html correspondra au chemin fichier @@ -89,8 +102,11 @@ avec le système de fichiers sera construit en utilisant ce chemin, suivi du nom de l'utilisateur considéré. Par exemple, avec cette configuration :

- UserDir /var/html - + + +UserDir /var/html + +

l'URL http://example.com/~rbowen/fichier.html correspondra au chemin fichier /var/html/rbowen/fichier.html

@@ -99,7 +115,11 @@ avec le système de fichiers remplacé par le nom de l'utilisateur dans le chemin du fichier correspondant. Par exemple, avec cette configuration :

- UserDir /var/www/*/docs + + +UserDir /var/www/*/docs + +

l'URL http://example.com/~rbowen/fichier.html correspondra au chemin fichier @@ -108,13 +128,17 @@ avec le système de fichiers

On peut aussi définir plusieurs répertoires ou chemins de répertoires.

- UserDir public_html /var/html + + +UserDir public_html /var/html + + -

Avec l'URL http://example.com/~rbowen/fichier.html, - Apache va rechercher ~rbowen. S'il ne le trouve pas, - Apache va rechercher rbowen dans - /var/html. S'il le trouve, l'URL ci-dessus correspondra - au chemin fichier /var/html/rbowen/file.html

+

Les arguments sont pris en compte selon l’ordre dans lequel ils + apparaissent. Pour l’URL http://example.com/~rbowen/file.html, + httpd recherchera d’abord ~rbowen. Si ce dernier n’est pas + trouvé, httpd cherchera rbowen dans /var/html. Le + fichier sera servi depuis le premier emplacement trouvé.

@@ -124,7 +148,11 @@ avec le système de fichiers module="mod_userdir">UserDir pour rediriger les requêtes relatives aux répertoires utilisateurs vers des URLs externes.

- UserDir http://example.org/users/*/ + + +UserDir http://example.org/users/*/ + +

L'exemple ci-dessus va rediriger une requête pour http://example.com/~bob/abc.html vers @@ -139,7 +167,11 @@ avec le système de fichiers vous pouvez définir quels utilisateurs sont autorisés à utiliser cette fonctionnalité :

- UserDir disabled root jro fish + + +UserDir disabled root jro fish + +

La configuration ci-dessus va autoriser l'utilisation de la fonctionnalité pour tous les utilisateurs, à l'exception de ceux @@ -148,11 +180,12 @@ avec le système de fichiers utilisateurs sauf certains d'entre eux en utilisant une configuration du style :

- + + UserDir disabled UserDir enabled rbowen krietz - - + +

Vous trouverez d'autres exemples dans la documentation de UserDir.

@@ -166,13 +199,14 @@ UserDir enabled rbowen krietz type="section">Directory pour activer CGI dans un sous-répertoire particulier d'un répertoire home utilisateur.

- + + <Directory "/home/*/public_html/cgi-bin/"> - Options ExecCGI - SetHandler cgi-script +Options ExecCGI +SetHandler cgi-script </Directory> - - + +

Avec la configuration ci-dessus, et en supposant que UserDir est défini à public_html, un programme CGI exemple.cgi pourra être chargé depuis ce diff --git a/docs/manual/howto/public_html.xml.ja b/docs/manual/howto/public_html.xml.ja index 2dc2f64a415..2e4cacb357d 100644 --- a/docs/manual/howto/public_html.xml.ja +++ b/docs/manual/howto/public_html.xml.ja @@ -1,7 +1,7 @@ - + + + + diff --git a/docs/manual/howto/reverse_proxy.xml.fr b/docs/manual/howto/reverse_proxy.xml.fr index 4a68e858cda..4fd3db51d15 100644 --- a/docs/manual/howto/reverse_proxy.xml.fr +++ b/docs/manual/howto/reverse_proxy.xml.fr @@ -1,7 +1,7 @@ - + + + @@ -30,7 +30,10 @@

Les SSI permettent d'ajouter du contenu dynamique à des documents -HTML préexistants.

+HTML préexistants sans nécessiter de cadriciel complet d’application. Ils +s’avèrent particulièrement utiles pour insérer des éléments courants — en-têtes, +pieds de page, navigation, horodatages — dans des pages qui, sans cela, seraient +statiques.

Qu'est-ce que SSI ? -

SSI (Server Side Includes) est constitué de directives placées dans - des pages HTML, et évaluées par le serveur au moment où les pages - sont servies. Elles vous permettent d'ajouter du contenu généré - dynamiquement à une page HTML préexistante, sans avoir à servir la - page entière via un programme CGI, ou toute autre technologie de - contenu dynamique.

- -

Par exemple, vous pouvez insérer la directive suivante dans une - page HTML existante :

- - - <!--#echo var="DATE_LOCAL" --> - +

Les directives SSI sont des commentaires HTML avec une syntaxe spécifique + que le module mod_include reconnaît et évalue avant que la + page ne soit envoyée au client. Elle sont de la forme suivante :

-

Ainsi, lorsque la page sera servie, la directive sera évaluée et - remplacée par sa valeur :

+ + +<!--#echo var="DATE_LOCAL" --> + + +

Lorsque la page est servie, ce fragment est remplacé par sa valeur :

+ - Tuesday, 15-Jan-2013 19:28:54 EST + Thursday, 18-Jun-2026 14:22:07 EDT -

Le choix entre l'utilisation des SSI et la génération entière de - la page par un programme quelconque, est en général dicté par la - proportion de contenu statique et de contenu devant être généré - chaque fois que la page est servie. SSI est idéal pour ajouter de - petites quantités d'information, comme l'heure courante dans - l'exemple précédent. Mais si la - plus grande partie de votre page est générée au moment où elle est - servie, vous devez vous tourner vers une autre solution.

+

Les directives étant intégrées dans des commentaires HTML, les + navigateurs les ignoreront si les SSI ne sont pas activées (bien qu’elles + demeurent visibles dans le code source de la page).

Configurer votre serveur pour permettre les SSI -

Pour permettre l'utilisation des SSI sur votre serveur, vous - devez ajouter la directive suivante dans votre fichier - httpd.conf, ou dans un fichier .htaccess - :

+

Pour activer le traitement des SSI, ajoutez la directive suivante à votre + fichier httpd.conf ou à un fichier .htaccess :

+ + Options +Includes + + +

Si cette option est définie, httpd va analyser les fichiers en y + recherchant des directives SSI. Comme la plupart des configurations + contiennent plusieurs directives Options qui peuvent s’outrepasser les unes les autres, + appliquez la directive d’activation au répertoire spécifique pour lequel + vous voulez activer les SSI.

+ +

Vous devez aussi indiquer à httpd les fichiers qu’il doit analyser. Pour + ce faire, il existe deux approches courantes.

+ +

La première consiste à indiquer une extension de nom de fichier (en + général .shtml) pour les pages pour lesquelles les SSI sont + activées :

-

Cette directive indique à Apache que vous désirez permettre la - recherche de directives SSI lors de l'interprétation des fichiers. - Notez cependant que la plupart des configurations contiennent de - nombreuses directives Options - qui peuvent s'écraser les unes les autres. Vous devrez probablement - appliquer ces directives Options au répertoire - spécifique pour lequel vous voulez activer les SSI, afin d'être sûr - qu'elles y seront bien activées.

- -

Tout fichier ne fera cependant pas l'objet de recherche de - directives SSI. Vous devez indiquer à Apache quels fichiers seront - concernés. Vous pouvez y parvenir en indiquant une extension, comme - .shtml, à l'aide des directives suivantes :

+ AddType text/html .shtml AddOutputFilter INCLUDES .shtml + -

Un des désavantages de cette approche réside dans le fait que si - vous voulez ajouter des directives SSI à une page préexistante, vous - devrez changer le nom de cette page, et donc tout lien qui la - contient, de façon à ce qu'elle possède l'extension - .shtml, condition nécessaire pour que les directives - SSI qu'elle contient soient traitées.

+

Cette approche a pour désavantage de nécessiter, pour ajouter des SSI à + une page existante, de renommer le fichier (et de mettre à jour tous les + liens vers ce dernier) pour utiliser l’extension .shtml.

-

Une autre méthode consiste à utiliser la directive La seconde approche consiste à utiliser la directive XBitHack :

+ + XBitHack on + + +

La directive XBitHack indique + à httpd qu’il doit analyser tout fichier dont le bit d’exécution est + positionné. Ainsi, pour activer les SSI pour une page existante, il suffit + de rendre le fichier exécutable :

-

La directive XBitHack - indique à Apache qu'il doit rechercher des directivves SSI dans les - fichiers si leur bit d'exécution est positionné. Il n'est ainsi plus - nécessaire de changer le nom du fichier pour ajouter des directives - SSI à une page préexistante ; vous devez simplement attribuer les - droits d'exécution au fichier à l'aide de chmod.

- chmod +x pagename.html + +chmod +x pagename.html + - -

Un bref commentaire sur ce qu'il ne faut pas faire. Certaines - personnes peuvent vous conseiller de tout simplement indiquer à - Apache de rechercher des directives SSI dans tous les fichiers - .html, ce qui vous évite d'avoir à gérer les noms de - fichiers avec extension .shtml. Ils n'ont probablement - pas entendu parler de la directive XBitHack. En effet, vous devez - garder à l'esprit qu'en faisant ceci, Apache va devoir rechercher - des directives SSI dans chaque fichier qu'il sert, même s'il n'en - contient aucune. Ce n'est donc pas une bonne idée car les - performances peuvent en être sensiblement affectées.

- -

Bien entendu, sous Windows, il n'y a pas de bit d'exécution à - positionner, ce qui limite un peu vos choix.

- -

Dans sa configuration par défaut, Apache n'envoie pas la date de - dernière modification ou les en-têtes HTTP relatifs à la taille des - contenus dans les pages SSI, car ses valeurs sont difficiles à - calculer pour les contenus dynamiques. Ceci peut induire une - impression de diminution des performances côté client, en empêchant - la mise en cache de votre document. Il existe deux méthodes pour - résoudre ce problème :

+ +

+ Évitez de configurer httpd pour analyser tous les fichiers + .html pour y trouver des directives SSI. Cela force en effet le + serveur à parcourir tous les fichiers HTML qu’il sert, même ceux qui n’ont + pas de contenu SSI, ce qui ajoute une surcharge de travail inutile. +

+ +

Sous Windows, il n’y a pas de bit d’exécution ; l’approche avec la + directive XBitHack n’est donc + pas valable dans ce cas. Vous devrez alors utiliser l’approche par extension + de nom de fichier.

+ +

Par défaut, httpd n’envoie pas la date de dernière modification ou les + en-têtes content-length sur les pages SSI, car ces valeurs sont difficiles à + calculer pour un contenu dynamique. Cela peut empêcher la mise en cache et + induire un ressenti de performances plus lentes. Deux approches peuvent + aider :

    -
  1. Utilisez la configuration XBitHack Full. Elle - indique à Apache de déterminer la date de dernière modification en - ne regardant que la date du fichier à l'origine de la requête, - tout en ignorant la date de modification de tout fichier inclus.
  2. - -
  3. Utilisez les directives fournies par le module - mod_expires pour définir de manière explicite la - date d'expiration de vos fichiers, laissant par la-même - aux navigateurs et aux mandataires le soin de déterminer s'il est - opportun ou non de les mettre en cache.
  4. +
  5. Utilisez la directive XBitHack Full qui indique à httpd + qu’il doit déterminer la date de dernière modification à partir du fichier + initialement demandé, tout en ignorant les dates de dernière modification + des fichiers inclus.
  6. + +
  7. Utilisez le module mod_expires pour définir un moment + d’expiration explicite, indiquant ainsi aux navigateurs et aux mandataires + que le contenu peut être mis en cache.
  8. +
Directives SSI de base -

Les directives SSI adoptent la syntaxe suivante :

+

Les directives SSI utilisent la syntaxe suivante :

- <!--#fonction attribut=valeur attribut=valeur ... --> + +<!--#function attribute=value attribute=value ... --> + -

Le format d'une directive SSI étant similaire à celui d'un - commentaire HTML, si vous n'avez pas activé correctement SSI, le - navigateur l'ignorera, mais elle sera encore visible dans le source - HTML. Si SSI est correctement configuré, la directive sera remplacée - par ses résultats.

- -

"fonction" peut prendre de nombreuses formes, et nous décrirons - plus précisément la plupart d'entre eux dans la prochaine version de - ce document. Pour le moment, voici quelques exemples de ce que vous - pouvez faire avec SSI.

+

Si les SSI sont correctement configurées, la directive sera remplacée par + sa sortie. Dans le cas contraire, elle demeurera en tant que commentaire + HTML — invisible à l’utilisateur final, mais présente dans le code source de + la page.

La date courante - <!--#echo var="DATE_LOCAL" --> + +<!--#echo var="DATE_LOCAL" --> + -

La fonction echo permet d'afficher la valeur d'une - variable. Il existe un grand nombre de variables standards, y - compris l'ensemble des variables d'environnement disponibles pour - les programmes CGI. De plus, vous pouvez définir vos propres - variables à l'aide de la fonction set.

+

La fonction echo a pour sortie la valeur d’une variable. Les + variables standard incluent le jeu complet de variables d’environnement + disponibles pour les programmes CGI, ainsi que les variables que vous pouvez + définir avec set.

-

Si vous n'aimez pas le format sous lequel la date s'affiche, vous - pouvez utiliser la fonction config avec un attribut - timefmt, pour le modifier.

+

Pour personnaliser le format de la date, utilisez la fonction + config avec l’attribut timefmt :

- <!--#config timefmt="%A %B %d, %Y" -->
- Today is <!--#echo var="DATE_LOCAL" --> + +<!--#config timefmt="%A %B %d, %Y" -->
+Today is <!--#echo var="DATE_LOCAL" --> +
Date de modification du fichier - Dernière modification du document <!--#flastmod file="index.html" --> + +Dernière modification du document <!--#flastmod file="index.html" --> +

Le format peut là aussi être modifié à l'aide de l'attribut @@ -236,12 +229,13 @@ AddOutputFilter INCLUDES .shtml

Inclusion des résultats d'un programme CGI -

C'est le cas le plus courant d'utilisation des SSI - afficher les - résultats d'un programme CGI, comme l'universellement adoré - "compteur d'accès".

+

Les SSI permettent d’inclure directement la sortie d’un programme CGI + dans la page :

- <!--#include virtual="/cgi-bin/counter.pl" --> + +<!--#include virtual="/cgi-bin/counter.pl" --> +
@@ -250,246 +244,216 @@ AddOutputFilter INCLUDES .shtml
Exemples additionnels -

Vous trouverez dans ce qui suit quelques exemples spécifiques de - ce que vous pouvez faire de vos documents HTML avec SSI.

+

Vous trouverez dans les exemples pratiques suivants des cas d’utilisation + courants des SSI.

Quand ce document a-t-il été modifié ? -

Nous avons mentionné plus haut que vous pouviez utiliser SSI pour - informer l'utilisateur de la date de dernière modification du - document. Cependant, la méthode pour y parvenir n'a pas été vraiment - abordée. Placé dans votre document HTML, le code suivant va insérer - un repère de temps dans votre page. Bien entendu, SSI devra avoir - été correctement activé, comme décrit plus haut.

- - <!--#config timefmt="%A %B %d, %Y" -->
- Dernière modification du fichier <!--#flastmod file="ssi.shtml" --> -
+

Une des utilisations courantes des SSI est l’affichage d’un horodatage + « date de dernière modification » sur chaque page. Le code suivant utilise + la variable LAST_MODIFIED ; vous pouvez donc coller le même + extrait dans tout fichier sans modifier son nom :

-

Bien entendu, vous devez remplacer ssi.shtml par le - nom du fichier auquel vous faites référence. Ceci ne conviendra pas - si vous recherchez un morceau de code générique que vous pourrez - insérer dans tout fichier ; dans ce cas, il est préférable - d'utiliser la variable LAST_MODIFIED :

- <!--#config timefmt="%D" -->
- This file last modified <!--#echo var="LAST_MODIFIED" --> + +<!--#config timefmt="%D" -->
+Date de dernière modification de ce fichier <!--#echo var="LAST_MODIFIED" --> +
+
-

Pour plus de détails sur le format timefmt, tapez - strftime dans votre moteur de recherche préferé. La - syntaxe est identique.

+

Pour des détails à propos des chaînes de formatage de + timefmt, voir la documentation de strftime dans le + manuel de référence de la bibliothèque C de votre système.

-Que puis-je configurer d'autre ? +Autres options de configuration -

En plus du format de date, vous pouvez utiliser l'élément - config pour configurer deux autres choses.

+

En plus de timefmt, la fonction config accepte + deux autres attributs.

-

En général, lorsque quelque chose se passe mal avec votre - directive SSI, vous recevez le message :

+

L’attribut errmsg modifie le message d’erreur affiché + lorsqu’une directive SSI échoue. Le message par défaut est :

- [an error occurred while processing this directive] +[an error occurred while processing this directive] -

Pour modifier ce message, vous pouvez utiliser l'attribut - errmsg avec la fonction config :

+

Vous pouvez le remplacer par un contenu plus adapté à votre site :

- <!--#config errmsg="[Il semblerait que vous ne sachiez pas - utiliser les SSI]" --> + +<!--#config errmsg="[Content unavailable]" --> + -

Il est cependant probable que les utilisateurs finaux ne voient - jamais ce message, car vous aurez résolu tous les problèmes issus de - vos directives SSI avant que votre site ne soit mis en production. - (N'est-ce pas ?)

- -

Vous pouvez aussi modifier le format sous lequel les tailles de - fichiers sont affichées à l'aide de l'attribut sizefmt. - Vous pouvez spécifier bytes pour un affichage en - octets, ou abbrev pour un affichage plus concis en Ko - ou Mo, selon le cas.

-
+

L’attribut sizefmt contrôle la manière dont les tailles de + fichier sont spécifiées : bytes pour un décompte en octets ou + abbrev pour une forme abrégée en Ko ou Mo.

+
Exécution de commandes -

Voici autre chose que vous pouvez faire avec la fonction - exec. Vous pouvez vraiment faire exécuter une commande - par SSI en utilisant le shell (/bin/sh, pour être plus - précis - ou le shell DOS, si vous êtes sous Win32). Par exemple, ce - qui suit vous permet d'afficher le contenu d'un répertoire.

- - <pre>
- <!--#exec cmd="ls" -->
- </pre> -
+

La fonction exec permet d’exécuter une commande du shell et + d’inclure sa sortie dans la page. Sur les systèmes de style Unix, la + commande est exécutée via /bin/sh, et sous Windows via + l’interpréteur de commande.

-

ou, sous Windows

- <pre>
- <!--#exec cmd="dir" -->
- </pre> + +<pre> +<!--#exec cmd="ls" --> +</pre> +
+

+ La fonctionnalité exec constitue un risque de sécurité + significatif. En effet, elle exécute des commandes arbitraires avec les + privilèges du processus du serveur web. Si les utilisateurs peuvent éditer + du contenu sur votre site, assurez-vous que cette fonctionnalité soit + désactivée en spécifiant IncludesNOEXEC au lieu de + Includes dans la définition de la directive Options. +

+
-

Vous noterez probablement l'étrange formatage provoqué par cette - directive sous Windows, car la sortie de dir contient - la chaîne de caractères "<dir>", ce qui trompe le - navigateur.

- -

Notez que cette fonctionnalité est très dangereuse, car elle va - permettre d'exécuter tout code associé à l'élément - exec. Si vous êtes dans la situation où les - utilisateurs peuvent éditer le contenu de vos pages web, dans le cas - d'un "livre d'or" par exemple, assurez-vous de désactiver cette - fonctionnalité. Vous pouvez, tout en permettant les SSI, désactiver - la fonctionnalité exec à l'aide de l'argument - IncludesNOEXEC de la directive - Options.

-
+
Techniques SSI avancées -

Outre l'affichage de contenu, les SSI d'Apache vous permettent de - définir des variables, et de les utiliser dans des comparaisons et - des conditions.

+

Au-delà de la simple inclusion de contenu, les SSI prennent en charge les + variables et les expressions conditionnelles, rendant possible la génération + de contenus différents en fonction du contexte de la requête.

Définition de variables -

Avec l'élément set, vous pouvez définir des - variables pour un usage ultérieur. Comme nous en aurons besoin plus - loin, nous allons en parler tout de suite. La syntaxe se présente - comme suit :

+

La directive set permet de définir des variables à utiliser + plus tard dans la page :

+ - <!--#set var="name" value="Rich" --> + +<!--#set var="name" value="Rich" --> + -

Pour affecter une valeur à vos variables, en plus de la - définition littérale de l'exemple ci-dessus, vous pouvez utiliser - une autre variable, y compris les variables d'environnement, ou les variables - décrites plus haut (comme LAST_MODIFIED par exemple). - Pour indiquer qu'il s'agit d'une variable et non d'une chaîne, vous - devez utiliser le symbole dollar ($) devant le nom de la - variable.

+

Les variables peuvent référencer d’autres variables (y compris des variables d’environnement) en utilisant le signe dollar + ($) comme préfixe :

- <!--#set var="modified" value="$LAST_MODIFIED" --> - + + +<!--#set var="modified" value="$LAST_MODIFIED" --> + + + +

Pour inclure un signe dollar littéral, protégez-le avec une + contre-oblique :

-

Pour insérer un caractère $ dans la valeur de votre variable, - vous devez l'échapper à l'aide d'un backslash.

- <!--#set var="cost" value="\$100" --> + +<!--#set var="cost" value="\$100" --> + -

Enfin, si vous voulez insérer une variable dans une chaîne, et - s'il y a une chance pour que le nom de la variable se confonde avec - le reste de la chaîne, vous pouvez l'entourer d'accolades pour - eviter toute confusion (Il est difficile de trouver un bon exemple - pour illustrer ceci, mais j'espère que vous comprendrez).

+

Lorsqu'un nom de variable risque d'être ambigu au sein d'une chaîne plus + longue, utilisez des accolades pour le délimiter :

+ - <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> + +<!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> +
Expressions conditionnelles -

Maintenent que nous avons des variables, et que nous pouvons - définir et comparer leurs valeurs, nous sommes à même de les - utiliser dans des expressions conditionnelles. Ceci confère à SSI le - statut de petit langage de programmation. - mod_include fournit une structure if, - elif, else, endif pour la - construction d'expressions conditionnelles, ce qui vous permet de - générer plusieurs pages logiques à partir d'une seule vraie - page.

- -

La structure de l'expression conditionnelle est :

+

mod_include fournit les éléments if, + elif, else et endif permettant de + construire une logique conditionnelle. Cette fonctionnalité permet de + générer des sorties différentes à partir d’une seule page physique.

+ +

La structure est :

+ - <!--#if expr="condition" -->
- <!--#elif expr="condition" -->
- <!--#else -->
- <!--#endif --> + +<!--#if expr="test_condition" -->
+<!--#elif expr="test_condition" -->
+<!--#else -->
+<!--#endif --> +
-

Une condition peut revêtir la forme de toute comparaison - logique - soit une comparaison de valeurs avec une autre, soit une - vérification de la "vérité" d'une valeur particulière (Une chaîne - donnée est vraie si elle n'est pas vide). Pour une liste exhaustive - des opérateurs de comparaison disponibles, voir la documentation du - module mod_include.

+

Une test_condition peut comparer des valeurs ou vérifier si une + variable n’est pas vide. Voir la documentation de + mod_include pour la liste complète des opérateurs de + comparaison.

-

Par exemple, spour insérer l'heure du jour dans votre page web, - vous pouvez ajouter ces lignes dans la page HTML :

+

Par exemple, pour afficher des salutations différentes en fonction de + l’heure du jour :

- - Good - <!--#if expr="%{TIME_HOUR} <12" -->
- morning!
- <!--#else -->
- afternoon!
- <!--#endif -->
-
- -

Toute autre variable (que vous avez définie, ou une variable - d'environnement normale) peut être utilisée dans les expressions - conditionnelles. Voir le document Expressions - rationnelles dans le serveur HTTP Apache pour plus de détails à - propos du fonctionnement du moteur d'évaluation des expressions - rationnelles.

- -

Associée à la possibilité avec Apache de définir - des variables d'environnement à l'aide de directives - SetEnvIf, ainsi que d'autres directives en rapport, - cette fonctionnalité vous permet d'ajouter une grande variété - de contenus dynamiques côté serveur sans avoir à concevoir une - application web de A à Z.

+ + +Good +<!--#if expr="%{TIME_HOUR} <12" -->
+morning!
+<!--#else -->
+afternoon!
+<!--#endif -->
+
+
+ +

Toute variable — définie par l’utilisateur ou issue de l’environnement + — peut être utilisée dans les expressions conditionnelles. Voir Les expressions dans le Serveur HTTP Apache pour des + détails complets à propos du moteur d’évaluation des expressions.

+ +

Combinées avec la capacité de httpd à définir des variables + d’environnement en utilisant SetEnvIf et les directives apparentées, + les SSI conditionnelles peuvent traiter une grande variété de scénarios de + contenu dynamique sans nécessiter de cadriciel complet d’applications.

Conclusion -

SSI ne remplace certainement pas CGI, ou d'autres technologies - utilisées pour la génération de pages web dynamiques. Mais c'est une - bonne méthode pour ajouter des petits contenus dynamiques à vos - pages, sans devoir fournir un gros effort supplémentaire.

+

Pour les sites principalement statiques mais nécessitant quelques touches + dynamiques, les SSI évitent la surcharge de travail induite par la + configuration d’une pile complète d’applications. Elles ne requièrent que + mod_include et quelques lignes de configuration pour + fonctionner.

diff --git a/docs/manual/howto/ssi.xml.ja b/docs/manual/howto/ssi.xml.ja index 5cfe9bd574b..a7f22c805d5 100644 --- a/docs/manual/howto/ssi.xml.ja +++ b/docs/manual/howto/ssi.xml.ja @@ -1,7 +1,7 @@ - + + + +``` + +## Generating PNGs from SVGs + +Use `rsvg-convert` (from `librsvg`): + +```bash +# Install (macOS): +brew install librsvg + +# Install (Fedora/RHEL/CentOS): +dnf install librsvg2-tools + +# Install (Debian/Ubuntu): +apt-get install librsvg2-bin + +# Convert at 1x (matching SVG viewBox dimensions): +rsvg-convert -o rewrite_l_flag_looping.png rewrite_l_flag_looping.svg + +# Or specify explicit dimensions: +rsvg-convert -w 520 -h 720 -o rewrite_l_flag_looping.png rewrite_l_flag_looping.svg +``` + +Existing PNGs in this directory are at 1x scale (matching their SVG +viewBox width/height). Keep PNGs at 1x for consistency with the rest +of the documentation build. + +## General Conventions + +- Diamonds for decisions, rounded rectangles for actions, pill shapes + for start/end terminals. +- Yes/No labels on decision branches (9px, gray). +- Phase boxes group related steps that occur in the same processing context. +- Dashed lines indicate loop-back paths or optional flows. +- Titles centered at the top of the SVG. +- Typical viewBox widths: 440–650px. Heights: 360–750px. diff --git a/docs/manual/images/rewrite_l_flag_looping.png b/docs/manual/images/rewrite_l_flag_looping.png new file mode 100644 index 00000000000..47aabf8b63c Binary files /dev/null and b/docs/manual/images/rewrite_l_flag_looping.png differ diff --git a/docs/manual/images/rewrite_l_flag_looping.svg b/docs/manual/images/rewrite_l_flag_looping.svg new file mode 100644 index 00000000000..bee5740c4f6 --- /dev/null +++ b/docs/manual/images/rewrite_l_flag_looping.svg @@ -0,0 +1,153 @@ + + + + + + + + + + Per-Directory Rewriting: [L] Flag Looping + + + + Request: /app/hello + + + + + Per-directory rules (.htaccess) — one pass + + + + Strip directory prefix + + + Pattern sees: "hello" + + + + + Get next rule + + + + + Pattern + matches? + + + + No + + + + Yes + + + + Conditions + met? + + + + No + + + + Yes + + + + Substitute URL / filename + + + + + [END] flag? + + + + Yes + + Done + + + + No + + + + + + + + + [L] or end + of rules? + + + More rules + + + + + [L] stops pass + + + + Internal subrequest with + rewritten URL + + + + + Same rule + matches again? + + + + No + + Done + + + + Yes + + + + Guarded by + RewriteCond? + + + + Yes — cond + fails 2nd pass + + Done + + + + No + + Infinite loop! + (500 error after 10 cycles) + + diff --git a/docs/manual/images/rewrite_module_order.png b/docs/manual/images/rewrite_module_order.png new file mode 100644 index 00000000000..fdde07ddc13 Binary files /dev/null and b/docs/manual/images/rewrite_module_order.png differ diff --git a/docs/manual/images/rewrite_module_order.svg b/docs/manual/images/rewrite_module_order.svg new file mode 100644 index 00000000000..bca2266c9ab --- /dev/null +++ b/docs/manual/images/rewrite_module_order.svg @@ -0,0 +1,110 @@ + + + + + + + + + + Module Processing Order: mod_rewrite vs mod_alias + + + + + + + Server / VirtualHost Context + + + + Request arrives + + + + + URL-to-filename translation phase + + + + + mod_rewrite + ← FIRST + + + + + mod_alias + second + + + + RewriteRule matches first. + If it rewrites, Redirect + never sees the request. + + + + + Content + + + + Per-Directory Context + (.htaccess / <Directory>) + + + + Request arrives + + + + + URL-to-filename translation phase + + + + + mod_alias + ← FIRST + + + + + Fixup phase (later) + + + + + mod_rewrite + second + + + + Redirect runs first. + If it matches, RewriteRule + in .htaccess never fires. + + + + + Content + + + The order reversal between contexts is a common source of confusion. Choose one module per task. + + diff --git a/docs/manual/images/rewrite_path_stripping.png b/docs/manual/images/rewrite_path_stripping.png new file mode 100644 index 00000000000..cfc901b09ab Binary files /dev/null and b/docs/manual/images/rewrite_path_stripping.png differ diff --git a/docs/manual/images/rewrite_path_stripping.svg b/docs/manual/images/rewrite_path_stripping.svg new file mode 100644 index 00000000000..12d40924074 --- /dev/null +++ b/docs/manual/images/rewrite_path_stripping.svg @@ -0,0 +1,142 @@ + + + + + + + + + + Per-Directory Path Stripping and RewriteBase + + + + Incoming request + + + + + /app/ + products/widget + ← full URL-path + + + + + Strip directory prefix + + + + Prefix = URL path to + .htaccess directory + (here: /app/) + + + + products/widget + ← no leading / + + + + + RewriteRule pattern matches + + + + e.g. RewriteRule "^products/(.+)$" "shop.php?item=$1" + + + + + Apply substitution + + + + + Substitution + type? + + + + http(s):// + + External + redirect + + 302 response + (no subrequest) + + + + starts with / + + + Absolute path: + RewriteBase + not applied + + + + relative + + + + shop.php?item=widget + ← relative + + + + + Prepend RewriteBase + + + + Default: URL path to + .htaccess directory + Or: explicit RewriteBase + + + + /app/ + shop.php?item=widget + ← full path + + + + + Issue internal subrequest + + + + + /app/shop.php?item=widget + + + + + Re-enters request cycle + + + Three possible substitution outcomes: + • Relative (e.g. "shop.php") → RewriteBase prepended → subrequest + • Absolute path (e.g. "/other/page") → used as-is → subrequest + • Absolute URI (e.g. "http://...") → external redirect (no subrequest) + + diff --git a/docs/manual/images/rewrite_simplified_overview.png b/docs/manual/images/rewrite_simplified_overview.png new file mode 100644 index 00000000000..14bc1da77d8 Binary files /dev/null and b/docs/manual/images/rewrite_simplified_overview.png differ diff --git a/docs/manual/images/rewrite_simplified_overview.svg b/docs/manual/images/rewrite_simplified_overview.svg new file mode 100644 index 00000000000..e960038caf4 --- /dev/null +++ b/docs/manual/images/rewrite_simplified_overview.svg @@ -0,0 +1,113 @@ + + + + + + + + + + How mod_rewrite Processes a Request + Simplified overview — see Technical Details for full processing model + + + + Request arrives + + + + + RewriteEngine + On? + + + + No + + Pass through + + + + Yes + + + + Get next rule + + + + + Any rules + left? + + + + No + + URL unchanged + + + + Yes + + + + Pattern + matches? + + + + No + + + + Yes + + + + RewriteCond + passes? + + + + No + + + + Yes + + + + Apply substitution + + + + + [L] or [END] + flag? + + + + No — try + next rule + + + + Yes + + + URL rewritten — done + + diff --git a/docs/manual/install.html.en.utf8 b/docs/manual/install.html.en.utf8 index f700528330d..9b27e9d72a0 100644 --- a/docs/manual/install.html.en.utf8 +++ b/docs/manual/install.html.en.utf8 @@ -34,15 +34,16 @@ -

This document covers compilation and installation of the Apache HTTP Server - on Unix and Unix-like systems only. For compiling and - installation on Windows, see Using Apache HTTP Server with Microsoft - Windows and Compiling Apache for Microsoft Windows. - For other platforms, see the platform documentation.

+

The Apache HTTP Server is released as source code. This document + covers building and installing the server from source on Unix and + Unix-like systems. For Windows, see Using Apache HTTP Server with Microsoft + Windows and Compiling Apache httpd for Microsoft + Windows. For other platforms, see the platform documentation.

-

Apache httpd uses libtool and autoconf - to create a build environment that looks like many other Open Source - projects.

+

If you install httpd from a distribution package (RPM, DEB, etc.), + configuration layout and defaults may differ from what is described here. + See third-party packages below, and consult your + distribution's documentation for platform-specific details.

If you are upgrading from one minor version to the next (for example, 2.4.66 to 2.4.67), please skip down to the upgrading section.

@@ -66,45 +67,6 @@

Overview for the impatient

-
-
Installing on Fedora/CentOS/Red Hat Enterprise Linux
-
-
sudo dnf install httpd
-
-# Start service
-sudo systemctl start httpd
-
-# Stop service
-sudo systemctl stop httpd
-
-# Restart service
-sudo systemctl restart httpd
- - -
See the - Fedora project's documentation for platform-specific notes.
-
- -
Installing on Ubuntu/Debian
-
-
sudo apt install apache2
-
-# Start service
-sudo systemctl start apache2
-
-# Stop service
-sudo systemctl stop apache2
-
-# Restart service
-sudo systemctl restart apache2
- - -
See Ubuntu's documentation for platform-specific notes.
- -
- -
Installing from source
-
@@ -164,12 +126,6 @@ $ cd httpd-NN

Each section of the compilation and installation process is described in more detail below, beginning with the requirements for compiling and installing Apache httpd.

- - - -
Don't see your favorite platform mentioned - here? Come help us - improve this doc.
top
@@ -187,19 +143,19 @@ $ cd httpd-NN (be sure the directory names do not have version numbers; for example, the APR distribution must be under /httpd_source_tree_root/srclib/apr/) and use ./configure's --with-included-apr - option. On some platforms, you may have to install the + option. On some platforms, you may have to install the corresponding -dev packages to allow httpd to build against your installed copy of APR and APR-Util. -
Perl-Compatible Regular Expressions Library (PCRE)
-
This library is required but no longer bundled with httpd. - Download the source code from https://www.pcre.org, - or install a Port or Package. If your build system can't find - the pcre-config script installed by the PCRE build, point to it - using the --with-pcre parameter. On some platforms, +
Perl-Compatible Regular Expressions Library (PCRE2)
+
This library is required but not bundled with httpd. + Download the source code from https://github.com/PCRE2Project/pcre2 + or install it from your system's package manager. If your build system can't find + the pcre2-config script installed by the PCRE2 build, + point to it using the --with-pcre parameter. On some platforms, you may have to install the corresponding -dev - package to allow httpd to build against your installed copy - of PCRE.
+ package (e.g. libpcre2-dev or pcre2-devel) + to allow httpd to build against your installed copy of PCRE2.
Disk Space
Make sure you have at least 200 MB of temporary free disk @@ -218,13 +174,11 @@ $ cd httpd-NN basic build tools such as make.
Accurate time keeping
-
Elements of the HTTP protocol are expressed as the time of - day. So, it's time to investigate setting some time - synchronization facility on your system. Most modern Linux - distributions provide systemd-timesyncd or - chrony for this purpose. See the NTP - homepage for more details about NTP software and public - time servers.
+
HTTP protocol headers use timestamps, so your system clock + must be accurate. Most Linux distributions enable + systemd-timesyncd or chrony by + default. Verify that time synchronization is active on your + system before running a production server.
Perl 5 [OPTIONAL]
@@ -239,16 +193,13 @@ $ cd httpd-NN

Download

-

If you wish to build from source, start by downloading - the source tarball from the Apache HTTP Server - download site. The build process (described below) - allows you to customize your server to suit your - needs.

+

Download the source tarball from the Apache HTTP Server + download site.

After downloading, it is important to verify that you have a complete and unmodified version of the Apache HTTP Server. This can be accomplished by testing the downloaded tarball against the - PGP signature. Details on how to do this are available on the + PGP signature. Details on how to do this are available on the verification page.

@@ -269,11 +220,11 @@ $ cd httpd-NN

Configuring the source tree

-

The next step is to configure the Apache source tree for your +

The next step is to configure the httpd source tree for your particular platform and personal requirements. This is done using the script configure included in the root directory of the distribution. (Developers downloading - an unreleased version of the Apache source tree will need to have + an unreleased version of the httpd source tree will need to have autoconf and libtool installed and will need to run buildconf before proceeding with the next steps. This is not necessary for official releases.)

@@ -284,14 +235,14 @@ $ cd httpd-NN and command line options.

The most important option is the location --prefix - where Apache is to be installed later, because Apache has to be - configured for this location to work correctly. More fine-tuned + where httpd is to be installed later, because httpd has to be + configured for this location to work correctly. More fine-tuned control of the location of files is possible with additional configure options.

Also at this point, you can specify which features you - want included in Apache by enabling and disabling modules. Apache comes with a wide range of modules - included by default. They will be compiled as + want included in httpd by enabling and disabling modules. httpd comes with a wide range of modules + included by default. They will be compiled as shared objects (DSOs) which can be loaded or unloaded at runtime. You can also choose to compile modules statically by using the option @@ -301,21 +252,21 @@ $ cd httpd-NN --enable-module option, where module is the name of the module with the mod_ string removed and with any underscore converted - to a dash. Similarly, you can disable modules with the - --disable-module option. Be careful when + to a dash. Similarly, you can disable modules with the + --disable-module option. Be careful when using these options, since configure cannot warn you if the module you specify does not exist; it will ignore the option.

In addition, it is sometimes necessary to provide the configure script with extra information about the - location of your compiler, libraries, or header files. This is + location of your compiler, libraries, or header files. This is done by passing either environment variables or command line - options to configure. For more information, see the + options to configure. For more information, see the configure manual page. Or invoke configure using the --help option.

For a short impression of what possibilities you have, here - is a typical example which compiles Apache for the installation + is a typical example which compiles httpd for the installation tree /sw/pkg/apache with a particular compiler and flags plus the two additional modules mod_ldap and mod_lua:

@@ -336,10 +287,11 @@ $ cd httpd-NN

Build

-

Now you can build the various parts which form the Apache +

Now you can build the various parts which form the httpd package by running:

-

$ make

+
$ make
+

Please be patient here, since a base configuration takes several minutes to compile and the time will vary widely @@ -353,7 +305,8 @@ $ cd httpd-NN installation PREFIX (see --prefix option above) by running:

-

$ make install

+
$ make install
+

This step will typically require root privileges, since PREFIX is usually a directory with restricted write @@ -365,23 +318,24 @@ $ cd httpd-NN

Customize

-

Next, you can customize your Apache HTTP server by editing +

Next, you can customize your Apache HTTP Server by editing the configuration files under PREFIX/conf/.

-

$ vi PREFIX/conf/httpd.conf

+
$ vi PREFIX/conf/httpd.conf
+
-

Have a look at the Apache manual under +

Have a look at the httpd manual under PREFIX/docs/manual/ or consult https://httpd.apache.org/docs/trunk/ for the most recent version of this manual and a complete reference of available configuration directives.

top

Test

-

Now you can start your Apache - HTTP server by immediately running:

+

Now you can start your Apache HTTP Server by immediately running:

-

$ PREFIX/bin/apachectl -k start

+
$ PREFIX/bin/apachectl -k start
+

You should then be able to request your first document via the URL http://localhost/. The web page you see is located @@ -390,27 +344,28 @@ $ cd httpd-NN Then stop the server again by running:

-

$ PREFIX/bin/apachectl -k stop

+
$ PREFIX/bin/apachectl -k stop
+
top

Upgrading

The first step in upgrading is to read the release announcement and the file CHANGES in the source distribution to - find any changes that may affect your site. When changing between + find any changes that may affect your site. When changing between major releases (for example, from 2.4 to 2.6), there will likely be major differences in the compile-time and - run-time configuration that will require manual adjustments. All + run-time configuration that will require manual adjustments. All modules will also need to be upgraded to accommodate changes in the module API.

Upgrading from one minor version to the next (for example, from - 2.4.66 to 2.4.67) is easier. The make install + 2.4.66 to 2.4.67) is easier. The make install process will not overwrite any of your existing documents, log - files, or configuration files. In addition, the developers make + files, or configuration files. In addition, the developers make every effort to avoid incompatible changes in the configure options, run-time configuration, or the - module API between minor versions. In most cases you should be able to + module API between minor versions. In most cases you should be able to use an identical configure command line, an identical configuration file, and all of your modules should continue to work.

@@ -418,9 +373,9 @@ $ cd httpd-NN

To upgrade across minor versions, start by finding the file config.nice in the build directory of your installed server or at the root of the source tree for your - old install. This will contain the exact + old install. This will contain the exact configure command line that you used to - configure the source tree. Then to upgrade from one version to + configure the source tree. Then to upgrade from one version to the next, you need only copy the config.nice file to the source tree of the new version, edit it to make any desired changes, and then run:

@@ -433,7 +388,7 @@ $ PREFIX/bin/apachectl -k start
You should always test any new version in your - environment before putting it into production. For example, you + environment before putting it into production. For example, you can install and run the new version along side the old one by using a different --prefix and a different port (by adjusting the Listen directive) to test for any @@ -443,32 +398,54 @@ $ PREFIX/bin/apachectl -k start which will be appended to your original configure options:

-

- $ ./config.nice --prefix=/home/test/apache --with-port=90 -

+
$ ./config.nice --prefix=/home/test/apache --with-port=90
+
top

Third-party packages

-

A large number of third parties provide their own packaged - distributions of the Apache HTTP Server for installation on - particular platforms. This includes the various Linux distributions, - various - Windows - packages, macOS, and many more.

+

Many operating systems ship pre-built Apache httpd packages. + These are convenient for getting started quickly, but they often + differ from a source build in configuration file layout, + compiled-in modules, and default paths. The documentation on this + site describes the server as built from source; if you are using a + platform package, consult your distribution's documentation for + platform-specific details.

+ +

Some common examples:

+ +
+
Fedora / CentOS / Red Hat Enterprise Linux
+
+
sudo dnf install httpd
+sudo systemctl start httpd
+ +

See the + Fedora project's documentation for configuration layout and + platform-specific notes.

+
+ +
Ubuntu / Debian
+
+
sudo apt install apache2
+sudo systemctl start apache2
+ +

See Ubuntu's + documentation for configuration layout and + platform-specific notes.

+
+

Our software license not only permits, but encourages, this kind of redistribution. However, it does result in a situation where the configuration layout and defaults on your installation of the server - may differ from what is stated in the documentation. While - unfortunate, this situation is not likely to change any time - soon.

- -

A description - of these third-party distributions is in the HTTP - Server wiki. However, you will need to familiarize - yourself with your particular platform's package management and - installation procedures.

+ may differ from what is stated in the documentation. A description + of these third-party distributions is available in the HTTP + Server wiki.

+ +
Don't see your favorite platform mentioned + here? Come help us + improve this doc.
diff --git a/docs/manual/install.html.fr.utf8 b/docs/manual/install.html.fr.utf8 index c008f593ee9..ff8cb9449a1 100644 --- a/docs/manual/install.html.fr.utf8 +++ b/docs/manual/install.html.fr.utf8 @@ -32,25 +32,24 @@  pt-br  |  tr 

-
Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
-

Ce document couvre l'installation et la compilation du serveur - HTTP Apache - sur les systèmes Unix et similaires seulement. Pour la compilation et - l'installation sous Windows, voir Utiliser le serveur HTTP Apache avec Microsoft - Windows et Compilation - d'Apache sous Microsoft Windows. Pour les autres plateformes, se - référer à la documentation par - plateforme.

+

Le serveur HTTP Apache est distribué sous forme de code source. Ce + document décrit la construction et l’installation du serveur à partir des + sources sous Unix et les systèmes de la famille d’Unix. Pour Windows, voir + Utiliser le serveur HTTP Apache avec + Microsoft Windows et Compilation + de httpd sous Microsoft Windows. Pour les autres plateformes, se + référer à la documentation par plateforme.

-

Apache httpd utilise libtool et autoconf - afin de créer un environnement de construction similaire à la plupart - des projets Open Source .

+

Si vous installez httpd depuis un paquet de distribution (RPM, DEB, + etc.), l’organisation de la configuration et les valeurs par défaut peuvent + être différentes de ce qui est décrit ici. Voir paquets + tiers ci-après et consultez la documentation de votre distribution pour + les détails spécifiques à la plateforme.

Si vous effectuez une mise à jour depuis une version mineure vers - la suivante (par exemple, 2.4.8 à 2.4.9), veuillez passer à la section + la suivante (par exemple, 2.4.66 à 2.4.67), veuillez passer à la section mise à jour.

@@ -66,52 +65,26 @@
  • Mise à jour
  • Paquets tiers
  • Voir aussi

    + des sources
  • Démarrer httpd
  • Arrêt et redémarrage
  • top

    Aperçu pour les plus pressés

    -
    -
    Installation sous Fedora/CentOS/Red Hat Enterprise Linux
    -
    -
    sudo dnf install httpd
    -sudo service httpd start
    - - -
    Les anciennes versions de ces distributions utilisent - yum au lieu de dnf. Voir la documentation du - projet Fedora pour des informations spécifiques à cette plateforme.
    -
    - -
    Installation sous Ubuntu/Debian
    -
    -
    sudo apt install apache2
    -sudo service apache2 start
    - - -
    Voir la documentation - Ubuntu pour des informations spécifiques à cette plateforme.
    - -
    - -
    Installation à partir des sources
    -
    -
    - + - + @@ -156,27 +129,20 @@ sudo service apache2 start

    Chaque étape du processus de compilation et d'installation est décrite plus en détails ci-dessous, à commencer par les prérequis - pour compiler et installer Apache httpd.

    - - - -
    L'installation sous votre plateforme favorite n'est pas - traitée ici ? N'hésitez pas à nous aider à compléter cette - documentation en nous faisant profiter de votre expérience.
    - - + pour compiler et installer httpd.

    top

    Prérequis

    -

    Les prérequis pour la construction d'Apache httpd sont les suivants:

    +

    Les prérequis pour la construction et l’exécution de httpd sont les + suivants:

    APR et APR-Util
    APR et APR-Util doivent être déjà installés sur votre système. Si ce n'est pas le cas, ou si vous préférez ne pas utiliser les versions fournies par le système, téléchargez les dernières - versions d'APR et APR-Util depuis Apache APR, décompressez-les + versions d'APR et APR-Util depuis Apache APR, décompressez-les respectivement dans /racine_sources_httpd/srclib/apr et /racine_sources_httpd/srclib/apr-util (les noms des répertoires ne doivent pas comporter de numéros de versions ; par exemple, la @@ -188,87 +154,70 @@ sudo service apache2 start installées d'APR et APR-Util.
    Bibliothèque d'expressions rationnelles compatibles Perl - (PCRE)
    -
    Cette bibliothèque est nécessaire mais n'est plus fournie avec la - distribution de httpd. Téléchargez le code source depuis http://www.pcre.org ou installez - un portage du paquet. Si votre suite de compilation ne trouve pas - le script pcre-config installé au cours du processus de - construction de PCRE, indiquez son chemin via l'option - --with-pcre du script ./configure. Sur - certaines plateformes, vous devrez - peut-être installer les paquets -dev correspondants - pour permettre la compilation de httpd avec la version - installée de PCRE.
    + (PCRE2) +
    Cette bibliothèque est nécessaire mais n'est pas fournie avec la + distribution de httpd. Téléchargez le code source depuis https://github.com/PCRE2Project/pcre2 + ou installez le avec le gestionnaire de paquets de votre système. Si votre + système de construction ne trouve pas le script pcre2-config + installé par la construction de PCRE2, pointez vers lui en utilisant + l’option --with-pcre. Sur certaines plateformes, vous devrez + peut-être installer le paquet -dev correspondant (par exemple + libpcre2-dev ou pcre2-devel) pour permettre la + construction de httpd avec votre version installée de PCRE2.
    Espace disque
    -
    Assurez-vous d'avoir au moins 50 Mo d'espace disque disponible +
    Assurez-vous d'avoir au moins 200 Mo d'espace disque disponible temporaire. Après l'installation le serveur occupe - approximativement 10 Mo d'espace disque. L'espace disque réellement + approximativement 50 Mo d'espace disque. L'espace disque réellement nécessaire va varier considérablement en fonction de vos options de configuration, de la présence éventuelle de modules tiers, et bien entendu de la taille de votre site web et des sites que vous hébergez sur votre serveur.
    Compilateur ANSI-C et système de construction
    -
    Vous devez disposer d'un compilateur ANSI-C. Le compilateur GNU C (GCC) de la Free Software Foundation (FSF) +
    Vous devez disposer d'un compilateur ANSI-C. Le compilateur GNU C (GCC) de la Free Software Foundation (FSF) est recommandé. Si vous ne possédez pas GCC, assurez-vous au moins que votre compilateur soit compatible ANSI. En outre, votre PATH doit contenir les outils de construction de base tels que make.
    Connaissance de l'heure exacte
    -
    Les éléments du protocole HTTP font référence à l'heure du jour. - Par conséquent, il est nécessaire d'équiper votre système d'un - dispositif de synchronisation du temps. Les programmes - ntpdate ou xntpd, basés sur le protocole NTP, - sont couramment utilisés à cet effet. - Voir la page d'accueil de NTP - pour plus de détails à propos du logiciel NTP et des serveurs - de temps publics.
    - -
    Perl 5 +
    Les entêtes du protocole HTTP utilisent un horodatage ; l’horloge de + votre système doit donc être précise. La plupart des distributions de + Linux activent systemd-timesyncd ou chrony par + défaut. Vérifiez que la synchronisation du temps est active sur votre + système avant d’exploiter un serveur en production.
    + +
    Perl 5 [OPTIONNEL]
    -
    L'interpréteur Perl 5 (les versions 5.003 ou supérieures conviennent) - est nécessaire pour l'exécution de certains scripts comme - apxs ou dbmmanage - (qui sont écrits en Perl). - Si le script configure ne trouve pas d'interpréteur - Perl 5, vous ne pourrez pas utiliser les scripts qui en ont besoin. - Bien entendu, vous pourrez tout de même construire et utiliser - Apache httpd.
    +
    L'interpréteur Perl 5 est nécessaire pour l'exécution de certains + scripts comme apxs ou dbmmanage (qui + sont écrits en Perl). Si le script configure ne trouve + pas d'interpréteur Perl 5, vous ne pourrez pas utiliser les scripts qui en + ont besoin. Bien entendu, vous pourrez tout de même construire et + utiliser httpd.
    top

    Téléchargement

    -

    Le serveur HTTP Apache peut être téléchargé à partir du - site de téléchargement - du serveur HTTP Apache, qui fournit la liste de nombreux miroirs. - Il sera plus commode à la plupart des utilisateurs d'Apache sur les - systèmes UNIX ou similaires de télécharger et de compiler - la version sources. Le processus de construction (décrit ci-dessous) est - simple, et vous permet de personnaliser votre serveur selon vos besoins. - En outre, les versions binaires sont souvent plus anciennes que les - dernières versions sources. Si vous téléchargez une version binaire, - suivez les instructions décrites dans le fichier - INSTALL.bindist inclus dans la distribution.

    - -

    Après le téléchargement, il est important de vérifier que vous - disposez d'une version complète et non modifiée du serveur HTTP Apache. - Vous pouvez le faire en testant l'archive téléchargée à l'aide de - la signature PGP. Vous trouverez les détails de cette opération sur la page de téléchargement ainsi qu'un exemple précis décrivant l'utilisation de - PGP.

    +

    Téléchargez l’archive tar du code source depuis le site de téléchargement du + serveur HTTP Apache.

    + +

    Après le téléchargement, il est important de vérifier que vous disposez + d'une version complète et non modifiée du serveur HTTP Apache. Vous pouvez + le faire en testant l'archive téléchargée à l'aide de la signature PGP. Vous + trouverez les détails de cette opération sur la page de + vérification.

    top

    Extraction

    -

    L'extraction des sources depuis l'archive du serveur HTTP Apache consiste - simplement à décompresser et à désarchiver cette dernière :

    +

    Extraire les sources depuis l'archive du serveur HTTP Apache :

    -
    $ gzip -d httpd-NN.tar.gz
    -$ tar xvf httpd-NN.tar
    +
    $ tar xzf httpd-NN.tar.gz

    Ceci créera, dans le répertoire courant, un nouveau répertoire @@ -279,45 +228,41 @@ $ tar xvf httpd-NN.tar

    Configuration de l'arborescence des sources

    L'étape suivante consiste à configurer l'arborescence des sources - d'Apache en fonction de votre plateforme et de vos besoins personnels. - Le script configure, situé à la racine du - répertoire de la distribution, a été conçu à cet effet - (Les développeurs qui téléchargent - une version non officielle de l'arborescence des sources d'Apache - devront disposer de - autoconf et libtool et - exécuter buildconf avant de passer à l'étape suivante, - ce qui n'est pas nécessaire pour les versions officielles).

    + de httpd en fonction de votre plateforme et de vos besoins personnels. + Le script configure, situé à la racine du répertoire de + la distribution, a été conçu à cet effet (Les développeurs qui téléchargent + une version non officielle de l'arborescence des sources de httpd + devront disposer de autoconf et libtool et + exécuter buildconf avant de passer à l'étape suivante, ce qui + n'est pas nécessaire pour les versions officielles).

    Pour configurer l'arborescence des sources avec les valeurs par défaut - pour toutes les options, entrez simplement ./configure. + pour toutes les options, saisissez ./configure. Pour modifier les valeurs des options, configure accepte toute une variété de variables et d'options de ligne de commande.

    -

    L'option la plus importante --prefix est le chemin - du répertoire d'installation d'Apache, car Apache doit être configuré - en fonction de ce chemin pour pouvoir fonctionner correctement. - Il est possible de définir plus finement le chemin d'installation des fichiers - à l'aide d'options +

    L'option la plus importante --prefix est le chemin du + répertoire d'installation de httpd, car httpd doit être + configuré en fonction de ce chemin pour pouvoir fonctionner correctement. + Il est possible de définir plus finement le chemin d'installation des + fichiers à l'aide d'options supplémentaires de configure.

    À ce niveau, vous pouvez aussi spécifier de quelles fonctionnalités vous - voulez disposer dans Apache en activant ou désactivant des modules. Apache est fourni avec un grand nombre de - modules inclus par défaut. Ils seront compilés en tant qu'objets partagés (DSOs) qui pourront être chargés - ou déchargés à l'exécution. Vous pouvez aussi choisir de compiler - les modules statiquement via l'option - --enable-module=static.

    -

    Des modules supplémentaires peuvent être activés à l'aide de l'option - --enable-module, où - module est le nom du module sans la chaîne - mod_ et où tout caractère de soulignement est converti - en tiret. D'une manière similaire, - vous pouvez désactiver des modules à l'aide de l'option - --disable-module. Faites très attention - en utilisant ces options, car configure n'est pas en - mesure de vous avertir si le module que vous avez spécifié n'existe pas; - il ignorera tout simplement l'option.

    + voulez disposer dans httpd en activant ou désactivant des modules. httpd est fourni avec un grand nombre de + modules inclus par défaut. Ils seront compilés en tant qu'objets partagés (DSOs) qui pourront être chargés ou + déchargés à l'exécution. Vous pouvez aussi choisir de compiler les modules + statiquement via l'option + --enable-module=static.

    Des modules + supplémentaires peuvent être activés à l'aide de l'option + --enable-module, où module est le nom du + module sans la chaîne mod_ et où tout caractère de soulignement + est converti en tiret. D'une manière similaire, vous pouvez désactiver des + modules à l'aide de l'option --disable-module. + Faites très attention en utilisant ces options, car + configure n'est pas en mesure de vous avertir si le + module que vous avez spécifié n'existe pas ; il ignorera l'option.

    En outre, vous devrez peut-être fournir au script configure des informations supplémentaires sur @@ -330,7 +275,7 @@ $ tar xvf httpd-NN.tar

    Pour vous faire une idée des possibilités qui s'offrent à vous, voici - un exemple typique de compilation d'Apache avec le répertoire + un exemple typique de compilation de Apache httpd avec le répertoire d'installation /sw/pkg/apache, un compilateur et des drapeaux particuliers et les deux modules additionnels mod_ldap et mod_lua :

    @@ -354,9 +299,10 @@ $ tar xvf httpd-NN.tar

    Construction

    Vous pouvez maintenant construire les différents éléments qui - composent le paquet Apache en lançant tout simplement la commande :

    + composent le paquet Apache httpd en lançant :

    -

    $ make

    +
    $ make
    +

    Vous devez être patient, car il faut plusieurs minutes pour compiler une configuration de base, et cette durée peut varier considérablement @@ -369,7 +315,8 @@ $ tar xvf httpd-NN.tar d'installation défini par PREFIX (voir plus haut l'option --prefix) en lançant:

    -

    $ make install

    +
    $ make install
    +

    Cette étape nécessite habituellement les privilèges de root, car PREFIX est en général un @@ -386,20 +333,22 @@ $ tar xvf httpd-NN.tar éditant les fichiers de configuration situés dans PREFIX/conf/.

    -

    $ vi PREFIX/conf/httpd.conf

    +
    $ vi PREFIX/conf/httpd.conf
    +
    -

    Consultez le manuel d'Apache situé dans +

    Consultez le manuel de httpd situé dans PREFIX/docs/manual/ ou - http://httpd.apache.org/docs/trunk/ pour la version la plus + https://httpd.apache.org/docs/trunk/ pour la version la plus récente de ce manuel et la liste complète des directives de configuration disponibles.

    top

    Test

    Vous pouvez maintenant démarrer votre - serveur HTTP Apache en lançant:

    + Serveur HTTP Apache en lançant :

    -

    $ PREFIX/bin/apachectl -k start

    +
    $ PREFIX/bin/apachectl -k start
    +

    Vous devriez alors pouvoir requérir votre premier document à l'aide de l'URL http://localhost/. La page web que vous @@ -408,24 +357,23 @@ $ tar xvf httpd-NN.tar qui est généralement PREFIX/htdocs/. Pour arrêter le serveur, lancez:

    -

    $ PREFIX/bin/apachectl -k stop

    +
    $ PREFIX/bin/apachectl -k stop
    +
    top

    Mise à jour

    La première étape d'une mise à jour consiste à lire l'annonce de la - sortie de la nouvelle version et le fichier CHANGES - dans la distribution des sources afin de déceler toutes les modifications - qui pourraient affecter votre site. Lors d'un changement majeur de version - (par exemple de 2.0 à 2.2 ou de 2.2 à 2.4), - il y aura certainement des différences importantes quant à la - configuration de la compilation et de l'exécution qui nécessiteront des - ajustements manuels. Tous les - modules devront aussi être mis à jour pour qu'ils s'adaptent aux - changements de l'API des modules.

    + sortie de la nouvelle version et le fichier CHANGES dans la + distribution des sources afin de déceler toutes les modifications qui + pourraient affecter votre site. Lors d'un changement majeur de version (par + exemple de 2.4 à 2.6), il y aura certainement des différences importantes + quant à la configuration de la compilation et de l'exécution qui + nécessiteront des ajustements manuels. Tous les modules devront aussi être + mis à jour pour qu'ils s'adaptent aux changements de l'API des modules.

    La mise à jour d'une version mineure à la suivante (par exemple, de - 2.2.55 à 2.2.57) est plus aisée. Le processus make install + 2.4.66 à 2.4.67) est plus aisée. Le processus make install n'écrasera aucun de vos documents existants, fichiers de log, ou fichiers de configuration. De plus, les développeurs font tout leur possible pour éviter les changements entraînant une @@ -467,31 +415,56 @@ $ PREFIX/bin/apachectl -k start config.nice ; ils seront alors ajoutés aux options de votre script configure original :

    -

    - $ ./config.nice --prefix=/home/test/apache --with-port=90 -

    +
    $ ./config.nice --prefix=/home/test/apache --with-port=90
    +
    top

    Paquets tiers

    -

    De nombreux tiers fournissent leur propre distribution du - serveur HTTP Apache à installer sur une plate-forme particulière. On - peut citer les différentes distributions Linux, divers - paquets tiers Windows, Mac OS X, Solaris et de nombreux autres.

    - -

    Notre license logicielle non seulement permet, mais aussi - encourage ce genre de redistribution. Cependant, ceci conduit à une - situation ou l'organisation de la configuration et les valeurs par - défaut de votre installation du serveur peuvent ne pas correspondre - à ce qui est écrit dans la documentation. Bien que fâcheuse, cette - situation n'est pas appelée à évoluer de sitôt.

    - -

    Une description - de ces distributions tierces est maintenue dans le wiki du - serveur HTTP, et doit en refléter l'état actuel. Vous devrez - cependant vous familiariser par vous-même avec la gestion du paquet - de votre plate-forme particulière et les procédures d'installation.

    +

    De nombreux systèmes d’exploitation fournissent des paquets Apache httpd + préconstruits. Ces paquets permettent de démarrer rapidement, mais ils + diffèrent souvent d’une construction à partir des sources quant à + l’organisation du fichier de configuration, aux modules intégrés et aux + chemins par défaut. La documentation sur ce site décrit la construction du + serveur à partir des sources ; si vous utilisez un paquet de plateforme, + consultez la documentation de votre distribution pour les détails + spécifiques à la plateforme.

    + +

    Quelques exemples courants :

    + +
    +
    Fedora / CentOS / Red Hat Enterprise Linux
    +
    +
    sudo dnf install httpd
    +sudo systemctl start httpd
    + +

    Voir la + documentation du projet Fedora pour l’organisation de la configuration + et des notes spécifiques à la plateforme.

    +
    + +
    Ubuntu / Debian
    +
    +
    sudo apt install apache2
    +sudo systemctl start apache2
    + +

    Voir documentation + d’Ubuntu pour l’organisation de la configuration + et des notes spécifiques à la plateforme.

    +
    +
    + +

    Notre licence logicielle non seulement permet, mais aussi encourage ce + genre de distribution tierce. Cependant, cela conduit à une situation ou + l'organisation de la configuration et les valeurs par défaut de votre + installation du serveur peuvent ne pas correspondre à ce qui est écrit dans + la documentation. Une description + de ces distributions tierces est disponible dans le wiki du serveur + HTTP.

    + +
    Votre plateforme favorite n’est pas mentionnée ici ? Voilà une bonne occasion pour + vous d’améliorer cette documentation.
    diff --git a/docs/manual/install.xml b/docs/manual/install.xml index c0073c5f6e6..2ac56465921 100644 --- a/docs/manual/install.xml +++ b/docs/manual/install.xml @@ -5,11 +5,11 @@ + - + + + + + - + + + + @@ -28,145 +27,243 @@ Standards applicables -

    Cette page documente tous les standards applicables que suit le - serveur HTTP Apache, accompagnés d'une brève description.

    +

    Cette page documente les standards applicables que le serveur HTTP Apache + implémente ou suit, avec une brève description.

    Pour compléter les informations fournies ci-dessous, vous pouvez consulter les ressources suivantes :

    - Avertissement -

    Ce document n'est pas encore finalisé.

    -
    -
    -
    Recommandations HTTP +
    HTTP

    Sans tenir compte des modules compilés et utilisés, Apache en - tant que serveur web de base respecte les recommandations IETF + tant que serveur web de base respecte les normes IETF suivantes :

    +
    9110 + (Série de standards) — Sémantique de HTTP
    + +
    Cette norme définit la sémantique partagée par toutes les versions de + HTTP : méthodes, codes d’état, champs d’en-tête et de fin de page, + négociation sur le contenu et métadonnées des messages. Elle rend + obsolètes les RFC 7231, 7232, 7233, 7235 et 7694.
    + +
    9111 + (Série de standards) — Mise en cache HTTP
    + +
    Cette norme définit les caches HTTP et les champs d’en-tête HTTP + associés qui contrôlent le comportement du cache ou indiquent des réponses + pouvant être mises en cache. Elle rend obsolète la RFC 7234.
    + +
    9112 + (Série de standards) — HTTP/1.1
    + +
    Cette norme définit la syntaxe des messages et la gestion des + connexions avec HTTP/1.1. Elle rend obsolète la RFC 7230.
    + +
    9113 + (Série de standards) — HTTP/2
    + +
    Cette norme définit et optimise l’expression de la sémantique de HTTP + en utilisant le cadrage binaire (binary framing) et des flux multiplexés + sur une seule connexion TCP. Elle rend obsolètes les RFC 7540 et 8740.
    + +
    9114 + (Série de standards) — HTTP/3
    + +
    Cette norme définit le mappage de la sémantique HTTP sur QUIC, tout en + fournissant des fonctionnalités similaires à HTTP/2 avec une latence + réduite.
    +
    1945 - (Informations)
    + (Informations) — HTTP/1.0 -
    Le Protocole de Transfert Hypertexte (Hypertext Transfer - Protocol - HTTP) est un protocole de niveau application avec la - clarté et la vitesse nécessaires pour les systèmes d'informations - distribués, collaboratifs et hypermédia. Cette RFC documente le - protocole HTTP/1.0.
    +
    La spécification HTTP/1.0 originale. Conservée à titre de référence + historique ; httpd accepte encore les requêtes HTTP/1.0.
    +
    -
    2616 - (Série de standards)
    +
    -
    Le Protocole de Transfert Hypertexte (Hypertext Transfer - Protocol - HTTP) est un protocole de niveau application pour les - systèmes d'informations distribués, collaboratifs et hypermédia. - Cette RFC documente le protocole HTTP/1.1.
    +
    URIs -
    2396 - (Série de standards)
    +
    +
    3986 + (Série de standards) — Uniform Resource Identifier (URI): Syntaxe + générique
    -
    Un Identificateur de Ressource Uniforme (Uniform Resource - Identifier - URI) est une chaîne de caractères compacte permettant - d'identifier une ressource physique ou abstraite.
    +
    La syntaxe générique et les règles de résolution des URIs. Cette norme + rend obsolète la RFC 2396.
    -
    4346 - (Série de standards)
    +
    6570 + (Série de standards) — Modèle d’URI
    -
    Le protocole TLS permet l'utilisation de communications - sécurisées sur l'Internet. Il fournit le chiffrement, et a été - conçu pour se prémunir contre l'interception, la modification et - la falsification de messages.
    +
    Cette norme définit une séquence compacte de caractères pour décrire + une gamme d’URIs à l’aide d’un développement de variable.
    -
    Recommandations HTML +
    TLS/SSL -

    En ce qui concerne le langage HTML, Apache respecte les - recommandations IETF et W3C suivantes :

    +

    Les normes suivantes s’appliquent lorsque mod_ssl est + activé :

    -
    2854 - (Informations)
    - -
    Ce document résume l'historique du développement de HTML, et - définit le type MIME "text/html" en pointant les recommandations - W3C correspondantes.
    - -
    Spécification HTML - 4.01 - (Corrections - Erreurs) -
    - -
    Cette spécification définit le Langage à Balises HyperTexte - (HyperText Markup Language - HTML), le langage de publication du - World Wide Web. Elle définit HTML 4.01, qui est une sous-version - de HTML 4.
    - -
    Référence HTML - 3.2
    - -
    Le langage à Balises HyperTexte (HyperText Markup Language - - HTML) est un langage à balises simple permettant de créer des - documents hypertextes portables. Les documents HTML sont aussi des - documents SGML.
    - -
    XHTML 1.1 - - XHTML sous forme de modules - (Corrections - d'erreurs) -
    - -
    Cette recommandation définit un nouveau type de document XHTML - basé sur le cadre de développement des modules et les modules - définis dans la modularisation de XHTML.
    - -
    XHTML 1.0, le Langage à - Balises Hypertexte Extensible (Extensible HyperText Markup - Language) - Seconde édition - (Corrections - d'erreurs) -
    - -
    Cette spécification définit la seconde édition de XHTML 1.0, - une reformulation de HTML 4 en tant qu'application XML 1.0, ainsi - que trois DTDs correspondant à celles définies par HTML 4.
    +
    8446 + (Série de standards) — TLS 1.3
    + +
    La version actuelle du protocole TLS (Transport Layer Security) + assurant la confidentialité des communications sur l’Internet. Cette norme + rend obsolète la RFC 5246 (texte de la spécification de TLS 1.2).
    + +
    5246 + (Série de standards) — TLS 1.2
    + +
    La version précédente de TLS largement déployée. Encore prise en + charge par httpd pour une compatibilité avec les clients anciens.
    + +
    6960 + (Série de standards) — OCSP
    + +
    Le protocole OCSP (Online Certificate Status Protocol) utilisé pour + vérifier l’état de révocation des certificats en temps réel (l’agrafage + OCSP - OCSP stapling - à l’aide de la directive SSLStaplingCache).
    + +
    6066 + (Série de standards) — TLS Extensions
    + +
    Cette norme définit les extensions de TLS, dont SNI (Server Name + Indication) qu’utilise httpd pour les serveurs virtuels à base de nom sur + TLS.
    -
    Authentification +
    Authentication + +

    À propos des différentes méthodes d’authentification :

    + +
    +
    7617 + (Série de standards) — Le schéma d’authentification « basique » de HTTP
    -

    En ce qui concerne les différentes méthodes d'authentification, - Apache respecte les recommandations IETF suivantes :

    +
    L’authentification basique de HTTP qui transmet les données + d’authentification sous la forme de paires identifiant utilisateur/mot de + passe encodées en Base64. Cette norme rend obsolète la RFC 2617 (la + portion basique de auth).
    + +
    7616 + (Série de standards) — L’authentification de l’accès par condensés de HTTP
    + +
    L’authentification par condensés de HTTP qui fournit un mécanisme de + question-réponse qui évite de transmettre le mot de passe en clair. Cette + norme rend obsolète la RFC 2617 (portion condensé de auth).
    +
    + +
    + +
    Négociation de contenu et compression
    -
    2617 - (Série de standards)
    +
    9110 - Négociation de contenu
    + +
    La négociation de contenu proactive et réactive à l’aide des champs + d’en-tête Accept, Accept-Language, Accept-Encoding et Accept-Charset.
    + +
    7932 + (Informations) — Brotli Compressed Data Format
    + +
    Cette norme définit l’algorithme de compression Brotli pris en charge + par le module mod_brotli.
    +
    + +
    + +
    Mandat et redirection + +

    Quand mod_proxy est activé :

    + +
    +
    7239 + (Série de standards) — L’extension HTTP Forwarded
    + +
    Cette norme définit le champ d’en-tête Forwarded pour le transport des + informations à propos de la face côté client des serveurs mandataires.
    + +
    9209 + (Série de standards) — Le champ d’en-tête de réponse HTTP Proxy-Status
    + +
    Cette norme définit un mécanisme permettant aux mandataires de + communiquer les détails de la gestion intermédiaire au client.
    + +
    9220 + (Série de standards) — « Bootstrapping » des WebSockets avec HTTP/2
    + +
    Cette norme définit un mécanisme permettant d’utiliser le protocole + WebSocket sur un seul flux HTTP/2.
    +
    + +
    + +
    WebSocket + +
    +
    6455 + (Série de standards) — The WebSocket Protocol
    + +
    Cette norme définit le protocole WebSocket qui permet une + communication bidirectionnelle entre un client et un serveur sur une seule + connexion TCP. Il est pris en charge par le module + mod_proxy_wstunnel.
    +
    + +
    + +
    CGI + +
    +
    3875 + (Informations) — CGI (Common Gateway Interface) Version 1.1
    + +
    Cette norme définit l’interface CGI qui permet d’exécuter des + programmes externes sur un serveur web. Implémenté par les modules + mod_cgi et mod_cgid.
    +
    + +
    + +
    WebDAV + +

    Quand mod_dav est activé :

    + +
    +
    4918 + (Série de standards) — Extensions HTTP pour WebDav (Web Distributed + Authoring and Versioning)
    + +
    Cette norme définit des extensions à HTTP pour les opérations de + création distribuée. Elle rend obsolète la RFC 2518.
    + +
    3744 + (Série de standards) — Protocole de contrôle d’accès pour WebDAV (Web + Distributed Authoring and Versioning)
    -
    "HTTP/1.0", y compris la spécification d'un protocole - d'authentification et de contrôle d'accès basique.
    +
    Cette norme définit des extensions de contrôle d’accès pour WebDAV.
    @@ -175,11 +272,11 @@
    Codes de langages et de pays -

    Les liens suivants fournissent des informations à propos des - codes de langages et de pays aux normes ISO ou autres :

    +

    Les codes de langages et de pays utilisés dans la négociation de contenu + :

    -
    ISO 639-2
    +
    ISO 639-2
    ISO 639 fournit deux jeux de codes de langages permettant de représenter les noms des langues ; le premier est @@ -187,31 +284,25 @@ présenté dans le lien ci-dessus), est un jeu de codes sur trois lettres (639-2).
    -
    +
    ISO 3166-1
    -
    Ce document présente les noms de pays (les noms raccourcis - officiels en anglais) dans l'ordre alphabétique, tels qu'ils sont - présentés dans la norme ISO 3166-1 et les éléments de codes - correspondants de la norme ISO 3166-1-alpha-2.
    +
    Noms des pays et éléments de code correspondants à deux et trois + caractères.
    -
    BCP 47 (Les - meilleurs pratiques courantes), 3066
    +
    5646 + (Meilleure pratique actuelle) — Symboles pour identifier les langues
    -
    Ce document décrit une balise de langue permettant de - spécifier la langue utilisée dans un objet contenant des - informations, la manière d'enregistrer des valeurs à utiliser dans - cette balise de langue, et une méthode pour comparer les balises - de langue de ce style.
    +
    Cette norme décrit la structure et l’enregistrement des symboles de + langue utilisés dans la négociation de contenu de HTTP (Accept-Language, + Content-Language). Elle rend obsolète la RFC 3066.
    3282 (Série de standards)
    -
    Ce document définit une en-tête "Content-language:" permettant - de spécifier la langue d'un élément possédant des en-têtes du - style RFC 822, comme les portions de corps MIME ou les documents - Web, et un en-tête "Accept-Language:" permettant de spécifier des - préférences en matière de langue.
    +
    Cette norme définit les champs d’en-tête Content-Language and + Accept-Language qui indiquent les préférences en matière de langue dans + les messages HTTP.
    diff --git a/docs/manual/mod/allmodules.xml.fr b/docs/manual/mod/allmodules.xml.fr index f6c0d84dd53..451105616eb 100644 --- a/docs/manual/mod/allmodules.xml.fr +++ b/docs/manual/mod/allmodules.xml.fr @@ -88,7 +88,7 @@ mod_proxy.xml.fr mod_proxy_ajp.xml.fr mod_proxy_balancer.xml.fr - mod_proxy_beacon.xml + mod_proxy_beacon.xml.fr mod_proxy_connect.xml.fr mod_proxy_express.xml.fr mod_proxy_fcgi.xml.fr @@ -139,7 +139,7 @@ mod_xml2enc.xml.fr mpm_common.xml.fr event.xml.fr - motorz.xml + motorz.xml.fr mpm_netware.xml.fr mpmt_os2.xml.fr prefork.xml.fr diff --git a/docs/manual/mod/core.html.fr.utf8 b/docs/manual/mod/core.html.fr.utf8 index 798d0b2c1cf..1404cdff947 100644 --- a/docs/manual/mod/core.html.fr.utf8 +++ b/docs/manual/mod/core.html.fr.utf8 @@ -33,8 +33,6 @@  ja  |  tr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    TéléchargementTéléchargez la dernière version depuis http://httpd.apache.org/download.cgi - Téléchargez la dernière version depuis https://httpd.apache.org/download.cgi +
    Extraction$ gzip -d httpd-NN.tar.gz
    - $ tar xvf httpd-NN.tar
    - $ cd httpd-NN
    $ tar xzf httpd-NN.tar.gz
    +$ cd httpd-NN
    +
    Description:Fonctionnalités de base du serveur HTTP Apache toujours disponibles
    Statut:Noyau httpd
    @@ -577,16 +575,34 @@ autorisés à transiter dans les URLs tels quels suivi d'une liste d'options, séparées par des virgules (sans espaces), pouvant être définies à l'aide de la directive Options. -

    Désactivation implicite des options

    -

    Bien que la liste des options disponibles dans les fichiers - .htaccess puisse être limitée par cette directive, tant qu'un - directive Options est - autorisée, toute autre option héritée peut être désactivée en - utilisant la syntaxe non-relative. En d'autres termes, ce - mécanisme ne peut pas forcer une option spécifique à rester - activée tout en permettant à toute autre option d'être - activée. -

    +

    Désactivation implicite des options

    +

    Cette restriction ne contrôle que les options qu’un fichier + .htaccess peut activer. Elle n’empêche pas la + désactivation des options héritées.

    + +

    Lorsqu’une directive Options dans + un fichier .htaccess utilise une syntaxe absolue (sans + préfixe + ou -), elle remplace la + totalité du jeu d’options héritées. Toute option auparavant active qui + n’est pas listée est implicitement désactivée—il en est de même pour + les options qui ne sont pas dans la liste AllowOverride des + options permises.

    + +

    Par exemple, si la configuration définit :

    +
    Options Indexes FollowSymLinks ExecCGI
    +AllowOverride Options=Indexes
    + +

    et si un fichier .htaccess contient :

    +
    Options Indexes
    + +

    les options FollowSymLinks et ExecCGI seront + implicitement désactivée pour le répertoire concerné, même si la ligne + AllowOverride ne fait que permettre la définition de l’option + Indexes.

    + +

    En bref, ce mécanisme ne peut pas forcer une option spécifique à rester + définie tout en permettant la définition de toutes les autres.

    +
    AllowOverride Options=Indexes,MultiViews
    diff --git a/docs/manual/mod/core.xml.fr b/docs/manual/mod/core.xml.fr index d9a67b5d7d4..a6cbd45769a 100644 --- a/docs/manual/mod/core.xml.fr +++ b/docs/manual/mod/core.xml.fr @@ -1,7 +1,7 @@ - + @@ -517,16 +517,36 @@ autorisés à transiter dans les URLs tels quels pouvant être définies à l'aide de la directive Options. - Désactivation implicite des options -

    Bien que la liste des options disponibles dans les fichiers - .htaccess puisse être limitée par cette directive, tant qu'un - directive Options est - autorisée, toute autre option héritée peut être désactivée en - utilisant la syntaxe non-relative. En d'autres termes, ce - mécanisme ne peut pas forcer une option spécifique à rester - activée tout en permettant à toute autre option d'être - activée. -

    + Désactivation implicite des options +

    Cette restriction ne contrôle que les options qu’un fichier + .htaccess peut activer. Elle n’empêche pas la + désactivation des options héritées.

    + +

    Lorsqu’une directive Options dans + un fichier .htaccess utilise une syntaxe absolue (sans + préfixe + ou -), elle remplace la + totalité du jeu d’options héritées. Toute option auparavant active qui + n’est pas listée est implicitement désactivée—il en est de même pour + les options qui ne sont pas dans la liste AllowOverride des + options permises.

    + +

    Par exemple, si la configuration définit :

    + +Options Indexes FollowSymLinks ExecCGI +AllowOverride Options=Indexes + +

    et si un fichier .htaccess contient :

    + +Options Indexes + +

    les options FollowSymLinks et ExecCGI seront + implicitement désactivée pour le répertoire concerné, même si la ligne + AllowOverride ne fait que permettre la définition de l’option + Indexes.

    + +

    En bref, ce mécanisme ne peut pas forcer une option spécifique à rester + définie tout en permettant la définition de toutes les autres.

    +
    AllowOverride Options=Indexes,MultiViews diff --git a/docs/manual/mod/core.xml.meta b/docs/manual/mod/core.xml.meta index b9d96ee4c52..e78755527af 100644 --- a/docs/manual/mod/core.xml.meta +++ b/docs/manual/mod/core.xml.meta @@ -10,7 +10,7 @@ de en es - fr + fr ja tr diff --git a/docs/manual/mod/directives.html.fr.utf8 b/docs/manual/mod/directives.html.fr.utf8 index 2f4b4368fba..93857fa4a72 100644 --- a/docs/manual/mod/directives.html.fr.utf8 +++ b/docs/manual/mod/directives.html.fr.utf8 @@ -498,6 +498,7 @@
  • MDDriveMode
  • MDExternalAccountBinding
  • MDHttpProxy
  • +
  • MDHttpProxyCACertificateFile
  • MDInitialDelay
  • MDMatchNames
  • MDMember
  • diff --git a/docs/manual/mod/event.html.en.utf8 b/docs/manual/mod/event.html.en.utf8 index f80529c8dde..8ca9ffdbae9 100644 --- a/docs/manual/mod/event.html.en.utf8 +++ b/docs/manual/mod/event.html.en.utf8 @@ -47,6 +47,12 @@ of consuming threads only for connections with active processing --with-mpm=event to the configure script's arguments when building the httpd.

    + +

    When built as a DSO module, it can be loaded with:

    + +
    LoadModule mpm_event_module modules/mod_mpm_event.so
    + +

    Topics

      @@ -78,6 +84,7 @@ of consuming threads only for connections with active processing

    Bugfix checklist

    See also

    top
    diff --git a/docs/manual/mod/event.html.fr.utf8 b/docs/manual/mod/event.html.fr.utf8 index d9656a363a7..68fd5e2c6ce 100644 --- a/docs/manual/mod/event.html.fr.utf8 +++ b/docs/manual/mod/event.html.fr.utf8 @@ -49,6 +49,12 @@ mobiliser des threads que pour les connexions en cours de traitement configure lorsque vous compilez le programme httpd.

    +

    Lorsque ce module est construit en tant que module DSO, il peut être +chargé à l’aide de la commande :

    + +
    LoadModule mpm_event_module modules/mod_mpm_event.so
    + +

    Sujets

      @@ -80,6 +86,7 @@ mobiliser des threads que pour les connexions en cours de traitement

    Traitement des bugs

    Voir aussi

    top
    @@ -103,7 +110,7 @@ propose le MPM workerCe module MPM a été conçu à l'origine pour résoudre le "problème keep alive" de HTTP. Lorsqu'un client a effectué une première requête, il peut - garder la connexion ouverte et envoyer les requêtes suivante en utilisant le + garder la connexion ouverte et envoyer les requêtes suivantes en utilisant le même socket, ce qui diminue considérablement la charge qui aurait été induite par la création de nouvelles connexions TCP. Cependant, le fonctionnement du serveur HTTP Apache impose de réserver un couple processus diff --git a/docs/manual/mod/event.xml b/docs/manual/mod/event.xml index 36f68f529dd..9211f8f259d 100644 --- a/docs/manual/mod/event.xml +++ b/docs/manual/mod/event.xml @@ -39,8 +39,16 @@ of consuming threads only for connections with active processing --with-mpm=event to the configure script's arguments when building the httpd.

    + +

    When built as a DSO module, it can be loaded with:

    + + +LoadModule mpm_event_module modules/mod_mpm_event.so + + +Multi-Processing Modules (MPMs) The worker MPM
    Relationship with the Worker MPM diff --git a/docs/manual/mod/event.xml.es b/docs/manual/mod/event.xml.es index 64ac954b26d..49984ecbb5a 100644 --- a/docs/manual/mod/event.xml.es +++ b/docs/manual/mod/event.xml.es @@ -1,7 +1,7 @@ - + + @@ -43,8 +43,15 @@ mobiliser des threads que pour les connexions en cours de traitementconfigure lorsque vous compilez le programme httpd.

    - +

    Lorsque ce module est construit en tant que module DSO, il peut être +chargé à l’aide de la commande :

    + +LoadModule mpm_event_module modules/mod_mpm_event.so + + + +Modules multi-processus (MPMs) Le MPM worker
    Relations avec le MPM Worker @@ -66,7 +73,7 @@ propose le MPM worker, avec l'unique addition de la directive

    Ce module MPM a été conçu à l'origine pour résoudre le "problème keep alive" de HTTP. Lorsqu'un client a effectué une première requête, il peut - garder la connexion ouverte et envoyer les requêtes suivante en utilisant le + garder la connexion ouverte et envoyer les requêtes suivantes en utilisant le même socket, ce qui diminue considérablement la charge qui aurait été induite par la création de nouvelles connexions TCP. Cependant, le fonctionnement du serveur HTTP Apache impose de réserver un couple processus diff --git a/docs/manual/mod/index.html.fr.utf8 b/docs/manual/mod/index.html.fr.utf8 index aefa8e52a0b..a37b269f3a2 100644 --- a/docs/manual/mod/index.html.fr.utf8 +++ b/docs/manual/mod/index.html.fr.utf8 @@ -56,8 +56,9 @@ disponibles

    modules multi-processus (MPM)
    event
    Une variante du MPM worker conçue pour ne mobiliser des threads que pour les connexions en cours de traitement
    -
    motorz
    A lean, fast, self-contained event-driven Multi-Processing Module -built on the APR pollset and thread pool especially suited as a reverse proxy
    +
    motorz
    Un MPM (Multi-Processing Module) événementiel léger, rapide et +autonome basé sur l'ensemble de requêtes et le pool de threads APR, +particulièrement adapté comme mandataire inverse
    mpm_netware
    Module multi-processus implémentant un serveur web basé exclusivement sur les threads et optimisé pour Novell NetWare
    @@ -226,8 +227,9 @@ utilisateurs. mod_proxy
    mod_proxy_balancer
    Extension de mod_proxy pour le support de la répartition de charge
    -
    mod_proxy_beacon
    Dynamic Balancer membership where backends announce themselves -to the reverse proxy over unicast UDP datagrams
    +
    mod_proxy_beacon
    Inscription dynamique comme membre d’un répartiteur de charge où +les serveurs dorsaux s’annoncent eux-mêmes au mandataire inverse à l’aide de +datagrammes UDP unicast
    mod_proxy_connect
    Extension de mod_proxy pour le traitement des requêtes CONNECT
    mod_proxy_express
    Extension à mod_proxy pour le mandatement diff --git a/docs/manual/mod/mod_access_compat.xml b/docs/manual/mod/mod_access_compat.xml index f68ac36ad3c..6b802845fcc 100644 --- a/docs/manual/mod/mod_access_compat.xml +++ b/docs/manual/mod/mod_access_compat.xml @@ -25,7 +25,7 @@ mod_access_compat Group authorizations based on host (name or IP address) -Extension +Deprecated mod_access_compat.c access_compat_module Available in Apache HTTP Server 2.3 as a compatibility module with diff --git a/docs/manual/mod/mod_allowhandlers.html.fr.utf8 b/docs/manual/mod/mod_allowhandlers.html.fr.utf8 index bad8f1e893e..e3c4c0908cb 100644 --- a/docs/manual/mod/mod_allowhandlers.html.fr.utf8 +++ b/docs/manual/mod/mod_allowhandlers.html.fr.utf8 @@ -30,8 +30,6 @@  es  |  fr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    diff --git a/docs/manual/mod/mod_allowhandlers.xml.meta b/docs/manual/mod/mod_allowhandlers.xml.meta index 42f4593ab1c..c9b669a2d8b 100644 --- a/docs/manual/mod/mod_allowhandlers.xml.meta +++ b/docs/manual/mod/mod_allowhandlers.xml.meta @@ -9,6 +9,6 @@ en es - fr + fr diff --git a/docs/manual/mod/mod_auth_digest.html.fr.utf8 b/docs/manual/mod/mod_auth_digest.html.fr.utf8 index f19fbd5c20d..b3d32ccb9e9 100644 --- a/docs/manual/mod/mod_auth_digest.html.fr.utf8 +++ b/docs/manual/mod/mod_auth_digest.html.fr.utf8 @@ -30,8 +30,6 @@  fr  |  ko 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    Description:Facilite la définition de la liste des gestionnaires HTTP qui peuvent être utilisés pour le serveur
    Statut:Expérimental
    @@ -176,18 +174,33 @@ concernant l'authentification à base de condensés
    top

    Directive AuthDigestNcCheck

    Description:Authentification utilisateur utilisant les condensés MD5
    Statut:Extension
    - + - + +
    Description:Active ou désactive la vérification du nombre d'envois du -nombre à valeur unique (nonce) par le serveur
    Description:Active ou désactive la vérification du compteur d'envois du +nombre à valeur unique (nonce) par le client
    Syntaxe:AuthDigestNcCheck On|Off
    Défaut:AuthDigestNcCheck Off
    Contexte:configuration globale
    Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
    Surcharges autorisées:AuthConfig
    Statut:Extension
    Module:mod_auth_digest
    -
    - Non encore implémenté. -
    - +

    La directive AuthDigestNcCheck permet d'activer ou de désactiver + la vérification du compteur d'envois du nombre à valeur unique (nonce) + par le client. Le compteur d'envois est un compteur séquentiel que le client + incrémente à chaque requête en utilisant le même nombre à valeur unique. + Cette vérification permet de détecter les attaques par rejeu.

    + +

    Cette fonctionnalité nécessite la prise en charge de la mémoire partagée + sur la plateforme. Si cette directive est définie à On alors + que la mémoire partagée n’est pas disponible, le serveur renverra une erreur + au démarrage.

    + +

    Bien qu’il soit recommandé de le faire du point de vue de la sécurité, + activer cette directive a des implications en matière de performance : + toutes les requêtes comportant un en-tête + Authorization doivent être sérialisées au sein d’une section + critique pour comparer de manière sure les valeurs du compteur d’envois du + nombre à valeur unique. Sur les serveurs à fort trafic, cela peut ne pas être + négligeable.

    top
    diff --git a/docs/manual/mod/mod_auth_digest.xml.meta b/docs/manual/mod/mod_auth_digest.xml.meta index 5e68b12cb21..7583c0e005d 100644 --- a/docs/manual/mod/mod_auth_digest.xml.meta +++ b/docs/manual/mod/mod_auth_digest.xml.meta @@ -8,7 +8,7 @@ en - fr + fr ko diff --git a/docs/manual/mod/mod_brotli.html.fr.utf8 b/docs/manual/mod/mod_brotli.html.fr.utf8 index c9e23a22e7a..39a90a7e73f 100644 --- a/docs/manual/mod/mod_brotli.html.fr.utf8 +++ b/docs/manual/mod/mod_brotli.html.fr.utf8 @@ -29,8 +29,6 @@

    Langues Disponibles:  en  |  fr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    @@ -98,7 +96,7 @@ SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli

    Si vous voulez restreindre la compression à certains types MIME particuliers, vous pouvez utiliser la directive AddOutputFilterByType. Dans l'exemple suivant, l'activation de la compression est restreinte aux fichiers html - de la documentation d'Apache :

    + de la documentation d'Apache httpd :

    <Directory "/your-server-root/manual">
         AddOutputFilterByType BROTLI_COMPRESS text/html
    @@ -228,9 +226,18 @@ compression
     
    Description:Compression du contenu via Brotli avant sa livraison au client
    Statut:Extension
    Identificateur de Module:brotli_module
    Module:mod_brotli

    La directive BrotliCompressionMaxInputBlock permet - de spécifier la taille maximale du bloc de données en entrée entre 16 et 24, - sachant que plus cette taille sera grande, plus grande sera la quantité de - mémoire consommée.

    + de spécifier la taille maximale du bloc de données en entrée sous la forme + de 2 élevé à une puissance égale à value. Cette dernière doit + être comprise entre 16 et 24, ce qui représente des blocs de 64 Ko à 16 Mo. + Des blocs de taille plus grande peuvent améliorer la compression, mais + nécessitent davantage de mémoire. Lorsque cette directive n’est pas définie, + la taille de bloc est automatiquement calculée en fonction de la valeur de + qualité définie. +

    + +

    Blocs en entrée de taille définie à 1 Mo

    # 2^20 = blocs de 1 Mo
    +BrotliCompressionMaxInputBlock 20
    +
    top
    @@ -246,9 +253,19 @@ compression

    La directive BrotliCompressionQuality permet de spécifier la qualité de la compression (une valeur entre 0 et 11). Les valeurs les plus hautes correspondent à une compression de - meilleure qualité mais plus lente. + meilleure qualité mais plus lente. La valeur par défaut 5 est un bon + compromis pour du contenu dynamique.

    +

    Compression rapide pour du contenu dynamique

    # La valeur de qualité 4 est à peu près équivalente à gzip niveau 6
    +BrotliCompressionQuality 4
    +
    + +

    Compression maximale pour les ressources statiques

    # Meilleur taux de compression mais très lent — ne convient qu’à la mise en
    +# cache
    +BrotliCompressionQuality 11
    +
    +
    top

    Directive BrotliCompressionWindow

    @@ -262,8 +279,20 @@ compression

    La directive BrotliCompressionWindow permet de spécifier la taille de la fenêtre de compression glissante brotli (une - valeur comprise entre 10 et 24). Une taille de fenêtre plus grande peut - améliorer la qualité de la compression mais consomme d'avantage de mémoire.

    + valeur comprise entre 10 et 24, représentant une fenêtre de + 2^value octets. Par exemple, 18 (la valeur par défaut) donne une + fenêtre de 256 Ko, alors que 24 en donne une de 16 Mo. Une taille de fenêtre + plus grande peut améliorer la qualité de la compression mais consomme + d'avantage de mémoire.

    + +

    Fenêtre modérée pour une utilisation raisonnable de mémoire

    # fenêtre de 1 Mo (2^20 octets)
    +BrotliCompressionWindow 20
    +
    + +

    Fenêtre maximale pour la meilleure compression

    # fenêtre de 16 Mo (2^24 octets) — nécessite une quantité de mémoire
    +# significative pour chaque connexion
    +BrotliCompressionWindow 24
    +
    top
    @@ -272,6 +301,7 @@ compression Description:Enregistre le taux de compression dans une note à des fins de journalisation Syntaxe:BrotliFilterNote [type] notename +Défaut:None Contexte:configuration globale, serveur virtuel Statut:Extension Module:mod_brotli diff --git a/docs/manual/mod/mod_brotli.xml.meta b/docs/manual/mod/mod_brotli.xml.meta index e06ba088469..8c6376e8a0f 100644 --- a/docs/manual/mod/mod_brotli.xml.meta +++ b/docs/manual/mod/mod_brotli.xml.meta @@ -8,6 +8,6 @@ en - fr + fr diff --git a/docs/manual/mod/mod_cern_meta.xml b/docs/manual/mod/mod_cern_meta.xml index b2e8e8f0a51..54d2a60a4f0 100644 --- a/docs/manual/mod/mod_cern_meta.xml +++ b/docs/manual/mod/mod_cern_meta.xml @@ -24,7 +24,7 @@ mod_cern_meta CERN httpd metafile semantics -Extension +Deprecated mod_cern_meta.c cern_meta_module diff --git a/docs/manual/mod/mod_dbd.html.fr.utf8 b/docs/manual/mod/mod_dbd.html.fr.utf8 index deb056dc484..e3846f65f62 100644 --- a/docs/manual/mod/mod_dbd.html.fr.utf8 +++ b/docs/manual/mod/mod_dbd.html.fr.utf8 @@ -29,8 +29,6 @@

    Langues Disponibles:  en  |  fr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    diff --git a/docs/manual/mod/mod_dbd.xml.fr b/docs/manual/mod/mod_dbd.xml.fr index 4875cdfd918..8937cd7257e 100644 --- a/docs/manual/mod/mod_dbd.xml.fr +++ b/docs/manual/mod/mod_dbd.xml.fr @@ -1,7 +1,7 @@ - + diff --git a/docs/manual/mod/mod_dbd.xml.meta b/docs/manual/mod/mod_dbd.xml.meta index 9131911db28..bf4a2e0a235 100644 --- a/docs/manual/mod/mod_dbd.xml.meta +++ b/docs/manual/mod/mod_dbd.xml.meta @@ -8,6 +8,6 @@ en - fr + fr diff --git a/docs/manual/mod/mod_heartmonitor.html.fr.utf8 b/docs/manual/mod/mod_heartmonitor.html.fr.utf8 index 82dbb476af0..ad744ade203 100644 --- a/docs/manual/mod/mod_heartmonitor.html.fr.utf8 +++ b/docs/manual/mod/mod_heartmonitor.html.fr.utf8 @@ -29,8 +29,6 @@

    Langues Disponibles:  en  |  fr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    Description:Gestion des connexions à une base de données SQL
    Statut:Extension
    Identificateur de Module:dbd_module
    @@ -111,10 +109,11 @@ serveur HTTP Apache contrôler la quantité de mémoire partagée allouée pour le stockage des données heartbeat lorsqu'on utilise mod_slotmem_shm.

    -

    Pour utiliser un stockage de type fichier bidimensionnel (flat-file) - lorque le module mod_slotmem_shm n'est pas chargé, cette - directive doit être définie à 0. La valeur doit être soit égale à 0, soit - supérieure ou égale à 10.

    + +

    Définissez cette directive à 0 pour utiliser un stockage de + type fichier bidimensionnel (flat-file) au lieu de la mémoire partagée + (c’est-à-dire sans charger mod_slotmem_shm). Lorsqu’on + utilise la mémoire partagée, la valeur doit être supérieure ou égale à 10.

    top
    diff --git a/docs/manual/mod/mod_heartmonitor.xml.fr b/docs/manual/mod/mod_heartmonitor.xml.fr index a7abcdfaec2..4aa432efb8d 100644 --- a/docs/manual/mod/mod_heartmonitor.xml.fr +++ b/docs/manual/mod/mod_heartmonitor.xml.fr @@ -1,7 +1,7 @@ - + @@ -114,10 +114,11 @@ serveur HTTP Apache contrôler la quantité de mémoire partagée allouée pour le stockage des données heartbeat lorsqu'on utilise mod_slotmem_shm.

    -

    Pour utiliser un stockage de type fichier bidimensionnel (flat-file) - lorque le module mod_slotmem_shm n'est pas chargé, cette - directive doit être définie à 0. La valeur doit être soit égale à 0, soit - supérieure ou égale à 10.

    + +

    Définissez cette directive à 0 pour utiliser un stockage de + type fichier bidimensionnel (flat-file) au lieu de la mémoire partagée + (c’est-à-dire sans charger mod_slotmem_shm). Lorsqu’on + utilise la mémoire partagée, la valeur doit être supérieure ou égale à 10.

    diff --git a/docs/manual/mod/mod_heartmonitor.xml.meta b/docs/manual/mod/mod_heartmonitor.xml.meta index d0c5b2fb350..269a7db4894 100644 --- a/docs/manual/mod/mod_heartmonitor.xml.meta +++ b/docs/manual/mod/mod_heartmonitor.xml.meta @@ -8,6 +8,6 @@ en - fr + fr diff --git a/docs/manual/mod/mod_imagemap.xml b/docs/manual/mod/mod_imagemap.xml index 6a4e50f9aa9..5f360d4c7ea 100644 --- a/docs/manual/mod/mod_imagemap.xml +++ b/docs/manual/mod/mod_imagemap.xml @@ -24,7 +24,7 @@ mod_imagemapServer-side imagemap processing -Base +Deprecatedmod_imagemap.cimagemap_module diff --git a/docs/manual/mod/mod_md.html.en.utf8 b/docs/manual/mod/mod_md.html.en.utf8 index 770737712d0..506a2acf810 100644 --- a/docs/manual/mod/mod_md.html.en.utf8 +++ b/docs/manual/mod/mod_md.html.en.utf8 @@ -186,16 +186,17 @@ If there is an error with an MD it will be shown here as well. This let's you assess problems without digging through your server logs.

    - There is also a new 'md-status' handler available to give you the MD information - from 'server-status' in JSON format. You configure it as + There is also a new 'md-status' handler available to give you the MD information + from 'server-status' in JSON format. You configure it as

    <Location "/md-status">
       SetHandler md-status
    +  Require host example.com
     </Location>

    - on your server. As with 'server-status' you will want to add - authorization for this. + on your server. As with 'server-status' you must protect + the md-status output from public view using authorization restrictions (such as mod_authz_host).

    If you just want to check the JSON status of a specific domain, simply append that to your status url: @@ -247,7 +248,7 @@ </MDomain>

    - and use the 'server-status' and/or MDMessageCmd to see how it operates. You will + and use the 'server-status' and/or MDMessageCmd to see how it operates. You will see if Stapling information is there, how long it is valid, from where it came and when it will be refreshed.

    @@ -452,13 +453,13 @@

    If you configure more than one URL, each one is tried in a round-robin fashion after a number of failures. You can configure how quickly or - delayed that happens via the MDRetryDelay and - MDRetryFailover directives. The default setting + delayed that happens via the MDRetryDelay and + MDRetryFailover directives. The default setting makes a failover after about half a day of trying.

    All other settings apply to each of these URLs. It is therefore not possible to have two with different - MDExternalAccountBindings, for example. + MDExternalAccountBindings, for example.

    For testing, CAs commonly offer a second service URL. The 'test' service does not give certificates valid in a browser, @@ -558,7 +559,7 @@

    Description:Moniteur centralisé pour les serveurs d'origine mod_heartbeat
    Statut:Expérimental
    Identificateur de Module:heartmonitor_module
    Module:mod_md

    - This is part of the 'server-status' HTML user interface and has nothing to + This is part of the 'server-status' HTML user interface and has nothing to do with the core functioning itself. It defines the link offered on that page for easy checking of a certificate monitor. The SHA256 fingerprint of the certificate is appended to the configured url. @@ -656,9 +657,11 @@ Compatibility:Available in version 2.4.58 and later

    - Set the way MDChallengeDns01 command is invoked, e.g the number and - types of arguments. See MDChallengeDns01 + Set the way MDChallengeDns01 + command is invoked, e.g the number and types of arguments. + See MDChallengeDns01 for the differences. +

    This setting is global and cannot be varied per domain.

    @@ -807,8 +810,10 @@ Compatibility:Available in version 2.4.58 and later

    - The mode `all` is the behavior as in all previous versions. Both ServerName - and ServerAlias are inspected to find the MDomain matching a VirtualHost. + The mode `all` is the behavior as in all previous versions. Both + ServerName + and ServerAlias are inspected + to find the MDomain matching a VirtualHost. This automatically detects coverage, even when you only have added one of the names to an MDomain.

    @@ -1182,18 +1187,18 @@ MDomain example2.org auto

    This about a non-standard ACME extension by Let's Encrypt.

    - Lets Encrypt supports Certificate Profiles in their CA. This, + Let's Encrypt supports Certificate Profiles in their CA. This, among some other details, let's you select the lifetime of the certificates you get. The "classic" profile is the default and will keep the 90 days, the "tlsserver" profile is also 90 days with a max of 25 Subject Alternative Names. The "shortlived" profile will issue certificates with only 6 days of validity.

    - If you do not change your mod_md configuration, you will + If you do not change your mod_md configuration, you will continue to get the 90 days certificates. Should you believe that a shorter lifetime is beneficial for you (and take the risk that the renewal time is way shorter), -+ you can configure the profile to use via 'MDProfile shortlived'. + you can configure the profile to use via 'MDProfile shortlived'.

    The profile names are defined by the CA. If a profile you configure is not available, no profile will be used and @@ -1214,6 +1219,7 @@ MDomain example2.org auto Context:server config Status:Experimental Module:mod_md +Compatibility:Available in version 2.4.64 and later

    Controls if a MDProfile @@ -1272,7 +1278,7 @@ MDomain example2.org auto

    En-/Disable certificate renewals triggered via the ACME ARI extension (rfc9773). These renewals happen *in addition* to - the mechanism controlled by MDRenewWindow. + the mechanism controlled by MDRenewWindow.

    ACME ARI allows an ACME CA to somewhat shape incoming renewal traffic. More importantly though, it can inform clients of @@ -1292,7 +1298,7 @@ MDomain example2.org auto Module:mod_md

    - If the validity of the certificate falls below duration, mod_md + If the validity of the certificate falls below duration, mod_md will get a new signed certificate.

    Normally, certificates are valid for around 90 days and mod_md will renew @@ -1411,7 +1417,7 @@ MDRenewWindow 10%

    The number of consecutive errors on renewing a certificate before another CA is selected. This only applies to configurations that - have more than one MDCertificateAuthority + have more than one MDCertificateAuthority specified.

    @@ -1419,19 +1425,22 @@ MDRenewWindow 10%
    top

    MDServerStatus Directive

    - + - +
    Description:Control if Managed Domain information is added to server-status.
    Description:Control if Managed Domain information is added to server-status.
    Syntax:MDServerStatus on|off
    Default:MDServerStatus on
    Default:MDServerStatus off
    Context:server config
    Status:Experimental
    Module:mod_md

    - Apaches 'server-status' handler allows you configure a resource to monitor - what is going on. This includes now a section listing all Managed Domains - with the DNS names, renewal status, lifetimes and main properties. + If enabled, adds a section to the + mod_status 'server-status' handler + output which lists all Managed Domains with the DNS + names, renewal status, lifetimes and main properties.

    - You can switch that off using this directive. + As with 'md-status', the 'server-status' output + must be protected from public view + using appropriate authorization restrictions.

    @@ -1578,11 +1587,12 @@ MDRenewWindow 10%

    Enable this to use a lock file on server startup when - MDStoreDir is synchronized with the server + MDStoreDir is synchronized with the server configuration and renewed certificates are activated.

    Locking is intended for setups in a cluster that have a shared - file system for MDStoreDir. It will protect the activation of + file system for MDStoreDir. + It will protect the activation of renewed certificates when cluster nodes are restarted/reloaded at the same time. Under the condition that the shared file system does support file locking. @@ -1618,8 +1628,8 @@ MDRenewWindow 10% window left. With the default, this mean 9 days for certificates from Let's Encrypt.

    - It also applies to Managed Domains with static certificate files ( - see MDCertificateFile). + It also applies to Managed Domains with static certificate files (see + MDCertificateFile).

    diff --git a/docs/manual/mod/mod_md.html.fr.utf8 b/docs/manual/mod/mod_md.html.fr.utf8 index 9bc52da9229..c9f576c2f1e 100644 --- a/docs/manual/mod/mod_md.html.fr.utf8 +++ b/docs/manual/mod/mod_md.html.fr.utf8 @@ -214,18 +214,23 @@ aussi ici, ce qui vous permettra de visualiser les éventuels problèmes sans devoir vous plonger dans les journaux du serveur.

    - Il existe aussi un nouveau gestionnaire, "md-status", qui peut + Il existe aussi un nouveau gestionnaire, + « md-status », qui peut vous fournir les informations à propos des domaines gérés à - partir de "server-status" et au format JSON. Vous pouvez le + partir de « server-status » et au format JSON. Vous pouvez le configurer comme suit sur votre serveur :

    <Location "/md-status">
       SetHandler md-status
    +  Require host example.com
     </Location>

    - Comme pour "server-status", vous devez - ajouter les autorisations nécessaires. + Comme pour « server-status », vous + devez protéger la sortie de + md-status de la vue du public en instaurant des + restrictions d’autorisation (telles que + mod_authz_host).

    Si vous ne souhaitez recevoir l'état JSON que pour un domaine spécifique, ajoutez le simplement à votre URL d'état : @@ -279,7 +284,7 @@ </MDomain>

    - et utilisez 'server-status' et/ou MDMessageCmd pour voir comment tout + et utilisez « server-status » et/ou MDMessageCmd pour voir comment tout cela fonctionne. Vous pourrez alors vérifier si l'information d'agrafage est présente, sa durée de validité, son origine et à quel moment elle sera rafraîchie. @@ -350,6 +355,7 @@

  • MDDriveMode
  • MDExternalAccountBinding
  • MDHttpProxy
  • +
  • MDHttpProxyCACertificateFile
  • MDInitialDelay
  • MDMatchNames
  • MDMember
  • @@ -427,6 +433,8 @@ Contexte:configuration globale Statut:Expérimental Module:mod_md +Compatibilité:Depuis la version 2.4.69, cette directive peut être + définie séparément pour chaque MDomain.

    Cette directive est principalement utilisée dans les @@ -522,13 +530,13 @@ Si vous spécifiez plusieurs URLs, chacune d'entre elles est testée en mode tourniquet ("round-robin") après un certain nombre d'échecs. Vous pouvez définir la rapidité de ce processus - à l'aide des directives MDRetryDelay et - MDRetryFailover. Par défaut, une demie + à l'aide des directives MDRetryDelay et + MDRetryFailover. Par défaut, une demie journée d'essais infructueux est considérée comme un échec. -

    +

    Tous les autres réglages s'appliquent à chacune de ces URLs. Il est ainsi par exemple impossible d'en avoir deux avec des - directives MDExternalAccountBinding + directives MDExternalAccountBinding différentes.

    A des fins de test, les CAs fournissent en général une seconde @@ -636,7 +644,8 @@ Module:mod_md

    - Cette directive impacte l'interface utilisateur HTML 'server-status' et + Cette directive impacte l'interface utilisateur HTML + « server-status » et n'a rien à voir avec le fonctionnement de mod_md proprement dit. Elle permet de définir le lien qui s'affiche sur cette interface pour accéder facilement à un moniteur de certificat. L'empreinte @@ -753,7 +762,7 @@

    Cette directive permet de définir de quelle manière est invoquée - la commande MDChallengeDns01, à savoir le nombre et le type de + la commande MDChallengeDns01, à savoir le nombre et le type de ses arguments. Voir MDChallengeDns01 pour les différences. Cette définition est globale et ne peut pas s'appliquer @@ -888,14 +897,50 @@ Contexte:configuration globale Statut:Expérimental Module:mod_md +Compatibilité:À partir de la version 2.4.69, un mandataire peut être + configuré séparément pour chaque MDomain. -

    Cette directive permet de spécifier un serveur http mandataire +

    Utiliser l’URL du serveur http mandataire direct donné pour se connecter à l'autorité de certification spécifiée via MDCertificateAuthority. Vous devez la définir si votre serveur web ne peut atteindre internet que - via un serveur mandataire. + via un mandataire direct.

    + +
    top
    +

    Directive MDHttpProxyCACertificateFile

    + + + + + + + + +
    Description:Définition des certificats racine (CA) à utiliser pour les + connexions TLS avec le mandataire http.
    Syntaxe:MDHttpProxyCACertificateFile path-to-pem-file
    Défaut:MDHttpProxyCACertificateFile none
    Contexte:configuration globale
    Statut:Expérimental
    Module:mod_md
    Compatibilité:Disponible à partir de la version 2.4.69 du serveur HTTP + Apache
    +

    + Cette directive est utilisée pour les connexions avec le + mandataire HTTPS direct (directive MDHttpProxy). Elle est requise si le + certificat du mandataire HTTPS ne peut pas être vérifié en + utilisant le magasin général de la racine du CA. Cela se produit + parfois dans les environnements de test ou au sein d’une + entreprise. +

    +

    + Le certificat du serveur ACME est vérifié avec les certificats + racine définis via la directive MDCACertificateFile ; vous serez + donc amené à utiliser les deux définitions. +

    +

    + Utilisez « none » comme chemin pour désactiver cette + fonctionnalité explicitement. +

    +

    Cette directive peut être configurée séparément pour chaque + MDomain.

    +
    top

    Directive MDInitialDelay

    @@ -929,11 +974,13 @@ Apache

    - Le mode `all` correspond au comportement de toutes les versions - précédentes. ServerName et ServerAlias sont inspectés pour - trouver le MDomain qui correspond à un serveur virtuel. Les - recouvrements sont automatiquement détectés, même si vous n'avez - ajouté qu'un des noms à un MDomain. + Le mode `all` correspond au comportement de toutes les versions + précédentes. ServerName et + ServerAlias sont inspectés + pour trouver le MDomain + qui correspond à un serveur virtuel. Les recouvrements sont + automatiquement détectés, même si vous n'avez ajouté qu'un des + noms à un MDomain.

    Cet automatisme présente cependant des inconvénients avec les configurations plus complexes. Si vous définissez cette @@ -1370,7 +1417,7 @@ MDomain example2.org auto

    Il s'agit d'une extension non standard d'ACME par Let's Encrypt.

    - Lets Encrypt prend en charge les profiles de certificat dans + Let’s Encrypt prend en charge les profiles de certificat dans leurs CA. Cette fonctionnalité, entre autres détails, vous permet de définir la durée de validité des certificats que vous recevez. Le profile par défaut « classic » conserve la valeur de @@ -1379,7 +1426,7 @@ MDomain example2.org auto profile « shortlived » délivre des certificats dont la durée de validité est de 6 jours seulement.

    - Si vous ne modifiez pas la configuration de votre module mod_md, + Si vous ne modifiez pas la configuration de votre module mod_md, vous continuerez à recevoir des certificats d'une durée de validité de 90 jours. Si vous pensez qu'une durée de validité plus courte convient mieux à votre situation (et acceptez le @@ -1405,6 +1452,8 @@ MDomain example2.org auto Contexte:configuration globale Statut:Expérimental Module:mod_md +Compatibilité:Disponible à partir de la version 2.4.64 du serveur HTTP + Apache

    Cette directive permet de contrôler si un MDProfile que vous définissez est @@ -1469,7 +1518,7 @@ MDomain example2.org auto déclenchement du renouvellement des certificats à l'aide de l'extension ACME ARI (rfc9773). Ces renouvellements s'ajoutent à ceux déclenchés par le mécanisme contrôlé à l'aide de la - directive MDRenewWindow. + directive MDRenewWindow.

    ACME ARI permet en quelque sorte à une CA ACME de façonner le trafic entrant des renouvellements. Plus important cependant, @@ -1490,7 +1539,7 @@ MDomain example2.org auto Module:mod_md

    - Lorsqu'un certificat arrive à expiration, mod_md va + Lorsqu'un certificat arrive à expiration, mod_md va tenter d'en obtenir un nouveau signé.

    Normalement, les certificats ont une validité de 90 jours, et @@ -1623,10 +1672,9 @@ MDRenewWindow 10% Apache

    - Le nombre d'erreurs consécutives lors du renouvellement d'un + Le nombre d'erreurs consécutives lors du renouvellement d'un certificat avant la sélection d'une autre CA. Ne s'applique - qu'aux configurations pour lesquelles plusieurs - MDCertificateAuthority ont été + qu'aux configurations pour lesquelles plusieurs MDCertificateAuthority ont été spécifiées.

    @@ -1635,22 +1683,23 @@ MDRenewWindow 10%

    Directive MDServerStatus

    + sont ajoutés ou non à server-status. - +
    Description:Définit si les informations à propos des domaines gérés - sont ajoutés ou non à server-status.
    Syntaxe:MDServerStatus on|off
    Défaut:MDServerStatus on
    Défaut:MDServerStatus off
    Contexte:configuration globale
    Statut:Expérimental
    Module:mod_md
    -

    - Le gestionnaire d'Apache "server-status" vous permet de - configurer une ressource pour monitorer le fonctionnement du - serveur. Cette ressource inclut maintenant une section indiquant - tous les domaines gérés avec leur nom DNS, l'état de - renouvellement du certificat, la durée de vie de ce dernier, - ainsi que d'autres propriétés fondamentales. -

    - Cette directive permet d'activer/désactiver cette ressource. +

    Si cette directive est activée, une section est ajoutée au + gestionnaire « server-status » de + mod_status, qui liste tous les domaines gérés avec + leur nom DNS, l'état de renouvellement du certificat, la durée de + vie de ce dernier, ainsi que d'autres propriétés fondamentales. +

    + Comme avec « md-status », la sortie de + « server-status » doit être + protégée de la vue du public en instaurant des restrictions + d’autorisation appropriées.

    @@ -1829,13 +1878,13 @@ MDRenewWindow 10% Apache

    - Définissez cette directive pour utiliser un fichier verrou au - démarrage du serveur lorsque MDStoreDir - est synchronisé avec la configuration du serveur et si les - certificats renouvelés sont activés. + Définissez cette directive pour utiliser un fichier verrou au + démarrage du serveur lorsque MDStoreDir est synchronisé avec la + configuration du serveur et si les certificats renouvelés sont + activés.

    Le verrouillage a été implémenté pour les configurations de - cluster où MDStoreDir appartient à un système de fichiers + cluster où MDStoreDir appartient à un système de fichiers partagé. L'activation des certificats renouvelés sera alors protégée lorsque plusieurs noeuds du cluster sont redémarrés ou reconfigurés simultanément ; ceci à condition bien entendu que diff --git a/docs/manual/mod/mod_md.xml b/docs/manual/mod/mod_md.xml index a78614d640e..f4aedc85926 100644 --- a/docs/manual/mod/mod_md.xml +++ b/docs/manual/mod/mod_md.xml @@ -124,7 +124,7 @@ Protocols h2 http/1.1 acme-tls/1

    And the `tls-alpn-01` challenge type is available. -

    +

    Wildcard Certificates @@ -184,17 +184,18 @@ MDChallengeDns01 /usr/bin/acme-setup-dns If there is an error with an MD it will be shown here as well. This let's you assess problems without digging through your server logs.

    - There is also a new 'md-status' handler available to give you the MD information - from 'server-status' in JSON format. You configure it as + There is also a new 'md-status' handler available to give you the MD information + from 'server-status' in JSON format. You configure it as

    <Location "/md-status"> SetHandler md-status + Require host example.com </Location>

    - on your server. As with 'server-status' you will want to add - authorization for this. + on your server. As with 'server-status' you must protect + the md-status output from public view using authorization restrictions (such as mod_authz_host).

    If you just want to check the JSON status of a specific domain, simply append that to your status url: @@ -249,7 +250,7 @@ MDChallengeDns01 /usr/bin/acme-setup-dns </MDomain>

    - and use the 'server-status' and/or MDMessageCmd to see how it operates. You will + and use the 'server-status' and/or MDMessageCmd to see how it operates. You will see if Stapling information is there, how long it is valid, from where it came and when it will be refreshed.

    @@ -537,9 +538,39 @@ MDCertificateAuthority https://acme-staging-v02.api.letsencrypt.org/directory server config + Since version 2.4.69, a proxy can be configured separately for each MDomain. -

    Use a http proxy to connect to the MDCertificateAuthority. Define this - if your webserver can only reach the internet with a forward proxy. +

    + Use the given http forward proxy URL to connect to the MDCertificateAuthority. + Define this if your webserver can only reach the internet with a forward proxy. +

    + + + + + MDHttpProxyCACertificateFile + Sets the root (CA) certificates to use for TLS connections to the http-proxy. + MDHttpProxyCACertificateFile path-to-pem-file + MDHttpProxyCACertificateFile none + + server config + + Available in version 2.4.69 and later + +

    + This is used for connections to the HTTPS forward proxy (MDHttpProxy). + It is needed if the certificate of the HTTPS proxy cannot be verified using the general CA root store. + This is sometimes the case in test setups or enterprise environments. +

    +

    + The certificate of the ACME server is verified with the root certificates set by + MDCACertificateFile, so you might need to use both settings. +

    +

    + Use "none" as path to disable explicitly. +

    +

    + This can be configured separately for each MDomain.

    @@ -1111,19 +1142,22 @@ MDMessageCmd /etc/apache/md-message MDServerStatus - Control if Managed Domain information is added to server-status. + Control if Managed Domain information is added to server-status. MDServerStatus on|off - MDServerStatus on + MDServerStatus off server config

    - Apaches 'server-status' handler allows you configure a resource to monitor - what is going on. This includes now a section listing all Managed Domains - with the DNS names, renewal status, lifetimes and main properties. + If enabled, adds a section to the + mod_status 'server-status' handler + output which lists all Managed Domains with the DNS + names, renewal status, lifetimes and main properties.

    - You can switch that off using this directive. + As with 'md-status', the 'server-status' output + must be protected from public view + using appropriate authorization restrictions.

    @@ -1138,7 +1172,7 @@ MDMessageCmd /etc/apache/md-message

    - This is part of the 'server-status' HTML user interface and has nothing to + This is part of the 'server-status' HTML user interface and has nothing to do with the core functioning itself. It defines the link offered on that page for easy checking of a certificate monitor. The SHA256 fingerprint of the certificate is appended to the configured url. @@ -1618,6 +1652,7 @@ MDMessageCmd /etc/apache/md-message server config + Since version 2.4.69, this can be configured separately for each MDomain.

    This is mainly used in test setups where the module needs to diff --git a/docs/manual/mod/mod_md.xml.fr b/docs/manual/mod/mod_md.xml.fr index 574bebc5013..de48c644041 100644 --- a/docs/manual/mod/mod_md.xml.fr +++ b/docs/manual/mod/mod_md.xml.fr @@ -2,7 +2,7 @@ - + + @@ -580,7 +580,8 @@ mandatées

    Les directives situées dans une section Proxy ne s'appliquent qu'au contenu - mandaté concerné. Les jokers de style shell sont autorisés.

    + mandaté concerné en utilisant une simple recherche de correspondance entre + une chaîne et l’URL. Les jokers de style shell sont aussi autorisés.

    Par exemple, les lignes suivantes n'autoriseront à accéder à un contenu via votre serveur mandataire que les hôtes appartenant à @@ -823,6 +824,13 @@ ProxyRemote ftp http://ftpproxy.mydomain:8080 d'authentification. La variable d'environnement Proxy-Chain-Auth n'est plus prise en compte si cet argument est utilisé.

    + + Résolution DNS et mandataires directs +

    Lorsqu’un mandataire direct (distant) est configuré, la résolution DNS du + nom d’hôte originel/dorsal n’est effectuée que sur le mandataire direct. + Toute règle ProxyBlock qui + restreint l’accès à des adresses IP spécifiques doit être définie sur le + mandataire direct.

    diff --git a/docs/manual/mod/mod_proxy.xml.ja b/docs/manual/mod/mod_proxy.xml.ja index 47b20e680b5..7dd0a057c17 100644 --- a/docs/manual/mod/mod_proxy.xml.ja +++ b/docs/manual/mod/mod_proxy.xml.ja @@ -1,7 +1,7 @@ - + +mod_proxy_beacon - Apache HTTP Server Version 2.5 + + + + + + + + +
    <-
    + +
    +

    Apache Module mod_proxy_beacon

    + +
    +

    Available Languages:  en  | + fr 

    +
    + + + + +
    Description:Dynamic Balancer membership where backends announce themselves +to the reverse proxy over unicast UDP datagrams
    Status:Extension
    Module Identifier:proxy_beacon_module
    Source File:mod_proxy_beacon.c
    Compatibility:Available in Apache 2.5 and later
    +

    Summary

    + +

    This module lets backend servers announce themselves to a + front-end reverse proxy, which then adds each announcing backend as a live + member (worker) of a mod_proxy_balancer balancer. When a + backend stops announcing, the proxy takes it out of rotation. This provides + self-registering, self-healing balancer membership without editing the proxy + configuration or driving the balancer-manager by hand.

    + +

    Communication uses plain unicast UDP datagrams (not + multicast, which is filtered on most networks and does not traverse the + public Internet). The data flows from backend to proxy:

    + +
      +
    • The reverse proxy binds a UDP socket and receives on a + stable address (ProxyBeaconListen).
    • +
    • Each backend periodically sends a short announcement datagram + to the proxy (ProxyBeaconAddress), advertising + its own routable URL + (ProxyBeaconAdvertise).
    • +
    + +

    Datagrams are fire-and-forget: a lost announcement is recovered by the + next periodic one, and reordering is rejected by a per-backend timestamp + check, so no connection, reconnect, or framing layer is needed.

    + +

    On the proxy, ProxyBeaconBalancer names the balancer + that announced backends are added to. Membership changes are applied using + the same internal mechanism as the balancer-manager web + interface, so a backend added this way behaves exactly like a statically + configured or manually added + BalancerMember, and is visible and + editable in the balancer-manager.

    + +

    This module requires the service of + mod_watchdog and mod_proxy_balancer. The + background work (listening, publishing, adding and evicting members) runs in + a single mod_watchdog child process, so it is not available + under the prefork MPM behaviour where that singleton cannot + run.

    + +

    Authentication

    +

    Any host that can reach the proxy's receive port could otherwise announce + an arbitrary backend URL and cause the proxy to send client traffic to it + (and a UDP source address is trivially spoofable). Set + ProxyBeaconSecret to the same value on the proxy and on + every backend so that announcements are authenticated with a keyed + message-authentication code (MAC) and a timestamp. When a secret is + configured the proxy drops any announcement that is not validly signed and + recent. If no secret is configured the channel is unauthenticated + and the proxy logs a warning at startup.

    +
    + +

    Confidentiality

    +

    Announcements are authenticated but not encrypted; the payload is + operational metadata (backend URLs), not secret data. Transport + confidentiality (e.g. DTLS) is not currently provided and would be a separate + future layer.

    +
    + +
    + +
    top
    +
    +

    Usage example

    + + +

    The following pair of configurations sets up a self-registering balancer. + The backends require no knowledge of each other and the proxy needs no + pre-declared BalancerMember + entries — only an empty balancer with room to grow.

    + +

    On the reverse proxy:

    +
    # Receive backend announcements on the cluster network interface (UDP).
    +ProxyBeaconListen 0.0.0.0:5555
    +ProxyBeaconSecret    "a-long-random-shared-cluster-secret"
    +ProxyBeaconBalancer  cluster
    +
    +# A backend is dropped from rotation if it does not announce for 30 seconds.
    +ProxyBeaconTimeout   30
    +
    +# An initially-empty balancer with spare slots for the dynamic members.
    +<Proxy balancer://cluster>
    +  ProxySet growth=16
    +</Proxy>
    +ProxyPass        "/" "balancer://cluster/"
    +ProxyPassReverse "/" "balancer://cluster/"
    + + +

    On each backend server:

    +
    # Announce this backend's routable origin to the proxy every 10 seconds (UDP).
    +ProxyBeaconAddress   proxy.example.com:5555
    +ProxyBeaconAdvertise http://10.0.0.5:8080
    +ProxyBeaconSecret    "a-long-random-shared-cluster-secret"
    +ProxyBeaconInterval  10
    + + +

    When a backend starts it begins sending announcements. The proxy + verifies each announcement against the shared secret, adds + http://10.0.0.5:8080 as a member of + balancer://cluster, and enables it. If that backend later stops + announcing for longer than ProxyBeaconTimeout, the proxy + disables the member (taking it out of rotation); a subsequent announcement + re-enables it.

    + +
    +

    A backend added at runtime occupies one of the balancer's growth slots + for the lifetime of the server process; it is disabled rather than removed + when it stops announcing, matching the behaviour of the + balancer-manager (which can add, but not remove, workers at + runtime). Size growth for the maximum number of backends you + expect to register.

    +
    + +
    +
    top
    +

    ProxyBeaconAddress Directive

    + + + + + + +
    Description:Address of the reverse proxy to which a backend sends its +announcements
    Syntax:ProxyBeaconAddress address:port
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconAddress directive marks a server as an + announcement sender (a backend). It sends UDP datagrams to the + proxy's ProxyBeaconListen address given by + address:port, e.g. proxy.example.com:5555 (a leading + scheme such as tcp:// is accepted and ignored). Because UDP is + connectionless, a backend may be started before the proxy is available: + early datagrams are simply dropped and the next interval retries.

    + +

    Use ProxyBeaconAdvertise to specify the routable URL + the backend announces. ProxyBeaconAddress and + ProxyBeaconListen are mutually exclusive on the same + server.

    + +
    +
    top
    +

    ProxyBeaconAdvertise Directive

    + + + + + + +
    Description:The routable URL a backend announces to the reverse proxy
    Syntax:ProxyBeaconAdvertise url
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconAdvertise directive sets the backend's + own reachable origin (for example http://10.0.0.5:8080) that the + proxy will add as a BalancerMember. + It must be a full scheme://host[:port] URL that the proxy can + reach — not the local listen address — and is validated when the + configuration is parsed.

    + +

    This directive is used on a backend, alongside + ProxyBeaconAddress. If it is omitted, the backend still + sends a heartbeat but advertises no URL, so the proxy logs the + announcement without adding a member.

    + +
    +
    top
    +

    ProxyBeaconBalancer Directive

    + + + + + + +
    Description:Name of the balancer that announced backends are added to
    Syntax:ProxyBeaconBalancer name
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconBalancer directive names the balancer, + on the reverse proxy, into which announced backends are inserted as members. + Give the bare balancer name (for example cluster for + balancer://cluster); a leading balancer:// is + accepted and stripped.

    + +

    The named balancer must exist and have spare capacity. Declare it with a + <Proxy> block and a + growth setting (or rely on + BalancerGrowth) so there are free + slots for the dynamically added members. This directive is used together + with ProxyBeaconListen.

    + +
    +
    top
    +

    ProxyBeaconInterval Directive

    + + + + + + + +
    Description:How often a backend publishes its announcement
    Syntax:ProxyBeaconInterval interval
    Default:ProxyBeaconInterval 5
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconInterval directive sets how frequently + a backend (a ProxyBeaconAddress server) publishes its + announcement. It uses the + time-interval directive syntax and + defaults to seconds; the default is 5 seconds.

    + +

    The interval must be meaningfully smaller than the proxy's + ProxyBeaconTimeout, so that the occasional lost or + delayed announcement does not cause a healthy backend to be evicted.

    + +
    +
    top
    +

    ProxyBeaconListen Directive

    + + + + + + +
    Description:Address on which the reverse proxy receives backend +beacons
    Syntax:ProxyBeaconListen [address][:port]
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconListen directive marks a server as + the beacon receiver (the reverse proxy). It binds a UDP socket to + the given address, e.g. 0.0.0.0:5555 to receive on all + interfaces. A leading scheme (such as tcp://) is accepted and + ignored.

    + +

    The address and port are both optional and, when omitted, are inherited + from this server's own address and port (its Listen/ServerName). With no argument at all, the beacon + listener binds the server's own address and port; given just an address it + inherits the port, and so on. Because UDP and TCP are independent port + spaces, binding the beacon socket to the server's port does not + collide with the server's TCP listener — letting the beacon channel + share the service endpoint, which also identifies the proxy to backends by + its real address. (The listener binds in an unprivileged child, so a + privileged port such as 80 or 443 cannot be shared this way; use the + server's port only when it is non-privileged.)

    + +

    Backends send to this address via + ProxyBeaconAddress. The directive should be used + together with ProxyBeaconBalancer; without it, + announcements are received and logged but no members are added. + ProxyBeaconListen and + ProxyBeaconAddress are mutually exclusive on the same + server.

    + +
    +
    top
    +

    ProxyBeaconMaxSkew Directive

    + + + + + + +
    Description:Maximum allowed age of a signed announcement
    Syntax:ProxyBeaconMaxSkew interval
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconMaxSkew directive sets the anti-replay + window used when ProxyBeaconSecret is configured: the + proxy rejects any announcement whose signed timestamp differs from the + current time by more than this amount, in either direction. It uses the + time-interval directive syntax and + defaults to seconds.

    + +

    If unset, the default is 30 seconds. A larger window tolerates greater + clock skew between hosts; a smaller window bounds the freshness check. Note + that the per-backend strictly-increasing-timestamp check (see + ProxyBeaconSecret) blocks replays regardless of this + window. This directive is used on the proxy.

    + +
    +
    top
    +

    ProxyBeaconSecret Directive

    + + + + + + +
    Description:Pre-shared secret used to authenticate announcements
    Syntax:ProxyBeaconSecret secret
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconSecret directive sets a pre-shared + cluster secret. It must be configured with the same value on the + reverse proxy and on every backend. The backend (sender) signs each + announcement with a keyed message-authentication code (a SipHash MAC) derived + from the secret, together with a timestamp; the proxy (receiver) recomputes the MAC and + checks the timestamp, dropping any announcement that is forged, tampered + with, or replayed. Replayed messages are caught two ways: a freshness window + (ProxyBeaconMaxSkew) rejects old timestamps, and a + per-backend check rejects any announcement whose timestamp does not strictly + advance, so a captured-and-resent message (for example, one replayed to keep + a dead backend from being evicted) is dropped.

    + +

    If ProxyBeaconSecret is set on the proxy, every + announcement must carry a valid, recent MAC or it is rejected. If the + secrets on the proxy and a backend differ, that backend's announcements are + silently rejected (and logged), which appears as the backend never joining + the balancer.

    + +

    If no secret is configured the channel is unauthenticated and the proxy + emits a warning when it starts listening. Because the secret is stored in + the configuration file, restrict that file's permissions as you would for a + private key.

    + +

    Clock synchronisation

    +

    The timestamp-based replay protection compares the announcement's time + against the proxy's clock, so the proxy and backends must have reasonably + synchronised clocks (for example via NTP). See + ProxyBeaconMaxSkew.

    +
    + +
    +
    top
    +

    ProxyBeaconTimeout Directive

    + + + + + + + +
    Description:How long the proxy waits, without an announcement, before a backend +is taken out of rotation
    Syntax:ProxyBeaconTimeout interval
    Default:ProxyBeaconTimeout 0
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_beacon
    +

    The ProxyBeaconTimeout directive sets how long the + reverse proxy will wait for an announcement from a backend before disabling + that backend's balancer member (taking it out of rotation). A later + announcement from the same backend re-enables it. It uses the + time-interval directive syntax and + defaults to seconds.

    + +

    The default, 0, disables eviction entirely: backends are + added when they announce but are never automatically removed. Set this to a + small multiple of the backends' ProxyBeaconInterval to + enable self-healing membership. This directive is used on the proxy.

    + +
    +
    +
    +

    Available Languages:  en  | + fr 

    +
    + \ No newline at end of file diff --git a/docs/manual/mod/mod_proxy_beacon.html.fr.utf8 b/docs/manual/mod/mod_proxy_beacon.html.fr.utf8 new file mode 100644 index 00000000000..adb9a6880d4 --- /dev/null +++ b/docs/manual/mod/mod_proxy_beacon.html.fr.utf8 @@ -0,0 +1,466 @@ + + + + +mod_proxy_beacon - Serveur HTTP Apache Version 2.5 + + + + + + + + +
    <-
    + +
    +

    Module Apache mod_proxy_beacon

    + +
    +

    Langues Disponibles:  en  | + fr 

    +
    + + + + +
    Description:Inscription dynamique comme membre d’un répartiteur de charge où +les serveurs dorsaux s’annoncent eux-mêmes au mandataire inverse à l’aide de +datagrammes UDP unicast
    Statut:Extension
    Identificateur de Module:proxy_beacon_module
    Fichier Source:mod_proxy_beacon.c
    Compatibilité:Disponible à partir de la version 2.5 du serveur HTTP Apache
    +

    Sommaire

    + +

    Ce module permet à des serveurs dorsaux de s’annoncer eux-mêmes + à un mandataire inverse frontal qui les ajoute alors en tant que membre + actif (worker) d’un répartiteur de charge de + mod_proxy_balancer. Lorsqu’un serveur dorsal cesse de + s’annoncer, le mandataire l’enlève de la rotation. Cela permet une gestion + autonome (inscriptions et maintenance) de la liste des membres du + répartiteur sans avoir à éditer la configuration du mandataire ou piloter le + balancer-manager à la main.

    + +

    La communication utilise des datagrammes pleinement unicast + UDP (pas de multicast qui est filtré sur la plupart des réseaux et + ne passe pas sur l’Internet public). Les données sont transmises du serveur + dorsal vers le mandataire :

    + +
      +
    • Le mandataire inverse se lie à un socket UDP et reçoit les + données sur une adresse fixe (ProxyBeaconListen).
    • +
    • Chaque serveur dorsal envoie périodiquement un court + datagramme d’annonce au mandataire + (ProxyBeaconAddress), indiquant son propre URL + routable (ProxyBeaconAdvertise).
    • +
    + +

    Les datagrammes sont envoyés en mode « fire-and-forget » : une annonce + perdue est récupérée par la prochaine annonce périodique, et le + réordonnancement est rejeté par une vérification d’horodatage par serveur + dorsal ; aucune connexion, reconnection ou couche de cadrage n’est donc + nécessaire.

    + +

    Au niveau du mandataire, la directive + ProxyBeaconBalancer nomme le répartiteur de charge + auquel des serveurs dorsaux qui se sont annoncés ont été ajoutés. Les + changements d’appartenance s’appliquent en utilisant le même mécanisme + interne que l’interface web balancer-manager ; un serveur + dorsal ajouté de cette manière se comporte donc exactement comme un + BalancerMember configuré + statiquement ou ajouté manuellement, et est visible et éditable dans + balancer-manager.

    + +

    Ce module nécessite les services de mod_watchdog et + mod_proxy_balancer. Le travail d’arrière-plan (écoute, + publication, ajout et suppression de membres) est effectué par un seul + processus enfant de mod_watchdog ; il n’est donc pas + disponible avec le comportement du MPM prefork où ce singleton + ne peut pas s’exécuter.

    + +

    Authentification

    +

    Tout hôte qui peut atteindre le port de réception du mandataire peut + aussi annoncer un URL de serveur dorsal arbitraire et faire que le + mandataire envoie le trafic du client à ce dernier (et une adresse source + UDP est facile à usurper). La directive + ProxyBeaconSecret est par conséquent + requise : elle doit être définie avec la même valeur sur le + mandataire et sur chaque serveur dorsal, et le serveur refusera de démarrer + si elle est omise sur un des serveurs impliqués. Les annonces sont + authentifiées avec un code d’authentification de message avec clé (MAC) et + un horodatage, et le mandataire rejette toute annonce qui n’est pas signée + de manière valable ou qui est trop ancienne. Il n’existe pas de mode non + autentifié.

    +
    + +

    Confidentialité

    +

    Les annonces sont authentifiées mais non chiffrées ; la charge utile + comporte des métadonnées opérationnelles (URLs de serveur dorsal) non + chiffrées. La confidentialité du transport (par exemple DTLS) + n’est actuellement pas prise en charge et fera l’objet d’une couche + séparée.

    +
    + +
    + +
    top
    +
    +

    Exemple d’utilisation

    + + +

    L’exemple suivant configure un répartiteur de charge à enregistrement + autonome. Les serveurs dorsaux n’ont pas besoin de se connaître entre eux et + le mandataire n’a pas besoin d’entrées BalancerMember prédéclarées — seulement + un répartiteur vide avec de la place pour grossir.

    + +

    Sur le mandataire inverse :

    +
    # Réception des annonces des serveurs dorsaux sur
    +# l’interface réseau de cluster (UDP).
    +ProxyBeaconListen 0.0.0.0:5555
    +ProxyBeaconSecret    "une_grande_phrase_secrète_partagée_aléatoire_de_cluster"
    +ProxyBeaconBalancer  cluster
    +
    +# Un serveur dorsal est éjecté de la rotation s’il ne
    +# s’annonce pas pendant 30 secondes.
    +ProxyBeaconTimeout   30
    +
    +# Un répartiteur initialement vide avec des emplacements
    +# libres pour les membres dynamiques.
    +<Proxy balancer://cluster>
    +  ProxySet growth=16
    +</Proxy>
    +ProxyPass        "/" "balancer://cluster/"
    +ProxyPassReverse "/" "balancer://cluster/"
    + + +

    Sur chaque serveur dorsal :

    +
    # Annoncer au mandataire cette adresse routable de serveur dorsal
    +# toutes les 10 secondes (UDP).
    +ProxyBeaconAddress   proxy.example.com:5555
    +ProxyBeaconAdvertise http://10.0.0.5:8080
    +ProxyBeaconSecret    "une_grande_phrase_secrète_partagée_aléatoire_de_cluster"
    +ProxyBeaconInterval  10
    + + +

    Au démarrage d’un serveur dorsal, ce dernier commence à s’annoncer. Le + mandataire vérifie la validité de chaque annonce à l’aide de la phrase + secrète, ajoute http://10.0.0.5:8080 comme membre de + balancer://cluster, et l’active. Si ce serveur dorsal arrête de + s’annoncer pendant une durée supérieure à la valeur de la directive + ProxyBeaconTimeout, le mandataire le désactive (en + l’enlevant de la rotation) ; si le serveur dorsal s’annonce à nouveau, il + est réactivé.

    + +
    +

    Un serveur dorsal ajouté à l’exécution occupe un des emplacements + du répartiteur pour la durée de vie du processus serveur ; plutôt que de le + supprimer lorsqu’il arrête de s’annoncer, il est désactivé, suivant en cela + le comportement du balancer-manager (qui peut ajouter des + membres à l’exécution, mais pas les supprimer). La taille du répartiteur + augmente jusqu’au nombre maximal de serveurs dorsaux que vous + souhaitez enregistrer.

    +
    + +
    +
    top
    +

    Directive ProxyBeaconAddress

    + + + + + + +
    Description:Adresse du mandataire inverse à laquelle un serveur dorsal envoie +ses annonces
    Syntaxe:ProxyBeaconAddress address:port
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconAddress marque un serveur + comme émetteur d’annonces (un serveur dorsal). Ce dernier envoie + des datagrammes UDP à l’adresse ProxyBeaconListen du + mandataire sous la forme adresse:port, par exemple + proxy.example.com:5555 (un préfixe de protocole tel que + tcp:// est accepté, mais ignoré). Étant donné que UDP est sans + connexion, un serveur dorsal peut être démarré avant que le mandataire soit + disponible : les datagrammes seront simplement supprimés et continueront à + être envoyés selon l’intervalle spécifié.

    + +

    Utilisez la directive ProxyBeaconAdvertise pour + spécifier l’URL routable qu’annonce le serveur dorsal. Les + directives ProxyBeaconListen et + ProxyBeaconAddress sont mutuellement exclusives sur + un même serveur.

    + +
    +
    top
    +

    Directive ProxyBeaconAdvertise

    + + + + + + +
    Description:L’URL routable qu’annonce le serveur dorsal au mandataire inverse
    Syntaxe:ProxyBeaconAdvertise url
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconAdvertise permet de + définir l’adresse à laquelle le serveur dorsal peut être atteint (par + exemple http://10.0.0.5:8080) et que le mandataire ajoutera en + tant que membre BalancerMember. + Il doit s’agir d’un URL complet comme scheme://host[:port] que + le mandataire pourra atteindre — pas l’adresse d’écoute locale — + et qui sera validé lors de l’analyse de la configuration.

    + +

    Cette directive est utilisée sur un serveur dorsal avec la directive + ProxyBeaconAddress. Si elle est omise, le serveur + dorsal envoie quand-même un signe de vie, mais pas d’URL ; le mandataire + journalise alors l’annonce sans ajouter de membre.

    + +
    +
    top
    +

    Directive ProxyBeaconBalancer

    + + + + + + +
    Description:Le nom du répartiteur de charge auquel les serveurs dorsaux +annoncés sont ajoutés
    Syntaxe:ProxyBeaconBalancer name
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconBalancer permet de nommer + le répartiteur, sur le mandataire inverse, dans lequel les serveurs dorsaux + annoncés sont insérés en tant que membres. Indiquez seulement le nom du + répartiteur (par exemple cluster pour + balancer://cluster) ; le préfixe balancer:// est + accepté et supprimé.

    + +

    Le répartiteur nommé doit exister et disposer d’emplacements vides. + Déclarez-le dans un bloc <Proxy> avec un paramètre + growth (ou utilisez la valeur de la directive BalancerGrowth) de façon qu’il y ait des + emplacements libres pour l’ajout dynamique de membres. Cette directive est + utilisée conjointement avec la directive + ProxyBeaconListen.

    + +
    +
    top
    +

    Directive ProxyBeaconInterval

    + + + + + + + +
    Description:Périodicité de l’envoi d’annonces par le serveur dorsal
    Syntaxe:ProxyBeaconInterval interval
    Défaut:ProxyBeaconInterval 5
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconInterval permet de définir + la périodicité à laquelle un serveur dorsal (un serveur + ProxyBeaconAddress) envoie ses annonces. Elle utilise + la syntaxe de la directive time-interval et sa valeur s’exprime + par défaut en secondes ; sa valeur par défaut est 5 secondes.

    + +

    L’intervalle doit être significativement plus petit que la valeur de la + directive ProxyBeaconTimeout, de façon qu’une perte + occasionnelle ou qu’une annonce retardée ne provoquent pas l’éviction d’un + serveur dorsal opérationnel.

    + +
    +
    top
    +

    Directive ProxyBeaconListen

    + + + + + + +
    Description:Adresse sur laquelle le mandataire inverse reçoit les annonces des +serveurs dorsaux
    Syntaxe:ProxyBeaconListen [address][:port]
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconListen marque un serveur + comme récepteur « phare » (le mandataire inverse). Il lie un socket + UDP à l’adresse spécifiée, par exemple 0.0.0.0:5555 pour + effectuer la réception sur toutes les interfaces. Un préfixe de protocole + (tel que tcp://) est accepté et ignoré.

    + +

    L’adresse et le port sont facultatifs et, s’ils sont omis, sont hérités + de l’adresse et du port de ce serveur (ses directives Listen et ServerName). Si aucun argument n’est fourni, + l’écouteur du « phare » lie les propres adresse et port du serveur ; si + seule l’adresse est donnée, le port est hérité, et ainsi de suite. Étant + donné que UDP et TCP sont des espaces de port indépendants, lier le socket + du « phare » au port du serveur n’entre pas en collision avec + l’écouteur TCP du serveur — faisant que le canal du « phare » partage + le point de terminaison du service, qui identifie aussi le mandataire auprès + des serveurs dorsaux avec son adresse réelle (comme l’écouteur effectue ses + liens dans un processus enfant non privilégié, un port privilégié comme 80 + ou 443 ne peut pas être partagé de cette manière ; n’utilisez le port du + serveur que s’il est non privilégié).

    + +

    Les serveurs dorsaux envoient leurs annonces à l’adresse spécifiée par la + directive ProxyBeaconAddress. Cette dernière doit + être utilisée conjointement avec la directive + ProxyBeaconBalancer ; dans le cas contraire, les + annonces sont reçues et journalisées, mais aucun membre n’est ajouté. Les + directives ProxyBeaconListen et + ProxyBeaconAddress sont mutuellement exclusives sur + un même serveur.

    + +
    +
    top
    +

    Directive ProxyBeaconMaxSkew

    + + + + + + +
    Description:Age maximal autorisé d’une annonce signée
    Syntaxe:ProxyBeaconMaxSkew interval
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconMaxSkew permet de définir + la fenêtre anti-réémission utilisée lorsque la directive + ProxyBeaconSecret est configurée : le mandataire + rejette toute annonce dont l’horodatage signé diffère du temps actuel d’une + valeur supérieure à celle de la directive + ProxyBeaconMaxSkew, et cela dans les deux directions. + Cette directive utilise la syntaxe de la directive time-interval et sa valeur s’exprime + par défaut en secondes.

    + +

    Si elle n’est pas définie, sa valeur par défaut est de 30 secondes. Une + fenêtre plus large tolère des écarts d’horloge plus grands entre les hôtes ; + une fenêtre plus petite restreint la tolérance sur la vérification de + fraîcheur. Notez que la vérification de la croissance stricte des + horodatages d’un même serveur (voir la directive + ProxyBeaconSecret) bloque les réémissions, quelle que + soit la valeur de cette fenêtre. Cette directive est utilisée au niveau du + mandataire.

    + +
    +
    top
    +

    Directive ProxyBeaconSecret

    + + + + + + +
    Description:Phrase secrète partagée à l’avance pour authentifier les annonces +des serveurs dorsaux
    Syntaxe:ProxyBeaconSecret secret
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconSecret permet de définir + une phrase secrète partagée à l’avance au sein de la grappe de serveurs. + Elle doit être définie avec la même valeur sur le mandataire + inverse et sur chaque serveur dorsal. Le serveur dorsal (l’émetteur) signe + chaque annonce avec un message-authentication code (un SipHash MAC) avec + clé, dérivé de la phrase secrète et avec un horodatage ; le mandataire (le + récepteur) recalcule le MAC et vérifie l’horodatage, en rejetant toute + annonce falsifiée, usurpée ou réenvoyée. Les messages réenvoyés sont + interceptés de deux manières : une fenêtre de fraîcheur (directive + ProxyBeaconMaxSkew) rejette les horodatages anciens, + et une vérification pour chaque serveur dorsal rejette toute annonce dont + l’horodatage n’avance pas strictement ; ainsi, un message capturé et renvoyé + (par exemple pour empêcher l’éviction d’un serveur dorsal éteint) sera + rejeté.

    + +

    Cette directive est requise sur chaque serveur impliqué dans le canal du + mandataire phare — le mandataire + (ProxyBeaconListen) et chaque serveur dorsal + (ProxyBeaconAddress). Si elle est omise sur un de ces + serveurs, le serveur refusera de démarrer ; il n’existe pas de mode non + authentifié.

    + +

    Toute annonce dont le MAC n’est pas valable et récent sera rejetée. Si + les phrases secrètes du mandataire et d’un serveur dorsal diffèrent, les + annonces de ce dernier seront rejetées silencieusement (et journalisées), ce + qui donne l’impression que le serveur dorsal n’a jamais atteint le + répartiteur de charge.

    + +

    Étant donné que la phrase secrète est stockée dans le fichier de + configuration, définissez les permissions de ce dernier comme s’il + s’agissait d’une clé privée.

    + +

    Synchronisation de l’horloge

    +

    La protection contre la réémission basée sur l’horodatage compare le + moment de l’annonce avec l’horloge du mandataire ; le mandataire et les + serveurs dorsaux doivent donc avoir des horloges correctement synchronisées + (par exemple à l’aide de NTP). Voir la directive + ProxyBeaconMaxSkew.

    +
    + +
    +
    top
    +

    Directive ProxyBeaconTimeout

    + + + + + + + +
    Description:Durée maximale de l’absence d’annonce d’un serveur dorsal au bout +de laquelle le mandataire enlève ce dernier de la rotation
    Syntaxe:ProxyBeaconTimeout interval
    Défaut:ProxyBeaconTimeout 0
    Contexte:configuration globale, serveur virtuel
    Statut:Extension
    Module:mod_proxy_beacon
    +

    La directive ProxyBeaconTimeout permet de définir + la durée maximale pendant laquelle le mandataire attendra une annonce en + provenance d’un serveur dorsal avant de désactiver ce dernier (en l’enlevant + de la rotation). Si ce serveur dorsal renvoie une annonce par la suite, il + est réactivé. Cette directive utilise + la syntaxe de la directive time-interval et sa valeur s’exprime + par défaut en secondes.

    + +

    La valeur par défaut, 0, désactive complètement l’éviction : + les serveurs dorsaux sont ajoutés lorsqu’ils s’annoncent mais ne sont jamais + désactivés automatiquement. Définissez cette directive à un multiple de + (quelques fois) la valeur de la directive + ProxyBeaconInterval du serveur dorsal pour mettre en + œuvre une maintenance autonome des adhésions. Cette directive est définie + sur le mandataire.

    + +
    +
    +
    +

    Langues Disponibles:  en  | + fr 

    +
    + \ No newline at end of file diff --git a/docs/manual/mod/mod_proxy_beacon.xml b/docs/manual/mod/mod_proxy_beacon.xml index c4ac7c70db4..413e8b952c5 100644 --- a/docs/manual/mod/mod_proxy_beacon.xml +++ b/docs/manual/mod/mod_proxy_beacon.xml @@ -73,13 +73,13 @@ to the reverse proxy over unicast UDP datagrams Authentication

    Any host that can reach the proxy's receive port could otherwise announce an arbitrary backend URL and cause the proxy to send client traffic to it - (and a UDP source address is trivially spoofable). Set - ProxyBeaconSecret to the same value on the proxy and on - every backend so that announcements are authenticated with a keyed - message-authentication code (MAC) and a timestamp. When a secret is - configured the proxy drops any announcement that is not validly signed and - recent. If no secret is configured the channel is unauthenticated - and the proxy logs a warning at startup.

    + (and a UDP source address is trivially spoofable). + ProxyBeaconSecret is therefore required: + it must be set to the same value on the proxy and on every backend, and the + server fails to start if any participating server omits it. Announcements are + authenticated with a keyed message-authentication code (MAC) and a timestamp, + and the proxy drops any announcement that is not validly signed and recent. + There is no unauthenticated mode.

    Confidentiality @@ -321,16 +321,19 @@ is taken out of rotation advance, so a captured-and-resent message (for example, one replayed to keep a dead backend from being evicted) is dropped.

    -

    If ProxyBeaconSecret is set on the proxy, every - announcement must carry a valid, recent MAC or it is rejected. If the +

    This directive is required on every server that + participates in the beacon channel — the proxy + (ProxyBeaconListen) and every backend + (ProxyBeaconAddress). If any such server omits it, the + server fails to start; there is no unauthenticated mode.

    + +

    Every announcement must carry a valid, recent MAC or it is rejected. If the secrets on the proxy and a backend differ, that backend's announcements are silently rejected (and logged), which appears as the backend never joining the balancer.

    -

    If no secret is configured the channel is unauthenticated and the proxy - emits a warning when it starts listening. Because the secret is stored in - the configuration file, restrict that file's permissions as you would for a - private key.

    +

    Because the secret is stored in the configuration file, restrict that + file's permissions as you would for a private key.

    Clock synchronisation

    The timestamp-based replay protection compares the announcement's time diff --git a/docs/manual/mod/mod_proxy_beacon.xml.fr b/docs/manual/mod/mod_proxy_beacon.xml.fr new file mode 100644 index 00000000000..fd7e493e7ca --- /dev/null +++ b/docs/manual/mod/mod_proxy_beacon.xml.fr @@ -0,0 +1,422 @@ + + + + + + + + + + +mod_proxy_beacon +Inscription dynamique comme membre d’un répartiteur de charge où +les serveurs dorsaux s’annoncent eux-mêmes au mandataire inverse à l’aide de +datagrammes UDP unicast +Extension +mod_proxy_beacon.c +proxy_beacon_module +Disponible à partir de la version 2.5 du serveur HTTP Apache + +

    +

    Ce module permet à des serveurs dorsaux de s’annoncer eux-mêmes + à un mandataire inverse frontal qui les ajoute alors en tant que membre + actif (worker) d’un répartiteur de charge de + mod_proxy_balancer. Lorsqu’un serveur dorsal cesse de + s’annoncer, le mandataire l’enlève de la rotation. Cela permet une gestion + autonome (inscriptions et maintenance) de la liste des membres du + répartiteur sans avoir à éditer la configuration du mandataire ou piloter le + balancer-manager à la main.

    + +

    La communication utilise des datagrammes pleinement unicast + UDP (pas de multicast qui est filtré sur la plupart des réseaux et + ne passe pas sur l’Internet public). Les données sont transmises du serveur + dorsal vers le mandataire :

    + +
      +
    • Le mandataire inverse se lie à un socket UDP et reçoit les + données sur une adresse fixe (ProxyBeaconListen).
    • +
    • Chaque serveur dorsal envoie périodiquement un court + datagramme d’annonce au mandataire + (ProxyBeaconAddress), indiquant son propre URL + routable (ProxyBeaconAdvertise).
    • +
    + +

    Les datagrammes sont envoyés en mode « fire-and-forget » : une annonce + perdue est récupérée par la prochaine annonce périodique, et le + réordonnancement est rejeté par une vérification d’horodatage par serveur + dorsal ; aucune connexion, reconnection ou couche de cadrage n’est donc + nécessaire.

    + +

    Au niveau du mandataire, la directive + ProxyBeaconBalancer nomme le répartiteur de charge + auquel des serveurs dorsaux qui se sont annoncés ont été ajoutés. Les + changements d’appartenance s’appliquent en utilisant le même mécanisme + interne que l’interface web balancer-manager ; un serveur + dorsal ajouté de cette manière se comporte donc exactement comme un + BalancerMember configuré + statiquement ou ajouté manuellement, et est visible et éditable dans + balancer-manager.

    + +

    Ce module nécessite les services de mod_watchdog et + mod_proxy_balancer. Le travail d’arrière-plan (écoute, + publication, ajout et suppression de membres) est effectué par un seul + processus enfant de mod_watchdog ; il n’est donc pas + disponible avec le comportement du MPM prefork où ce singleton + ne peut pas s’exécuter.

    + +Authentification +

    Tout hôte qui peut atteindre le port de réception du mandataire peut + aussi annoncer un URL de serveur dorsal arbitraire et faire que le + mandataire envoie le trafic du client à ce dernier (et une adresse source + UDP est facile à usurper). La directive + ProxyBeaconSecret est par conséquent + requise : elle doit être définie avec la même valeur sur le + mandataire et sur chaque serveur dorsal, et le serveur refusera de démarrer + si elle est omise sur un des serveurs impliqués. Les annonces sont + authentifiées avec un code d’authentification de message avec clé (MAC) et + un horodatage, et le mandataire rejette toute annonce qui n’est pas signée + de manière valable ou qui est trop ancienne. Il n’existe pas de mode non + autentifié.

    +
    + +Confidentialité +

    Les annonces sont authentifiées mais non chiffrées ; la charge utile + comporte des métadonnées opérationnelles (URLs de serveur dorsal) non + chiffrées. La confidentialité du transport (par exemple DTLS) + n’est actuellement pas prise en charge et fera l’objet d’une couche + séparée.

    +
    + +
    +mod_proxy +mod_proxy_balancer +mod_proxy_hcheck +mod_watchdog + +
    + Exemple d’utilisation + +

    L’exemple suivant configure un répartiteur de charge à enregistrement + autonome. Les serveurs dorsaux n’ont pas besoin de se connaître entre eux et + le mandataire n’a pas besoin d’entrées BalancerMember prédéclarées — seulement + un répartiteur vide avec de la place pour grossir.

    + +

    Sur le mandataire inverse :

    + +# Réception des annonces des serveurs dorsaux sur +# l’interface réseau de cluster (UDP). +ProxyBeaconListen 0.0.0.0:5555 +ProxyBeaconSecret "une_grande_phrase_secrète_partagée_aléatoire_de_cluster" +ProxyBeaconBalancer cluster + +# Un serveur dorsal est éjecté de la rotation s’il ne +# s’annonce pas pendant 30 secondes. +ProxyBeaconTimeout 30 + +# Un répartiteur initialement vide avec des emplacements +# libres pour les membres dynamiques. +<Proxy balancer://cluster> + ProxySet growth=16 +</Proxy> +ProxyPass "/" "balancer://cluster/" +ProxyPassReverse "/" "balancer://cluster/" + + +

    Sur chaque serveur dorsal :

    + +# Annoncer au mandataire cette adresse routable de serveur dorsal +# toutes les 10 secondes (UDP). +ProxyBeaconAddress proxy.example.com:5555 +ProxyBeaconAdvertise http://10.0.0.5:8080 +ProxyBeaconSecret "une_grande_phrase_secrète_partagée_aléatoire_de_cluster" +ProxyBeaconInterval 10 + + +

    Au démarrage d’un serveur dorsal, ce dernier commence à s’annoncer. Le + mandataire vérifie la validité de chaque annonce à l’aide de la phrase + secrète, ajoute http://10.0.0.5:8080 comme membre de + balancer://cluster, et l’active. Si ce serveur dorsal arrête de + s’annoncer pendant une durée supérieure à la valeur de la directive + ProxyBeaconTimeout, le mandataire le désactive (en + l’enlevant de la rotation) ; si le serveur dorsal s’annonce à nouveau, il + est réactivé.

    + + +

    Un serveur dorsal ajouté à l’exécution occupe un des emplacements + du répartiteur pour la durée de vie du processus serveur ; plutôt que de le + supprimer lorsqu’il arrête de s’annoncer, il est désactivé, suivant en cela + le comportement du balancer-manager (qui peut ajouter des + membres à l’exécution, mais pas les supprimer). La taille du répartiteur + augmente jusqu’au nombre maximal de serveurs dorsaux que vous + souhaitez enregistrer.

    +
    + +
    + + +ProxyBeaconListen +Adresse sur laquelle le mandataire inverse reçoit les annonces des +serveurs dorsaux +ProxyBeaconListen [address][:port] +server configvirtual host + + + +

    La directive ProxyBeaconListen marque un serveur + comme récepteur « phare » (le mandataire inverse). Il lie un socket + UDP à l’adresse spécifiée, par exemple 0.0.0.0:5555 pour + effectuer la réception sur toutes les interfaces. Un préfixe de protocole + (tel que tcp://) est accepté et ignoré.

    + +

    L’adresse et le port sont facultatifs et, s’ils sont omis, sont hérités + de l’adresse et du port de ce serveur (ses directives Listen et ServerName). Si aucun argument n’est fourni, + l’écouteur du « phare » lie les propres adresse et port du serveur ; si + seule l’adresse est donnée, le port est hérité, et ainsi de suite. Étant + donné que UDP et TCP sont des espaces de port indépendants, lier le socket + du « phare » au port du serveur n’entre pas en collision avec + l’écouteur TCP du serveur — faisant que le canal du « phare » partage + le point de terminaison du service, qui identifie aussi le mandataire auprès + des serveurs dorsaux avec son adresse réelle (comme l’écouteur effectue ses + liens dans un processus enfant non privilégié, un port privilégié comme 80 + ou 443 ne peut pas être partagé de cette manière ; n’utilisez le port du + serveur que s’il est non privilégié).

    + +

    Les serveurs dorsaux envoient leurs annonces à l’adresse spécifiée par la + directive ProxyBeaconAddress. Cette dernière doit + être utilisée conjointement avec la directive + ProxyBeaconBalancer ; dans le cas contraire, les + annonces sont reçues et journalisées, mais aucun membre n’est ajouté. Les + directives ProxyBeaconListen et + ProxyBeaconAddress sont mutuellement exclusives sur + un même serveur.

    +
    +
    + + +ProxyBeaconAddress +Adresse du mandataire inverse à laquelle un serveur dorsal envoie +ses annonces +ProxyBeaconAddress address:port +server configvirtual host + + + +

    La directive ProxyBeaconAddress marque un serveur + comme émetteur d’annonces (un serveur dorsal). Ce dernier envoie + des datagrammes UDP à l’adresse ProxyBeaconListen du + mandataire sous la forme adresse:port, par exemple + proxy.example.com:5555 (un préfixe de protocole tel que + tcp:// est accepté, mais ignoré). Étant donné que UDP est sans + connexion, un serveur dorsal peut être démarré avant que le mandataire soit + disponible : les datagrammes seront simplement supprimés et continueront à + être envoyés selon l’intervalle spécifié.

    + +

    Utilisez la directive ProxyBeaconAdvertise pour + spécifier l’URL routable qu’annonce le serveur dorsal. Les + directives ProxyBeaconListen et + ProxyBeaconAddress sont mutuellement exclusives sur + un même serveur.

    +
    +
    + + +ProxyBeaconAdvertise +L’URL routable qu’annonce le serveur dorsal au mandataire inverse +ProxyBeaconAdvertise url +server configvirtual host + + + +

    La directive ProxyBeaconAdvertise permet de + définir l’adresse à laquelle le serveur dorsal peut être atteint (par + exemple http://10.0.0.5:8080) et que le mandataire ajoutera en + tant que membre BalancerMember. + Il doit s’agir d’un URL complet comme scheme://host[:port] que + le mandataire pourra atteindre — pas l’adresse d’écoute locale — + et qui sera validé lors de l’analyse de la configuration.

    + +

    Cette directive est utilisée sur un serveur dorsal avec la directive + ProxyBeaconAddress. Si elle est omise, le serveur + dorsal envoie quand-même un signe de vie, mais pas d’URL ; le mandataire + journalise alors l’annonce sans ajouter de membre.

    +
    +
    + + +ProxyBeaconBalancer +Le nom du répartiteur de charge auquel les serveurs dorsaux +annoncés sont ajoutés +ProxyBeaconBalancer name +server configvirtual host + + + +

    La directive ProxyBeaconBalancer permet de nommer + le répartiteur, sur le mandataire inverse, dans lequel les serveurs dorsaux + annoncés sont insérés en tant que membres. Indiquez seulement le nom du + répartiteur (par exemple cluster pour + balancer://cluster) ; le préfixe balancer:// est + accepté et supprimé.

    + +

    Le répartiteur nommé doit exister et disposer d’emplacements vides. + Déclarez-le dans un bloc <Proxy> avec un paramètre + growth (ou utilisez la valeur de la directive BalancerGrowth) de façon qu’il y ait des + emplacements libres pour l’ajout dynamique de membres. Cette directive est + utilisée conjointement avec la directive + ProxyBeaconListen.

    +
    +
    + + +ProxyBeaconInterval +Périodicité de l’envoi d’annonces par le serveur dorsal +ProxyBeaconInterval interval +ProxyBeaconInterval 5 +server configvirtual host + + + +

    La directive ProxyBeaconInterval permet de définir + la périodicité à laquelle un serveur dorsal (un serveur + ProxyBeaconAddress) envoie ses annonces. Elle utilise + la syntaxe de la directive time-interval et sa valeur s’exprime + par défaut en secondes ; sa valeur par défaut est 5 secondes.

    + +

    L’intervalle doit être significativement plus petit que la valeur de la + directive ProxyBeaconTimeout, de façon qu’une perte + occasionnelle ou qu’une annonce retardée ne provoquent pas l’éviction d’un + serveur dorsal opérationnel.

    +
    +
    + + +ProxyBeaconTimeout +Durée maximale de l’absence d’annonce d’un serveur dorsal au bout +de laquelle le mandataire enlève ce dernier de la rotation +ProxyBeaconTimeout interval +ProxyBeaconTimeout 0 +server configvirtual host + + + +

    La directive ProxyBeaconTimeout permet de définir + la durée maximale pendant laquelle le mandataire attendra une annonce en + provenance d’un serveur dorsal avant de désactiver ce dernier (en l’enlevant + de la rotation). Si ce serveur dorsal renvoie une annonce par la suite, il + est réactivé. Cette directive utilise + la syntaxe de la directive time-interval et sa valeur s’exprime + par défaut en secondes.

    + +

    La valeur par défaut, 0, désactive complètement l’éviction : + les serveurs dorsaux sont ajoutés lorsqu’ils s’annoncent mais ne sont jamais + désactivés automatiquement. Définissez cette directive à un multiple de + (quelques fois) la valeur de la directive + ProxyBeaconInterval du serveur dorsal pour mettre en + œuvre une maintenance autonome des adhésions. Cette directive est définie + sur le mandataire.

    +
    +
    + + +ProxyBeaconSecret +Phrase secrète partagée à l’avance pour authentifier les annonces +des serveurs dorsaux +ProxyBeaconSecret secret +server configvirtual host + + + +

    La directive ProxyBeaconSecret permet de définir + une phrase secrète partagée à l’avance au sein de la grappe de serveurs. + Elle doit être définie avec la même valeur sur le mandataire + inverse et sur chaque serveur dorsal. Le serveur dorsal (l’émetteur) signe + chaque annonce avec un message-authentication code (un SipHash MAC) avec + clé, dérivé de la phrase secrète et avec un horodatage ; le mandataire (le + récepteur) recalcule le MAC et vérifie l’horodatage, en rejetant toute + annonce falsifiée, usurpée ou réenvoyée. Les messages réenvoyés sont + interceptés de deux manières : une fenêtre de fraîcheur (directive + ProxyBeaconMaxSkew) rejette les horodatages anciens, + et une vérification pour chaque serveur dorsal rejette toute annonce dont + l’horodatage n’avance pas strictement ; ainsi, un message capturé et renvoyé + (par exemple pour empêcher l’éviction d’un serveur dorsal éteint) sera + rejeté.

    + +

    Cette directive est requise sur chaque serveur impliqué dans le canal du + mandataire phare — le mandataire + (ProxyBeaconListen) et chaque serveur dorsal + (ProxyBeaconAddress). Si elle est omise sur un de ces + serveurs, le serveur refusera de démarrer ; il n’existe pas de mode non + authentifié.

    + +

    Toute annonce dont le MAC n’est pas valable et récent sera rejetée. Si + les phrases secrètes du mandataire et d’un serveur dorsal diffèrent, les + annonces de ce dernier seront rejetées silencieusement (et journalisées), ce + qui donne l’impression que le serveur dorsal n’a jamais atteint le + répartiteur de charge.

    + +

    Étant donné que la phrase secrète est stockée dans le fichier de + configuration, définissez les permissions de ce dernier comme s’il + s’agissait d’une clé privée.

    + + Synchronisation de l’horloge +

    La protection contre la réémission basée sur l’horodatage compare le + moment de l’annonce avec l’horloge du mandataire ; le mandataire et les + serveurs dorsaux doivent donc avoir des horloges correctement synchronisées + (par exemple à l’aide de NTP). Voir la directive + ProxyBeaconMaxSkew.

    +
    +
    +
    + + +ProxyBeaconMaxSkew +Age maximal autorisé d’une annonce signée +ProxyBeaconMaxSkew interval +server configvirtual host + + + +

    La directive ProxyBeaconMaxSkew permet de définir + la fenêtre anti-réémission utilisée lorsque la directive + ProxyBeaconSecret est configurée : le mandataire + rejette toute annonce dont l’horodatage signé diffère du temps actuel d’une + valeur supérieure à celle de la directive + ProxyBeaconMaxSkew, et cela dans les deux directions. + Cette directive utilise la syntaxe de la directive time-interval et sa valeur s’exprime + par défaut en secondes.

    + +

    Si elle n’est pas définie, sa valeur par défaut est de 30 secondes. Une + fenêtre plus large tolère des écarts d’horloge plus grands entre les hôtes ; + une fenêtre plus petite restreint la tolérance sur la vérification de + fraîcheur. Notez que la vérification de la croissance stricte des + horodatages d’un même serveur (voir la directive + ProxyBeaconSecret) bloque les réémissions, quelle que + soit la valeur de cette fenêtre. Cette directive est utilisée au niveau du + mandataire.

    +
    +
    + + diff --git a/docs/manual/mod/mod_proxy_beacon.xml.meta b/docs/manual/mod/mod_proxy_beacon.xml.meta index 3f37efddb01..b087c3346be 100644 --- a/docs/manual/mod/mod_proxy_beacon.xml.meta +++ b/docs/manual/mod/mod_proxy_beacon.xml.meta @@ -8,5 +8,6 @@ en + fr diff --git a/docs/manual/mod/mod_proxy_wstunnel.xml b/docs/manual/mod/mod_proxy_wstunnel.xml index 7c02d26c7d8..3d8dfb82f92 100644 --- a/docs/manual/mod/mod_proxy_wstunnel.xml +++ b/docs/manual/mod/mod_proxy_wstunnel.xml @@ -25,7 +25,7 @@ mod_proxy_wstunnel Websockets support module for mod_proxy -Extension +Deprecated mod_proxy_wstunnel.c proxy_wstunnel_module Available in httpd 2.4.5 and later diff --git a/docs/manual/mod/mod_rewrite.html.en.utf8 b/docs/manual/mod/mod_rewrite.html.en.utf8 index da167f9b76a..a0737f1406f 100644 --- a/docs/manual/mod/mod_rewrite.html.en.utf8 +++ b/docs/manual/mod/mod_rewrite.html.en.utf8 @@ -156,7 +156,7 @@ URLs on the fly Description:Defines a condition under which rewriting will take place Syntax: RewriteCond - TestString CondPattern [flags] + TestString [!]CondPattern [flags]
    Context:server config, virtual host, directory, .htaccess Override:FileInfo Status:Extension @@ -172,49 +172,61 @@ URLs on the fly condition is determined to be true only if the the CondPattern does not match.

    -

    TestString is a string which can contain the + + + + +

    TestString

    + +

    TestString is a string which can contain the following expanded constructs in addition to plain text:

    -
      -
    • - RewriteRule backreferences: These are - backreferences of the form $N + + +

      Backreferences

      + +
      +
      $N — RewriteRule backreferences
      +
      Backreferences of the form $N (0 <= N <= 9). $1 to $9 provide access to the grouped parts (in parentheses) of the pattern, from the RewriteRule which is subject to the current set of RewriteCond conditions. $0 provides - access to the whole string matched by that pattern. - -
      Backreferences are only defined if the pattern - matches. Thus, if the pattern is prefixed with - !, no backreferences are ever defined.
      -
    • -
    • - RewriteCond backreferences: These are - backreferences of the form %N + access to the whole string matched by that pattern.
    + +
    %N — RewriteCond backreferences
    +
    Backreferences of the form %N (0 <= N <= 9). %1 to %9 provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions. %0 provides access to the whole string matched by - that pattern. - -
    Backreferences are only defined if the pattern - matches. Thus, if the pattern is prefixed with - !, no backreferences are ever defined.
    - -
  • - RewriteMap expansions: These are - expansions of the form ${mapname:key|default}. - See the documentation for - RewriteMap for more details. -
  • -
  • - Server variables: These are variables of - the form - %{ NAME_OF_VARIABLE - } - where NAME_OF_VARIABLE can be a string taken - from the following list: + that pattern.
  • +
    + +
    Backreferences are only defined if the pattern + matches. Thus, if the pattern is prefixed with + !, no backreferences are ever defined. + See How the + Ruleset is Applied for more details on the order in which + patterns are matched and backreferences populated.
    + + + +

    RewriteMap Expansions

    + +

    These are expansions of the form ${mapname:key|default}. + See the documentation for + RewriteMap for more details.

    + + + +

    Server and CGI Variables

    + +

    These are variables of the form + %{ NAME_OF_VARIABLE + } + where NAME_OF_VARIABLE can be a string taken + from the following list:

    @@ -299,7 +311,7 @@ URLs on the fly correspond to the similarly named HTTP MIME-headers, C variables of the Apache HTTP Server or struct tm fields of the Unix system. - Most are documented in the + Most are documented in the Expressions doc, in the Environment Variables doc, or the CGI specification (RFC 3875).

    @@ -309,7 +321,30 @@ URLs on the flyUseCanonicalPhysicalPort respectively.

    -

    Those that are special to mod_rewrite include those below.

    +

    The variables SCRIPT_FILENAME and REQUEST_FILENAME + contain the same value - the value of the + filename field of the internal + request_rec structure of the Apache HTTP Server. + The first name is the commonly known CGI variable name + while the second is the appropriate counterpart of + REQUEST_URI (which contains the value of the + uri field of request_rec).

    + +

    If a substitution occurred and the rewriting continues, + the value of both variables will be updated accordingly.

    + +

    If used in per-server context (i.e., before the + request is mapped to the filesystem) SCRIPT_FILENAME and + REQUEST_FILENAME cannot contain the full local filesystem + path since the path is unknown at this stage of processing. + Both variables will initially contain the value of REQUEST_URI + in that case. In order to obtain the full local filesystem + path of the request in per-server context, use an URL-based + look-ahead %{LA-U:REQUEST_FILENAME} to determine + the final value of REQUEST_FILENAME.

    + +

    Those that are special to mod_rewrite + include those below.

    API_VERSION
    @@ -372,7 +407,7 @@ URLs on the fly such as "/index.html". This notably excludes the query string which is available as its own variable named QUERY_STRING. The value returned for - REQUEST_URI + REQUEST_URI has already been %-decoded, to re-encode it pass it through the "escape" mapping-function. Note that this server variable differs from the CGI @@ -393,79 +428,63 @@ URLs on the fly (decoded), unlike most other variables below.
    - - -

    If the TestString has the special value expr, - the CondPattern will be treated as an - ap_expr. HTTP headers referenced in the - expression will be added to the Vary header if the novary - flag is not given.

    + -

    Other things you should be aware of:

    +

    Prefixed Variable Lookups

    -
      -
    1. -

      The variables SCRIPT_FILENAME and REQUEST_FILENAME - contain the same value - the value of the - filename field of the internal - request_rec structure of the Apache HTTP Server. - The first name is the commonly known CGI variable name - while the second is the appropriate counterpart of - REQUEST_URI (which contains the value of the - uri field of request_rec).

      -

      If a substitution occurred and the rewriting continues, - the value of both variables will be updated accordingly.

      -

      If used in per-server context (i.e., before the - request is mapped to the filesystem) SCRIPT_FILENAME and - REQUEST_FILENAME cannot contain the full local filesystem - path since the path is unknown at this stage of processing. - Both variables will initially contain the value of REQUEST_URI - in that case. In order to obtain the full local filesystem - path of the request in per-server context, use an URL-based - look-ahead %{LA-U:REQUEST_FILENAME} to determine - the final value of REQUEST_FILENAME.

    2. - -
    3. - %{ENV:variable}, where variable can be - any environment variable, is also available. - This is looked-up via internal +

      In addition to the server variables above, the + %{PREFIX:name} syntax provides + access to additional sources:

      + +
      +
      %{ENV:variable}
      +
      Where variable can be + any environment variable. This is looked-up via internal Apache httpd structures and (if not found there) via - getenv() from the Apache httpd server process.
    4. + getenv() from the Apache httpd server process. -
    5. - %{SSL:variable}, where variable is the +
      %{SSL:variable}
      +
      Where variable is the name of an SSL environment - variable, can be used whether or not + variable. This can be used whether or not mod_ssl is loaded, but will always expand to the empty string if it is not. Example: %{SSL:SSL_CIPHER_USEKEYSIZE} may expand to 128. These variables are available even without setting the StdEnvVars option of the - SSLOptions directive.
    6. + SSLOptions directive. -
    7. - %{HTTP:header}, where header can be - any HTTP MIME-header name, can always be used to obtain the +
      %{HTTP:header}
      +
      Where header can be + any HTTP MIME-header name. This can always be used to obtain the value of a header sent in the HTTP request. Example: %{HTTP:Proxy-Connection} is the value of the HTTP header ``Proxy-Connection:''. -

      If a HTTP header is used in a condition this header is added to +

      If an HTTP header is used in a condition, this header is added to the Vary header of the response in case the condition evaluates to true for the request. It is not added if the condition evaluates to false for the request. Adding the HTTP header to the Vary header of the response is needed for proper caching.

      It has to be kept in mind that conditions follow a short circuit logic in the case of the 'ornext|OR' flag - so that certain conditions might not be evaluated at all.

    8. + so that certain conditions might not be evaluated at all.

      + -
    9. - %{LA-U:variable} - can be used for look-aheads which perform - an internal (URL-based) sub-request to determine the final + + +

      Look-ahead Sub-requests

      + +

      These forms perform an internal sub-request to determine the + final value of a variable that is not yet available at the current + stage of processing:

      + +
      +
      %{LA-U:variable}
      +
      Performs an internal (URL-based) sub-request to determine the final value of variable. This can be used to access - variable for rewriting which is not available at the current + a variable for rewriting which is not available at the current stage, but will be set in a later phase.

      For instance, to rewrite according to the REMOTE_USER variable from within the @@ -478,14 +497,29 @@ URLs on the fly its per-directory context via the Fixup phase of the API and because the authorization phases come before this phase, you just can use - %{REMOTE_USER} in that context.

    10. + %{REMOTE_USER} in that context.

      -
    11. - %{LA-F:variable} can be used to perform an internal - (filename-based) sub-request, to determine the final value - of variable. Most of the time, this is the same as - LA-U above.
    12. -
    +
    %{LA-F:variable}
    +
    Performs an internal (filename-based) sub-request to determine + the final value of variable. Most of the time, this is + the same as LA-U above.
    + + + + +

    Expression Syntax

    + +

    If the TestString has the special value expr, + the CondPattern will be treated as an + ap_expr. HTTP headers referenced in the + expression will be added to the Vary header if the novary + flag is not given.

    + + + + + +

    CondPattern

    CondPattern is the condition pattern, a regular expression which is applied to the @@ -498,16 +532,18 @@ URLs on the fly additional syntax available to perform other useful tests against the Teststring:

    -
      -
    1. You can prefix the pattern string with a + + +

      You can prefix the pattern string with a '!' character (exclamation mark) to negate the result of the condition, no matter what kind of CondPattern is used. -

    2. +

      + + -
    3. - You can perform lexicographical string comparisons: +

      String Comparisons

      -
      +
      <CondPattern
      Lexicographically precedes
      Treats the CondPattern as a plain string and @@ -547,21 +583,21 @@ URLs on the fly if TestString lexicographically follows CondPattern, or is equal to CondPattern (the two strings are equal, character for character).
      -
      +
      +

      Note

      The string comparison operator is part of the CondPattern argument and must be included in the quotes if those are used. Eg. - +
      RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"
      - -
    4. -
    5. - You can perform integer comparisons: -
      + + +

      Integer Comparisons

      +
      -eq
      Is numerically equal to
      The TestString is treated as an integer, and is @@ -606,32 +642,26 @@ URLs on the fly numerically compared to the CondPattern. True if the two are numerically different. This is equivalent to !-eq.
      +
      -
      -
    6. - -
    7. You can perform various file attribute tests: - + -
      +

      File Attribute Tests

      +
      -d
      -
      Is directory.
      Treats the TestString as a pathname and tests whether or not it exists, and is a directory.
      -f
      -
      Is regular file.
      - Treats the TestString as a pathname and tests whether or not it exists, and is a regular file. -
      +
      -F
      -
      Is existing file, via subrequest.
      Checks whether or not TestString is a valid file, accessible via all the server's currently-configured @@ -646,7 +676,6 @@ URLs on the fly
      -l
      -
      Is symbolic link.
      Treats the TestString as a pathname and tests whether or not it exists, and is a symbolic link. May also @@ -685,18 +714,18 @@ URLs on the fly whether or not it exists, and has executable permissions. These permissions are determined according to the underlying OS.
      +
      -
      - - For example: +

      For example:

      RewriteCond /var/www/%{REQUEST_URI} !-f
       RewriteRule ^(.+) /other/archive/$1 [R]
      -
    8. + + +

      Expression Evaluation

      -
    9. If the TestString has the special value expr, the CondPattern will be treated as an ap_expr.

      @@ -710,28 +739,31 @@ RewriteRule ^(.+) /other/archive/$1 [R]
      RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
       RewriteRule "^/images" "-" [F]
      -
    10. -
    -

    You can also set special flags for CondPattern by appending + + + + +

    Flags

    + +

    You can set special flags for CondPattern by appending [flags] as the third argument to the RewriteCond directive, where flags is a comma-separated list of any of the following flags:

    - -
      -
    • 'nocase|NC' - (no case)
      + +
      +
      'nocase|NC'
      +
      (no case)
      This makes the test case-insensitive - differences between 'A-Z' and 'a-z' are ignored, both in the expanded TestString and the CondPattern. This flag is effective only for comparisons between TestString and CondPattern. It has no - effect on filesystem and subrequest checks.
    • + effect on filesystem and subrequest checks. -
    • - 'ornext|OR' - (or next condition)
      +
      'ornext|OR'
      +
      (or next condition)
      Use this to combine rule conditions with a local OR instead of the implicit AND. Typical example: @@ -743,20 +775,24 @@ RewriteRule ...some special stuff for any of these hosts... Without this flag you would have to write the condition/rule pair three times. -
    • + -
    • 'novary|NV' - (no vary)
      - If a HTTP header is used in the condition, this flag prevents +
      'novary|NV'
      +
      (no vary)
      + If an HTTP header is used in the condition, this flag prevents this header from being added to the Vary header of the response.
      Using this flag might break proper caching of the response if the representation of this response varies on the value of this header. So this flag should be only used if the meaning of the Vary header is well understood. -
    • -
    + + -

    Example:

    + + + + +

    Example

    To rewrite the Homepage of a site according to the ``User-Agent:'' header of the request, you can @@ -1109,24 +1145,94 @@ RewriteRule "^/$" "/homepage.std.html" [L]

    What is matched?

    -

    -The Pattern is matched against the %-decoded URL-path -(in server context) or the directory-relative path (in -per-directory context). -See RewriteRule -Basics for details on what the pattern is matched against -in each context. -

    +
      +
    • In VirtualHost context, + The Pattern will initially be matched against the part of the + URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). + This is the (%-decoded) URL-path.

    • + +
    • In per-directory context + (Directory and .htaccess), + the Pattern is matched against only a partial path, for example a request + of "/app1/index.html" may result in comparison against "app1/index.html" + or "index.html" depending on the directory-path for which the + RewriteRule applies.

      + +

      The directory-path to which the rule applies is stripped from the currently mapped + filesystem path before comparison (up to and including a trailing slash). + The net result of this per-directory prefix stripping is that rules in + this context only match against the portion of the currently mapped filesystem path + "below" the directory-path to which the rule applies.

      + +

      Directives such as DocumentRoot and Alias, or even the + result of previous RewriteRule substitutions, determine + the currently mapped filesystem path. +

      +
    • + +
    • If you wish to match against the hostname, port, or query string, use a + RewriteCond with the + %{HTTP_HOST}, %{SERVER_PORT}, or + %{QUERY_STRING} variables respectively.

    • +

    Per-directory Rewrites

    -

    -Using rewrite rules in per-directory -context requires special attention to how patterns are -matched and how rule inheritance works. See the -Per-directory Rewrites -guide for complete details. -

    +
      +
    • The rewrite engine may be used in .htaccess files and in <Directory> sections, with some additional +complexity.
    • + +
    • To enable the rewrite engine in this context, you need to set +RewriteEngine On and +at least one of the FollowSymLinks or +SymLinksIfOwnerMatch +Options must be enabled. Note +that these options cannot be set in a distributed configuration file +(.htaccess) unless +AllowOverride permits it +in the server configuration.
    • + +
    • See the RewriteBase +directive for more information regarding what prefix will be added back to +relative substitutions.
    • + +
    • If you wish to match against the full URL-path in a +per-directory context +RewriteRule, use the %{REQUEST_URI} variable in +a RewriteCond.
    • + +
    • The removed prefix always ends with a slash, meaning the matching occurs against a string which +never has a leading slash. Therefore, a Pattern with ^/ never +matches in per-directory context.
    • + +
    • Although rewrite rules are syntactically permitted in <Location> and <Files> sections +(including their regular expression counterparts), this +should never be necessary and is unsupported. A likely feature +to break in these contexts is relative substitutions.
    • + +
    • The If blocks +follow the rules of the directory context.
    • + +
    • By default, mod_rewrite overrides rules when +merging sections belonging to the same context. The RewriteOptions directive can change this behavior, +for example using the Inherit setting.
    • + +
    • The RewriteOptions also regulates the +behavior of sections that are stated at the same nesting level of the configuration. In the +following example, by default only the RewriteRules stated in the second +If block +are considered, since the first ones are overridden. Using RewriteOptions Inherit forces mod_rewrite to merge the two +sections and consider both set of statements, rather than only the last one.
    • +
    +
    <If "true">
    +  # Without RewriteOptions Inherit, this rule is overridden by the next
    +  # section and no redirect will happen for URIs containing 'foo'
    +  RewriteRule foo http://example.com/foo [R]
    +</If>
    +<If "true">
    +  RewriteRule bar http://example.com/bar [R]
    +</If>
    +

    For information on regular @@ -1136,8 +1242,9 @@ guide for complete details. section of the mod_rewrite introduction.

    The Substitution of a - rewrite rule is the string that replaces the original URL-path that - was matched by Pattern. The Substitution may + rewrite rule is the string that replaces the URL-path (see + "What is matched?" above) + when the rule's conditions are met. The Substitution may be a:

    diff --git a/docs/manual/mod/mod_rewrite.html.fr.utf8 b/docs/manual/mod/mod_rewrite.html.fr.utf8 index a4ebd97eab1..d0489ee8f9b 100644 --- a/docs/manual/mod/mod_rewrite.html.fr.utf8 +++ b/docs/manual/mod/mod_rewrite.html.fr.utf8 @@ -29,8 +29,6 @@

    Langues Disponibles:  en  |  fr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
    @@ -50,17 +48,20 @@ règles permettant de réécrire les URLs des requêtes

    mod_rewrite fournit une méthode souple et puissante pour manipuler les URLs en utilisant un nombre illimité de règles. Chaque règle peut être associée à un nombre illimité de conditions, afin de vous - permettre de réécrire les URLs en fonction de variables du serveur, de - variables d'environnement, de cookies, d'en-têtes HTTP, ou de repères - temporels.

    -

    mod_rewrite agit sur la totalité de l'URL, ou de toute - partie de cette dernière, y compris PATH_INFO ou QUERY_STRING.

    - + permettre de réécrire les URLs en fonction de variables du serveur (y compris les en-têtes + HTTP, les détails de la connexion et les horodatages), de + variables d'environnement ou d’autres propriétés de la requête. Les règles + peuvent agir sur le chemin d’URL + (y compris toute information en fin de + nom de chemin) et peut aussi modifier la chaîne de paramètres. +

    +

    Une règle de réécriture peut être invoquée dans les fichiers de - configuration globale du serveur ou dans un contexte de répertoire. Le chemin généré par - une règle de réécriture peut inclure une chaîne de paramètres, ou peut - renvoyer vers un traitement secondaire interne, une redirection vers une - requête externe ou vers le mandataire interne.

    + configuration globale du serveur ou dans un contexte de répertoire. La chaîne de + substitution d’une règle de réécriture peut comporter une chaîne de + paramètres et une règle peut renvoyer vers un traitement secondaire + interne, une redirection vers une requête externe ou vers le mandataire + interne.

    Vous trouverez plus de détails, discussions et exemples dans le Guide détaillé sur mod_rewrite.

    @@ -76,7 +77,10 @@ règles permettant de réécrire les URLs des requêtes
  • RewriteOptions
  • RewriteRule
  • -

    Traitement des bugs

    +

    Traitement des bugs

    Voir aussi

    +
    top

    Journalisation

    @@ -104,7 +108,7 @@ règles permettant de réécrire les URLs des requêtes mod_rewrite vont probablement rechercher en vain les directives RewriteLog et RewriteLogLevel. Depuis la sortie de httpd 2.4, ces directives ont en effet été remplacées par une - configuration de la journalisation par module à l'aide de la directive + configuration de la journalisation par module à l’aide de la directive LogLevel.

    Pour extraire les traces spécifiques à @@ -141,7 +145,7 @@ répertoire DocumentRoot (c'est à dire que pour y accéder, il n'est pas nécessaire d'utiliser une directive telle qu'Alias). -

  • Le chemin de répertoire auquel la RewriteRule s'applique, suffixé par +
  • Le chemin de répertoire auquel la RewriteRule s’applique, suffixé par la substitution relative est aussi valable en tant que chemin d'URL sur le serveur (ce qui est rare).
  • A partir de la version 2.4.16 du serveur HTTP Apache, @@ -160,7 +164,7 @@ répertoire la réécriture soit effectuée
  • + TestString [!]CondPattern [flags] @@ -174,39 +178,63 @@ la réécriture soit effectuée et si l'URI correspond au modèle spécifié dans la règle.

    +

    Si CondPattern est préfixé par un !, la condition + ne sera évaluée à vrai que si CondPattern ne correspond pas.

    + + + + + +

    TestString

    +

    TestString est une chaîne qui peut contenir les extensions suivantes en plus du texte simple :

    -
      -
    • - références arrières de règle de réécriture : - ce sont des références arrières de la forme - $N (0 <= N <= 9). $1 à $9 - permettent d'accéder aux parties regroupées (entre - parenthèses) du modèle, issues de la RewriteRule - concernée par le jeu de conditions RewriteCond - courant. $0 donne accès à l'ensemble de la chaîne - correspondant au modèle.
    • -
    • - Références arrières de condition de réécriture - : ce sont des références arrières de la forme - %N (0 <= N <= 9). %1 à %9 - permettent d'accéder aux parties regroupées (entre - parenthèses) du modèle, issues de la dernière - condition RewriteCond satisfaite du jeu de conditions RewriteCond - courant. %0 donne accès à l'ensemble de la chaîne - correspondant au modèle.
    • -
    • - extensions de table de réécriture : - ce sont des extensions de la forme ${nomTable:clé|défaut}. Voir la href="#mapfunc">documentation sur RewriteMap - pour plus de détails. -
    • -
    • - Variables du serveur : - ce sont des variables de la forme - %{ NAME_OF_VARIABLE }, - où NOM_DE_VARIABLE peut contenir une chaîne issue - de la liste suivante : + + +

      Références arrières

      + +
      +
      $N — Références arrières des + règles RewriteRule
      +
      Les références arrières de la forme $N (0 <= N <= + 9). $1 à $9 permettent d'accéder aux parties regroupées (entre + parenthèses) du modèle, issues de la RewriteRule concernée + par le jeu de conditions RewriteCond courant. $0 donne + accès à l'ensemble de la chaîne correspondant au modèle.
      + +
      %N — Références arrières des + conditions RewriteCond
      +
      Les références arrières de la forme %N (0 <= N <= + 9). %1 à %9 permettent d'accéder aux parties regroupées (entre + parenthèses) du modèle, issues de la dernière condition + RewriteCond satisfaite du jeu de conditions + RewriteCond courant. %0 donne accès à l'ensemble de la + chaîne correspondant au modèle.
      + +
      + +
      Les références arrières ne sont définies que si le motif correspond. + Si le motif est préfixé de !, aucune référence arrière + ne sera donc définie. Voir le document La manière dont le jeu de + règles est appliqué pour plus de détails à propos de l’ordre dans + lequel les motifs sont mis en correspondance et les références arrières + définies.
      + + + +

      Développement des mappages RewriteMap

      + +

      Ce sont des développements de la forme + ${mapname:key|default}. Voir la documentation de RewriteMap pour plus de détails.

      + + + +

      Le serveur et les variables CGI

      + +

      Ce sont des variables de la forme %{ + NAME_OF_VARIABLE } où + NAME_OF_VARIABLE peut être une des chaînes de la liste suivante :

    Description:Ce module fournit un moteur de réécriture à base de règles permettant de réécrire les URLs des requêtes à la volée
    Syntaxe: RewriteCond - chaîne_de_test expression_de_comparaison [drapeaux]
    Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
    Surcharges autorisées:FileInfo
    Statut:Extension
    @@ -231,7 +259,7 @@ la réécriture soit effectuée CONTEXT_PREFIX
    CONTEXT_DOCUMENT_ROOT
    IPV6
    - PATH_INFO
    + PATH_INFO
    QUERY_STRING
    REMOTE_ADDR
    REMOTE_HOST
    @@ -292,12 +320,35 @@ la réécriture soit effectuée struct tm du système Unix. La plupart d'entre elles sont documentées dans la documentation des expressions, dans la documentation des variables - d'environnement ou dans la spécification de + d’environnement ou dans la spécification de CGI (RFC 3875).

    SERVER_NAME et SERVER_PORT dépendent respectivement des valeurs des directives UseCanonicalName et UseCanonicalPhysicalPort.

    +

    Les variables SCRIPT_FILENAME et REQUEST_FILENAME contiennent + la même valeur — la valeur du champ filename de la + structure interne request_rec du serveur HTTP + Apache. Le premier nom est plus connu en tant que nom de + variable CGI alors que le second est la contrepartie appropriée + de REQUEST_URI (qui contient la valeur du champ uri + de la structure request_rec).

    + +

    Si une substitution se produit et que la réécriture continue, + la valeur des deux variables sera mise à jour en conséquence.

    + +

    Si elles sont utilisées dans un contexte global au serveur + (c’est-à-dire avant que la requête ne soit mise en parallèle + avec le système de fichiers), SCRIPT_FILENAME et + REQUEST_FILENAME ne peuvent pas contenir le chemin complet du + système de fichiers local, car le chemin est inconnu à ce + stade du traitement. Dans ce cas, les deux variables + contiendront initialement la valeur de REQUEST_URI. Pour obtenir + le chemin complet du système de fichiers local correspondant à + la requête, Utilisez une projection vers l’avant à base d’URL + %{LA-U:REQUEST_FILENAME} pour déterminer la valeur + finale de REQUEST_FILENAME.

    +

    Parmi les variables spécifiques à mod_rewrite, ou trouve les suivantes :

    @@ -370,8 +421,8 @@ la réécriture soit effectuée recoder, passez-la à la fonction de mappage "escape". Notez que cette variable de serveur est distincte de la - variable d'environnement CGI de même nom : dans un contexte - CGI, REQUEST_URI contient l'URI original complet + variable d’environnement CGI de même nom : dans un contexte + CGI, REQUEST_URI contient l’URI original complet de la requête, y compris la chaîne de paramètres. Voir la directive CGIVar pour les détails. @@ -387,70 +438,36 @@ la réécriture soit effectuée différence de la plupart des variables suivantes. - - + -

    Si la chaîne_de_test contient la valeur spéciale - expr, expression_de_comparaison sera traité - en tant qu'expression rationnelle de type ap_expr. Si des en-têtes HTTP sont - référencés dans l'expression rationnelle, et si le drapeau - novary n'est pas activé, ils seront ajoutés à - l'en-tête Vary.

    +

    Consultation de variables préfixées

    + +

    En plus des variables de serveur ci-avant, la syntaxe + %{PREFIX:name} permet d’accéder à des + ressources supplémentaires :

    -

    Autres points à connaître ::

    -
      -
    1. -

      Les variables SCRIPT_FILENAME et - REQUEST_FILENAME contiennent toutes deux la valeur - du champ filename de la - structure interne request_recdu serveur HTTP Apache. - Le premier nom correspond au nom de variable bien connu CGI, - alors que le second est l'équivalent de REQUEST_URI (qui - contient la valeur du champ uri de - request_rec).

      -

      Si une substitution intervient et si la réécriture se - poursuit, la valeur des deux variables sera mise à jour en - conséquence.

      -

      Dans le contexte du serveur principal (c'est à dire avant que - la requête ne soit mise en correspondance avec le système de - fichiers), SCRIPT_FILENAME et REQUEST_FILENAME ne peuvent pas - contenir le chemin entier dans le système de fichiers local car - ce chemin b'est pas connu à ce stade du traitement. Dans ce cas, - les deux variables contiendront la valeur de REQUEST_URI. Pour - obtenir le chemin complet de la requête dans le système de - fichiers local dans le contexte du serveur principal, utilisez une - référence avant à base d'URL - %{LA-U:REQUEST_FILENAME} pour déterminer la valeur - finale de REQUEST_FILENAME.

    2. - - -
    3. - %{ENV:variable}, où variable peut - correspondre à une variable d'environnement quelconque.
    4. -
    5. - %{ENV:variable} est aussi disponible, où - variable peut correspondre à toute variable - d'environnement. Peut être consulté via des structures internes +
      +
      %{ENV:variable}
      +
      variable peut correspondre à n’importe quelle variable + d’environnement. Peut être consulté via des structures internes d'Apache httpd et (si on ne les trouve pas ici) via la fonction getenv() à partir du processus du serveur Apache - httpd.
    6. - -
    7. Que mod_ssl soit chargé ou non, on peut - utiliser %{SSL:variable}, où variable - peut être remplacé par le nom d'une - variable - d'environnement SSL . Si mod_ssl n'est pas - chargé, cette variable contiendra toujours une chaîne vide. + httpd. + +
      %{SSL:variable}
      +
      variable est le nom d’une variable d’environnement SSL. Cette + variable peut être utilisée que mod_ssl soit chargé ou + non, mais elle sera toujours développée en une chaîne vide si + mod_ssl n’est pas chargé. Exemple : %{SSL:SSL_CIPHER_USEKEYSIZE} pourra contenir la valeur 128. Ces variables sont disponibles même si l'option StdEnvVars de la directive SSLOptions n'a - pas été définie.
    8. + pas été définie. -
    9. - On peut utiliser %{HTTP:en-tête}, où - en-tête peut correspondre à tout nom d'en-tête MIME - HTTP, pour extraire la valeur d'un en-tête envoyé dans la +
      %{HTTP:header}
      +
      header peut correspondre à n’importe quel nom d’en-tête + MIME HTTP. Cette variable peut toujours être utilisée pour obtenir la valeur d'un en-tête envoyé dans la requête HTTP. Par exemple, %{HTTP:Proxy-Connection} contiendra la valeur de l'en-tête HTTP "Proxy-Connection:". @@ -464,105 +481,130 @@ la réécriture soit effectuée logique de cout-circuit si le drapeau 'ornext|OR' est utilisé, et que de ce fait, certaines d'entre elles ne seront pas évaluées.

      -
    10. - -
    11. A des fins de référence avant, on peut utiliser, - %{LA-U:variable}, qui - permet d'effectuer une sous-requête interne à base d'URL, afin - de déterminer la valeur finale de variable. Ceci permet - d'accéder à la valeur d'une variable pour la réécriture inconnue - à ce stade du traitement, mais qui sera définie au - cours d'une phase ultérieure. -

      Par exemple, pour effectuer une réécriture dépendant de la - variable REMOTE_USER dans le contexte du serveur - principal (fichier httpd.conf), vous devez utiliser - %{LA-U:REMOTE_USER} - cette variable est définie - par la phase d'autorisation qui intervient après la - phase de traduction d'URL (pendant laquelle mod_rewrite - opère).

      -

      Par contre, comme mod_rewrite implémente son - contexte de répertoire (fichier - .htaccess) via la phase Fixup de l'API, et comme la phase - d'autorisation intervient avant cette dernière, vous pouvez - vous contenter d'utiliser %{REMOTE_USER} dans ce - contexte.

    12. - -
    13. - %{LA-F:variable} peut être utilisée pour effectuer - une sous-requête interne (basée sur le nom de fichier), afin de - déterminer la valeur finale de variable. La plupart du - temps, elle est identique à LA-U (voir ci-dessus).
    14. -
    + + + + + +

    Sous-requêtes de projection vers l’avant

    +

    Ces formes génèrent une sous-requête interne pour déterminer la valeur + finale d’une variable qui n’est pas encore disponible à ce stade du + traitement :

    -

    expression_de_comparaison est une expression +

    +
    %{LA-U:variable}
    +
    Génère une sous-requête interne (à base d’URL) pour déterminer la + valeur finale de variable. Ceci permet d'accéder à la valeur + d'une variable pour la réécriture inconnue à ce stade du traitement, + mais qui sera définie au cours d'une phase ultérieure. +

    Par exemple, pour effectuer une réécriture dépendant de la variable + REMOTE_USER dans le contexte du serveur principal (fichier + httpd.conf), vous devez utiliser + %{LA-U:REMOTE_USER} - cette variable est définie par la + phase d'autorisation qui intervient après la phase de + traduction d'URL (pendant laquelle mod_rewrite + opère).

    +

    Par contre, comme mod_rewrite implémente + son contexte de répertoire + (fichier .htaccess) via la phase Fixup de l'API, et comme + la phase d'autorisation intervient avant cette dernière, vous + pouvez vous contenter d'utiliser %{REMOTE_USER} dans ce + contexte.

    + +
    %{LA-F:variable}
    +
    Génère une sous-requête interne (à base de nom de fichier) pour + déterminer la valeur finale de la variable. Identique la + plupart du temps à LA-U ci-dessus.
    +
    + + + +

    Syntaxe des expressions

    + +

    Si la chaîne TestString contient la valeur spéciale + expr, le motif CondPattern sera traité comme une + expression ap_expr. Les en-têtes HTTP + référencés dans l’expression seront ajoutés à l’en-tête Vary si le drapeau + novary n’a pas été spécifié.

    + + + + + +

    CondPattern

    + + +

    CondPattern est une expression rationnelle qui est appliquée à l'instance actuelle de - chaîne_de_test. chaîne_de_test est d'abord + TestString. TestString est d'abord évaluée, puis comparée à - l'expression_de_comparaison.

    + l'CondPattern.

    -

    expression_de_comparaison est en général une +

    CondPattern est en général une expression rationnelle, mais vous disposez des syntaxes supplémentaires suivantes pour effectuer - d'autres tests utiles sur chaîne_de_test : + d'autres tests utiles sur TestString :

    -
      -
    1. Vous pouvez préfixer l'expression avec un caractère + + +

      Vous pouvez préfixer l'expression avec un caractère '!' (point d'exclamation) pour inverser le résultat de la condition, quelle que soit l'expression de - comparaison utilisée.

    2. + comparaison utilisée.

      -
    3. Vous pouvez effectuer des comparaisons lexicographiques de - chaînes : + -
      +

      Comparaisons de chaînes

      + +
      <expression
      inférieur au sens lexicographique
      Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à - chaîne_de_test. La condition est satisfaite si - chaîne_de_test est inférieure au sens + TestString. La condition est satisfaite si + TestString est inférieure au sens lexicographique à l'expression.
      >expression
      supérieur au sens lexicographique
      Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à - chaîne_de_test. La condition est satisfaite si - chaîne_de_test est supérieure au sens + TestString. La condition est satisfaite si + TestString est supérieure au sens lexicographique à l'expression.
      =expression
      égal au sens lexicographique
      Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à - chaîne_de_test. La condition est satisfaite si - chaîne_de_test est égale au sens + TestString. La condition est satisfaite si + TestString est égale au sens lexicographique à l'expression (les deux chaînes sont exactement identiques, caractère pour caractère). Si expression est "" (deux guillemets), - chaîne_de_test est comparée à la + TestString est comparée à la chaîne vide.
      <=expression de comparaison
      inférieur ou égal à au sens lexicographique
      - Considère l'expression_de_comparaison comme une + Considère la CondPattern comme une chaîne de caractères et la compare au sens lexicographique à - la chaîne_de_test. Vrai si chaîne_de_test - précède lexicographiquement expression_de_comparaison, ou est - égale à expression_de_comparaison (les deux chaînes + la TestString. Vrai si TestString + précède lexicographiquement CondPattern, ou est + égale à CondPattern (les deux chaînes sont identiques, caractère pour caractère).
      >=expression de comparaison
      supérieur ou égal à au sens lexicographique
      - Considère l'expression_de_comparaison comme une + Considère la CondPattern comme une chaîne de caractères et la compare au sens lexicographique à - la chaîne_de_test. Vrai si chaîne_de_test - suit lexicographiquement expression_de_comparaison, ou est - égale à expression_de_comparaison (les deux chaînes + la TestString. Vrai si TestString + suit lexicographiquement CondPattern, ou est + égale à CondPattern (les deux chaînes sont identiques, caractère pour caractère).
      -
      +

      Note

      L'opérateur de comparaison de chaînes fait partie des arguments de la CondPattern et doit par conséquent se trouver entre les @@ -572,53 +614,53 @@ la réécriture soit effectuée
      -
    4. -
    5. - Vous pouvez effectuer des comparaisons d'entiers : -
      + +

      Comparaisons d’entiers

      + +
      -eq
      est numériquement égal à
      - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si les deux expressions sont numériquement égales.
      -ge
      est numériquement supérieur ou égal à
      - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement supérieure ou égale à - expression_de_comparaison.
      + CondPattern.
      -gt
      est numériquement supérieur à
      - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement - supérieure à expression_de_comparaison.
      + supérieure à CondPattern.
      -le
      est numériquement inférieur ou égal à
      - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement - inférieure ou égale à expression_de_comparaison. + inférieure ou égale à CondPattern. Attention à la confusion avec le drapeau -l en utilisant la variante the -L ou -h.
      -lt
      est numériquement inférieur à
      - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement - inférieure à expression_de_comparaison. + inférieure à CondPattern. Attention à la confusion avec le drapeau -l en utilisant la variante the -L ou -h.
      @@ -630,39 +672,42 @@ la réécriture soit effectuée si les deux éléments comparés sont numériquement différents. Equivalent à !-eq. -
      -
    6. - -
    7. Vous pouvez effectuer différents tests sur les attributs de - fichier : -
      +
      + + +

      Tests des attributs de fichier

      + +
      -d
      est un répertoire
      - Traite chaîne_de_test comme un chemin et vérifie + Traite TestString comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un répertoire.
      -f
      est un fichier régulier
      - Traite chaîne_de_test comme un chemin et vérifie - s'il existe ou pas, et s'il s'agit d'un fichier régulier.
      + Traite TestString comme un chemin et vérifie + s'il existe ou pas, et s'il s'agit d'un fichier régulier. +
      -F
      test de l'existence d'un fichier via une sous-requête
      - Vérifie si chaîne_de_test est un fichier valide, + Vérifie si TestString est un fichier valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à utiliser avec précautions car les performances du serveur - peuvent s'en trouver affectées !
      + peuvent s'en trouver affectées ! +
      -h
      est un lien symbolique, selon la convention bash
      - Voir -l.
      + Voir -l. +
      -l
      est un lien symbolique
      - Considère la chaîne_de_test comme un chemin et + Considère la TestString comme un chemin et vérifie son existence et si elle est un lien symbolique. On peut aussi utiliser la convention bash -L ou -h lorsqu'il y a risque de confusion @@ -674,14 +719,14 @@ la réécriture soit effectuée
      -s
      est un fichier régulier d'une certaine taille
      - Considère la chaîne_de_test comme un chemin et + Considère la TestString comme un chemin et vérifie son existence et si elle est un fichier régulier d'une taille supérieure à zéro.
      -U

      test de l'existence d'une URL via une sous-requête
      - Vérifie si chaîne_de_test est une URL valide, + Vérifie si TestString est une URL valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à @@ -696,23 +741,24 @@ la réécriture soit effectuée

      -x
      a l'attribut d'exécution positionné
      - Considère la chaîne_de_test comme un chemin et + Considère la TestString comme un chemin et vérifie son existence et si elle a son attribut d'exécution positionné. Ce positionnement est déterminé en fonction de l'OS sous-jacent.
      -
      + - Par exemple: +

      Par exemple :

      RewriteCond /var/www/%{REQUEST_URI} !-f
       RewriteRule ^(.+) /other/archive/$1 [R]
      -
    8. + + +

      Évaluation des expressions

      -
    9. -

      Si la chaîne_de_test contient la valeur spéciale +

      Si TestString contient la valeur spéciale expr, la chaîne de comparaison sera traitée en tant qu'expression rationnelle de type ap_expr.

      @@ -726,31 +772,34 @@ RewriteRule ^(.+) /other/archive/$1 [R]
                 RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
                  RewriteRule "^/images" "-" [F]
      -
    10. -
    + + + + +

    Drapeaux

    Vous pouvez aussi définir certains drapeaux pour - l'expression_de_comparaison en ajoutant ces - [drapeaux] + la CondPattern en ajoutant ces + [flags] comme troisième argument de la directive - RewriteCond, où drapeaux est un + RewriteCond, où flags est un sous-ensemble séparé par des virgules des drapeaux suivants :

    -
      -
    • 'nocase|NC' - (no case)
      +
      +
      'nocase|NC'
      +
      (no case)
      Rend le test insensible à la casse - il n'est pas fait de distinction entre majuscules et minuscules, à la fois dans le - développement de chaîne_de_test et dans - expression_de_comparaison. Ce drapeau n'est pris en - compte que lors d'une comparaison entre chaîne_de_test - et expression_de_comparaison. Il ne l'est pas pour les + développement de TestString et dans + CondPattern. Ce drapeau n'est pris en + compte que lors d'une comparaison entre TestString + et CondPattern. Il ne l'est pas pour les vérification par sous-requêtes ou sur le système de - fichiers.
    • + fichiers. + -
    • - 'ornext|OR' - (ou condition suivante)
      +
      'ornext|OR'
      +
      (or condition suivante)
      Permet de chaîner les conditions de règles avec un OU au lieu du AND implicite. Exemple typique : @@ -762,10 +811,10 @@ RewriteRule ...règles concernant tous ces hôtes... Sans ce drapeau, les paires condition/règle devraient être écrites trois fois. -
    • + -
    • 'novary|NV' - (no vary)
      +
      'novary|NV'
      +
      (no vary)
      Si la condition contient un en-tête HTTP, ce drapeau empêche ce dernier d'être ajouté à l'en-tête Vary de la réponse.
      L'utilisation de ce drapeau peut provoquer une mise en cache @@ -773,11 +822,14 @@ RewriteRule ...règles concernant tous ces hôtes... varie avec la valeur de l'en-tête considéré. Ce drapeau ne devrait donc être utilisé que si l'on maîtrise parfaitement le fonctionnement de l'en-tête Vary. -
    • -
    + + + + + -

    Exemple :

    +

    Exemple

    Pour réécrire la page d'accueil d'un site en fonction de l'en-tête ``User-Agent:'' de la requête, vous @@ -1135,7 +1187,7 @@ pour le moteur de réécriture

    + [!]PatternSubstitution [flags] @@ -1149,11 +1201,14 @@ pour le moteur de réécriture les règles seront appliquées au cours du processus de réécriture.

    -

    Modèle est une expression +

    Pattern est une expression rationnelle. Ce avec quoi ce modèle est comparé dépend de l'endroit où la directive RewriteRule est définie.

    +

    Si le motif est précédé d’un !, la substitution ne sera + effectuée que si le pattern ne correspond pas.

    +

    Qu'est-ce qui est comparé ?

      @@ -1164,17 +1219,17 @@ pour le moteur de réécriture
    • Dans un contexte de répertoire (sections Directory et fichiers .htaccess), le - Modèle est comparé avec une partie de chemin ; par exemple une + Pattern est comparé avec une partie de chemin ; par exemple une requête pour "/app1/index.html" entraînera une comparaison avec "app1/index.html" ou "index.html" selon le chemin de répertoire où la directive RewriteRule est définie.

      -

      Le chemin de répertoire auquel la règle s'applique est supprimé du +

      Le chemin de répertoire auquel la règle s’applique est supprimé du chemin correspondant du système de fichiers avant comparaison (jusqu'au slash final compris). En conséquence de cette suppression, les règles définies dans ce contexte n'effectuent des comparaisons qu'avec la portion du chemin du système de fichiers "en dessous" du chemin de répertoire - auquel la règle s'applique.

      + auquel la règle s’applique.

      Le chemin correspondant actuel du système de fichiers est déterminé par des directives telles que DocumentRoot et @@ -1257,34 +1312,15 @@ dernière.

    -

    Pour quelques conseils à propos des expressions rationnelles, voir le - document Introduction à - mod_rewrite.

    - -

    Dans mod_rewrite, on peut aussi utiliser le caractère - NOT ('!') comme préfixe de modèle. Ceci vous permet - d'inverser la signification d'un modèle, soit pour dire - ``si l'URL considérée ne correspond PAS à - ce modèle''. Le caractère NON peut donc être utilisé à - titre exceptionnel, lorsqu'il est plus simple d'effectuer une - comparaison avec le modèle inversé, ou dans la dernière règle - par défaut.

    - -

    Note

    -Si vous utilisez le caractère NON pour inverser la signification d'un -modèle, vous ne pouvez pas inclure de parties génériques groupées dans -le modèle. Ceci est dû au fait que, lorsque le modèle ne correspond -pas (autrement dit, sa négation correspond), les groupes sont vides. -Ainsi, si vous utilisez des modèles inversés, vous ne pouvez -pas vous référer aux groupes par $N dans la chaîne de -substitution ! -
    +

    Pour des informations à propos des expressions + rationnelles, y compris l’utilisation du préfixe ! + pour inverser un motif, voir la section Expressions rationnelles de + l’introduction à mod_rewrite.

    -

    Dans une règle de réécriture, - Substitution est la chaîne - de caractères qui remplace le chemin de l'URL original qui - correspondait au Modèle. Substitution peut - être :

    +

    Dans une règle de réécriture, Substitution est la chaîne de caractères qui + remplace le chemin de l'URL (voir "Qu’est-ce + qui est comparé ?" ci-avant) lorsque les conditions de la règle sont + satisfaites. Substitution peut être :

    @@ -1292,7 +1328,7 @@ substitution !
    Il indique alors la localisation dans le système de fichiers de la ressource qui doit être envoyée au client. Une substitution commençant - par / n'est traitée comme un chemin du système de fichiers + par / n’est traitée comme un chemin du système de fichiers que dans un contexte de serveur virtuel ou de serveur global, et seulement si le premier composant du chemin existe dans le système de fichiers. Dans un contexte de @@ -1304,7 +1340,7 @@ substitution ! doit être servie. Dans un contexte de serveur virtuel ou de serveur global, si le premier composant du chemin existe à la racine du système de fichiers, la substitution est traitée comme un chemin du système de - fichiers. Par exemple, /www/file.html est un chemin d'URL, + fichiers. Par exemple, /www/file.html est un chemin d’URL, sauf si un répertoire nommé www existe à la racine du système de fichiers. Si vous désirez que d'autres directives de correspondance d'URL (comme la directive Alias) soient appliquées au @@ -1337,23 +1373,23 @@ substitution !

    Comment sont interprétées les substitutions de chemin

    En fonction du contexte et si elle commence ou non par un slash, une substitution sera traitée comme un chemin du système de fichiers ou comme - un chemin d'URL :

    + un chemin d’URL :

    • Commence par un /, contexte de serveur virtuel ou de serveur global : Traitée comme un chemin du système de fichiers si le premier composant du - chemin existe sur disque ; sinon, traitée comme un chemin d'URL.
    • + chemin existe sur disque ; sinon, traitée comme un chemin d’URL.
    • Commence par un /, contexte de répertoire : - Toujours traitée comme un chemin d'URL. Pas de vérification sur le + Toujours traitée comme un chemin d’URL. Pas de vérification sur le système de fichiers.
    • Ne commence pas par un / (chemin relatif), contexte de serveur virtuel - ou de serveur global : Traitée comme un chemin d'URL relatif à - l'URI de la requête actuelle.
    • + ou de serveur global : Traitée comme un chemin d’URL relatif à + l’URI de la requête actuelle.
    • Ne commence pas par un / (chemin relatif), contexte de - répertoire : Traitée comme un chemin d'URL relatif + répertoire : Traitée comme un chemin d’URL relatif au chemin de répertoire auquel la directive Directory ou le fichier .htaccess - s'appliquent. Voir RewriteBase pour le contrôle + s’appliquent. Voir RewriteBase pour le contrôle du préfixe ajouté aux substitutions relatives.
    @@ -1372,7 +1408,7 @@ substitution ! condition d'une règle (%{VARNAME})
  • des appels de - fonctions de comparaison + fonctions de mappage (${nom correspondance:clé|défaut})
  • @@ -1421,10 +1457,10 @@ substitution !

    En outre, vous pouvez spécifier des actions spéciales à effectuer en ajoutant des - [drapeaux] + [flags] comme troisième argument de la directive RewriteRule. Séparés par des virgules au sein d'une - liste encadrée par des crochets, les drapeaux peuvent + liste encadrée par des crochets, les flags peuvent être choisis dans la table suivante. Vous trouverez plus de détails, et des exemples pour chaque drapeau dans le document à propos des drapeaux de réécriture.

    @@ -1582,7 +1618,7 @@ substitution !
    - @@ -1590,7 +1626,7 @@ substitution ! c=t mais pas à c/t
    Description:Définit les règles pour le moteur de réécriture
    Syntaxe:RewriteRule - Modèle Substitution [drapeaux]
    Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
    Surcharges autorisées:FileInfo
    Statut:Extension
    UnsafeAllow3FAutorise les substitutions à partir d'URL potentiellement non + Autorise les substitutions à partir d’URL potentiellement non fiables. détails ...
    UnsafePrefixStat Autorise les substitutions potentiellement non fiables à partir - d'une variable de tête ou d'une référence arrière vers un chemin du + d’une variable de tête ou d’une référence arrière vers un chemin du système de fichiers. détails ...
    Disponible à partir de la version 2.5.1 du serveur HTTP Apache. diff --git a/docs/manual/mod/mod_rewrite.xml b/docs/manual/mod/mod_rewrite.xml index 6f9b071c955..a2e6d0cd30f 100644 --- a/docs/manual/mod/mod_rewrite.xml +++ b/docs/manual/mod/mod_rewrite.xml @@ -453,7 +453,7 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" Defines a condition under which rewriting will take place RewriteCond - TestString CondPattern [flags] + TestString [!]CondPattern [flags] server configvirtual host directory.htaccess FileInfo @@ -467,53 +467,69 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" >and if these conditions are met.

    If the CondPattern is prefixed with a ! the - condition is determined to be true only if the the + condition is determined to be true only if the CondPattern does not match.

    -

    TestString is a string which can contain the + + + + +

    TestString

    + +

    TestString is a string which can contain the following expanded constructs in addition to plain text:

    -
      -
    • - RewriteRule backreferences: These are - backreferences of the form $N + + +

      Backreferences

      + +
      +
      $N — RewriteRule backreferences
      +
      Backreferences of the form $N (0 <= N <= 9). $1 to $9 provide access to the grouped parts (in parentheses) of the pattern, from the RewriteRule which is subject to the current set of RewriteCond conditions. $0 provides - access to the whole string matched by that pattern. - - Backreferences are only defined if the pattern - matches. Thus, if the pattern is prefixed with - !, no backreferences are ever defined. -
    • -
    • - RewriteCond backreferences: These are - backreferences of the form %N + access to the whole string matched by that pattern. + +
      %N — RewriteCond backreferences
      +
      Backreferences of the form %N (0 <= N <= 9). %1 to %9 provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions. %0 provides access to the whole string matched by - that pattern. - - Backreferences are only defined if the pattern - matches. Thus, if the pattern is prefixed with - !, no backreferences are ever defined. -
    • -
    • - RewriteMap expansions: These are - expansions of the form ${mapname:key|default}. - See the documentation for - RewriteMap for more details. -
    • -
    • - Server variables: These are variables of - the form - %{ NAME_OF_VARIABLE - } - where NAME_OF_VARIABLE can be a string taken - from the following list: + that pattern. + + + Backreferences are only defined if the pattern + matches. Thus, if the pattern is prefixed with + !, no backreferences are ever defined. + See How the + Ruleset is Applied for more details on the order in which + patterns are matched and backreferences populated. + + + +

      RewriteMap Expansions

      + +

      These are expansions of the form ${mapname:key|default}. + See the documentation for + RewriteMap for more details.

      + + + +

      Server and CGI Variables

      + +

      These are variables of the form + %{ NAME_OF_VARIABLE + } + where NAME_OF_VARIABLE can be a string taken + from the following list:

      @@ -599,7 +615,7 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" correspond to the similarly named HTTP MIME-headers, C variables of the Apache HTTP Server or struct tm fields of the Unix system. - Most are documented in the + Most are documented in the Expressions doc, in the Environment Variables doc, or the CGI specification (3875).

      @@ -609,7 +625,30 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" UseCanonicalPhysicalPort respectively.

      -

      Those that are special to mod_rewrite include those below.

      +

      The variables SCRIPT_FILENAME and REQUEST_FILENAME + contain the same value - the value of the + filename field of the internal + request_rec structure of the Apache HTTP Server. + The first name is the commonly known CGI variable name + while the second is the appropriate counterpart of + REQUEST_URI (which contains the value of the + uri field of request_rec).

      + +

      If a substitution occurred and the rewriting continues, + the value of both variables will be updated accordingly.

      + +

      If used in per-server context (i.e., before the + request is mapped to the filesystem) SCRIPT_FILENAME and + REQUEST_FILENAME cannot contain the full local filesystem + path since the path is unknown at this stage of processing. + Both variables will initially contain the value of REQUEST_URI + in that case. In order to obtain the full local filesystem + path of the request in per-server context, use an URL-based + look-ahead %{LA-U:REQUEST_FILENAME} to determine + the final value of REQUEST_FILENAME.

      + +

      Those that are special to mod_rewrite + include those below.

      API_VERSION
      @@ -672,7 +711,7 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" such as "/index.html". This notably excludes the query string which is available as its own variable named QUERY_STRING. The value returned for - REQUEST_URI + REQUEST_URI has already been %-decoded, to re-encode it pass it through the "escape" mapping-function. Note that this server variable differs from the CGI @@ -693,79 +732,65 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" (decoded), unlike most other variables below.
      - - -

      If the TestString has the special value expr, - the CondPattern will be treated as an - ap_expr. HTTP headers referenced in the - expression will be added to the Vary header if the novary - flag is not given.

      + -

      Other things you should be aware of:

      +

      Prefixed Variable Lookups

      -
        -
      1. -

        The variables SCRIPT_FILENAME and REQUEST_FILENAME - contain the same value - the value of the - filename field of the internal - request_rec structure of the Apache HTTP Server. - The first name is the commonly known CGI variable name - while the second is the appropriate counterpart of - REQUEST_URI (which contains the value of the - uri field of request_rec).

        -

        If a substitution occurred and the rewriting continues, - the value of both variables will be updated accordingly.

        -

        If used in per-server context (i.e., before the - request is mapped to the filesystem) SCRIPT_FILENAME and - REQUEST_FILENAME cannot contain the full local filesystem - path since the path is unknown at this stage of processing. - Both variables will initially contain the value of REQUEST_URI - in that case. In order to obtain the full local filesystem - path of the request in per-server context, use an URL-based - look-ahead %{LA-U:REQUEST_FILENAME} to determine - the final value of REQUEST_FILENAME.

      2. - -
      3. - %{ENV:variable}, where variable can be - any environment variable, is also available. - This is looked-up via internal +

        In addition to the server variables above, the + %{PREFIX:name} syntax provides + access to additional sources:

        + +
        +
        %{ENV:variable}
        +
        Where variable can be + any environment variable. This is looked-up via internal Apache httpd structures and (if not found there) via - getenv() from the Apache httpd server process.
      4. + getenv() from the Apache httpd server process. -
      5. - %{SSL:variable}, where variable is the +
        %{SSL:variable}
        +
        Where variable is the name of an SSL environment - variable, can be used whether or not + variable. This can be used whether or not mod_ssl is loaded, but will always expand to the empty string if it is not. Example: %{SSL:SSL_CIPHER_USEKEYSIZE} may expand to 128. These variables are available even without setting the StdEnvVars option of the - SSLOptions directive.
      6. + SSLOptions directive. -
      7. - %{HTTP:header}, where header can be - any HTTP MIME-header name, can always be used to obtain the +
        %{HTTP:header}
        +
        Where header can be + any HTTP MIME-header name. This can always be used to obtain the value of a header sent in the HTTP request. Example: %{HTTP:Proxy-Connection} is the value of the HTTP header ``Proxy-Connection:''. -

        If a HTTP header is used in a condition this header is added to +

        If an HTTP header is used in a condition, this header is added to the Vary header of the response in case the condition evaluates to true for the request. It is not added if the condition evaluates to false for the request. Adding the HTTP header to the Vary header of the response is needed for proper caching.

        It has to be kept in mind that conditions follow a short circuit logic in the case of the 'ornext|OR' flag - so that certain conditions might not be evaluated at all.

      8. + so that certain conditions might not be evaluated at all.

        + -
      9. - %{LA-U:variable} - can be used for look-aheads which perform - an internal (URL-based) sub-request to determine the final + + +

        Look-ahead Sub-requests

        + +

        These forms perform an internal sub-request to determine the + final value of a variable that is not yet available at the current + stage of processing:

        + +
        +
        %{LA-U:variable}
        +
        Performs an internal (URL-based) sub-request to determine the final value of variable. This can be used to access - variable for rewriting which is not available at the current + a variable for rewriting which is not available at the current stage, but will be set in a later phase.

        For instance, to rewrite according to the REMOTE_USER variable from within the @@ -778,14 +803,31 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" its per-directory context via the Fixup phase of the API and because the authorization phases come before this phase, you just can use - %{REMOTE_USER} in that context.

      10. + %{REMOTE_USER} in that context.

        -
      11. - %{LA-F:variable} can be used to perform an internal - (filename-based) sub-request, to determine the final value - of variable. Most of the time, this is the same as - LA-U above.
      12. -
      +
      %{LA-F:variable}
      +
      Performs an internal (filename-based) sub-request to determine + the final value of variable. Most of the time, this is + the same as LA-U above.
      + + + + +

      Expression Syntax

      + +

      If the TestString has the special value expr, + the CondPattern will be treated as an + ap_expr. HTTP headers referenced in the + expression will be added to the Vary header if the novary + flag is not given.

      + + + + + +

      CondPattern

      CondPattern is the condition pattern, a regular expression which is applied to the @@ -798,16 +840,19 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" additional syntax available to perform other useful tests against the Teststring:

      -
        -
      1. You can prefix the pattern string with a + + +

        You can prefix the pattern string with a '!' character (exclamation mark) to negate the result of the condition, no matter what kind of CondPattern is used. -

      2. +

        + + -
      3. - You can perform lexicographical string comparisons: +

        String Comparisons

        -
        +
        <CondPattern
        Lexicographically precedes
        Treats the CondPattern as a plain string and @@ -847,22 +892,23 @@ RewriteRule "^/ex/(.*)" "${examplemap:$1}" if TestString lexicographically follows CondPattern, or is equal to CondPattern (the two strings are equal, character for character).
        -
        +
        + Note The string comparison operator is part of the CondPattern argument and must be included in the quotes if those are used. Eg. - + RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0" - -
      4. -
      5. - You can perform integer comparisons: -
        + + +

        Integer Comparisons

        +
        -eq
        Is numerically equal to
        The TestString is treated as an integer, and is @@ -907,32 +953,27 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0" numerically compared to the CondPattern. True if the two are numerically different. This is equivalent to !-eq.
        +
        -
        -
      6. - -
      7. You can perform various file attribute tests: - + -
        +

        File Attribute Tests

        +
        -d
        -
        Is directory.
        Treats the TestString as a pathname and tests whether or not it exists, and is a directory.
        -f
        -
        Is regular file.
        - Treats the TestString as a pathname and tests whether or not it exists, and is a regular file. -
        +
        -F
        -
        Is existing file, via subrequest.
        Checks whether or not TestString is a valid file, accessible via all the server's currently-configured @@ -947,7 +988,6 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"
        -l
        -
        Is symbolic link.
        Treats the TestString as a pathname and tests whether or not it exists, and is a symbolic link. May also @@ -986,19 +1026,20 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0" whether or not it exists, and has executable permissions. These permissions are determined according to the underlying OS.
        +
        -
        - - For example: +

        For example:

        RewriteCond /var/www/%{REQUEST_URI} !-f RewriteRule ^(.+) /other/archive/$1 [R] -
      8. + + +

        Expression Evaluation

        -
      9. If the TestString has the special value expr, the CondPattern will be treated as an ap_expr.

        @@ -1013,28 +1054,32 @@ RewriteRule ^(.+) /other/archive/$1 [R] RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule "^/images" "-" [F] -
      10. -
      -

      You can also set special flags for CondPattern by appending + + + + +

      Flags

      + +

      You can set special flags for CondPattern by appending [flags] as the third argument to the RewriteCond directive, where flags is a comma-separated list of any of the following flags:

      - -
        -
      • 'nocase|NC' - (no case)
        + +
        +
        'nocase|NC'
        +
        (no case)
        This makes the test case-insensitive - differences between 'A-Z' and 'a-z' are ignored, both in the expanded TestString and the CondPattern. This flag is effective only for comparisons between TestString and CondPattern. It has no - effect on filesystem and subrequest checks.
      • + effect on filesystem and subrequest checks. -
      • - 'ornext|OR' - (or next condition)
        +
        'ornext|OR'
        +
        (or next condition)
        Use this to combine rule conditions with a local OR instead of the implicit AND. Typical example: @@ -1047,20 +1092,25 @@ RewriteRule ...some special stuff for any of these hosts... Without this flag you would have to write the condition/rule pair three times. -
      • + -
      • 'novary|NV' - (no vary)
        - If a HTTP header is used in the condition, this flag prevents +
        'novary|NV'
        +
        (no vary)
        + If an HTTP header is used in the condition, this flag prevents this header from being added to the Vary header of the response.
        Using this flag might break proper caching of the response if the representation of this response varies on the value of this header. So this flag should be only used if the meaning of the Vary header is well understood. -
      • -
      + + + + + + -

      Example:

      +

      Example

      To rewrite the Homepage of a site according to the ``User-Agent:'' header of the request, you can @@ -1090,6 +1140,7 @@ RewriteRule "^/$" "/homepage.std.html" [L] + RewriteRule Defines rules for the rewriting engine @@ -1112,29 +1163,109 @@ RewriteRule "^/$" "/homepage.std.html" [L] on where the RewriteRule directive is defined.

      If the pattern is prefixed with a ! the - substitution will be performed only if the the + substitution will be performed only if the pattern does not match.

      <a id="what_is_matched" name="what_is_matched">What is matched?</a> -

      -The Pattern is matched against the %-decoded URL-path -(in server context) or the directory-relative path (in -per-directory context). -See RewriteRule -Basics for details on what the pattern is matched against -in each context. -

      +
        +
      • In VirtualHost context, + The Pattern will initially be matched against the part of the + URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). + This is the (%-decoded) URL-path.

      • + +
      • In per-directory context + (Directory and .htaccess), + the Pattern is matched against only a partial path, for example a request + of "/app1/index.html" may result in comparison against "app1/index.html" + or "index.html" depending on the directory-path for which the + RewriteRule applies.

        + +

        The directory-path to which the rule applies is stripped from the currently mapped + filesystem path before comparison (up to and including a trailing slash). + The net result of this per-directory prefix stripping is that rules in + this context only match against the portion of the currently mapped filesystem path + "below" the directory-path to which the rule applies.

        + +

        Directives such as DocumentRoot and Alias, or even the + result of previous RewriteRule substitutions, determine + the currently mapped filesystem path. +

        +
      • + +
      • If you wish to match against the hostname, port, or query string, use a + RewriteCond with the + %{HTTP_HOST}, %{SERVER_PORT}, or + %{QUERY_STRING} variables respectively.

      • +
      <glossary ref="perdirectory">Per-directory</glossary> Rewrites -

      -Using rewrite rules in per-directory -context requires special attention to how patterns are -matched and how rule inheritance works. See the -Per-directory Rewrites -guide for complete details. -

      +
        +
      • The rewrite engine may be used in .htaccess files and in Directory sections, with some additional +complexity.
      • + +
      • To enable the rewrite engine in this context, you need to set +RewriteEngine On and +at least one of the FollowSymLinks or +SymLinksIfOwnerMatch +Options must be enabled. Note +that these options cannot be set in a distributed configuration file +(.htaccess) unless +AllowOverride permits it +in the server configuration.
      • + +
      • See the RewriteBase +directive for more information regarding what prefix will be added back to +relative substitutions.
      • + +
      • If you wish to match against the full URL-path in a +per-directory context +RewriteRule, use the %{REQUEST_URI} variable in +a RewriteCond.
      • + +
      • The removed prefix always ends with a slash, meaning the matching occurs against a string which +never has a leading slash. Therefore, a Pattern with ^/ never +matches in per-directory context.
      • + +
      • Although rewrite rules are syntactically permitted in Location and Files sections +(including their regular expression counterparts), this +should never be necessary and is unsupported. A likely feature +to break in these contexts is relative substitutions.
      • + +
      • The If blocks +follow the rules of the directory context.
      • + +
      • By default, mod_rewrite overrides rules when +merging sections belonging to the same context. The RewriteOptions directive can change this behavior, +for example using the Inherit setting.
      • + +
      • The RewriteOptions also regulates the +behavior of sections that are stated at the same nesting level of the configuration. In the +following example, by default only the RewriteRules stated in the second +If block +are considered, since the first ones are overridden. Using RewriteOptions Inherit forces mod_rewrite to merge the two +sections and consider both set of statements, rather than only the last one.
      • +
      + + +<If "true"> + # Without RewriteOptions Inherit, this rule is overridden by the next + # section and no redirect will happen for URIs containing 'foo' + RewriteRule foo http://example.com/foo [R] +</If> +<If "true"> + RewriteRule bar http://example.com/bar [R] +</If> + +

      For information on regular @@ -1144,8 +1275,9 @@ guide for complete details. section of the mod_rewrite introduction.

      The Substitution of a - rewrite rule is the string that replaces the original URL-path that - was matched by Pattern. The Substitution may + rewrite rule is the string that replaces the URL-path (see + "What is matched?" above) + when the rule's conditions are met. The Substitution may be a:

      diff --git a/docs/manual/mod/mod_rewrite.xml.fr b/docs/manual/mod/mod_rewrite.xml.fr index 844ad4d2ab3..c3117c1a5a9 100644 --- a/docs/manual/mod/mod_rewrite.xml.fr +++ b/docs/manual/mod/mod_rewrite.xml.fr @@ -1,7 +1,7 @@ - + @@ -46,22 +46,28 @@ règles permettant de réécrire les URLs des requêtes

      mod_rewrite fournit une méthode souple et puissante pour manipuler les URLs en utilisant un nombre illimité de règles. Chaque règle peut être associée à un nombre illimité de conditions, afin de vous - permettre de réécrire les URLs en fonction de variables du serveur, de - variables d'environnement, de cookies, d'en-têtes HTTP, ou de repères - temporels.

      -

      mod_rewrite agit sur la totalité de l'URL, ou de toute - partie de cette dernière, y compris PATH_INFO ou QUERY_STRING.

      - + permettre de réécrire les URLs en fonction de variables du serveur (y compris les en-têtes + HTTP, les détails de la connexion et les horodatages), de + variables d'environnement ou d’autres propriétés de la requête. Les règles + peuvent agir sur le chemin d’URL + (y compris toute information en fin de + nom de chemin) et peut aussi modifier la chaîne de paramètres. +

      +

      Une règle de réécriture peut être invoquée dans les fichiers de configuration globale du serveur ou dans un contexte de répertoire. Le chemin généré par - une règle de réécriture peut inclure une chaîne de paramètres, ou peut - renvoyer vers un traitement secondaire interne, une redirection vers une - requête externe ou vers le mandataire interne.

      + ref="perdirectory">contexte de répertoire. La chaîne de + substitution d’une règle de réécriture peut comporter une chaîne de + paramètres et une règle peut renvoyer vers un traitement secondaire + interne, une redirection vers une requête externe ou vers le mandataire + interne.

      Vous trouverez plus de détails, discussions et exemples dans le Guide détaillé sur mod_rewrite.

      +Guide de mod_rewrite
      Journalisation @@ -91,7 +97,7 @@ LogLevel alert rewrite:trace3 mod_rewrite vont probablement rechercher en vain les directives RewriteLog et RewriteLogLevel. Depuis la sortie de httpd 2.4, ces directives ont en effet été remplacées par une - configuration de la journalisation par module à l'aide de la directive + configuration de la journalisation par module à l’aide de la directive LogLevel.

      Pour extraire les traces spécifiques à @@ -479,7 +485,7 @@ répertoire une directive telle qu'Alias).

    • Le chemin de répertoire auquel la RewriteRule s'applique, suffixé par + module="mod_rewrite">RewriteRule s’applique, suffixé par la substitution relative est aussi valable en tant que chemin d'URL sur le serveur (ce qui est rare).
    • A partir de la version 2.4.16 du serveur HTTP Apache, @@ -499,7 +505,7 @@ répertoire la réécriture soit effectuée RewriteCond - chaîne_de_test expression_de_comparaison [drapeaux] + TestString [!]CondPattern [flags] server configvirtual host directory.htaccess FileInfo @@ -514,41 +520,69 @@ la réécriture soit effectuée et si l'URI correspond au modèle spécifié dans la règle.

      +

      Si CondPattern est préfixé par un !, la condition + ne sera évaluée à vrai que si CondPattern ne correspond pas.

      + + + + + +

      TestString

      +

      TestString est une chaîne qui peut contenir les extensions suivantes en plus du texte simple :

      -
        -
      • - références arrières de règle de réécriture : - ce sont des références arrières de la forme - $N (0 <= N <= 9). $1 à $9 - permettent d'accéder aux parties regroupées (entre - parenthèses) du modèle, issues de la RewriteRule - concernée par le jeu de conditions RewriteCond - courant. $0 donne accès à l'ensemble de la chaîne - correspondant au modèle.
      • -
      • - Références arrières de condition de réécriture - : ce sont des références arrières de la forme - %N (0 <= N <= 9). %1 à %9 - permettent d'accéder aux parties regroupées (entre - parenthèses) du modèle, issues de la dernière - condition RewriteCond satisfaite du jeu de conditions RewriteCond - courant. %0 donne accès à l'ensemble de la chaîne - correspondant au modèle.
      • -
      • - extensions de table de réécriture : - ce sont des extensions de la forme ${nomTable:clé|défaut}. Voir la href="#mapfunc">documentation sur RewriteMap - pour plus de détails. -
      • -
      • - Variables du serveur : - ce sont des variables de la forme - %{ NAME_OF_VARIABLE }, - où NOM_DE_VARIABLE peut contenir une chaîne issue - de la liste suivante : + + +

        Références arrières

        + +
        +
        $N — Références arrières des + règles RewriteRule
        +
        Les références arrières de la forme $N (0 <= N <= + 9). $1 à $9 permettent d'accéder aux parties regroupées (entre + parenthèses) du modèle, issues de la RewriteRule concernée + par le jeu de conditions RewriteCond courant. $0 donne + accès à l'ensemble de la chaîne correspondant au modèle.
        + +
        %N — Références arrières des + conditions RewriteCond
        +
        Les références arrières de la forme %N (0 <= N <= + 9). %1 à %9 permettent d'accéder aux parties regroupées (entre + parenthèses) du modèle, issues de la dernière condition + RewriteCond satisfaite du jeu de conditions + RewriteCond courant. %0 donne accès à l'ensemble de la + chaîne correspondant au modèle.
        + +
        + + Les références arrières ne sont définies que si le motif correspond. + Si le motif est préfixé de !, aucune référence arrière + ne sera donc définie. Voir le document La manière dont le jeu de + règles est appliqué pour plus de détails à propos de l’ordre dans + lequel les motifs sont mis en correspondance et les références arrières + définies. + + + +

        Développement des mappages RewriteMap

        + +

        Ce sont des développements de la forme + ${mapname:key|default}. Voir la documentation de RewriteMap pour plus de détails.

        + + + +

        Le serveur et les variables CGI

        + +

        Ce sont des variables de la forme %{ + NAME_OF_VARIABLE } où + NAME_OF_VARIABLE peut être une des chaînes de la liste suivante :

    • @@ -574,7 +608,7 @@ la réécriture soit effectuée CONTEXT_PREFIX
      CONTEXT_DOCUMENT_ROOT
      IPV6
      - PATH_INFO
      + PATH_INFO
      QUERY_STRING
      REMOTE_ADDR
      REMOTE_HOST
      @@ -636,7 +670,7 @@ la réécriture soit effectuée sont documentées dans la documentation des expressions, dans la documentation des variables - d'environnement ou dans la spécification de + d’environnement ou dans la spécification de CGI (3875).

      SERVER_NAME et SERVER_PORT dépendent respectivement @@ -644,6 +678,29 @@ la réécriture soit effectuée module="core">UseCanonicalName et UseCanonicalPhysicalPort.

      +

      Les variables SCRIPT_FILENAME et REQUEST_FILENAME contiennent + la même valeur — la valeur du champ filename de la + structure interne request_rec du serveur HTTP + Apache. Le premier nom est plus connu en tant que nom de + variable CGI alors que le second est la contrepartie appropriée + de REQUEST_URI (qui contient la valeur du champ uri + de la structure request_rec).

      + +

      Si une substitution se produit et que la réécriture continue, + la valeur des deux variables sera mise à jour en conséquence.

      + +

      Si elles sont utilisées dans un contexte global au serveur + (c’est-à-dire avant que la requête ne soit mise en parallèle + avec le système de fichiers), SCRIPT_FILENAME et + REQUEST_FILENAME ne peuvent pas contenir le chemin complet du + système de fichiers local, car le chemin est inconnu à ce + stade du traitement. Dans ce cas, les deux variables + contiendront initialement la valeur de REQUEST_URI. Pour obtenir + le chemin complet du système de fichiers local correspondant à + la requête, Utilisez une projection vers l’avant à base d’URL + %{LA-U:REQUEST_FILENAME} pour déterminer la valeur + finale de REQUEST_FILENAME.

      +

      Parmi les variables spécifiques à mod_rewrite, ou trouve les suivantes :

      @@ -718,8 +775,8 @@ la réécriture soit effectuée recoder, passez-la à la fonction de mappage "escape". Notez que cette variable de serveur est distincte de la - variable d'environnement CGI de même nom : dans un contexte - CGI, REQUEST_URI contient l'URI original complet + variable d’environnement CGI de même nom : dans un contexte + CGI, REQUEST_URI contient l’URI original complet de la requête, y compris la chaîne de paramètres. Voir la directive CGIVar pour les détails. @@ -735,71 +792,38 @@ la réécriture soit effectuée différence de la plupart des variables suivantes. - - + -

      Si la chaîne_de_test contient la valeur spéciale - expr, expression_de_comparaison sera traité - en tant qu'expression rationnelle de type ap_expr. Si des en-têtes HTTP sont - référencés dans l'expression rationnelle, et si le drapeau - novary n'est pas activé, ils seront ajoutés à - l'en-tête Vary.

      +

      Consultation de variables préfixées

      + +

      En plus des variables de serveur ci-avant, la syntaxe + %{PREFIX:name} permet d’accéder à des + ressources supplémentaires :

      -

      Autres points à connaître ::

      -
        -
      1. -

        Les variables SCRIPT_FILENAME et - REQUEST_FILENAME contiennent toutes deux la valeur - du champ filename de la - structure interne request_recdu serveur HTTP Apache. - Le premier nom correspond au nom de variable bien connu CGI, - alors que le second est l'équivalent de REQUEST_URI (qui - contient la valeur du champ uri de - request_rec).

        -

        Si une substitution intervient et si la réécriture se - poursuit, la valeur des deux variables sera mise à jour en - conséquence.

        -

        Dans le contexte du serveur principal (c'est à dire avant que - la requête ne soit mise en correspondance avec le système de - fichiers), SCRIPT_FILENAME et REQUEST_FILENAME ne peuvent pas - contenir le chemin entier dans le système de fichiers local car - ce chemin b'est pas connu à ce stade du traitement. Dans ce cas, - les deux variables contiendront la valeur de REQUEST_URI. Pour - obtenir le chemin complet de la requête dans le système de - fichiers local dans le contexte du serveur principal, utilisez une - référence avant à base d'URL - %{LA-U:REQUEST_FILENAME} pour déterminer la valeur - finale de REQUEST_FILENAME.

      2. - - -
      3. - %{ENV:variable}, où variable peut - correspondre à une variable d'environnement quelconque.
      4. -
      5. - %{ENV:variable} est aussi disponible, où - variable peut correspondre à toute variable - d'environnement. Peut être consulté via des structures internes +
        +
        %{ENV:variable}
        +
        variable peut correspondre à n’importe quelle variable + d’environnement. Peut être consulté via des structures internes d'Apache httpd et (si on ne les trouve pas ici) via la fonction getenv() à partir du processus du serveur Apache - httpd.
      6. - -
      7. Que mod_ssl soit chargé ou non, on peut - utiliser %{SSL:variable}, où variable - peut être remplacé par le nom d'une - variable - d'environnement SSL . Si mod_ssl n'est pas - chargé, cette variable contiendra toujours une chaîne vide. + httpd. + +
        %{SSL:variable}
        +
        variable est le nom d’une variable d’environnement SSL. Cette + variable peut être utilisée que mod_ssl soit chargé ou + non, mais elle sera toujours développée en une chaîne vide si + mod_ssl n’est pas chargé. Exemple : %{SSL:SSL_CIPHER_USEKEYSIZE} pourra contenir la valeur 128. Ces variables sont disponibles même si l'option StdEnvVars de la directive SSLOptions n'a - pas été définie.
      8. + pas été définie. -
      9. - On peut utiliser %{HTTP:en-tête}, où - en-tête peut correspondre à tout nom d'en-tête MIME - HTTP, pour extraire la valeur d'un en-tête envoyé dans la +
        %{HTTP:header}
        +
        header peut correspondre à n’importe quel nom d’en-tête + MIME HTTP. Cette variable peut toujours être utilisée pour obtenir la valeur d'un en-tête envoyé dans la requête HTTP. Par exemple, %{HTTP:Proxy-Connection} contiendra la valeur de l'en-tête HTTP "Proxy-Connection:". @@ -813,105 +837,134 @@ la réécriture soit effectuée logique de cout-circuit si le drapeau 'ornext|OR' est utilisé, et que de ce fait, certaines d'entre elles ne seront pas évaluées.

        -
      10. - -
      11. A des fins de référence avant, on peut utiliser, - %{LA-U:variable}, qui - permet d'effectuer une sous-requête interne à base d'URL, afin - de déterminer la valeur finale de variable. Ceci permet - d'accéder à la valeur d'une variable pour la réécriture inconnue - à ce stade du traitement, mais qui sera définie au - cours d'une phase ultérieure. -

        Par exemple, pour effectuer une réécriture dépendant de la - variable REMOTE_USER dans le contexte du serveur - principal (fichier httpd.conf), vous devez utiliser - %{LA-U:REMOTE_USER} - cette variable est définie - par la phase d'autorisation qui intervient après la - phase de traduction d'URL (pendant laquelle mod_rewrite - opère).

        -

        Par contre, comme mod_rewrite implémente son - contexte de répertoire (fichier - .htaccess) via la phase Fixup de l'API, et comme la phase - d'autorisation intervient avant cette dernière, vous pouvez - vous contenter d'utiliser %{REMOTE_USER} dans ce - contexte.

      12. - -
      13. - %{LA-F:variable} peut être utilisée pour effectuer - une sous-requête interne (basée sur le nom de fichier), afin de - déterminer la valeur finale de variable. La plupart du - temps, elle est identique à LA-U (voir ci-dessus).
      14. -
      + + + -

      expression_de_comparaison est une expression +

      Sous-requêtes de projection vers l’avant

      + +

      Ces formes génèrent une sous-requête interne pour déterminer la valeur + finale d’une variable qui n’est pas encore disponible à ce stade du + traitement :

      + +
      +
      %{LA-U:variable}
      +
      Génère une sous-requête interne (à base d’URL) pour déterminer la + valeur finale de variable. Ceci permet d'accéder à la valeur + d'une variable pour la réécriture inconnue à ce stade du traitement, + mais qui sera définie au cours d'une phase ultérieure. +

      Par exemple, pour effectuer une réécriture dépendant de la variable + REMOTE_USER dans le contexte du serveur principal (fichier + httpd.conf), vous devez utiliser + %{LA-U:REMOTE_USER} - cette variable est définie par la + phase d'autorisation qui intervient après la phase de + traduction d'URL (pendant laquelle mod_rewrite + opère).

      +

      Par contre, comme mod_rewrite implémente + son contexte de répertoire + (fichier .htaccess) via la phase Fixup de l'API, et comme + la phase d'autorisation intervient avant cette dernière, vous + pouvez vous contenter d'utiliser %{REMOTE_USER} dans ce + contexte.

      + +
      %{LA-F:variable}
      +
      Génère une sous-requête interne (à base de nom de fichier) pour + déterminer la valeur finale de la variable. Identique la + plupart du temps à LA-U ci-dessus.
      +
      + + + +

      Syntaxe des expressions

      + +

      Si la chaîne TestString contient la valeur spéciale + expr, le motif CondPattern sera traité comme une + expression ap_expr. Les en-têtes HTTP + référencés dans l’expression seront ajoutés à l’en-tête Vary si le drapeau + novary n’a pas été spécifié.

      + + + + + +

      CondPattern

      + + +

      CondPattern est une expression rationnelle qui est appliquée à l'instance actuelle de - chaîne_de_test. chaîne_de_test est d'abord + TestString. TestString est d'abord évaluée, puis comparée à - l'expression_de_comparaison.

      + l'CondPattern.

      -

      expression_de_comparaison est en général une +

      CondPattern est en général une expression rationnelle, mais vous disposez des syntaxes supplémentaires suivantes pour effectuer - d'autres tests utiles sur chaîne_de_test : + d'autres tests utiles sur TestString :

      -
        -
      1. Vous pouvez préfixer l'expression avec un caractère + + +

        Vous pouvez préfixer l'expression avec un caractère '!' (point d'exclamation) pour inverser le résultat de la condition, quelle que soit l'expression de - comparaison utilisée.

      2. + comparaison utilisée.

        + + -
      3. Vous pouvez effectuer des comparaisons lexicographiques de - chaînes : +

        Comparaisons de chaînes

        -
        +
        <expression
        inférieur au sens lexicographique
        Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à - chaîne_de_test. La condition est satisfaite si - chaîne_de_test est inférieure au sens + TestString. La condition est satisfaite si + TestString est inférieure au sens lexicographique à l'expression.
        >expression
        supérieur au sens lexicographique
        Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à - chaîne_de_test. La condition est satisfaite si - chaîne_de_test est supérieure au sens + TestString. La condition est satisfaite si + TestString est supérieure au sens lexicographique à l'expression.
        =expression
        égal au sens lexicographique
        Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à - chaîne_de_test. La condition est satisfaite si - chaîne_de_test est égale au sens + TestString. La condition est satisfaite si + TestString est égale au sens lexicographique à l'expression (les deux chaînes sont exactement identiques, caractère pour caractère). Si expression est "" (deux guillemets), - chaîne_de_test est comparée à la + TestString est comparée à la chaîne vide.
        <=expression de comparaison
        inférieur ou égal à au sens lexicographique
        - Considère l'expression_de_comparaison comme une + Considère la CondPattern comme une chaîne de caractères et la compare au sens lexicographique à - la chaîne_de_test. Vrai si chaîne_de_test - précède lexicographiquement expression_de_comparaison, ou est - égale à expression_de_comparaison (les deux chaînes + la TestString. Vrai si TestString + précède lexicographiquement CondPattern, ou est + égale à CondPattern (les deux chaînes sont identiques, caractère pour caractère).
        >=expression de comparaison
        supérieur ou égal à au sens lexicographique
        - Considère l'expression_de_comparaison comme une + Considère la CondPattern comme une chaîne de caractères et la compare au sens lexicographique à - la chaîne_de_test. Vrai si chaîne_de_test - suit lexicographiquement expression_de_comparaison, ou est - égale à expression_de_comparaison (les deux chaînes + la TestString. Vrai si TestString + suit lexicographiquement CondPattern, ou est + égale à CondPattern (les deux chaînes sont identiques, caractère pour caractère).
        -
        +
        Note L'opérateur de comparaison de chaînes fait partie des arguments de la CondPattern et doit par conséquent se trouver entre les @@ -922,53 +975,54 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0" -
      4. + + +

        Comparaisons d’entiers

        -
      5. - Vous pouvez effectuer des comparaisons d'entiers : -
        +
        -eq
        est numériquement égal à
        - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de comparaison. Vrai si les deux expressions sont numériquement égales.
        -ge
        est numériquement supérieur ou égal à
        - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement supérieure ou égale à - expression_de_comparaison.
        + CondPattern.
        -gt
        est numériquement supérieur à
        - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement - supérieure à expression_de_comparaison.
        + supérieure à CondPattern.
        -le
        est numériquement inférieur ou égal à
        - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement - inférieure ou égale à expression_de_comparaison. + inférieure ou égale à CondPattern. Attention à la confusion avec le drapeau -l en utilisant la variante the -L ou -h.
        -lt
        est numériquement inférieur à
        - La chaîne_de_test est considérée comme un entier, + TestString est considérée comme un entier, et est comparée numériquement à l'expression de - comparaison. Vrai si chaîne_de_test est + comparaison. Vrai si TestString est numériquement - inférieure à expression_de_comparaison. + inférieure à CondPattern. Attention à la confusion avec le drapeau -l en utilisant la variante the -L ou -h.
        @@ -980,39 +1034,43 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0" si les deux éléments comparés sont numériquement différents. Equivalent à !-eq. -
        -
      6. - -
      7. Vous pouvez effectuer différents tests sur les attributs de - fichier : -
        +
        + + +

        Tests des attributs de fichier

        + +
        -d
        est un répertoire
        - Traite chaîne_de_test comme un chemin et vérifie + Traite TestString comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un répertoire.
        -f
        est un fichier régulier
        - Traite chaîne_de_test comme un chemin et vérifie - s'il existe ou pas, et s'il s'agit d'un fichier régulier.
        + Traite TestString comme un chemin et vérifie + s'il existe ou pas, et s'il s'agit d'un fichier régulier. +
        -F
        test de l'existence d'un fichier via une sous-requête
        - Vérifie si chaîne_de_test est un fichier valide, + Vérifie si TestString est un fichier valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à utiliser avec précautions car les performances du serveur - peuvent s'en trouver affectées !
        + peuvent s'en trouver affectées ! +
        -h
        est un lien symbolique, selon la convention bash
        - Voir -l.
        + Voir -l. +
        -l
        est un lien symbolique
        - Considère la chaîne_de_test comme un chemin et + Considère la TestString comme un chemin et vérifie son existence et si elle est un lien symbolique. On peut aussi utiliser la convention bash -L ou -h lorsqu'il y a risque de confusion @@ -1024,14 +1082,14 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"
        -s
        est un fichier régulier d'une certaine taille
        - Considère la chaîne_de_test comme un chemin et + Considère la TestString comme un chemin et vérifie son existence et si elle est un fichier régulier d'une taille supérieure à zéro.
        -U

        test de l'existence d'une URL via une sous-requête
        - Vérifie si chaîne_de_test est une URL valide, + Vérifie si TestString est une URL valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à @@ -1046,24 +1104,26 @@ RewriteCond %{HTTP_USER_AGENT} "=This Robot/1.0"

        -x
        a l'attribut d'exécution positionné
        - Considère la chaîne_de_test comme un chemin et + Considère la TestString comme un chemin et vérifie son existence et si elle a son attribut d'exécution positionné. Ce positionnement est déterminé en fonction de l'OS sous-jacent.
        -
        + - Par exemple: +

        Par exemple :

        RewriteCond /var/www/%{REQUEST_URI} !-f RewriteRule ^(.+) /other/archive/$1 [R] -
      8. + -
      9. -

        Si la chaîne_de_test contient la valeur spéciale +

        Évaluation des expressions

        + +

        Si TestString contient la valeur spéciale expr, la chaîne de comparaison sera traitée en tant qu'expression rationnelle de type ap_expr.

        @@ -1079,31 +1139,35 @@ RewriteRule ^(.+) /other/archive/$1 [R] RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'" RewriteRule "^/images" "-" [F] -
      10. -
      + + + + +

      Drapeaux

      Vous pouvez aussi définir certains drapeaux pour - l'expression_de_comparaison en ajoutant ces - [drapeaux] + la CondPattern en ajoutant ces + [flags] comme troisième argument de la directive - RewriteCond, où drapeaux est un + RewriteCond, où flags est un sous-ensemble séparé par des virgules des drapeaux suivants :

      -
        -
      • 'nocase|NC' - (no case)
        +
        +
        'nocase|NC'
        +
        (no case)
        Rend le test insensible à la casse - il n'est pas fait de distinction entre majuscules et minuscules, à la fois dans le - développement de chaîne_de_test et dans - expression_de_comparaison. Ce drapeau n'est pris en - compte que lors d'une comparaison entre chaîne_de_test - et expression_de_comparaison. Il ne l'est pas pour les + développement de TestString et dans + CondPattern. Ce drapeau n'est pris en + compte que lors d'une comparaison entre TestString + et CondPattern. Il ne l'est pas pour les vérification par sous-requêtes ou sur le système de - fichiers.
      • + fichiers. + -
      • - 'ornext|OR' - (ou condition suivante)
        +
        'ornext|OR'
        +
        (or condition suivante)
        Permet de chaîner les conditions de règles avec un OU au lieu du AND implicite. Exemple typique : @@ -1116,10 +1180,10 @@ RewriteRule ...règles concernant tous ces hôtes... Sans ce drapeau, les paires condition/règle devraient être écrites trois fois. -
      • + -
      • 'novary|NV' - (no vary)
        +
        'novary|NV'
        +
        (no vary)
        Si la condition contient un en-tête HTTP, ce drapeau empêche ce dernier d'être ajouté à l'en-tête Vary de la réponse.
        L'utilisation de ce drapeau peut provoquer une mise en cache @@ -1127,11 +1191,15 @@ RewriteRule ...règles concernant tous ces hôtes... varie avec la valeur de l'en-tête considéré. Ce drapeau ne devrait donc être utilisé que si l'on maîtrise parfaitement le fonctionnement de l'en-tête Vary. -
      • -
      + + + + + -

      Exemple :

      +

      Exemple

      Pour réécrire la page d'accueil d'un site en fonction de l'en-tête ``User-Agent:'' de la requête, vous @@ -1168,7 +1236,7 @@ RewriteRule "^/$" "/homepage.std.html" [L] RewriteRule Définit les règles pour le moteur de réécriture RewriteRule - Modèle Substitution [drapeaux] + [!]Pattern Substitution [flags] server configvirtual host directory.htaccess FileInfo @@ -1182,12 +1250,15 @@ RewriteRule "^/$" "/homepage.std.html" [L] les règles seront appliquées au cours du processus de réécriture.

      -

      Modèle est une Pattern est une expression rationnelle. Ce avec quoi ce modèle est comparé dépend de l'endroit où la directive RewriteRule est définie.

      +

      Si le motif est précédé d’un !, la substitution ne sera + effectuée que si le pattern ne correspond pas.

      + <a id="what_is_matched" name="what_is_matched">Qu'est-ce qui est comparé ?</a>
        @@ -1201,17 +1272,17 @@ RewriteRule "^/$" "/homepage.std.html" [L]
      • Dans un contexte de répertoire (sections Directory et fichiers .htaccess), le - Modèle est comparé avec une partie de chemin ; par exemple une + Pattern est comparé avec une partie de chemin ; par exemple une requête pour "/app1/index.html" entraînera une comparaison avec "app1/index.html" ou "index.html" selon le chemin de répertoire où la directive RewriteRule est définie.

        -

        Le chemin de répertoire auquel la règle s'applique est supprimé du +

        Le chemin de répertoire auquel la règle s’applique est supprimé du chemin correspondant du système de fichiers avant comparaison (jusqu'au slash final compris). En conséquence de cette suppression, les règles définies dans ce contexte n'effectuent des comparaisons qu'avec la portion du chemin du système de fichiers "en dessous" du chemin de répertoire - auquel la règle s'applique.

        + auquel la règle s’applique.

        Le chemin correspondant actuel du système de fichiers est déterminé par des directives telles que DocumentRoot et @@ -1306,36 +1377,17 @@ dernière.

      • -

        Pour quelques conseils à propos des expressions rationnelles, voir le - document Introduction à - mod_rewrite.

        - -

        Dans mod_rewrite, on peut aussi utiliser le caractère - NOT ('!') comme préfixe de modèle. Ceci vous permet - d'inverser la signification d'un modèle, soit pour dire - ``si l'URL considérée ne correspond PAS à - ce modèle''. Le caractère NON peut donc être utilisé à - titre exceptionnel, lorsqu'il est plus simple d'effectuer une - comparaison avec le modèle inversé, ou dans la dernière règle - par défaut.

        - -Note -Si vous utilisez le caractère NON pour inverser la signification d'un -modèle, vous ne pouvez pas inclure de parties génériques groupées dans -le modèle. Ceci est dû au fait que, lorsque le modèle ne correspond -pas (autrement dit, sa négation correspond), les groupes sont vides. -Ainsi, si vous utilisez des modèles inversés, vous ne pouvez -pas vous référer aux groupes par $N dans la chaîne de -substitution ! - +

        Pour des informations à propos des expressions + rationnelles, y compris l’utilisation du préfixe ! + pour inverser un motif, voir la section Expressions rationnelles de + l’introduction à mod_rewrite.

        -

        Dans une règle de réécriture, - Substitution est la chaîne - de caractères qui remplace le chemin de l'URL original qui - correspondait au Modèle. Substitution peut - être :

        +

        Dans une règle de réécriture, Substitution est la chaîne de caractères qui + remplace le chemin de l'URL (voir "Qu’est-ce + qui est comparé ?" ci-avant) lorsque les conditions de la règle sont + satisfaites. Substitution peut être :

        @@ -1343,7 +1395,7 @@ substitution !
        Il indique alors la localisation dans le système de fichiers de la ressource qui doit être envoyée au client. Une substitution commençant - par / n'est traitée comme un chemin du système de fichiers + par / n’est traitée comme un chemin du système de fichiers que dans un contexte de serveur virtuel ou de serveur global, et seulement si le premier composant du chemin existe dans le système de fichiers. Dans un contexte de @@ -1356,7 +1408,7 @@ substitution ! doit être servie. Dans un contexte de serveur virtuel ou de serveur global, si le premier composant du chemin existe à la racine du système de fichiers, la substitution est traitée comme un chemin du système de - fichiers. Par exemple, /www/file.html est un chemin d'URL, + fichiers. Par exemple, /www/file.html est un chemin d’URL, sauf si un répertoire nommé www existe à la racine du système de fichiers. Si vous désirez que d'autres directives de correspondance d'URL (comme la directive Comment sont interprétées les substitutions de chemin

        En fonction du contexte et si elle commence ou non par un slash, une substitution sera traitée comme un chemin du système de fichiers ou comme - un chemin d'URL :

        + un chemin d’URL :

        • Commence par un /, contexte de serveur virtuel ou de serveur global : Traitée comme un chemin du système de fichiers si le premier composant du - chemin existe sur disque ; sinon, traitée comme un chemin d'URL.
        • + chemin existe sur disque ; sinon, traitée comme un chemin d’URL.
        • Commence par un /, contexte de répertoire : - Toujours traitée comme un chemin d'URL. Pas de vérification sur le + Toujours traitée comme un chemin d’URL. Pas de vérification sur le système de fichiers.
        • Ne commence pas par un / (chemin relatif), contexte de serveur virtuel - ou de serveur global : Traitée comme un chemin d'URL relatif à - l'URI de la requête actuelle.
        • + ou de serveur global : Traitée comme un chemin d’URL relatif à + l’URI de la requête actuelle.
        • Ne commence pas par un / (chemin relatif), contexte de - répertoire : Traitée comme un chemin d'URL relatif + répertoire : Traitée comme un chemin d’URL relatif au chemin de répertoire auquel la directive Directory ou le fichier .htaccess - s'appliquent. Voir RewriteBase pour le contrôle + s’appliquent. Voir RewriteBase pour le contrôle du préfixe ajouté aux substitutions relatives.
        @@ -1427,7 +1479,7 @@ substitution ! condition d'une règle (%{VARNAME})
      • des appels de - fonctions de comparaison + fonctions de mappage (${nom correspondance:clé|défaut})
      • @@ -1480,10 +1532,10 @@ substitution !

        En outre, vous pouvez spécifier des actions spéciales à effectuer en ajoutant des - [drapeaux] + [flags] comme troisième argument de la directive RewriteRule. Séparés par des virgules au sein d'une - liste encadrée par des crochets, les drapeaux peuvent + liste encadrée par des crochets, les flags peuvent être choisis dans la table suivante. Vous trouverez plus de détails, et des exemples pour chaque drapeau dans le document à propos des drapeaux de @@ -1667,7 +1719,7 @@ substitution !

      - @@ -1675,7 +1727,7 @@ substitution !

      Traitement des bugs

      Voir aussi

        +
      • Modules multi-processus (MPMs)
      • Définition des adresses et ports qu'utilise Apache httpd
      • diff --git a/docs/manual/mod/mpm_netware.xml b/docs/manual/mod/mpm_netware.xml index 5ea65a50f3e..01c2e225f7a 100644 --- a/docs/manual/mod/mpm_netware.xml +++ b/docs/manual/mod/mpm_netware.xml @@ -60,7 +60,9 @@ ones and launching new ones. On the NetWare OS it is highly recommended that this directive remain set to 0. This allows worker threads to continue servicing requests indefinitely.

        + +Multi-Processing Modules (MPMs) Setting which addresses and ports Apache httpd uses diff --git a/docs/manual/mod/mpm_netware.xml.fr b/docs/manual/mod/mpm_netware.xml.fr index 6394fe58b68..76e21e06fab 100644 --- a/docs/manual/mod/mpm_netware.xml.fr +++ b/docs/manual/mod/mpm_netware.xml.fr @@ -1,7 +1,7 @@ - + @@ -69,6 +69,7 @@ NetWare laisser cette directive à 0, ce qui permet aux threads esclaves de continuer à traiter les requêtes indéfiniment.

        +Modules multi-processus (MPMs) Définition des adresses et ports qu'utilise Apache httpd diff --git a/docs/manual/mod/mpm_winnt.html.en.utf8 b/docs/manual/mod/mpm_winnt.html.en.utf8 index 70fdf97cb29..eb114402512 100644 --- a/docs/manual/mod/mpm_winnt.html.en.utf8 +++ b/docs/manual/mod/mpm_winnt.html.en.utf8 @@ -102,6 +102,7 @@ AcceptFilter https none documentation for details.)
      +

      Directives

        @@ -121,6 +122,7 @@ AcceptFilter https none

      Bugfix checklist

      See also

      diff --git a/docs/manual/mod/mpm_winnt.html.fr.utf8 b/docs/manual/mod/mpm_winnt.html.fr.utf8 index 2b238bf5e32..91e344be89a 100644 --- a/docs/manual/mod/mpm_winnt.html.fr.utf8 +++ b/docs/manual/mod/mpm_winnt.html.fr.utf8 @@ -126,6 +126,7 @@ AcceptFilter https none

      Traitement des bugs

      Voir aussi

      diff --git a/docs/manual/mod/mpm_winnt.xml b/docs/manual/mod/mpm_winnt.xml index 45012c56cec..9db82b79bda 100644 --- a/docs/manual/mod/mpm_winnt.xml +++ b/docs/manual/mod/mpm_winnt.xml @@ -95,8 +95,10 @@ AcceptFilter https none documentation for details.) + +Multi-Processing Modules (MPMs)Using Apache HTTP Server on Microsoft WindowsAcceptFilter diff --git a/docs/manual/mod/mpm_winnt.xml.de b/docs/manual/mod/mpm_winnt.xml.de index dd0273f1752..b3281aa4e4e 100644 --- a/docs/manual/mod/mpm_winnt.xml.de +++ b/docs/manual/mod/mpm_winnt.xml.de @@ -1,7 +1,7 @@ - + + @@ -109,6 +109,7 @@ AcceptFilter https none +Modules multi-processus (MPMs) Utiliser le serveur HTTP Apache sous Microsoft Windows diff --git a/docs/manual/mod/mpm_winnt.xml.ja b/docs/manual/mod/mpm_winnt.xml.ja index 3942af52d03..c435e6943f9 100644 --- a/docs/manual/mod/mpm_winnt.xml.ja +++ b/docs/manual/mod/mpm_winnt.xml.ja @@ -1,7 +1,7 @@ - + + @@ -48,7 +48,9 @@ OS/2 nombre de threads inactifs soit maintenu entre MinSpareThreads et MaxSpareThreads.

      + +Modules multi-processus (MPMs) Définition des adresses et ports qu'utilise Apache diff --git a/docs/manual/mod/overrides.html.fr.utf8 b/docs/manual/mod/overrides.html.fr.utf8 index 07472151c61..449e84c6d62 100644 --- a/docs/manual/mod/overrides.html.fr.utf8 +++ b/docs/manual/mod/overrides.html.fr.utf8 @@ -308,9 +308,9 @@ condensés du défit et de sa réponse
      - - + + diff --git a/docs/manual/mod/prefork.html.en.utf8 b/docs/manual/mod/prefork.html.en.utf8 index 2f91abac65c..9137e508dfc 100644 --- a/docs/manual/mod/prefork.html.en.utf8 +++ b/docs/manual/mod/prefork.html.en.utf8 @@ -52,6 +52,12 @@ to handle as many simultaneous requests as you expect to receive, but small enough to assure that there is enough physical RAM for all processes.

      + +

      When built as a DSO module, it can be loaded with:

      + +
      LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
      + + diff --git a/docs/manual/mod/prefork.html.fr.utf8 b/docs/manual/mod/prefork.html.fr.utf8 index cbed1efcb76..e92cd889e75 100644 --- a/docs/manual/mod/prefork.html.fr.utf8 +++ b/docs/manual/mod/prefork.html.fr.utf8 @@ -55,6 +55,13 @@ processus, sans thread assez grande pour pouvoir traiter autant de requêtes simultanées que vous pensez recevoir, mais assez petite pour conserver suffisamment de mémoire RAM pour tous les processus.

      + +

      Lorsqu’il est construit en tant que module DSO, ce module peut être + chargé avec la commande :

      + +
      LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
      + + diff --git a/docs/manual/mod/prefork.html.tr.utf8 b/docs/manual/mod/prefork.html.tr.utf8 index e91f8c5afc2..fcb767a98c1 100644 --- a/docs/manual/mod/prefork.html.tr.utf8 +++ b/docs/manual/mod/prefork.html.tr.utf8 @@ -32,6 +32,7 @@  ja  |  tr 

      +
      Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.
      UnsafeAllow3FAutorise les substitutions à partir d'URL potentiellement non + Autorise les substitutions à partir d’URL potentiellement non fiables. détails ...
      UnsafePrefixStat Autorise les substitutions potentiellement non fiables à partir - d'une variable de tête ou d'une référence arrière vers un chemin du + d’une variable de tête ou d’une référence arrière vers un chemin du système de fichiers. détails ...
      2.5.1 diff --git a/docs/manual/mod/mod_rewrite.xml.meta b/docs/manual/mod/mod_rewrite.xml.meta index 0be21e86f4d..decc0a7b1e8 100644 --- a/docs/manual/mod/mod_rewrite.xml.meta +++ b/docs/manual/mod/mod_rewrite.xml.meta @@ -8,6 +8,6 @@ en - fr + fr diff --git a/docs/manual/mod/mod_ssl_ct.xml b/docs/manual/mod/mod_ssl_ct.xml index 76274755d7b..5d30bb6db64 100644 --- a/docs/manual/mod/mod_ssl_ct.xml +++ b/docs/manual/mod/mod_ssl_ct.xml @@ -25,7 +25,7 @@ mod_ssl_ct Implementation of Certificate Transparency (RFC 6962) -Extension +Deprecated mod_ssl_ct.c ssl_ct_module diff --git a/docs/manual/mod/mod_unique_id.html.fr.utf8 b/docs/manual/mod/mod_unique_id.html.fr.utf8 index dd7ccbdcd2d..4b651ddf277 100644 --- a/docs/manual/mod/mod_unique_id.html.fr.utf8 +++ b/docs/manual/mod/mod_unique_id.html.fr.utf8 @@ -31,8 +31,6 @@  ja  |  ko 

      -
      Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
      @@ -88,27 +86,30 @@ identifiant unique pour chaque requête
    • Les temps des machines sont synchronisés via NTP ou tout autre protocole de synchronisation du temps en réseau.
    • -
    • Les nom d'hôtes des machines sont tous différents, de façon à - ce que le module puisse recevoir une adresse IP différente pour - chaque machine du cluster en effectuant une recherche sur le nom - d'hôte.
    • +

      Changements à partir de la version 2.4.29

      +

      Dans les versions précédentes, l’unicité nécessitait aussi que chaque + machine ait une adresse IP distincte. Depuis la version 2.4.29, le module + utilise un générateur de nombres pseudo-aléatoires cryptographique (PRNG) + ensemencé au démarrage, tout en supprimant l’adresse IP et le PID de + l’identifiant et en ne nécessitant plus de noms d’hôte distincts ou de + délai au démarrage.

      +

      Au vu des caractéristiques actuelles du système d'exploitation, nous supposerons que les pids (identifiants processus) sont codés sur 32 bits. Si le système d'exploitation utilise plus de 32 bits pour un pid, la correction est triviale mais doit être effectuée dans le code.

      -

      Ces hypothèses posées, à un instant donné, nous pouvons - distinguer tout processus httpd sur toute machine du cluster de tous - les autres processus httpd. Pour ce faire, il suffit d'utiliser - l'adresse IP de la machine et le pid du processus httpd. Un - processus httpd peut traiter plusieurs requêtes simultanément si - vous utilisez un module MPM multi-threadé. Pour identifier les - threads, Apache httpd utilise en interne un index de threads. Ainsi, - afin de générer des identifiants uniques pour chaque requête, il - suffit d'effectuer une distinction en fonction du temps.

      +

      Ces hypothèses posées, à un instant donné, nous pouvons distinguer tout + processus httpd sur toute machine du cluster de tous les autres processus + httpd. La valeur racine générée par PRNG et l’index des threads permettent + d’accomplir cette tâche. Un processus httpd peut traiter plusieurs requêtes + simultanément si vous utilisez un module MPM multi-threadé. Pour identifier + les threads, Apache httpd utilise en interne un index de threads. Ainsi, + afin de générer des identifiants uniques pour chaque requête, il suffit + d'effectuer une distinction en fonction du temps.

      Pour déterminer le temps, nous utiliserons un repère de temps Unix (les secondes écoulées depuis le 1er janvier 1970 UTC), et un @@ -190,21 +191,21 @@ identifiant unique pour chaque requête redémarrage.

      -

      La variable d'environnement UNIQUE_ID est construite - par codage du quadruplet de 144 bits (adresse IP sur 32 bits, pid - sur 32 bits, repère de temps sur 32 bits, compteur 16 bits et index - de threads sur 32 bits) en +

      Depuis la version 2.4.29, la variable d'environnement UNIQUE_ID est construite + par codage d’une valeur de 160 bits (32 bits pour l’horodatage, 80 bits pour + la racine PRNG, 16 bits pour le compteur et 32 bits pour l’index des + threads)) en utilisant l'alphabet [A-Za-z0-9_-] d'une manière similaire à celle du codage MIME base64, et sa valeur se présente - sous la forme d'une chaîne de 24 caractères. L'alphabet MIME base64 + sous la forme d'une chaîne de 27 caractères. L'alphabet MIME base64 est en fait [A-Za-z0-9+/] ; cependant, les caractères + et / nécessitent un codage particulier dans les URLs, ce qui rend leur utilisation peu commode. Toutes les valeurs sont codées dans l'ordre des octets d'une adresse réseau de façon à ce que le codage soit comparable entre des architectures où l'ordre des - octets est différent. L'ordre réel de codage est : repère de temps, - adresse IP, pid, compteur. Cet ordre de codage possède un but + octets est différent. L'ordre réel de codage est : horodatage, racine, + compteur, index des threads. Cet ordre de codage possède un but précis, mais il faut souligner que les applications n'ont aucun intérêt à entrer dans les détails de ce codage. Les applications doivent se contenter de traiter la variable UNIQUE_ID @@ -232,12 +233,7 @@ identifiant unique pour chaque requête machines du cluster (seule la synchronisation NTP est requise, ce qui représente une charge très faible), et aucune communication entre les processus httpd n'est nécessaire (la communication est - implicite et incluse dans le pid assigné par le noyau). Dans des - situations très spécifiques, l'identifiant peut être raccourci, mais - dans ce cas, d'avantage d'informations doivent être admises (par - exemple, les 32 bits de l'adresse IP sont excessifs pour la plupart - des sites, mais il n'existe pas de valeur de remplacement portable - plus courte).

      + implicite dans la graine PRNG assignée au démarrage)..

      diff --git a/docs/manual/mod/mod_unique_id.xml.fr b/docs/manual/mod/mod_unique_id.xml.fr index adaaccaa54b..c04ba0e84ef 100644 --- a/docs/manual/mod/mod_unique_id.xml.fr +++ b/docs/manual/mod/mod_unique_id.xml.fr @@ -1,7 +1,7 @@ - + @@ -13,7 +13,7 @@ (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 +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, @@ -73,27 +73,30 @@ identifiant unique pour chaque requête
    • Les temps des machines sont synchronisés via NTP ou tout autre protocole de synchronisation du temps en réseau.
    • -
    • Les nom d'hôtes des machines sont tous différents, de façon à - ce que le module puisse recevoir une adresse IP différente pour - chaque machine du cluster en effectuant une recherche sur le nom - d'hôte.
    • + Changements à partir de la version 2.4.29 +

      Dans les versions précédentes, l’unicité nécessitait aussi que chaque + machine ait une adresse IP distincte. Depuis la version 2.4.29, le module + utilise un générateur de nombres pseudo-aléatoires cryptographique (PRNG) + ensemencé au démarrage, tout en supprimant l’adresse IP et le PID de + l’identifiant et en ne nécessitant plus de noms d’hôte distincts ou de + délai au démarrage.

      +

      Au vu des caractéristiques actuelles du système d'exploitation, nous supposerons que les pids (identifiants processus) sont codés sur 32 bits. Si le système d'exploitation utilise plus de 32 bits pour un pid, la correction est triviale mais doit être effectuée dans le code.

      -

      Ces hypothèses posées, à un instant donné, nous pouvons - distinguer tout processus httpd sur toute machine du cluster de tous - les autres processus httpd. Pour ce faire, il suffit d'utiliser - l'adresse IP de la machine et le pid du processus httpd. Un - processus httpd peut traiter plusieurs requêtes simultanément si - vous utilisez un module MPM multi-threadé. Pour identifier les - threads, Apache httpd utilise en interne un index de threads. Ainsi, - afin de générer des identifiants uniques pour chaque requête, il - suffit d'effectuer une distinction en fonction du temps.

      +

      Ces hypothèses posées, à un instant donné, nous pouvons distinguer tout + processus httpd sur toute machine du cluster de tous les autres processus + httpd. La valeur racine générée par PRNG et l’index des threads permettent + d’accomplir cette tâche. Un processus httpd peut traiter plusieurs requêtes + simultanément si vous utilisez un module MPM multi-threadé. Pour identifier + les threads, Apache httpd utilise en interne un index de threads. Ainsi, + afin de générer des identifiants uniques pour chaque requête, il suffit + d'effectuer une distinction en fonction du temps.

      Pour déterminer le temps, nous utiliserons un repère de temps Unix (les secondes écoulées depuis le 1er janvier 1970 UTC), et un @@ -175,21 +178,21 @@ identifiant unique pour chaque requête redémarrage.

      -

      La variable d'environnement UNIQUE_ID est construite - par codage du quadruplet de 144 bits (adresse IP sur 32 bits, pid - sur 32 bits, repère de temps sur 32 bits, compteur 16 bits et index - de threads sur 32 bits) en +

      Depuis la version 2.4.29, la variable d'environnement UNIQUE_ID est construite + par codage d’une valeur de 160 bits (32 bits pour l’horodatage, 80 bits pour + la racine PRNG, 16 bits pour le compteur et 32 bits pour l’index des + threads)) en utilisant l'alphabet [A-Za-z0-9_-] d'une manière similaire à celle du codage MIME base64, et sa valeur se présente - sous la forme d'une chaîne de 24 caractères. L'alphabet MIME base64 + sous la forme d'une chaîne de 27 caractères. L'alphabet MIME base64 est en fait [A-Za-z0-9+/] ; cependant, les caractères + et / nécessitent un codage particulier dans les URLs, ce qui rend leur utilisation peu commode. Toutes les valeurs sont codées dans l'ordre des octets d'une adresse réseau de façon à ce que le codage soit comparable entre des architectures où l'ordre des - octets est différent. L'ordre réel de codage est : repère de temps, - adresse IP, pid, compteur. Cet ordre de codage possède un but + octets est différent. L'ordre réel de codage est : horodatage, racine, + compteur, index des threads. Cet ordre de codage possède un but précis, mais il faut souligner que les applications n'ont aucun intérêt à entrer dans les détails de ce codage. Les applications doivent se contenter de traiter la variable UNIQUE_ID @@ -217,12 +220,7 @@ identifiant unique pour chaque requête machines du cluster (seule la synchronisation NTP est requise, ce qui représente une charge très faible), et aucune communication entre les processus httpd n'est nécessaire (la communication est - implicite et incluse dans le pid assigné par le noyau). Dans des - situations très spécifiques, l'identifiant peut être raccourci, mais - dans ce cas, d'avantage d'informations doivent être admises (par - exemple, les 32 bits de l'adresse IP sont excessifs pour la plupart - des sites, mais il n'existe pas de valeur de remplacement portable - plus courte).

      + implicite dans la graine PRNG assignée au démarrage)..

      diff --git a/docs/manual/mod/mod_unique_id.xml.meta b/docs/manual/mod/mod_unique_id.xml.meta index 433c4753bb6..c5e950d875b 100644 --- a/docs/manual/mod/mod_unique_id.xml.meta +++ b/docs/manual/mod/mod_unique_id.xml.meta @@ -8,7 +8,7 @@ en - fr + fr ja ko diff --git a/docs/manual/mod/module-dict.xml b/docs/manual/mod/module-dict.xml index ed6e06b3005..1cd042714d0 100644 --- a/docs/manual/mod/module-dict.xml +++ b/docs/manual/mod/module-dict.xml @@ -71,6 +71,13 @@ if you try to use it. The module is being documented for completeness, and is not necessarily supported. +
      Deprecated
      + +
      A module with "Deprecated" status is still available and + functional, but its use is discouraged. The module may be + removed in the next minor release. Check the module's documentation for + recommended replacements or migration paths.
      +
      External
      Modules which are not included with the base Apache diff --git a/docs/manual/mod/motorz.html b/docs/manual/mod/motorz.html index 915fb7cf07d..3e3a13e6502 100644 --- a/docs/manual/mod/motorz.html +++ b/docs/manual/mod/motorz.html @@ -3,3 +3,7 @@ URI: motorz.html.en.utf8 Content-Language: en Content-type: text/html; charset=UTF-8 + +URI: motorz.html.fr.utf8 +Content-Language: fr +Content-type: text/html; charset=UTF-8 diff --git a/docs/manual/mod/motorz.html.en.utf8 b/docs/manual/mod/motorz.html.en.utf8 index dfa8743988d..c02367afc7f 100644 --- a/docs/manual/mod/motorz.html.en.utf8 +++ b/docs/manual/mod/motorz.html.en.utf8 @@ -26,7 +26,8 @@

      Apache MPM motorz

      -

      Available Languages:  en 

      +

      Available Languages:  en  | + fr 

      Description:Fournit une variable d'environnement contenant un identifiant unique pour chaque requête
      Statut:Extension
      @@ -55,6 +56,12 @@ built on the APR pollset and thread pool especially suited as a reverse proxy--enable-mpms-shared=motorz.

      + +

      When built as a DSO module, it can be loaded with:

      + +
      LoadModule mpm_motorz_module modules/mod_mpm_motorz.so
      + +

      Topics

      -

      Available Languages:  en 

      +

      Available Languages:  en  | + fr 

      + + + + +
      <-
      + +
      +

      Apache MPM motorz

      + +
      +

      Langues Disponibles:  en  | + fr 

      +
      +
      Description:A lean, fast, self-contained event-driven Multi-Processing Module built on the APR pollset and thread pool especially suited as a reverse proxy
      + + +
      Description:Un MPM (Multi-Processing Module) événementiel léger, rapide et +autonome basé sur l'ensemble de requêtes et le pool de threads APR, +particulièrement adapté comme mandataire inverse
      Statut:MPM
      Identificateur de Module:mpm_motorz_module
      Fichier Source:motorz.c
      +

      Sommaire

      + +

      Le MPM motorz est une implémentation évènementielle + asynchrone. Il combine un ensemble fixe de processus enfants de style prefork + avec un cœur construit sur l’ensemble de requêtes d’APR + et un jeu de threads partagés. Chaque processus enfant exécute un ou + plusieurs threads sondeurs dédiés qui surveillent les sockets et + les compteurs de délai tout en répartissant les évènements d’entrée/sortie prêts + et les compteurs de délai expirés parmi un jeu de threads de travail. Les + threads de travail ne sondent jamais ; ils ne font que traiter les + connexions/requêtes qui leur sont envoyées.

      + +

      Le but est de concevoir un MPM rapide, efficace, autonome et compact qui + fonctionne sur les plateformes Unix modernes en s’appuyant le plus possible + sur APR, tout en prenant en charge la gestion des connexions asynchrones + nécessaire à l’efficacité des connexions persistantes et de HTTP/2.

      + +

      Pour utiliser le MPM motorz, ajoutez + --with-mpm=motorz aux arguments du script + configure lors de la construction de + httpd, ou construisez le en tant que module chargeable + avec --enable-mpms-shared=motorz.

      + +

      Lorsque ce module est construit en tant que module DSO, il peut être + chargé avec la commande :

      + +
      LoadModule mpm_motorz_module modules/mod_mpm_motorz.so
      + + + + +
      top
      +
      +

      Comment cela fonctionne-t-il

      +

      motorz utilise prefork comme cadre pour la gestion des + processus et un cœur à base d’évènements pour la gestion des connexions. Un + seul processus de contrôle (le parent) lance un nombre fixe de processus + enfants, ce nombre étant défini par la directive StartServers. À la différence des MPM + worker et event, le nombre de processus + enfants ne varie pas avec la charge : motorz maintient un + jeu de processus statique en les remplaçant nombre pour nombre lorsqu’ils + quittent. Le parallélisme de traitement au sein d’un hôte est mis en œuvre + en ajoutant des threads de travail (ThreadsPerChild) et, lorsque le cheminement + du processus de sondage/répartition constitue un goulot d’étranglement, des + threads sondeurs (PollersPerChild), au lieu de lancer + davantage de processus.

      + +

      Chaque processus enfant exécute :

      +
        +
      • Un ou plusieurs threads sondeurs. Chaque sondeur + possède ses propres domaine de sondage, sonnerie de chronomètre (avec un + mutex de protection) et liste de recyclage du jeu de transactions non + bloquante, de sorte que les sondeurs n’interfèrent pas les uns avec les + autres. Un thread sondeur sonde, répartit les évènements d’entrée/sortie + prêts et les délais expirés au sein du jeu de threads de travail, et (en + ce qui concerne le thread sondeur qui possède le socket d’écoute) + accepte de nouvelles connexions. Le nombre de threads sondeurs est + contrôlé par la directive PollersPerChild.
      • + +
      • Un jeu de threads de travail partagé (ThreadsPerChild) qui gère la connexion + proprement dite et traite les requêtes qui lui sont envoyées. Les + threads de travail ne sondent jamais.
      • + +
      • Un superviseur (le thread principal de l’enfant) + qui surveille MaxConnectionsPerChild et la + "pipe-of-death / generation", enjoint les threads sondeurs de ralentir + et les rejoint lorsqu’ils quittent.
      • +
      + +

      Une connexion est attribuée à un thread sondeur au moment de + l'acceptation (round-robin) et le reste pendant toute sa durée de vie : elle + réinitialise et fait passer à l’état expiré le domaine de sondage et la + sonnerie du chronomètre de ce thread sondeur. Utiliser plusieurs threads + sondeurs augmente le plafond de débit par rapport à celui d’un sondage par + thread unique ; ainsi l’acceptation, la répartition des évènements et + l’expiration du délai sont réglées par + PollersPerChild au lieu d’être sérialisées sur un + seul thread.

      + +

      Alors que le processus parent est en général démarré en tant que + root sous Unix de façon à se lier au port 80, les processus + enfants et les threads sont lancés par le serveur sous un utilisateur moins + privilégié. Les directives User et + Group permettent de définir les + privilèges des processus enfants du serveur HTTP Apache. Les processus enfants + doivent pouvoir lire tout le contenu destiné à être servi, mais cela mis à + part, doivent posséder le moins de privilèges possible.

      + +

      La directive MaxConnectionsPerChild permet de contrôler + la fréquence à laquelle le serveur recycle les processus en retirant les + anciens et en en lançant de nouveaux.

      +
      top
      +
      +

      Gestion des connexions asynchrones

      +

      motorz se définit lui-même comme un MPM asynchrone. + Lorsqu’un thread de travail termine la phase active d’une connexion (par + exemple, une connexion persistante HTTP entre les requêtes ou une connexion + attendant une entrée/sortie), il confie le socket à son thread sondeur au + lieu de maintenir un thread de travail inactif. Le thread sondeur attend le + prochain évènement sur ce socket (dans les limites du délai défini par la + directive Timeout) et n’attribue + la connexion à un thread de travail que s’il y a quelque chose à faire. Cela + libère les threads de travail des connexions persistantes inactives et + permet une gestion efficace de HTTP/2 où la connexion principale est reprise + par le MPM entre les requêtes.

      + +

      La fermeture avec délai (lingering close) n’est, elle non plus, pas + bloquante : plutôt que de bloquer un thread de travail pendant la durée du + délai de fermeture, le socket en cours de vidage est confié à la boucle de + sondage avec un délai d’inaction limité ; ainsi, le thread de travail est + replacé dans le pool immédiatement.

      + +

      Les modules qui acceptent une connexion totalement asynchrone (la + suspendant et la réactivant plus tard) sont pris en charge ; une connexion + suspendue est parquée et réarmée sur son propre thread sondeur lorsqu’elle + est réactivée.

      +
      top
      +
      +

      Contrôle d’admission

      +

      Pour qu’un processus enfant reste fiable en cas de surcharge, + motorz applique une pression en retour (backpressure) à + l’écouteur. Lorsque le pool de threads de travail sature, le thread sondeur + qui possède les sockets d’écoute les enlève de son domaine de sondage et + arrête d’accepter ; il les réajoute lorsque la liste de demandes se + vide. Cela a pour effet de limiter la taille de la file d’attente de + travaux et la mémoire consommée par connexion, au lieu de les laisser + grandir sans limite. La décision se base sur le décompte des threads + inactifs, en attente et actifs dans le pool de threads de travail, avec + hystérèse pour éviter un basculement excessif des écouteurs entre « on » et + « off ».

      + +

      ThreadsPerChild et contrôle d’admission

      +

      Ètant donné que la marque des « basses eaux » du contrôle d’admission est + une fraction de la valeur de la directive ThreadsPerChild, une très petite valeur pour + cette dernière (en particulier ThreadsPerChild 1) fait que les + écouteurs ne sont réactivés que lorsque la file d’attente de travaux est + totalement vide, ce qui dégrade sévèrement le débit. Une valeur d’au moins 4 + pour ThreadsPerChild est fortement recommandée ; si cette + valeur est inférieure à 4, le serveur émet un avertissement.

      +
      +
      top
      +
      +

      Liens de parenté avec les autres MPMs

      +

      motorz utilise prefork pour la gestion des processus et + un pool de threads de travail APR, avec des threads sondeurs qui + répartissent le travail au sein du pool de threads de travail. Cette + approche est différente de la conception écouteur,thread de travail/fdqueue + du MPM event dans laquelle les threads de travail réarment + eux-mêmes un domaine de sondage partagé et sûr en ce qui concerne les + threads.

      + +

      La charge de travail détermine si l’ajout de threads sondeurs peut aider. + Si les threads de travail constituent le goulot d’étranglement du + CPU#8212;c’est en général le cas pour le traitement réel des + requêtes#8212;les threads sondeurs ne sont pas le facteur de limitation et + une valeur de la directive PollersPerChild au delà + de 1 ou 2 sera de peu d’effet. La conception à plusieurs threads sondeurs + supprime le plafond structurel de la conception à thread sondeur + unique, mais le débit par hôte reste tout de même gouverné par le CPU de + travail.

      + +

      Pas de ServerLimit / modification dynamique du nombre de + processus

      +

      À la différence des MPMs worker et + event, motorz ne modifie pas le nombre de + processus enfants avec la charge et ne définit pas de plafond séparé avec + ServerLimit. Le nombre de + processus enfants est fixé par la directive StartServers qui agit de ce fait comme une + limite physique du démon, et il n’y a pas de contrôles du style MinSpareThreads, MaxSpareThreads ou MaxRequestWorkers. Il est possible de + définir le parallélisme du traitement avec la directive ThreadsPerChild (et, si le processus de + sondage sature, avec la directive PollersPerChild).

      +
      +
      +
      top
      +

      Directive PollersPerChild

      + + + + + + + +
      Description:Nombre de threads sondeurs par processus enfant
      Syntaxe:PollersPerChild number
      Défaut:PollersPerChild 0
      Contexte:configuration globale
      Statut:MPM
      Module:motorz
      +

      La directive PollersPerChild permet de définir le + nombre de threads sondeurs pour chaque processus enfant. Chaque thread + sondeur possède ses propres domaine de sondage, sonnerie de chronomètre et + liste de recyclage de connexion, et gère une partie des connexions du + processus enfant. Comme chaque thread sondeur accepte les connexions de + manière indépendante et répartit les évènements d’entrée/sortie et les + expirations de délai au sein du jeu de threads de travail, ajouter des + threads sondeurs augmente la fréquence à laquelle un seul processus enfant + peut gérer ces opérations en parallèle, plutôt que de les sérialiser sur un + seul thread sondeur.

      + +

      Une valeur de 0 (la valeur par défaut) signifie que le + nombre de threads sondeurs est calculé automatiquement : il est + déduit du nombre de CPUs en ligne, plafonné à un maximum codé en dur. Dans + tous les cas, le nombre de threads sondeurs est contraint de façon qu’il ne + dépasse jamais la valeur de la directive ThreadsPerChild et ne soit jamais inférieur + à un.

      + +

      Étant donné que la répartition d’évènements est rarement le goulot + d’étranglement pour le traitement des requêtes réelles—il s’agit en + général du CPU de travail—des valeurs au-delà de un ou deux améliorent + rarement le débit. Augmenter PollersPerChild s’avère + principalement utile pour les charges de travail dominées par une rotation + très importante des connexions ou un grand nombre de connexions à base + d’évènements et inactives, où le processus de sondage/acceptation devient la + limite.

      + +

      Exemple

      +
      StartServers       2
      +ThreadsPerChild   64
      +ThreadLimit       64
      +PollersPerChild    2
      + +
      + +
      + +
      +

      Langues Disponibles:  en  | + fr 

      +
      + \ No newline at end of file diff --git a/docs/manual/mod/motorz.xml b/docs/manual/mod/motorz.xml index 8950e476732..bc6287b1631 100644 --- a/docs/manual/mod/motorz.xml +++ b/docs/manual/mod/motorz.xml @@ -49,8 +49,16 @@ built on the APR pollset and thread pool especially suited as a reverse proxy--enable-mpms-shared=motorz.

      + +

      When built as a DSO module, it can be loaded with:

      + + +LoadModule mpm_motorz_module modules/mod_mpm_motorz.so + + +Multi-Processing Modules (MPMs) The event MPM The worker MPM The prefork MPM @@ -227,9 +235,11 @@ built on the APR pollset and thread pool especially suited as a reverse proxyThe PollersPerChild directive sets the number of poller threads created in each child process. Each poller owns its own pollset, timer ring and connection-recycle list, and handles a shard of - the child's connections, so adding pollers raises the rate at which a - single child can accept connections and dispatch I/O events and timer - expiries.

      + the child's connections. Because each poller thread independently + accepts connections and dispatches ready I/O events and timer + expiries to the worker pool, adding pollers raises the rate at which a + single child process can handle these operations in parallel rather than + serializing them on one poll thread.

      A value of 0 (the default) means auto: the number of pollers is derived from the number of online CPUs, capped at a built-in diff --git a/docs/manual/mod/motorz.xml.fr b/docs/manual/mod/motorz.xml.fr new file mode 100644 index 00000000000..b14f38261e9 --- /dev/null +++ b/docs/manual/mod/motorz.xml.fr @@ -0,0 +1,302 @@ + + + + + + + + + +motorz +Un MPM (Multi-Processing Module) événementiel léger, rapide et +autonome basé sur l'ensemble de requêtes et le pool de threads APR, +particulièrement adapté comme mandataire inverse +MPM +motorz.c +mpm_motorz_module + +

      +

      Le MPM motorz est une implémentation évènementielle + asynchrone. Il combine un ensemble fixe de processus enfants de style prefork + avec un cœur construit sur l’ensemble de requêtes d’APR + et un jeu de threads partagés. Chaque processus enfant exécute un ou + plusieurs threads sondeurs dédiés qui surveillent les sockets et + les compteurs de délai tout en répartissant les évènements d’entrée/sortie prêts + et les compteurs de délai expirés parmi un jeu de threads de travail. Les + threads de travail ne sondent jamais ; ils ne font que traiter les + connexions/requêtes qui leur sont envoyées.

      + +

      Le but est de concevoir un MPM rapide, efficace, autonome et compact qui + fonctionne sur les plateformes Unix modernes en s’appuyant le plus possible + sur APR, tout en prenant en charge la gestion des connexions asynchrones + nécessaire à l’efficacité des connexions persistantes et de HTTP/2.

      + +

      Pour utiliser le MPM motorz, ajoutez + --with-mpm=motorz aux arguments du script + configure lors de la construction de + httpd, ou construisez le en tant que module chargeable + avec --enable-mpms-shared=motorz.

      + +

      Lorsque ce module est construit en tant que module DSO, il peut être + chargé avec la commande :

      + + +LoadModule mpm_motorz_module modules/mod_mpm_motorz.so + + +
      + +Modules multi-processus (MPMs) +Le MPM event +Le MPM worker +Le MPM prefork +Définir les adresses et ports qu’utilise le +serveur HTTP Apache + +
      Comment cela fonctionne-t-il +

      motorz utilise prefork comme cadre pour la gestion des + processus et un cœur à base d’évènements pour la gestion des connexions. Un + seul processus de contrôle (le parent) lance un nombre fixe de processus + enfants, ce nombre étant défini par la directive StartServers. À la différence des MPM + worker et event, le nombre de processus + enfants ne varie pas avec la charge : motorz maintient un + jeu de processus statique en les remplaçant nombre pour nombre lorsqu’ils + quittent. Le parallélisme de traitement au sein d’un hôte est mis en œuvre + en ajoutant des threads de travail (ThreadsPerChild) et, lorsque le cheminement + du processus de sondage/répartition constitue un goulot d’étranglement, des + threads sondeurs (PollersPerChild), au lieu de lancer + davantage de processus.

      + +

      Chaque processus enfant exécute :

      +
        +
      • Un ou plusieurs threads sondeurs. Chaque sondeur + possède ses propres domaine de sondage, sonnerie de chronomètre (avec un + mutex de protection) et liste de recyclage du jeu de transactions non + bloquante, de sorte que les sondeurs n’interfèrent pas les uns avec les + autres. Un thread sondeur sonde, répartit les évènements d’entrée/sortie + prêts et les délais expirés au sein du jeu de threads de travail, et (en + ce qui concerne le thread sondeur qui possède le socket d’écoute) + accepte de nouvelles connexions. Le nombre de threads sondeurs est + contrôlé par la directive PollersPerChild.
      • + +
      • Un jeu de threads de travail partagé (ThreadsPerChild) qui gère la connexion + proprement dite et traite les requêtes qui lui sont envoyées. Les + threads de travail ne sondent jamais.
      • + +
      • Un superviseur (le thread principal de l’enfant) + qui surveille MaxConnectionsPerChild et la + "pipe-of-death / generation", enjoint les threads sondeurs de ralentir + et les rejoint lorsqu’ils quittent.
      • +
      + +

      Une connexion est attribuée à un thread sondeur au moment de + l'acceptation (round-robin) et le reste pendant toute sa durée de vie : elle + réinitialise et fait passer à l’état expiré le domaine de sondage et la + sonnerie du chronomètre de ce thread sondeur. Utiliser plusieurs threads + sondeurs augmente le plafond de débit par rapport à celui d’un sondage par + thread unique ; ainsi l’acceptation, la répartition des évènements et + l’expiration du délai sont réglées par + PollersPerChild au lieu d’être sérialisées sur un + seul thread.

      + +

      Alors que le processus parent est en général démarré en tant que + root sous Unix de façon à se lier au port 80, les processus + enfants et les threads sont lancés par le serveur sous un utilisateur moins + privilégié. Les directives User et + Group permettent de définir les + privilèges des processus enfants du serveur HTTP Apache. Les processus enfants + doivent pouvoir lire tout le contenu destiné à être servi, mais cela mis à + part, doivent posséder le moins de privilèges possible.

      + +

      La directive MaxConnectionsPerChild permet de contrôler + la fréquence à laquelle le serveur recycle les processus en retirant les + anciens et en en lançant de nouveaux.

      +
      + +
      Gestion des connexions asynchrones +

      motorz se définit lui-même comme un MPM asynchrone. + Lorsqu’un thread de travail termine la phase active d’une connexion (par + exemple, une connexion persistante HTTP entre les requêtes ou une connexion + attendant une entrée/sortie), il confie le socket à son thread sondeur au + lieu de maintenir un thread de travail inactif. Le thread sondeur attend le + prochain évènement sur ce socket (dans les limites du délai défini par la + directive Timeout) et n’attribue + la connexion à un thread de travail que s’il y a quelque chose à faire. Cela + libère les threads de travail des connexions persistantes inactives et + permet une gestion efficace de HTTP/2 où la connexion principale est reprise + par le MPM entre les requêtes.

      + +

      La fermeture avec délai (lingering close) n’est, elle non plus, pas + bloquante : plutôt que de bloquer un thread de travail pendant la durée du + délai de fermeture, le socket en cours de vidage est confié à la boucle de + sondage avec un délai d’inaction limité ; ainsi, le thread de travail est + replacé dans le pool immédiatement.

      + +

      Les modules qui acceptent une connexion totalement asynchrone (la + suspendant et la réactivant plus tard) sont pris en charge ; une connexion + suspendue est parquée et réarmée sur son propre thread sondeur lorsqu’elle + est réactivée.

      +
      + +
      Contrôle d’admission +

      Pour qu’un processus enfant reste fiable en cas de surcharge, + motorz applique une pression en retour (backpressure) à + l’écouteur. Lorsque le pool de threads de travail sature, le thread sondeur + qui possède les sockets d’écoute les enlève de son domaine de sondage et + arrête d’accepter ; il les réajoute lorsque la liste de demandes se + vide. Cela a pour effet de limiter la taille de la file d’attente de + travaux et la mémoire consommée par connexion, au lieu de les laisser + grandir sans limite. La décision se base sur le décompte des threads + inactifs, en attente et actifs dans le pool de threads de travail, avec + hystérèse pour éviter un basculement excessif des écouteurs entre « on » et + « off ».

      + + ThreadsPerChild et contrôle d’admission +

      Ètant donné que la marque des « basses eaux » du contrôle d’admission est + une fraction de la valeur de la directive ThreadsPerChild, une très petite valeur pour + cette dernière (en particulier ThreadsPerChild 1) fait que les + écouteurs ne sont réactivés que lorsque la file d’attente de travaux est + totalement vide, ce qui dégrade sévèrement le débit. Une valeur d’au moins 4 + pour ThreadsPerChild est fortement recommandée ; si cette + valeur est inférieure à 4, le serveur émet un avertissement.

      +
      +
      + +
      Liens de parenté avec les autres MPMs +

      motorz utilise prefork pour la gestion des processus et + un pool de threads de travail APR, avec des threads sondeurs qui + répartissent le travail au sein du pool de threads de travail. Cette + approche est différente de la conception écouteur,thread de travail/fdqueue + du MPM event dans laquelle les threads de travail réarment + eux-mêmes un domaine de sondage partagé et sûr en ce qui concerne les + threads.

      + +

      La charge de travail détermine si l’ajout de threads sondeurs peut aider. + Si les threads de travail constituent le goulot d’étranglement du + CPU#8212;c’est en général le cas pour le traitement réel des + requêtes#8212;les threads sondeurs ne sont pas le facteur de limitation et + une valeur de la directive PollersPerChild au delà + de 1 ou 2 sera de peu d’effet. La conception à plusieurs threads sondeurs + supprime le plafond structurel de la conception à thread sondeur + unique, mais le débit par hôte reste tout de même gouverné par le CPU de + travail.

      + + Pas de ServerLimit / modification dynamique du nombre de + processus +

      À la différence des MPMs worker et + event, motorz ne modifie pas le nombre de + processus enfants avec la charge et ne définit pas de plafond séparé avec + ServerLimit. Le nombre de + processus enfants est fixé par la directive StartServers qui agit de ce fait comme une + limite physique du démon, et il n’y a pas de contrôles du style MinSpareThreads, MaxSpareThreads ou MaxRequestWorkers. Il est possible de + définir le parallélisme du traitement avec la directive ThreadsPerChild (et, si le processus de + sondage sature, avec la directive PollersPerChild).

      +
      +
      + +CoreDumpDirectory + +EnableExceptionHook + +Group + +Listen + +ListenBacklog + +MaxConnectionsPerChild + +MaxMemFree + +PidFile + +ScoreBoardFile + +SendBufferSize + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + + +PollersPerChild +Nombre de threads sondeurs par processus enfant +PollersPerChild number +PollersPerChild 0 +server config +motorz + + +

      La directive PollersPerChild permet de définir le + nombre de threads sondeurs pour chaque processus enfant. Chaque thread + sondeur possède ses propres domaine de sondage, sonnerie de chronomètre et + liste de recyclage de connexion, et gère une partie des connexions du + processus enfant. Comme chaque thread sondeur accepte les connexions de + manière indépendante et répartit les évènements d’entrée/sortie et les + expirations de délai au sein du jeu de threads de travail, ajouter des + threads sondeurs augmente la fréquence à laquelle un seul processus enfant + peut gérer ces opérations en parallèle, plutôt que de les sérialiser sur un + seul thread sondeur.

      + +

      Une valeur de 0 (la valeur par défaut) signifie que le + nombre de threads sondeurs est calculé automatiquement : il est + déduit du nombre de CPUs en ligne, plafonné à un maximum codé en dur. Dans + tous les cas, le nombre de threads sondeurs est contraint de façon qu’il ne + dépasse jamais la valeur de la directive ThreadsPerChild et ne soit jamais inférieur + à un.

      + +

      Étant donné que la répartition d’évènements est rarement le goulot + d’étranglement pour le traitement des requêtes réelles—il s’agit en + général du CPU de travail—des valeurs au-delà de un ou deux améliorent + rarement le débit. Augmenter PollersPerChild s’avère + principalement utile pour les charges de travail dominées par une rotation + très importante des connexions ou un grand nombre de connexions à base + d’évènements et inactives, où le processus de sondage/acceptation devient la + limite.

      + + Exemple + +StartServers 2 +ThreadsPerChild 64 +ThreadLimit 64 +PollersPerChild 2 + + +
      +
      + + diff --git a/docs/manual/mod/motorz.xml.meta b/docs/manual/mod/motorz.xml.meta index 0d8012243a8..cd8e40134b6 100644 --- a/docs/manual/mod/motorz.xml.meta +++ b/docs/manual/mod/motorz.xml.meta @@ -8,5 +8,6 @@ en + fr diff --git a/docs/manual/mod/mpm_netware.html.en.utf8 b/docs/manual/mod/mpm_netware.html.en.utf8 index 8fbce7f0de8..0c5c672855c 100644 --- a/docs/manual/mod/mpm_netware.html.en.utf8 +++ b/docs/manual/mod/mpm_netware.html.en.utf8 @@ -65,6 +65,7 @@ ones and launching new ones. On the NetWare OS it is highly recommended that this directive remain set to 0. This allows worker threads to continue servicing requests indefinitely.

      +

      Directives

        @@ -82,6 +83,7 @@

      Bugfix checklist

      See also

      AuthDigestDomainmod_auth_digest
      Les URIs qui se trouvent dans le même espace de protection concernant l'authentification à base de condensés
      AuthDigestNonceFormatmod_auth_digest
      Détermine la manière dont le nombre à valeur unique du -serveur (nonce) est généré
      AuthDigestNcCheckmod_auth_digest
      Active ou désactive la vérification du compteur d'envois du +nombre à valeur unique (nonce) par le client
      AuthDigestNonceLifetimemod_auth_digest
      Durée de validité du nombre à valeur unique du serveur (nonce)
      diff --git a/docs/manual/mod/prefork.xml b/docs/manual/mod/prefork.xml index 715b581a2cc..5ebdb5c776e 100644 --- a/docs/manual/mod/prefork.xml +++ b/docs/manual/mod/prefork.xml @@ -43,7 +43,15 @@ to handle as many simultaneous requests as you expect to receive, but small enough to assure that there is enough physical RAM for all processes.

      + +

      When built as a DSO module, it can be loaded with:

      + + +LoadModule mpm_prefork_module modules/mod_mpm_prefork.so + + +Multi-Processing Modules (MPMs)Setting which addresses and ports Apache HTTP Server uses diff --git a/docs/manual/mod/prefork.xml.de b/docs/manual/mod/prefork.xml.de index 85aa8b5e11f..f0d1b08a64b 100644 --- a/docs/manual/mod/prefork.xml.de +++ b/docs/manual/mod/prefork.xml.de @@ -1,7 +1,7 @@ - + + @@ -49,7 +49,16 @@ processus, sans thread assez grande pour pouvoir traiter autant de requêtes simultanées que vous pensez recevoir, mais assez petite pour conserver suffisamment de mémoire RAM pour tous les processus.

      + +

      Lorsqu’il est construit en tant que module DSO, ce module peut être + chargé avec la commande :

      + + +LoadModule mpm_prefork_module modules/mod_mpm_prefork.so + + +Modules multi-processus(MPMs)Définition des adresses et ports qu'utilise le serveur HTTP Apache diff --git a/docs/manual/mod/prefork.xml.ja b/docs/manual/mod/prefork.xml.ja index ea9c29513eb..bbb0ad94217 100644 --- a/docs/manual/mod/prefork.xml.ja +++ b/docs/manual/mod/prefork.xml.ja @@ -1,7 +1,7 @@ - + + + + @@ -45,7 +45,16 @@ multi-processus multi-thread nombre de threads lancés par chaque processus enfant et MaxRequestWorkers, qui définit le nombre global maximum de threads qui peuvent être lancés.

      + +

      Lorsqu’il est construit en tant que module DSO, ce module peut être + chargé avec la commande :

      + + +LoadModule mpm_worker_module modules/mod_mpm_worker.so + + +Modules multi-processus (MPMs)Définition des adresses et ports qu'utilise le serveur HTTP Apache diff --git a/docs/manual/mod/worker.xml.ja b/docs/manual/mod/worker.xml.ja index 2c438498f1a..f9499e65bd6 100644 --- a/docs/manual/mod/worker.xml.ja +++ b/docs/manual/mod/worker.xml.ja @@ -1,7 +1,7 @@ - + + + - + + + + + +Présentation des nouvelles fonctionnalités de la version 2.6 du serveur +HTTP Apache - Serveur HTTP Apache Version 2.5 + + + + + + + +
      <-
      +

      Présentation des nouvelles fonctionnalités de la version 2.6 du serveur +HTTP Apache

      + +
      +

      Langues Disponibles:  en  | + fr 

      +
      + +

      Ce document décrit quelques changements majeurs entre les version 2.4 et + 2.6 du serveur HTTP Apache. Pour les nouvelles fonctionnalités apparues dans + la version 2.4, voir le document nouvelles + fonctionnalités de la version 2.4.

      +
      + +
      top
      +
      +

      Évolutions du cœur du serveur

      + +
      +
      Directive ContentDigest et en-tête Content-MD5
      +
      La directive ContentDigest et la prise en charge de + l’en-tête Content-MD5 ont été supprimées du serveur, en + accord avec la suppression de cet en-tête de la RFC 7231 (Hypertext Transfer Protocol (HTTP/1.1): + Semantics and Content).
      + +
      Options de la directive Listen
      +
      La directive Listen prend + maintenant en charge un argument facultatif options=..., + permettant de spécifier des options de socket par écouteur, en particulier + multipathtcp pour activer TCP multi-chemin s’il est pris en + charge par la plateforme.
      + +
      Filtrage et complètement de saisie asynchrones
      +
      La nouvelle directive AsyncFilter + permet de déclarer les types de filtre qui prennent en charge la gestion + asynchrone, et la prise en charge du complètement de saisie asynchrone a + été étendue à l'ensemble du noyau. Cela étaie la description de la gestion + asynchrone des serveurs mandataires et des WebSockets ci-après.
      + +
      Contrôles de la stricte conformité à HTTP/1.1
      +
      De nouvelles directives du noyau permettent un contrôle plus fin de la + conformité à HTTP/1.1 : HttpExpectStrict contrôle si un code + 417 est renvoyé lorsqu’un client omet une prévision + 100-Continue, et HttpContentLengthHeadZero contrôle la gestion de + Content-Length pour les requêtes HEAD.
      + +
      Outrepassement du niveau de journalisation en fontion du contexte
      +
      La nouvelle directive LogLevelOverride permet d’outrepasser le niveau + de journalisation pour des adresses IP clientes individuelles, facilitant + ainsi le débogage ciblé sur un serveur en fonctionnement.
      + +
      Activation du socket systemd
      +
      httpd peut maintenant être configuré pour démarrer + via l’l’activation + du socket systemd.
      + + + +
      Nouvelle directive DefaultStateDir
      +
      La nouvelle directive DefaultStateDir permet de spécifier un + répertoire pour stocker les états persistants.
      + +
      Prise en charge de la Zone/portée dans les adresses IPv6
      +
      Si le serveur a été compilé avec APR version 1.7.0 ou supérieure, des + zones (portées) peuvent être spécifiées dans une adresse IPv6 link-local + utilisée avec la directive Listen ou VirtualHost.
      + +
      +
      top
      +
      +

      Nouveaux modules

      + +
      +
      mod_auth_bearer, mod_autht_core, + mod_autht_jwt
      +
      Un nouveau cadriciel de fournisseur de jeton d’authentification + (autht) a été ajouté en plus des piles de fournisseurs + authn/authz existantes. mod_auth_bearer implémente + l’authentification à jeton Bearer de la RFC 6750 en + tant que frontal (semblable à mod_auth_basic), + mod_autht_core héberge l’enregistrement du fournisseur + autht et mod_autht_jwt fournit la signature et la + vérification par jeton Web JSON.
      + +
      mod_crypto
      +
      Ce nouveau module peut chiffrer et déchiffrer des corps de requête et + de réponse à l’aide de filtres en entrée et en sortie en utilisant les + pilotes crypto APR.
      +
      mod_journald, mod_syslog
      +
      Ces nouveaux modules permettent la prise en charge de la + journalisation vers syslog ou journald.
      + +
      mod_log_json
      +
      Ce nouveau module permet une journalisation des accès structurée au + format JSON.
      + +
      mod_proxy_beacon
      +
      Ce nouveau module permet aux serveurs dorsaux des serveurs mandataires + inverses de s’annoncer eux-mêmes à l’aide de datagrammes UDP afin qu’ils + soient automatiquement ajoutés au répartiteur de charge de leur mandataire + frontal.
      + +
      mod_allowhandlers
      +
      Ce nouveau module restreint la liste des gestionnaires qui peuvent + s’exécuter dans un certain contexte, fournissant ainsi une couche + supplémentaire de contrôle d’accès.
      + +
      +
      top
      +
      +

      Évolutions des module

      + +
      +
      mod_ssl
      +
      Les évolutions de mod_ssl suivantes sont incluses : +
        +
      • La directive SSLRandomSeed + est maintenant obsolète et ignorée si le serveur a été compilé avec + OpenSSL version 1.1.1 ou supérieure.
      • +
      • La variable d’environnement SSLKEYLOGFILE peut + maintenant être définie pour enregistrer des informations de clé privée + pour déchiffrer hors-ligne des vidages du protocole SSL/TLS en utilisant + des outils tiers.
      • +
      • La nouvelle directive SSLPolicy permet de définir une fois pour + toutes un ensemble de définitions SSL nommé et de l’appliquer à + plusieurs serveurs virtuels.
      • +
      + +
      mod_proxy, mod_proxy_wstunnel
      +
      Le mandataire peut maintenant s’exécuter de manière asynchrone sous le + MPM event, libérant de ce fait les threads de travail lors de l’attente de + serveurs dorsaux lents. Cela inclut la gestion asynchrone des protocoles + Upgraded et des WebSockets, personnalisés à l’aide des + nouvelles + directives ProxyAsyncDelay, + ProxyAsyncIdleTimeout, + ProxyWebsocketAsyncDelay et + ProxyWebsocketIdleTimeout.
      + +
      mod_http2
      +
      HTTP/2 prend maintenant en charge du « bootstrap » des WebSockets comme + décrit dans la RFC 8441 (activé à l’aide de la nouvelle directive + H2WebSockets), de la nouvelle directive + H2EarlyHint permettant d’ajouter des en-têtes à + une réponse 103 Early Hints et d’un comptage précis des + octets envoyés pour le format de journalisation %O.
      + +
      mod_dav
      +
      WebDAV prend maintenant en charge les quota de répertoire (directive + DAVquota), les extensions du + protocole WebDAV de Microsoft (directive DAVMSext), les directives + DAVHonorMtimeHeader et DAVLockDBType, et une + conformité accrue de l’ETag fort.
      + +
      Autres améliorations de modules
      +
      mod_autoindex ajoute la directive IndexForbiddenReturn404, + mod_mime ajoute MimeOptions et + mod_session_cookie ajoute + SessionCookieMaxAge.
      + +
      mod_cgid
      +
      Si le serveur a été configuré avec + --enable-cgid-fdpassing, le démon CGI configure la gestion de + stderr de la même façon que mod_cgi.
      + + +
      +
      top
      +
      +

      Évolutions des programmes

      + +
      +
      htpasswd
      +
      L’utilitaire htpasswd peut maintenant générer des + hachages crypt() SHA-256 ou SHA-512 s’ils sont pris en + charge par la bibliothèque C.
      +
      +
      top
      +
      +

      Modifications pour le développeur de modules

      + +
      +
      Séparation entre le noyau et le module http
      + +
      Une grande quantité de code a été déplacée du module http + vers le noyau du serveur — en particulier le gestionnaire par + défaut, les filtres en entrée et en sortie par défaut et les directives de + configuration du noyau — de façon que le serveur puisse fonctionner + que le module http soit chargé ou non. Le déplacement de + ap_set_etag() depuis le module http vers le + noyau était une partie de ce travail.
      + +
      Nouveaux types de bloc de métadonnées et division du filtre HTTP
      + +
      Les nouveaux types de bloc de métadonnées REQUEST, + RESPONSE et HEADERS ont été ajoutés à l’API, + ainsi qu’une nouvelle méthode pour définir les en-têtes de réponse + standards Date et Server et des aides au + formatage de parties de HTTP/1.x (en-têtes, segments de fin) à réutiliser + en dehors du noyau, par exemple dans mod_proxy. Le filtre + HTTP_IN a été divisé en un filtre HTTP générique et un filtre + spécifique à HTTP/1.x HTTP1_BODY_IN, et un nouveau drapeau + body_indeterminate sur request_rec indique qu’un + corps de requête peut être présent et doit être lu ou supprimé.
      + +
      Prise en charge d’un ETag fort et notes binaires de requête
      + +
      Un concept de « notes binaires » (binary notes) a été ajouté à + request_rec, permettant la définition des indicateurs de bits + compactés sur une requête. La première de ces notes, + AP_REQUEST_STRONG_ETAG, fait que les modules forcent la + compatibilité d’un ETag fort avec les exigences des RFC telles que celles + mandatées par diverses extensions de WebDav. Les nouvelles fonctions + ap_make_etag_ex() et ap_set_etag_fd() permettent + un contrôle total de la génération des ETag.
      + +
      Nouveau type ap_method_mask_t
      + +
      Le type ap_method_mask_t a été ajouté et est maintenant + utilisé pour le champ method_mask dans ap_method_list_t, AP_METHOD_BIT, le + champ allowed de request_rec, le champ limited de cmd_parms.
      + +
      Modification du fichier mod_ssl.h de l’API de mod_ssl
      + +
      L’API de la fonction optionnelle ssl_var_lookup prend + maintenant un argument const char *name et renvoie + une chaîne const char *. L’argument pool doit maintenant être + non NULL.
      + +
      APIs supprimées
      + +
      Suite à la suppression de l’en-tête Content-MD5, les + fonctions ap_md5digest() et ap_md5contextTo64() + ont été supprimées.
      + +
      +

      La documentation du développeur contient une liste détaillée des changements de l’API. +

      +
      +
      +

      Langues Disponibles:  en  | + fr 

      +
      + \ No newline at end of file diff --git a/docs/manual/new_features_2_6.xml.fr b/docs/manual/new_features_2_6.xml.fr index d4c1dccf97c..9a6d4e6295b 100644 --- a/docs/manual/new_features_2_6.xml.fr +++ b/docs/manual/new_features_2_6.xml.fr @@ -1,7 +1,7 @@ - + +
      mod_auth_bearer, mod_autht_core, + mod_autht_jwt
      +
      Un nouveau cadriciel de fournisseur de jeton d’authentification + (autht) a été ajouté en plus des piles de fournisseurs + authn/authz existantes. mod_auth_bearer implémente + l’authentification à jeton Bearer de la 6750 en + tant que frontal (semblable à mod_auth_basic), + mod_autht_core héberge l’enregistrement du fournisseur + autht et mod_autht_jwt fournit la signature et la + vérification par jeton Web JSON.
      +
      mod_crypto
      +
      Ce nouveau module peut chiffrer et déchiffrer des corps de requête et + de réponse à l’aide de filtres en entrée et en sortie en utilisant les + pilotes crypto APR.
      mod_journald, mod_syslog
      Ces nouveaux modules permettent la prise en charge de la journalisation vers syslog ou journald.
      +
      mod_log_json
      +
      Ce nouveau module permet une journalisation des accès structurée au + format JSON.
      + +
      mod_proxy_beacon
      +
      Ce nouveau module permet aux serveurs dorsaux des serveurs mandataires + inverses de s’annoncer eux-mêmes à l’aide de datagrammes UDP afin qu’ils + soient automatiquement ajoutés au répartiteur de charge de leur mandataire + frontal.
      + +
      mod_allowhandlers
      +
      Ce nouveau module restreint la liste des gestionnaires qui peuvent + s’exécuter dans un certain contexte, fournissant ainsi une couche + supplémentaire de contrôle d’accès.
      + @@ -98,8 +149,46 @@ HTTP Apache maintenant être définie pour enregistrer des informations de clé privée pour déchiffrer hors-ligne des vidages du protocole SSL/TLS en utilisant des outils tiers. +
    • La nouvelle directive SSLPolicy permet de définir une fois pour + toutes un ensemble de définitions SSL nommé et de l’appliquer à + plusieurs serveurs virtuels.
    • +
      mod_proxy, mod_proxy_wstunnel
      +
      Le mandataire peut maintenant s’exécuter de manière asynchrone sous le + MPM event, libérant de ce fait les threads de travail lors de l’attente de + serveurs dorsaux lents. Cela inclut la gestion asynchrone des protocoles + Upgraded et des WebSockets, personnalisés à l’aide des + nouvelles + directives ProxyAsyncDelay, + ProxyAsyncIdleTimeout, + ProxyWebsocketAsyncDelay et + ProxyWebsocketIdleTimeout.
      + +
      mod_http2
      +
      HTTP/2 prend maintenant en charge du « bootstrap » des WebSockets comme + décrit dans la 8441 (activé à l’aide de la nouvelle directive + H2WebSockets), de la nouvelle directive + H2EarlyHint permettant d’ajouter des en-têtes à + une réponse 103 Early Hints et d’un comptage précis des + octets envoyés pour le format de journalisation %O.
      + +
      mod_dav
      +
      WebDAV prend maintenant en charge les quota de répertoire (directive + DAVquota), les extensions du + protocole WebDAV de Microsoft (directive DAVMSext), les directives + DAVHonorMtimeHeader et DAVLockDBType, et une + conformité accrue de l’ETag fort.
      + +
      Autres améliorations de modules
      +
      mod_autoindex ajoute la directive IndexForbiddenReturn404, + mod_mime ajoute MimeOptions et + mod_session_cookie ajoute + SessionCookieMaxAge.
      +
      mod_cgid
      Si le serveur a été configuré avec --enable-cgid-fdpassing, le démon CGI configure la gestion de @@ -119,18 +208,43 @@ HTTP Apache -
      - Documentation -
      -
      Complétez moi
      -
      La documentation de mod_example "Complétez moi".
      - -
      -
      -
      Modifications pour le développeur de modules
      +
      Séparation entre le noyau et le module http
      + +
      Une grande quantité de code a été déplacée du module http + vers le noyau du serveur — en particulier le gestionnaire par + défaut, les filtres en entrée et en sortie par défaut et les directives de + configuration du noyau — de façon que le serveur puisse fonctionner + que le module http soit chargé ou non. Le déplacement de + ap_set_etag() depuis le module http vers le + noyau était une partie de ce travail.
      + +
      Nouveaux types de bloc de métadonnées et division du filtre HTTP
      + +
      Les nouveaux types de bloc de métadonnées REQUEST, + RESPONSE et HEADERS ont été ajoutés à l’API, + ainsi qu’une nouvelle méthode pour définir les en-têtes de réponse + standards Date et Server et des aides au + formatage de parties de HTTP/1.x (en-têtes, segments de fin) à réutiliser + en dehors du noyau, par exemple dans mod_proxy. Le filtre + HTTP_IN a été divisé en un filtre HTTP générique et un filtre + spécifique à HTTP/1.x HTTP1_BODY_IN, et un nouveau drapeau + body_indeterminate sur request_rec indique qu’un + corps de requête peut être présent et doit être lu ou supprimé.
      + +
      Prise en charge d’un ETag fort et notes binaires de requête
      + +
      Un concept de « notes binaires » (binary notes) a été ajouté à + request_rec, permettant la définition des indicateurs de bits + compactés sur une requête. La première de ces notes, + AP_REQUEST_STRONG_ETAG, fait que les modules forcent la + compatibilité d’un ETag fort avec les exigences des RFC telles que celles + mandatées par diverses extensions de WebDav. Les nouvelles fonctions + ap_make_etag_ex() et ap_set_etag_fd() permettent + un contrôle total de la génération des ETag.
      +
      Nouveau type ap_method_mask_t
      Le type ap_method_mask_t a été ajouté et est maintenant @@ -144,6 +258,12 @@ HTTP Apache une chaîne const char *. L’argument pool doit maintenant être non NULL.
      +
      APIs supprimées
      + +
      Suite à la suppression de l’en-tête Content-MD5, les + fonctions ap_md5digest() et ap_md5contextTo64() + ont été supprimées.
      +

      La documentation du développeur contient une liste détaillée des changements de l’API. diff --git a/docs/manual/platform/netware.html.fr.utf8 b/docs/manual/platform/netware.html.fr.utf8 index 32e69e4efa8..2eff5b943cc 100644 --- a/docs/manual/platform/netware.html.fr.utf8 +++ b/docs/manual/platform/netware.html.fr.utf8 @@ -27,8 +27,6 @@  fr  |  ko 

      -
      Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.

      Ce document explique l'installation, la configuration et le @@ -201,9 +199,10 @@ "install" à la ligne de commande du makefile va provoquer la construction d'une distribution complète sous forme d'un paquetage dans le sous-répertoire DIST. Vous pouvez simplement - installer Apache en copiant la distribution créée précédemment à la + installer Apache en copiant la distribution créée précédemment par les + makefiles à la racine d'un volume Netware (voir Compilation - d'Apache pour NetWare ci-dessous).

      + d'Apache httpd pour NetWare ci-dessous).

      top
      diff --git a/docs/manual/platform/netware.xml.fr b/docs/manual/platform/netware.xml.fr index c67f028167d..4caea9b39e5 100644 --- a/docs/manual/platform/netware.xml.fr +++ b/docs/manual/platform/netware.xml.fr @@ -1,7 +1,7 @@ - + @@ -198,9 +198,10 @@ "install" à la ligne de commande du makefile va provoquer la construction d'une distribution complète sous forme d'un paquetage dans le sous-répertoire DIST. Vous pouvez simplement - installer Apache en copiant la distribution créée précédemment à la + installer Apache en copiant la distribution créée précédemment par les + makefiles à la racine d'un volume Netware (voir Compilation - d'Apache pour NetWare ci-dessous).

      + d'Apache httpd pour NetWare ci-dessous).

      diff --git a/docs/manual/platform/netware.xml.meta b/docs/manual/platform/netware.xml.meta index 575ac8c5bde..3db34498aa0 100644 --- a/docs/manual/platform/netware.xml.meta +++ b/docs/manual/platform/netware.xml.meta @@ -8,7 +8,7 @@ en - fr + fr ko diff --git a/docs/manual/platform/win_compiling.html.en.utf8 b/docs/manual/platform/win_compiling.html.en.utf8 index dbc5d4ab764..0ceb8bedf6c 100644 --- a/docs/manual/platform/win_compiling.html.en.utf8 +++ b/docs/manual/platform/win_compiling.html.en.utf8 @@ -6,7 +6,7 @@ This file is generated from xml source: DO NOT EDIT XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --> -Compiling Apache for Microsoft Windows - Apache HTTP Server Version 2.5 +Compiling Apache httpd for Microsoft Windows - Apache HTTP Server Version 2.5 @@ -20,7 +20,7 @@
      <-

      Compiling Apache for Microsoft Windows

      +Apache > HTTP Server > Documentation > Version 2.5 > Platform Specific Notes

      Compiling Apache httpd for Microsoft Windows

      Available Languages:  en  | diff --git a/docs/manual/platform/win_compiling.html.fr.utf8 b/docs/manual/platform/win_compiling.html.fr.utf8 index 0bb4ab66402..ab9e53e0573 100644 --- a/docs/manual/platform/win_compiling.html.fr.utf8 +++ b/docs/manual/platform/win_compiling.html.fr.utf8 @@ -6,7 +6,7 @@ This file is generated from xml source: DO NOT EDIT XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --> -Compiler Apache pour Microsoft Windows - Serveur HTTP Apache Version 2.5 +Compiler Apache httpd pour Microsoft Windows - Serveur HTTP Apache Version 2.5 @@ -21,7 +21,7 @@

      <-

      Compiler Apache pour Microsoft Windows

      + plates-formes

      Compiler Apache httpd pour Microsoft Windows

      Langues Disponibles:  en  | diff --git a/docs/manual/platform/win_compiling.xml b/docs/manual/platform/win_compiling.xml index 2b554f2ead6..74fb132a601 100644 --- a/docs/manual/platform/win_compiling.xml +++ b/docs/manual/platform/win_compiling.xml @@ -23,7 +23,7 @@ Platform Specific Notes - Compiling Apache for Microsoft Windows + Compiling Apache httpd for Microsoft Windows

      diff --git a/docs/manual/platform/win_compiling.xml.fr b/docs/manual/platform/win_compiling.xml.fr index aad005880f9..7bb3afa2ab0 100644 --- a/docs/manual/platform/win_compiling.xml.fr +++ b/docs/manual/platform/win_compiling.xml.fr @@ -1,7 +1,7 @@ - + @@ -26,7 +26,7 @@ Notes spécifiques à certaines plates-formes - Compiler Apache pour Microsoft Windows + Compiler Apache httpd pour Microsoft Windows diff --git a/docs/manual/platform/win_compiling.xml.ko b/docs/manual/platform/win_compiling.xml.ko index ba61ad39f5d..c21b2a55910 100644 --- a/docs/manual/platform/win_compiling.xml.ko +++ b/docs/manual/platform/win_compiling.xml.ko @@ -1,7 +1,7 @@ - + + @@ -60,12 +60,11 @@ vous tourner vers mod_rewrite.

      Introduction à mod_rewrite Redirection et remise en correspondance -Contrôle d'accès +Réécritures par répertoire +Drapeaux de RewriteRule Serveurs virtuels -Serveurs mandataires Utilisation de RewriteMap -Techniques avancées - +Détails techniques
      Redirection simple @@ -107,45 +106,36 @@ Redirect "/one/" "http://one.example.com/" example.com vers www.example.com, voir la méthode Noms d'hôtes canoniques.

      -

      Pour rediriger les URLs http vers https, -utilisez cette définition :

      - - -<VirtualHost *:80> - ServerName www.example.com - Redirect "/" "https://www.example.com/" -</VirtualHost> - -<VirtualHost *:443> - ServerName www.example.com - # ... insérer ici la configuration SSL -</VirtualHost> - - -

      L'utilisation de la directive RewriteRule pour accomplir -cette tâche peut se justifier s'il existe d'autres directives -RewriteRule dans la même portée. En effet, lorsque des -directives Redirect et RewriteRule se trouvent -dans la même portée, les directives RewriteRule sont -exécutées en premier, sans tenir compte de leur ordre d'apparition dans -le fichier de configuration.

      - -

      Dans le cas de la redirection http-vers-https, l'utilisation -de règles RewriteRule se justifie si vous n'avez pas accès -au fichier de configuration principal, et devez donc accomplir cette -tâche au sein d'un fichier .htaccess.

      +

      Pour rediriger les URLs http vers https, une +directive Redirect dans un serveur +virtuel HTTP dédié est l’approche la plus propre. Voir la recette Forcer HTTPS pour la configuration +recommandée et l’alternative de mod_rewrite pour l’utilisation +des fichiers .htaccess.

      + + Ordre de traitement +

      Si vous mélangez des directives Redirect et RewriteRule dans le même contexte, sachez + que leur ordre d’exécution dépend de l’emplacement où elles apparaissent. + Dans un contexte de serveur virtuel ou global, c’est + mod_rewrite qui agit en premier, alors que dans un contexte + de répertoire (fichiers .htaccess), c’est + mod_alias. Voir Ordre de + traitement des modules pour les détails.

      +
      Alias d'URL -

      La directive Alias permet -de mettre en correspondance un URI avec un répertoire, ce dernier étant -en général situé en dehors de l'arborescence définie par la directive -DocumentRoot. Bien qu'il soit -possible d'effectuer cette mise en correspondance avec -mod_rewrite, il est préférable d'utiliser la directive -Alias pour des raisons de simplicité -et de performances.

      +

      La directive Alias permet de mettre +en correspondance un chemin d’URL avec un répertoire, ce dernier étant en +général situé en dehors de l'arborescence définie par la directive DocumentRoot. Bien qu'il soit possible d'effectuer +cette mise en correspondance avec mod_rewrite, il est +préférable d'utiliser la directive Alias pour des raisons de simplicité et de +performances.

      Utilisation de la directive Alias @@ -166,31 +156,6 @@ symboliques, pourvu que Options FollowSymLinks soit activé sur votre serveur.

      -
      Hébergement virtuel -

      Bien qu'il soit possible de gérer les serveurs -virtuels avec mod_rewrite, il s'agit rarement de la bonne méthode. -Il est pratiquement toujours préférable de créer des blocs -VirtualHost individuels. -Dans l'éventualité où vous devez gérer -un grand nombre de serveurs virtuels, vous devez vous tourner vers -mod_vhost_alias pour créer ces serveurs -automatiquement.

      - -

      Il est aussi possible d'utiliser des modules comme mod_macro pour -créer un grand nombre de serveurs virtuels dynamiquement.

      - -

      L'utilisation de mod_rewrite pour la création de -serveurs virtuels peut se révéler appropriée si votre service -d'hébergement ne vous permet pas d'accéder aux fichiers de configuration -du serveur, et que vous soyez par conséquent obligé de passer par les -fichiers .htaccess.

      - -

      Voir le document création de serveurs virtuels -avec mod_rewrite pour plus de détails sur la manière d'y parvenir si -cela semble être tout de même la meilleure approche.

      - -
      -
      Mandat simple

      La directive RewriteRule fournit @@ -228,6 +193,25 @@ lorsque d'autres RewriteRules se trouvent dans la même portée, car elles agissent en général avant les directives ProxyPass, et peuvent ainsi les court-circuiter.

      +

      RewriteRule s’avère vraiment +utile pour ne mandater les requêtes que si le contenu n’existe pas localement +— par exemple, lors de la migration d’un serveur vers un autre :

      + + +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "^/(.*)" "http://old.example.com/$1" [P] +ProxyPassReverse "/" "http://old.example.com/" + + +

      Dans cet exemple, les requêtes pour des ressources qui n’ont pas encore été +migrées sont mandatées silencieusement vers l’ancien serveur. Lors de la +migration du contenu, les fichiers locaux ont la priorité. N’oubliez pas de +toujours inclure une directive ProxyPassReverse pour être sûr que toute +redirection effectuée par le serveur dorsal est correctement transmise au +client.

      +
      Test de variables d'environnement @@ -264,4 +248,343 @@ ainsi que dans certaines directives.

      +
      Contrôleur frontal / Routage des +ressources + +

      Une utilisation très courante de mod_rewrite consiste à +router toutes les requêtes pour des ressources non existantes vers un seul +script de contrôle frontal (par exemple index.php). Il s’agit de la +base du routage dans le cadre de la plus grande partie du web moderne.

      + +

      L’approche typique avec mod_rewrite est :

      + + +RewriteEngine On +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "^(.*)$" "/index.php" [L] + + +

      Cette opération peut être effectuée beaucoup plus simplement avec la +directive FallbackResource :

      + + +FallbackResource /index.php + + +

      La directive FallbackResource fait la +même chose — les requêtes pour des fichiers et répertoires existants sont +traitées normalement, toutes les autres étant routées vers la ressource +spécifiée — mais sans la surcharge de travail et la complexité du moteur de +réécriture. Elle fonctionne dans les deux contextes de configuration globale du +serveur et des fichiers .htaccess.

      + +

      Pour désactiver une FallbackResource définie dans un répertoire +parent :

      + + +FallbackResource disabled + + +
      + +
      Configuration conditionnelle avec des +expressions rationnelles + +

      Dans de nombreux cas, l’utilisation de RewriteCond peut être remplacée par la +directive If qui prend en +charge une syntaxe des expressions riche et s’intègre +parfaitement avec les autres directives de httpd.

      + +

      Redirection basée sur un élément de la chaîne de paramètres :

      + + +<If "%{QUERY_STRING} =~ /lang=fr/"> + Redirect "/welcome" "/bienvenue" +</If> + + +

      Restriction d’accès en fonction de la méthode de la requête :

      + + +<If "%{REQUEST_METHOD} IN {'DELETE', 'PUT', 'PATCH'}"> + Require ip 10.0.0.0/8 +</If> + + +

      Blocage des requêtes qui ne comportent pas d’en-tête Host (clients +HTTP/1.0) :

      + + +<If "-z req('Host')"> + Require all denied +</If> + + +

      Voir la documentation sur l’évaluation des +expressions pour une description complète de la syntaxe disponible dans les +blocs If.

      + +
      + +
      + + Blocage du référencement à chaud (Hotlinking) d'images + +
      +
      Description :
      + +
      +

      Le référencement à chaud consiste pour les autres sites à inclure + directement vos images dans leurs pages en utilisant votre bande + passante pour servir des contenus pour le site de quelqu'un d'autre. + Vous pouvez empêcher cela sans utiliser + mod_rewrite.

      +
      + +
      Solution :
      + +
      +

      Utilisez la directive SetEnvIf avec la directive Require :

      + + +SetEnvIf Referer example\.com localreferer +<FilesMatch "\.(jpg|png|gif)$"> + Require env localreferer +</FilesMatch> + +
      + +
      Discussion :
      + +
      +

      Si vous avez besoin d’une logique plus complexe — comme servir une + autre image aux référenceurs à chaud au lieu de rejeter la requête — vous + aurez peut-être besoin de mod_rewrite. Les exemples + suivants s’appuient sur l’en-tête HTTP_REFERER qui est + facultatif et peut être usurpé. La condition !^$ autorise les + requêtes qui ne comportent aucun en-tête Referer, de sorte que les + utilisateurs qui saisissent l’URL directement, ou dont les navigateurs + suppriment cet en-tête ne soient pas bloqués.

      + +

      Rejeter purement et simplement la requête :

      + + +RewriteCond "%{HTTP_REFERER}" "!^$" +RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC] +RewriteRule "\.(gif|jpg|png)$" "-" [F,NC] + + +

      Servir une image alternative :

      + + +RewriteCond "%{HTTP_REFERER}" "!^$" +RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC] +RewriteRule "\.(gif|jpg|png)$" "/images/go-away.png" [R,NC] + + +
      +
      + +
      + +
      + + Blocage des robots + +
      +
      Description :
      + +
      +

      Vous voulez bloquer les requêtes persistantes d’un robot particulier ou + d’un agent utilisateur qui ignore votre /robots.txt.

      +
      + +
      Solution :
      + +
      +

      Utilisez la directive SetEnvIfNoCase avec la directive + Require :

      + + +SetEnvIfNoCase User-Agent ^NameOfBadRobot goaway +<Location "/secret/files"> + <RequireAll> + Require all granted + Require not env goaway + </RequireAll> +</Location> + +
      + +
      Discussion :
      + +
      +

      Toute technique qui s’appuie sur la chaîne USER_AGENT peut + être facilement contournée, car cette chaîne peut être modifiée par le + client. Si vous subissez une attaque soutenue, vous devez la traiter à un + niveau supérieur, par exemple au niveau de votre pare-feu.

      + +

      Si vous devez combiner la recherche de correspondance par agent + utilisateur et par adresse IP, mod_rewrite peut être + utilisé en remplacement :

      + + +RewriteCond "%{HTTP_USER_AGENT}" "^NameOfBadRobot" +RewriteCond "%{REMOTE_ADDR}" "=123\.45\.67\.[8-9]" +RewriteRule "^/secret/files/" "-" [F] + + +
      +
      + +
      + +
      + + Interdire des hôtes dans une liste de rejets + +
      +
      Description :
      + +
      +

      Nous souhaitons établir une liste des hôtes auxquels nous voulons + interdire l’accès à notre serveur.

      +
      + +
      Solution :
      + +
      +

      Pour un simple blocage basé sur l’adresse IP, utilisez la directive + Require directement :

      + + +<Location "/"> + Require all granted + Require not ip 193.102.180.41 + Require not ip 192.76.162.40 +</Location> + +
      + +
      Discussion :
      + +
      +

      Si vous avez besoin d’une liste d’interdiction dynamique basée sur un + fichier (plutôt que d’énumérer des adresses IP dans la configuration), + vous pouvez utiliser mod_rewrite et sa directive + RewriteMap :

      + + +RewriteEngine on +RewriteMap hosts-deny "txt:/path/to/hosts.deny" +RewriteCond "${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}" "!=NOT-FOUND" [OR] +RewriteCond "${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}" "!=NOT-FOUND" +RewriteRule "^" "-" [F] + + +

      Le fichier de mappage contient une entrée par ligne, avec une adresse + IP ou un nom d’hôte comme clé et une valeur factice (parce que la + directive RewriteMap requiert + des paires clé/valeur) :

      + + +## hosts.deny
      +193.102.180.41 -
      +192.76.162.40 -
      +
      + +

      La seconde directive RewriteCond présuppose que + HostnameLookups est activé. Dans le cas contraire, + supprimer-la, ainsi que le drapeau [OR] de la première + condition.

      +
      +
      + +
      + +
      Serveurs virtuels +

      Bien qu’il soit possible de gérer les serveurs virtuels +avec mod_rewrite, il s’agit rarement de la bonne méthode. Le bon choix +consiste pratiquement toujours à créer des blocs VirtualHost individuels. Si vous devez gérer un très +grand nombre de serveurs virtuels, choisissez plutôt d’utiliser +mod_vhost_alias pour créer ces hôtes automatiquement.

      + +

      Des modules tels que mod_macro permettent aussi de créer un +grand nombre de serveurs virtuels dynamiquement.

      + +

      Utiliser mod_rewrite pour la création de serveurs virtuels +peut convenir si vous utilisez un service d’hébergement qui ne vous permet pas +d’accéder aux fichiers de configuration du serveur, et que vous soyez par +conséquent contraint d’utiliser des fichiers .htaccess.

      + +

      Voir le document les serveurs virtuels avec +mod_rewrite pour plus de détails sur la manière de procéder si cette +approche vous semble encore être la bonne.

      + +
      + +
      + + Répartition de charge + +
      +
      Description :
      + +
      +

      Nous souhaitons répartir la charge entre plusieurs serveurs dorsaux.

      +
      + +
      Solution :
      + +
      +

      Utilisez le module mod_proxy_balancer qui fournit une + solution de répartition de charge flexible et totalement fonctionnelle. Il + prend en charge plusieurs algorithmes de répartition, la persistance de + session, les contrôles de bon fonctionnement et une configuration + dynamique avec le gestionnaire de répartition de charge (Balancer Manager) + — toutes choses impossibles avec l’approche de + mod_rewrite.

      + + +<Proxy "balancer://mycluster"> + BalancerMember "http://one.example.com" + BalancerMember "http://two.example.com" + BalancerMember "http://three.example.com" +</Proxy> +ProxyPass "/" "balancer://mycluster/" +ProxyPassReverse "/" "balancer://mycluster/" + + +
      + +
      Discussion :
      +
      + +

      Il est possible de mettre en œuvre une répartition de charge aléatoire +rudimentaire en utilisant mod_rewrite et une directive +RewriteMap de type +rnd :

      + + +RewriteEngine on +RewriteMap lb "rnd:/path/to/serverlist.txt" +RewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L] + + +

      mod_proxy_balancer est cependant beaucoup plus flexible et +fonctionnel que tout ce que vous pourrez « bricoler » en utilisant +mod_rewrite, et correspond à l’approche recommandée.

      + +
      +
      + +
      + diff --git a/docs/manual/rewrite/avoid.xml.meta b/docs/manual/rewrite/avoid.xml.meta index 2199f87ca2b..a496ea22d0d 100644 --- a/docs/manual/rewrite/avoid.xml.meta +++ b/docs/manual/rewrite/avoid.xml.meta @@ -10,7 +10,7 @@ de en es - fr + fr ja ko tr diff --git a/docs/manual/rewrite/flags.html.fr.utf8 b/docs/manual/rewrite/flags.html.fr.utf8 index 0400b8d9380..88fd09d4fe9 100644 --- a/docs/manual/rewrite/flags.html.fr.utf8 +++ b/docs/manual/rewrite/flags.html.fr.utf8 @@ -32,14 +32,13 @@  tr  |  zh-cn 

      -
      Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.

      Ce document décrit les drapeaux disponibles dans la directive RewriteRule, en fournissant des explications détaillées et des exemples.

      +correspondance
    • Réécritures par répertoire
    • Serveurs virtuels
    • Utilisation de RewriteMap
    • Quand ne pas utiliser mod_rewrite
    • Détails techniques
    • top

      Introduction

      @@ -89,14 +88,146 @@ bien mémoriser ce que chaque drapeau est supposé faire. Certains drapeaux acceptent un ou plusieurs arguments. Les drapeaux ne sont pas sensibles à la casse.

      -

      Les drapeaux qui modifient les métadonnées associées à la requête -(T=, H=, E=) n'ont aucun effet dans un contexte de répertoire ou de -fichier htaccess, lorsqu'une substitution (autre que '-') est effectuée -au cours de la même passe du processus de réécriture. -

      +

      Les drapeaux qui modifient les métadonnées associées à la requête (T=, H=, +E=) n'ont aucun effet dans un contexte de +répertoire ou de fichier htaccess, lorsqu'une substitution (autre que +'-') est effectuée au cours de la même passe du processus de réécriture.

      Chaque drapeau disponible est présenté ici, avec un exemple d'utilisation.

      +
      top
      +
      +

      Référence rapide des drapeaux

      + +

      Les drapeaux peuvent être combinés : [R=301,L], [P,QSA], +[E=VAR:val,L]. Cette table les groupe par fonction et les trie +selon la fréquence de leur utilisation.

      + +
      Açıklama:Evresiz ön çatallamalı HTTP sunucusu oluşturur
      Durum:MPM
      Modül Betimleyici:mpm_prefork_module
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      DrapeauFonctionEffetCombinaisons courantes
      Contrôle de flux
      [L]Dernière règleArrête le traitement des règles (pour cette passe)[R=301,L] [F] [G]
      [END]Arrêt completArrête tout le processus de réécriture (pas de réentrance dans .htaccess)[R=301,END]
      [S=N]SautSauter les N prochaines règles (logique if/else)
      [N]Instance suivante de la boucleRedémarrer le traitement du jeu de règles à partir de la première + (attention : risque de boucle infinie)
      [C]ChaînageChaîner la règle actuelle à la prochaine ; si la règle actuelle échoue, + sauter les règles chaînées
      Redirection et mandatement
      [R=code]RedirectionRedirection externe (par défaut 302). Utilisez Redirect/RedirectMatch pour + les cas simple[R=301,L] [R=302,L]
      [P]MandatementMandatement inverse vers une cible (nécessite mod_proxy)[P,QSA]
      Contrôle d’accès
      [F]InterdictionRenvoie 403 (implique [L])
      [G]PartiRenvoie 410 (implique [L])
      URL / chaîne de paramètres
      [QSA]Ajout de la chaîne de paramètresAjout de la chaîne de paramètres originelle à la substitution[QSA,L] [P,QSA]
      [QSD]Suppression de la chaîne de paramètresSupprime entièrement la chaîne de paramètres[R=301,QSD,L]
      [B]Échappement des références arrièresRéencode les caractères spéciaux dans les références arrières[B,PT]
      [NE]Pas d’échappementPas d’échappement des caractères spéciaux dans la sortie (pass #, ? through)[R=301,NE,L]
      Metadonnées et gestionnaires
      [E]Définition d’une variable d’environnementDéfinit une variable d’environnement[E=VAR:val,L]
      [T]Type MIMEForçage du type de contenu
      [H]GestionnaireForçage d’un gestionnaire de contenu
      [PT]Transmission résultatTransmission du résultat au gestionnaire suivant (requis pour Alias/ScriptAlias)[PT,L]
      Cookie
      [CO]Définir un cookieDéfinir un cookie HTTP pour la réponse[CO=name:val:.domain,R=302,L]
      +
      top

      B (échappement dans les références arrières)

      @@ -164,6 +295,10 @@ RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"

      Pour définir la liste des caractères à échapper de cette manière, voir #flag_bne et #flag_bctls

      +

      Voir Encodage et décodage des URLs pour une +explication détaillée de la manière dont httpd décode les URIs avant la mise en +correspondance des motifs.

      +
      top

      BNP|backrefnoplus (ne pas échapper @@ -181,6 +316,10 @@ RewriteRule "^search/(.*)$" "/search.php/$1" "[B,BNP]"

      Ce drapeau est disponible à partir de la version 2.4.26 du serveur HTTP Apache.

      +

      Voir Encodage et décodage des URLs pour +découvrir la manière dont l’encodage est géré dans le tube (pipeline) de +réécriture.

      +

      top

      BCTLS

      @@ -193,7 +332,7 @@ rejetés lorsqu'ils sont copiés dans la chaîne de param&egrav RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]" -

      Ce drapeau est disponible à partir de la version 2.5.1 du serveur HTTP +

      Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP Apache.

      top
      @@ -207,7 +346,7 @@ correspondant aux drapeaux [B] ou [BCTLS]. Ils ne seront donc pas échapp& RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]" -

      Ce drapeau est disponible à partir de la version 2.5.1 du serveur HTTP +

      Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP Apache.

      top
      @@ -219,6 +358,18 @@ normalement et passe le contrôle à la règle suivante. Par co elle ne s'applique pas, la règle suivante, ainsi que toutes les règles chaînées qui suivent, seront sautées.

      +
      # Réécrire les URLs des anciens produits vers la nouvelle application du
      +# catalogue, et ajouter un paramètre de traçage — mais seulement pour ceux qui
      +# sont réécrits.
      +RewriteRule "^/products/([0-9]+)$" "/catalog/item/$1" [C]
      +RewriteRule "^/catalog/(.*)$" "/catalog/$1?via=legacy" [QSA]
      + + +

      Sans le drapeau [C], la seconde règle s’appliquerait aux requêtes qui +arrivent directement à /catalog/. Le chaînage des deux règles +permet de s’assurer que la seconde règle ne s’appliquera que si la première +s’applique.

      +
      top

      CO|cookie

      @@ -262,7 +413,7 @@ ce style de cookie est interdit par le modèle de sécurité d
      Lifetime
      La durée de vie du cookie, en minutes.
      -
      Une valeur de 0 indique une durée de vie correspondant à la session +
      Une valeur de 0 indique une durée de vie correspondant à lasession courante du navigateur. Il s'agit de la valeur par défaut.
      Une valeur négative indique que la définition du cookie doit être annulée dans le navigateur.
      @@ -311,24 +462,26 @@ pour tous les URIs.

      top

      DPI|discardpath

      -

      Avec le drapeau DPI, la partie PATH_INFO de l'URI -réécrit est supprimée.

      -

      Ce drapeau est disponible dans les versions 2.2.12 et supérieures.

      -

      Dans un contexte de répertoire, l'URI mis en comparaison par chaque -règle RewriteRule est la concaténation des -valeurs courantes de l'URI et de PATH_INFO.

      - -

      L'URI courant peut être l'URI initial tel qu'il a été fourni par le +

      Avec le drapeau DPI, la partie PATH_INFO +qui a été ajoutée au chemin d’URL réécrit est +supprimée.

      + +

      Dans un contexte de répertoire, le +chemin d’URL que compare chaque +RewriteRule est la concaténation des valeurs courantes du +chemin d’URL et de PATH_INFO.

      + +

      Le chemin d’URL actuel peut être le chemin initial tel qu'il a été fourni par le client, le résultat d'une passe précédente du processus de réécriture, -ou le résultat de la règle précédente dans le processus courant de +ou le résultat de la règle précédente de la passe actuelle du processus de réécriture.

      -

      Par contre, la partie PATH_INFO ajoutée à l'URI avant chaque règle ne -reflète que la valeur de PATH_INFO avant la passe courante du processus -de réécriture. En conséquence, si de larges portions de l'URI -correspondent et sont traduites via plusieurs directives +

      Par contre, la partie PATH_INFO ajoutée au chemin d’URL avant chaque règle ne +reflète que la valeur de PATH_INFO avant la passe actuelle du processus +de réécriture. En conséquence, si de larges portions du chemin d’URL +correspondent et sont copiées dans une substitution via plusieurs directives RewriteRule, sans prendre en compte -quelles parties de l'URI provenaient du PATH_INFO courant, l'URI final +quelles parties du chemin d’URL provenaient du PATH_INFO actuel, le chemin d’URL final pourra se voir ajouter plusieurs copies de PATH_INFO.

      Utilisez ce drapeau pour toute substitution où la présence du PATH_INFO qui @@ -339,6 +492,17 @@ débute est oublié. PATH_INFO ne sera pas recalculé tant que courante du processus de réécriture ne sera pas achevée. Les règles suivantes de cette passe ne verront que le résultat direct des substitutions, sans aucun PATH_INFO ajouté.

      + +
      # Requête : /app/script.php/extra/path (PATH_INFO contient /extra/path)
      +# Sans le drapeau DPI, la substitution serait "script.php/extra/path" et
      +# pourrait par accident copier PATH_INFO dans le résultat.
      +RewriteRule "^script\.php(.*)$" "/new-app/handler$1" [DPI]
      + + +

      Le drapeau DPI supprime /extra/path, de sorte que seul le +résultat de la substitution est transmis aux règles suivantes ou à la requête +finale.

      +
      top

      E|env

      @@ -379,7 +543,7 @@ comme les programmes CGI, d'autres directives RewriteRule, ou des directives CustomLog.

      L'exemple suivant définit une variable d'environnement nommée 'image' -avec une valeur de '1' si l'URI de la requête correspond à un fichier +avec une valeur de '1' si le chemin d’URL de la requête correspond à un fichier image. Cette variable d'environnement est ensuite utilisée pour exclure une telle requête du journal des accès.

      @@ -390,16 +554,83 @@ CustomLog "logs/access_log" combined env=!image

      Notez que le même effet peut être obtenu à l'aide de la directive SetEnvIf. Cette technique est présentée à titre d'exemple et non de recommandation.

      + + +

      Définir des variables d’environnement pour tracer les réécritures

      + +

      Parfois, nous souhaitons être au courant de l’état de la situation lorsque +nous effectuons une réécriture. Par exemple, vous voudriez prendre note +que vous avez effectué cette réécriture, de sorte que vous pourriez +ultérieurement voir si une requête est arrivée par l’intermédaire de cette +réécriture. Une solution pour y parvenir est la définition d’une variable +d’environnement.

      + +
      RewriteEngine on
      +RewriteRule   "^/horse/(.*)"   "/pony/$1" [E=rewritten:1]
      + + +

      Dans la suite de votre jeu de règles, vous pouvez consulter cette variable +d’environnement en utilisant une RewriteCond :

      + +
      RewriteCond "%{ENV:rewritten}"  =1
      + + +

      Notez que les variables d’environnements ne survivent pas à une redirection +externe. Vous devez alors utiliser le drapeau [CO] pour définir un cookie.

      + +

      Préfixe REDIRECT_ après une redirection interne

      +

      Dans un contexte de répertoire, + une substitution réussie déclenche une redirection interne. Lorsque cela se + produit, toutes les variables d’environnement définies au cours de la passe + précédente — y compris celles créées avec [E=VAR:VAL] — sont + renommées par l’ajout du préfixe REDIRECT_. Une variable que + vous avez nommée rewritten devient ainsi + REDIRECT_rewritten dans la requête redirigée.

      + +

      Pour tester la variable renommée, référencez-la avec le préfixe :

      +
      + +
      RewriteRule   "^/horses/(.*)" "/ponies/$1" [E=rewritten:1]
      +
      +# À la passe suivante, la variable a été renommée :
      +RewriteCond "%{ENV:REDIRECT_rewritten}" =1
      +RewriteRule "^/ponies/(.*)" "-" [E=seen_redirect:1,L]
      + + +

      Si la requête est redirigée plusieurs fois, le préfixe est empilé : + REDIRECT_REDIRECT_rewritten, et ainsi de suite. Voir Variables REDIRECT_ pour la description + complète de ce mécanisme.

      +
      top

      END

      L'utilisation du drapeau [END] permet non seulement de terminer le processus de réécriture en cours (comme [L]), mais aussi d'empêcher tout -processus de réécriture ultérieur dans un contexte de répertoire -(htaccess).

      +processus de réécriture ultérieur dans un contexte +de répertoire, ce qui en fait le drapeau préféré pour la plupart des +règles de niveau répertoire.

      + +

      Dans un contexte de serveur virtuel ou global, [END] et [L] se comportent de +manière identique. La différence entre les deux se situe dans un contexte de +répertoire où [L] interrompt la passe actuelle, mais où le jeu de règles est à +nouveau appliqué à l’URL réécrit. Cela peut provoquer des boucles infinies. +[END] empêche tout processus de réécriture ultérieur en interrompant le cycle.

      + +
      # Dans .htaccess : routage de toutes les requêtes vers un contrôleur frontal
      +# ici, [L] proquerait une boucle infine, pas [END]
      +RewriteCond "%{REQUEST_FILENAME}" !-f
      +RewriteCond "%{REQUEST_FILENAME}" !-d
      +RewriteRule "^(.*)$" "/index.php" [END]
      +

      Ceci ne s'applique pas aux nouvelles requêtes résultant d'une redirection externe.

      + +

      Voir la discussion Réécritures dans un contexte +de répertoire pour une explication détaillée de la raison pour laquelle [L] +se comporte différemment dans un contexte de répertoire, et des cas où [END] +constitue le bon choix.

      +
      top

      F|forbidden

      @@ -415,9 +646,9 @@ Forbidden.

      RewriteRule "\.exe" "-" [F]
      -

      Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce -qui signifie que l'URI de la requête n'est pas modifié. Il n'y a aucune -raison de réécrire un URI, si vous avez l'intention d'interdire la +

      Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce qui +signifie que le chemin d’URL de la requête n'est pas modifié. Il n'y a aucune +raison de réécrire un chemin d’URL, si vous avez l'intention d'interdire la requête.

      Lorsqu'on utilise [F], [L] est implicite - c'est à dire que la @@ -484,30 +715,11 @@ traitée. Ce drapeau correspond à la commande Perl last -

      Si vous utilisez des règles RewriteRule dans des fichiers -.htaccess ou des sections <Directory>, il est important d'avoir quelques -notions sur la manière dont les règles sont traitées. Pour simplifier, -une fois les règles traitées, la requête réécrite est passée à nouveau -au moteur d'interprétation des URLs afin que ce dernier puisse la -traiter. Il est possible qu'au cours du traitement de la requête -réécrite, le fichier .htaccess ou la section <Directory> soient à nouveau -rencontrés, entraînant un nouveau traitement du jeu de règles depuis le -début. Cette situation se présente le plus souvent lorsqu'une des règles -provoque une redirection - interne ou externe - ce qui réinitialise le -traitement de la requête.

      - -

      Si vous utilisez des directives RewriteRule dans un de ces contextes, -il importe par conséquent de prévoir explicitement des étapes permettant -d'éviter un bouclage infini sur les règles, -et de ne pas compter seulement sur -le drapeau [L] pour terminer l'exécution d'une série de règles, comme -décrit ci-dessous.

      - -

      Un autre drapeau, [END], permet non seulement d'interrompre le cycle -courant du processus de réécriture, mais aussi d'empêcher toute -réécriture ultérieure dans le contexte de répertoire (htaccess). Ceci ne -s'applique pas aux nouvelles requêtes résultant de redirections -externes.

      +

      Dans un contexte de répertoire, [L] +arrête la passe actuelle du jeu de règles, mais la requête réécrite peut être +traitée à nouveau depuis le début du jeu de règles — ce qui peut provoquer des +boucles infinies. Pour éviter ce problème, utilisez le drapeau [END], ou consultez le document Réécritures au niveau répertoire pour une +description détaillée du problème et des solutions alternatives.

      Dans l'exemple donné ici, toute requête est réécrite en index.php, la requête originale étant ajoutée comme chaîne @@ -540,7 +752,7 @@ ceci jusqu'il n'y ait plus de A à remplacer.

      Vous pouvez vous représenter ce traitement comme une boucle while : tant que le modèle de la règle correspond (c'est à -dire, tant que l'URI contient un A), +dire, tant que le chemin d’URL contient un A), effectuer la substitution (c'est à dire, remplacer le A par un B).

      @@ -558,7 +770,7 @@ RewriteRule "(.+)[><;]$" "$1" [N=10]

      NC|nocase

      Avec le drapeau [NC], le modèle de la règle RewriteRule est comparé à la requête de manière insensible à la casse. C'est à dire que cette comparaison -s'effectue sans tenir compte des majuscules/minuscules dans l'URI +s'effectue sans tenir compte des majuscules/minuscules dans le chemin URL comparé.

      Dans l'exemple suivant, toute requête pour un fichier image sera @@ -600,6 +812,10 @@ aurait été converti en son équivalent hexadécimal, < qui aurait provoqué un code d'erreur "404 Not Found".

      +

      Voir Encodage et décodage des URLs pour une +description complète de la manière dont httpd encode et décode les URLs lors de +la réécriture.

      +
      top

      NS|nosubreq

      @@ -627,6 +843,14 @@ Les images, scripts java, ou fichiers css, chargés en tant que partie d'une page html, ne sont pas des sous-requêtes - le navigateur les appelle sous forme de requêtes HTTP à part entière.

      + +
      # Ne réécrire que les requêtes directes vers le contrôleur frontal, pas les
      +# sous-requêtes des inclusions SSI ou de mod_dir.
      +RewriteCond "%{REQUEST_FILENAME}" !-f
      +RewriteCond "%{REQUEST_FILENAME}" !-d
      +RewriteRule "^(.*)$" "/app/index.php?page=$1" [NS,L]
      + +
      top

      P|proxy

      @@ -644,7 +868,7 @@ autrement dit, la requête est immédiatement envoyée au manda toute règle ultérieure sera ignorée.

      -Vous devez vous assurer que la chaîne de substitution soit un URI valide +Vous devez vous assurer que la chaîne de substitution soit un URL valide (commençant typiquement par http://nom-serveur) qui puisse être traitée par le module mod_proxy. Dans le cas contraire, le module mandataire vous renverra une erreur. @@ -655,12 +879,17 @@ local.

      Avertissement à propos de la sécurité

      -

      Lors de la construction de l'URL cible de la règle, il convient - de prendre en compte l'impact en matière de sécurité qu'aura le - fait de permettre au client d'influencer le jeu d'URLs pour - lesquelles votre serveur agira en tant que mandataire. - Assurez-vous que la partie protocole://nom-serveur de l'URL soit - fixe, ou ne permette pas au client de l'influencer induement.

      +

      Lors de la construction de l'URL cible de la règle, il convient de + prendre en compte l'impact en matière de sécurité qu'aura le fait de + permettre au client d'influencer le jeu d'URLs pour lesquelles votre + serveur agira en tant que mandataire. Si une partie de l’URL cible est + dérivée de l’entrée de l’utilisateur (références arrières, chaînes de + paramètres, etc.), un attaquant pourra être capable de faire que votre + serveur génère des requêtes vers des hôtes internes ou externes + arbitraires. Cette vulnérabilité est connue sous le nom de falsification + de requête côté serveur (Server-Side Request Forgery — SSRF). Assurez-vous + que la partie protocole://nom-serveur de l'URL soit fixe, ou ne permette + pas au client de l'influencer indument.

      @@ -687,7 +916,7 @@ utiliser ce drapeau.

      Par défaut, la cible (ou chaîne de substitution) d'une règle RewriteRule est sensée être un chemin de fichier. Avec le drapeau [PT], -par contre, elle est traitée comme un URI. Autrement dit, avec le +par contre, elle est traitée comme un chemin URL. Autrement dit, avec le drapeau [PT], le résultat de la règle RewriteRule est passé à nouveau au système de mise en correspondance des URLs avec le système de fichiers, de façon à ce que les systèmes de mise en correspondance basés sur les @@ -722,7 +951,7 @@ réécrire vers -.

      QSA|qsappend

      -Quand l'URI de remplacement contient une chaîne de requête, le +Quand l'URL de remplacement contient une chaîne de requête, le comportement par défaut de la règle RewriteRule est de supprimer la query string (il s'agit des paramètres éventuellement passés dans l'URL après le caractère ?, usuellement pour les formulaires traités par la @@ -745,10 +974,10 @@ autrement dit, la chaîne de requête (query string) exis

      QSD|qsdiscard

      -Lorsque l'URI de la requête contient une chaîne de paramètres, et si +Lorsque l'URL de la requête contient une chaîne de paramètres, et si l'URI cible n'en contient pas, le comportement par défaut de la directive RewriteRule consiste à copier cette -chaîne de paramètres dans l'URI cible. Avec le drapeau [QSD], la chaîne +chaîne de paramètres dans l'URL cible. Avec le drapeau [QSD], la chaîne de paramètres est supprimée.

      @@ -760,12 +989,18 @@ drapeau [QSD] qui l'emporte.

      -Si l'URI cible possède une chaîne de paramètres, le comportement par +Si l'URL cible possède une chaîne de paramètres, le comportement par défaut sera respecté - c'est à dire que la chaîne de paramètres originale sera supprimée et remplacée par la chaîne de paramètres de -l'URI cible. +l'URL cible.

      +
      # Redirection des anciens URLs « search » vers le nouveau chemin en supprimant
      +# la chaîne de paramètres. /search?q=term&page=2 devient /find (chaîne de
      +# paramètres supprimée)
      +RewriteRule "^/search" "/find" [QSD,R=301,L]
      + +
      top

      QSL|qslast

      @@ -781,6 +1016,20 @@ points d'interrogation. Si aucune chaîne de paramètre n'est pr&eacu substitution, il est alors possible d'ajouter un point d'interrogation à la fin et d'utiliser ce drapeau.

      +

      Par exemple, si une application patrimoniale attend une chaîne de paramètres +qui contient elle-même un point d’interrogation :

      + +
      # Associe /lookup/foo?bar à /app?type=foo?bar
      +# Sans [QSL], le premier ? dans la substitution couperait le chemin, en
      +# produisant incorrectement /app avec la chaîne de paramètres type=foo?bar.
      +# Avec [QSL], le DERNIER ? est utilisé comme délimiteur.
      +RewriteRule "^/lookup/(.*)" "/app?type=$1" [QSL,PT]
      + + +

      Sans [QSL], la substitution /app?type=foo?bar serait coupée au +premier ?, perdant de ce fait le point d’interrogation littéral de +la valeur.

      +

      Ce drapeau est disponible à partir de la version 2.4.19 du serveur HTTP Apache.

      @@ -812,7 +1061,7 @@ codes de redirection en utilisant leurs noms symboliques :

      Vous utiliserez presque toujours [R] en conjonction avec [L] (c'est à -dire [R,L]), car employé seul, le drapeau [R] préfixe l'URI avec +dire [R,L]), car employé seul, le drapeau [R] préfixe le chemin URL avec http://cet-hôte[:ce-port], mais passe ensuite cette adresse à la règle suivante, ce qui provoquera le plus souvent des avertissements 'Invalid URI in request'. @@ -822,19 +1071,32 @@ avertissements 'Invalid URI in request'. spécification de HTTP. Utiliser un code d'état non reconnu provoquera une erreur 500 et l'enregistrement d'un message dans le journal des erreurs.

      +

      [R=4xx] ne sert pas la substitution

      +

      Lorsqu’un code d’état en dehors de l’intervalle 300-399 est spécifié (par +exemple [R=403] ou [R=410]), la chaîne de substitution +est ignorée. L’URL que vous avez saisi comme cible n’est pas servi au client. À +la place, httpd renvoie le code d’état spécifié et le traite de la manière +habituelle pour les réponses d'erreur (entre autres tout ErrorDocument configuré). Si vous souhaitez interdire +l’accès, les drapeaux [F] et [G] +sont des solutions plus adaptées pour exprimer la même intention.

      +
      + +
      # Redirection des requêtes pour l’ancien chemin de la documentation vers le
      +# nouvel emplacement.
      +RewriteRule "^/docs/(.*)$" "http://docs.example.com/$1" [R=301,L]
      + +
      top

      S|skip

      -

      Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir -exécuter. La syntaxe du drapeau [S] est [S=N], où -N correspond au nombre de règles à sauter (sous -réserve que la règle RewriteRule corresponde et qu'au moins -une condition RewriteCond -préalable soit vérifiée). -Ceci peut s'interpréter comme une instruction -goto dans votre jeu de règles de réécriture. Dans -l'exemple suivant, nous ne voulons exécuter la règle RewriteRule que si l'URI demandé ne -correspond pas à un fichier existant.

      +

      Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir exécuter. +La syntaxe du drapeau [S] est [S=N], où N correspond au nombre +de règles à sauter (sous réserve que la règle RewriteRule corresponde et qu'au moins une +condition RewriteCond préalable soit +vérifiée). Ceci peut s'interpréter comme une instruction goto +dans votre jeu de règles de réécriture. Dans l'exemple suivant, nous ne voulons +exécuter la règle RewriteRule que si +le chemin URL demandé ne correspond pas à un fichier existant.

      # La requête concerne-t-elle un fichier qui n'existe pas ?
       RewriteCond "%{REQUEST_FILENAME}" !-f
       RewriteCond "%{REQUEST_FILENAME}" !-d
      @@ -845,8 +1107,6 @@ RewriteRule "(.*\.gif)" "images.php?$1"
       RewriteRule "(.*\.html)" "docs.php?$1"
      - -

      Cette technique trouve son utilité dans le fait qu'une directive RewriteCond ne s'applique qu'à la règle qui la suit immédiatement. Ainsi, si vous voulez @@ -917,9 +1177,31 @@ utiliser le drapeau L pour terminer la séquence

      UnsafeAllow3F

      Il est nécessaire de définir ce drapeau pour permettre à une réécriture - de continuer si la requête HTTP en cours d'écriture possède un point d'interrogation encodé, « %3f », et si le résultat réécrit contient un « ? » dans - la substitution. Cela protège d'une URL malveillante tirant avantage d'une - capture et d'une resubstitution du point d'interrogation encodé.

      + de continuer si la requête HTTP en cours d'écriture possède un point + d'interrogation encodé, « %3f », et si le résultat réécrit + contient un « ? » dans la substitution. Cela protège d'une URL + malveillante tirant avantage d'une capture et d'une resubstitution du point + d'interrogation encodé.

      + +
      # Un contrôleur frontal PHP qui route toutes les requêtes via un élément de la
      +# chaîne de paramètres.
      +# Sans UnsafeAllow3F, une requête comme /page%3Fname=test renverrait 403 Forbidden,
      +# car le substitution réécrite contient '?' alors que la requête originelle
      +# contient un caractère encodé '%3F'.
      +RewriteCond "%{REQUEST_FILENAME}" !-f
      +RewriteCond "%{REQUEST_FILENAME}" !-d
      +RewriteRule "(.+)" "index.php?route=$1" [L,QSA,UnsafeAllow3F]
      + + +
      +L’existence de ce drapeau est due à CVE-2024-38474. Ne +l’utilisez que dans les règles pour lesquelles vous êtes certain qu’un +%3F saisi par l’utilisateur dans la requête ne peut pas être +exploité pour manipuler la chaîne de paramètres de la cible de substitution. +Préférez autant que possible la restructuration des URLs pour éviter les points +d’interrogation encodés. +
      +
      top

      UnsafePrefixStat

      @@ -927,11 +1209,29 @@ utiliser le drapeau L pour terminer la séquence l'échelle du serveur qui commencent par une variable ou une référence arrière et se résolvent en un chemin du système de fichiers. Ces substitutions ne sont pas préfixées par la racine des documents. Cela protège - d'une URL malveillante faisant correspondre la substitution expansée à un + d'un URL malveillant faisant correspondre la substitution développée à un emplacement non souhaité du système de fichiers.

      Disponible à partir de la version 2.5.1 du serveur HTTP Apache.

      -
      top
      + +
      # Cette règle lance la substitution avec une référence arrière.
      +# Depuis la version 2.4.60, cette opération est rejetée par défaut pour empêcher
      +# le chemin développé de s’échapper de la racine des documents (CVE-2024-38475).
      +# N’ajoutez UnsafePrefixStat qu’après avoir vérifié que la substitution ne peut
      +# pas se résoudre en un chemin du système de fichiers en dehors de la racine des
      +# documents de votre site.
      +RewriteRule "^/mirror/(.+)$" "$1" [PT,UnsafePrefixStat]
      + + +
      +L’existence de ce drapeau est due à CVE-2024-38475. Sans +lui, une substitution commençant par une référence arrière ou une variable qui +correspond à un chemin existant du système de fichiers pourrait permettre à des +requêtes de s’échapper de la racine des documents. N’utilisez ce drapeau +qu’après avoir confirmé que la substitution est contrainte de manière adéquate. +
      + +
      top

      UNC

      Définir ce drapeau empêche la fusion des slashes de début multiples tels @@ -940,6 +1240,21 @@ utiliser le drapeau L pour terminer la séquence multiples littéraux.

      Disponible à partir de la version 2.5.1 du serveur HTTP Apache.

      + +
      # Sous Windows, réécriture vers un partage de fichiers UNC
      +# en utilisant une variable
      +# Sans [UNC], les barres obliques de tête dans la substitution seraient
      +# fusionnées (//server/share deviendrait /server/share).
      +RewriteCond "%{HTTP_HOST}" "^(.+)\.internal$"
      +RewriteRule "^/shared/(.*)$" "//%1/fileshare/$1" [UNC]
      + + +

      Ce drapeau n’est pertinent que sous Windows. Il empêche httpd de fusionner +les doubles barres obliques de tête (//) qui sont présentes dans un +chemin UNC lorsque ce dernier a été construit à partir d’une référence arrière +ou d’une variable. Si la substitution commence par des doubles barres obliques +littérales, aucun drapeau n’est nécessaire.

      +

      Langues Disponibles:  de  | diff --git a/docs/manual/rewrite/flags.xml b/docs/manual/rewrite/flags.xml index b5cf4a417a5..aa69daf326f 100644 --- a/docs/manual/rewrite/flags.xml +++ b/docs/manual/rewrite/flags.xml @@ -65,6 +65,144 @@ have no effect in per-directory context, of how you might use them.

      +
      Flag Quick Reference + +

      Flags can be combined: [R=301,L], [P,QSA], +[E=VAR:val,L]. This table groups them by purpose, ordered +by how commonly each is used.

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FlagPurposeEffectCommon combos
      Flow Control
      [L]Last ruleStop processing rules (this pass)[R=301,L] [F] [G]
      [END]Full stopStop all rewrite processing (no re-entry in .htaccess)[R=301,END]
      [S=N]SkipSkip next N rules (if/else logic)
      [N]Next (loop)Restart ruleset from the top (caution: loop risk)
      [C]ChainTie rule to the next; if this fails, skip chained rules
      Redirection and Proxying
      [R=code]RedirectExternal redirect (default 302). Consider Redirect/RedirectMatch for simple cases[R=301,L] [R=302,L]
      [P]ProxyReverse proxy to target (requires mod_proxy)[P,QSA]
      Access Control
      [F]ForbiddenReturn 403 (implies [L])
      [G]GoneReturn 410 (implies [L])
      URL / Query String
      [QSA]Query string appendAppend original query string to substitution[QSA,L] [P,QSA]
      [QSD]Query string discardDrop original query string entirely[R=301,QSD,L]
      [B]Escape backrefsRe-encode special chars in backreferences[B,PT]
      [NE]No escapeDon't escape special chars in output (pass #, ? through)[R=301,NE,L]
      Metadata and Handlers
      [E]Set env varSet an environment variable[E=VAR:val,L]
      [T]MIME typeForce content type
      [H]HandlerForce a content handler
      [PT]Pass throughPass result to next handler (needed with Alias/ScriptAlias)[PT,L]
      Cookie
      [CO]Set cookieSet an HTTP cookie on the response[CO=name:val:.domain,R=302,L]
      + +
      +
      B (escape backreferences)

      The [B] flag instructs RewriteRule to escape non-alphanumeric @@ -212,6 +350,13 @@ follows:

      [CO=NAME:VALUE:DOMAIN:lifetime:path:secure:httponly:samesite] + +Security Warning +

      Exercise care when constructing the argument from backreferences or other +variable expansion. If any part of the argument is derived from user input, +a malicious request may include delimeters or other unexpected values.

      +
      +

      If a literal ':' character is needed in any of the cookie fields, an alternate syntax is available. To opt-in to the alternate syntax, the cookie "Name" should be preceded with a ';' character, and field separators should be diff --git a/docs/manual/rewrite/flags.xml.de b/docs/manual/rewrite/flags.xml.de index 3f7d989482b..417e6b523a8 100644 --- a/docs/manual/rewrite/flags.xml.de +++ b/docs/manual/rewrite/flags.xml.de @@ -1,7 +1,7 @@ - + + + @@ -37,12 +37,11 @@ des explications détaillées et des exemples.

      Introduction à mod_rewrite Redirection and remise en correspondance -Contrôle d'accès +Réécritures par répertoire Serveurs virtuels -Mise en cache Utilisation de RewriteMap -Techniques avancées Quand ne pas utiliser mod_rewrite +Détails techniques
      Introduction

      Le comportement d'une directive -

      Les drapeaux qui modifient les métadonnées associées à la requête -(T=, H=, E=) n'ont aucun effet dans un contexte de répertoire ou de -fichier htaccess, lorsqu'une substitution (autre que '-') est effectuée -au cours de la même passe du processus de réécriture. -

      +

      Les drapeaux qui modifient les métadonnées associées à la requête (T=, H=, +E=) n'ont aucun effet dans un contexte de +répertoire ou de fichier htaccess, lorsqu'une substitution (autre que +'-') est effectuée au cours de la même passe du processus de réécriture.

      Chaque drapeau disponible est présenté ici, avec un exemple d'utilisation.

      +
      Référence rapide des drapeaux + +

      Les drapeaux peuvent être combinés : [R=301,L], [P,QSA], +[E=VAR:val,L]. Cette table les groupe par fonction et les trie +selon la fréquence de leur utilisation.

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      DrapeauFonctionEffetCombinaisons courantes
      Contrôle de flux
      [L]Dernière règleArrête le traitement des règles (pour cette passe)[R=301,L] [F] [G]
      [END]Arrêt completArrête tout le processus de réécriture (pas de réentrance dans .htaccess)[R=301,END]
      [S=N]SautSauter les N prochaines règles (logique if/else)
      [N]Instance suivante de la boucleRedémarrer le traitement du jeu de règles à partir de la première + (attention : risque de boucle infinie)
      [C]ChaînageChaîner la règle actuelle à la prochaine ; si la règle actuelle échoue, + sauter les règles chaînées
      Redirection et mandatement
      [R=code]RedirectionRedirection externe (par défaut 302). Utilisez Redirect/RedirectMatch pour + les cas simple[R=301,L] [R=302,L]
      [P]MandatementMandatement inverse vers une cible (nécessite mod_proxy)[P,QSA]
      Contrôle d’accès
      [F]InterdictionRenvoie 403 (implique [L])
      [G]PartiRenvoie 410 (implique [L])
      URL / chaîne de paramètres
      [QSA]Ajout de la chaîne de paramètresAjout de la chaîne de paramètres originelle à la substitution[QSA,L] [P,QSA]
      [QSD]Suppression de la chaîne de paramètresSupprime entièrement la chaîne de paramètres[R=301,QSD,L]
      [B]Échappement des références arrièresRéencode les caractères spéciaux dans les références arrières[B,PT]
      [NE]Pas d’échappementPas d’échappement des caractères spéciaux dans la sortie (pass #, ? through)[R=301,NE,L]
      Metadonnées et gestionnaires
      [E]Définition d’une variable d’environnementDéfinit une variable d’environnement[E=VAR:val,L]
      [T]Type MIMEForçage du type de contenu
      [H]GestionnaireForçage d’un gestionnaire de contenu
      [PT]Transmission résultatTransmission du résultat au gestionnaire suivant (requis pour Alias/ScriptAlias)[PT,L]
      Cookie
      [CO]Définir un cookieDéfinir un cookie HTTP pour la réponse[CO=name:val:.domain,R=302,L]
      + +
      +
      B (échappement dans les références arrières)

      Avec le drapeau [B], la directive RewriteRule échappe les caractères @@ -142,8 +281,13 @@ RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"

      Pour définir la liste des caractères à échapper de cette manière, voir #flag_bne et #flag_bctls

      +

      Voir Encodage et décodage des URLs pour une +explication détaillée de la manière dont httpd décode les URIs avant la mise en +correspondance des motifs.

      +
      +
      BNP|backrefnoplus (ne pas échapper l'espace en +)

      Si le drapeau [BNP] est spécifié, la directive Ce drapeau est disponible à partir de la version 2.4.26 du serveur HTTP Apache.

      +

      Voir Encodage et décodage des URLs pour +découvrir la manière dont l’encodage est géré dans le tube (pipeline) de +réécriture.

      +
      BCTLS @@ -174,7 +322,7 @@ rejetés lorsqu'ils sont copiés dans la chaîne de paramètres non codée. RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]" -

      Ce drapeau est disponible à partir de la version 2.5.1 du serveur HTTP +

      Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP Apache.

      @@ -189,7 +337,7 @@ correspondant aux drapeaux [B] ou [BCTLS]. Ils ne seront donc pas échappés. RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]" -

      Ce drapeau est disponible à partir de la version 2.5.1 du serveur HTTP +

      Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP Apache.

      @@ -202,6 +350,19 @@ normalement et passe le contrôle à la règle suivante. Par contre, si elle ne s'applique pas, la règle suivante, ainsi que toutes les règles chaînées qui suivent, seront sautées.

      + +# Réécrire les URLs des anciens produits vers la nouvelle application du +# catalogue, et ajouter un paramètre de traçage — mais seulement pour ceux qui +# sont réécrits. +RewriteRule "^/products/([0-9]+)$" "/catalog/item/$1" [C] +RewriteRule "^/catalog/(.*)$" "/catalog/$1?via=legacy" [QSA] + + +

      Sans le drapeau [C], la seconde règle s’appliquerait aux requêtes qui +arrivent directement à /catalog/. Le chaînage des deux règles +permet de s’assurer que la seconde règle ne s’appliquera que si la première +s’applique.

      +
      CO|cookie @@ -245,7 +406,7 @@ ce style de cookie est interdit par le modèle de sécurité des cookies.
      Lifetime
      La durée de vie du cookie, en minutes.
      -
      Une valeur de 0 indique une durée de vie correspondant à la session +
      Une valeur de 0 indique une durée de vie correspondant à lasession courante du navigateur. Il s'agit de la valeur par défaut.
      Une valeur négative indique que la définition du cookie doit être annulée dans le navigateur.
      @@ -295,24 +456,26 @@ pour tous les URIs.

      DPI|discardpath -

      Avec le drapeau DPI, la partie PATH_INFO de l'URI -réécrit est supprimée.

      -

      Ce drapeau est disponible dans les versions 2.2.12 et supérieures.

      -

      Dans un contexte de répertoire, l'URI mis en comparaison par chaque -règle RewriteRule est la concaténation des -valeurs courantes de l'URI et de PATH_INFO.

      - -

      L'URI courant peut être l'URI initial tel qu'il a été fourni par le +

      Avec le drapeau DPI, la partie PATH_INFO +qui a été ajoutée au chemin d’URL réécrit est +supprimée.

      + +

      Dans un contexte de répertoire, le +chemin d’URL que compare chaque +RewriteRule est la concaténation des valeurs courantes du +chemin d’URL et de PATH_INFO.

      + +

      Le chemin d’URL actuel peut être le chemin initial tel qu'il a été fourni par le client, le résultat d'une passe précédente du processus de réécriture, -ou le résultat de la règle précédente dans le processus courant de +ou le résultat de la règle précédente de la passe actuelle du processus de réécriture.

      -

      Par contre, la partie PATH_INFO ajoutée à l'URI avant chaque règle ne -reflète que la valeur de PATH_INFO avant la passe courante du processus -de réécriture. En conséquence, si de larges portions de l'URI -correspondent et sont traduites via plusieurs directives +

      Par contre, la partie PATH_INFO ajoutée au chemin d’URL avant chaque règle ne +reflète que la valeur de PATH_INFO avant la passe actuelle du processus +de réécriture. En conséquence, si de larges portions du chemin d’URL +correspondent et sont copiées dans une substitution via plusieurs directives RewriteRule, sans prendre en compte -quelles parties de l'URI provenaient du PATH_INFO courant, l'URI final +quelles parties du chemin d’URL provenaient du PATH_INFO actuel, le chemin d’URL final pourra se voir ajouter plusieurs copies de PATH_INFO.

      Utilisez ce drapeau pour toute substitution où la présence du PATH_INFO qui @@ -323,6 +486,18 @@ débute est oublié. PATH_INFO ne sera pas recalculé tant que la passe courante du processus de réécriture ne sera pas achevée. Les règles suivantes de cette passe ne verront que le résultat direct des substitutions, sans aucun PATH_INFO ajouté.

      + + +# Requête : /app/script.php/extra/path (PATH_INFO contient /extra/path) +# Sans le drapeau DPI, la substitution serait "script.php/extra/path" et +# pourrait par accident copier PATH_INFO dans le résultat. +RewriteRule "^script\.php(.*)$" "/new-app/handler$1" [DPI] + + +

      Le drapeau DPI supprime /extra/path, de sorte que seul le +résultat de la substitution est transmis aux règles suivantes ou à la requête +finale.

      +
      E|env @@ -364,7 +539,7 @@ comme les programmes CGI, d'autres directives RewriteRule, ou des directives CustomLog.

      L'exemple suivant définit une variable d'environnement nommée 'image' -avec une valeur de '1' si l'URI de la requête correspond à un fichier +avec une valeur de '1' si le chemin d’URL de la requête correspond à un fichier image. Cette variable d'environnement est ensuite utilisée pour exclure une telle requête du journal des accès.

      @@ -376,16 +551,88 @@ CustomLog "logs/access_log" combined env=!image

      Notez que le même effet peut être obtenu à l'aide de la directive SetEnvIf. Cette technique est présentée à titre d'exemple et non de recommandation.

      + + +

      Définir des variables d’environnement pour tracer les réécritures

      + +

      Parfois, nous souhaitons être au courant de l’état de la situation lorsque +nous effectuons une réécriture. Par exemple, vous voudriez prendre note +que vous avez effectué cette réécriture, de sorte que vous pourriez +ultérieurement voir si une requête est arrivée par l’intermédaire de cette +réécriture. Une solution pour y parvenir est la définition d’une variable +d’environnement.

      + + +RewriteEngine on +RewriteRule "^/horse/(.*)" "/pony/$1" [E=rewritten:1] + + +

      Dans la suite de votre jeu de règles, vous pouvez consulter cette variable +d’environnement en utilisant une RewriteCond :

      + + +RewriteCond "%{ENV:rewritten}" =1 + + +

      Notez que les variables d’environnements ne survivent pas à une redirection +externe. Vous devez alors utiliser le drapeau [CO] pour définir un cookie.

      + + Préfixe REDIRECT_ après une redirection interne +

      Dans un contexte de répertoire, + une substitution réussie déclenche une redirection interne. Lorsque cela se + produit, toutes les variables d’environnement définies au cours de la passe + précédente — y compris celles créées avec [E=VAR:VAL] — sont + renommées par l’ajout du préfixe REDIRECT_. Une variable que + vous avez nommée rewritten devient ainsi + REDIRECT_rewritten dans la requête redirigée.

      + +

      Pour tester la variable renommée, référencez-la avec le préfixe :

      +
      + + +RewriteRule "^/horses/(.*)" "/ponies/$1" [E=rewritten:1] + +# À la passe suivante, la variable a été renommée : +RewriteCond "%{ENV:REDIRECT_rewritten}" =1 +RewriteRule "^/ponies/(.*)" "-" [E=seen_redirect:1,L] + + +

      Si la requête est redirigée plusieurs fois, le préfixe est empilé : + REDIRECT_REDIRECT_rewritten, et ainsi de suite. Voir Variables REDIRECT_ pour la description + complète de ce mécanisme.

      +
      END

      L'utilisation du drapeau [END] permet non seulement de terminer le processus de réécriture en cours (comme [L]), mais aussi d'empêcher tout -processus de réécriture ultérieur dans un contexte de répertoire -(htaccess).

      +processus de réécriture ultérieur dans un contexte +de répertoire, ce qui en fait le drapeau préféré pour la plupart des +règles de niveau répertoire.

      + +

      Dans un contexte de serveur virtuel ou global, [END] et [L] se comportent de +manière identique. La différence entre les deux se situe dans un contexte de +répertoire où [L] interrompt la passe actuelle, mais où le jeu de règles est à +nouveau appliqué à l’URL réécrit. Cela peut provoquer des boucles infinies. +[END] empêche tout processus de réécriture ultérieur en interrompant le cycle.

      + + +# Dans .htaccess : routage de toutes les requêtes vers un contrôleur frontal +# ici, [L] proquerait une boucle infine, pas [END] +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "^(.*)$" "/index.php" [END] +

      Ceci ne s'applique pas aux nouvelles requêtes résultant d'une redirection externe.

      + +

      Voir la discussion Réécritures dans un contexte +de répertoire pour une explication détaillée de la raison pour laquelle [L] +se comporte différemment dans un contexte de répertoire, et des cas où [END] +constitue le bon choix.

      +
      F|forbidden @@ -400,9 +647,9 @@ Forbidden.

      RewriteRule "\.exe" "-" [F] -

      Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce -qui signifie que l'URI de la requête n'est pas modifié. Il n'y a aucune -raison de réécrire un URI, si vous avez l'intention d'interdire la +

      Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce qui +signifie que le chemin d’URL de la requête n'est pas modifié. Il n'y a aucune +raison de réécrire un chemin d’URL, si vous avez l'intention d'interdire la requête.

      Lorsqu'on utilise [F], [L] est implicite - c'est à dire que la @@ -468,34 +715,13 @@ traitée. Ce drapeau correspond à la commande Perl last, ou que la règle courante doit être appliquée immédiatement, sans tenir compte des règles ultérieures.

      -

      Si vous utilisez des règles RewriteRule dans des fichiers -.htaccess ou des sections Directory, il est important d'avoir quelques -notions sur la manière dont les règles sont traitées. Pour simplifier, -une fois les règles traitées, la requête réécrite est passée à nouveau -au moteur d'interprétation des URLs afin que ce dernier puisse la -traiter. Il est possible qu'au cours du traitement de la requête -réécrite, le fichier .htaccess ou la section Directory soient à nouveau -rencontrés, entraînant un nouveau traitement du jeu de règles depuis le -début. Cette situation se présente le plus souvent lorsqu'une des règles -provoque une redirection - interne ou externe - ce qui réinitialise le -traitement de la requête.

      - -

      Si vous utilisez des directives RewriteRule dans un de ces contextes, -il importe par conséquent de prévoir explicitement des étapes permettant -d'éviter un bouclage infini sur les règles, -et de ne pas compter seulement sur -le drapeau [L] pour terminer l'exécution d'une série de règles, comme -décrit ci-dessous.

      - -

      Un autre drapeau, [END], permet non seulement d'interrompre le cycle -courant du processus de réécriture, mais aussi d'empêcher toute -réécriture ultérieure dans le contexte de répertoire (htaccess). Ceci ne -s'applique pas aux nouvelles requêtes résultant de redirections -externes.

      +

      Dans un contexte de répertoire, [L] +arrête la passe actuelle du jeu de règles, mais la requête réécrite peut être +traitée à nouveau depuis le début du jeu de règles — ce qui peut provoquer des +boucles infinies. Pour éviter ce problème, utilisez le drapeau [END], ou consultez le document Réécritures au niveau répertoire pour une +description détaillée du problème et des solutions alternatives.

      Dans l'exemple donné ici, toute requête est réécrite en index.php, la requête originale étant ajoutée comme chaîne @@ -530,7 +756,7 @@ ceci jusqu'il n'y ait plus de A à remplacer.

      Vous pouvez vous représenter ce traitement comme une boucle while : tant que le modèle de la règle correspond (c'est à -dire, tant que l'URI contient un A), +dire, tant que le chemin d’URL contient un A), effectuer la substitution (c'est à dire, remplacer le A par un B).

      @@ -550,7 +776,7 @@ RewriteRule "(.+)[><;]$" "$1" [N=10]

      Avec le drapeau [NC], le modèle de la règle RewriteRule est comparé à la requête de manière insensible à la casse. C'est à dire que cette comparaison -s'effectue sans tenir compte des majuscules/minuscules dans l'URI +s'effectue sans tenir compte des majuscules/minuscules dans le chemin URL comparé.

      Dans l'exemple suivant, toute requête pour un fichier image sera @@ -591,6 +817,10 @@ aurait été converti en son équivalent hexadécimal, %23, ce qui aurait provoqué un code d'erreur "404 Not Found".

      +

      Voir Encodage et décodage des URLs pour une +description complète de la manière dont httpd encode et décode les URLs lors de +la réécriture.

      +
      NS|nosubreq @@ -618,6 +848,15 @@ Les images, scripts java, ou fichiers css, chargés en tant que partie d'une page html, ne sont pas des sous-requêtes - le navigateur les appelle sous forme de requêtes HTTP à part entière.

      + + +# Ne réécrire que les requêtes directes vers le contrôleur frontal, pas les +# sous-requêtes des inclusions SSI ou de mod_dir. +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "^(.*)$" "/app/index.php?page=$1" [NS,L] + +
      P|proxy @@ -634,7 +873,7 @@ autrement dit, la requête est immédiatement envoyée au mandataire, et toute règle ultérieure sera ignorée.

      -Vous devez vous assurer que la chaîne de substitution soit un URI valide +Vous devez vous assurer que la chaîne de substitution soit un URL valide (commençant typiquement par http://nom-serveur) qui puisse être traitée par le module mod_proxy. Dans le cas contraire, le module mandataire vous renverra une erreur. @@ -645,12 +884,17 @@ local.

      Avertissement à propos de la sécurité -

      Lors de la construction de l'URL cible de la règle, il convient - de prendre en compte l'impact en matière de sécurité qu'aura le - fait de permettre au client d'influencer le jeu d'URLs pour - lesquelles votre serveur agira en tant que mandataire. - Assurez-vous que la partie protocole://nom-serveur de l'URL soit - fixe, ou ne permette pas au client de l'influencer induement.

      +

      Lors de la construction de l'URL cible de la règle, il convient de + prendre en compte l'impact en matière de sécurité qu'aura le fait de + permettre au client d'influencer le jeu d'URLs pour lesquelles votre + serveur agira en tant que mandataire. Si une partie de l’URL cible est + dérivée de l’entrée de l’utilisateur (références arrières, chaînes de + paramètres, etc.), un attaquant pourra être capable de faire que votre + serveur génère des requêtes vers des hôtes internes ou externes + arbitraires. Cette vulnérabilité est connue sous le nom de falsification + de requête côté serveur (Server-Side Request Forgery — SSRF). Assurez-vous + que la partie protocole://nom-serveur de l'URL soit fixe, ou ne permette + pas au client de l'influencer indument.

      @@ -680,7 +924,7 @@ utiliser ce drapeau.

      Par défaut, la cible (ou chaîne de substitution) d'une règle RewriteRule est sensée être un chemin de fichier. Avec le drapeau [PT], -par contre, elle est traitée comme un URI. Autrement dit, avec le +par contre, elle est traitée comme un chemin URL. Autrement dit, avec le drapeau [PT], le résultat de la règle RewriteRule est passé à nouveau au système de mise en correspondance des URLs avec le système de fichiers, @@ -724,7 +968,7 @@ réécrire vers -.

      QSA|qsappend

      -Quand l'URI de remplacement contient une chaîne de requête, le +Quand l'URL de remplacement contient une chaîne de requête, le comportement par défaut de la règle RewriteRule est de supprimer la query string (il s'agit des paramètres éventuellement passés dans l'URL après le @@ -747,10 +991,10 @@ autrement dit, la chaîne de requête (query string) existante sera

      QSD|qsdiscard

      -Lorsque l'URI de la requête contient une chaîne de paramètres, et si +Lorsque l'URL de la requête contient une chaîne de paramètres, et si l'URI cible n'en contient pas, le comportement par défaut de la directive RewriteRule consiste à copier cette -chaîne de paramètres dans l'URI cible. Avec le drapeau [QSD], la chaîne +chaîne de paramètres dans l'URL cible. Avec le drapeau [QSD], la chaîne de paramètres est supprimée.

      @@ -762,12 +1006,19 @@ drapeau [QSD] qui l'emporte.

      -Si l'URI cible possède une chaîne de paramètres, le comportement par +Si l'URL cible possède une chaîne de paramètres, le comportement par défaut sera respecté - c'est à dire que la chaîne de paramètres originale sera supprimée et remplacée par la chaîne de paramètres de -l'URI cible. +l'URL cible.

      + +# Redirection des anciens URLs « search » vers le nouveau chemin en supprimant +# la chaîne de paramètres. /search?q=term&page=2 devient /find (chaîne de +# paramètres supprimée) +RewriteRule "^/search" "/find" [QSD,R=301,L] + +
      QSL|qslast @@ -783,6 +1034,21 @@ points d'interrogation. Si aucune chaîne de paramètre n'est présente dans la substitution, il est alors possible d'ajouter un point d'interrogation à la fin et d'utiliser ce drapeau.

      +

      Par exemple, si une application patrimoniale attend une chaîne de paramètres +qui contient elle-même un point d’interrogation :

      + + +# Associe /lookup/foo?bar à /app?type=foo?bar +# Sans [QSL], le premier ? dans la substitution couperait le chemin, en +# produisant incorrectement /app avec la chaîne de paramètres type=foo?bar. +# Avec [QSL], le DERNIER ? est utilisé comme délimiteur. +RewriteRule "^/lookup/(.*)" "/app?type=$1" [QSL,PT] + + +

      Sans [QSL], la substitution /app?type=foo?bar serait coupée au +premier ?, perdant de ce fait le point d’interrogation littéral de +la valeur.

      +

      Ce drapeau est disponible à partir de la version 2.4.19 du serveur HTTP Apache.

      @@ -814,7 +1080,7 @@ codes de redirection en utilisant leurs noms symboliques :

      Vous utiliserez presque toujours [R] en conjonction avec [L] (c'est à -dire [R,L]), car employé seul, le drapeau [R] préfixe l'URI avec +dire [R,L]), car employé seul, le drapeau [R] préfixe le chemin URL avec http://cet-hôte[:ce-port], mais passe ensuite cette adresse à la règle suivante, ce qui provoquera le plus souvent des avertissements 'Invalid URI in request'. @@ -824,21 +1090,35 @@ avertissements 'Invalid URI in request'. spécification de HTTP. Utiliser un code d'état non reconnu provoquera une erreur 500 et l'enregistrement d'un message dans le journal des erreurs.

      +[R=4xx] ne sert pas la substitution +

      Lorsqu’un code d’état en dehors de l’intervalle 300-399 est spécifié (par +exemple [R=403] ou [R=410]), la chaîne de substitution +est ignorée. L’URL que vous avez saisi comme cible n’est pas servi au client. À +la place, httpd renvoie le code d’état spécifié et le traite de la manière +habituelle pour les réponses d'erreur (entre autres tout ErrorDocument configuré). Si vous souhaitez interdire +l’accès, les drapeaux [F] et [G] +sont des solutions plus adaptées pour exprimer la même intention.

      +
      + + +# Redirection des requêtes pour l’ancien chemin de la documentation vers le +# nouvel emplacement. +RewriteRule "^/docs/(.*)$" "http://docs.example.com/$1" [R=301,L] + +
      S|skip -

      Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir -exécuter. La syntaxe du drapeau [S] est [S=N], où -N correspond au nombre de règles à sauter (sous -réserve que la règle RewriteRule corresponde et qu'au moins -une condition RewriteCond -préalable soit vérifiée). -Ceci peut s'interpréter comme une instruction -goto dans votre jeu de règles de réécriture. Dans -l'exemple suivant, nous ne voulons exécuter la règle RewriteRule que si l'URI demandé ne -correspond pas à un fichier existant.

      +

      Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir exécuter. +La syntaxe du drapeau [S] est [S=N], où N correspond au nombre +de règles à sauter (sous réserve que la règle RewriteRule corresponde et qu'au moins une +condition RewriteCond préalable soit +vérifiée). Ceci peut s'interpréter comme une instruction goto +dans votre jeu de règles de réécriture. Dans l'exemple suivant, nous ne voulons +exécuter la règle RewriteRule que si +le chemin URL demandé ne correspond pas à un fichier existant.

      # La requête concerne-t-elle un fichier qui n'existe pas ? RewriteCond "%{REQUEST_FILENAME}" !-f @@ -850,8 +1130,6 @@ RewriteRule "(.*\.gif)" "images.php?$1" RewriteRule "(.*\.html)" "docs.php?$1" - -

      Cette technique trouve son utilité dans le fait qu'une directive RewriteCond ne s'applique qu'à la règle qui la suit immédiatement. Ainsi, si vous voulez @@ -929,20 +1207,64 @@ utiliser le drapeau L pour terminer la séquence

      UnsafeAllow3F

      Il est nécessaire de définir ce drapeau pour permettre à une réécriture - de continuer si la requête HTTP en cours d'écriture possède un point d'interrogation encodé, « %3f », et si le résultat réécrit contient un « ? » dans - la substitution. Cela protège d'une URL malveillante tirant avantage d'une - capture et d'une resubstitution du point d'interrogation encodé.

      + de continuer si la requête HTTP en cours d'écriture possède un point + d'interrogation encodé, « %3f », et si le résultat réécrit + contient un « ? » dans la substitution. Cela protège d'une URL + malveillante tirant avantage d'une capture et d'une resubstitution du point + d'interrogation encodé.

      + + +# Un contrôleur frontal PHP qui route toutes les requêtes via un élément de la +# chaîne de paramètres. +# Sans UnsafeAllow3F, une requête comme /page%3Fname=test renverrait 403 Forbidden, +# car le substitution réécrite contient '?' alors que la requête originelle +# contient un caractère encodé '%3F'. +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "(.+)" "index.php?route=$1" [L,QSA,UnsafeAllow3F] + + + +L’existence de ce drapeau est due à CVE-2024-38474. Ne +l’utilisez que dans les règles pour lesquelles vous êtes certain qu’un +%3F saisi par l’utilisateur dans la requête ne peut pas être +exploité pour manipuler la chaîne de paramètres de la cible de substitution. +Préférez autant que possible la restructuration des URLs pour éviter les points +d’interrogation encodés. + +
      UnsafePrefixStat

      La définition de ce drapeau est requise dans les substitutions à l'échelle du serveur qui commencent par une variable ou une référence arrière et se résolvent en un chemin du système de fichiers. Ces substitutions ne sont pas préfixées par la racine des documents. Cela protège - d'une URL malveillante faisant correspondre la substitution expansée à un + d'un URL malveillant faisant correspondre la substitution développée à un emplacement non souhaité du système de fichiers.

      2.5.1

      -
      + + +# Cette règle lance la substitution avec une référence arrière. +# Depuis la version 2.4.60, cette opération est rejetée par défaut pour empêcher +# le chemin développé de s’échapper de la racine des documents (CVE-2024-38475). +# N’ajoutez UnsafePrefixStat qu’après avoir vérifié que la substitution ne peut +# pas se résoudre en un chemin du système de fichiers en dehors de la racine des +# documents de votre site. +RewriteRule "^/mirror/(.+)$" "$1" [PT,UnsafePrefixStat] + + + +L’existence de ce drapeau est due à CVE-2024-38475. Sans +lui, une substitution commençant par une référence arrière ou une variable qui +correspond à un chemin existant du système de fichiers pourrait permettre à des +requêtes de s’échapper de la racine des documents. N’utilisez ce drapeau +qu’après avoir confirmé que la substitution est contrainte de manière adéquate. + + +
      UNC

      Définir ce drapeau empêche la fusion des slashes de début multiples tels @@ -951,6 +1273,22 @@ utiliser le drapeau L pour terminer la séquence multiples littéraux.

      2.5.1

      + + +# Sous Windows, réécriture vers un partage de fichiers UNC +# en utilisant une variable +# Sans [UNC], les barres obliques de tête dans la substitution seraient +# fusionnées (//server/share deviendrait /server/share). +RewriteCond "%{HTTP_HOST}" "^(.+)\.internal$" +RewriteRule "^/shared/(.*)$" "//%1/fileshare/$1" [UNC] + + +

      Ce drapeau n’est pertinent que sous Windows. Il empêche httpd de fusionner +les doubles barres obliques de tête (//) qui sont présentes dans un +chemin UNC lorsque ce dernier a été construit à partir d’une référence arrière +ou d’une variable. Si la substitution commence par des doubles barres obliques +littérales, aucun drapeau n’est nécessaire.

      +
      diff --git a/docs/manual/rewrite/flags.xml.ja b/docs/manual/rewrite/flags.xml.ja index 4617dc70c9f..851dc7e0440 100644 --- a/docs/manual/rewrite/flags.xml.ja +++ b/docs/manual/rewrite/flags.xml.ja @@ -1,7 +1,7 @@ - + + + + -mod_rewrite et les fichiers .htaccess - Serveur HTTP Apache Version 2.5 +Réécritures au niveau répertoire - Serveur HTTP Apache Version 2.5 @@ -20,7 +20,7 @@
      <-

      mod_rewrite et les fichiers .htaccess

      +Apache > Serveur HTTP > Documentation > Version 2.5 > Rewrite

      Réécritures au niveau répertoire

      Langues Disponibles:  de  | @@ -32,19 +32,410 @@  tr  |  zh-cn 

      -
      Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.
      -

      Ce document est un complément de la documentation de référence du module -mod_rewrite. Il décrit les changements apportés aux règles -lorsqu'on utilise mod_rewrite dans les fichiers .htaccess, et -comment travailler avec ces changements.

      +

      Utiliser mod_rewrite dans les fichiers +.htaccess est une des configurations dans un contexte de répertoire les plus courantes — et les +plus sujettes à confusion. Ce document expose les principales différences entre +l’utilisation de règles de réécriture dans un contexte global au serveur et leur +utilisation dans les fichiers .htaccess, et fournit un guide +pratique pour éviter les pièges les plus courants.

      + +

      Pour des détails techniques de bas niveau à propos de la manière dont +mod_rewrite traite les règles dans un contexte de répertoire, +voir le document Détails techniques.

      - + +
      top
      +
      +

      Prérequis : AllowOverride

      + +

      Pour que des directives de mod_rewrite dans un fichier +.htaccess puissent être traitées, la configuration du serveur doit +tout d’abord les autoriser de la manière suivante :

      + +
      <Directory "/var/www/htdocs">
      +    AllowOverride FileInfo
      +</Directory>
      + + +

      Si au minimum AllowOverride FileInfo (ou AllowOverride +All) n’est pas présente, toute directive de mod_rewrite +dans les fichiers .htaccess sera silencieusement ignorée. Si vos +règles semblent ne pas fonctionner, il s’agit de la première chose à vérifier.

      + +

      En outre, soit Options FollowSymLinks, soit Options +SymLinksIfOwnerMatch doit être activée pour le répertoire en question. +Comme une règle RewriteRule peut +associer un URL à un chemin arbitraire du système de fichiers +— fonctionnellement équivalent à un lien symbolique +— mod_rewrite refusera d’opérer dans un contexte de répertoire +si aucune de ces options n’est définie. Vous verrez alors l’erreur suivante :

      + +

      +AH00670: Options FollowSymLinks and SymLinksIfOwnerMatch are both off, +so the RewriteRule directive is also forbidden due to its similar +ability to circumvent directory restrictions +

      + +

      Cette restriction s’applique aux fichiers .htaccess et aux +sections <Directory>.

      + +
      top
      +
      +

      Quel URL la règle voit-elle ?

      + +

      Dans un contexte de serveur virtuel ou global au serveur, le motif de la +règle RewriteRule est comparé à +l’ensemble du chemin d’URL, en commençant par une barre oblique. Dans un +contexte de fichier .htaccess, le préfixe du répertoire est +supprimé.

      + +

      Par exemple, si votre fichier .htaccess est dans +/var/www/htdocs/app/ et si une requête arrive pour +/app/products/widget, la règle RewriteRule ne voit que +products/widget — pas de barre oblique en tête, pas de préfixe +/app/.

      + +

      + Organigramme montrant la suppression du chemin, la substitution    et le pipeline de RewriteBase dans un contexte de répertoire, avec    trois résultats : un chemin relatif (préfixé par RewriteBase), un    chemin absolu (utilisé tel quel) et un URI absolu (redirection    externe)
      + Figure : Suppression du chemin dans un contexte de répertoire + et pipeline de RewriteBase +

      + +

      Cela signifie que vous devez écrire vos motifs différemment en fonction de +l’emplacement des règles :

      + + + + + + + + + + + + + + +
      Emplacement de la règleRègle
      Section VirtualHostRewriteRule "^/app/products/(.+)$" "/app/shop.php?item=$1"
      .htaccess dans /var/www/htdocs/app/RewriteRule "^products/(.+)$" "shop.php?item=$1"
      + +

      Notez que la version pour .htaccess n’a de barre oblique de tête +ni dans le motif, ni dans la substitution. Il s’agit de la source de confusion +la plus courante avec la réécriture dans un contexte de répertoire.

      + +

      Lorsqu’une substitution est effectuée dans un contexte de répertoire, httpd +génère une nouvelle sous-requête interne avec l’URL réécrit en redémarrant le +traitement de la requête depuis le début. Si la substitution est un chemin +relatif, la directive RewriteBase +détermine le préfixe à ajouter au chemin d’URL. Ce mécanisme de sous-requête +peut aussi être à l’origine d’un bouclage infini des règles — voir ci-après.

      + + +

      Ne faites pas commencer vos motifs de .htaccess avec +une barre oblique

      +

      Étant donné que le préfixe du répertoire (y compris la barre oblique de fin) +est supprimé avant la mise en correspondance, les motifs dans un contexte de répertoire ne correspondront +jamais avec une adresse commençant par une barre oblique. Un motif +commençant par ^/ ne correspondra jamais dans ce contexte. Une +règle telle que RewriteRule "^/foo" ... placée dans un fichier +.htaccess échouera silencieusement à s’appliquer à quelque requête +que ce soit.

      + +

      Si vous devez faire une recherche de correspondance avec le chemin d’URL +original complet (y compris le préfixe de répertoire), utilisez +%{REQUEST_URI} dans une directive RewriteCond :

      + +
      RewriteCond "%{REQUEST_URI}" "^/admin/"
      +RewriteRule "^.*$" "-" [F]
      + + +
      top
      +
      +

      Quand avez-vous besoin de RewriteBase ?

      + +

      Quand mod_rewrite effectue une substitution dans un fichier +.htaccess, il doit retransformer le résultat relatif en un chemin +d’URL complet. La directive RewriteBase lui indique quel préfixe il doit +ajouter.

      + +

      Par défaut, RewriteBase est +définie avec le chemin physique du fichier .htaccess. Dans la +plupart des cas, cela correspond aux attentes, et vous n’avez pas besoin de la +définir explicitement. Il y a cependant des situations où vous devrez le faire :

      + +
        +
      • Alias ou lien symbolique : Si le répertoire est atteint via +une directive Alias ou un lien +symbolique, le chemin d’URL et le chemin du système de fichiers diffèrent, et la +directive RewriteBase doit être +définie avec le chemin d’URL.
      • + +
      • Applications de sous-répertoire : Avec les cadriciels PHP, +il est courant de placer un fichier .htaccess dans un +sous-répertoire (par exemple /var/www/htdocs/myapp/) et de router +toutes les requêtes vers un contrôleur frontal :
      • +
      + +
      # Dans /var/www/htdocs/myapp/.htaccess
      +RewriteEngine On
      +RewriteBase "/myapp/"
      +RewriteCond "%{REQUEST_FILENAME}" !-f
      +RewriteCond "%{REQUEST_FILENAME}" !-d
      +RewriteRule "^(.*)$" "index.php" [L]
      + + +
      Dans ce cas particulier — routage de toutes les requêtes qui ne +correspondent pas vers un contrôleur frontal — la directive FallbackResource est une alternative à +mod_rewrite plus simple et plus efficace.
      + +

      Sans la ligne RewriteBase "/myapp/", l’URL réécrit risque de se +résoudre incorrectement, car mod_rewrite ajouterait comme +préfixe le chemin du système de fichiers au lieu du chemin d’URL.

      + +

      Si vous utilisez des URLs absolus (commençant par / ou +http://) dans vos substitutions, RewriteBase n’aura aucun effet, car elle ne +s’applique qu’aux substitutions relatives.

      + +
      top
      +
      +

      Le drapeau [L] et les boucles infinies

      + +

      Dans le contexte global du serveur, le drapeau [L] signifie +« arrêter le traitement du jeu de règles ». Dans le contexte des fichiers +.htaccess, il a une signification subtilement différente : +« arrêter le traitement du jeu de règles pour cette passe ». Une fois +la substitution effectuée, httpd traite à nouveau la requête depuis le début du +jeu de règles — tout en appliquant à nouveau les règles du fichier +.htaccess. Cela peut provoquer des boucles infinies.

      + +

      + Organigramme montrant la manière dont le drapeau [L] provoque une    boucle infinie dans un contexte de répertoire en déclenchant une    sous-requête qui réexécute le jeu de règles
      + Figure: Risque de boucle infinie avec le drapeau [L] dans un + contexte de répertoire +

      + +

      Considérez cette règle :

      + +
      # Dans .htaccess - risque de boucle infinie !
      +RewriteRule "^(.*)$" "/index.php?q=$1" [L]
      + + +

      À la première passe, une requête pour /hello est réécrite en +/index.php?q=hello. Puis la requête est traitée à nouveau, et +là, index.php correspond encore à ^(.*)$, et la +requête est réécrite en /index.php?q=index.php. Ce processus +continue jusqu’à ce que httpd atteigne sa limite de redirections internes et +renvoie une erreur 500. Le message suivant sera alors enregistré dans le journal +des erreurs :

      + +

      +AH00124: Request exceeded the limit of 10 internal redirects due to +probable configuration error. Use 'LimitInternalRecursion' to increase +the limit if necessary. Use 'LogLevel debug' to get a backtrace. +

      + +

      Il existe plusieurs méthodes pour interrompre la boucle infinie :

      + +

      Option 1 : utiliser le drapeau [END] (recommandé)

      + +
      RewriteRule "^(.*)$" "/index.php?q=$1" [END]
      + + +

      Le drapeau [END] (disponible depuis la version 2.3.9 de httpd) +arrête tout processus de réécriture ultérieur, y compris les passes +suivantes. Il s’agit de la méthode la plus propre pour prévenir les boucles +infinies.

      + +

      Option 2 : ajouter une condition pour empêcher le traitement des URLs déjà réécrits

      + +
      RewriteCond "%{REQUEST_FILENAME}" !-f
      +RewriteCond "%{REQUEST_FILENAME}" !-d
      +RewriteRule "^(.*)$" "/index.php?q=$1" [L]
      + + +

      Étant donné que index.php existe en tant que fichier, la +condition !-f fait que la règle est sautée à la seconde passe.

      + +

      Option 3 : vérifier la variable THE_REQUEST

      + +
      RewriteCond "%{THE_REQUEST}" "!index\.php"
      +RewriteRule "^(.*)$" "/index.php?q=$1" [L]
      + + +

      La variable %{THE_REQUEST} contient la requête originelle telle +qu’elle a été envoyée par le client et non modifiée par +mod_rewrite. Sa vérification empêche la règle de s’appliquer aux +URLs réécrits.

      + +
      top
      +
      +

      RewriteMap ne peut pas être déclarée +dans un fichier .htaccess

      + +

      La directive RewriteMap ne peut +être déclarée que dans un contexte de serveur virtuel ou global au serveur, pas +dans les fichiers .htaccess ou les sections <Directory>. Cependant, lorsqu’un mappage +est déclaré dans la configuration globale du serveur, vous pouvez +l’utiliser dans un fichier .htaccess :

      + +
      # Dans httpd.conf ou dans un VirtualHost
      +RewriteMap product2id "txt:/etc/apache2/productmap.txt"
      + + +
      # Dans .htaccess - utilisation du mappage déclaré ci-avant
      +RewriteEngine On
      +RewriteRule "^product/(.+)$" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
      + + +

      Cette restriction existe, car les fichiers .htaccess sont +analysés pour chaque requête, et la répétition de l’initialisation du mappage +(en particulier pour les types de mappage dbm:, dbd: +et prg:) serait d’un coût prohibitif en ressources.

      + +
      top
      +
      +

      Quels contextes peuvent accueillir des +règles de réécriture ?

      + +

      Les règles de réécriture sont prises en charge dans les contextes de répertoire (fichiers .htaccess et sections <Directory> et <If>).

      + +

      Bien que les règles de réécriture soient syntaxiquement autorisées dans les +sections <Location> et +<Files> (et dans leurs +équivalents avec expressions rationnelles), cela n’est pas pris en charge et ne +devrait jamais être nécessaire. Les substitutions relatives, en particulier, +sont susceptibles d’échouer dans ces contextes.

      + +

      Ces conteneurs modifient silencieusement le +comportement des réécritures

      +

      Placer une règle RewriteRule dans +une section <Directory>, +<If> ou <Location> — même dans un +<VirtualHost> dans la +configuration globale du serveur — fait silencieusement adopter un +comportement de contexte de répertoire. +Cela signifie que la barre oblique de tête est supprimée de l’URL avant la +comparaison avec le motif, que les substitutions déclenchent une redirection +interne (avec risque de boucle infinie), et que le drapeau [L] n’arrête plus strictement le +traitement — utilisez plutôt le drapeau [END].

      +
      + +
      top
      +
      +

      Héritage des règles avec RewriteOptions

      + +

      Par défaut, les règles de mod_rewrite ne sont pas +héritées par les sous-répertoires. Si vous définissez des règles dans +/var/www/htdocs/.htaccess, elles ne s’appliqueront qu’au +répertoire correspondant. Un fichier .htaccess dans un +sous-répertoire contient initial un jeu de règles initial vide, à moins que vous +n’activiez explicitement l’héritage.

      + +

      La directive RewriteOptions +permet d’effectuer cette activation :

      + +
      +
      RewriteOptions Inherit
      +
      Les règles du contexte parent sont ajoutées à la fin du jeu de règles de +l’enfant. Le traitement des règles de l’enfant est effectué en premier, suivi du +traitement des règles du parent. Utilisez cette fonctionnalité lorsqu’un +sous-répertoire doit ajouter ses propre règles, tout en gardant actives les +règles du parent.
      + +
      RewriteOptions InheritBefore
      +
      Identique à Inherit, excepté que les règles du parent sont +traitées avant celles de l’enfant. Cela s’avère utile lorsque le parent définit +un motif de contrôleur frontal et que l’enfant doit ajouter des exceptions. +Disponible depuis la version 2.4.8 de httpd.
      + + +
      RewriteOptions InheritDown
      +
      Spécifiez cette option dans le parent pour que tous les contextes enfant +héritent des règles du parent sans avoir à spécifier Inherit. +Disponible depuis la version 2.4.8 de httpd.
      + +
      RewriteOptions InheritDownBefore
      +
      Identique à InheritDown, excepté que les règles du parent sont +traitées avant celles des enfants. Disponible depuis la version 2.4.8 de httpd.
      + +
      RewriteOptions IgnoreInherit
      +
      Spécifiez cette option dans le contexte d’un enfant pour que ce dernier +renonce à l’héritage qui avait été forcé par l’option InheritDown +d’un parent. Disponible depuis la version 2.4.8 de httpd.
      + +
      RewriteOptions MergeBase
      +
      Quand l’héritage est activé, la directive RewriteBase de chaque +contexte s’applique aux règles définies dans ce contexte, au lieu que la +directive RewriteBase de l’enfant s’applique à toutes les règles +héritées. Disponible depuis la version 2.4.26 de httpd.
      +
      + +
      top
      +
      +

      Débogage des règles de réécriture dans les +fichiers .htaccess

      + +

      Lorsque les règles de réécriture dans les fichiers .htaccess ne +fonctionnent pas comme vous le souhaitez, le journal des réécritures est votre +meilleur ami. Activez-le avec le niveau approprié :

      + +
      LogLevel alert rewrite:trace3
      + + +

      Avec cette directive, le journal des erreurs montre exactement comment chaque +règle est traitée — à quoi les motifs ont été comparés, les conditions ont-elles +été satisfaites ou non et quelles substitutions ont été effectuées. Le +comportement du contexte de répertoire et la suppression d’une partie du +chemin sera visible dans ces entrées du journal.

      + +
      ne conservez pas à « trace » le niveau de journalisation sur un +serveur en production. Il génère en effet un grand volume de données en sortie +et affecte les performances.
      + +
      top
      +
      +

      Mise en cache des « 301 redirects » au niveau du +navigateur

      + +

      Quand vous renvoyez une redirection 301 Moved Permanently (via +[R=301] ou Redirect permanent), le navigateur est autorisé à mettre en cache +cette réponse indéfiniment. Cela signifie que même lorsque vous aurez corrigé +une règle de redirection incorrecte dans votre configuration, les clients qui +font à nouveau la même requête pourront se voir redirigés vers l’ancienne +destination (incorrecte) sans jamais contacter à nouveau votre serveur.

      + +

      Lors d’un débogage de règles de redirection, utilisez [R=302] +(redirection temporaire) à la place de [R=301]. Ne repassez à 301 +que lorsque vous avez confirmé que la règle est correcte. Si vous avez déjà +renvoyé un code 301, les clients affectés devront vider le cache de leur +navigateur (ou utiliser une fenêtre privée/incognito) pour voir un comportement +correct.

      + +
      Les moteurs de recherche mettent aussi en cache les redirections 301. Un +code 301 incorrect peut prendre des jours ou des semaines avant d’être +réexploré, même après que la configuration a été corrigée. C’est une autre +raison pour laquelle il vaut mieux faire ses tests avec un code 302.
      + +

      Langues Disponibles:  de  |  en  | diff --git a/docs/manual/rewrite/htaccess.xml b/docs/manual/rewrite/htaccess.xml index 5db5037db3b..00bbe7a4cd9 100644 --- a/docs/manual/rewrite/htaccess.xml +++ b/docs/manual/rewrite/htaccess.xml @@ -101,6 +101,16 @@ In .htaccess context, the directory prefix is products/widget - no leading slash, no /app/ prefix.

      +

      + Flowchart showing the path stripping, substitution,
+          and RewriteBase pipeline in per-directory context, with
+          three outcomes: relative path (RewriteBase prepended),
+          absolute path (used as-is), and absolute URI (external
+          redirect)
      + Figure: Per-directory path stripping and RewriteBase pipeline +

      +

      This means you must write your patterns differently depending on where the rule lives:

      @@ -215,6 +225,14 @@ After the substitution is made, Apache re-processes the request from the top - including re-applying the .htaccess rules. This can lead to infinite loops.

      +

      + Flowchart showing how the [L] flag causes looping in
+          per-directory context by triggering a subrequest that
+          re-enters the ruleset
      + Figure: Per-directory [L] flag looping behavior +

      +

      Consider this rule:

      diff --git a/docs/manual/rewrite/htaccess.xml.de b/docs/manual/rewrite/htaccess.xml.de index cc92862c395..d37effec258 100644 --- a/docs/manual/rewrite/htaccess.xml.de +++ b/docs/manual/rewrite/htaccess.xml.de @@ -1,7 +1,7 @@ - + + + @@ -25,26 +25,439 @@ Rewrite -mod_rewrite et les fichiers .htaccess +Réécritures au niveau répertoire -

      Ce document est un complément de la documentation de référence du module -mod_rewrite. Il décrit les changements apportés aux règles -lorsqu'on utilise mod_rewrite dans les fichiers .htaccess, et -comment travailler avec ces changements.

      +

      Utiliser mod_rewrite dans les fichiers +.htaccess est une des configurations dans un contexte de répertoire les plus courantes — et les +plus sujettes à confusion. Ce document expose les principales différences entre +l’utilisation de règles de réécriture dans un contexte global au serveur et leur +utilisation dans les fichiers .htaccess, et fournit un guide +pratique pour éviter les pièges les plus courants.

      + +

      Pour des détails techniques de bas niveau à propos de la manière dont +mod_rewrite traite les règles dans un contexte de répertoire, +voir le document Détails techniques.

      Documentation du module mod_rewrite Introduction à mod_rewrite Redirection et remise en correspondance - Serveurs virtuels -Serveurs mandataires Utilisation de RewriteMap -Techniques avancées Quand ne pas utiliser mod_rewrite +Drapeaux de RewriteRule +Détails techniques +Qu’est-ce qui est +comparé ? + +
      Prérequis : AllowOverride + +

      Pour que des directives de mod_rewrite dans un fichier +.htaccess puissent être traitées, la configuration du serveur doit +tout d’abord les autoriser de la manière suivante :

      + + +<Directory "/var/www/htdocs"> + AllowOverride FileInfo +</Directory> + + +

      Si au minimum AllowOverride FileInfo (ou AllowOverride +All) n’est pas présente, toute directive de mod_rewrite +dans les fichiers .htaccess sera silencieusement ignorée. Si vos +règles semblent ne pas fonctionner, il s’agit de la première chose à vérifier.

      + +

      En outre, soit Options FollowSymLinks, soit Options +SymLinksIfOwnerMatch doit être activée pour le répertoire en question. +Comme une règle RewriteRule peut +associer un URL à un chemin arbitraire du système de fichiers +— fonctionnellement équivalent à un lien symbolique +— mod_rewrite refusera d’opérer dans un contexte de répertoire +si aucune de ces options n’est définie. Vous verrez alors l’erreur suivante :

      + + +AH00670: Options FollowSymLinks and SymLinksIfOwnerMatch are both off, +so the RewriteRule directive is also forbidden due to its similar +ability to circumvent directory restrictions + + +

      Cette restriction s’applique aux fichiers .htaccess et aux +sections Directory.

      + +
      + +
      Quel URL la règle voit-elle ? + +

      Dans un contexte de serveur virtuel ou global au serveur, le motif de la +règle RewriteRule est comparé à +l’ensemble du chemin d’URL, en commençant par une barre oblique. Dans un +contexte de fichier .htaccess, le préfixe du répertoire est +supprimé.

      + +

      Par exemple, si votre fichier .htaccess est dans +/var/www/htdocs/app/ et si une requête arrive pour +/app/products/widget, la règle RewriteRule ne voit que +products/widget — pas de barre oblique en tête, pas de préfixe +/app/.

      + +

      + Organigramme montrant la suppression du chemin, la substitution
+	  et le pipeline de RewriteBase dans un contexte de répertoire, avec
+	  trois résultats : un chemin relatif (préfixé par RewriteBase), un
+	  chemin absolu (utilisé tel quel) et un URI absolu (redirection
+	  externe)
      + Figure : Suppression du chemin dans un contexte de répertoire + et pipeline de RewriteBase +

      + +

      Cela signifie que vous devez écrire vos motifs différemment en fonction de +l’emplacement des règles :

      + + + + + + + + + + + + + + +
      Emplacement de la règleRègle
      Section VirtualHostRewriteRule "^/app/products/(.+)$" "/app/shop.php?item=$1"
      .htaccess dans /var/www/htdocs/app/RewriteRule "^products/(.+)$" "shop.php?item=$1"
      + +

      Notez que la version pour .htaccess n’a de barre oblique de tête +ni dans le motif, ni dans la substitution. Il s’agit de la source de confusion +la plus courante avec la réécriture dans un contexte de répertoire.

      + +

      Lorsqu’une substitution est effectuée dans un contexte de répertoire, httpd +génère une nouvelle sous-requête interne avec l’URL réécrit en redémarrant le +traitement de la requête depuis le début. Si la substitution est un chemin +relatif, la directive RewriteBase +détermine le préfixe à ajouter au chemin d’URL. Ce mécanisme de sous-requête +peut aussi être à l’origine d’un bouclage infini des règles — voir ci-après.

      + + +Ne faites pas commencer vos motifs de .htaccess avec +une barre oblique +

      Étant donné que le préfixe du répertoire (y compris la barre oblique de fin) +est supprimé avant la mise en correspondance, les motifs dans un contexte de répertoire ne correspondront +jamais avec une adresse commençant par une barre oblique. Un motif +commençant par ^/ ne correspondra jamais dans ce contexte. Une +règle telle que RewriteRule "^/foo" ... placée dans un fichier +.htaccess échouera silencieusement à s’appliquer à quelque requête +que ce soit.

      +
      + +

      Si vous devez faire une recherche de correspondance avec le chemin d’URL +original complet (y compris le préfixe de répertoire), utilisez +%{REQUEST_URI} dans une directive RewriteCond :

      + + +RewriteCond "%{REQUEST_URI}" "^/admin/" +RewriteRule "^.*$" "-" [F] + + +
      + +
      Quand avez-vous besoin de RewriteBase ? + +

      Quand mod_rewrite effectue une substitution dans un fichier +.htaccess, il doit retransformer le résultat relatif en un chemin +d’URL complet. La directive RewriteBase lui indique quel préfixe il doit +ajouter.

      + +

      Par défaut, RewriteBase est +définie avec le chemin physique du fichier .htaccess. Dans la +plupart des cas, cela correspond aux attentes, et vous n’avez pas besoin de la +définir explicitement. Il y a cependant des situations où vous devrez le faire :

      + +
        +
      • Alias ou lien symbolique : Si le répertoire est atteint via +une directive Alias ou un lien +symbolique, le chemin d’URL et le chemin du système de fichiers diffèrent, et la +directive RewriteBase doit être +définie avec le chemin d’URL.
      • + +
      • Applications de sous-répertoire : Avec les cadriciels PHP, +il est courant de placer un fichier .htaccess dans un +sous-répertoire (par exemple /var/www/htdocs/myapp/) et de router +toutes les requêtes vers un contrôleur frontal :
      • +
      + + +# Dans /var/www/htdocs/myapp/.htaccess +RewriteEngine On +RewriteBase "/myapp/" +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "^(.*)$" "index.php" [L] + + +Dans ce cas particulier — routage de toutes les requêtes qui ne +correspondent pas vers un contrôleur frontal — la directive FallbackResource est une alternative à +mod_rewrite plus simple et plus efficace. + +

      Sans la ligne RewriteBase "/myapp/", l’URL réécrit risque de se +résoudre incorrectement, car mod_rewrite ajouterait comme +préfixe le chemin du système de fichiers au lieu du chemin d’URL.

      + +

      Si vous utilisez des URLs absolus (commençant par / ou +http://) dans vos substitutions, RewriteBase n’aura aucun effet, car elle ne +s’applique qu’aux substitutions relatives.

      + +
      + +
      Le drapeau [L] et les boucles infinies + +

      Dans le contexte global du serveur, le drapeau [L] signifie +« arrêter le traitement du jeu de règles ». Dans le contexte des fichiers +.htaccess, il a une signification subtilement différente : +« arrêter le traitement du jeu de règles pour cette passe ». Une fois +la substitution effectuée, httpd traite à nouveau la requête depuis le début du +jeu de règles — tout en appliquant à nouveau les règles du fichier +.htaccess. Cela peut provoquer des boucles infinies.

      + +

      + Organigramme montrant la manière dont le drapeau [L] provoque une
+	  boucle infinie dans un contexte de répertoire en déclenchant une
+	  sous-requête qui réexécute le jeu de règles
      + Figure: Risque de boucle infinie avec le drapeau [L] dans un + contexte de répertoire +

      + +

      Considérez cette règle :

      + + +# Dans .htaccess - risque de boucle infinie ! +RewriteRule "^(.*)$" "/index.php?q=$1" [L] + + +

      À la première passe, une requête pour /hello est réécrite en +/index.php?q=hello. Puis la requête est traitée à nouveau, et +là, index.php correspond encore à ^(.*)$, et la +requête est réécrite en /index.php?q=index.php. Ce processus +continue jusqu’à ce que httpd atteigne sa limite de redirections internes et +renvoie une erreur 500. Le message suivant sera alors enregistré dans le journal +des erreurs :

      + + +AH00124: Request exceeded the limit of 10 internal redirects due to +probable configuration error. Use 'LimitInternalRecursion' to increase +the limit if necessary. Use 'LogLevel debug' to get a backtrace. + + +

      Il existe plusieurs méthodes pour interrompre la boucle infinie :

      + +

      Option 1 : utiliser le drapeau [END] (recommandé)

      + + +RewriteRule "^(.*)$" "/index.php?q=$1" [END] + + +

      Le drapeau [END] (disponible depuis la version 2.3.9 de httpd) +arrête tout processus de réécriture ultérieur, y compris les passes +suivantes. Il s’agit de la méthode la plus propre pour prévenir les boucles +infinies.

      + +

      Option 2 : ajouter une condition pour empêcher le traitement des URLs déjà réécrits

      + + +RewriteCond "%{REQUEST_FILENAME}" !-f +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteRule "^(.*)$" "/index.php?q=$1" [L] + + +

      Étant donné que index.php existe en tant que fichier, la +condition !-f fait que la règle est sautée à la seconde passe.

      + +

      Option 3 : vérifier la variable THE_REQUEST

      + + +RewriteCond "%{THE_REQUEST}" "!index\.php" +RewriteRule "^(.*)$" "/index.php?q=$1" [L] + + +

      La variable %{THE_REQUEST} contient la requête originelle telle +qu’elle a été envoyée par le client et non modifiée par +mod_rewrite. Sa vérification empêche la règle de s’appliquer aux +URLs réécrits.

      + +
      + +
      RewriteMap ne peut pas être déclarée +dans un fichier .htaccess + +

      La directive RewriteMap ne peut +être déclarée que dans un contexte de serveur virtuel ou global au serveur, pas +dans les fichiers .htaccess ou les sections Directory. Cependant, lorsqu’un mappage +est déclaré dans la configuration globale du serveur, vous pouvez +l’utiliser dans un fichier .htaccess :

      + + +# Dans httpd.conf ou dans un VirtualHost +RewriteMap product2id "txt:/etc/apache2/productmap.txt" + + + +# Dans .htaccess - utilisation du mappage déclaré ci-avant +RewriteEngine On +RewriteRule "^product/(.+)$" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT] + + +

      Cette restriction existe, car les fichiers .htaccess sont +analysés pour chaque requête, et la répétition de l’initialisation du mappage +(en particulier pour les types de mappage dbm:, dbd: +et prg:) serait d’un coût prohibitif en ressources.

      + +
      + +
      Quels contextes peuvent accueillir des +règles de réécriture ? + +

      Les règles de réécriture sont prises en charge dans les contextes de répertoire (fichiers .htaccess et sections Directory et If).

      + +

      Bien que les règles de réécriture soient syntaxiquement autorisées dans les +sections Location et +Files (et dans leurs +équivalents avec expressions rationnelles), cela n’est pas pris en charge et ne +devrait jamais être nécessaire. Les substitutions relatives, en particulier, +sont susceptibles d’échouer dans ces contextes.

      + +Ces conteneurs modifient silencieusement le +comportement des réécritures +

      Placer une règle RewriteRule dans +une section Directory, +If ou Location — même dans un +VirtualHost dans la +configuration globale du serveur — fait silencieusement adopter un +comportement de contexte de répertoire. +Cela signifie que la barre oblique de tête est supprimée de l’URL avant la +comparaison avec le motif, que les substitutions déclenchent une redirection +interne (avec risque de boucle infinie), et que le drapeau [L] n’arrête plus strictement le +traitement — utilisez plutôt le drapeau [END].

      +
      + +
      + +
      Héritage des règles avec RewriteOptions + +

      Par défaut, les règles de mod_rewrite ne sont pas +héritées par les sous-répertoires. Si vous définissez des règles dans +/var/www/htdocs/.htaccess, elles ne s’appliqueront qu’au +répertoire correspondant. Un fichier .htaccess dans un +sous-répertoire contient initial un jeu de règles initial vide, à moins que vous +n’activiez explicitement l’héritage.

      + +

      La directive RewriteOptions +permet d’effectuer cette activation :

      + +
      +
      RewriteOptions Inherit
      +
      Les règles du contexte parent sont ajoutées à la fin du jeu de règles de +l’enfant. Le traitement des règles de l’enfant est effectué en premier, suivi du +traitement des règles du parent. Utilisez cette fonctionnalité lorsqu’un +sous-répertoire doit ajouter ses propre règles, tout en gardant actives les +règles du parent.
      + +
      RewriteOptions InheritBefore
      +
      Identique à Inherit, excepté que les règles du parent sont +traitées avant celles de l’enfant. Cela s’avère utile lorsque le parent définit +un motif de contrôleur frontal et que l’enfant doit ajouter des exceptions. +Disponible depuis la version 2.4.8 de httpd.
      + + +
      RewriteOptions InheritDown
      +
      Spécifiez cette option dans le parent pour que tous les contextes enfant +héritent des règles du parent sans avoir à spécifier Inherit. +Disponible depuis la version 2.4.8 de httpd.
      + +
      RewriteOptions InheritDownBefore
      +
      Identique à InheritDown, excepté que les règles du parent sont +traitées avant celles des enfants. Disponible depuis la version 2.4.8 de httpd.
      + +
      RewriteOptions IgnoreInherit
      +
      Spécifiez cette option dans le contexte d’un enfant pour que ce dernier +renonce à l’héritage qui avait été forcé par l’option InheritDown +d’un parent. Disponible depuis la version 2.4.8 de httpd.
      + +
      RewriteOptions MergeBase
      +
      Quand l’héritage est activé, la directive RewriteBase de chaque +contexte s’applique aux règles définies dans ce contexte, au lieu que la +directive RewriteBase de l’enfant s’applique à toutes les règles +héritées. Disponible depuis la version 2.4.26 de httpd.
      +
      + +
      + +
      Débogage des règles de réécriture dans les +fichiers .htaccess + +

      Lorsque les règles de réécriture dans les fichiers .htaccess ne +fonctionnent pas comme vous le souhaitez, le journal des réécritures est votre +meilleur ami. Activez-le avec le niveau approprié :

      + + +LogLevel alert rewrite:trace3 + + +

      Avec cette directive, le journal des erreurs montre exactement comment chaque +règle est traitée — à quoi les motifs ont été comparés, les conditions ont-elles +été satisfaites ou non et quelles substitutions ont été effectuées. Le +comportement du contexte de répertoire et la suppression d’une partie du +chemin sera visible dans ces entrées du journal.

      + +ne conservez pas à « trace » le niveau de journalisation sur un +serveur en production. Il génère en effet un grand volume de données en sortie +et affecte les performances. + +
      + +
      Mise en cache des « 301 redirects » au niveau du +navigateur + +

      Quand vous renvoyez une redirection 301 Moved Permanently (via +[R=301] ou Redirect permanent), le navigateur est autorisé à mettre en cache +cette réponse indéfiniment. Cela signifie que même lorsque vous aurez corrigé +une règle de redirection incorrecte dans votre configuration, les clients qui +font à nouveau la même requête pourront se voir redirigés vers l’ancienne +destination (incorrecte) sans jamais contacter à nouveau votre serveur.

      + +

      Lors d’un débogage de règles de redirection, utilisez [R=302] +(redirection temporaire) à la place de [R=301]. Ne repassez à 301 +que lorsque vous avez confirmé que la règle est correcte. Si vous avez déjà +renvoyé un code 301, les clients affectés devront vider le cache de leur +navigateur (ou utiliser une fenêtre privée/incognito) pour voir un comportement +correct.

      + +Les moteurs de recherche mettent aussi en cache les redirections 301. Un +code 301 incorrect peut prendre des jours ou des semaines avant d’être +réexploré, même après que la configuration a été corrigée. C’est une autre +raison pour laquelle il vaut mieux faire ses tests avec un code 302. + +
      diff --git a/docs/manual/rewrite/htaccess.xml.ja b/docs/manual/rewrite/htaccess.xml.ja index 2b19c963e44..34a31531dab 100644 --- a/docs/manual/rewrite/htaccess.xml.ja +++ b/docs/manual/rewrite/htaccess.xml.ja @@ -1,7 +1,7 @@ - + + + + + + + @@ -40,15 +40,14 @@ pieds. Documentation du module mod_rewrite - -Redirection and remise en +Redirection et remise en correspondance -Contrôle d'accès +Réécritures par répertoire +Drapeaux de RewriteRule Serveurs virtuels -Mise en cache Utilisation de RewriteMap -Techniques avancées Quand ne pas utiliser mod_rewrite +Détails techniques
      Introduction

      Le module Apache mod_rewrite est un module puissant @@ -78,17 +77,32 @@ le débogage des problèmes avec la configuration de mod_rewrite est à ce prix car vous verrez alors exactement comment chaque règle est traitée.

      +

      + Organigramme
+simplifié du fonctionnement de mod_rewrite : arrivée de la requête, vérification
+RewriteEngine On, traitement des règles dans l’ordre, test de correspondance du
+motif et des RewriteCond, application des substitutions si ces deux tests sont
+positifs, arrêt du traitement des règles si un drapeau L ou END est défini,
+sinon traitement de la règle suivante
      + Figure : Présentation simplifiée de la manière dont +mod_rewrite traite une requête. Voir Détails techniques pour une description complète du +traitement avec les phases, les drapeaux et le bouclage. +

      +
      Expressions rationnelles -

      mod_rewrite utilise le vocabulaire des Expressions rationnelles compatibles Perl. +

      mod_rewrite utilise le vocabulaire des Expressions +rationnelles compatibles avec Perl à l’aide de la bibliothèque PCRE2. Ce document n'a pas pour prétention d'être une référence détaillée des -expressions rationnelles. A cet effet, nous recommandons les pages de manuel de PCRE, la page de manuel des -expressions rationnelles Perl, et l'ouvrage documentation de +PCRE2, la page de manuel des +expressions rationnelles de Perl, et l'ouvrage Mastering Regular Expressions, par Jeffrey Friedl (la troisième édition date de 2006, mais la syntaxe des expressions rationnelles n'a pas vraiment @@ -160,18 +174,29 @@ correspond à tout caractère ne faisant pas partie de la classe

    -

    Avec mod_rewrite, le caractère ! peut +

    Le caractère ! (Not) peut préfixer une expression rationnelle afin d'en exprimer la négation. Autrement dit, une chaîne ne correspondra que si elle ne correspond pas à l'expression située après le !.

    +

    Notez que lorsqu’on utilise ! pour inverser un motif, les références arrières (par exemple $1, +$2) ne sont pas disponibles, car le motif ne correspond plus.

    + +

    La règle suivante, par exemple, redirige toute requête qui ne commence +pas par /admin

    + + +RewriteRule "!^/admin" "/xyz.html" [R,L] + +
    Disponibilité des références arrières dans les expressions rationnelles

    Vous devez vous souvenir d'une chose importante : chaque fois - que vous utilisez des parenthèses dans un Modèle ou dans + que vous utilisez des parenthèses dans un Motif ou dans un des modèles de conditions, des références arrières sont créées en interne et peuvent être rappelées via les chaînes $N et %N (voir ci-dessous). Ces @@ -197,15 +222,23 @@ arrières dans les expressions rationnelles elles vous paraissent un peu exotiques au premier abord.

    - Flux des comparaisons effectuées par les règles RewriteRule
-      et RewriteCond
    + Diagramme montrant la
+manière dont les références arrières circulent entre les RewriteRule et les
+RewriteCond : $1-$9 capturent des groupes issus des motifs RewriteRule, %1-%9
+capturent des groupes issus des motifs des chaînes à tester (ou TestStrings) de
+RewriteCond, les deux étant disponibles dans les chaînes de substitution et dans
+les chaînes à tester de RewriteCond subséquentes
    Figure 1 : Le cheminement d'une référence arrière à travers une règle.
    - Dans cet exemple, une requête pour /test/1234 serait + Dans cet exemple, une requête pour /test/1234 vers l’hôte admin.example.com serait transformée en - /admin.foo?page=test&id=1234&host=admin.example.com. + /admin.foo?page=test&id=1234&host=admin.example.com, + sous réserve que %{DOCUMENT_ROOT}/test ne soit pas un fichier + existant.

    +

    Voir aussi Détails techniques + pour un diagramme montrant le cheminement des références arrières avec des + conditions multiples.

    @@ -215,28 +248,48 @@ arrières dans les expressions rationnelles module="mod_rewrite">RewriteRule est constituée de trois arguments séparés par des espaces. Les arguments sont :

      -
    1. Modèle: le modèle des URLs auxquelles la règle doit +
    2. Motif: le motif des URLs auxquelles la règle doit s'appliquer;
    3. Substitution: vers quoi la requête correspondante doit être transformée;
    4. [drapeaux]: options affectant la requête réécrite.
    -

    Le Modèle est une expression -rationnelle. Au sein de la première règle de réécriture, ou jusqu'à -ce qu'une substitution survienne, elle est comparée au chemin de -l'URL de la requête entrante (la -partie située après le nom d'hôte mais avant tout point d'interrogation -qui indique le début d'une chaîne de paramètres de -requête) ou, dans un contexte de répertoire, au chemin de la -requête relativement au répertoire pour lequel la -règle est définie. Lorsqu'une substitution a eu lieu, les -règles suivantes effectuent leurs comparaisons par rapport à la valeur -substituée.

    +

    Le Motif est une expression +rationnelle. Dans un contexte de serveur virtuel ou de serveur global, il +est comparé au chemin d’URL %-décodé +de la requête entrante — la partie après le nom d’hôte et le port, en +excluant la chaîne de paramètres (par exemple /app/index.html). +Dans un contexte de répertoire, le motif +est comparé au chemin de la requête relatif au répertoire pour lequel la règle +est définie (avec le préfixe de répertoire supprimé — voir Réécritures par répertoire pour les +détails). +

    + +

    Lorsqu’une substitution a été effectuée, toute règle qui suit est comparée à +la valeur substituée.

    + +

    Le Motif n’est comparé qu’au chemin d’URL — à l’exclusion +des nom d’hôte, port ou chaîne de paramètres. Pour une comparaison incluant ces +derniers, utilisez une condition RewriteCond avec les variables +%{HTTP_HOST}, %{SERVER_PORT} ou +%{QUERY_STRING}, respectivement.

    + +mod_rewrite opère exclusivement sur le chemin d’URL et les +en-têtes HTTP. Il ne peut pas inspecter le corps de la requête (par exemple, les +données POST). Si vous devez prendre des décisions de routage en fonction du +contenu du corps de la requête, traitez le problème à l’aide de la logique de +votre application ou utilisez un module tel que mod_request +associé à un filtre personnalisé.

    Syntaxe de la directive RewriteRule
    + alt="Diagramme annoté pour la syntaxe de la directive RewriteRule montrant +trois composants : le motif (une expression rationnelle mise en correspondance +avec le chemin d’URL, la substitution (l’URL ou le chemin de remplacement) et +des drapeaux facultatifs entourés de crochets" />
    Figure 2 : Syntaxe de la directive RewriteRule.

    @@ -284,13 +337,13 @@ le cas avec 2 (par exemple, il n'y a pas de répertoire

    La chaîne de Substitution peut aussi contenir des références arrières vers des parties du chemin d'URL entrant -correspondant au Modèle. Considérons ce qui suit :

    +correspondant au Motif. Considérons ce qui suit :

    RewriteRule "^/produits/(.*)/view$" "/var/web/produitsdb/$1"

    La variable $1 sera remplacée par tout texte correspondant à l'expression située entre les parenthèses dans le -Modèle. Par exemple, une requête pour +Motif. Par exemple, une requête pour http://example.com/produits/r14df/vue correspondra au chemin /var/web/produitsdb/r14df.

    @@ -332,7 +385,10 @@ correspondance est évaluée.

    Syntaxe de la directive RewriteCond
    + alt="Diagramme annoté pour la syntaxe de la directive RewriteCond montrant +deux composants : la chaîne à tester ou TestString (une variable ou du texte à +tester) et le motif de condition ou CondPattern (expression rationnelle ou +comparaison à évaluer) avec des drapeaux facultatifs entourés de crochets" />
    Figure 3 : Syntaxe de la directive RewriteCond

    @@ -390,25 +446,98 @@ supplémentaire sur RewriteMap.

    Fichiers .htaccess -

    La réécriture est en général définie au niveau de la configuration du -serveur principal (en dehors de toute section Directory) ou dans une section VirtualHost. Il s'agit là de la -manière la plus simple de mettre en oeuvre la réécriture et nous la -recommandons. Il est possible, cependant, de mettre en oeuvre la -réécriture au sein d'une section Directory ou d'un fichier .htaccess ; ce type de -configuration est cependant plus complexe. Cette technique est appelée -réécriture par répertoire.

    - -

    La principale différence avec les réécritures au niveau du serveur réside -dans le fait que le préfixe du chemin du répertoire contenant le fichier -.htaccess est supprimé avant la mise en correspondance dans -la règle RewriteRule. De -plus, on doit utiliser la directive RewriteBase pour s'assurer que la -requête est correctement mise en correspondance.

    +

    Il est possible d’utiliser des règles de réécriture dans un contexte de répertoire (fichiers .htaccess et sections Directory), mais dans ce cas, les +règles se comportent différemment — en particulier, le préfixe du répertoire est +supprimé de l’URL avant la recherche de correspondance. Voir le document Réécritures dans un contexte de +répertoire pour une explication détaillée. Notez que les sections If et Location adoptent aussi le comportement du contexte +de répertoire — voir Quels +contextes prennent en charge les règles de réécriture ?.

    + +
    + +
    Considérations en matière de sécurité + +

    mod_rewrite est un outil de manipulation d’URL puissant, +mais qui dit puissance dit risque d’erreurs liées à la sécurité. Cette section +met en lumière les pièges en matière de sécurité courants à éviter lors de +la rédaction de règles de réécritures.

    + +
    Redirections ouvertes + +

    Si une règle RewriteRule +construit un URL de redirection en utilisant une entrée utilisateur non validée, +un attaquant pourra fabriquer un lien qui redirige les visiteurs vers un site +malveillant semblant provenir de votre domaine. Cette vulnérabilité est connue +sous le nom de redirection ouverte.

    + +

    Par exemple, cette règle est dangereuse :

    + + +# DANGEREUX - permet une redirection ouverte +RewriteRule "^/redirect" "%{QUERY_STRING}" [R,L] + + +

    Un attaquant pourrait en effet utiliser +https://yoursite.com/redirect?https://evil.com pour rediriger les +utilisateurs vers un site malveillant. Assurez vous de toujours valider ou +contraindre les cibles de redirection. Si la destination doit être sur votre +propre site, assurez vous que la substitution commence par / (un +chemin relatif) plutôt que de permettre à l’utilisateur d’entrer un URL complet.

    + +
    + +
    Server-Side Request Forgery (SSRF) + +

    Lorsqu’on utilise la drapeau [P] (proxy), +mod_rewrite fait que le serveur +effectue une requête HTTP vers l’URL de substitution de la part du client. Si +une partie de cet URL est dérivée de l’entrée du client — références arrières, +chaînes de paramètres ou en-têtes — un attaquant pourrait faire que votre +serveur effectue des requêtes vers des services internes arbitraires ou des +hôtes externes.

    + +

    Par exemple :

    + + +# DANGEREUX - l’utilisateur contrôle la cible du mandataire +RewriteCond "%{QUERY_STRING}" "target=(.+)" +RewriteRule "^/fetch" "http://%1" [P] + + +

    Un attaquant pourrait utiliser cette configuration pour tester des services +réseau internes qui autrement ne seraient pas accessibles depuis l’Internet. +Utilisez toujours un nom d’hôte fixe dans les cibles de mandataire et limitez +les références arrières à la partie chemin seulement.

    + +
    + +
    Traversée de chemin + +

    Des règles de réécriture qui associent directement des composants du chemin +fournis par l’utilisateur au système de fichier ouvrent la voie à des attaques +de traversée de chemin si l’entrée n’est pas correctement contrainte. Par +exemple :

    + + +# DANGEREUX - permet une traversée de chemin +RewriteRule "^/files/(.+)" "/var/data/$1" [L] + + +

    Une requête pour /files/../../etc/passwd pourrait accéder à des +fichiers en dehors du répertoire souhaité. Utilisez des motifs restreints dans +votre règle RewriteRule (par exemple +[a-zA-Z0-9_-]+ au lieu de .+), et utilisez les +protections intégrées d’Apache httpd (restrictions Options et Directory) pour une défense en profondeur.

    + +
    diff --git a/docs/manual/rewrite/intro.xml.ja b/docs/manual/rewrite/intro.xml.ja index f6884abdfb5..a98d8e0b968 100644 --- a/docs/manual/rewrite/intro.xml.ja +++ b/docs/manual/rewrite/intro.xml.ja @@ -1,7 +1,7 @@ - + + + + + @@ -37,22 +37,15 @@ correspondance une requête. Il contient de nombreux exemples d'utilisation courante de mod_rewrite avec une description détaillée de leur fonctionnement.

    -Vous devez vous attacher à comprendre le -fonctionnement des exemples, car la plupart d'entre eux ne -fonctionneront pas sur votre système si vous vous contentez de les -copier/coller dans vos fichiers de configuration. - Documentation du module mod_rewrite Introduction à mod_rewrite - -Contrôler l'accès +Réécritures par répertoire +Drapeaux des règles RewriteRule Serveurs virtuels -Serveurs mandataires Utilisation de RewriteMap -Techniques avancées Quand ne pas utiliser mod_rewrite +Détails techniques
    @@ -80,11 +73,239 @@ correspondance--> RewriteEngine on RewriteRule "^/foo\.html$" "/bar.html" [PT] + + + +
    + +
    + + Forcer HTTPS + +
    +
    Description :
    + +
    +

    Rediriger toutes les requêtes HTTP vers HTTPS. C’est un des + emplois les plus courants de mod_rewrite, mais dans la + plupart des cas, on y parvient d’une meilleur façon sans lui.

    +
    + +
    Solution :
    + +
    + +

    L’approche préférée utilise une directive Redirect dans un serveur virtuel HTTP + dédié :

    + + +<VirtualHost *:80> + ServerName www.example.com + Redirect permanent "/" "https://www.example.com/" +</VirtualHost> + +<VirtualHost *:443> + ServerName www.example.com + # ... emplacement de la configuration SSL +</VirtualHost> + + +
    + +
    Explication :
    + +
    +

    Si vous n’avez pas accès à la configuration du serveur et devez + utiliser un fichier .htaccess, mod_rewrite + sera l’outil approprié :

    + + +RewriteEngine On +RewriteCond "%{HTTPS}" !=on +RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L] + + +

    La variable %{HTTPS} est définie à on si + la connexion utilise SSL/TLS, et est vide ou à off dans le + cas contraire. Utiliser R=301 produit une redirection + permanente qui signale aux moteurs de recherche qu’ils doivent mettre + leur index à jour.

    + +

    Voir aussi le document Quand ne pas + utiliser mod_rewrite pour plus de discussions à propos de l’approche + Redirect.

    + + Derrière un répartiteur de charge ou un terminateur SSL +

    La variable %{HTTPS} n’est pas une variable + d’environnement à usage général — elle interroge directement + mod_ssl. Si la terminaison SSL/TLS est effectuée au + niveau d'un répartiteur de charge ou d'un mandataire inverse en amont, + mod_ssl ne gère pas la connexion et %{HTTPS} + indiquera toujours off, même si le client originel s’est + connecté en HTTPS.

    + +

    Dans cette situation, il faut plutôt consulter l’en-tête défini par le + mandataire en amont. La plupart des répartiteurs de charge définissent + X-Forwarded-Proto :

    +
    + + +RewriteEngine On +RewriteCond "%{HTTP:X-Forwarded-Proto}" =http [NC] +RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L] + + + +

    Ne faites confiance à X-Forwarded-Proto que si vous + contrôlez le mandataire en amont et qu'il écrase l'en-tête à chaque + requête. Un attaquant pourrait corrompre cet en-tête en se connectant + directement à votre serveur. Assurez-vous de restreindre l’accès de façon + que seul votre répartiteur de charge puisse atteindre le serveur dorsal, + ou utilisez mod_remoteip pour valider la source.

    +
    +
    +
    + + Exempter les requêtes de défi ACME de la redirection HTTPS + +
    +
    Description :
    + +
    +

    Vous avez forcé tout le trafic à s’effectuer en HTTPS (comme ci-avant), + mais votre client ACME (Let's Encrypt, Certbot, etc.) nécessite un accès + en HTTP à /.well-known/acme-challenge/ pour achever la + validation du domaine.

    +
    + +
    Solution :
    + +
    +

    Placer une exception avant la règle de redirection HTTPS :

    + + +RewriteEngine On +RewriteRule "^/\.well-known/acme-challenge/" - [L] +RewriteCond "%{HTTPS}" !=on +RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L] + +
    + +
    Explication :
    + +
    +

    La substitution matérialisée par un tiret (-) signifie + « ne pas réécrire ». En combinaison avec le drapeau [L], elle + arrête le traitement des règles pour toute requête correspondant au chemin + du défi ACME, permettant à cette dernière d’être servie en HTTP. Le + traitement de toutes les autres requêtes continue avec la règle suivante + et les redirige vers HTTPS de la manière habituelle.

    + +

    Si vous adoptez l’approche par la directive Redirect dans un serveur virtuel dédié au + port 80, utilisez les directives Alias et RedirectMatch à la place :

    + + +<VirtualHost *:80> + ServerName www.example.com + + # Permettre les défis ACME sur HTTP + Alias "/.well-known/acme-challenge/" "/var/www/acme/.well-known/acme-challenge/" + <Directory "/var/www/acme/.well-known/acme-challenge"> + Require all granted + </Directory> + + # Tout le reste est redirigé vers HTTPS + RedirectMatch permanent "^/(?!\.well-known/acme-challenge/)(.*)$" "https://www.example.com/$1" +</VirtualHost> + + +
    +
    + +
    + +
    + + Normalisation de la barre oblique de fin + +
    +
    Description :
    + +
    +

    Vous souhaitez que les URLs pour des répertoires se terminent toujours + par une barre oblique ou, au contraire, que ce ne soit jamais le cas. + Il s’agit d’un prérequis courant pour SEO et pour la gestion cohérente des + URLs par les applications web.

    +
    + +
    Solution :
    + +
    +

    Pour ajouter une barre oblique de fin aux URLs qui correspondent à des + répertoires :

    + + +RewriteCond "%{REQUEST_FILENAME}" -d +RewriteCond "%{REQUEST_URI}" "!/$" +RewriteRule "^(.*)$" "$1/" [R=301,L] + + +

    Pour supprimer la barre oblique de fin (sauf pour les véritables + répertoires) :

    + + +RewriteCond "%{REQUEST_FILENAME}" !-d +RewriteCond "%{REQUEST_URI}" "(.+)/$" +RewriteRule "^" "%1" [R=301,L] + + +
    + +
    Explication :
    + +
    +

    Le module mod_dir de httpd gère déjà les redirections + de barre oblique de fin pour les véritables répertoires lorsque la + directive DirectorySlash est + activée (elle l’est par défaut). Vous n’avez besoin que d’une règle de + mod_rewrite si vous souhaitez imposer un comportement + pour les barres obliques de fin pour les URLs qui ne correspondent pas à + de véritables répertoires sur disque, ou si vous voulez supprimer des + barres obliques de fin.

    +
    +
    + +
    + +
    + + Contrôleur frontal / Routage d’pplication + +

    La plupart des cadriciels web modernes routent toutes les requêtes vers un + seul point d’entrée : le contrôleur frontal (« front controller »). La + directive FallbackResource gère cela + plus simplement et efficacement que mod_rewrite. Voir le + document Quand ne pas utiliser + mod_rewrite pour l’approche recommandée.

    + +

    Si vous avez réellement besoin de mod_rewrite pour cela + (par exemple, pour ajouter des conditions plus complexes que « fichier non + existant »), consultez le document Réécritures par répertoire pour un + exemple annoté qui illustre aussi l’utilisation de la directive RewriteBase.

    + +
    +
    De l'ancien au nouveau (en externe) @@ -115,7 +336,7 @@ RewriteRule "^foo\.html$" "bar.html" [ -
    Discussion
    +
    Explication

    Dans l'exemple

    - - -
    - - - -
    - - De statique à dynamique - -
    -
    Description :
    - +
    Explication :
    -

    Comment transformer une page statique foo.html - en sa variante dynamique foo.cgi de manière - transparente, c'est à dire sans en avertir le - navigateur/utilisateur.

    -
    -
    Solution :
    - -
    -

    On réécrit simplement l'URL en script CGI et force le - gestionnaire de contenu à cgi-script de façon - à ce que le script s'exécute en tant que programme CGI. - Ainsi, une requête vers /~quux/foo.html conduit - en interne à l'invocation de - /~quux/foo.cgi.

    - - -RewriteEngine on -RewriteBase "/~quux/" -RewriteRule "^foo\.html$" "foo.cgi" [H=cgi-script] - +

    Pour une simple redirection vers un autre serveur, il est préférable + d’utiliser les directives Redirect ou RedirectMatch, car elles sont plus simples + et plus efficaces.

    @@ -224,10 +418,10 @@ RewriteRule "^foo\.html$" "foo.cgi" [H=cgi-script]
    Solution :
    -

    L'URL n'est réécrite en remplaçant l'ancienne extension par la +

    L’URL n’est réécrite en remplaçant l’ancienne extension par la nouvelle que si le fichier cible avec la nouvelle extension existe et - si le fichier originel avec l'ancienne extension n'existe pas. Sinon, - l'URL reste inchangée.

    + si le fichier originel avec l’ancienne extension n’existe pas. Sinon, + l’URL reste inchangée.

    @@ -245,7 +439,7 @@ RewriteRule "^foo\.html$" "foo.cgi" [H=cgi-script]
    -
    Discussion
    +
    Explication

    Cet exemple utilise une fonctionnalité souvent méconnue de mod_rewrite, en tirant avantage de l'ordre d'exécution du jeu de @@ -348,6 +542,16 @@ RewriteRule "^/?(.*)" "http://www.example.com/$1" [L,R,NE] possibles de example.com, vous pouvez utiliser le jeu de règles suivants :

    +

    Pour faire l’inverse — supprimer le préfixe www. — inversez la +condition :

    + + +RewriteCond "%{HTTP_HOST}" "^www\.(.+)$" [NC] +RewriteRule "^(.*)" "http://%1/$1" [L,R,NE] + + +

    Pour ajouter de manière générique www. à tout nom d’hôte :

    + RewriteCond "%{HTTP_HOST}" "!^www\." [NC] RewriteCond "%{HTTP_HOST}" "!^$" @@ -359,9 +563,26 @@ RewriteRule "^/?(.*)" "http://www.%{HTTP_HOST}/$1" [L,R,NE] .htaccess placé dans le répertoire défini par la directive DocumentRoot du serveur.

    -
    - + + +
    Explication :
    + +
    +

    Si vous avez accès à la configuration globale du serveur, une directive + Redirect dans un serveur virtuel dédié constitue + l’approche la plus propre. Mettre sous forme canonique le nom d’hôte + permet de s’assurer que les moteurs de recherche traiterons votre site + comme une seule entité, et évite les problèmes de portée de cookie qui + surviennent lorsqu’un même site est accessible sous plusieurs noms.

    +

    N’utilisez la directive If et mod_rewrite comme + compromis que si vous êtes contraint d’utiliser un fichier + .htaccess.

    +
    + +
    @@ -405,64 +626,14 @@ RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/dir2/$1" [L] RewriteRule "^" "-" [PT] - - -
    -
    +
    Explication :
    - Redirection vers des serveurs géographiquement distribués - -
    -
    Description :
    - -
    -

    Notre site web possède de nombreux miroirs, et nous voulons - rediriger les utilisateurs vers celui qui se situe dans le pays où - ils se trouvent.

    -
    - -
    Solution :
    - -
    -

    En consultant le nom d'hôte du client demandeur, on détermine le - pays dans lequel il se trouve. S'il est impossible d'effectuer une - recherche sur leur adresse IP, on se rabat sur un serveur par - défaut.

    -

    Nous allons utiliser une directive RewriteMap afin de construire une - liste des serveurs que nous voulons utiliser.

    - - -HostnameLookups on -RewriteEngine on -RewriteMap multiplex "txt:/path/to/map.mirrors" -RewriteCond "%{REMOTE_HOST}" "([a-z]+)$ [NC]" -RewriteRule "^/(.*)$" "${multiplex:%1|http://www.example.com/}$1" [R,L] - - - -## liste_miroirs -- Table de correspondance pays - serveurs
    -
    -de http://www.exemple.de/
    -uk http://www.exemple.uk/
    -com http://www.example.com/
    -##EOF## -
    -
    - -
    Discussion
    - Ce jeu de règles nécessite la définition à - on de la directive HostNameLookups, ce qui peut induire une - baisse de performance significative. - -

    La directive RewriteCond extrait la dernière - partie du nom d'hôte du client demandeur - le code du pays - et la - règle de réécriture qui suit utilise cette valeur pour rechercher le - serveur miroir approprié dans le fichier de correspondances.

    +

    Ce qui précède s’avère utile pendant les migrations lorsque le contenu + est déplacé d’un répertoire vers un autre. Pour une configuration + permanente, utilisez plutôt la directive Alias ou des liens symboliques.

    @@ -555,56 +726,7 @@ de réécrire les URLs.

    -
    -Ressource par défaut - -
    -
    Description :
    -
    Vous voulez qu'une seule ressource (disons un certain fichier tel -que index.php) soit servie pour toutes les requêtes à destination d'un -certain répertoire, sauf pour celles qui concernent une ressource -existant effectivement comme une image, ou un fichier css.
    - -
    Solution :
    -
    -

    Depuis la version 2.2.16, vous pouvez y parvenir via la directive -FallbackResource :

    - - -<Directory "/var/www/my_blog"> - FallbackResource index.php -</Directory> - - -

    Cependant, si vos besoins étaient plus complexes, vous pouviez, dans -les versions plus anciennes d'Apache, utiliser un jeu de règles du style -:

    - - -<Directory "/var/www/my_blog"> - RewriteBase "/my_blog" - - RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-f - RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-d - RewriteRule "^" "index.php" [PT] -</Directory> - - -

    D'autre part, si vous voulez transmettre l'URI de la requête en tant -que chaîne de paramètres à index.php, vous pouvez remplacer cette règle -de réécriture par :

    -RewriteRule "(.*)" "index.php?$1" [PT,QSA] - -

    Notez que l'on peut utiliser ces jeux de règles aussi bien dans un -fichier .htaccess que dans une section -<Directory>.

    - -
    - -
    - -
    Rewrite query string @@ -653,20 +775,208 @@ RewriteRule "(.*)" - [F] -
  • Cette solution produit l'effet inverse des précédentes ; elle - copie des composantes du chemin (peut-être PATH_INFO) depuis l'URL - vers sa chaîne de paramètres : - -# The desired URL might be /products/kitchen-sink, and the script expects +
  • Cette solution produit l'effet inverse des précédentes ; elle copie des + composantes du chemin (peut-être PATH_INFO) depuis l'URL vers sa chaîne de paramètres + : +# The desired URL might be /products/kitchen-sink, and the script expects # /path?products=kitchen-sink. -RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT] - +RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]
  • +
    Explication :
    + +
    +

    Voir aussi les drapeaux [QSA] et [QSD] qui permettent de contrôler si la chaîne de +paramètres originelle est ajoutée à la fin de la substitution ou supprimée de +cette dernière.

    +
    + +
    +
    + + Répertoires utilisateur structurés + +
    +
    Description :
    + +
    +

    Certains sites avec plusieurs milliers d’utilisateurs possèdent une + organisation structurée des répertoires utilisateur, c’est-à-dire que + chaque répertoire utilisateur est dans un sous-répertoire qui commence + (par exemple) par le premier caractère du nom de l’utilisateur. Ainsi, + /~larry/anypath correspond à + /home/l/larry/public_html/anypath et + /~waldo/anypath à + /home/w/waldo/public_html/anypath.

    +
    + +
    Solution :
    + +
    +

    Nous utilisons le jeu de règles suivant pour développer les URLs avec + tilde selon l’organisation ci-dessus.

    + + +RewriteEngine on +RewriteRule "^/~(([a-z])[a-z0-9]+)(.*)" "/home/$2/$1/public_html$3" + +
    + +
    Explication :
    + +
    +

    Cette technique est principalement utile pour les environnements + d’hébergement de grande capacité avec plusieurs milliers d’utilisateurs. + Pour la plupart des sites, mod_userdir gère les URLs + utilisateur avec tilde sans avoir besoin de mod_rewrite.

    +
    +
    + +
    + +
    + + Redirection vers une ancre + +
    +
    Description :
    + +
    +

    Par défaut, la redirection vers une ancre HTML ne fonctionne pas, car + mod_rewrite échappe le caractère # en le + remplaçant par %23, ce qui casse la redirection.

    +
    + +
    Solution :
    + +
    +

    Utiliser le drapeau [NE] dans la règle + RewriteRule. NE signifie « No Escape ». +

    +
    + +
    Explication :
    +
    Bien entendu, cette technique fonctionne aussi pour d’autres caractères + spéciaux que mod_rewrite encode par défaut pour les URLs.
    +
    + +
    + +
    + + Réécriture dépendant du temps + +
    +
    Description :
    + +
    +

    Nous voulons utiliser mod_rewrite pour servir des + contenus différents en fonction de l’heure du jour.

    +
    + +
    Solution :
    + +
    +

    Il esixte de nombreuses variables nommées TIME_xxx à + utiliser dans les conditions de réécriture. En combinaison avec les motifs + de comparaison lexicographique spéciaux <STRING, + >STRING et =STRING, nous pouvons configurer + des redirections dépendant du temps :

    + + +RewriteEngine on +RewriteCond "%{TIME_HOUR}%{TIME_MIN}" >0700 +RewriteCond "%{TIME_HOUR}%{TIME_MIN}" <1900 +RewriteRule "^foo\.html$" "foo.day.html" [L] +RewriteRule "^foo\.html$" "foo.night.html" + + +

    Cette configuration sert le contenu de foo.day.html sous + l’URL foo.html de 07:01 à 18:59 et + le contenu de foo.night.html pendant le temps restant.

    + + mod_cache, les mandataires + intermédiaires et les navigateurs peuvent chacun mettre en cache les + réponses et provoquer de ce fait l’affichage d’une page en dehors de la + fenêtre de temps configurée. mod_expires permet de + contrôler cet effet. Il est bien entendu préférable de simplement servir + le contenu de manière dynamique et de le personnaliser en fonction de + l’heure du jour. + +
    + +
    Explication :
    + +
    +

    Servir du contenu dynamique par l’intermédiaire de votre application + constitue pratiquement toujours une meilleure approche. La mise en cache + par les navigateurs, les mandataires et mod_cache rend la + réécriture en fonction du temps non fiable en pratique.

    +
    +
    + +
    + +
    + + Régénération du contenu à la volée + +
    +
    Description :
    + +
    +

    Nous voulons générer dynamiquement du contenu, mais le stocker ensuite + statiquement. La règle suivante va vérifier si le fichier + statique existe, et le générer dans le cas contraire. Les fichiers + statiques peuvent être supprimés périodiquement, si souhaité (par exemple + via cron) et seront régénérés à la demande.

    +
    + +
    Solution :
    + +
    + Pour ce faire, on utilise le jeu de règles suivant : + + +# Cet exemple n’est valable que dans un contexte de répertoire +RewriteCond "%{REQUEST_URI}" !-U +RewriteRule "^(.+)\.html$" "/regenerate_page.cgi" [PT,L] + + +

    L’opérateur -U détermine si la chaîne de test (dans ce cas + REQUEST_URI) est un URL valable. Il effectue cette opération + via une sous-requête. Si cette sous-requête échoue — autrement dit, si la + ressource demandée n’existe pas — cette règle invoque le programme CGI + /regenerate_page.cgi qui va générer la ressource demandée et la + sauvegarder dans le répertoire des documents de sorte qu’une copie statique + puissent en être servie la prochaine fois qu’elle sera demandée.

    + +

    Ainsi, les documents qui ne sont pas souvent mis à jour peuvent être + servis sous forme statique. Si ces documents doivent être rafraîchis, ils + peuvent être supprimés du répertoire des documents ; ils seront alors + régénérés la prochaine fois qu’ils seront demandés.

    +
    + +
    Explication :
    + +
    +

    Les approches modernes telles que mod_cache, les + couches de mise en cache CDN ou la mise en cache au niveau de + l’application fournissent des solutions plus robustes et configurables + pour servir du contenu statique pré-généré. Le test de la sous-requête de + l’opérateur -U utilisé ici induit un coût en performance à + chaque requête.

    +
    +
    + +
    + diff --git a/docs/manual/rewrite/remapping.xml.meta b/docs/manual/rewrite/remapping.xml.meta index 21c834aac45..8f8e6ccac49 100644 --- a/docs/manual/rewrite/remapping.xml.meta +++ b/docs/manual/rewrite/remapping.xml.meta @@ -10,7 +10,7 @@ de en es - fr + fr ja ko tr diff --git a/docs/manual/rewrite/rewritemap.html.fr.utf8 b/docs/manual/rewrite/rewritemap.html.fr.utf8 index a6290e24baf..d186016a77a 100644 --- a/docs/manual/rewrite/rewritemap.html.fr.utf8 +++ b/docs/manual/rewrite/rewritemap.html.fr.utf8 @@ -32,8 +32,6 @@  tr  |  zh-cn 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.

    Ce document est un complément à la documentation de référence du @@ -42,13 +40,7 @@ fournit des exemples pour chacun des différents types de RewriteMap.

    -
    Notez que la plupart de ces exemples ne - fonctionneront pas en l'état dans le contexte de votre configuration - particulière ; vous devez donc vous attacher à les - comprendre, plutôt que de simplement les insérer dans votre - configuration par copier/coller.
    - - + + mod_rewrite
  • Introduction à mod_rewrite
  • Redirection et remise en correspondance
  • Drapeaux des règles de réécriture
  • Serveurs virtuels
  • Réécritures par répertoire
  • Quand ne pas utiliser mod_rewrite
  • Détails techniques
  • top

    Introduction

    @@ -168,7 +160,7 @@ exemples pour chacun d'entre eux.

    fonction interne, et insérez-la dans votre RewriteRule :

    -

    Redirection d'un URI vers une version en minuscules +

    Redirection d'un chemin d’URL vers une version en minuscules d'elle-même

    RewriteMap lc int:tolower
     RewriteRule "(.*)" "${lc:$1}" [R]
    @@ -418,7 +410,7 @@ directive R directive Mutex.

    Voici un exemple simple qui remplace tous les tirets par des - caractères de soulignement dans l'URI de la requête.

    + caractères de soulignement dans le chemin d’URL de la requête.

    Configuration de la réécriture

    RewriteMap d2u "prg:/www/bin/dash2under.py" apache:apache
    @@ -433,16 +425,49 @@ for line in sys.stdin:
         print(line.strip().replace('-', '_'), flush=True)
    +

    Un exemple plus complet montre un motif typique pour qu’un programme de + correspondance prg: lise une ligne, recherche le résultat et l’affiche. La + sortie de diagnostic est écrite sur STDERR et termine sa course + dans le journal des erreurs de httpd.

    + +

    Configuration de la réécriture

    +
    RewriteMap vhost2docroot "prg:/www/bin/vhost_lookup.py"
    +RewriteRule "^/(.*)$" "${vhost2docroot:%{HTTP_HOST}}/$1"
    + + +

    vhost_lookup.py

    +
    #!/usr/bin/env python3
    +"""Associer un nom d’hôte au répertoire racine de ses documents."""
    +import sys
    +
    +VHOSTS = {
    +    "example.com": "/srv/www/example",
    +    "blog.example.com": "/srv/www/blog",
    +}
    +
    +for line in sys.stdin:
    +    host = line.strip().lower()
    +    docroot = VHOSTS.get(host)
    +    if docroot:
    +        print(docroot, flush=True)
    +    else:
    +        # "NULL" indique à mod_rewrite que la recherche a échoué
    +        print("NULL", flush=True)
    +        print(f"vhost_lookup: no match for {host!r}", file=sys.stderr)
    + +

    Mises en garde !

      -
    • Votre programme doit être le plus -simple possible. Si le programme se bloque, httpd va attendre -indéfiniment une réponse de sa part, et par conséquent ne répondra plus -aux requêtes.
    • -
    • Assurez-vous de bien désactiver la mise en tampon dans votre -programme. Dans l'exemple en Python ci-avant, cette opération s'effectue en -passant flush=True à print(). Si les entrées/sorties sont mises en tampon, httpd va -attendre une sortie, et va par conséquent se bloquer.
    • +
    • Votre programme doit être le plus simple possible. Si le programme se +bloque, httpd va attendre indéfiniment une réponse de sa part, et par conséquent +ne répondra plus aux requêtes.
    • +
    • Assurez-vous de bien désactiver la mise en tampon dans votre programme. Dans +l'exemple en Python ci-avant, cette opération s'effectue en passant +flush=True à print(). Si les entrées/sorties sont +mises en tampon, httpd va attendre une sortie, et va par conséquent se bloquer. +Il s’agit de la cause la plus courante pour laquelle le mappage prg: semble ne +rien faire — le programme a la réponse mais httpd ne la verra jamais, car +elle est prisonnière d’un tampon.
    • Rappelez-vous qu'il n'existe qu'une copie du programme lancé au démarrage du serveur, et que toutes les requêtes vont devoir passer par ce goulot d'étranglement. Ceci peut provoquer des ralentissements @@ -493,6 +518,75 @@ est envoyé au programme ; s'il ne s'arrête pas dans les 3 secondes,
    top
    +

    Distribution de la charge (sharding) basée sur l'URL entre plusieurs serveurs dorsaux

    + + + +
    +
    Description :
    + +
    +

    Le « sharding » est une technique courante de distribution de la charge + de travail ou de l’espace de stockage. Lorsqu’on utilise cette méthode, un + serveur frontal va utiliser l’URL pour distribuer les utilisateurs ou + objets à des serveurs dorsaux de manière cohérente.

    +
    + +
    Solution :
    + +
    +

    Un mappage entre les utilisateurs et les serveurs cible est entretenu + dans des fichiers de mappage. Ces derniers sont sous la forme :

    + +

    +utilisateur1 serveur_physique_de_utilisateur1
    +utilisateur2 serveur_physique_de_utilisateur2
    +# ... et ainsi de suite +

    + +

    Nous inscrivons ceci dans un fichier + mappage.utilisateur-vers-serveur. Le but est d’associer

    + +

    +/u/utilisateur1/chemin +

    + +

    à

    + +

    +http://serveur_physique_de_utilisateur1/u/utilisateur/chemin +

    + +

    de sorte que tous les chemins d’URL n’ont pas besoin d’être valables + sur chaque serveur dorsal physique. Le jeu de règles suivant fait cela + pour nous avec l’aide des fichiers de mappage, en supposant que server0 + est un serveur par défaut qui sera utilisé si un utilisateur n’a pas + d’entrée dans le mappage :

    + +
    RewriteEngine on
    +RewriteMap    users-to-hosts      "txt:/path/to/map.users-to-hosts"
    +RewriteRule   "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"
    + +
    + +
    Discussion :
    + +
    +

    Pour distribuer les requêtes aux différents serveurs dorsaux, + mod_proxy_balancer constitue une approche plus robuste et + configurable, avec la prise en charge d’un bilan de santé, d’une + pondération des charges et de la persistance des sessions. L’approche + basée sur un mappage txt: présentée ici est plus simple mais ne prend pas + en charge ces fonctionnalités.

    +
    +
    + +

    Voir la documentation de RewriteMap pour une description plus complète + de la syntaxe de cette directive. +

    + +
    top
    +

    Résumé

    diff --git a/docs/manual/rewrite/rewritemap.xml.fr b/docs/manual/rewrite/rewritemap.xml.fr index 2199af340cd..4ba5b141046 100644 --- a/docs/manual/rewrite/rewritemap.xml.fr +++ b/docs/manual/rewrite/rewritemap.xml.fr @@ -1,7 +1,7 @@ - + @@ -33,23 +33,16 @@ fournit des exemples pour chacun des différents types de RewriteMap.

    - Notez que la plupart de ces exemples ne - fonctionneront pas en l'état dans le contexte de votre configuration - particulière ; vous devez donc vous attacher à les - comprendre, plutôt que de simplement les insérer dans votre - configuration par copier/coller. - - + Documentation du module mod_rewrite Introduction à mod_rewrite - Redirection et remise en - correspondance - Contrôle d'accès + Redirection et remise en correspondance + Drapeaux des règles de réécriture Serveurs virtuels - Mise en cache - Techniques avancées + Réécritures par répertoire Quand ne pas utiliser mod_rewrite + Détails techniques
    Introduction @@ -154,7 +147,7 @@ exemples pour chacun d'entre eux.

    module="mod_rewrite">RewriteRule :

    -

    Redirection d'un URI vers une version en minuscules +

    Redirection d'un chemin d’URL vers une version en minuscules d'elle-même

    @@ -413,7 +406,7 @@ directive RewriteMap.

    directive Mutex.

    Voici un exemple simple qui remplace tous les tirets par des - caractères de soulignement dans l'URI de la requête.

    + caractères de soulignement dans le chemin d’URL de la requête.

    Configuration de la réécriture

    @@ -431,16 +424,51 @@ for line in sys.stdin: print(line.strip().replace('-', '_'), flush=True) +

    Un exemple plus complet montre un motif typique pour qu’un programme de + correspondance prg: lise une ligne, recherche le résultat et l’affiche. La + sortie de diagnostic est écrite sur STDERR et termine sa course + dans le journal des erreurs de httpd.

    + +

    Configuration de la réécriture

    + +RewriteMap vhost2docroot "prg:/www/bin/vhost_lookup.py" +RewriteRule "^/(.*)$" "${vhost2docroot:%{HTTP_HOST}}/$1" + + +

    vhost_lookup.py

    + +#!/usr/bin/env python3 +"""Associer un nom d’hôte au répertoire racine de ses documents.""" +import sys + +VHOSTS = { + "example.com": "/srv/www/example", + "blog.example.com": "/srv/www/blog", +} + +for line in sys.stdin: + host = line.strip().lower() + docroot = VHOSTS.get(host) + if docroot: + print(docroot, flush=True) + else: + # "NULL" indique à mod_rewrite que la recherche a échoué + print("NULL", flush=True) + print(f"vhost_lookup: no match for {host!r}", file=sys.stderr) + + Mises en garde !
      -
    • Votre programme doit être le plus -simple possible. Si le programme se bloque, httpd va attendre -indéfiniment une réponse de sa part, et par conséquent ne répondra plus -aux requêtes.
    • -
    • Assurez-vous de bien désactiver la mise en tampon dans votre -programme. Dans l'exemple en Python ci-avant, cette opération s'effectue en -passant flush=True à print(). Si les entrées/sorties sont mises en tampon, httpd va -attendre une sortie, et va par conséquent se bloquer.
    • +
    • Votre programme doit être le plus simple possible. Si le programme se +bloque, httpd va attendre indéfiniment une réponse de sa part, et par conséquent +ne répondra plus aux requêtes.
    • +
    • Assurez-vous de bien désactiver la mise en tampon dans votre programme. Dans +l'exemple en Python ci-avant, cette opération s'effectue en passant +flush=True à print(). Si les entrées/sorties sont +mises en tampon, httpd va attendre une sortie, et va par conséquent se bloquer. +Il s’agit de la cause la plus courante pour laquelle le mappage prg: semble ne +rien faire — le programme a la réponse mais httpd ne la verra jamais, car +elle est prisonnière d’un tampon.
    • Rappelez-vous qu'il n'existe qu'une copie du programme lancé au démarrage du serveur, et que toutes les requêtes vont devoir passer par ce goulot d'étranglement. Ceci peut provoquer des ralentissements @@ -494,6 +522,78 @@ RewriteMap ma-requete "fastdbd:SELECT destination FROM rewrite WHERE source = %s règles imposées par votre base de données (comme la sensibilité à la casse).

    + +
    + + Distribution de la charge (sharding) basée sur l'URL entre plusieurs serveurs dorsaux + +
    +
    Description :
    + +
    +

    Le « sharding » est une technique courante de distribution de la charge + de travail ou de l’espace de stockage. Lorsqu’on utilise cette méthode, un + serveur frontal va utiliser l’URL pour distribuer les utilisateurs ou + objets à des serveurs dorsaux de manière cohérente.

    +
    + +
    Solution :
    + +
    +

    Un mappage entre les utilisateurs et les serveurs cible est entretenu + dans des fichiers de mappage. Ces derniers sont sous la forme :

    + + +utilisateur1 serveur_physique_de_utilisateur1
    +utilisateur2 serveur_physique_de_utilisateur2
    +# ... et ainsi de suite +
    + +

    Nous inscrivons ceci dans un fichier + mappage.utilisateur-vers-serveur. Le but est d’associer

    + + +/u/utilisateur1/chemin + + +

    à

    + + +http://serveur_physique_de_utilisateur1/u/utilisateur/chemin + + +

    de sorte que tous les chemins d’URL n’ont pas besoin d’être valables + sur chaque serveur dorsal physique. Le jeu de règles suivant fait cela + pour nous avec l’aide des fichiers de mappage, en supposant que server0 + est un serveur par défaut qui sera utilisé si un utilisateur n’a pas + d’entrée dans le mappage :

    + + +RewriteEngine on +RewriteMap users-to-hosts "txt:/path/to/map.users-to-hosts" +RewriteRule "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2" + +
    + +
    Discussion :
    + +
    +

    Pour distribuer les requêtes aux différents serveurs dorsaux, + mod_proxy_balancer constitue une approche plus robuste et + configurable, avec la prise en charge d’un bilan de santé, d’une + pondération des charges et de la persistance des sessions. L’approche + basée sur un mappage txt: présentée ici est plus simple mais ne prend pas + en charge ces fonctionnalités.

    +
    +
    + +

    Voir la documentation de RewriteMap pour une description plus complète + de la syntaxe de cette directive. +

    + +
    +
    Résumé diff --git a/docs/manual/rewrite/rewritemap.xml.meta b/docs/manual/rewrite/rewritemap.xml.meta index 2c27274f555..eca3342996b 100644 --- a/docs/manual/rewrite/rewritemap.xml.meta +++ b/docs/manual/rewrite/rewritemap.xml.meta @@ -10,7 +10,7 @@ de en es - fr + fr ja ko tr diff --git a/docs/manual/rewrite/tech.html.fr.utf8 b/docs/manual/rewrite/tech.html.fr.utf8 index abe4b35546d..19f28caa31d 100644 --- a/docs/manual/rewrite/tech.html.fr.utf8 +++ b/docs/manual/rewrite/tech.html.fr.utf8 @@ -32,13 +32,13 @@  tr  |  zh-cn 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.

    Ce document passe en revue certains détails techniques à propos du module mod_rewrite et de la mise en correspondance des URLs

    @@ -80,48 +80,171 @@ correspondance
  • Drapeaux de réécri s'exécute au cours de la phase Fixup.

    Dans tous ces cas, mod_rewrite réécrit le - REQUEST_URI soit vers une nouvelle URL, soit vers un + REQUEST_URI soit vers un nouvel URL, soit vers un nom de fichier.

    Dans un contexte de répertoire, - les règles sont appliquées durant la phase "Fixup" après que l'URL a été - traduite en nom de fichier. Cela modifie ce à quoi correspond le motif et la + les règles sont appliquées durant la phase "Fixup" après que l’URL a été + traduit en nom de fichier. Cela modifie ce à quoi correspond le motif et la manière dont les substitutions sont gérées. Voir le document Réécritures en fonction du répertoire pour des détails pratiques à propos de la suppression du - chemin, de RewriteBase et de la manière d'éviter un bouclage.

    + chemin, de RewriteBase et de la manière d’éviter un bouclage.

    + +
    top
    +
    +

    Module Processing Order

    + +

    mod_rewrite et mod_alias agissent tous + les deux au cours de la phase de traduction de l’URL en nom de fichier, mais + mod_rewrite opère en premier, quel que soit l’ordre + d’apparition des directives dans le fichier de configuration. Ce + comportement est déterminé par la priorité des points d’accroche + qu’enregistre chaque module, pas par l’ordre du code source.

    + +

    La conséquence pratique : lorsque des directives RewriteRule et Redirect (ou RedirectMatch) sont présentent simultanément + dans le même contexte de serveur virtuel ou global au serveur, les règles de + réécriture sont évaluées en premier. Si une règle RewriteRule + correspond et réécrit le chemin d’URL (ou renvoie une redirection), + Redirect ne verra jamais la requête.

    + +

    + Comparaison côte-à-côte des ordres d’opération des modules : dans    un contexte global au serveur, mod_rewrite opère en premier lors de la    phase de traduction du chemin d’URL en nom de fichier, mod_alias    opèrant en second ; dans un contexte de répertoire, mod_alias opère en    premier lors de la phase de traduction du chemin d’URL en nom de    fichier, mod_rewrite opérant plus tard lors de la phase de    correction
    + Figure : Inversion de l’ordre d’opération des modules entre les + contextes global au serveur et de répertoire +

    + +
    # Dans cette configuration, le Redirect n’est jamais atteint pour /old,
    +# car la règle RewriteRule s’applique en premier — même si
    +# Redirect apparaît plus tôt dans le fichier.
    +Redirect "/old" "http://example.com/new"
    +RewriteRule "^/old" "/other" [L]
    + + +

    Le contexte de répertoire inverse l’ordre

    +

    Dans un contexte de répertoire, + la situation est différente. Les directives de mod_alias + comme Redirect s’appliquent encore dans la phase de traduction + de l’URL en nom de fichier, mais les directives de + mod_rewrite s’appliquent plus tard, lors de la phase de + correction. Cela signifie que dans un contexte de répertoire, + Redirect est évaluée avant l’application des + règles RewriteRule.

    +
    + +

    Du fait de l’incohérence entre les contextes, mélanger des directives de + mod_rewrite et de mod_alias dans la même + portée est une source courante de confusion. Un conseil simple : choisissez + un module pour une tâche donnée. Si vous avez besoin de conditions de + réécritures ou de comparaison de motif, utilisez exclusivement + RewriteRule. Si une simple redirection de préfixe suffit, + utilisez la directive Redirect et n’ajoutez pas de règles de + réécritures qui pourraient interagir avec elle.

    + +
    top
    +
    +

    Encodage et décodage des URLs

    + +

    Apache httpd supprime l’échappement des caractères encodés pour l’URL + dans le chemin d’URL de la requête avant que toute comparaison de motif de + directive RewriteRule ne soit + effectuée. Une requête pour /my%20page/cats%3Fdogs est décodée + en /my page/cats?dogs, et c’est à cette chaîne décodée qu’est + comparé le motif de la directive RewriteRule.

    + +

    Cela signifie que vous ne pouvez pas écrire un motif correspondant à la + forme littérale de l’URL encodé. Si vous devez distinguer + /horses%2Fponies de /horses/ponies, utilisez la + variable %{THE_REQUEST} dans une directive RewriteCond — cette variable conserve la + requête originelle telle qu’elle a été envoyée par le client, avant tout + décodage :

    + +
    # Ne correspond qu’au caractère encodé littéral %2F, 
    +# pas au séparateur de chemin réel
    +RewriteCond "%{THE_REQUEST}" "/horses%2F"
    +RewriteRule "^/horses/ponies$" "/special-handler" [L]
    + + +

    Après la substitution, mod_rewrite réencode le chemin + d’URL résultant en sortie. Plusieurs drapeaux permettent de contrôler ce + comportement :

    + +
      +
    • [B] : rétablit l’échappement des + références arrières de façon que les caractères spéciaux capturés dans le + chemin d’URL décodé ne soient pas interprétés comme des délimiteurs dans + la substitution.
    • + +
    • [BNP] : si [B] est actif, ce drapeau + encode les espaces en %20 au lieu de + (convient + pour les éléments du chemin, pas pour la chaîne de paramètres).
    • + +
    • [NE] : ce drapeau supprime + l’échappement par défaut des caractères spéciaux dans le résultat de la + substitution, permettant la transmission sans modification des littéraux + #, ? et d’autres caractères lors des + redirections externes.
    • +
    + +

    Directive AllowEncodedSlashes

    + + +

    Par défaut, httpd renvoie un code 404 pour tout URL contenant une barre + oblique encodée (%2F). La directive AllowEncodedSlashes permet de modifier ce + comportement :

    + +
      +
    • Off (valeur par défaut) : rejette %2F avec + un code 404.
    • +
    • On : autorise %2F et le décode en + / avant de le transmettre aux gestionnaires.
    • +
    • NoDecode : autorise %2F, mais le conserve + sous sa forme encodée de façon que l’application dorsale le distingue d’un + séparateur de chemin réel.
    • +
    + +

    Lorsqu’on utilise le drapeau [B] avec des + URLs qui peuvent contenir des barres obliques encodées, il est en général + nécessaire d’utiliser AllowEncodedSlashes NoDecode pour éviter + que httpd ne rejette le résultat réencodé.

    + +
    top

    Traitement du jeu de règles

    -

    Maintenant, quand mod_rewrite se lance dans ces deux phases de - l'API, il lit le jeu de règles configurées depuis la structure - contenant sa configuration (qui a été elle-même créée soit au - démarrage d'Apache pour le contexte du serveur, soit lors du - parcours des répertoires par le noyau d'Apache pour le contexte de - répertoire). Puis le moteur de réécriture est démarré avec le jeu - de règles contenu (une ou plusieurs règles associées à leurs - conditions). En lui-même, le mode opératoire du moteur de - réécriture d'URLs est exactement le même dans les deux contextes - de configuration. Seul le traitement du résultat final diffère.

    - -

    L'ordre dans lequel les règles sont définies est important car - le moteur de réécriture les traite selon une chronologie - particulière (et pas très évidente). Le principe est le suivant : - le moteur de réécriture traite les règles (les directives RewriteRule) les unes - à la suite des autres, et lorsqu'une règle s'applique, il parcourt - les éventuelles conditions (directives - RewriteConddirectives) associées. - Pour des raisons historiques, les - conditions précèdent les règles, si bien que le déroulement du - contrôle est un peu compliqué. Voir la figure 1 pour plus de - détails.

    +

    Maintenant, quand mod_rewrite se lance dans ces deux + phases de l'API, il lit le jeu de règles configuré depuis la structure + contenant sa configuration (qui a été elle-même créée soit au démarrage + d'Apache httpd pour le contexte du serveur, soit lors du parcours des + répertoires par le noyau d'Apache httpd pour le contexte de répertoire). + Puis le moteur de réécriture est démarré avec le jeu de règles contenu + (une ou plusieurs règles associées à leurs conditions). En lui-même, le + mode opératoire du moteur de réécriture d'URLs est exactement le même dans + les deux contextes de configuration. Seul le traitement du résultat final + diffère.

    +

    - Flux des comparaisons des directives RewriteRule et RewriteCond
    - Figure 1:Déroulement du contrôle à travers le jeu de - règles de réécriture + Survol du processus de réécriture par requête lors des phases par    serveur et par répertoire
    + Figure 1 :Le processus de réécriture par requête montrant les + deux phases du traitement des règles (par serveur et par répertoire)

    -

    L'URL est tout d'abord comparée au + +

    L'ordre dans lequel les règles sont définies est important car le + moteur de réécriture les traite selon une chronologie particulière (et pas + très évidente). Le principe est le suivant : le moteur de réécriture + traite les règles (les directives RewriteRule) les unes à la suite des + autres, et lorsqu'une règle s'applique, il parcourt les éventuelles + conditions (directives RewriteConddirectives) associées. + Pour des raisons historiques, les conditions précèdent les règles, si bien + que le déroulement du contrôle est un peu compliqué. Voir la figure 2 pour + plus de détails.

    +

    + Organigramme montrant le flux de contrôle par règle : pour chaque    règle, comparaison du motif avec l’URL, évaluation des conditions    RewriteCond, application de la substitution si les deux opérations    précédentes ont réussi, puis consultation des drapeaux pour déterminer    si l’on doit arrêter le traitement ou continuer avec la règle    suivante
    + Figure 2 :Le flux de contrôle en parcourant le jeu de règles de + réécriture +

    +

    L'URL est tout d'abord comparé au Modèle de chaque règle. Lorsqu'une règle ne s'applique pas, mod_rewrite stoppe immédiatement le traitement de cette règle et passe à la règle suivante. Si l'URL correspond au @@ -146,6 +269,15 @@ correspondance

  • Drapeaux de réécri satisfaites, le traitement de la règle en cours se poursuit avec le remplacement de l'URL par la chaîne de Substitution.

    +

    + Flux des références arrières entre les directives RewriteRule et    RewriteCond
    + Figure 3 :Le flux des références arrières dans une règle + Tout d’abord, le motif de la règle RewriteRule est comparé ; ses captures + ($1...$9) sont disponibles dans toutes les chaînes de test des conditions + RewriteCond. Les dernières captures du motif de la condition qui + correspondent (%1...%9) sont disponibles dans la substitution. +

    +

    Langues Disponibles:  de  | diff --git a/docs/manual/rewrite/tech.xml b/docs/manual/rewrite/tech.xml index 8e1eded6381..7ce37487f47 100644 --- a/docs/manual/rewrite/tech.xml +++ b/docs/manual/rewrite/tech.xml @@ -100,6 +100,17 @@ and URL matching.

    the URL-path (or returns a redirect), Redirect never sees the request.

    +

    + Side-by-side comparison of module processing order:
+          in server context, mod_rewrite runs first in the
+          URL-to-filename phase then mod_alias runs second; in
+          per-directory context, mod_alias runs first in the
+          URL-to-filename phase, then mod_rewrite runs later in the
+          Fixup phase
    + Figure: Module processing order reversal between server and per-directory context +

    + # In this configuration, the Redirect is never reached for /old # because the RewriteRule matches first — even though @@ -233,7 +244,10 @@ RewriteRule "^/horses/ponies$" "/special-handler" [L] Figure 2 for more details.

    Flow of RewriteRule and RewriteCond matching
    + alt="Flowchart showing per-rule control flow: for each rule, + check pattern against URL, evaluate RewriteCond conditions, + apply substitution if both pass, then check flags to decide + whether to stop or continue to the next rule" />
    Figure 2:The control flow through the rewriting ruleset

    First the URL is matched against the diff --git a/docs/manual/rewrite/tech.xml.de b/docs/manual/rewrite/tech.xml.de index 0e899e66b21..bb5e7f645dd 100644 --- a/docs/manual/rewrite/tech.xml.de +++ b/docs/manual/rewrite/tech.xml.de @@ -1,7 +1,7 @@ - + + + @@ -78,51 +78,196 @@ correspondance s'exécute au cours de la phase Fixup.

    Dans tous ces cas, mod_rewrite réécrit le - REQUEST_URI soit vers une nouvelle URL, soit vers un + REQUEST_URI soit vers un nouvel URL, soit vers un nom de fichier.

    Dans un contexte de répertoire, - les règles sont appliquées durant la phase "Fixup" après que l'URL a été - traduite en nom de fichier. Cela modifie ce à quoi correspond le motif et la + les règles sont appliquées durant la phase "Fixup" après que l’URL a été + traduit en nom de fichier. Cela modifie ce à quoi correspond le motif et la manière dont les substitutions sont gérées. Voir le document Réécritures en fonction du répertoire pour des détails pratiques à propos de la suppression du - chemin, de RewriteBase et de la manière d'éviter un bouclage.

    + chemin, de RewriteBase et de la manière d’éviter un bouclage.

    +
    Module Processing Order + +

    mod_rewrite et mod_alias agissent tous + les deux au cours de la phase de traduction de l’URL en nom de fichier, mais + mod_rewrite opère en premier, quel que soit l’ordre + d’apparition des directives dans le fichier de configuration. Ce + comportement est déterminé par la priorité des points d’accroche + qu’enregistre chaque module, pas par l’ordre du code source.

    + +

    La conséquence pratique : lorsque des directives RewriteRule et Redirect (ou RedirectMatch) sont présentent simultanément + dans le même contexte de serveur virtuel ou global au serveur, les règles de + réécriture sont évaluées en premier. Si une règle RewriteRule + correspond et réécrit le chemin d’URL (ou renvoie une redirection), + Redirect ne verra jamais la requête.

    + +

    + Comparaison côte-à-côte des ordres d’opération des modules : dans
+	  un contexte global au serveur, mod_rewrite opère en premier lors de la
+	  phase de traduction du chemin d’URL en nom de fichier, mod_alias
+	  opèrant en second ; dans un contexte de répertoire, mod_alias opère en
+	  premier lors de la phase de traduction du chemin d’URL en nom de
+	  fichier, mod_rewrite opérant plus tard lors de la phase de
+	  correction
    + Figure : Inversion de l’ordre d’opération des modules entre les + contextes global au serveur et de répertoire +

    + + +# Dans cette configuration, le Redirect n’est jamais atteint pour /old, +# car la règle RewriteRule s’applique en premier — même si +# Redirect apparaît plus tôt dans le fichier. +Redirect "/old" "http://example.com/new" +RewriteRule "^/old" "/other" [L] + + + Le contexte de répertoire inverse l’ordre +

    Dans un contexte de répertoire, + la situation est différente. Les directives de mod_alias + comme Redirect s’appliquent encore dans la phase de traduction + de l’URL en nom de fichier, mais les directives de + mod_rewrite s’appliquent plus tard, lors de la phase de + correction. Cela signifie que dans un contexte de répertoire, + Redirect est évaluée avant l’application des + règles RewriteRule.

    +
    + +

    Du fait de l’incohérence entre les contextes, mélanger des directives de + mod_rewrite et de mod_alias dans la même + portée est une source courante de confusion. Un conseil simple : choisissez + un module pour une tâche donnée. Si vous avez besoin de conditions de + réécritures ou de comparaison de motif, utilisez exclusivement + RewriteRule. Si une simple redirection de préfixe suffit, + utilisez la directive Redirect et n’ajoutez pas de règles de + réécritures qui pourraient interagir avec elle.

    + +
    + +
    Encodage et décodage des URLs + +

    Apache httpd supprime l’échappement des caractères encodés pour l’URL + dans le chemin d’URL de la requête avant que toute comparaison de motif de + directive RewriteRule ne soit + effectuée. Une requête pour /my%20page/cats%3Fdogs est décodée + en /my page/cats?dogs, et c’est à cette chaîne décodée qu’est + comparé le motif de la directive RewriteRule.

    + +

    Cela signifie que vous ne pouvez pas écrire un motif correspondant à la + forme littérale de l’URL encodé. Si vous devez distinguer + /horses%2Fponies de /horses/ponies, utilisez la + variable %{THE_REQUEST} dans une directive RewriteCond — cette variable conserve la + requête originelle telle qu’elle a été envoyée par le client, avant tout + décodage :

    + + +# Ne correspond qu’au caractère encodé littéral %2F, +# pas au séparateur de chemin réel +RewriteCond "%{THE_REQUEST}" "/horses%2F" +RewriteRule "^/horses/ponies$" "/special-handler" [L] + + +

    Après la substitution, mod_rewrite réencode le chemin + d’URL résultant en sortie. Plusieurs drapeaux permettent de contrôler ce + comportement :

    + +
      +
    • [B] : rétablit l’échappement des + références arrières de façon que les caractères spéciaux capturés dans le + chemin d’URL décodé ne soient pas interprétés comme des délimiteurs dans + la substitution.
    • + +
    • [BNP] : si [B] est actif, ce drapeau + encode les espaces en %20 au lieu de + (convient + pour les éléments du chemin, pas pour la chaîne de paramètres).
    • + +
    • [NE] : ce drapeau supprime + l’échappement par défaut des caractères spéciaux dans le résultat de la + substitution, permettant la transmission sans modification des littéraux + #, ? et d’autres caractères lors des + redirections externes.
    • +
    + +
    + Directive AllowEncodedSlashes + +

    Par défaut, httpd renvoie un code 404 pour tout URL contenant une barre + oblique encodée (%2F). La directive AllowEncodedSlashes permet de modifier ce + comportement :

    + +
      +
    • Off (valeur par défaut) : rejette %2F avec + un code 404.
    • +
    • On : autorise %2F et le décode en + / avant de le transmettre aux gestionnaires.
    • +
    • NoDecode : autorise %2F, mais le conserve + sous sa forme encodée de façon que l’application dorsale le distingue d’un + séparateur de chemin réel.
    • +
    + +

    Lorsqu’on utilise le drapeau [B] avec des + URLs qui peuvent contenir des barres obliques encodées, il est en général + nécessaire d’utiliser AllowEncodedSlashes NoDecode pour éviter + que httpd ne rejette le résultat réencodé.

    + +
    + +
    + +
    Traitement du jeu de règles -

    Maintenant, quand mod_rewrite se lance dans ces deux phases de - l'API, il lit le jeu de règles configurées depuis la structure - contenant sa configuration (qui a été elle-même créée soit au - démarrage d'Apache pour le contexte du serveur, soit lors du - parcours des répertoires par le noyau d'Apache pour le contexte de - répertoire). Puis le moteur de réécriture est démarré avec le jeu - de règles contenu (une ou plusieurs règles associées à leurs - conditions). En lui-même, le mode opératoire du moteur de - réécriture d'URLs est exactement le même dans les deux contextes - de configuration. Seul le traitement du résultat final diffère.

    - -

    L'ordre dans lequel les règles sont définies est important car - le moteur de réécriture les traite selon une chronologie - particulière (et pas très évidente). Le principe est le suivant : - le moteur de réécriture traite les règles (les directives RewriteRule) les unes - à la suite des autres, et lorsqu'une règle s'applique, il parcourt - les éventuelles conditions (directives - RewriteConddirectives) associées. - Pour des raisons historiques, les - conditions précèdent les règles, si bien que le déroulement du - contrôle est un peu compliqué. Voir la figure 1 pour plus de - détails.

    +

    Maintenant, quand mod_rewrite se lance dans ces deux + phases de l'API, il lit le jeu de règles configuré depuis la structure + contenant sa configuration (qui a été elle-même créée soit au démarrage + d'Apache httpd pour le contexte du serveur, soit lors du parcours des + répertoires par le noyau d'Apache httpd pour le contexte de répertoire). + Puis le moteur de réécriture est démarré avec le jeu de règles contenu + (une ou plusieurs règles associées à leurs conditions). En lui-même, le + mode opératoire du moteur de réécriture d'URLs est exactement le même dans + les deux contextes de configuration. Seul le traitement du résultat final + diffère.

    + +

    + Survol du processus de réécriture par requête lors des phases par
+	  serveur et par répertoire
    + Figure 1 :Le processus de réécriture par requête montrant les + deux phases du traitement des règles (par serveur et par répertoire) +

    + +

    L'ordre dans lequel les règles sont définies est important car le + moteur de réécriture les traite selon une chronologie particulière (et pas + très évidente). Le principe est le suivant : le moteur de réécriture + traite les règles (les directives RewriteRule) les unes à la suite des + autres, et lorsqu'une règle s'applique, il parcourt les éventuelles + conditions (directives RewriteConddirectives) associées. + Pour des raisons historiques, les conditions précèdent les règles, si bien + que le déroulement du contrôle est un peu compliqué. Voir la figure 2 pour + plus de détails.

    Flux des comparaisons des directives RewriteRule et RewriteCond
    - Figure 1:Déroulement du contrôle à travers le jeu de - règles de réécriture + alt="Organigramme montrant le flux de contrôle par règle : pour chaque + règle, comparaison du motif avec l’URL, évaluation des conditions + RewriteCond, application de la substitution si les deux opérations + précédentes ont réussi, puis consultation des drapeaux pour déterminer + si l’on doit arrêter le traitement ou continuer avec la règle + suivante" />
    + Figure 2 :Le flux de contrôle en parcourant le jeu de règles de + réécriture

    -

    L'URL est tout d'abord comparée au +

    L'URL est tout d'abord comparé au Modèle de chaque règle. Lorsqu'une règle ne s'applique pas, mod_rewrite stoppe immédiatement le traitement de cette règle et passe à la règle suivante. Si l'URL correspond au @@ -147,7 +292,17 @@ correspondance satisfaites, le traitement de la règle en cours se poursuit avec le remplacement de l'URL par la chaîne de Substitution.

    -
    +

    + Flux des références arrières entre les directives RewriteRule et
+	  RewriteCond
    + Figure 3 :Le flux des références arrières dans une règle + Tout d’abord, le motif de la règle RewriteRule est comparé ; ses captures + ($1...$9) sont disponibles dans toutes les chaînes de test des conditions + RewriteCond. Les dernières captures du motif de la condition qui + correspondent (%1...%9) sont disponibles dans la substitution. +

    + diff --git a/docs/manual/rewrite/tech.xml.ja b/docs/manual/rewrite/tech.xml.ja index d323373a9fe..423313e75c4 100644 --- a/docs/manual/rewrite/tech.xml.ja +++ b/docs/manual/rewrite/tech.xml.ja @@ -1,7 +1,7 @@ - + + + + + @@ -17,7 +17,7 @@ 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. + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressor implied. See the License for the specific language governing permissions and limitations under the License. --> @@ -48,12 +48,11 @@ il'utilisation de mod_rewrite. Introduction à mod_rewrite Redirection et remise en correspondance -Contrôle d'accès - -Serveurs mandataires +Réécritures dans un contexte de répertoire +Drapeaux de la règle RewriteRule Utilisation de RewriteMap -Techniques avancées Quand ne pas utiliser mod_rewrite +Détails techniques
    diff --git a/docs/manual/rewrite/vhosts.xml.meta b/docs/manual/rewrite/vhosts.xml.meta index b54e21cb34a..3850862b00b 100644 --- a/docs/manual/rewrite/vhosts.xml.meta +++ b/docs/manual/rewrite/vhosts.xml.meta @@ -10,7 +10,7 @@ de en es - fr + fr ja ko tr diff --git a/docs/manual/style/css/manual.css b/docs/manual/style/css/manual.css index 9eb7979cbbb..4084e684947 100644 --- a/docs/manual/style/css/manual.css +++ b/docs/manual/style/css/manual.css @@ -1237,4 +1237,9 @@ h2:hover > .permalink { overflow-x: auto; max-width: 100%; } + + /* Bug 70098: hide back-to-top arrows on narrow viewports */ + div.top { + display: none; + } } diff --git a/docs/manual/style/lang/da.xml b/docs/manual/style/lang/da.xml index afe0bb6c1cd..cccd7ae745d 100644 --- a/docs/manual/style/lang/da.xml +++ b/docs/manual/style/lang/da.xml @@ -96,6 +96,8 @@ Eksperimental Ekstern + Forældet + server konfiguration virtuel vrt diff --git a/docs/manual/style/lang/de.xml b/docs/manual/style/lang/de.xml index 71078ec555b..59e2b06543d 100644 --- a/docs/manual/style/lang/de.xml +++ b/docs/manual/style/lang/de.xml @@ -91,6 +91,8 @@ experimentell extern + Veraltet + Serverkonfiguration Virtual Host diff --git a/docs/manual/style/lang/en.xml b/docs/manual/style/lang/en.xml index 1b6f72bda41..b9501e5121b 100644 --- a/docs/manual/style/lang/en.xml +++ b/docs/manual/style/lang/en.xml @@ -94,6 +94,8 @@ Extension Experimental External + Deprecated + server config diff --git a/docs/manual/style/lang/es.xml b/docs/manual/style/lang/es.xml index b5b24c70abd..99562c4dfb4 100644 --- a/docs/manual/style/lang/es.xml +++ b/docs/manual/style/lang/es.xml @@ -99,6 +99,8 @@ Experimental Externo + Obsoleto + server config virtual host diff --git a/docs/manual/style/lang/fr.xml b/docs/manual/style/lang/fr.xml index 3ccb09d4067..52b82642a80 100644 --- a/docs/manual/style/lang/fr.xml +++ b/docs/manual/style/lang/fr.xml @@ -95,6 +95,8 @@ Expérimental Externe + Obsolète + configuration globale serveur virtuel diff --git a/docs/manual/style/lang/ja.xml b/docs/manual/style/lang/ja.xml index 2d1be26c8ef..77c48147309 100644 --- a/docs/manual/style/lang/ja.xml +++ b/docs/manual/style/lang/ja.xml @@ -90,6 +90,8 @@ Experimental External + 非推奨 + サーバ設定ファイル バーチャルホスト diff --git a/docs/manual/style/lang/ko.xml b/docs/manual/style/lang/ko.xml index 3f4177fba66..fa4ec120cfb 100644 --- a/docs/manual/style/lang/ko.xml +++ b/docs/manual/style/lang/ko.xml @@ -96,6 +96,8 @@ Experimental External + 사용 중단됨 + ּ ȣƮ diff --git a/docs/manual/style/lang/pt-br.xml b/docs/manual/style/lang/pt-br.xml index 8813105c9ba..a7febb977bf 100644 --- a/docs/manual/style/lang/pt-br.xml +++ b/docs/manual/style/lang/pt-br.xml @@ -95,6 +95,8 @@ Experimental Externo + Obsoleto + configuração do servidor host virtual diff --git a/docs/manual/style/lang/ru.xml b/docs/manual/style/lang/ru.xml index 4e6c9e6b99e..15ee7c2635e 100644 --- a/docs/manual/style/lang/ru.xml +++ b/docs/manual/style/lang/ru.xml @@ -94,6 +94,8 @@ Experimental External + Устаревший + server config virtual host diff --git a/docs/manual/style/lang/tr.xml b/docs/manual/style/lang/tr.xml index 3a3c193b60e..99ff0d72ad3 100644 --- a/docs/manual/style/lang/tr.xml +++ b/docs/manual/style/lang/tr.xml @@ -97,6 +97,8 @@ Deneysel Harici + Kullanımdan Kaldırıldı + sunucu geneli sanal konak diff --git a/docs/manual/suexec.html.fr.utf8 b/docs/manual/suexec.html.fr.utf8 index 5adf99314d3..c21251fe96f 100644 --- a/docs/manual/suexec.html.fr.utf8 +++ b/docs/manual/suexec.html.fr.utf8 @@ -29,8 +29,6 @@  ko  |  tr 

    -
    Cette traduction peut être périmée. Vérifiez la version - anglaise pour les changements récents.

    La fonctionnalité suEXEC permet l'exécution des programmes CGI et diff --git a/docs/manual/suexec.xml.fr b/docs/manual/suexec.xml.fr index 32224f76a26..e161c361593 100644 --- a/docs/manual/suexec.xml.fr +++ b/docs/manual/suexec.xml.fr @@ -3,7 +3,7 @@ - + - + + + + "); - dump_content(ctx); } } static void pendElement(void *ctxt, const xmlChar *uname) diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c index 12cb04a20f9..193a41254ff 100644 --- a/modules/filters/mod_sed.c +++ b/modules/filters/mod_sed.c @@ -489,7 +489,7 @@ static apr_status_t sed_request_filter(ap_filter_t *f, static const char *sed_add_expr(cmd_parms *cmd, void *cfg, const char *arg) { - int offset = (int) (long) cmd->info; + apr_size_t offset = (apr_size_t) cmd->info; sed_expr_config *sed_cfg = (sed_expr_config *) (((char *) cfg) + offset); if (compile_sed_expr(sed_cfg, cmd, arg) != APR_SUCCESS) { diff --git a/modules/filters/mod_substitute.c b/modules/filters/mod_substitute.c index 65ca5f95d01..2533d7dcd04 100644 --- a/modules/filters/mod_substitute.c +++ b/modules/filters/mod_substitute.c @@ -679,7 +679,7 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line) if (delim) from = ++ourline; if (from) { - if (*ourline != delim) { + if (*ourline && *ourline != delim) { while (*++ourline && *ourline != delim); } if (*ourline) { @@ -688,7 +688,7 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line) } } if (to) { - if (*ourline != delim) { + if (*ourline && *ourline != delim) { while (*++ourline && *ourline != delim); } if (*ourline) { @@ -777,12 +777,18 @@ static const char *set_max_line_length(cmd_parms *cmd, void *cfg, const char *ar rv = apr_strtoff(&max, arg, &end, 10); if (rv == APR_SUCCESS) { if ((*end == 'K' || *end == 'k') && !end[1]) { + if (max > APR_INT64_MAX / KBYTE) + return "SubstituteMaxLineLength value too large"; max *= KBYTE; } else if ((*end == 'M' || *end == 'm') && !end[1]) { + if (max > APR_INT64_MAX / MBYTE) + return "SubstituteMaxLineLength value too large"; max *= MBYTE; } else if ((*end == 'G' || *end == 'g') && !end[1]) { + if (max > APR_INT64_MAX / GBYTE) + return "SubstituteMaxLineLength value too large"; max *= GBYTE; } else if (*end && /* neither empty nor [Bb] */ diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c index 21f6e5ec7e2..21d1cc78a50 100644 --- a/modules/filters/sed1.c +++ b/modules/filters/sed1.c @@ -433,7 +433,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz while (bufsz) { apr_status_t rc = 0; - char *n; + const char *n; apr_size_t llen; n = memchr((char *)buf, '\n', bufsz); diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 94ad7ee8733..42bd384c20a 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -192,6 +192,8 @@ typedef struct { } cgid_rlimit_t; #endif +#define ENV_COUNT_MAX (256) + typedef struct { int req_type; /* request type (CGI_REQ, SSI_REQ, etc.) */ unsigned long conn_id; /* connection id; daemon uses this as a hash value @@ -201,7 +203,7 @@ typedef struct { pid_t ppid; /* sanity check for config problems leading to * wrong cgid socket use */ - int env_count; + unsigned env_count; ap_unix_identity_t ugid; apr_size_t filename_len; apr_size_t argv0_len; @@ -342,7 +344,7 @@ static apr_status_t close_unix_socket(void *thefd) { int fd = (int)((long)thefd); - return close(fd); + return close(fd) < 0 ? errno : APR_SUCCESS; } /* Read from the socket dealing with incomplete messages and signals. @@ -431,13 +433,18 @@ static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) { int rc; + const char *b = buf; + size_t written = 0; do { - rc = write(fd, buf, buf_size); - } while (rc < 0 && errno == EINTR); - if (rc < 0) { - return errno; - } + do { + rc = write(fd, b + written, buf_size - written); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { + return errno; + } + written += rc; + } while (written < buf_size); return APR_SUCCESS; } @@ -513,6 +520,11 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, if (stat != APR_SUCCESS) { return stat; } + + if (req->loglevel > APLOG_TRACE8) { + return APR_EINVAL; + } + r->server->log.level = req->loglevel; if (req->req_type == GETPID_REQ) { /* no more data sent for this request */ @@ -520,17 +532,18 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, } /* 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) { + if (req->env_count > ENV_COUNT_MAX + || req->filename_len == 0 || req->filename_len > APR_PATH_MAX + || req->argv0_len == 0 || req->argv0_len > APR_PATH_MAX + || req->uri_len == 0 || req->uri_len > APR_PATH_MAX + || req->args_len > APR_PATH_MAX) { return APR_EINVAL; } - + /* handle module indexes and such */ rconf = (void **)ap_create_request_config(r->pool); - temp_core = (core_request_config *)apr_palloc(r->pool, sizeof(core_module)); + temp_core = (core_request_config *)apr_palloc(r->pool, sizeof *temp_core); rconf[AP_CORE_MODULE_INDEX] = (void *)temp_core; r->request_config = (ap_conf_vector_t *)rconf; ap_set_module_config(r->request_config, &cgid_module, (void *)&req->ugid); @@ -560,6 +573,9 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, if ((stat = sock_read(fd, &curlen, sizeof(curlen))) != APR_SUCCESS) { return stat; } + if (curlen > APR_PATH_MAX) { + return APR_EINVAL; + } environ[i] = apr_pcalloc(r->pool, curlen + 1); if ((stat = sock_read(fd, environ[i], curlen)) != APR_SUCCESS) { return stat; @@ -862,7 +878,7 @@ static int cgid_server(void *data) errfileno = STDERR_FILENO; } else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server, + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 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), @@ -1067,7 +1083,7 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, return DECLINED; } if (strlen(tmp_sockname) > sizeof(server_addr->sun_path) - 1) { - tmp_sockname[sizeof(server_addr->sun_path)] = '\0'; + tmp_sockname[sizeof(server_addr->sun_path) - 1] = '\0'; ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, APLOGNO(01254) "The length of the ScriptSock path exceeds maximum, " "truncating to %s", tmp_sockname); @@ -1728,8 +1744,8 @@ static void add_ssi_vars(request_rec *r) } } -static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb, const char *command) +static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, const char *command) { char **env; int sd; @@ -1747,30 +1763,29 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, env = ap_create_environment(r->pool, r->subprocess_env); if ((retval = connect_to_daemon(&sd, r, conf)) != OK) { - return retval; + return APR_EGENERAL; } - send_req(sd, NULL, r, command, env, SSI_REQ); + rv = send_req(sd, NULL, r, command, env, SSI_REQ); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, + "could not send request to cgi daemon (for SSI)"); + return rv; + } 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) { - /* for this type of request, the script is invoked through an - * intermediate shell process... cleanup_script is only able - * to knock out the shell process, not the actual script - */ - apr_pool_cleanup_register(r->pool, info, - cleanup_script, - apr_pool_cleanup_null); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi PID (for SSI)"); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi daemon PID (for SSI)"); + return rv; } - apr_pool_cleanup_register(r->pool, info, - cleanup_script, + /* For this type of request, the script is invoked through an + * intermediate shell process... cleanup_script is only able to + * knock out the shell process, not the actual script. */ + apr_pool_cleanup_register(r->pool, info, cleanup_script, apr_pool_cleanup_null); /* We are putting the socket discriptor into an apr_file_t so that we can diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c index a710c4ad0fc..e00d0f7327d 100644 --- a/modules/http/mod_mime.c +++ b/modules/http/mod_mime.c @@ -53,7 +53,7 @@ typedef struct attrib_info { char *name; - int offset; + apr_size_t offset; } attrib_info; /* Information to which an extension can be mapped @@ -267,7 +267,7 @@ static const char *add_extension_info(cmd_parms *cmd, void *m_, { mime_dir_config *m=m_; extension_info *exinfo; - int offset = (int) (long) cmd->info; + apr_size_t offset = (apr_size_t) cmd->info; char *key = apr_pstrdup(cmd->temp_pool, ext); char *value = apr_pstrdup(cmd->pool, value_); ap_str_tolower(value); @@ -322,7 +322,7 @@ static const char *remove_extension_info(cmd_parms *cmd, void *m_, suffix = (attrib_info *)apr_array_push(m->remove_mappings); suffix->name = apr_pstrdup(cmd->pool, ext); ap_str_tolower(suffix->name); - suffix->offset = (int) (long) cmd->info; + suffix->offset = (apr_size_t) cmd->info; return NULL; } diff --git a/modules/http2/h2_push.c b/modules/http2/h2_push.c index e6a10c5ab10..589862ceff2 100644 --- a/modules/http2/h2_push.c +++ b/modules/http2/h2_push.c @@ -699,179 +699,3 @@ apr_array_header_t *h2_push_collect_update(struct h2_stream *stream, pushes = h2_push_collect(stream->pool, req, stream->push_policy, res); return h2_push_diary_update(stream->session, pushes); } - -typedef struct { - h2_push_diary *diary; - unsigned char log2p; - int mask_bits; - int delta_bits; - int fixed_bits; - apr_uint64_t fixed_mask; - apr_pool_t *pool; - unsigned char *data; - apr_size_t datalen; - apr_size_t offset; - unsigned int bit; - apr_uint64_t last; -} gset_encoder; - -static int cmp_puint64(const void *p1, const void *p2) -{ - const apr_uint64_t *pu1 = p1, *pu2 = p2; - return (*pu1 > *pu2)? 1 : ((*pu1 == *pu2)? 0 : -1); -} - -/* in golomb bit stream encoding, bit 0 is the 8th of the first char, or - * more generally: - * char(bit/8) & cbit_mask[(bit % 8)] - */ -static unsigned char cbit_mask[] = { - 0x80u, - 0x40u, - 0x20u, - 0x10u, - 0x08u, - 0x04u, - 0x02u, - 0x01u, -}; - -static apr_status_t gset_encode_bit(gset_encoder *encoder, int bit) -{ - if (++encoder->bit >= 8) { - if (++encoder->offset >= encoder->datalen) { - apr_size_t nlen = encoder->datalen*2; - unsigned char *ndata = apr_pcalloc(encoder->pool, nlen); - if (!ndata) { - return APR_ENOMEM; - } - memcpy(ndata, encoder->data, encoder->datalen); - encoder->data = ndata; - encoder->datalen = nlen; - } - encoder->bit = 0; - encoder->data[encoder->offset] = 0xffu; - } - if (!bit) { - encoder->data[encoder->offset] &= ~cbit_mask[encoder->bit]; - } - return APR_SUCCESS; -} - -static apr_status_t gset_encode_next(gset_encoder *encoder, apr_uint64_t pval) -{ - apr_uint64_t delta, flex_bits; - apr_status_t status = APR_SUCCESS; - int i; - - delta = pval - encoder->last; - encoder->last = pval; - flex_bits = (delta >> encoder->fixed_bits); - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, encoder->pool, - "h2_push_diary_enc: val=%"APR_UINT64_T_HEX_FMT", delta=%" - APR_UINT64_T_HEX_FMT" flex_bits=%"APR_UINT64_T_FMT", " - ", fixed_bits=%d, fixed_val=%"APR_UINT64_T_HEX_FMT, - pval, delta, flex_bits, encoder->fixed_bits, delta&encoder->fixed_mask); - for (; flex_bits != 0; --flex_bits) { - status = gset_encode_bit(encoder, 1); - if (status != APR_SUCCESS) { - return status; - } - } - status = gset_encode_bit(encoder, 0); - if (status != APR_SUCCESS) { - return status; - } - - for (i = encoder->fixed_bits-1; i >= 0; --i) { - status = gset_encode_bit(encoder, (delta >> i) & 1); - if (status != APR_SUCCESS) { - return status; - } - } - return APR_SUCCESS; -} - -/** - * Get a cache digest as described in - * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ - * from the contents of the push diary. - * - * @param diary the diary to calculdate the digest from - * @param p the pool to use - * @param pdata on successful return, the binary cache digest - * @param plen on successful return, the length of the binary data - */ -apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool, - int maxP, const char *authority, - const char **pdata, apr_size_t *plen) -{ - int nelts, N; - unsigned char log2n, log2pmax; - gset_encoder encoder; - apr_uint64_t *hashes; - apr_size_t hash_count, i; - - nelts = diary->entries->nelts; - N = ceil_power_of_2(nelts); - log2n = h2_log2(N); - - /* Now log2p is the max number of relevant bits, so that - * log2p + log2n == mask_bits. We can use a lower log2p - * and have a shorter set encoding... - */ - log2pmax = h2_log2(ceil_power_of_2(maxP)); - - memset(&encoder, 0, sizeof(encoder)); - encoder.diary = diary; - encoder.log2p = H2MIN(diary->mask_bits - log2n, log2pmax); - encoder.mask_bits = log2n + encoder.log2p; - encoder.delta_bits = diary->mask_bits - encoder.mask_bits; - encoder.fixed_bits = encoder.log2p; - encoder.fixed_mask = 1; - encoder.fixed_mask = (encoder.fixed_mask << encoder.fixed_bits) - 1; - encoder.pool = pool; - encoder.datalen = 512; - encoder.data = apr_pcalloc(encoder.pool, encoder.datalen); - - encoder.data[0] = log2n; - encoder.data[1] = encoder.log2p; - encoder.offset = 1; - encoder.bit = 8; - encoder.last = 0; - - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, - "h2_push_diary_digest_get: %d entries, N=%d, log2n=%d, " - "mask_bits=%d, enc.mask_bits=%d, delta_bits=%d, enc.log2p=%d, authority=%s", - (int)nelts, (int)N, (int)log2n, diary->mask_bits, - (int)encoder.mask_bits, (int)encoder.delta_bits, - (int)encoder.log2p, authority); - - if (!authority || !diary->authority - || !strcmp("*", authority) || !strcmp(diary->authority, authority)) { - hash_count = diary->entries->nelts; - hashes = apr_pcalloc(encoder.pool, hash_count); - for (i = 0; i < hash_count; ++i) { - hashes[i] = ((&APR_ARRAY_IDX(diary->entries, i, h2_push_diary_entry))->hash - >> encoder.delta_bits); - } - - qsort(hashes, hash_count, sizeof(apr_uint64_t), cmp_puint64); - for (i = 0; i < hash_count; ++i) { - if (!i || (hashes[i] != hashes[i-1])) { - gset_encode_next(&encoder, hashes[i]); - } - } - /* Intentional no APLOGNO */ - ap_log_perror(APLOG_MARK, GCSLOG_LEVEL, 0, pool, - "h2_push_diary_digest_get: golomb compressed hashes, %d bytes", - (int)encoder.offset + 1); - } - *pdata = (const char *)encoder.data; - *plen = encoder.offset + 1; - - return APR_SUCCESS; -} - diff --git a/modules/http2/h2_push.h b/modules/http2/h2_push.h index 947b73bc854..630d461d6a1 100644 --- a/modules/http2/h2_push.h +++ b/modules/http2/h2_push.h @@ -140,19 +140,4 @@ apr_array_header_t *h2_push_collect_update(struct h2_stream *stream, const struct h2_headers *res); #endif -/** - * Get a cache digest as described in - * https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ - * from the contents of the push diary. - * - * @param diary the diary to calculdate the digest from - * @param p the pool to use - * @param authority the authority to get the data for, use NULL/"*" for all - * @param pdata on successful return, the binary cache digest - * @param plen on successful return, the length of the binary data - */ -apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *p, - int maxP, const char *authority, - const char **pdata, apr_size_t *plen); - #endif /* defined(__mod_h2__h2_push__) */ diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c index 00f9f91361a..8c3ed68fe2a 100644 --- a/modules/ldap/util_ldap.c +++ b/modules/ldap/util_ldap.c @@ -1013,11 +1013,10 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); /* a simple compare? */ if (!compare_dn_on_server) { - /* unlock this read lock */ + ldap_cache_unlock(st, r); if (strcmp(dn, reqdn)) { ldc->reason = "DN Comparison FALSE (direct strcmp())"; return LDAP_COMPARE_FALSE; @@ -1030,22 +1029,18 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, if (curl) { /* no - it's a server side compare */ - ldap_cache_lock(st, r); /* is it in the compare cache? */ newnode.reqdn = (char *)reqdn; node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); if (node != NULL) { /* If it's in the cache, it's good */ - /* unlock this read lock */ ldap_cache_unlock(st, r); ldc->reason = "DN Comparison TRUE (cached)"; return LDAP_COMPARE_TRUE; } - - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + ldap_cache_unlock(st, r); start_over: if (failures > st->retries) { @@ -1104,18 +1099,21 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, result = LDAP_COMPARE_FALSE; } else { - if (curl) { + { /* compare successful - add to the compare cache */ ldap_cache_lock(st, r); - newnode.reqdn = (char *)reqdn; - newnode.dn = (char *)dn; - - node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); - if ( (node == NULL) - || (strcmp(reqdn, node->reqdn) != 0) - || (strcmp(dn, node->dn) != 0)) - { - util_ald_cache_insert(curl->dn_compare_cache, &newnode); + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + newnode.reqdn = (char *)reqdn; + newnode.dn = (char *)dn; + + node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); + if ( (node == NULL) + || (strcmp(reqdn, node->reqdn) != 0) + || (strcmp(dn, node->dn) != 0)) + { + util_ald_cache_insert(curl->dn_compare_cache, &newnode); + } } ldap_cache_unlock(st, r); } @@ -1158,11 +1156,9 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); if (curl) { /* make a comparison to the cache */ - ldap_cache_lock(st, r); curtime = apr_time_now(); the_compare_node.dn = (char *)dn; @@ -1193,8 +1189,8 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, ldc->reason = "Comparison no such attribute (cached)"; } else { - ldc->reason = apr_psprintf(r->pool, - "Comparison undefined: (%d): %s (adding to cache)", + ldc->reason = apr_psprintf(r->pool, + "Comparison undefined: (%d): %s (adding to cache)", result, ldap_err2string(result)); } @@ -1203,15 +1199,15 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, /* and unlock this read lock */ ldap_cache_unlock(st, r); - ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, - "ldap_compare_s(%pp, %s, %s, %s) = %s (cached)", + ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, + "ldap_compare_s(%pp, %s, %s, %s) = %s (cached)", ldc->ldap, dn, attrib, value, ldap_err2string(result)); return result; } } - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + /* unlock this read lock */ + ldap_cache_unlock(st, r); start_over: if (failures > st->retries) { @@ -1256,36 +1252,39 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, if ((LDAP_COMPARE_TRUE == result) || (LDAP_COMPARE_FALSE == result) || (LDAP_NO_SUCH_ATTRIBUTE == result)) { - if (curl) { + { /* compare completed; caching result */ ldap_cache_lock(st, r); - the_compare_node.lastcompare = curtime; - the_compare_node.result = result; - the_compare_node.sgl_processed = 0; - the_compare_node.subgroupList = NULL; - - /* If the node doesn't exist then insert it, otherwise just update - * it with the last results - */ - compare_nodep = util_ald_cache_fetch(curl->compare_cache, + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + the_compare_node.lastcompare = curtime; + the_compare_node.result = result; + the_compare_node.sgl_processed = 0; + the_compare_node.subgroupList = NULL; + + /* If the node doesn't exist then insert it, otherwise just update + * it with the last results + */ + compare_nodep = util_ald_cache_fetch(curl->compare_cache, + &the_compare_node); + if ( (compare_nodep == NULL) + || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) + || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0) + || (strcmp(the_compare_node.value, compare_nodep->value) != 0)) + { + void *junk; + + junk = util_ald_cache_insert(curl->compare_cache, &the_compare_node); - if ( (compare_nodep == NULL) - || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) - || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0) - || (strcmp(the_compare_node.value, compare_nodep->value) != 0)) - { - void *junk; - - junk = util_ald_cache_insert(curl->compare_cache, - &the_compare_node); - if (junk == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01287) - "cache_compare: Cache insertion failure."); + if (junk == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01287) + "cache_compare: Cache insertion failure."); + } + } + else { + compare_nodep->lastcompare = curtime; + compare_nodep->result = result; } - } - else { - compare_nodep->lastcompare = curtime; - compare_nodep->result = result; } ldap_cache_unlock(st, r); } @@ -1555,11 +1554,9 @@ static int uldap_cache_check_subgroups(request_rec *r, ldap_cache_lock(st, r); curnode.url = url; curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); - ldap_cache_unlock(st, r); if (curl && curl->compare_cache) { /* make a comparison to the cache */ - ldap_cache_lock(st, r); the_compare_node.dn = (char *)dn; the_compare_node.attrib = (char *)"objectClass"; @@ -1601,8 +1598,8 @@ static int uldap_cache_check_subgroups(request_rec *r, } } } - ldap_cache_unlock(st, r); } + ldap_cache_unlock(st, r); if (!tmp_local_sgl && !sgl_cached_empty) { /* No Cached SGL, retrieve from LDAP */ @@ -1616,72 +1613,74 @@ static int uldap_cache_check_subgroups(request_rec *r, dn); } - if (curl && curl->compare_cache) { + { /* * Find the generic group cache entry and add the sgl we just retrieved. */ ldap_cache_lock(st, r); + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl && curl->compare_cache) { + the_compare_node.dn = (char *)dn; + the_compare_node.attrib = (char *)"objectClass"; + the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name; + the_compare_node.result = 0; + the_compare_node.sgl_processed = 0; + the_compare_node.subgroupList = NULL; - the_compare_node.dn = (char *)dn; - the_compare_node.attrib = (char *)"objectClass"; - the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name; - the_compare_node.result = 0; - the_compare_node.sgl_processed = 0; - the_compare_node.subgroupList = NULL; - - compare_nodep = util_ald_cache_fetch(curl->compare_cache, - &the_compare_node); - - if (compare_nodep == NULL) { - /* - * The group entry we want to attach our SGL to doesn't exist. - * We only got here if we verified this DN was actually a group - * based on the objectClass, but we can't call the compare function - * while we already hold the cache lock -- only the insert. - */ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01291) - "Cache entry for %s doesn't exist", dn); - the_compare_node.result = LDAP_COMPARE_TRUE; - util_ald_cache_insert(curl->compare_cache, &the_compare_node); compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node); - if (compare_nodep == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01292) - "util_ldap: Couldn't retrieve group entry " - "for %s from cache", - dn); - } - } - /* - * We have a valid cache entry and a locally generated SGL. - * Attach the SGL to the cache entry - */ - if (compare_nodep && !compare_nodep->sgl_processed) { - if (!tmp_local_sgl) { - /* We looked up an SGL for a group and found it to be empty */ - if (compare_nodep->subgroupList == NULL) { - compare_nodep->sgl_processed = 1; + if (compare_nodep == NULL) { + /* + * The group entry we want to attach our SGL to doesn't exist. + * We only got here if we verified this DN was actually a group + * based on the objectClass, but we can't call the compare function + * while we already hold the cache lock -- only the insert. + */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01291) + "Cache entry for %s doesn't exist", dn); + the_compare_node.result = LDAP_COMPARE_TRUE; + util_ald_cache_insert(curl->compare_cache, &the_compare_node); + compare_nodep = util_ald_cache_fetch(curl->compare_cache, + &the_compare_node); + if (compare_nodep == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01292) + "util_ldap: Couldn't retrieve group entry " + "for %s from cache", + dn); } } - else { - util_compare_subgroup_t *sgl_copy = - util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01293) - "Copying local SGL of len %d for group %s into cache", - tmp_local_sgl->len, dn); - if (sgl_copy) { - if (compare_nodep->subgroupList) { - util_ald_sgl_free(curl->compare_cache, - &(compare_nodep->subgroupList)); + + /* + * We have a valid cache entry and a locally generated SGL. + * Attach the SGL to the cache entry + */ + if (compare_nodep && !compare_nodep->sgl_processed) { + if (!tmp_local_sgl) { + /* We looked up an SGL for a group and found it to be empty */ + if (compare_nodep->subgroupList == NULL) { + compare_nodep->sgl_processed = 1; } - compare_nodep->subgroupList = sgl_copy; - compare_nodep->sgl_processed = 1; } else { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01294) - "Copy of SGL failed to obtain shared memory, " - "couldn't update cache"); + util_compare_subgroup_t *sgl_copy = + util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01293) + "Copying local SGL of len %d for group %s into cache", + tmp_local_sgl->len, dn); + if (sgl_copy) { + if (compare_nodep->subgroupList) { + util_ald_sgl_free(curl->compare_cache, + &(compare_nodep->subgroupList)); + } + compare_nodep->subgroupList = sgl_copy; + compare_nodep->sgl_processed = 1; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01294) + "Copy of SGL failed to obtain shared memory, " + "couldn't update cache"); + } } } } @@ -1770,10 +1769,8 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); if (curl) { - ldap_cache_lock(st, r); the_search_node.username = filter; search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node); @@ -1810,9 +1807,9 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, return LDAP_SUCCESS; } } - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + /* unlock this read lock */ + ldap_cache_unlock(st, r); /* * At this point, there is no valid cached search, so lets do the search. @@ -1969,37 +1966,40 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, /* * Add the new username to the search cache. */ - if (curl) { + { ldap_cache_lock(st, r); - the_search_node.username = filter; - the_search_node.dn = *binddn; - the_search_node.bindpw = bindpw; - the_search_node.lastbind = apr_time_now(); - the_search_node.vals = vals; - the_search_node.numvals = numvals; - - /* Search again to make sure that another thread didn't ready insert - * this node into the cache before we got here. If it does exist then - * update the lastbind - */ - search_nodep = util_ald_cache_fetch(curl->search_cache, - &the_search_node); - if ((search_nodep == NULL) || - (strcmp(*binddn, search_nodep->dn) != 0)) { + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + the_search_node.username = filter; + the_search_node.dn = *binddn; + the_search_node.bindpw = bindpw; + the_search_node.lastbind = apr_time_now(); + the_search_node.vals = vals; + the_search_node.numvals = numvals; + + /* Search again to make sure that another thread didn't ready insert + * this node into the cache before we got here. If it does exist then + * update the lastbind + */ + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if ((search_nodep == NULL) || + (strcmp(*binddn, search_nodep->dn) != 0)) { - /* Nothing in cache, insert new entry */ - util_ald_cache_insert(curl->search_cache, &the_search_node); - } - else if ((!search_nodep->bindpw) || - (strcmp(bindpw, search_nodep->bindpw) != 0)) { + /* Nothing in cache, insert new entry */ + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + else if ((!search_nodep->bindpw) || + (strcmp(bindpw, search_nodep->bindpw) != 0)) { - /* Entry in cache is invalid, remove it and insert new one */ - util_ald_cache_remove(curl->search_cache, search_nodep); - util_ald_cache_insert(curl->search_cache, &the_search_node); - } - else { - /* Cache entry is valid, update lastbind */ - search_nodep->lastbind = the_search_node.lastbind; + /* Entry in cache is invalid, remove it and insert new one */ + util_ald_cache_remove(curl->search_cache, search_nodep); + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + else { + /* Cache entry is valid, update lastbind */ + search_nodep->lastbind = the_search_node.lastbind; + } } ldap_cache_unlock(st, r); } @@ -2046,10 +2046,8 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); if (curl) { - ldap_cache_lock(st, r); the_search_node.username = filter; search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node); @@ -2080,9 +2078,9 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, return LDAP_SUCCESS; } } - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + /* unlock this read lock */ + ldap_cache_unlock(st, r); /* * At this point, there is no valid cached search, so lets do the search. @@ -2178,35 +2176,38 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, /* * Add the new username to the search cache. */ - if (curl) { + { ldap_cache_lock(st, r); - the_search_node.username = filter; - the_search_node.dn = *binddn; - the_search_node.bindpw = NULL; - the_search_node.lastbind = apr_time_now(); - the_search_node.vals = vals; - the_search_node.numvals = numvals; - - /* Search again to make sure that another thread didn't ready insert - * this node into the cache before we got here. If it does exist then - * update the lastbind - */ - search_nodep = util_ald_cache_fetch(curl->search_cache, - &the_search_node); - if ((search_nodep == NULL) || - (strcmp(*binddn, search_nodep->dn) != 0)) { + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + the_search_node.username = filter; + the_search_node.dn = *binddn; + the_search_node.bindpw = NULL; + the_search_node.lastbind = apr_time_now(); + the_search_node.vals = vals; + the_search_node.numvals = numvals; + + /* Search again to make sure that another thread didn't ready insert + * this node into the cache before we got here. If it does exist then + * update the lastbind + */ + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if ((search_nodep == NULL) || + (strcmp(*binddn, search_nodep->dn) != 0)) { - /* Nothing in cache, insert new entry */ - util_ald_cache_insert(curl->search_cache, &the_search_node); - } - /* - * Don't update lastbind on entries with bindpw because - * we haven't verified that password. It's OK to update - * the entry if there is no password in it. - */ - else if (!search_nodep->bindpw) { - /* Cache entry is valid, update lastbind */ - search_nodep->lastbind = the_search_node.lastbind; + /* Nothing in cache, insert new entry */ + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + /* + * Don't update lastbind on entries with bindpw because + * we haven't verified that password. It's OK to update + * the entry if there is no password in it. + */ + else if (!search_nodep->bindpw) { + /* Cache entry is valid, update lastbind */ + search_nodep->lastbind = the_search_node.lastbind; + } } ldap_cache_unlock(st, r); } diff --git a/modules/mappers/mod_dir.c b/modules/mappers/mod_dir.c index d13babf8185..53ecf0e533c 100644 --- a/modules/mappers/mod_dir.c +++ b/modules/mappers/mod_dir.c @@ -303,7 +303,7 @@ static int fixup_dir(request_rec *r) if (d->checkhandler == MODDIR_ON && strcmp(r->handler, DIR_MAGIC_TYPE)) { /* Prevent DIR_MAGIC_TYPE from leaking out when someone has taken over */ - if (!strcmp(r->content_type, DIR_MAGIC_TYPE)) { + if (r->content_type && !strcmp(r->content_type, DIR_MAGIC_TYPE)) { r->content_type = NULL; } return DECLINED; @@ -312,7 +312,7 @@ static int fixup_dir(request_rec *r) /* we're running between mod_rewrites fixup and its internal redirect handler, step aside */ if (!strcmp(r->handler, REWRITE_REDIRECT_HANDLER_NAME)) { /* Prevent DIR_MAGIC_TYPE from leaking out when someone has taken over */ - if (!strcmp(r->content_type, DIR_MAGIC_TYPE)) { + if (r->content_type && !strcmp(r->content_type, DIR_MAGIC_TYPE)) { r->content_type = NULL; } return DECLINED; diff --git a/modules/md/md.h b/modules/md/md.h index fb1a270ac8f..2c866f0cbba 100644 --- a/modules/md/md.h +++ b/modules/md/md.h @@ -20,7 +20,6 @@ #include #include "md_time.h" -#include "md_version.h" struct apr_array_header_t; struct apr_hash_t; @@ -100,7 +99,11 @@ struct md_t { struct apr_array_header_t *acme_tls_1_domains; /* domains supporting "acme-tls/1" protocol */ const char *dns01_cmd; /* DNS challenge command, override global command */ - + const char *proxy_url; /* Proxy URL, override global command */ + const char *ca_certs; /* root certificates to use for connections, + override global command */ + const char *proxy_ca_certs; /* root certificates to use for proxy connections, + override global command */ const struct md_srv_conf_t *sc; /* server config where it was defined or NULL */ const char *defn_name; /* config file this MD was defined */ unsigned defn_line_number; /* line number of definition */ @@ -125,6 +128,7 @@ struct md_t { #define MD_KEY_AUTHORIZATIONS "authorizations" #define MD_KEY_BITS "bits" #define MD_KEY_CA "ca" +#define MD_KEY_CA_CERTS "ca-certs" #define MD_KEY_CA_URL "ca-url" #define MD_KEY_CERT "cert" #define MD_KEY_CERT_FILES "cert-files" @@ -185,6 +189,8 @@ struct md_t { #define MD_KEY_PROFILE "profile" #define MD_KEY_PROFILE_MANDATORY "profile-mandatory" #define MD_KEY_PROTO "proto" +#define MD_KEY_PROXY_CA_CERTS "proxy-ca-certs" +#define MD_KEY_PROXY_URL "proxy-url" #define MD_KEY_READY "ready" #define MD_KEY_REGISTRATION "registration" #define MD_KEY_RENEW "renew" diff --git a/modules/md/md_acme.c b/modules/md/md_acme.c index 7c876c62c9e..abae7bee53a 100644 --- a/modules/md/md_acme.c +++ b/modules/md/md_acme.c @@ -34,7 +34,6 @@ #include "md_store.h" #include "md_result.h" #include "md_util.h" -#include "md_version.h" #include "md_acme.h" #include "md_acme_acct.h" @@ -624,7 +623,8 @@ apr_status_t md_acme_POST_new_account(md_acme_t *acme, /* ACME setup */ apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url, - const char *proxy_url, const char *ca_file) + const char *proxy_url, const char *ca_file, + const char *proxy_ca_file) { md_acme_t *acme; const char *err = NULL; @@ -646,10 +646,11 @@ apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url, acme->url = url; acme->p = p; acme->user_agent = apr_psprintf(p, "%s mod_md/%s", - base_product, MOD_MD_VERSION); - acme->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL; - acme->max_retries = 99; + base_product, AP_SERVER_BASEREVISION); + acme->proxy_url = apr_pstrdup(p, proxy_url); + acme->max_retries = 9; acme->ca_file = ca_file; + acme->proxy_ca_file = proxy_ca_file; if (APR_SUCCESS != (rv = apr_uri_parse(p, url, &uri_parsed))) { md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "parsing ACME uri: %s", url); @@ -802,6 +803,7 @@ apr_status_t md_acme_setup(md_acme_t *acme, md_result_t *result) md_http_set_connect_timeout_default(acme->http, apr_time_from_sec(30)); md_http_set_stalling_default(acme->http, 10, apr_time_from_sec(30)); md_http_set_ca_file(acme->http, acme->ca_file); + md_http_set_proxy_ca_file(acme->http, acme->proxy_ca_file); md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, acme->p, "get directory from %s", acme->url); diff --git a/modules/md/md_acme.h b/modules/md/md_acme.h index c2b98b412d0..76c27a88dd0 100644 --- a/modules/md/md_acme.h +++ b/modules/md/md_acme.h @@ -98,6 +98,7 @@ struct md_acme_t { const char *user_agent; const char *proxy_url; const char *ca_file; + const char *proxy_ca_file; const char *acct_id; /* local storage id account was loaded from or NULL */ struct md_acme_acct_t *acct; /* account at ACME server to use for requests */ @@ -151,9 +152,12 @@ apr_status_t md_acme_init(apr_pool_t *pool, const char *base_version, int init_s * @param p pool to used * @param url url of the server, optional if known at path * @param proxy_url optional url of a HTTP(S) proxy to use + * @param ca_file optional CA trust anchor file to use + * @param proxy_ca_file optional CA trust anchor file to use for the HTTP proxy */ apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url, - const char *proxy_url, const char *ca_file); + const char *proxy_url, const char *ca_file, + const char *proxy_ca_file); /** * Contact the ACME server and retrieve its directory information. diff --git a/modules/md/md_acme_acct.c b/modules/md/md_acme_acct.c index f3e043e87c0..3fd768b2338 100644 --- a/modules/md/md_acme_acct.c +++ b/modules/md/md_acme_acct.c @@ -33,7 +33,6 @@ #include "md_result.h" #include "md_store.h" #include "md_util.h" -#include "md_version.h" #include "md_acme.h" #include "md_acme_acct.h" diff --git a/modules/md/md_acme_authz.c b/modules/md/md_acme_authz.c index 9d07052b90b..e74a2035b02 100644 --- a/modules/md/md_acme_authz.c +++ b/modules/md/md_acme_authz.c @@ -385,7 +385,7 @@ static apr_status_t cha_tls_alpn_01_setup(md_acme_authz_cha_t *cha, md_acme_auth rv = md_store_save(store, p, MD_SG_CHALLENGES, authz->domain, cfn, MD_SV_CERT, (void*)cha_cert, 0); } - ++notify_server; + notify_server = 1; } } diff --git a/modules/md/md_acme_drive.c b/modules/md/md_acme_drive.c index 94bcc8aab47..bef07e52d91 100644 --- a/modules/md/md_acme_drive.c +++ b/modules/md/md_acme_drive.c @@ -771,7 +771,9 @@ static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result) md_result_activity_printf(result, "Contacting ACME server for %s at %s", d->md->name, ca_effective); if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, ca_effective, - d->proxy_url, d->ca_file))) { + ad->md->proxy_url ? ad->md->proxy_url : d->proxy_url, + ad->md->ca_certs ? ad->md->ca_certs : d->ca_certs, + ad->md->proxy_ca_certs ? ad->md->proxy_ca_certs : d->proxy_ca_certs))) { md_result_printf(result, rv, "setup ACME communications"); md_result_log(result, MD_LOG_ERR); goto out; @@ -1033,7 +1035,9 @@ static apr_status_t acme_preload(md_proto_driver_t *d, md_store_group_t load_gro } if (APR_SUCCESS != (rv = md_acme_create(&acme, d->p, md->ca_effective, - d->proxy_url, d->ca_file))) { + d->md->proxy_url ? d->md->proxy_url : d->proxy_url, + d->md->ca_certs ? d->md->ca_certs : d->ca_certs, + d->md->proxy_ca_certs ? d->md->proxy_ca_certs : d->proxy_ca_certs))) { md_result_set(result, rv, "error setting up acme"); goto leave; } @@ -1142,7 +1146,9 @@ static apr_status_t acme_get_ari(md_proto_driver_t *d, } if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, ca_effective, - d->proxy_url, d->ca_file))) { + d->md->proxy_url ? d->md->proxy_url : d->proxy_url, + d->md->ca_certs ? d->md->ca_certs : d->ca_certs, + d->md->proxy_ca_certs ? d->md->proxy_ca_certs : d->proxy_ca_certs))) { md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, "create ACME communications"); goto out; diff --git a/modules/md/md_acme_drive.h b/modules/md/md_acme_drive.h index 986b49e8f4a..719c821f14a 100644 --- a/modules/md/md_acme_drive.h +++ b/modules/md/md_acme_drive.h @@ -16,6 +16,8 @@ #ifndef md_acme_drive_h #define md_acme_drive_h +#define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory" + struct apr_array_header_t; struct md_acme_order_t; struct md_credentials_t; diff --git a/modules/md/md_core.c b/modules/md/md_core.c index d47c4463287..704212365e9 100644 --- a/modules/md/md_core.c +++ b/modules/md/md_core.c @@ -258,6 +258,9 @@ md_t *md_clone(apr_pool_t *p, const md_t *src) md->acme_tls_1_domains = md_array_str_compact(p, src->acme_tls_1_domains, 0); md->stapling = src->stapling; if (src->dns01_cmd) md->dns01_cmd = apr_pstrdup(p, src->dns01_cmd); + if (src->proxy_url) md->proxy_url = apr_pstrdup(p, src->proxy_url); + if (src->ca_certs) md->ca_certs = apr_pstrdup(p, src->ca_certs); + if (src->proxy_ca_certs) md->proxy_ca_certs = apr_pstrdup(p, src->proxy_ca_certs); if (src->cert_files) md->cert_files = md_array_str_clone(p, src->cert_files); if (src->pkey_files) md->pkey_files = md_array_str_clone(p, src->pkey_files); } @@ -315,6 +318,9 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p) if (md->pkey_files) md_json_setsa(md->pkey_files, json, MD_KEY_PKEY_FILES, NULL); md_json_setb(md->stapling > 0, json, MD_KEY_STAPLING, NULL); if (md->dns01_cmd) md_json_sets(md->dns01_cmd, json, MD_KEY_CMD_DNS01, NULL); + if (md->proxy_url) md_json_sets(md->proxy_url, json, MD_KEY_PROXY_URL, NULL); + if (md->ca_certs) md_json_sets(md->ca_certs, json, MD_KEY_CA_CERTS, NULL); + if (md->proxy_ca_certs) md_json_sets(md->proxy_ca_certs, json, MD_KEY_PROXY_CA_CERTS, NULL); if (md->ca_eab_kid && strcmp("none", md->ca_eab_kid)) { md_json_sets(md->ca_eab_kid, json, MD_KEY_EAB, MD_KEY_KID, NULL); if (md->ca_eab_hmac) md_json_sets(md->ca_eab_hmac, json, MD_KEY_EAB, MD_KEY_HMAC, NULL); @@ -384,6 +390,9 @@ md_t *md_from_json(md_json_t *json, apr_pool_t *p) } md->stapling = (int)md_json_getb(json, MD_KEY_STAPLING, NULL); md->dns01_cmd = md_json_dups(p, json, MD_KEY_CMD_DNS01, NULL); + md->proxy_url = md_json_dups(p, json, MD_KEY_PROXY_URL, NULL); + md->ca_certs = md_json_dups(p, json, MD_KEY_CA_CERTS, NULL); + md->proxy_ca_certs = md_json_dups(p, json, MD_KEY_PROXY_CA_CERTS, NULL); if (md_json_has_key(json, MD_KEY_EAB, NULL)) { md->ca_eab_kid = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_KID, NULL); md->ca_eab_hmac = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_HMAC, NULL); diff --git a/modules/md/md_crypt.c b/modules/md/md_crypt.c index eef12683539..a90eb0fc9b4 100644 --- a/modules/md/md_crypt.c +++ b/modules/md/md_crypt.c @@ -2226,7 +2226,7 @@ apr_status_t md_cert_get_ari_cert_id(const char **pari_cert_id, const ASN1_INTEGER *serial; BIGNUM *bn; int i = -1, sder_len; - unsigned char *ucp, sbuf[256]; + unsigned char *ucp, *sbuf; *pari_cert_id = NULL; s_aki = X509_get_ext_d2i(cert->x509, NID_authority_key_identifier, &i, NULL); @@ -2253,6 +2253,10 @@ apr_status_t md_cert_get_ari_cert_id(const char **pari_cert_id, } memset(&ser_buf, 0, sizeof(ser_buf)); bn = ASN1_INTEGER_to_BN(serial, NULL); + if (!bn) { + return APR_EINVAL; + } + sbuf = apr_pcalloc(p, BN_num_bytes(bn)); sder_len = BN_bn2bin(bn, sbuf); BN_free(bn); if (sder_len < 1) diff --git a/modules/md/md_curl.c b/modules/md/md_curl.c index 2484faf51a1..ee1c3cabd23 100644 --- a/modules/md/md_curl.c +++ b/modules/md/md_curl.c @@ -248,6 +248,7 @@ static apr_status_t internals_setup(md_http_request_t *req) CURL *curl; apr_status_t rv = APR_SUCCESS; long ssl_options = 0; + long proxy_ssl_options = 0; curl = md_http_get_impl_data(req->http); if (!curl) { @@ -315,6 +316,16 @@ static apr_status_t internals_setup(md_http_request_t *req) ssl_options |= CURLSSLOPT_NO_REVOKE; #endif } + if (req->proxy_ca_file) { + curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO, req->proxy_ca_file); + /* for a custom CA, allow certificates checking to ignore the + * Schannel error CRYPT_E_NO_REVOCATION_CHECK (could be a missing OCSP + * responder URL in the certs???). See issue #361 */ +#ifdef CURLSSLOPT_NO_REVOKE + proxy_ssl_options |= CURLSSLOPT_NO_REVOKE; +#endif + } + if (req->unix_socket_path) { curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, req->unix_socket_path); } @@ -356,6 +367,9 @@ static apr_status_t internals_setup(md_http_request_t *req) if (ssl_options) curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, ssl_options); + if (proxy_ssl_options) + curl_easy_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, proxy_ssl_options); + leave: req->internals = (APR_SUCCESS == rv)? internals : NULL; return rv; diff --git a/modules/md/md_http.c b/modules/md/md_http.c index 283f4be1352..4884dcaa662 100644 --- a/modules/md/md_http.c +++ b/modules/md/md_http.c @@ -36,6 +36,7 @@ struct md_http_t { const char *unix_socket_path; md_http_timeouts_t timeout; const char *ca_file; + const char *proxy_ca_file; }; static md_http_impl_t *cur_impl; @@ -82,7 +83,7 @@ apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_a http->pool = p; http->impl = cur_impl; http->user_agent = apr_pstrdup(p, user_agent); - http->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL; + http->proxy_url = apr_pstrdup(p, proxy_url); http->bucket_alloc = apr_bucket_alloc_create(p); if (!http->bucket_alloc) { return APR_EGENERAL; @@ -107,6 +108,9 @@ apr_status_t md_http_clone(md_http_t **phttp, if (source_http->ca_file) { (*phttp)->ca_file = apr_pstrdup(p, source_http->ca_file); } + if (source_http->proxy_ca_file) { + (*phttp)->proxy_ca_file = apr_pstrdup(p, source_http->proxy_ca_file); + } } return rv; } @@ -163,6 +167,11 @@ void md_http_set_ca_file(md_http_t *http, const char *ca_file) http->ca_file = ca_file; } +void md_http_set_proxy_ca_file(md_http_t *http, const char *ca_file) +{ + http->proxy_ca_file = ca_file; +} + void md_http_set_unix_socket_path(md_http_t *http, const char *path) { http->unix_socket_path = path; @@ -235,6 +244,7 @@ static apr_status_t req_create(md_http_request_t **preq, md_http_t *http, req->proxy_url = http->proxy_url; req->timeout = http->timeout; req->ca_file = http->ca_file; + req->proxy_ca_file = http->proxy_ca_file; req->unix_socket_path = http->unix_socket_path; *preq = req; return rv; diff --git a/modules/md/md_http.h b/modules/md/md_http.h index 2f250f6d769..a777c149834 100644 --- a/modules/md/md_http.h +++ b/modules/md/md_http.h @@ -65,6 +65,7 @@ struct md_http_request_t { const char *user_agent; const char *proxy_url; const char *ca_file; + const char *proxy_ca_file; const char *unix_socket_path; apr_table_t *headers; struct apr_bucket_brigade *body; @@ -119,12 +120,19 @@ void md_http_set_stalling_default(md_http_t *http, long bytes_per_sec, apr_time_ void md_http_set_stalling(md_http_request_t *req, long bytes_per_sec, apr_time_t timeout); /** - * Set a CA file (in PERM format) to use for root certificates when + * Set a CA file (in PEM format) to use for root certificates when * verifying SSL connections. If not set (or set to NULL), the systems * certificate store will be used. */ void md_http_set_ca_file(md_http_t *http, const char *ca_file); +/** + * Set a CA file (in PEM format) to use for root certificates when + * verifying SSL connections to the HTTP proxy. If not set (or set to NULL), + * the systems certificate store will be used. + */ +void md_http_set_proxy_ca_file(md_http_t *http, const char *ca_file); + /** * Set the path of a unix domain socket for use instead of TCP * in a connection. Disable by providing NULL as path. diff --git a/modules/md/md_ocsp.c b/modules/md/md_ocsp.c index aee799a7b39..2e7f14dff31 100644 --- a/modules/md/md_ocsp.c +++ b/modules/md/md_ocsp.c @@ -533,13 +533,23 @@ static const char *certid_summary(const OCSP_CERTID *certid, apr_pool_t *p) serial = issuer = key = "???"; OCSP_id_get0_info(&aname_hash, &amd_nid, &akey_hash, &aserial, (OCSP_CERTID*)certid); if (aname_hash) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L data.len = (apr_size_t)aname_hash->length; data.data = (const char*)aname_hash->data; +#else + data.len = (apr_size_t)ASN1_STRING_length(aname_hash); + data.data = (const char*)ASN1_STRING_get0_data(aname_hash); +#endif md_data_to_hex(&issuer, 0, p, &data); } if (akey_hash) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L data.len = (apr_size_t)akey_hash->length; data.data = (const char*)akey_hash->data; +#else + data.len = (apr_size_t)ASN1_STRING_length(akey_hash); + data.data = (const char*)ASN1_STRING_get0_data(akey_hash); +#endif md_data_to_hex(&key, 0, p, &data); } if (aserial) { diff --git a/modules/md/md_reg.c b/modules/md/md_reg.c index 36d1944b879..c461fc2b614 100644 --- a/modules/md/md_reg.c +++ b/modules/md/md_reg.c @@ -47,7 +47,8 @@ struct md_reg_t { int can_http; int can_https; const char *proxy_url; - const char *ca_file; + const char *ca_certs; + const char *proxy_ca_certs; int domains_frozen; md_timeslice_t *renew_window; md_timeslice_t *warn_window; @@ -96,9 +97,10 @@ static apr_status_t load_props(md_reg_t *reg, apr_pool_t *p) } apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *p, struct md_store_t *store, - const char *proxy_url, const char *ca_file, - apr_time_t min_delay, int retry_failover, - int use_store_locks, apr_time_t lock_wait_timeout) + const char *proxy_url, const char *ca_certs, + const char *proxy_ca_certs, apr_time_t min_delay, + int retry_failover, int use_store_locks, + apr_time_t lock_wait_timeout) { md_reg_t *reg; apr_status_t rv; @@ -110,9 +112,11 @@ apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *p, struct md_store_t *st reg->certs = apr_hash_make(p); reg->can_http = 1; reg->can_https = 1; - reg->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL; - reg->ca_file = (ca_file && apr_cstr_casecmp("none", ca_file))? - apr_pstrdup(p, ca_file) : NULL; + reg->proxy_url = apr_pstrdup(p, proxy_url); + reg->ca_certs = (ca_certs && apr_cstr_casecmp("none", ca_certs))? + apr_pstrdup(p, ca_certs) : NULL; + reg->proxy_ca_certs = (proxy_ca_certs && apr_cstr_casecmp("none", proxy_ca_certs))? + apr_pstrdup(p, proxy_ca_certs) : NULL; reg->min_delay = min_delay; reg->retry_failover = retry_failover; reg->use_store_locks = use_store_locks; @@ -1109,7 +1113,8 @@ static apr_status_t run_init(void *baton, apr_pool_t *p, ...) driver->reg = reg; driver->store = md_reg_store_get(reg); driver->proxy_url = reg->proxy_url; - driver->ca_file = reg->ca_file; + driver->ca_certs = reg->ca_certs; + driver->proxy_ca_certs = reg->proxy_ca_certs; driver->md = md; driver->can_http = reg->can_http; driver->can_https = reg->can_https; diff --git a/modules/md/md_reg.h b/modules/md/md_reg.h index ce83c255e9b..452b58ec3d3 100644 --- a/modules/md/md_reg.h +++ b/modules/md/md_reg.h @@ -39,14 +39,16 @@ typedef struct md_reg_t md_reg_t; * @param pm memory pool to use for creation * @param store the store to base on * @param proxy_url optional URL of a proxy to use for requests - * @param ca_file optioinal CA trust anchor file to use + * @param ca_certs optional CA trust anchor file to use + * @param proxy_ca_certs optional CA trust anchor file to use for the HTTP proxy * @param min_delay minimum delay between renewal attempts for a domain - * @param retry_failover numer of failed renewals attempt to fail over to alternate ACME ca + * @param retry_failover number of failed renewals attempt to fail over to alternate ACME ca */ apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *pm, md_store_t *store, - const char *proxy_url, const char *ca_file, - apr_time_t min_delay, int retry_failover, - int use_store_locks, apr_time_t lock_wait_timeout); + const char *proxy_url, const char *ca_certs, + const char *proxy_ca_certs, apr_time_t min_delay, + int retry_failover, int use_store_locks, + apr_time_t lock_wait_timeout); md_store_t *md_reg_store_get(md_reg_t *reg); @@ -224,7 +226,8 @@ struct md_proto_driver_t { md_reg_t *reg; md_store_t *store; const char *proxy_url; - const char *ca_file; + const char *ca_certs; + const char *proxy_ca_certs; const md_t *md; int can_http; diff --git a/modules/md/md_status.c b/modules/md/md_status.c index da89b832ca2..096503109e8 100644 --- a/modules/md/md_status.c +++ b/modules/md/md_status.c @@ -23,6 +23,8 @@ #include #include +#include + #include "md_json.h" #include "md.h" #include "md_acme.h" @@ -326,7 +328,7 @@ apr_status_t md_status_get_json(md_json_t **pjson, apr_array_header_t *mds, int i; json = md_json_create(p); - md_json_sets(MOD_MD_VERSION, json, MD_KEY_VERSION, NULL); + md_json_sets(AP_SERVER_BASEREVISION, json, MD_KEY_VERSION, NULL); for (i = 0; i < mds->nelts; ++i) { md = APR_ARRAY_IDX(mds, i, const md_t *); status_get_md_json(&mdj, md, reg, ocsp, 0, p); diff --git a/modules/md/md_store_fs.c b/modules/md/md_store_fs.c index 77063bff703..93bd7def1e4 100644 --- a/modules/md/md_store_fs.c +++ b/modules/md/md_store_fs.c @@ -33,7 +33,6 @@ #include "md_store.h" #include "md_store_fs.h" #include "md_util.h" -#include "md_version.h" /**************************************************************************************************/ /* file system based implementation of md_store_t */ diff --git a/modules/md/md_version.h b/modules/md/md_version.h deleted file mode 100644 index ace0946095b..00000000000 --- a/modules/md/md_version.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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. - */ - -#ifndef mod_md_md_version_h -#define mod_md_md_version_h - -#undef PACKAGE_VERSION -#undef PACKAGE_TARNAME -#undef PACKAGE_STRING -#undef PACKAGE_NAME -#undef PACKAGE_BUGREPORT - -/** - * @macro - * Version number of the md module as c string - */ -#define MOD_MD_VERSION "2.6.10" - -/** - * @macro - * Numerical representation of the version number of the md module - * 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 0x02060a - -#define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory" - -#endif /* mod_md_md_version_h */ diff --git a/modules/md/mod_md.c b/modules/md/mod_md.c index 349d18750c8..af68213d913 100644 --- a/modules/md/mod_md.c +++ b/modules/md/mod_md.c @@ -44,7 +44,6 @@ #include "md_reg.h" #include "md_status.h" #include "md_util.h" -#include "md_version.h" #include "md_acme.h" #include "md_acme_authz.h" @@ -855,6 +854,9 @@ static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog, apr_status_t rv = APR_SUCCESS; int dry_run = 0, log_level = APLOG_DEBUG; md_store_t *store; + const char *proxy_url; + const char *ca_certs; + const char *proxy_ca_certs; apr_pool_userdata_get(&data, mod_md_init_key, s->process->pool); if (data == NULL) { @@ -875,7 +877,7 @@ static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog, } else { ap_log_error( APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10071) - "mod_md (v%s), initializing...", MOD_MD_VERSION); + "mod_md (v%s), initializing...", AP_SERVER_BASEREVISION); } (void)plog; @@ -893,7 +895,11 @@ static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog, rv = setup_store(&store, mc, p, s); if (APR_SUCCESS != rv) goto leave; - rv = md_reg_create(&mc->reg, p, store, mc->proxy_url, mc->ca_certs, + proxy_url = apr_table_get(mc->env, MD_KEY_PROXY_URL); + ca_certs = apr_table_get(mc->env, MD_KEY_CA_CERTS); + proxy_ca_certs = apr_table_get(mc->env, MD_KEY_PROXY_CA_CERTS); + + rv = md_reg_create(&mc->reg, p, store, proxy_url, ca_certs, proxy_ca_certs, mc->min_delay, mc->retry_failover, mc->use_store_locks, mc->lock_wait_timeout); if (APR_SUCCESS != rv) { @@ -903,7 +909,7 @@ static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog, /* renew on 30% remaining /*/ rv = md_ocsp_reg_make(&mc->ocsp, p, store, mc->ocsp_renew_window, - AP_SERVER_BASEVERSION, mc->proxy_url, + AP_SERVER_BASEVERSION, proxy_url, mc->min_delay); if (APR_SUCCESS != rv) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10196) "setup ocsp registry"); diff --git a/modules/md/mod_md.dsp b/modules/md/mod_md.dsp index 7b247a5bc0d..e141ffc10f7 100644 --- a/modules/md/mod_md.dsp +++ b/modules/md/mod_md.dsp @@ -85,7 +85,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so -# ADD LINK32 kernel32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib ssleay32.lib libeay32.lib jansson_d.lib libcurl.lib /nologo /subsystem:windows /dll /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/jansson/lib" /libpath:"../../srclib/curl/lib" /incremental:no /debug /out:".\Debug\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so +# ADD LINK32 kernel32.lib libhttpd.lib libapr-1.lib libaprutil-1.lib ssleay32.lib libeay32.lib jansson_d.lib libcurl_debug.lib /nologo /subsystem:windows /dll /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/jansson/lib" /libpath:"../../srclib/curl/lib" /incremental:no /debug /out:".\Debug\mod_md.so" /base:@..\..\os\win32\BaseAddr.ref,mod_md.so # Begin Special Build Tool TargetPath=.\Debug\mod_md.so SOURCE="$(InputPath)" diff --git a/modules/md/mod_md_config.c b/modules/md/mod_md_config.c index 96887145376..a691b1d016f 100644 --- a/modules/md/mod_md_config.c +++ b/modules/md/mod_md_config.c @@ -61,7 +61,6 @@ static md_mod_conf_t defmc = { #else MD_DEFAULT_BASE_DIR, #endif - NULL, /* proxy url for outgoing http */ NULL, /* md_reg_t */ NULL, /* md_ocsp_reg_t */ 80, /* local http: port */ @@ -77,13 +76,12 @@ static md_mod_conf_t defmc = { NULL, /* message cmd */ NULL, /* env table */ 0, /* dry_run flag */ - 1, /* server_status_enabled */ + 0, /* server_status_enabled */ 1, /* certificate_status_enabled */ &def_ocsp_keep_window, /* default time to keep ocsp responses */ &def_ocsp_renew_window, /* default time to renew ocsp responses */ "crt.sh", /* default cert checker site name */ "https://crt.sh?q=", /* default cert checker site url */ - NULL, /* CA cert file to use */ APR_TIME_C(0), /* initial cert check delay */ apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */ apr_time_from_sec(30), /* minimum delay for retries */ @@ -127,6 +125,9 @@ static md_srv_conf_t defconf = { 1, /* staple others */ 1, /* ACME ARI renewals */ NULL, /* dns01_cmd */ + NULL, /* proxy URL */ + NULL, /* CA cert file to use */ + NULL, /* CA cert file to use for proxy */ NULL, /* currently defined md */ NULL, /* assigned md, post config */ 0, /* is_ssl, set during mod_ssl post_config */ @@ -185,6 +186,9 @@ static void srv_conf_props_clear(md_srv_conf_t *sc) sc->staple_others = DEF_VAL; sc->ari_renewals = DEF_VAL; sc->dns01_cmd = NULL; + sc->proxy_url = NULL; + sc->ca_certs = NULL; + sc->proxy_ca_certs = NULL; } static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from) @@ -209,6 +213,9 @@ static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from) to->staple_others = from->staple_others; to->ari_renewals = from->ari_renewals; to->dns01_cmd = from->dns01_cmd; + to->proxy_url = from->proxy_url; + to->ca_certs = from->ca_certs; + to->proxy_ca_certs = from->proxy_ca_certs; } static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t *p) @@ -236,6 +243,9 @@ static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t if (from->ari_renewals != DEF_VAL) md->ari_renewals = from->ari_renewals; if (from->stapling != DEF_VAL) md->stapling = from->stapling; if (from->dns01_cmd) md->dns01_cmd = from->dns01_cmd; + if (from->proxy_url) md->proxy_url = from->proxy_url; + if (from->ca_certs) md->ca_certs = from->ca_certs; + if (from->proxy_ca_certs) md->proxy_ca_certs = from->proxy_ca_certs; } void *md_config_create_svr(apr_pool_t *pool, server_rec *s) @@ -285,6 +295,9 @@ static void *md_config_merge(apr_pool_t *pool, void *basev, void *addv) nsc->staple_others = (add->staple_others != DEF_VAL)? add->staple_others : base->staple_others; nsc->ari_renewals = (add->ari_renewals != DEF_VAL)? add->ari_renewals : base->ari_renewals; nsc->dns01_cmd = (add->dns01_cmd)? add->dns01_cmd : base->dns01_cmd; + nsc->proxy_url = (add->proxy_url)? add->proxy_url : base->proxy_url; + nsc->ca_certs = (add->ca_certs)? add->ca_certs : base->ca_certs; + nsc->proxy_ca_certs = (add->proxy_ca_certs)? add->proxy_ca_certs : base->proxy_ca_certs; nsc->current = NULL; return nsc; @@ -865,14 +878,20 @@ static const char *md_config_set_proxy(cmd_parms *cmd, void *arg, const char *va md_srv_conf_t *sc = md_config_get(cmd->server); const char *err; - if ((err = md_conf_check_location(cmd, MD_LOC_NOT_MD))) { + if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) { return err; } md_util_abs_http_uri_check(cmd->pool, value, &err); if (err) { return err; } - sc->mc->proxy_url = value; + + if (inside_md_section(cmd)) { + sc->proxy_url = value; + } else { + apr_table_set(sc->mc->env, MD_KEY_PROXY_URL, value); + } + (void)arg; return NULL; } @@ -1240,12 +1259,41 @@ static const char *md_config_set_activation_delay(cmd_parms *cmd, void *mconfig, return NULL; } -static const char *md_config_set_ca_certs(cmd_parms *cmd, void *dc, const char *path) +static const char *md_config_set_ca_certs(cmd_parms *cmd, void *arg, const char *value) { md_srv_conf_t *sc = md_config_get(cmd->server); + const char *err; - (void)dc; - sc->mc->ca_certs = path; + if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) { + return err; + } + + if (inside_md_section(cmd)) { + sc->ca_certs = value; + } else { + apr_table_set(sc->mc->env, MD_KEY_CA_CERTS, value); + } + + (void)arg; + return NULL; +} + +static const char *md_config_set_proxy_ca_certs(cmd_parms *cmd, void *arg, const char *value) +{ + md_srv_conf_t *sc = md_config_get(cmd->server); + const char *err; + + if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) { + return err; + } + + if (inside_md_section(cmd)) { + sc->proxy_ca_certs = value; + } else { + apr_table_set(sc->mc->env, MD_KEY_PROXY_CA_CERTS, value); + } + + (void)arg; return NULL; } @@ -1387,6 +1435,8 @@ const command_rec md_cmds[] = { "How long to delay activation of new certificates"), AP_INIT_TAKE1("MDCACertificateFile", md_config_set_ca_certs, NULL, RSRC_CONF, "Set the CA file to use for connections"), + AP_INIT_TAKE1("MDHttpProxyCACertificateFile", md_config_set_proxy_ca_certs, NULL, RSRC_CONF, + "Set the CA file to use for connections to the HTTP(S) proxy"), AP_INIT_TAKE12("MDExternalAccountBinding", md_config_set_eab, NULL, RSRC_CONF, "Set the external account binding keyid and hmac values to use at CA"), AP_INIT_TAKE1("MDRetryDelay", md_config_set_min_delay, NULL, RSRC_CONF, @@ -1471,8 +1521,6 @@ const char *md_config_gets(const md_srv_conf_t *sc, md_config_var_t var) return sc->ca_proto? sc->ca_proto : defconf.ca_proto; case MD_CONFIG_BASE_DIR: return sc->mc->base_dir; - case MD_CONFIG_PROXY: - return sc->mc->proxy_url; case MD_CONFIG_CA_AGREEMENT: return sc->ca_agreement? sc->ca_agreement : defconf.ca_agreement; case MD_CONFIG_NOTIFY_CMD: diff --git a/modules/md/mod_md_config.h b/modules/md/mod_md_config.h index 3159ec651f7..3bff6c4c7d3 100644 --- a/modules/md/mod_md_config.h +++ b/modules/md/mod_md_config.h @@ -32,7 +32,6 @@ typedef enum { MD_CONFIG_RENEW_WINDOW, MD_CONFIG_WARN_WINDOW, MD_CONFIG_TRANSITIVE, - MD_CONFIG_PROXY, MD_CONFIG_REQUIRE_HTTPS, MD_CONFIG_MUST_STAPLE, MD_CONFIG_NOTIFY_CMD, @@ -53,7 +52,6 @@ typedef struct md_mod_conf_t md_mod_conf_t; struct md_mod_conf_t { apr_array_header_t *mds; /* all md_t* defined in the config, shared */ const char *base_dir; /* base dir for store */ - const char *proxy_url; /* proxy url to use (or NULL) */ struct md_reg_t *reg; /* md registry instance */ struct md_ocsp_reg_t *ocsp; /* ocsp status registry */ @@ -77,7 +75,6 @@ struct md_mod_conf_t { md_timeslice_t *ocsp_renew_window; /* time before exp. that we start renewing ocsp resp. */ 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 initial_delay; /* how long to delay the first cert renewal check */ apr_time_t check_interval; /* duration between cert renewal checks */ apr_time_t min_delay; /* minimum delay for retries */ @@ -115,6 +112,11 @@ typedef struct md_srv_conf_t { int ari_renewals; /* ACME ARI extension enabled */ const char *dns01_cmd; /* DNS challenge command, override global command */ + const char *proxy_url; /* Proxy URL, override global command */ + const char *ca_certs; /* root certificates to use for connections, + override global command */ + const char *proxy_ca_certs; /* root certificates to use for proxy connections, + override global command */ md_t *current; /* md currently defined in section */ struct apr_array_header_t *assigned; /* post_config: MDs that apply to this server */ diff --git a/modules/md/mod_md_drive.c b/modules/md/mod_md_drive.c index c5d710817c9..14e3725b094 100644 --- a/modules/md/mod_md_drive.c +++ b/modules/md/mod_md_drive.c @@ -41,7 +41,6 @@ #include "md_result.h" #include "md_reg.h" #include "md_util.h" -#include "md_version.h" #include "md_acme.h" #include "md_acme_authz.h" diff --git a/modules/md/mod_md_status.c b/modules/md/mod_md_status.c index c83e73d17aa..2f3904cec59 100644 --- a/modules/md/mod_md_status.c +++ b/modules/md/mod_md_status.c @@ -40,7 +40,6 @@ #include "md_log.h" #include "md_reg.h" #include "md_util.h" -#include "md_version.h" #include "md_acme.h" #include "md_acme_authz.h" diff --git a/modules/metadata/mod_cern_meta.c b/modules/metadata/mod_cern_meta.c index 3f36b2dba8a..a150b3c9fa1 100644 --- a/modules/metadata/mod_cern_meta.c +++ b/modules/metadata/mod_cern_meta.c @@ -256,6 +256,18 @@ static int scan_meta_file(request_rec *r, apr_file_t *f) sscanf(l, "%d", &r->status); r->status_line = apr_pstrdup(r->pool, l); } + else if (!ap_cstr_casecmp(w, "Transfer-Encoding") + || !ap_cstr_casecmp(w, "Content-Length") + || !ap_cstr_casecmp(w, "Connection") + || !ap_cstr_casecmp(w, "Trailer") + || !ap_cstr_casecmp(w, "Upgrade") + || !ap_cstr_casecmp(w, "Keep-Alive") + || !ap_cstr_casecmp(w, "TE")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10596) + "forbidden HTTP framing header '%s' in meta file: %s", + w, r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } else { apr_table_set(tmp_headers, w, l); } diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index 27a42d3cd37..805c6543ea5 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -931,6 +931,12 @@ static int remoteip_hook_pre_connection(conn_rec *c, void *csd) return OK; } +/** Return length for a v2 protocol header. */ +static apr_size_t remoteip_get_v2_len(proxy_header *hdr) +{ + return ntohs(hdr->v2.len); +} + /* Binary format: * * sig = \x0D \x0A \x0D \x0A \x00 \x0D \x0A \x51 \x55 \x49 \x54 \x0A @@ -950,10 +956,19 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, switch (hdr->v2.ver_cmd & 0xF) { case 0x00: /* LOCAL command */ /* keep local connection address for LOCAL */ + conn_conf->client_addr = c->client_addr; + conn_conf->client_ip = c->client_ip; return HDR_DONE; case 0x01: /* PROXY command */ switch (hdr->v2.fam) { case 0x11: /* TCPv4 */ + if (remoteip_get_v2_len(hdr) < sizeof(hdr->v2.addr.ip4)) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10597) + "RemoteIPProxyProtocol: address length " + "%" APR_SIZE_T_FMT " too short for TCPv4", + remoteip_get_v2_len(hdr)); + return HDR_ERROR; + } ret = apr_sockaddr_info_get(&conn_conf->client_addr, NULL, APR_INET, ntohs(hdr->v2.addr.ip4.src_port), @@ -971,6 +986,13 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, case 0x21: /* TCPv6 */ #if APR_HAVE_IPV6 + if (remoteip_get_v2_len(hdr) < sizeof(hdr->v2.addr.ip6)) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10598) + "RemoteIPProxyProtocol: address length " + "%" APR_SIZE_T_FMT " too short for TCPv6", + remoteip_get_v2_len(hdr)); + return HDR_ERROR; + } ret = apr_sockaddr_info_get(&conn_conf->client_addr, NULL, APR_INET6, ntohs(hdr->v2.addr.ip6.src_port), @@ -1017,12 +1039,6 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, return HDR_DONE; } -/** Return length for a v2 protocol header. */ -static apr_size_t remoteip_get_v2_len(proxy_header *hdr) -{ - return ntohs(hdr->v2.len); -} - /** Determine if this is a v1 or v2 PROXY header. */ static int remoteip_determine_version(conn_rec *c, const char *ptr) diff --git a/modules/proxy/README.beacon b/modules/proxy/README.beacon index 143befd1b73..adf60bf1b6f 100644 --- a/modules/proxy/README.beacon +++ b/modules/proxy/README.beacon @@ -93,19 +93,21 @@ Message format: BEACON url=http://host:port host= pid= seq= ts= mac= url= is the routable backend origin the proxy adds as a BalancerMember. ts= - (microseconds since the epoch) and mac= are present only when a shared secret - is configured (see below). host=/pid=/seq= are informational. + (microseconds since the epoch) and mac= authenticate the message and are always + present, since a shared secret is required (see below). host=/pid=/seq= are + informational. A UDP datagram is delivered whole, so the receiver reads each message into a fixed stack buffer and NUL-terminates it (buf[len] = '\0') before parsing. The sender transmits strlen(msg) bytes (no trailing NUL on the wire). -Authentication (ProxyBeaconSecret, optional but recommended): - Without a secret the channel is unauthenticated: anyone who can reach the - receiver port could announce a URL and hijack client traffic (the proxy logs a - warning at startup in this case). A UDP source address is trivially spoofable, - so authentication matters at least as much here as it would over a connection. +Authentication (ProxyBeaconSecret, REQUIRED): + ProxyBeaconSecret must be set on every participating server (the receiver and + every sender); startup fails otherwise. There is no unauthenticated mode: + without a MAC, anyone who can reach the receiver port could announce a URL and + hijack client traffic, and a UDP source address is trivially spoofable, so + authentication matters at least as much here as it would over a connection. With ProxyBeaconSecret set identically on the proxy and all backends, each announcement is signed with a SipHash-2-4 MAC over the message prefix (the key diff --git a/modules/proxy/balancers/mod_lbmethod_heartbeat.c b/modules/proxy/balancers/mod_lbmethod_heartbeat.c index ef38cd92fa3..cf966d36f67 100644 --- a/modules/proxy/balancers/mod_lbmethod_heartbeat.c +++ b/modules/proxy/balancers/mod_lbmethod_heartbeat.c @@ -61,6 +61,28 @@ typedef struct ctx_servers { apr_hash_t *servers; } ctx_servers_t; +static int hb_parse_int(const char *val, int min, int max, int *result) +{ + apr_int64_t parsed; + char *end = NULL; + + if (!val || !*val) { + return 0; + } + + errno = 0; + parsed = apr_strtoi64(val, &end, 10); + if (errno == ERANGE || end == val || *end != '\0') { + return 0; + } + if (parsed < min || parsed > max) { + return 0; + } + + *result = (int)parsed; + return 1; +} + static void argstr_to_table(apr_pool_t *p, char *str, apr_table_t *parms) { @@ -179,19 +201,31 @@ static apr_status_t readfile_heartbeats(const char *path, apr_hash_t *servers, argstr_to_table(pool, apr_pstrdup(pool, t), hbt); if ((val = apr_table_get(hbt, "busy"))) { - server->busy = atoi(val); + int parsed; + if (hb_parse_int(val, 0, INT_MAX, &parsed)) { + server->busy = parsed; + } } if ((val = apr_table_get(hbt, "ready"))) { - server->ready = atoi(val); + int parsed; + if (hb_parse_int(val, 0, INT_MAX, &parsed)) { + server->ready = parsed; + } } if ((val = apr_table_get(hbt, "lastseen"))) { - server->seen = atoi(val); + int parsed; + if (hb_parse_int(val, 0, INT_MAX, &parsed)) { + server->seen = parsed; + } } if ((val = apr_table_get(hbt, "port"))) { - server->port = atoi(val); + int parsed; + if (hb_parse_int(val, 1, 65535, &parsed)) { + server->port = parsed; + } } if (server->busy == 0 && server->ready != 0) { @@ -312,7 +346,13 @@ static proxy_worker *find_best_hb(proxy_balancer *balancer, if (PROXY_WORKER_IS_USABLE(*worker)) { server->worker = *worker; if (server->seen < LBM_HEARTBEAT_MAX_LASTSEEN) { - openslots += server->ready; + apr_uint32_t ready = (apr_uint32_t)server->ready; + if (ready > APR_UINT32_MAX - openslots) { + openslots = APR_UINT32_MAX; + } + else { + openslots += ready; + } APR_ARRAY_PUSH(up_servers, hb_server_t *) = server; } } @@ -325,12 +365,20 @@ static proxy_worker *find_best_hb(proxy_balancer *balancer, pick = ap_random_pick(0, openslots); for (i = 0; i < up_servers->nelts; i++) { + apr_uint32_t upper; server = APR_ARRAY_IDX(up_servers, i, hb_server_t *); - if (pick >= c && pick <= c + server->ready) { + if ((apr_uint32_t)server->ready > APR_UINT32_MAX - c) { + upper = APR_UINT32_MAX; + } + else { + upper = c + (apr_uint32_t)server->ready; + } + + if (pick >= c && pick <= upper) { mycandidate = server->worker; } - c += server->ready; + c = upper; } } diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index bac659614e6..892bde38ae2 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -171,10 +171,10 @@ static char *get_cookie_param(request_rec *r, const char *name) if (start_cookie == cookies || start_cookie[-1] == ';' || start_cookie[-1] == ',' || - isspace(start_cookie[-1])) { + apr_isspace(start_cookie[-1])) { start_cookie += strlen(name); - while(*start_cookie && isspace(*start_cookie)) + while(*start_cookie && apr_isspace(*start_cookie)) ++start_cookie; if (*start_cookie++ == '=' && *start_cookie) { /* diff --git a/modules/proxy/mod_proxy_beacon-guide.md b/modules/proxy/mod_proxy_beacon-guide.md index 930fb0000e5..4495dd0cc2f 100644 --- a/modules/proxy/mod_proxy_beacon-guide.md +++ b/modules/proxy/mod_proxy_beacon-guide.md @@ -124,7 +124,7 @@ as an enabled member of `balancer://cluster` on the proxy. Stop one, and after | `ProxyBeaconListen [addr][:port]` | — | **Marks this server as the receiver.** Binds a UDP socket. `addr`/`port` are optional and inherited from the server's own `Listen`/`ServerName` when omitted (see note below). | | `ProxyBeaconBalancer name` | — | Balancer that announced backends are added to. Bare name (`cluster`); a leading `balancer://` is stripped. Must already exist with spare `growth`. | | `ProxyBeaconTimeout interval` | `0` (no eviction) | Seconds of silence before a member is disabled. `0` = add-only, never auto-remove. Set to a small multiple of the backends' interval to get self-healing. | -| `ProxyBeaconSecret secret` | — (unauthenticated) | Shared cluster secret; **same value on proxy and all backends.** | +| `ProxyBeaconSecret secret` | — (**required**) | Shared cluster secret; **same value on proxy and all backends.** The server fails to start if a participating server omits it. | | `ProxyBeaconMaxSkew interval` | `30` | Anti-replay freshness window: reject announcements whose signed timestamp is more than this far from now (either direction). | **Inheriting the listen address:** because UDP and TCP are separate port spaces, @@ -141,7 +141,7 @@ this way — use an explicit high port there.) | `ProxyBeaconAddress addr:port` | — | **Marks this server as a sender.** UDP target = the proxy's `ProxyBeaconListen` address. | | `ProxyBeaconAdvertise url` | — | The routable `scheme://host[:port]` the proxy adds as a member. Omit it and the backend beacons but advertises nothing (logged, never added). | | `ProxyBeaconInterval interval` | `5` | How often this backend announces. Must be **meaningfully smaller** than the proxy's `ProxyBeaconTimeout`. | -| `ProxyBeaconSecret secret` | — | Same shared secret as the proxy. | +| `ProxyBeaconSecret secret` | — (**required**) | Same shared secret as the proxy. | > `ProxyBeaconListen` and `ProxyBeaconAddress` are **mutually exclusive** on the > same server — a server is either a receiver or a sender, not both. @@ -160,8 +160,9 @@ unauthenticated channel is a route-hijack / SSRF risk: anyone who can reach the receive port could announce an arbitrary backend URL, and **UDP source addresses are trivially spoofable.** -**Always set `ProxyBeaconSecret`** in production (identical on proxy and every -backend). With it: +`ProxyBeaconSecret` is therefore **required** (identical on proxy and every +backend) — the server refuses to start if a participating server omits it, so +there is no unauthenticated mode to fall into. With it: - Each announcement is signed with a **SipHash-2-4 MAC** plus a timestamp; the proxy recomputes the MAC (constant-time compare) and drops anything forged or @@ -177,8 +178,6 @@ Operational notes: - **Clocks must be roughly in sync** (NTP). The timestamp check compares the announcement's time against the proxy's clock; widen `ProxyBeaconMaxSkew` if your hosts drift. -- With **no secret**, the channel is unauthenticated and the proxy logs a - one-time `UNAUTHENTICATED` warning at startup. - The secret lives in your config file — **restrict its permissions like a private key.** - Announcements are **authenticated, not encrypted.** The payload is operational @@ -233,7 +232,7 @@ Useful log signals (grep the error log): | `re-enabled backend ...` | a previously-evicted backend came back | | `dropped ... mac mismatch` | wrong/missing secret on a sender (or a forged datagram) | | `replayed/reordered ts` | a stale/duplicate datagram was rejected | -| `UNAUTHENTICATED` (startup) | no `ProxyBeaconSecret` — channel is open | +| `ProxyBeaconSecret is required` (startup) | a participating server has no `ProxyBeaconSecret` — startup aborts | **Common gotchas:** diff --git a/modules/proxy/mod_proxy_beacon.c b/modules/proxy/mod_proxy_beacon.c index 3cbbd0dd352..6adb468aa56 100644 --- a/modules/proxy/mod_proxy_beacon.c +++ b/modules/proxy/mod_proxy_beacon.c @@ -72,8 +72,9 @@ * a keyed MAC (SipHash-2-4 via APR-util -- the same primitive mod_session_crypto * uses) plus a timestamp; the receiver recomputes the MAC and checks timestamp * freshness (anti-replay), dropping any forged, tampered, or stale message - * before it is parsed/acted on. Authentication is opt-in: with no secret the - * channel behaves as before but logs a one-time "UNAUTHENTICATED" warning. We + * before it is parsed/acted on. Authentication is REQUIRED: ProxyBeaconSecret + * must be set on every server that participates in the channel (sender or + * listener), or startup fails -- there is no unauthenticated mode. We * authenticate, not encrypt -- the payload (backend URLs) is not secret; for * transport confidentiality DTLS would be a separate, orthogonal future layer. * @@ -150,7 +151,6 @@ typedef struct { apr_int64_t max_skew; /* ProxyBeaconMaxSkew, seconds (replay window) */ apr_uint64_t reject_count; /* listener: dropped-since-last-log counter */ apr_time_t last_reject_log; /* listener: reject-log rate limiter */ - int warned_insecure; /* listener: emitted the one-time warning */ int open_failed; /* STARTING: socket open/listen/dial failed permanently */ } beacon_ctx_t; @@ -166,9 +166,9 @@ typedef struct { * announcement -- back off this long between attempts for a given url. */ #define BEACON_RETRY_BACKOFF apr_time_from_sec(60) -/* Cap on tracked backend urls, to bound memory against an unauthenticated - * channel announcing unboundedly many distinct urls. Once reached, unknown - * urls are dropped (rate-limited log) rather than tracked/added. */ +/* Cap on tracked backend urls, to bound memory against a buggy or compromised + * (authenticated) backend announcing unboundedly many distinct urls. Once + * reached, unknown urls are dropped (rate-limited log) rather than tracked/added. */ #define BEACON_MAX_MEMBERS 256 /* Process-wide watchdog handle, like mod_proxy_hcheck's static watchdog. */ @@ -383,9 +383,10 @@ static const command_rec beacon_cmds[] = { "proxy: seconds without an announcement after which a backend " "is disabled (taken out of rotation); 0 disables eviction"), AP_INIT_TAKE1("ProxyBeaconSecret", beacon_set_secret, NULL, RSRC_CONF, - "pre-shared cluster secret; set on both proxy and backends to " - "authenticate announcements (SipHash MAC). Keep the conf file " - "readable only by the server user."), + "pre-shared cluster secret (REQUIRED); set to the same value on " + "the proxy and all backends to authenticate announcements " + "(SipHash MAC). Keep the conf file readable only by the server " + "user."), AP_INIT_TAKE1("ProxyBeaconMaxSkew", beacon_set_maxskew, NULL, RSRC_CONF, "proxy: max allowed seconds between an announcement's timestamp " "and now (anti-replay window; requires NTP-synced clocks). " @@ -544,15 +545,6 @@ static void beacon_cb_starting(beacon_ctx_t *ctx) "Set ProxyBeaconBalancer to add announced backends.", ctx->addr); } - /* Phase 4: warn once if we'll add members from an unauthenticated - * channel (anyone who can reach this port could announce a backend). */ - if (ctx->balancer_name && !ctx->has_secret && !ctx->warned_insecure) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, - APLOGNO(10572) "mod_proxy_beacon: beacon channel on %pI is " - "UNAUTHENTICATED; set ProxyBeaconSecret on the proxy and " - "all backends to require signed beacons", ctx->addr); - ctx->warned_insecure = 1; - } } else if (ctx->role == BEACON_ROLE_SEND) { /* Sender: the destination host:port targets the proxy and cannot be @@ -763,8 +755,8 @@ static apr_status_t beacon_try_add(beacon_ctx_t *ctx, apr_pool_t *pool, * - a previously-evicted member is re-enabled when it announces again; * - an add that failed (e.g. balancer full) is retried only after a backoff, * not on every announcement. - * msg_ts is the signed timestamp (microseconds) from the verified message, or 0 - * when the channel is unauthenticated. + * msg_ts is the signed timestamp (microseconds) from the verified message; this + * path is only reached on the authenticated balancer path, so it is always set. */ static void beacon_handle_announce(beacon_ctx_t *ctx, apr_pool_t *pool, const char *url, apr_time_t now, @@ -773,8 +765,8 @@ static void beacon_handle_announce(beacon_ctx_t *ctx, apr_pool_t *pool, beacon_member_t *m = apr_hash_get(ctx->seen, url, APR_HASH_KEY_STRING); if (!m) { - /* Bound memory: don't track unboundedly many distinct urls (a concern - * on an unauthenticated channel). */ + /* Bound memory: don't track unboundedly many distinct urls (defense in + * depth against a buggy or compromised authenticated backend). */ if (apr_hash_count(ctx->seen) >= BEACON_MAX_MEMBERS) { beacon_log_throttled(ctx, now, "member table full"); return; @@ -788,12 +780,12 @@ static void beacon_handle_announce(beacon_ctx_t *ctx, apr_pool_t *pool, return; } - /* Anti-replay (2): on an authenticated channel, each url's signed ts must - * strictly increase. A replayed (byte-identical) announcement carries a ts - * we've already accepted, so reject it -- this closes the in-window replay - * the freshness check alone allows (e.g. replaying a dead backend's last - * announcement to keep it from being evicted). */ - if (ctx->has_secret && msg_ts <= m->last_ts) { + /* Anti-replay (2): each url's signed ts must strictly increase. A replayed + * (byte-identical) announcement carries a ts we've already accepted, so + * reject it -- this closes the in-window replay the freshness check alone + * allows (e.g. replaying a dead backend's last announcement to keep it from + * being evicted). */ + if (msg_ts <= m->last_ts) { beacon_log_throttled(ctx, now, "replayed/reordered ts"); return; } @@ -912,14 +904,13 @@ static void beacon_mac_hex(const beacon_ctx_t *ctx, const char *base, ap_bin2hex(mac, sizeof(mac), out); /* writes BEACON_MAC_HEXLEN + NUL */ } -/* sender: return " mac=" (signed) when a secret is set, else base. */ +/* sender: return " mac=", appending the keyed MAC. A secret is + * required on every participating server (enforced at config time), so this + * always signs. */ static const char *beacon_sign(beacon_ctx_t *ctx, apr_pool_t *pool, const char *base) { char hex[BEACON_MAC_HEXLEN + 1]; - if (!ctx->has_secret) { - return base; - } beacon_mac_hex(ctx, base, strlen(base), hex); return apr_psprintf(pool, "%s mac=%s", base, hex); } @@ -1087,20 +1078,22 @@ static void beacon_cb_running(beacon_ctx_t *ctx, apr_pool_t *pool) buf[sz] = '\0'; msg_str = buf; - /* Escape the untrusted payload before it can reach the log: a - * publisher -- or, on an unauthenticated channel, anyone who can - * reach the listen port -- could embed newline/control/ANSI - * sequences to forge or corrupt error-log lines. */ + /* Escape the untrusted payload before it can reach the log: on the + * log-only path (no ProxyBeaconBalancer) messages are logged without + * MAC verification, so anyone who can reach the listen port could + * embed newline/control/ANSI sequences to forge or corrupt error-log + * lines. (On the balancer path, forged messages are dropped at + * verification below and `safe` is only logged after it passes.) */ safe = ap_escape_logitem(pool, msg_str); - /* Phase 4: when a secret is set, verify the MAC and freshness - * BEFORE logging or acting on the payload, so forged/tampered - * content is dropped (throttled) and never reaches the INFO log. + /* Phase 4: verify the MAC and freshness BEFORE logging or acting on + * the payload, so forged/tampered content is dropped (throttled) and + * never reaches the INFO log. A secret is required (enforced at + * config time), so this always runs in the active (balancer) path. * msg_ts (microseconds) is the signed timestamp, used below for the - * per-url monotonic replay check. Verification only matters in the - * active (balancer) path; with no balancer we take no action and - * the escaped payload is safe to log for diagnostics. */ - if (ctx->balancer_name && ctx->has_secret) { + * per-url monotonic replay check. With no balancer we take no action + * and the escaped payload is safe to log for diagnostics. */ + if (ctx->balancer_name) { const char *reason = "?"; if (!beacon_verify(ctx, msg_str, msg_now, &msg_ts, &reason)) { beacon_log_throttled(ctx, msg_now, reason); @@ -1210,6 +1203,20 @@ static int beacon_post_config(apr_pool_t *pconf, apr_pool_t *plog, if (ctx->role == BEACON_ROLE_NONE) { continue; } + /* ProxyBeaconSecret is required on every participating server (sender or + * listener): the channel is authenticated, with no unauthenticated mode. + * A UDP source address is trivially spoofable, so an unsigned channel + * would let anyone who can reach the listen port announce an arbitrary + * backend url and hijack client traffic. Fail startup rather than run + * insecurely. */ + if (!ctx->has_secret) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, + APLOGNO(10572) "mod_proxy_beacon: ProxyBeaconSecret is " + "required but not set; the beacon channel must be " + "authenticated. Set ProxyBeaconSecret to the same value " + "on the proxy and all backends."); + return !OK; + } rv = beacon_register_callback(beacon_watchdog, AP_WD_TM_SLICE, ctx, beacon_watchdog_callback); if (rv) { diff --git a/modules/slotmem/mod_slotmem_plain.c b/modules/slotmem/mod_slotmem_plain.c index 4c2b19b61da..e3460089641 100644 --- a/modules/slotmem/mod_slotmem_plain.c +++ b/modules/slotmem/mod_slotmem_plain.c @@ -38,6 +38,26 @@ struct ap_slotmem_instance_t { static struct ap_slotmem_instance_t *globallistmem = NULL; static apr_pool_t *gpool = NULL; +static int slotmem_size_mul(apr_size_t a, apr_size_t b, apr_size_t *res) +{ + if (a != 0 && b > ((apr_size_t)-1) / a) { + return 0; + } + + *res = a * b; + return 1; +} + +static int slotmem_size_add(apr_size_t a, apr_size_t b, apr_size_t *res) +{ + if (a > ((apr_size_t)-1) - b) { + return 0; + } + + *res = a + b; + return 1; +} + static apr_status_t slotmem_do(ap_slotmem_instance_t *mem, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool) { unsigned int i; @@ -67,10 +87,19 @@ static apr_status_t slotmem_create(ap_slotmem_instance_t **new, const char *name { ap_slotmem_instance_t *res; ap_slotmem_instance_t *next = globallistmem; - apr_size_t basesize = (item_size * item_num); + apr_size_t basesize; + apr_size_t inuse_size; + apr_size_t alloc_size; const char *fname; + if (!slotmem_size_mul(item_size, (apr_size_t)item_num, &basesize) + || !slotmem_size_mul((apr_size_t)item_num, sizeof(char), + &inuse_size) + || !slotmem_size_add(basesize, inuse_size, &alloc_size)) { + return APR_EINVAL; + } + if (name) { if (name[0] == ':') fname = name; @@ -97,7 +126,7 @@ static apr_status_t slotmem_create(ap_slotmem_instance_t **new, const char *name /* create the memory using the gpool */ res = (ap_slotmem_instance_t *) apr_pcalloc(gpool, sizeof(ap_slotmem_instance_t)); - res->base = apr_pcalloc(gpool, basesize + (item_num * sizeof(char))); + res->base = apr_pcalloc(gpool, alloc_size); if (!res->base) return APR_ENOSHMAVAIL; @@ -156,6 +185,10 @@ static apr_status_t slotmem_dptr(ap_slotmem_instance_t *score, unsigned int id, if (id >= score->num) return APR_EINVAL; + if (score->size != 0 + && (apr_size_t)id > ((apr_size_t)-1) / score->size) + return APR_EINVAL; + ptr = (char *)score->base + score->size * id; if (!ptr) return APR_ENOSHMAVAIL; @@ -172,11 +205,14 @@ static apr_status_t slotmem_get(ap_slotmem_instance_t *slot, unsigned int id, un if (!slot) { return APR_ENOSHMAVAIL; } - - inuse = slot->inuse + id; if (id >= slot->num) { return APR_EINVAL; } + if (dest_len > slot->size) { + return APR_EINVAL; + } + + inuse = slot->inuse + id; if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) { return APR_NOTFOUND; } @@ -198,11 +234,14 @@ static apr_status_t slotmem_put(ap_slotmem_instance_t *slot, unsigned int id, un if (!slot) { return APR_ENOSHMAVAIL; } - - inuse = slot->inuse + id; if (id >= slot->num) { return APR_EINVAL; } + if (src_len > slot->size) { + return APR_EINVAL; + } + + inuse = slot->inuse + id; if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) { return APR_NOTFOUND; } diff --git a/modules/slotmem/mod_slotmem_shm.c b/modules/slotmem/mod_slotmem_shm.c index 4d14faf36b4..46aca109706 100644 --- a/modules/slotmem/mod_slotmem_shm.c +++ b/modules/slotmem/mod_slotmem_shm.c @@ -72,6 +72,26 @@ struct ap_slotmem_instance_t { static struct ap_slotmem_instance_t *globallistmem = NULL; static apr_pool_t *gpool = NULL; +static int slotmem_size_mul(apr_size_t a, apr_size_t b, apr_size_t *res) +{ + if (a != 0 && b > ((apr_size_t)-1) / a) { + return 0; + } + + *res = a * b; + return 1; +} + +static int slotmem_size_add(apr_size_t a, apr_size_t b, apr_size_t *res) +{ + if (a > ((apr_size_t)-1) - b) { + return 0; + } + + *res = a + b; + return 1; +} + #define DEFAULT_SLOTMEM_PREFIX "slotmem-shm-" #define DEFAULT_SLOTMEM_SUFFIX ".shm" #define DEFAULT_SLOTMEM_PERSIST_SUFFIX ".persist" @@ -348,9 +368,10 @@ static apr_status_t slotmem_create(ap_slotmem_instance_t **new, ap_slotmem_instance_t *next = globallistmem; const char *fname, *pname = NULL; apr_shm_t *shm; - apr_size_t basesize = (item_size * item_num); - apr_size_t size = AP_SLOTMEM_OFFSET + AP_UNSIGNEDINT_OFFSET + - (item_num * sizeof(char)) + basesize; + apr_size_t header_size; + apr_size_t basesize; + apr_size_t inuse_size; + apr_size_t size; int persist = (type & AP_SLOTMEM_TYPE_PERSIST) != 0; apr_status_t rv; @@ -358,6 +379,14 @@ static apr_status_t slotmem_create(ap_slotmem_instance_t **new, if (gpool == NULL) { return APR_ENOSHMAVAIL; } + if (!slotmem_size_mul(item_size, (apr_size_t)item_num, &basesize) + || !slotmem_size_mul((apr_size_t)item_num, sizeof(char), &inuse_size) + || !slotmem_size_add(AP_SLOTMEM_OFFSET, AP_UNSIGNEDINT_OFFSET, + &header_size) + || !slotmem_size_add(header_size, inuse_size, &size) + || !slotmem_size_add(size, basesize, &size)) { + return APR_EINVAL; + } if (slotmem_filenames(pool, name, &fname, persist ? &pname : NULL)) { /* first try to attach to existing slotmem */ if (next) { @@ -483,6 +512,11 @@ static apr_status_t slotmem_attach(ap_slotmem_instance_t **new, sharedslotdesc_t *desc; const char *fname; apr_shm_t *shm; + apr_size_t header_size; + apr_size_t basesize; + apr_size_t inuse_size; + apr_size_t expected_size; + apr_size_t shm_size; apr_status_t rv; if (gpool == NULL) { @@ -524,6 +558,23 @@ static apr_status_t slotmem_attach(ap_slotmem_instance_t **new, /* Read the description of the slotmem */ desc = (sharedslotdesc_t *)apr_shm_baseaddr_get(shm); + + if (!slotmem_size_mul(desc->size, (apr_size_t)desc->num, &basesize) + || !slotmem_size_mul((apr_size_t)desc->num, sizeof(char), &inuse_size) + || !slotmem_size_add(AP_SLOTMEM_OFFSET, AP_UNSIGNEDINT_OFFSET, + &header_size) + || !slotmem_size_add(header_size, basesize, &expected_size) + || !slotmem_size_add(expected_size, inuse_size, &expected_size)) { + apr_shm_detach(shm); + return APR_EINVAL; + } + + shm_size = apr_shm_size_get(shm); + if (expected_size > shm_size) { + apr_shm_detach(shm); + return APR_EINVAL; + } + ptr = (char *)desc + AP_SLOTMEM_OFFSET; /* For the chained slotmem stuff */ @@ -537,7 +588,7 @@ static apr_status_t slotmem_attach(ap_slotmem_instance_t **new, res->base = (void *)ptr; res->desc = desc; res->gpool = gpool; - res->inuse = ptr + (desc->size * desc->num); + res->inuse = ptr + basesize; res->next = NULL; *new = res; @@ -562,6 +613,11 @@ static apr_status_t slotmem_dptr(ap_slotmem_instance_t *slot, return APR_EINVAL; } + if (slot->desc->size != 0 + && (apr_size_t)id > ((apr_size_t)-1) / slot->desc->size) { + return APR_EINVAL; + } + ptr = (char *)slot->base + slot->desc->size * id; if (!ptr) { return APR_ENOSHMAVAIL; @@ -580,11 +636,14 @@ static apr_status_t slotmem_get(ap_slotmem_instance_t *slot, unsigned int id, if (!slot) { return APR_ENOSHMAVAIL; } - - inuse = slot->inuse + id; if (id >= slot->desc->num) { return APR_EINVAL; } + if (dest_len > slot->desc->size) { + return APR_EINVAL; + } + + inuse = slot->inuse + id; if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) { return APR_NOTFOUND; } @@ -607,11 +666,14 @@ static apr_status_t slotmem_put(ap_slotmem_instance_t *slot, unsigned int id, if (!slot) { return APR_ENOSHMAVAIL; } - - inuse = slot->inuse + id; if (id >= slot->desc->num) { return APR_EINVAL; } + if (src_len > slot->desc->size) { + return APR_EINVAL; + } + + inuse = slot->inuse + id; if (AP_SLOTMEM_IS_PREGRAB(slot) && !*inuse) { return APR_NOTFOUND; } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 9ee25ec52ca..3e96f9efdac 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -2238,7 +2238,7 @@ static apr_status_t set_challenge_creds(conn_rec *c, const char *servername, cleanup: if (our_data && cert) X509_free(cert); if (our_data && key) EVP_PKEY_free(key); - return APR_SUCCESS; + return rv; } /* diff --git a/modules/ssl/ssl_engine_ocsp.c b/modules/ssl/ssl_engine_ocsp.c index 539ed103eae..6a03fb41744 100644 --- a/modules/ssl/ssl_engine_ocsp.c +++ b/modules/ssl/ssl_engine_ocsp.c @@ -80,7 +80,7 @@ static apr_uri_t *determine_responder_uri(SSLSrvConfigRec *sc, X509 *cert, } rv = apr_uri_parse(p, s, u); - if (rv || !u->hostname) { + if (rv || !u->hostname || !u->scheme) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01919) "failed to parse OCSP responder URI '%s'", s); return NULL; diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 442b8b17ae4..a34b034f265 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -290,8 +290,9 @@ #define EVP_PKEY_up_ref(pk) (CRYPTO_add(&(pk)->references, +1, CRYPTO_LOCK_EVP_PKEY)) #define ASN1_STRING_get0_data(x) ((x)->data) #define ASN1_STRING_length(x) ((int)(x)->length) -#define X509_get0_before(x) X509_get_before(x) -#define X509_get0_after(x) X509_get_after(x) +#define X509_get0_serialNumber(x) X509_get_serialNumber(x) +#define X509_get0_notBefore(x) X509_get_notBefore(x) +#define X509_get0_notAfter(x) X509_get_notAfter(x) #else void init_bio_methods(void); void free_bio_methods(void); diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c index 12ffff511e2..cf289682330 100644 --- a/modules/ssl/ssl_util.c +++ b/modules/ssl/ssl_util.c @@ -201,9 +201,13 @@ ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key, { apr_ssize_t klen = strlen(key); ssl_asn1_t *asn1 = apr_hash_get(table, key, klen); - apr_size_t length = i2d_PrivateKey(pkey, NULL); + int derlen = i2d_PrivateKey(pkey, NULL); + apr_size_t length; unsigned char *p; + ap_assert(derlen > 0); /* should never happen for any loaded key */ + length = (apr_size_t)derlen; + /* Re-use structure if cached previously. */ if (asn1) { if (asn1->nData != length) { diff --git a/server/config.c b/server/config.c index 712bcab3db7..c294fed56a0 100644 --- a/server/config.c +++ b/server/config.c @@ -1472,7 +1472,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd, void *struct_ptr, const char *arg) { - int offset = (int)(long)cmd->info; + int offset = (int)(apr_uintptr_t)cmd->info; *(const char **)((char *)struct_ptr + offset) = arg; @@ -1485,7 +1485,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd, { char *endptr; char *error_str = NULL; - int offset = (int)(long)cmd->info; + apr_size_t offset = (apr_size_t)cmd->info; *(int *)((char*)struct_ptr + offset) = strtol(arg, &endptr, 10); @@ -1503,7 +1503,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd, const char *arg_) { char *arg = apr_pstrdup(cmd->pool,arg_); - int offset = (int)(long)cmd->info; + apr_size_t offset = (apr_size_t)cmd->info; ap_str_tolower(arg); *(char **)((char *)struct_ptr + offset) = arg; @@ -1514,7 +1514,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd, AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd, void *struct_ptr_v, int arg) { - int offset = (int)(long)cmd->info; + apr_size_t offset = (apr_size_t)cmd->info; char *struct_ptr = (char *)struct_ptr_v; *(int *)(struct_ptr + offset) = arg ? 1 : 0; @@ -1525,7 +1525,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd, AP_DECLARE_NONSTD(const char *) ap_set_flag_slot_char(cmd_parms *cmd, void *struct_ptr_v, int arg) { - int offset = (int)(long)cmd->info; + apr_size_t offset = (apr_size_t)cmd->info; char *struct_ptr = (char *)struct_ptr_v; *(struct_ptr + offset) = arg ? 1 : 0; @@ -1542,7 +1542,7 @@ AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_pt * so the server can be moved or mirrored with less pain. */ const char *path; - int offset = (int)(long)cmd->info; + int offset = (int)(apr_uintptr_t)cmd->info; path = ap_server_root_relative(cmd->pool, arg); diff --git a/server/core.c b/server/core.c index 315d6b5bace..b060ce5f64e 100644 --- a/server/core.c +++ b/server/core.c @@ -3208,7 +3208,7 @@ static const char *set_server_string_slot(cmd_parms *cmd, void *dummy, { /* This one's pretty generic... */ - int offset = (int)(long)cmd->info; + apr_size_t offset = (apr_size_t)cmd->info; char *struct_ptr = (char *)cmd->server; const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT); diff --git a/test/Makefile.in b/test/Makefile.in index d9ad04d5d95..ae5bf2b8c98 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -21,6 +21,7 @@ test: $(bin_PROGRAMS) clean: rm -rf gen + find . -name __pycache__ | xargs rm -rf distclean: - rm -f pyhttpd/config.ini \ No newline at end of file + rm -f pyhttpd/config.ini diff --git a/test/README b/test/README index 3ccdc201398..f63c0bb9444 100644 --- a/test/README +++ b/test/README @@ -73,20 +73,24 @@ The runner exits non-zero if either suite has failures. Running a suite directly ------------------------ -pytest_suite (from its own directory; it creates its own virtualenv): +Both runtests.sh scripts create their own virtualenv on first run and can be +invoked from any directory -- the paths below are just the convenient way to +type them. The venv is (re)built automatically whenever it is missing or its +pyproject.toml has changed, using `uv sync` (uv reads pyproject.toml + uv.lock). +uv (https://docs.astral.sh/uv/) is required. To force a clean rebuild yourself, +`rm -rf /.venv`. - cd pytest_suite - uv sync # one-time: create the venv - ./runtests.sh --apxs=/path/to/apxs # all tests - ./runtests.sh --php-fpm=/path/to/php-fpm tests/t/php # PHP tests - ./runtests.sh -k rewrite -v # any pytest args pass through +pytest_suite (self-contained; the venv holds only pytest + httpx): + + ./pytest_suite/runtests.sh --apxs=/path/to/apxs # all tests + ./pytest_suite/runtests.sh --php-fpm=/path/to/php-fpm tests/t/php # PHP tests + ./pytest_suite/runtests.sh -k rewrite -v # any pytest args pass through pyhttpd tests (need pyhttpd/config.ini from httpd's configure, plus curl, nghttp2/h2load, and -- for modules/md -- pyOpenSSL and an ACME test server): - pytest modules/http2 # all HTTP/2 tests - pytest modules/core -k test_001 # a subset - + ./pyhttpd/runtests.sh modules/http2 # all HTTP/2 tests + ./pyhttpd/runtests.sh modules/core -k test_001 # a subset Other contents -------------- diff --git a/test/README.pytest b/test/README.pytest index 620f69c8643..e6630ac394f 100644 --- a/test/README.pytest +++ b/test/README.pytest @@ -5,11 +5,11 @@ for a more flexible testing of Apache httpd. Install ------- -If not already installed, you will need to install 'pytest' and 'OpenSSL' for -python: -> apt install python3-pip -> pip install -U pytest -> pip install -U pyopenssl +The Python dependencies (pytest, pyOpenSSL, etc.) are managed with uv +(https://docs.astral.sh/uv/), which reads pyproject.toml + uv.lock and creates +a local .venv. Install uv, then let pyhttpd/runtests.sh build the venv on first +run (it invokes `uv sync` for you); or create it yourself: +> uv sync And for 'h2load': > apt install nghttp2-client diff --git a/test/modules/core/test_006_merge_lang.py b/test/modules/core/test_006_merge_lang.py new file mode 100644 index 00000000000..885214cac75 --- /dev/null +++ b/test/modules/core/test_006_merge_lang.py @@ -0,0 +1,39 @@ +import os +import pytest + +from pyhttpd.conf import HttpdConf + + +class TestMergeLanguage: + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env): + # Create a file with two language extensions so mod_mime + # populates r->content_languages with nelts == nalloc == 2. + doc_dir = os.path.join(env.server_dir, "htdocs", "test1") + with open(os.path.join(doc_dir, "doc.en.fr.html"), "w") as f: + f.write("Hello World\n") + + conf = HttpdConf(env, extras={ + f"test1.{env.http_tld}": """ + AddLanguage en .en + AddLanguage fr .fr + Header set Content-Language "de, es" + """, + }) + conf.add_vhost_test1() + conf.install() + assert env.apache_restart() == 0 + + # Requesting a file with two language extensions while mod_headers + # adds two non-matching Content-Language tokens should not crash. + # The merge loop in merge_response_headers must refresh its pointer + # to r->content_languages->elts after apr_array_push reallocates. + def test_core_006_01(self, env): + url = env.mkurl("http", "test1", "/doc.en.fr.html") + r = env.curl_get(url) + assert r.response, "no response: server may have crashed" + assert r.response["status"] == 200 + cl = r.response["header"]["content-language"] + for lang in ["en", "fr", "de", "es"]: + assert lang in cl, f"expected '{lang}' in Content-Language: {cl}" diff --git a/test/modules/http2/test_200_header_invalid.py b/test/modules/http2/test_200_header_invalid.py index adb203b5b6b..a3c2928d592 100644 --- a/test/modules/http2/test_200_header_invalid.py +++ b/test/modules/http2/test_200_header_invalid.py @@ -168,11 +168,13 @@ def test_h2_200_14(self, env): conf.install() assert env.apache_restart() == 0 url = env.mkurl("https", "cgi", "/") - opt = [] - for i in range(21): - opt += ["-H", "x{0}: 1".format(i)] - r = env.curl_get(url, options=opt) - assert 431 == r.response["status"] + + for desc, opts in [ + ("regular", [v for i in range(21) for v in ("-H", f"x{i}: 1")]), + ("cookie", [v for i in range(21) for v in ("-H", f"cookie: c{i}=v{i}")]), + ]: + r = env.curl_get(url, options=opts) + assert r.response["status"] == 431, f"{desc} header failed" conf = H2Conf(env) conf.add(""" LimitRequestFields 0 diff --git a/test/modules/md/md_cert_util.py b/test/modules/md/md_cert_util.py index 6cd034a02b5..796af220dfb 100755 --- a/test/modules/md/md_cert_util.py +++ b/test/modules/md/md_cert_util.py @@ -11,7 +11,12 @@ from http.client import HTTPConnection from urllib.parse import urlparse +from cryptography.hazmat._oid import ExtensionOID +from cryptography.hazmat.bindings._rust import ObjectIdentifier +from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, load_pem_private_key + from cryptography import x509 +from cryptography.x509 import DNSName, ExtensionNotFound SEC_PER_DAY = 24 * 60 * 60 @@ -21,7 +26,6 @@ class MDCertUtil(object): # Utility class for inspecting certificates in test cases - # Uses PyOpenSSL: https://pyopenssl.org/en/stable/index.html @classmethod def load_server_cert(cls, host_ip, host_port, host_name, tls=None, ciphers=None): @@ -42,12 +46,12 @@ def load_server_cert(cls, host_ip, host_port, host_name, tls=None, ciphers=None) connection.setblocking(1) connection.set_tlsext_host_name(host_name.encode('utf-8')) connection.do_handshake() - peer_cert = connection.get_peer_certificate() - return MDCertUtil(None, cert=peer_cert) + ossl_cert = connection.get_peer_certificate() + return MDCertUtil(None, cert=ossl_cert.to_cryptography()) @classmethod def parse_pem_cert(cls, text): - cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, text.encode('utf-8')) + cert = x509.load_pem_x509_certificate(text.encode('utf-8')) return MDCertUtil(None, cert=cert) @classmethod @@ -72,24 +76,26 @@ def get_plain(cls, url, timeout): return None def __init__(self, cert_path, cert=None): + self.cert = cert + self.privkey = None if cert_path is not None: self.cert_path = cert_path # load certificate and private key if cert_path.startswith("http"): - cert_data = self.get_plain(cert_path, 1) - else: - cert_data = MDCertUtil._load_binary_file(cert_path) - - for file_type in (OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.FILETYPE_ASN1): - try: - self.cert = OpenSSL.crypto.load_certificate(file_type, cert_data) - except Exception as error: - self.error = error - if cert is not None: - self.cert = cert - - if self.cert is None: - raise self.error + assert False + try: + with open(cert_path) as fd: + cert = x509.load_pem_x509_certificate("".join(fd.readlines()).encode()) + except Exception as error: + self.error = error + if cert is not None: + self.cert = cert + if self.cert is None: + raise self.error + + def add_privkey(self, path, password=None): + with open(path) as fd: + self.privkey = load_pem_private_key("".join(fd.readlines()).encode(), password=password) def get_issuer(self): return self.cert.get_issuer() @@ -97,21 +103,20 @@ def get_issuer(self): def get_serial(self): # the string representation of a serial number is not unique. Some # add leading 0s to align with word boundaries. - return ("%lx" % (self.cert.get_serial_number())).upper() + return ("%lx" % (self.cert.serial_number)).upper() @staticmethod def _get_serial(cert) -> int: if isinstance(cert, x509.Certificate): return cert.serial_number if isinstance(cert, MDCertUtil): - return cert.get_serial_number() - elif isinstance(cert, OpenSSL.crypto.X509): - return cert.get_serial_number() + return cert.cert.serial_number elif isinstance(cert, str): # assume a hex number return int(cert, 16) elif isinstance(cert, int): return cert + assert False, f'{cert}' return 0 def get_serial_number(self): @@ -121,89 +126,33 @@ def same_serial_as(self, other): return self._get_serial(self.cert) == self._get_serial(other) def get_not_before(self): - tsp = self.cert.get_notBefore() - return self._parse_tsp(tsp) + try: + return self.cert.not_valid_before_utc + except AttributeError: + return self.cert.not_valid_before def get_not_after(self): - tsp = self.cert.get_notAfter() - return self._parse_tsp(tsp) - - def get_cn(self): - return self.cert.get_subject().CN + try: + return self.cert.not_valid_after_utc + except AttributeError: + return self.cert.not_valid_after def get_key_length(self): - return self.cert.get_pubkey().bits() + return self.cert.public_key().key_size 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+critical)?\s*(.*)", text) - sans_list = [] - if m: - sans_list = m.group(2).split(",") - - def _strip_prefix(s): - return s.split(":")[1] if s.strip().startswith("DNS:") else s.strip() - return list(map(_strip_prefix, sans_list)) + sans = self.cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) + return sans.value.get_values_for_type(DNSName) def get_must_staple(self): - text = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_TEXT, self.cert).decode("utf-8") - m = re.search(r"1.3.6.1.5.5.7.1.24:\s*\n\s*0....", text) - if not m: - # Newer openssl versions print this differently - m = re.search(r"TLS Feature:\s*\n\s*status_request\s*\n", text) - return m is not None + try: + self.cert.extensions.get_extension_for_oid(ExtensionOID.TLS_FEATURE) + return True + except ExtensionNotFound: + return False @classmethod def validate_privkey(cls, privkey_path, passphrase=None): - privkey_data = cls._load_binary_file(privkey_path) - if passphrase: - privkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, privkey_data, passphrase) - else: - privkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, privkey_data) - return privkey.check() - - def validate_cert_matches_priv_key(self, privkey_path): - # Verifies that the private key and cert match. - privkey_data = MDCertUtil._load_binary_file(privkey_path) - privkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, privkey_data) - context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) - context.use_privatekey(privkey) - context.use_certificate(self.cert) - context.check_privatekey() - - # --------- _utils_ --------- - - def astr(self, s): - return s.decode('utf-8') - - def _parse_tsp(self, tsp): - # timestampss returned by PyOpenSSL are bytes - # parse date and time part - s = ("%s-%s-%s %s:%s:%s" % (self.astr(tsp[0:4]), self.astr(tsp[4:6]), self.astr(tsp[6:8]), - self.astr(tsp[8:10]), self.astr(tsp[10:12]), self.astr(tsp[12:14]))) - timestamp = datetime.strptime(s, '%Y-%m-%d %H:%M:%S') - # adjust timezone - tz_h, tz_m = 0, 0 - m = re.match(r"([+\-]\d{2})(\d{2})", self.astr(tsp[14:])) - if m: - tz_h, tz_m = int(m.group(1)), int(m.group(2)) if tz_h > 0 else -1 * int(m.group(2)) - return timestamp.replace(tzinfo=self.FixedOffset(60 * tz_h + tz_m)) - - @classmethod - def _load_binary_file(cls, path): - with open(path, mode="rb") as file: - return file.read() - - class FixedOffset(tzinfo): - - def __init__(self, offset): - self.__offset = timedelta(minutes=offset) - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return None - - def dst(self, dt): - return timedelta(0) + with open(privkey_path) as fd: + privkey = load_pem_private_key("".join(fd.readlines()).encode(), password=passphrase) + return privkey is not None diff --git a/test/modules/md/md_conf.py b/test/modules/md/md_conf.py index 54b10abc659..95e10f4cf06 100755 --- a/test/modules/md/md_conf.py +++ b/test/modules/md/md_conf.py @@ -46,7 +46,7 @@ def __init__(self, env: MDTestEnv, text=None, std_ports=True, " ProxyRequests On", " ProxyVia On", " # be totally open", - " AllowCONNECT 0-56535", + " AllowCONNECT 0-65535", " ", " # No require or other restrictions, this is just a test server", " ", diff --git a/test/modules/md/md_env.py b/test/modules/md/md_env.py index acc8417b149..7b5f0f9e561 100755 --- a/test/modules/md/md_env.py +++ b/test/modules/md/md_env.py @@ -340,7 +340,7 @@ def check_md_complete(self, domain, pkey=None): md = self.get_md_status(domain) assert md assert 'state' in md, "md is unexpected: {0}".format(md) - assert md['state'] is MDTestEnv.MD_S_COMPLETE, f"unexpected state: {md['state']}" + assert md['state'] is MDTestEnv.MD_S_COMPLETE, f"unexpected state: {md}" pkey_file = self.store_domain_file(domain, self.pkey_fname(pkey)) cert_file = self.store_domain_file(domain, self.cert_fname(pkey)) r = self.run(['ls', os.path.dirname(pkey_file)]) @@ -359,7 +359,7 @@ def check_md_credentials(self, domain): # check private key, validate certificate, etc 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')) + cert.add_privkey(self.store_domain_file(domain, 'privkey.pem')) # 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 diff --git a/test/modules/md/test_502_acmev2_drive.py b/test/modules/md/test_502_acmev2_drive.py index 484e4d4bd95..c3a6854b2be 100644 --- a/test/modules/md/test_502_acmev2_drive.py +++ b/test/modules/md/test_502_acmev2_drive.py @@ -395,7 +395,7 @@ def test_md_502_200(self, env): # check new cert env.check_md_credentials([name, "test." + domain]) new_cert = MDCertUtil(env.store_domain_file(name, 'pubcert.pem')) - assert not old_cert.same_serial_as(new_cert.get_serial) + assert not old_cert.same_serial_as(new_cert.get_serial()) @pytest.mark.parametrize("renew_window,test_data_list", [ ("14d", [ @@ -550,4 +550,4 @@ def _check_account_key(self, env, name): # check: key file is encrypted PEM md = env.a2md(["list", name]).json['output'][0] acc = md['ca']['account'] - MDCertUtil.validate_privkey(env.path_account_key(acc), lambda *args: encrypt_key) + MDCertUtil.validate_privkey(env.path_account_key(acc), encrypt_key) diff --git a/test/modules/md/test_702_auto.py b/test/modules/md/test_702_auto.py index 7246b62255c..b4d7a0b0517 100644 --- a/test/modules/md/test_702_auto.py +++ b/test/modules/md/test_702_auto.py @@ -208,8 +208,8 @@ def test_md_702_005(self, env): # check temporary cert from server cert2 = MDCertUtil(env.path_fallback_cert(domain)) assert cert1.same_serial_as(cert2), \ - "Unexpected temporary certificate on vhost %s. Expected cn: %s , "\ - "but found cn: %s" % (name_a, cert2.get_cn(), cert1.get_cn()) + f"Unexpected temporary certificate on vhost {name_a}." \ + f" Expected cn: {cert2}, but found cn: {cert1}" # test case: drive MD with only invalid challenges, domains should stay 503'd def test_md_702_006(self, env): @@ -297,6 +297,55 @@ def test_md_702_008a(self, env): assert env.apache_restart() == 0, f'{env.apachectl_stderr}' env.check_md_complete(domain) + # Specify a valid http proxy for a single MDomain + def test_md_702_008b(self, env): + domain = self.test_domain + domains = [domain] + # + conf = MDConf(env, admin=f"admin@{domain}", proxy=True) + conf.add_drive_mode("always") + conf.start_md(domains) + conf.add(f" MDHttpProxy http://localhost:{env.proxy_port}") + conf.end_md() + conf.install() + # + # - restart (-> drive), check that md is in store + assert env.apache_restart() == 0, f'{env.apachectl_stderr}' + assert env.await_completion([domain]) + assert env.apache_restart() == 0, f'{env.apachectl_stderr}' + env.check_md_complete(domain) + + # Specify a non-working http proxy for MDomain A and a valid http proxy for MDomain B + def test_md_702_008c(self, env): + domain_a = f"a{self.test_domain}" + domain_b = f"b{self.test_domain}" + conf = MDConf(env, admin=f"admin@{domain_a}", proxy=True) + conf.start_md([domain_a]) + conf.add(f" MDHttpProxy http://localhost:1") + conf.end_md() + conf.add_vhost(domains=[domain_a]) + conf.start_md([domain_b]) + conf.add(f" MDHttpProxy http://localhost:{env.proxy_port}") + conf.end_md() + conf.add_vhost(domains=[domain_b]) + conf.install() + assert env.apache_restart() == 0, f'{env.apachectl_stderr}' + assert env.await_completion([domain_b], restart=False) + md = env.await_error(domain_a) + assert md + assert md['renewal']['errors'] > 0 + assert md['renewal']['last']['status-description'] == 'Connection refused' + assert 'account' not in md['ca'] + # + env.httpd_error_log.ignore_recent( + lognos = [ + "AH10056" # Unsuccessful in contacting ACME server + ], + matches = [ + r'.*Unsuccessful in contacting ACME server at .*' + ] + ) + # Force cert renewal due to critical remaining valid duration # Assert that new cert activation is delayed def test_md_702_009(self, env, acme): diff --git a/test/modules/md/test_800_must_staple.py b/test/modules/md/test_800_must_staple.py index 8433ca8cee5..d2d8225dd62 100644 --- a/test/modules/md/test_800_must_staple.py +++ b/test/modules/md/test_800_must_staple.py @@ -1,4 +1,5 @@ # test mod_md must-staple support +import time import pytest from .md_conf import MDConf @@ -21,7 +22,8 @@ def _class_scope(self, env, acme): @pytest.fixture(autouse=True, scope='function') def _method_scope(self, env, request): - self.domain = env.get_class_domain(self.__class__) + env.clear_store() + self.domain = env.get_request_domain(request) def configure_httpd(self, env, domain, add_lines=""): conf = MDConf(env, admin="admin@" + domain) @@ -43,6 +45,7 @@ def test_md_800_001(self, env): def test_md_800_002(self, env): self.configure_httpd(env, self.domain, "MDMustStaple off") assert env.apache_restart() == 0, f'{env.apachectl_stderr}' + assert env.await_completion([self.domain]) env.check_md_complete(self.domain) cert1 = MDCertUtil(env.store_domain_file(self.domain, 'pubcert.pem')) assert not cert1.get_must_staple() diff --git a/test/modules/proxy/env.py b/test/modules/proxy/env.py index 92e85ba9fc4..fc443370754 100644 --- a/test/modules/proxy/env.py +++ b/test/modules/proxy/env.py @@ -20,6 +20,7 @@ def __init__(self, host, port): self._host = host self._port = port self._done = False + self._request = None def start(self): def process(): @@ -51,6 +52,8 @@ def _process(self): c, client_address = self._socket.accept() try: data = c.recv(4096) + # capture request to backend + self._request = data c.sendall(self._make_response(data)) finally: c.close() @@ -66,7 +69,7 @@ def __init__(self, env: 'HttpdTestEnv'): super().__init__(env=env) self.add_source_dir(os.path.dirname(inspect.getfile(ProxyTestSetup))) self.add_modules(["proxy", "proxy_http", "proxy_ajp", "proxy_balancer", - "lbmethod_byrequests", "remoteip"]) + "proxy_uwsgi", "lbmethod_byrequests", "remoteip"]) class ProxyTestEnv(HttpdTestEnv): diff --git a/test/modules/proxy/test_05_uwsgi.py b/test/modules/proxy/test_05_uwsgi.py new file mode 100644 index 00000000000..b0733aba7dd --- /dev/null +++ b/test/modules/proxy/test_05_uwsgi.py @@ -0,0 +1,53 @@ +import pytest + +from pyhttpd.conf import HttpdConf +from .env import TCPFaker + + +class _UWSGIFaker(TCPFaker): + + @staticmethod + def hello(data): + body = b"Hello" + return ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/plain\r\n" + b"Content-Length: 5\r\n" + b"\r\n" + + body + ) + + +class TestProxyUwsgi: + + @pytest.fixture(autouse=True, scope='class') + def _class_scope(self, env): + if not env.has_shared_module("proxy_uwsgi"): + pytest.skip("mod_proxy_uwsgi not available") + faker = _UWSGIFaker("127.0.0.1", env.http_port2) + faker.start() + conf = HttpdConf(env) + conf.start_vhost(domains=[f"test1.{env.http_tld}"], port=env.http_port) + conf.add([ + f"ProxyPass / uwsgi://127.0.0.1:{env.http_port2}/", + ]) + conf.end_vhost() + conf.install() + assert env.apache_restart() == 0 + yield faker + faker.stop() + + # verify uwsgi request header + def test_proxy_005_01(self, env, _class_scope): + _class_scope._make_response = _UWSGIFaker.hello + r = env.curl_get(env.mkurl("http", "test1", "/")) + assert r.response["status"] == 200 + assert r.response["body"] == b"Hello" + + data = _class_scope._request + + assert data[0] == 0x00 # standard WSGI request + datasize = data[1] + (data[2] * 256) # read from 16bit little-endian + assert data[3] == 0x00 # standard WSGI request + assert len(data) == 4 + datasize + diff --git a/test/pyhttpd/log.py b/test/pyhttpd/log.py index 3a0727d2e3c..75d6980f0b7 100644 --- a/test/pyhttpd/log.py +++ b/test/pyhttpd/log.py @@ -13,6 +13,8 @@ class HttpdErrorLog: RE_ERRLOG_WARN = re.compile(r'.*\[[^:]+:warn].*') RE_ERRLOG_ERROR = re.compile(r'.*\[[^:]+:error].*') + RE_ERRLOG_CRASH = re.compile(r'.*\bexit signal (?:Segmentation fault|Abort(ed)?|Bus error)\b.*') + RE_ERRLOG_ASAN = re.compile(r'.*==\d+==ERROR: (?:Address|Memory|Leak|Thread)Sanitizer:.*') RE_APLOGNO = re.compile(r'.*\[[^:]+:(error|warn)].* (?PAH\d+): .+') def __init__(self, path: str): @@ -126,6 +128,10 @@ def get_missed(self) -> Tuple[List[str], List[str]]: continue if line in self._caught_matches: continue + if self.RE_ERRLOG_CRASH.match(line) or \ + self.RE_ERRLOG_ASAN.match(line): + errors.append(line) + continue m = self.RE_ERRLOG_WARN.match(line) if m and line not in self._caught_warnings: warnings.append(line) diff --git a/test/pyhttpd/runtests.sh b/test/pyhttpd/runtests.sh index 283b4715536..1f93dbcff79 100755 --- a/test/pyhttpd/runtests.sh +++ b/test/pyhttpd/runtests.sh @@ -18,21 +18,29 @@ set -eu here="$(cd "$(dirname "$0")" && pwd)" +# --- ensure the venv exists and is current ---------------------------------- +# The suite baselines on uv (https://docs.astral.sh/uv/) as its dependency and +# venv manager: it reads pyproject.toml + uv.lock, so there is a single source +# of truth for dependencies. We invoke .venv/bin/pytest directly rather than +# `uv run` so the suite works even where `uv run` is shimmed/unavailable. +# +# Create $here/.venv on first run, and rebuild it when pyproject.toml is newer +# than the venv (i.e. dependencies changed). Absolute paths throughout, so this +# behaves identically regardless of the caller's cwd. This block is kept +# byte-for-byte identical in pytest_suite/runtests.sh and pyhttpd/runtests.sh +# -- edit both together. PYTEST="$here/.venv/bin/pytest" -if [ ! -x "$PYTEST" ]; then - if command -v uv >/dev/null 2>&1; then - echo "runtests.sh: .venv not found; running 'uv sync' to create it..." >&2 - uv sync --project "$here" - elif command -v python3 >/dev/null 2>&1; then - echo "runtests.sh: .venv not found; creating with python3 + pip..." >&2 - python3 -m venv "$here/.venv" - # Keep this list in sync with pyproject.toml [project].dependencies - "$here/.venv/bin/pip" install --quiet \ - "pytest>=7.0" cryptography filelock "python-multipart" pyopenssl packaging websockets - else - echo "runtests.sh: ERROR: $PYTEST not found and neither 'uv' nor 'python3' is on PATH." >&2 +if [ ! -x "$PYTEST" ] || [ "$here/pyproject.toml" -nt "$here/.venv" ]; then + if ! command -v uv >/dev/null 2>&1; then + echo "runtests.sh: ERROR: 'uv' is required but not installed." >&2 + echo " Install it from https://docs.astral.sh/uv/ and re-run." >&2 exit 1 fi + echo "runtests.sh: (re)creating $here/.venv via 'uv sync'..." >&2 + uv sync --project "$here" + # Mark the venv as freshly built so the staleness check above won't retrigger + # until pyproject.toml changes again. + touch "$here/.venv" fi # Prepend the venv's bin dir so that CGI scripts forked by httpd also resolve @@ -40,8 +48,40 @@ fi # that any shim wrappers earlier on PATH are shadowed. export PATH="$here/.venv/bin:$PATH" -targets="${PYHTTPD_TARGETS:-modules}" +# The modules/ test suite lives in test/, a sibling of this script's directory +# (test/pyhttpd/) -- cd there so both the default target and any +# PYHTTPD_TARGETS/positional path the caller supplies resolve the same way +# regardless of where runtests.sh was invoked from. +cd "$(dirname "$here")" + +# Only fall back to the "modules" default when the caller gave no positional +# test path of their own -- otherwise it would always tag along after theirs +# (`pytest modules modules/http1`), silently widening any subset selection +# back out to the full suite. A positional path is recognized by actually +# existing on disk (relative to test/, our cwd at this point) -- this avoids +# both having to enumerate every pytest flag that takes a separate-word value +# (-k, -m, -p, --tb, --maxfail, -n from pytest-xdist, ...) and misdetecting a +# -k/-m expression that happens to contain '/' (this suite's own parametrize +# IDs look like "/006/006.css", so "-k 006/006" is a realistic selector, and +# it does not exist as a path). +have_path=0 +for arg in "$@"; do + case "$arg" in + -*) ;; + # Strip a trailing ::nodeid (pytest's file::Class::test node-selector + # syntax) before checking existence -- only the file/dir part is real. + *) [ -e "${arg%%::*}" ] && have_path=1 ;; + esac +done + +if [ -n "${PYHTTPD_TARGETS:-}" ]; then + targets="$PYHTTPD_TARGETS" +elif [ "$have_path" = 1 ]; then + targets="" +else + targets="modules" +fi -# shellcheck disable=SC2086 echo "runtests.sh: $PYTEST $targets $*" >&2 +# shellcheck disable=SC2086 # $targets is an intentional word-split path list exec "$PYTEST" $targets "$@" diff --git a/test/pytest_suite/README.md b/test/pytest_suite/README.md index 6479d6b02ad..9485ee1368f 100644 --- a/test/pytest_suite/README.md +++ b/test/pytest_suite/README.md @@ -27,8 +27,8 @@ optionally, a **`php-fpm`** binary for the PHP tests. ## Quick start ```sh -# 1. Create the virtualenv (pytest + httpx). Needs `uv` (https://docs.astral.sh/uv/), -# or substitute a plain venv -- see "Environment" below. +# 1. Create the virtualenv (pytest + httpx). Needs `uv` (https://docs.astral.sh/uv/); +# reads pyproject.toml + uv.lock. runtests.sh also does this for you on first run. uv sync # 2. Run the whole suite against your httpd build. diff --git a/test/pytest_suite/runtests.sh b/test/pytest_suite/runtests.sh index a22501012ae..7d836f39362 100755 --- a/test/pytest_suite/runtests.sh +++ b/test/pytest_suite/runtests.sh @@ -26,23 +26,29 @@ set -eu here="$(cd "$(dirname "$0")" && pwd)" cd "$here" -# --- locate the virtualenv's pytest ----------------------------------------- -# We invoke .venv/bin/pytest directly rather than `uv run` so the suite works -# even where `uv run` is shimmed/unavailable. Create the venv with `uv sync` -# (or `python -m venv .venv && .venv/bin/pip install -e .`) if it's missing. +# --- ensure the venv exists and is current ---------------------------------- +# The suite baselines on uv (https://docs.astral.sh/uv/) as its dependency and +# venv manager: it reads pyproject.toml + uv.lock, so there is a single source +# of truth for dependencies. We invoke .venv/bin/pytest directly rather than +# `uv run` so the suite works even where `uv run` is shimmed/unavailable. +# +# Create $here/.venv on first run, and rebuild it when pyproject.toml is newer +# than the venv (i.e. dependencies changed). Absolute paths throughout, so this +# behaves identically regardless of the caller's cwd. This block is kept +# byte-for-byte identical in pytest_suite/runtests.sh and pyhttpd/runtests.sh +# -- edit both together. PYTEST="$here/.venv/bin/pytest" -if [ ! -x "$PYTEST" ]; then - if command -v uv >/dev/null 2>&1; then - echo "runtests.sh: .venv not found; running 'uv sync' to create it..." >&2 - uv sync - elif command -v python3 >/dev/null 2>&1; then - echo "runtests.sh: .venv not found; creating it with python3 + pip..." >&2 - python3 -m venv .venv - .venv/bin/pip install --quiet -e . - else - echo "runtests.sh: ERROR: $PYTEST not found and neither 'uv' nor 'python3' is installed." >&2 +if [ ! -x "$PYTEST" ] || [ "$here/pyproject.toml" -nt "$here/.venv" ]; then + if ! command -v uv >/dev/null 2>&1; then + echo "runtests.sh: ERROR: 'uv' is required but not installed." >&2 + echo " Install it from https://docs.astral.sh/uv/ and re-run." >&2 exit 1 fi + echo "runtests.sh: (re)creating $here/.venv via 'uv sync'..." >&2 + uv sync --project "$here" + # Mark the venv as freshly built so the staleness check above won't retrigger + # until pyproject.toml changes again. + touch "$here/.venv" fi # --- discover apxs / httpd / php-fpm ---------------------------------------- @@ -93,6 +99,6 @@ esac rm -f "$here/t/logs/cgisock"* 2>/dev/null || true # --- run -------------------------------------------------------------------- -# shellcheck disable=SC2086 # auto_args is an intentional word-split flag list echo "runtests.sh: $PYTEST $auto_args $*" >&2 +# shellcheck disable=SC2086 # auto_args is an intentional word-split flag list exec "$PYTEST" $auto_args "$@" diff --git a/test/run-all-tests.sh b/test/run-all-tests.sh index c34600620f9..71625c7138b 100755 --- a/test/run-all-tests.sh +++ b/test/run-all-tests.sh @@ -70,7 +70,14 @@ config_ini="$here/pyhttpd/config.ini" # paths and go ONLY to pytest_suite. The pyhttpd side selects its # tests via PYHTTPD_TARGETS (or its auto-detected default), since a # pytest_suite path is meaningless there. -# A flag that takes a separate-word value (-k NAME) keeps the value as a flag. +# +# The hard part is telling a positional test path from the value of a flag that +# takes a separate word (e.g. `--tb short`, `--maxfail 3`, `-n 4`). We handle it +# two ways: (a) the common value-flags -k/-m/-p are known to consume the next +# word, and (b) any OTHER bare word is treated as a pysuite path only if it +# actually exists on disk -- a flag value like "short"/"3"/"no" never does, so +# it stays with `flags` (attached to its preceding flag) instead of being +# misrouted to pysuite-only paths and stripped from what pyhttpd receives. only="" apxs_opt="" flags="" @@ -89,7 +96,15 @@ for arg in "$@"; do --clean-modules) pysuite_flags="$pysuite_flags $arg" ;; # pysuite-only; pyhttpd has no C modules -k|-m|-p) flags="$flags $arg"; expect_flagval=1 ;; # take a value next -*) flags="$flags $arg" ;; - *) paths="$paths $arg" ;; + # A real pysuite path exists relative to pytest_suite/ (how users type + # it, e.g. "tests/t/php") or to our cwd; strip any ::nodeid suffix + # first. Anything else is a stray flag value -> keep it with the flags. + *) if [ -e "$suite_dir/${arg%%::*}" ] || [ -e "${arg%%::*}" ]; then + paths="$paths $arg" + else + flags="$flags $arg" + fi + ;; esac done @@ -110,6 +125,7 @@ php_args="" [ -n "${PHP_FPM:-}" ] && php_args="--php-fpm=$PHP_FPM" rc=0 +skipped="" # names of suites that did NOT run (so we never report them "passed") run_pysuite() { echo "==========================================================" @@ -134,6 +150,7 @@ run_pyhttpd() { if [ ! -f "$config_ini" ]; then echo "run-all-tests.sh: note: pyhttpd/config.ini not found;" >&2 echo " build httpd with its test config (configure) to run these." >&2 + skipped="$skipped pyhttpd" return 0 fi # runtests.sh manages the venv, prepends its bin/ to PATH (so CGI @@ -159,6 +176,21 @@ case "$only" in esac echo "==========================================================" -[ "$rc" -eq 0 ] && echo "ALL SUITES PASSED" || echo "SOME TESTS FAILED (rc=$rc)" +if [ "$rc" -ne 0 ]; then + echo "SOME TESTS FAILED (rc=$rc)" +elif [ -n "$skipped" ]; then + # Nothing failed, but at least one suite never ran -- don't claim success + # for a suite that was skipped (e.g. pyhttpd with no config.ini). + echo "PASSED, BUT SKIPPED:$skipped (not run -- see notes above)" +else + echo "ALL SUITES PASSED" +fi echo "==========================================================" + +# If a suite was skipped and the user explicitly asked for ONLY that suite, +# treat "ran nothing" as a failure -- otherwise --only=pyhttpd could exit 0 +# having executed zero tests. +if [ -n "$skipped" ] && [ -n "$only" ] && [ "$rc" -eq 0 ]; then + exit 3 +fi exit "$rc"