[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1034329: marked as done (unblock: apache2/2.4.57-1)



Your message dated Thu, 13 Apr 2023 07:21:55 +0000
with message-id <E1pmrHH-00FGSL-TH@respighi.debian.org>
and subject line unblock apache2
has caused the Debian Bug report #1034329,
regarding unblock: apache2/2.4.57-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1034329: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1034329
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: apache2@packages.debian.org
Control: affects -1 + src:apache2

Please unblock package apache2

[ Reason ]
The security fixes provided by version 2.4.56 includes some regressions
(#1033408 and #1033284)

[ Impact ]
Major bugs

[ Tests ]
Test updated, passes

[ Risks ]
Low risk here, the version 2.4.57 contains only bug fixes

[ Checklist ]
  [X] all changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in testing

[ Other info ]
The diff contains also a debian/NEWS entry (added also in bullseye after
#1018718 fix)

unblock apache2/2.4.57-1
diff --git a/CHANGES b/CHANGES
index 16f8f55d..b0e8b117 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,58 @@
                                                          -*- coding: utf-8 -*-
+Changes with Apache 2.4.57
+
+  *) mod_proxy: Check before forwarding that a nocanon path has not been
+     rewritten with spaces during processing.  [Yann Ylavic]
+
+  *) mod_proxy: In case that AllowEncodedSlashes is set to NoDecode do not
+     double encode encoded slashes in the URL sent by the reverse proxy to the
+     backend. [Ruediger Pluem]
+
+  *) mod_http2: fixed a crash during connection termination. See PR 66539.
+     [Stefan Eissing]
+
+  *) mod_rewrite: Fix a 2.4.56 regression for substitutions ending
+     in a question mark. PR66547. [Eric Covener]
+
+  *) mod_rewrite: Add "BCTLS" and "BNE" RewriteRule flags. Re-allow encoded
+     characters on redirections without the "NE" flag. 
+     [Yann Ylavic, Eric Covener]
+
+  *) mod_proxy: Fix double encoding of the uri-path of the request forwarded
+     to the origin server, when using mapping=encoded|servlet.  [Yann Ylavic]
+
+  *) mod_mime: Do not match the extention against possible query string
+     parameters in case ProxyPass was used with the nocanon option.
+     [Ruediger Pluem]
+
 Changes with Apache 2.4.56
 
+  *) SECURITY: CVE-2023-27522: Apache HTTP Server: mod_proxy_uwsgi
+     HTTP response splitting (cve.mitre.org)
+     HTTP Response Smuggling vulnerability in Apache HTTP Server via
+     mod_proxy_uwsgi. This issue affects Apache HTTP Server: from
+     2.4.30 through 2.4.55.
+     Special characters in the origin response header can
+     truncate/split the response forwarded to the client.
+     Credits: Dimas Fariski Setyawan Putra (nyxsorcerer)
+
+  *) SECURITY: CVE-2023-25690: HTTP request splitting with
+     mod_rewrite and mod_proxy (cve.mitre.org)
+     Some mod_proxy configurations on Apache HTTP Server versions
+     2.4.0 through 2.4.55 allow a HTTP Request Smuggling attack.
+     Configurations are affected when mod_proxy is enabled along with
+     some form of RewriteRule or ProxyPassMatch in which a non-specific
+     pattern matches some portion of the user-supplied request-target (URL)
+     data and is then re-inserted into the proxied request-target
+     using variable substitution. For example, something like:
+        RewriteEngine on
+        RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1";; [P]
+        ProxyPassReverse /here/  http://example.com:8080/
+     Request splitting/smuggling could result in bypass of access
+     controls in the proxy server, proxying unintended URLs to
+     existing origin servers, and cache poisoning.
+     Credits: Lars Krapf of Adobe
+
   *) rotatelogs: Add -T flag to allow subsequent rotated logfiles to be
      truncated without the initial logfile being truncated.  [Eric Covener]
 
@@ -112,6 +164,7 @@ Changes with Apache 2.4.55
        The checks for this in nghttp2 v1.50.0+ are disabled.
      - Extensive testing in production done by Alessandro Bianchi (@alexskynet)
        on the v2.0.x versions for stability. Many thanks!
+
   *) mod_proxy_http2: fixed #235 by no longer forwarding 'Host:' header when
      request ':authority' is known. Improved test case that did not catch that
      the previous 'fix' was incorrect.
@@ -319,6 +372,9 @@ Changes with Apache 2.4.54
      domain names in the *.ts.net space.
      [Stefan Eissing]
 
+  *) core: Change default value of LimitRequestBody from 0 (unlimited)
+     to 1GB. [Eric Covener]
+
 Changes with Apache 2.4.53
 
   *) SECURITY: CVE-2022-23943: mod_sed: Read/write beyond bounds
diff --git a/debian/NEWS b/debian/NEWS
new file mode 100644
index 00000000..a55a9d70
--- /dev/null
+++ b/debian/NEWS
@@ -0,0 +1,9 @@
+apache2 (2.4.54-3) unstable; urgency=medium
+
+  This version does not automatically enable the apache2 config snippet for
+  /manual anymore. If you want to have it enabled you will need to do this
+  yourself, e.g. with
+
+    /usr/sbin/a2enconf apache2-doc
+
+ -- Yadd <yadd@debian.org>  Sat, 01 Apr 2023 08:17:08 +0400
diff --git a/debian/changelog b/debian/changelog
index 4ae13cf0..a6602864 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,24 @@
+apache2 (2.4.57-2) unstable; urgency=medium
+
+  * Revert debian/* changes (Bookworm freeze)
+
+ -- Yadd <yadd@debian.org>  Thu, 13 Apr 2023 07:26:51 +0400
+
+apache2 (2.4.57-1) unstable; urgency=medium
+
+  * New upstream version 2.4.57
+  * Drop 2.4.56-regression patches
+
+ -- Yadd <yadd@debian.org>  Sat, 08 Apr 2023 06:57:16 +0400
+
+apache2 (2.4.56-2) unstable; urgency=medium
+
+  * Fix regression in mod_rewrite introduced in version 2.4.56
+    (Closes: #1033284)
+  * Fix regression in http2 introduced by 2.4.56 (Closes: #1033408)
+
+ -- Yadd <yadd@debian.org>  Sun, 02 Apr 2023 06:54:25 +0400
+
 apache2 (2.4.56-1) unstable; urgency=medium
 
   * New upstream version (Closes: #1032476, CVE-2023-27522, CVE-2023-25690)
diff --git a/debian/config-dir/sites-available/default-ssl.conf b/debian/config-dir/sites-available/default-ssl.conf
index 9de96fa2..330280de 100644
--- a/debian/config-dir/sites-available/default-ssl.conf
+++ b/debian/config-dir/sites-available/default-ssl.conf
@@ -45,8 +45,8 @@
 	#   certificates for client authentication or alternatively one
 	#   huge file containing all of them (file must be PEM encoded)
 	#   Note: Inside SSLCACertificatePath you need hash symlinks
-	#         to point to the certificate files. Use the provided
-	#         Makefile to update the hash symlinks after changes.
+	#	  to point to the certificate files. Use the provided
+	#	  Makefile to update the hash symlinks after changes.
 	#SSLCACertificatePath /etc/ssl/certs/
 	#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
 
@@ -55,8 +55,8 @@
 	#   authentication or alternatively one huge file containing all
 	#   of them (file must be PEM encoded)
 	#   Note: Inside SSLCARevocationPath you need hash symlinks
-	#         to point to the certificate files. Use the provided
-	#         Makefile to update the hash symlinks after changes.
+	#	  to point to the certificate files. Use the provided
+	#	  Makefile to update the hash symlinks after changes.
 	#SSLCARevocationPath /etc/apache2/ssl.crl/
 	#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
 
diff --git a/docs/manual/mod/core.html.tr.utf8 b/docs/manual/mod/core.html.tr.utf8
index ed1dba5c..5d87a514 100644
--- a/docs/manual/mod/core.html.tr.utf8
+++ b/docs/manual/mod/core.html.tr.utf8
@@ -33,7 +33,6 @@
 <a href="../ja/mod/core.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a> |
 <a href="../tr/mod/core.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
 </div>
-<div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
 <table class="module"><tr><th><a href="module-dict.html#Description">Açıklama:</a></th><td>Apache HTTP Sunucusunda daima mevcut olan çekirdek
  özellikler</td></tr>
 <tr><th><a href="module-dict.html#Status">Durum:</a></th><td>Çekirdek</td></tr></table>
@@ -1359,6 +1358,11 @@ DocumentRoot "/var/www/${servername}/htdocs"</pre>
 &lt;/IfDefine&gt;</pre>
 
 
+    <div class="warning"><h3>Ek Bilgi</h3>
+      <p>Bu yönerge, çalışma zamanında değil, yapılandırma işlemi sırasında
+      değerlendirilir. Sonuç olarak, bu yönerge bir <code class="directive"><a href="#if">&lt;If&gt;</a></code> bölümü içine alınarak koşullu olarak
+      değerlendirilemez.</p>
+    </div>
 
 </div>
 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
@@ -1696,7 +1700,7 @@ ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %7F: %E: %M"
 ErrorLogFormat request "[%{uc}t] [R:%L] Request %k on C:%{c}L pid:%P tid:%T"
 ErrorLogFormat request "[%{uc}t] [R:%L] UA:'%+{User-Agent}i'"
 ErrorLogFormat request "[%{uc}t] [R:%L] Referer:'%+{Referer}i'"
-ErrorLogFormat connection "[%{uc}t] [C:%{c}L] local\ %a remote\ %A"</pre>
+ErrorLogFormat connection "[%{uc}t] [C:%{c}L] remote\ %a local\ %A"</pre>
 
 
 
@@ -2252,6 +2256,13 @@ takdirde uygulanacak yönergeleri barındırır.</td></tr>
     yönerge için kullanılabilir olmayacaktır.
     </div>
 
+    <div class="warning"><code class="directive">Define</code>,
+    <code class="directive">Include</code> ve <code class="directive">Error</code> gibi
+    yapılandırma ayrıştırılırken etkili olan yönergeler, bir <code class="directive">&lt;If&gt;</code> yapılandırma bölümü içine alınarak koşullu
+    hale getirilemez. Bu bölümler, çalışma anında nasıl değerlendirildiklerine
+    bakılmaksızın, her zaman yapılandırmanın bir parçasıdır.
+    </div>
+
 
 <h3>Ayrıca bakınız:</h3>
 <ul>
diff --git a/docs/manual/mod/mod_md.html.fr.utf8 b/docs/manual/mod/mod_md.html.fr.utf8
index 737cfbe7..22a15ac2 100644
--- a/docs/manual/mod/mod_md.html.fr.utf8
+++ b/docs/manual/mod/mod_md.html.fr.utf8
@@ -29,8 +29,6 @@
 <p><span>Langues Disponibles: </span><a href="../en/mod/mod_md.html" hreflang="en" rel="alternate" title="English">&nbsp;en&nbsp;</a> |
 <a href="../fr/mod/mod_md.html" title="Français">&nbsp;fr&nbsp;</a></p>
 </div>
-<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version
-            anglaise pour les changements récents.</div>
 <table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Gestion des domaines au sein des serveurs virtuels et obtention
     de certificats via le protocole ACME
     </td></tr>
@@ -736,6 +734,12 @@
 		vérification valide pour les certificats génériques. Si vous
 		avez besoin d'un tel certificat, vous devez alors définir cette
 		directive.
+            </p><p>
+	        Il est maintenant possible d'utiliser cette directive dans une
+		section <code class="directive"><a href="#mdomain">MDomain</a></code> pour
+		spécifier une commande spécifique au domaine considéré. Cela
+		permet de configurer un script spécifique au fournisseur de DNS
+		concerné.
             </p><p>
                 Reportez vous à la section sur les certificats génériques pour
 		plus de détails.
diff --git a/docs/manual/mod/mod_rewrite.html.en b/docs/manual/mod/mod_rewrite.html.en
index 1631fe0c..30d74341 100644
--- a/docs/manual/mod/mod_rewrite.html.en
+++ b/docs/manual/mod/mod_rewrite.html.en
@@ -1307,6 +1307,16 @@ cannot use <code>$N</code> in the substitution string!
         <td>Escape non-alphanumeric characters in backreferences <em>before</em>
         applying the transformation. <em><a href="../rewrite/flags.html#flag_b">details ...</a></em></td>
     </tr>
+<tr class="odd">
+        <td>BCTLS</td>
+        <td>Like [B], but only escape control characters and spaces.
+        <em><a href="../rewrite/flags.html#flag_bctls">details ...</a></em></td>
+    </tr>
+<tr>
+        <td>BNE</td>
+        <td>Characters of [B] or [BCTLS] which should <strong>not</strong> be escaped.
+        <em><a href="../rewrite/flags.html#flag_bne">details ...</a></em></td>
+     </tr>
 <tr class="odd">
         <td>backrefnoplus|BNP</td>
         <td>If backreferences are being escaped, spaces should be escaped to
diff --git a/docs/manual/mod/mod_rewrite.html.fr.utf8 b/docs/manual/mod/mod_rewrite.html.fr.utf8
index fcb07527..2f2625a9 100644
--- a/docs/manual/mod/mod_rewrite.html.fr.utf8
+++ b/docs/manual/mod/mod_rewrite.html.fr.utf8
@@ -1415,6 +1415,17 @@ substitution !
 	dans les références arrières <em>avant</em>
 	d'appliquer la transformation. <em><a href="../rewrite/flags.html#flag_b">détails ...</a></em></td>
     </tr>
+<tr class="odd">
+        <td>BCTLS</td>
+        <td>Identique à [B], mais n'échappe que les espaces et les caractères de
+	contrôle. <em><a href="../rewrite/flags.html#flag_bctls">détails ...</a></em></td>
+    </tr>
+<tr>
+        <td>BNE</td>
+	<td>Les caractères de [B] ou [BCTLS] qui <strong>ne doivent pas</strong>
+	être échappés.  <em><a href="../rewrite/flags.html#flag_bne">détails
+	...</a></em></td>
+    </tr>
 <tr class="odd">
         <td>backrefnoplus|BNP</td>
         <td>Avec ce drapeau, si les références arrières sont échappées,
diff --git a/docs/manual/programs/rotatelogs.html.fr.utf8 b/docs/manual/programs/rotatelogs.html.fr.utf8
index c5f8ee1d..fc71646f 100644
--- a/docs/manual/programs/rotatelogs.html.fr.utf8
+++ b/docs/manual/programs/rotatelogs.html.fr.utf8
@@ -30,8 +30,6 @@
 <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
 <a href="../tr/programs/rotatelogs.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
 </div>
-<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version
-            anglaise pour les changements récents.</div>
 
      <p><code>rotatelogs</code> est un programme simple à utiliser en
      conjonction avec la fonctionnalité d'Apache de redirection dans un
@@ -120,6 +118,15 @@ chaînes de format contenant des caractères '%' sont cependant
 respectées.
 </dd>
 
+<dt><code>-T</code></dt>
+<dd>Provoque la troncature de tous les fichiers journaux lors de leur ouverture,
+à l'exception du fichier journal initial. Cela s'avère utile lorsque la chaîne
+de formatage contient quelque chose qui va se répéter de manière cyclique, comme
+le jour du mois par exemple. Disponible à partir de la version 2.4.56 du serveur
+HTTP Apache.
+</dd>
+
+
 <dt><code>-v</code></dt>
 <dd>Affiche une sortie verbeuse sur STDERR. La sortie contient le
 résultat de l'interprétation de la configuration, ainsi que toutes les
@@ -252,6 +259,15 @@ spécifier un décalage.</dd>
      tronquant au démarrage, puis une fois par jour. Ce scénario implique qu'un
      processus séparé (tel que tail) traite le fichier en temps réel.</p>
 
+<div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -T /var/log/logfile.%d 86400" common</pre>
+</div>
+
+<p>Si le serveur est démarré ou redémarré le premier du mois, cela s'ajoute à la
+fin de <code>/var/log/logfile.01</code>. Lorsqu'une entrée de journal est écrite
+le deux du mois, <code>/var/log/logfile.02</code> est tronqué et les nouvelles
+entrées seront ajoutées à partir du début du fichier. Cet exemple conserve
+environ 1 mois de journaux sans nécessiter de maintenance externe.</p>
+
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
 <h2><a name="portability" id="portability">Portabilité</a></h2>
diff --git a/docs/manual/programs/rotatelogs.html.tr.utf8 b/docs/manual/programs/rotatelogs.html.tr.utf8
index dd0156c3..22d438b6 100644
--- a/docs/manual/programs/rotatelogs.html.tr.utf8
+++ b/docs/manual/programs/rotatelogs.html.tr.utf8
@@ -30,7 +30,6 @@
 <a href="../ko/programs/rotatelogs.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
 <a href="../tr/programs/rotatelogs.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
 </div>
-<div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
 
      <p><code><strong>rotatelogs</strong></code>, Apache'nin borulu günlük
      dosyaları özelliği ile birlikte kullanmak için tasarlanmış basit bir
@@ -109,6 +108,13 @@
     Dosya ismine bir sonek eklenmez, ancak biçem dizgesi '%' karakteri
     içeriyorsa buna uyulur.</dd>
 
+    <dt><code>-T</code></dt>
+    <dd>Açıldığında ilk günlük dosyası dışındaki tüm dosyaların kırpılmasına
+    neden olur. Bu, biçem dizgesi ayın günü gibi döngüsel bir şey içerdiğinde
+    kullanışlıdır. 2.4.56 ve sonrasında mevcuttur.
+    </dd>
+
+
     <dt><code><strong>-v</strong></code></dt>
     <dd>Standart hataya verilen çıktı daha ayrıntılı olur. Çıktı,
     yapılandırma çözümlemesinin sonuçlarını ve tüm dosya açma/kapama
@@ -191,9 +197,8 @@
 <div class="section">
 <h2><a name="examples" id="examples">Örnekler</a></h2>
 
-<div class="example"><p><code>
-     CustomLog "|bin/rotatelogs /var/log/logfile 86400" common
-</code></p></div>
+<div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/logfile 86400" common</pre>
+</div>
 
      <p>nnnn, günlük kaydının başladığı sistem zamanı olmak üzere
      /var/log/logfile.nnnn dosyası oluşturulur. Bu zaman, daima döngü
@@ -201,36 +206,41 @@
      kullanabilirsiniz. Her döngü süresinin sonunda (burada 24 saat sonra)
      yeni bir günlük dosyası açılır.</p>
 
-<div class="example"><p><code>
-     CustomLog "|bin/rotatelogs -l /var/log/logfile.%Y.%m.%d 86400" common
-</code></p></div>
+<div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -l /var/log/logfile.%Y.%m.%d 86400" common</pre>
+</div>
 
      <p>yyyy, yıl; mm, ay; dd, ayın gününü belirtmek üzere
      /var/log/logfile.yyyy.mm.dd dosyası oluşturulur. Her gün yerel zamanla
      geceyarısı yeni bir günlük dosyasına geçilecektir.</p>
 
-<div class="example"><p><code>
-     CustomLog "|bin/rotatelogs /var/log/logfile 5M" common
-</code></p></div>
+<div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs /var/log/logfile 5M" common</pre>
+</div>
 
      <p>Günlük dosyası 5 megabaytlık olunca yenisinin oluşturulmasını sağlar.
      </p>
 
-<div class="example"><p><code>
-     ErrorLog "|bin/rotatelogs /var/log/errorlog.%Y-%m-%d-%H_%M_%S 5M"
-</code></p></div>
+<div class="example"><pre class="prettyprint lang-config">ErrorLog "|bin/rotatelogs /var/log/errorlog.%Y-%m-%d-%H_%M_%S 5M"</pre>
+</div>
      <p>Hata günlüğünün 5 megabaytta bir
      <code>errorlog.YYYY-mm-dd-HH_MM_SS</code> biçemli bir isimle
      oluşturulmasını sağlar.</p>
 
-<div class="example"><p><code>
-     CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common
-</code></p></div>
+<div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common</pre>
+</div>
 
-     <p>/var/log/logfile dosyasını oluşturur, sunucu başlatılırken ve günde
+     <p><code>/var/log/logfile</code> dosyasını oluşturur, sunucu başlatılırken ve günde
        bir kere dosyanın tepesi kırpılır. Bu senaryoda ayrı bir sürecin (tail
        gibi) dosyayı gerçek zamanlı işleyeceği umulur.</p>
 
+<div class="example"><pre class="prettyprint lang-config">CustomLog "|bin/rotatelogs -T /var/log/logfile.%d 86400" common</pre>
+</div>
+
+     <p>Sunucu ayın birinde başlatılırsa (veya yeniden başlatılırsa), bu,
+     <code>/var/log/logfile.01</code> dosyasının sonuna eklenir. Ayın ikinci
+     günü bir günlük girişi yazıldığında, <code>/var/log/logfile.02</code>
+     kırpılır ve en üste yeni girdiler eklenir. Bu örnek, özel bir bakım
+     gerektirmeden yaklaşık 1 aylık günlük tutar.</p>
+
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
 <h2><a name="portability" id="portability">Taşınabilirlik</a></h2>
diff --git a/docs/manual/rewrite/flags.html.en b/docs/manual/rewrite/flags.html.en
index 5ffd1b2e..5e175f17 100644
--- a/docs/manual/rewrite/flags.html.en
+++ b/docs/manual/rewrite/flags.html.en
@@ -34,6 +34,8 @@ providing detailed explanations and examples.</p>
 <div id="quickview"><a href="https://www.apache.org/foundation/contributing.html"; class="badge"><img src="https://www.apache.org/images/SupportApache-small.png"; alt="Support Apache!" /></a><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#introduction">Introduction</a></li>
 <li><img alt="" src="../images/down.gif" /> <a href="#flag_b">B (escape backreferences)</a></li>
 <li><img alt="" src="../images/down.gif" /> <a href="#flag_bnp">BNP|backrefnoplus (don't escape space to +)</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#flag_bctls">BCTLS</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#flag_bne">BNE</a></li>
 <li><img alt="" src="../images/down.gif" /> <a href="#flag_c">C|chain</a></li>
 <li><img alt="" src="../images/down.gif" /> <a href="#flag_co">CO|cookie</a></li>
 <li><img alt="" src="../images/down.gif" /> <a href="#flag_dpi">DPI|discardpath</a></li>
@@ -85,10 +87,6 @@ of how you might use them.</p>
 <h2><a name="flag_b" id="flag_b">B (escape backreferences)</a></h2>
 <p>The [B] flag instructs <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to escape non-alphanumeric
 characters before applying the transformation.</p>
-<p>In 2.4.26 and later, you can limit the escaping to specific characters
-in backreferences by listing them: <code>[B=#?;]</code>. Note: The space
-character can be used in the list of characters to escape, but it cannot be
-the last character in the list.</p>
 
 <p><code>mod_rewrite</code> has to unescape URLs before mapping them,
 so backreferences are unescaped at the time they are applied.
@@ -120,6 +118,20 @@ when the backend may break if presented with an unescaped URL.</p>
 
 <p>An alternative to this flag is using a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> to capture against %{THE_REQUEST} which will capture
 strings in the encoded form.</p>
+
+<p>In 2.4.26 and later, you can limit the escaping to specific characters
+in backreferences by listing them: <code>[B=#?;]</code>. Note: The space
+character can be used in the list of characters to escape, but you must quote
+the entire third argument of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
+and the space must not be the last character in the list.</p>
+
+<pre class="prettyprint lang-config"># Escape spaces and question marks.  The quotes around the final argument 
+# are required when a space is included.
+RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"</pre>
+
+
+<p>To limit the characters escaped this way, see <a href="flag_bne">flag_bne</a>
+and <a href="flag_bctls">flag_bctls</a></p>
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
 <h2><a name="flag_bnp" id="flag_bnp">BNP|backrefnoplus (don't escape space to +)</a></h2>
@@ -127,8 +139,40 @@ strings in the encoded form.</p>
 in a backreference to %20 rather than '+'. Useful when the backreference
 will be used in the path component rather than the query string.</p>
 
+<pre class="prettyprint lang-config"># Escape spaces to %20 in the path instead of + as used in form submission via
+# the query string
+RewriteRule "^search/(.*)$" "/search.php/$1" "[B,BNP]"</pre>
+
+
+
 <p>This flag is available in version 2.4.26 and later.</p>
+</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="section">
+<h2><a name="flag_bctls" id="flag_bctls">BCTLS</a></h2>
+<p>The [BCTLS] flag is similar to the [B] flag, but only escapes
+control characters and the space character. This is the same set of
+characters rejected when they are copied into the query string unencoded.
+</p>
+
+<pre class="prettyprint lang-config"># Escape control characters and spaces
+RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]"</pre>
+
+
+<p>This flag is available in version 2.4.57 and later.</p>
+
+</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="section">
+<h2><a name="flag_bne" id="flag_bne">BNE</a></h2>
+<p>The list of characters in [BNE=...] are treated as exclusions to the
+characters of the [B] or [BCTLS] flags. The listed characters will not be
+escaped.
+</p>
+
+<pre class="prettyprint lang-config"># Escape the default characters, but leave /
+RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]"</pre>
+
 
+<p>This flag is available in version 2.4.57 and later.</p>
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
 <h2><a name="flag_c" id="flag_c">C|chain</a></h2>
@@ -210,7 +254,7 @@ attribute is set to the specified value.  Typical values are <code>None</code>,
 <p>Consider this example:</p>
 
 <pre class="prettyprint lang-config">RewriteEngine On
-RewriteRule "^/index\.html" "-" [CO=frontdoor:yes:.example.com:1440:/]</pre>
+RewriteRule   "^/index\.html"   "-" [CO=frontdoor:yes:.example.com:1440:/]</pre>
 
 
 <p>In the example give, the rule doesn't rewrite the request.
@@ -295,8 +339,8 @@ value of '1' if the requested URI is an image file. Then, that
 environment variable is used to exclude those requests from the access
 log.</p>
 
-<pre class="prettyprint lang-config">RewriteRule "\.(png|gif|jpg)$" "-" [E=image:1]
-CustomLog "logs/access_log" combined env=!image</pre>
+<pre class="prettyprint lang-config">RewriteRule "\.(png|gif|jpg)$"   "-" [E=image:1]
+CustomLog   "logs/access_log"    combined env=!image</pre>
 
 
 <p>Note that this same effect can be obtained using <code class="directive"><a href="../mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>. This technique is offered as
@@ -321,7 +365,7 @@ allows more flexibility in assigning a Forbidden status.</p>
 <p>The following rule will forbid <code>.exe</code> files from being
 downloaded from your server.</p>
 
-<pre class="prettyprint lang-config">RewriteRule "\.exe" "-" [F]</pre>
+<pre class="prettyprint lang-config">RewriteRule "\.exe"   "-" [F]</pre>
 
 
 <p>This example uses the "-" syntax for the rewrite target, which means
@@ -341,7 +385,7 @@ longer available.</p>
 <p>As with the [F] flag, you will typically use the "-" syntax for the
 rewrite target when using the [G] flag:</p>
 
-<pre class="prettyprint lang-config">RewriteRule "oldproduct" "-" [G,NC]</pre>
+<pre class="prettyprint lang-config">RewriteRule "oldproduct"   "-" [G,NC]</pre>
 
 
 <p>When using [G], an [L] is implied - that is, the response is returned
@@ -354,7 +398,7 @@ immediately, and no further rules are evaluated.</p>
 handler. For example, one might use this to force all files without a
 file extension to be parsed by the php handler:</p>
 
-<pre class="prettyprint lang-config">RewriteRule "!\." "-" [H=application/x-httpd-php]</pre>
+<pre class="prettyprint lang-config">RewriteRule "!\."  "-" [H=application/x-httpd-php]</pre>
 
 
 <p>
@@ -416,8 +460,8 @@ argument to <code>index.php</code>, however, the <code class="directive"><a href
 is already for <code>index.php</code>, the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> will be skipped.</p>
 
 <pre class="prettyprint lang-config">RewriteBase "/"
-RewriteCond "%{REQUEST_URI}" "!=/index.php"
-RewriteRule "^(.*)" "/index.php?req=$1" [L,PT]</pre>
+RewriteCond "%{REQUEST_URI}" !=/index.php
+RewriteRule "^(.*)"          "/index.php?req=$1" [L,PT]</pre>
 
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
@@ -440,11 +484,11 @@ pattern still matches (i.e., while the URI still contains an
 <code>A</code>), perform this substitution (i.e., replace the
 <code>A</code> with a <code>B</code>).</p>
 
-<p>In 2.4.8 and later, this module returns an error after 32,000 iterations to
+<p>In 2.4.8 and later, this module returns an error after 10,000 iterations to
 protect against unintended looping.  An alternative maximum number of
 iterations can be specified by adding to the N flag.  </p>
 <pre class="prettyprint lang-config"># Be willing to replace 1 character in each pass of the loop
-RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=64000]
+RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=32000]
 # ... or, give up if after 10 loops
 RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=10]</pre>
 
@@ -688,19 +732,21 @@ URI in request' warnings.
 <p>The [S] flag is used to skip rules that you don't want to run. The
 syntax of the skip flag is [S=<em>N</em>], where <em>N</em> signifies
 the number of rules to skip (provided the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">
-RewriteRule</a></code> matches). This can be thought of as a <code>goto</code>
-statement in your rewrite ruleset. In the following example, we only want
-to run the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> if the
-requested URI doesn't correspond with an actual file.</p>
+RewriteRule</a></code> and any preceding <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">
+RewriteCond</a></code> directives match). This can be thought of as a
+<code>goto</code> statement in your rewrite ruleset. In the following
+example, we only want to run the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">
+RewriteRule</a></code> if the requested URI doesn't correspond with an
+actual file.</p>
 
 <pre class="prettyprint lang-config"># Is the request for a non-existent file?
-RewriteCond "%{REQUEST_FILENAME}" "!-f"
-RewriteCond "%{REQUEST_FILENAME}" "!-d"
+RewriteCond "%{REQUEST_FILENAME}" !-f
+RewriteCond "%{REQUEST_FILENAME}" !-d
 # If so, skip these two RewriteRules
-RewriteRule ".?" "-" [S=2]
+RewriteRule ".?"                  "-" [S=2]
 
-RewriteRule "(.*\.gif)" "images.php?$1"
-RewriteRule "(.*\.html)" "docs.php?$1"</pre>
+RewriteRule "(.*\.gif)"           "images.php?$1"
+RewriteRule "(.*\.html)"          "docs.php?$1"</pre>
 
 
 <p>This technique is useful because a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> only applies to the
@@ -712,18 +758,18 @@ use this to make pseudo if-then-else constructs: The last rule of
 the then-clause becomes <code>skip=N</code>, where N is the
 number of rules in the else-clause:</p>
 <pre class="prettyprint lang-config"># Does the file exist?
-RewriteCond "%{REQUEST_FILENAME}" "!-f"
-RewriteCond "%{REQUEST_FILENAME}" "!-d"
+RewriteCond "%{REQUEST_FILENAME}" !-f
+RewriteCond "%{REQUEST_FILENAME}" !-d
 # Create an if-then-else construct by skipping 3 lines if we meant to go to the "else" stanza.
-RewriteRule ".?" "-" [S=3]
+RewriteRule ".?"                  "-" [S=3]
 
 # IF the file exists, then:
-    RewriteRule "(.*\.gif)" "images.php?$1"
+    RewriteRule "(.*\.gif)"  "images.php?$1"
     RewriteRule "(.*\.html)" "docs.php?$1"
     # Skip past the "else" stanza.
-    RewriteRule ".?" "-" [S=1]
+    RewriteRule ".?"         "-" [S=1]
 # ELSE...
-    RewriteRule "(.*)" "404.php?file=$1"
+    RewriteRule "(.*)"       "404.php?file=$1"
 # END</pre>
 
 
@@ -740,7 +786,7 @@ sent. This has the same effect as the <code class="directive"><a href="../mod/mo
 source code as plain text, if requested in a particular way:</p>
 
 <pre class="prettyprint lang-config"># Serve .pl files as plain text
-RewriteRule "\.pl$" "-" [T=text/plain]</pre>
+RewriteRule "\.pl$"  "-" [T=text/plain]</pre>
 
 
 <p>Or, perhaps, if you have a camera that produces jpeg images without
@@ -748,7 +794,7 @@ file extensions, you could force those images to be served with the
 correct MIME type by virtue of their file names:</p>
 
 <pre class="prettyprint lang-config"># Files with 'IMG' in the name are jpg images.
-RewriteRule "IMG" "-" [T=image/jpg]</pre>
+RewriteRule "IMG"  "-" [T=image/jpg]</pre>
 
 
 <p>Please note that this is a trivial example, and could be better done
diff --git a/docs/manual/rewrite/flags.html.fr.utf8 b/docs/manual/rewrite/flags.html.fr.utf8
index 75d9aa84..4c3e4864 100644
--- a/docs/manual/rewrite/flags.html.fr.utf8
+++ b/docs/manual/rewrite/flags.html.fr.utf8
@@ -88,13 +88,7 @@ d'utilisation.</p>
 <div class="section">
 <h2><a name="flag_b" id="flag_b">B (échappement dans les références arrières)</a></h2>
 <p>Avec le drapeau [B], la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> échappe les caractères
-non-alphanumériques avant d'appliquer la transformation. A partir
-de la version 2.4.26, vous pouvez limiter l'échappement dans les
-références arrières à une liste de caractères que vous pouvez spécifiez comme
-dans cet exemple : <code>[B=#?;]</code>. Notez que l'espace peut faire
-partie de la liste des caractères à échapper, mais qu'il ne doit pas
-être le dernier caractère de cette liste.
-</p>
+non-alphanumériques avant d'appliquer la transformation.</p>
 
 <p><code>mod_rewrite</code> doit supprimer les séquences d'échappement
 des URLs avant leur
@@ -138,6 +132,22 @@ si on présente à ce dernier une URL non échappée.</p>
 %{THE_REQUEST}, les chaînes capturées se présentant
 alors sous la forme codée.</p>
 
+<p>A partir
+de la version 2.4.26, vous pouvez limiter l'échappement dans les
+références arrières à une liste de caractères que vous pouvez spécifiez comme
+dans cet exemple : <code>[B=#?;]</code>. Notez que l'espace peut faire
+partie de la liste des caractères à échapper, mais que vous devez mettre entre
+guillemets le troisième argument de la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> et que l'espace ne doit pas
+être le dernier caractère de cette liste.
+</p>
+
+<pre class="prettyprint lang-config"># Échappement des espaces et des points d'interrogation. Les guillemets autour
+# du dernier argument sont obligatoires lorsque l'espace est inclus.
+RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"</pre>
+
+
+<p>Pour définir la liste des caractères à échapper de cette manière, voir <a href="flag_bne">flag_bne</a> et <a href="flag_bctls">flag_bctls</a></p>
+
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
 <h2><a name="flag_bnp" id="flag_bnp">BNP|backrefnoplus (ne pas échapper
@@ -147,9 +157,43 @@ espace en %20 au lieu de '+' dans les références arrières. Ceci s'avère
 utile lorsque la référence arrière est utilisée dans la partie chemin,
 et non dans les paramètres de la requête.</p>
 
+<pre class="prettyprint lang-config"># Échappe le caractère espace en %20 dans le chemin au lieu de + comme dans la
+# soumission de formulaire à l'aide de la chaîne de paramètres
+RewriteRule "^search/(.*)$" "/search.php/$1" "[B,BNP]"</pre>
+
+
 <p>Ce drapeau est disponible à partir de la version 2.4.26 du serveur HTTP
 Apache.</p>
 
+<h3><a name="flag_bctls" id="flag_bctls">BCTLS</a></h3>
+<p>Le drapeau [BCTLS] est similaire à [B], à la différence que seuls les espaces
+et les caractères de contrôle sont échappés. Il s'agit du même jeu de caractères
+rejetés lorsqu'ils sont copiés dans la chaîne de paramètres non codée.
+</p>
+
+<pre class="prettyprint lang-config"># Échappe les espaces et les caractères de contrôle
+RewriteRule "^search/(.*)$" "/search.php/$1" "[BCTLS]"</pre>
+
+
+<p>Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP
+Apache.</p>
+
+
+
+<h3><a name="flag_bne" id="flag_bne">BNE</a></h3>
+<p>Les caractères listés dans [BNE=...] sont exclus des listes de caractères
+correspondant aux drapeaux [B] ou [BCTLS]. Ils ne seront donc pas échappés.
+</p>
+
+<pre class="prettyprint lang-config"># Échappe les caractères par défaut, sauf /
+RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B,BNE=/]"</pre>
+
+ 
+<p>Ce drapeau est disponible à partir de la version 2.4.57 du serveur HTTP
+Apache.</p>
+
+
+
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
 <h2><a name="flag_c" id="flag_c">C|chain</a></h2>
@@ -234,7 +278,7 @@ partir de la version 2.4.47 du serveur HTTP Apache.</dd>
 <p>Voici un exemple :</p>
 
 <pre class="prettyprint lang-config">RewriteEngine On
-RewriteRule "^/index\.html" "-" [CO=frontdoor:yes:.example.org:1440:/]</pre>
+RewriteRule   "^/index\.html"   "-" [CO=frontdoor:yes:.example.com:1440:/]</pre>
 
 
 <p>Dans l'exemple ci-dessus, la règle ne réécrit
@@ -321,10 +365,9 @@ avec une valeur de '1' si l'URI 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.</p>
 
-<div class="example"><p><code>
-RewriteRule "\.(png|gif|jpg)" "-" [E=image:1]<br />
-CustomLog "logs/access_log" combined env=!image
-</code></p></div>
+<pre class="prettyprint lang-config">RewriteRule "\.(png|gif|jpg)$"   "-" [E=image:1]
+CustomLog   "logs/access_log"    combined env=!image</pre>
+
 
 <p>Notez que le même effet peut être obtenu à l'aide de la directive
 <code class="directive"><a href="../mod/mod_setenvif.html#setenvif">SetEnvIf</a></code>. Cette technique
@@ -351,7 +394,7 @@ Forbidden.</p>
 <p>La règle suivante va interdire la téléchargement de fichiers
 <code>.exe</code> depuis votre serveur.</p>
 
-<pre class="prettyprint lang-config">RewriteRule "\.exe" "-" [F]</pre>
+<pre class="prettyprint lang-config">RewriteRule "\.exe"   "-" [F]</pre>
 
 
 <p>Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce
@@ -372,7 +415,7 @@ disponible auparavant ne l'est plus actuellement.</p>
 <p>Comme dans le cas du drapeau [F], on utilise en général la syntaxe
 "-" pour la cible de réécriture lorsqu'on utilise le drapeau [G] :</p>
 
-<pre class="prettyprint lang-config">RewriteRule "oldproduct" "-" [G,NC]</pre>
+<pre class="prettyprint lang-config">RewriteRule "oldproduct"   "-" [G,NC]</pre>
 
 
 <p>Lorsqu'on utilise [G], [L] est implicite - c'est à dire que la
@@ -386,7 +429,7 @@ spécifié. Par exemple, on peut utiliser ce drapeau pour forcer
 l'interprétation de tous les fichiers sans extension par le gestionnaire
 php :</p>
 
-<pre class="prettyprint lang-config">RewriteRule "!\." "-" [H=application/x-httpd-php]</pre>
+<pre class="prettyprint lang-config">RewriteRule "!\."  "-" [H=application/x-httpd-php]</pre>
 
 
 <p>
@@ -455,8 +498,8 @@ directive <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">
 la requête concerne déjà <code>index.php</code>, la directive <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> sera sautée.</p>
 
 <pre class="prettyprint lang-config">RewriteBase "/"
-RewriteCond "%{REQUEST_URI}" "!=/index.php"
-RewriteRule "^(.*)" "/index.php?req=$1" [L,PT]</pre>
+RewriteCond "%{REQUEST_URI}" !=/index.php
+RewriteRule "^(.*)"          "/index.php?req=$1" [L,PT]</pre>
 
 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
 <div class="section">
@@ -484,10 +527,10 @@ effectuer la substitution (c'est à dire, remplacer le <code>A</code> par
 un <code>B</code>).</p>
 
 <p>A partir de la version 2.4.8, ce module renvoie une erreur après
-32000 itérations afin d'éviter les boucles infinies. Ce nombre maximum
+10000 itérations afin d'éviter les boucles infinies. Ce nombre maximum
 d'itération peut être modifié via le drapeau N.</p>
 <pre class="prettyprint lang-config"># On veut remplacer 1 caractère à chaque itération de la boucle
-RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=64000]
+RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=32000]
 # ... ou s'arrêter après 10 itérations
 RewriteRule "(.+)[&gt;&lt;;]$" "$1" [N=10]</pre>
 
@@ -745,19 +788,21 @@ avertissements 'Invalid URI in request'.
 <p>Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir
 exécuter. La syntaxe du drapeau [S] est [S=<em>N</em>], où
 <em>N</em> correspond au nombre de règles à sauter (sous
-réserve que la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> corresponde).
+réserve que la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> corresponde et qu'au moins
+une condition <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>
+préalable soit vérifiée). 
 Ceci peut s'interpréter comme une instruction
 <code>goto</code>  dans votre jeu de règles de réécriture. Dans
 l'exemple suivant, nous ne voulons exécuter la règle <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> que si l'URI demandé ne
 correspond pas à un fichier existant.</p>
 <pre class="prettyprint lang-config"># La requête concerne-t-elle un fichier qui n'existe pas ?
-RewriteCond "%{REQUEST_FILENAME}" "!-f"
-RewriteCond "%{REQUEST_FILENAME}" "!-d"
+RewriteCond "%{REQUEST_FILENAME}" !-f
+RewriteCond "%{REQUEST_FILENAME}" !-d
 # Si c'est la cas, on saute les deux règles de réécriture suivantes
-RewriteRule ".?" "-" [S=2]
+RewriteRule ".?"                  "-" [S=2]
 
-RewriteRule "(.*\.gif)" "images.php?$1"
-RewriteRule "(.*\.html)" "docs.php?$1"</pre>
+RewriteRule "(.*\.gif)"           "images.php?$1"
+RewriteRule "(.*\.html)"          "docs.php?$1"</pre>
 
 
 
@@ -772,18 +817,19 @@ d'élaborer des pseudo-constructions if-then-else : la dernière règle du
 bloc then contiendra <code>skip=N</code>, où N est le nombre de règles
 contenues dans le bloc else :</p>
 <pre class="prettyprint lang-config"># Est-ce que le fichier existe ?
-RewriteCond "%{REQUEST_FILENAME}" "!-f"
-RewriteCond "%{REQUEST_FILENAME}" "!-d"
-# Create an if-then-else construct by skipping 3 lines if we meant to go to the "else" stanza.
-RewriteRule ".?" "-" [S=3]
+RewriteCond "%{REQUEST_FILENAME}" !-f
+RewriteCond "%{REQUEST_FILENAME}" !-d
+# Créer une structure conditionnelle if-then-else en sautant 3 lignes si nous
+# avions l'intention d'aller au bloc "else".
+RewriteRule ".?"                  "-" [S=3]
 
 # Si le fichier existe, alors :
-RewriteRule "(.*\.gif)" "images.php?$1"
+    RewriteRule "(.*\.gif)"  "images.php?$1"
     RewriteRule "(.*\.html)" "docs.php?$1"
-    # Skip past the "else" stanza.
-    RewriteRule ".?" "-" [S=1]
+    # Passer le bloc "else".
+    RewriteRule ".?"         "-" [S=1]
 # ELSE...
-RewriteRule "(.*)" "404.php?file=$1
+    RewriteRule "(.*)"       "404.php?file=$1"
 # END</pre>
 
 
@@ -801,7 +847,7 @@ du code source Perl en tant que plein texte, s'il est requis d'une
 certaine manière :</p>
 
 <pre class="prettyprint lang-config"># Sert les fichier .pl en tant que plein texte
-RewriteRule "\.pl$" "-" [T=text/plain]</pre>
+RewriteRule "\.pl$"  "-" [T=text/plain]</pre>
 
 
 <p>Ou encore, si vous possédez une caméra qui produit des fichiers
@@ -809,7 +855,7 @@ images jpeg sans extension, vous pouvez forcer le renvoi de ces images
 avec le type MIME correct en se basant sur le nom du fichier :</p>
 
 <pre class="prettyprint lang-config"># Les fichiers dont le nom contient 'IMG' sont des images jpg.
-RewriteRule "IMG" "-" [T=image/jpg]</pre>
+RewriteRule "IMG"  "-" [T=image/jpg]</pre>
 
 
 <p>Notez cependant qu'il s'agit d'un exemple trivial, et que le problème
diff --git a/docs/manual/sections.html.tr.utf8 b/docs/manual/sections.html.tr.utf8
index be6ff8a7..b3a7cbf9 100644
--- a/docs/manual/sections.html.tr.utf8
+++ b/docs/manual/sections.html.tr.utf8
@@ -29,7 +29,6 @@
 <a href="./ko/sections.html" hreflang="ko" rel="alternate" title="Korean">&nbsp;ko&nbsp;</a> |
 <a href="./tr/sections.html" title="Türkçe">&nbsp;tr&nbsp;</a></p>
 </div>
-<div class="outofdate">Bu çeviri güncel olmayabilir. Son değişiklikler için İngilizce sürüm geçerlidir.</div>
 
     <p><a href="configuring.html">Yapılandırma dosyaları</a>ndaki
        yönergeler sunucunun tamamına uygulanacağı gibi sadece belli dizinler,
@@ -349,9 +348,9 @@ ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofail
     <p>Bazı bölüm türleri başka bölüm türlerinin içinde olabilir. Bir yandan,
       <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümü
       <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümünün
-      içinde bulunabilirken diğer yandan bir <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümü <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ve <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümlerinde bulunabilir fakat 
-      başka bir <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümünün 
-      içinde bulunamaz. Bu bölümlerin düzenli ifadeli türevleri de benzer tarzda 
+      içinde bulunabilirken diğer yandan bir <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümü <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>, <code class="directive"><a href="./mod/core.html#location">&lt;Location&gt;</a></code> ve <code class="directive"><a href="./mod/core.html#files">&lt;Files&gt;</a></code> bölümlerinde bulunabilir fakat
+      başka bir <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümünün
+      içinde bulunamaz. Bu bölümlerin düzenli ifadeli türevleri de benzer tarzda
       davranır.</p>
 
     <p>İç içe bölümler, aynı türdeki iç içe olmayan bölümlerin sonrasına
@@ -440,7 +439,9 @@ ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofail
       ve <code class="directive"><a href="./mod/core.html#locationmatch">&lt;LocationMatch&gt;</a></code>
       aynı anda işleme sokulur.</li>
 
-      <li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>
+      <li><code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> bölümleri,
+      önceki bağlamlardan herhangi birinin içine alınmış olsalar bile.
+
       </li>
     </ol>
 
@@ -448,31 +449,41 @@ ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofail
     <ul>
         <li><code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code>
         bölümündekiler hariç, her grup, yapılandırma dosyasında bulundukları
-        sıraya göre işleme sokulurlar. Örneğin, 4. grupta <em>/foo/bar</em> için yapılan 
-        bir istek <code>&lt;Location "/foo/bar"&gt;</code> ve <code>&lt;Location 
-        "/foo"&gt;</code> bölümleriyle de eşleşir ve bunlar yapılandırma 
+        sıraya göre işleme sokulurlar. Örneğin, 4. grupta <em>/foo/bar</em> için yapılan
+        bir istek <code>&lt;Location "/foo/bar"&gt;</code> ve <code>&lt;Location
+        "/foo"&gt;</code> bölümleriyle de eşleşir ve bunlar yapılandırma
         dosyalarında bulundukları sıraya göre değerlendirilir.</li>
-      
-        <li>Yukarıda 1. grup olan <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü en kısa dizin elemanından en uzun 
-        dizin elemanına doğru işleme sokulur. Yani, örneğin, <code>&lt;Directory 
-        "/var/web/dir"&gt;</code> bölümü <code>&lt;Directory    
+
+        <li>Yukarıda 1. grup olan <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü en kısa dizin elemanından en uzun
+        dizin elemanına doğru işleme sokulur. Yani, örneğin, <code>&lt;Directory
+        "/var/web/dir"&gt;</code> bölümü <code>&lt;Directory
         "/var/web/dir/subdir"&gt;</code> bölümünden önce işleme sokulacaktır.</li>
-    
-        <li>Eğer aynı dizin için birden fazla <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü varsa bunlar yapılandırma 
+
+        <li>Eğer aynı dizin için birden fazla <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> bölümü varsa bunlar yapılandırma
         dosyasında bulundukları sıraya göre işleme sokulurlar.</li>
-      
-        <li><code class="directive"><a href="./mod/core.html#include">Include</a></code> yönergeleri ile 
-        yapılandırmaya dahil edilen dosyaların içerikleri <code class="directive"><a href="./mod/core.html#include">Include</a></code> yönergesinin bulunduğu yere konulduktan 
+
+        <li><code class="directive"><a href="./mod/core.html#include">Include</a></code> yönergeleri ile
+        yapılandırmaya dahil edilen dosyaların içerikleri <code class="directive"><a href="./mod/core.html#include">Include</a></code> yönergesinin bulunduğu yere konulduktan
         sonra işleme sokulurlar.</li>
 
        <li><code class="directive"><a href="./mod/core.html#virtualhost">&lt;VirtualHost&gt;</a></code>
        bölümlerinin içindeki bölümler, sanal konak tanımı dışındaki
-       karşılıklarından <em>sonra</em> uygulanırlar. Bu yöntemle ana sunucu 
+       karşılıklarından <em>sonra</em> uygulanırlar. Bu yöntemle ana sunucu
        yapılandırmasındaki tanımlar geçersiz kılınabilir</li>
 
        <li>İstek <code class="module"><a href="./mod/mod_proxy.html">mod_proxy</a></code> tarafından sunulduğu takdirde,
        <code class="directive"><a href="./mod/mod_proxy.html#proxy">&lt;Proxy&gt;</a></code> taşıyıcısı
        işlem sırasında <code class="directive"><a href="./mod/core.html#directory">&lt;Directory&gt;</a></code> taşıyıcısının yerini alır.</li>
+
+       <li>katıştırma düzeni üzerindeki etkisi nedeniyle, ilgili yapılandırma
+       yönergelerini <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code>'in
+       içinde ve dışında karıştırırken dikkatli olunmalıdır.  Doğrudan
+       <code class="directive"><a href="./mod/core.html#else">&lt;Else&gt;</a></code> kullanımının
+       yardımı olabilir.</li>
+
+       <li><code>.htaccess</code> içinde <code class="directive"><a href="./mod/core.html#if">&lt;If&gt;</a></code> kullanıldığında, üst dizindeki sarmalanmış
+       yönergeler, alt dizinde sarmalanmamış yönergelerden <em>sonra</em>
+       birleştirilir.</li>
     </ul>
 
     <div class="note"><h3>Bazı Teknik Bilgiler</h3>
@@ -484,35 +495,35 @@ ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofail
       tamamen elden çıkarılır.
     </div>
 
-  <h3><a name="relationship-module-configuration" id="relationship-module-configuration">Modüllerle 
+  <h3><a name="relationship-module-configuration" id="relationship-module-configuration">Modüllerle
     yapılandırma bölümleri arasındaki ilişki</a></h3>
-  
-    <p>Yapılandırma bölümlerini okurken örneğin <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>  
-      gibi belli modüllerin yönergelerinin bu bölümlere nasıl katılacağı ve  
-      ne zaman nasıl işleneceği gibi sorular sıkça aklımızdan geçer. Bunun 
-      belli bir yanıtı yoktur ve biraz temel bilgi gerektirir. Her httpd 
-      modülü yapılandırmasını kendi yönetir ve httpd.conf içindeki 
-      yönergelerinin her biri belli bir bağlamdaki bir yapılandırmayı 
+
+    <p>Yapılandırma bölümlerini okurken örneğin <code class="module"><a href="./mod/mod_rewrite.html">mod_rewrite</a></code>
+      gibi belli modüllerin yönergelerinin bu bölümlere nasıl katılacağı ve
+      ne zaman nasıl işleneceği gibi sorular sıkça aklımızdan geçer. Bunun
+      belli bir yanıtı yoktur ve biraz temel bilgi gerektirir. Her httpd
+      modülü yapılandırmasını kendi yönetir ve httpd.conf içindeki
+      yönergelerinin her biri belli bir bağlamdaki bir yapılandırmayı
       belirtir. httpd bir komutu okunduğu sırada çalıştırmaz.</p>
-    
-    <p>Çalışma anında, httpd çekirdeği geçerli isteğe hangilerinin 
-      uygulanacağını belirlemek için yukarıda açıklanan sırada tanımlı 
-      yapılandırma bölümlerini tekrar tekrar okur. Eşleşen ilk bölümün bu 
-      istek için geçerli yapılandırmayı içerdiği varsayılır. Eğer alt 
-      bölümlerden biri de eşleşmişse bu bölümlerde yönergeleri bulunan her 
-      modüle yapılandırmasını iki bölüm arasında katıştırma şansı verilir. 
-      Sonuç üçüncü bir yapılandırma olup işlem bütün yapılandırma bölümleri 
+
+    <p>Çalışma anında, httpd çekirdeği geçerli isteğe hangilerinin
+      uygulanacağını belirlemek için yukarıda açıklanan sırada tanımlı
+      yapılandırma bölümlerini tekrar tekrar okur. Eşleşen ilk bölümün bu
+      istek için geçerli yapılandırmayı içerdiği varsayılır. Eğer alt
+      bölümlerden biri de eşleşmişse bu bölümlerde yönergeleri bulunan her
+      modüle yapılandırmasını iki bölüm arasında katıştırma şansı verilir.
+      Sonuç üçüncü bir yapılandırma olup işlem bütün yapılandırma bölümleri
       değerlendirilene kadar sürer.</p>
-    
-    <p>Yukarıdaki adımların ardından HTTP isteğiyle ilgili "asıl" işlem 
-      başlar: her modül ondan istenen görevleri gerçekleştirme şansına sahip 
-      olur. Nasıl davranacaklarını belirlemek için kendilerinin katıştırılmış 
+
+    <p>Yukarıdaki adımların ardından HTTP isteğiyle ilgili "asıl" işlem
+      başlar: her modül ondan istenen görevleri gerçekleştirme şansına sahip
+      olur. Nasıl davranacaklarını belirlemek için kendilerinin katıştırılmış
       son yapılandırmalarını http çekirdeğinden alabilirler.</p>
-    
-    <p>Sürecin tamamı bir örnekle görselleştirilebilir. Aşağıdaki örnekte 
-      belli bir HTTP başlığını ayarlamak için <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> 
-      modülünün <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> yönergesi 
-      kullanılmıştır. <code>/example/index.html</code> isteği için httpd 
+
+    <p>Sürecin tamamı bir örnekle görselleştirilebilir. Aşağıdaki örnekte
+      belli bir HTTP başlığını ayarlamak için <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code>
+      modülünün <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> yönergesi
+      kullanılmıştır. <code>/example/index.html</code> isteği için httpd
       <code>CustomHeaderName</code> başlığına hangi değeri atayacaktır?
     </p>
     <pre class="prettyprint lang-config">&lt;Directory "/"&gt;
@@ -525,37 +536,37 @@ ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofail
 &lt;Directory "/example"&gt;
     Header set CustomHeaderName iki
 &lt;/Directory&gt;</pre>
-    
+
     <ul>
-        <li><code class="directive">Directory</code> "/" eşleşir ve ilk yapılandırma 
-          olarak <code>CustomHeaderName</code> başlığı <code>bir</code> 
+        <li><code class="directive">Directory</code> "/" eşleşir ve ilk yapılandırma
+          olarak <code>CustomHeaderName</code> başlığı <code>bir</code>
           değeriyle oluşturulur.</li>
-        
-        <li><code class="directive">Directory</code> "/example" eşleşir ve 
-          <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> modülünün koduna göre bir katıştırma 
-          durumundan yeni değer eskiyi geçersiz kılacağından yeni bir 
-          yapılandırma ile <code>CustomHeaderName</code> başlığının değeri 
+
+        <li><code class="directive">Directory</code> "/example" eşleşir ve
+          <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> modülünün koduna göre bir katıştırma
+          durumundan yeni değer eskiyi geçersiz kılacağından yeni bir
+          yapılandırma ile <code>CustomHeaderName</code> başlığının değeri
           <code>iki</code> yapılır.</li>
-        
-        <li><code class="directive">FilesMatch</code> ".*" eşleşir ve başka bir 
-          katıştırma fırsatı doğar: <code>CustomHeaderName</code> başlığının 
+
+        <li><code class="directive">FilesMatch</code> ".*" eşleşir ve başka bir
+          katıştırma fırsatı doğar: <code>CustomHeaderName</code> başlığının
           değeri <code>yedi</code> yapılır.</li>
-        
-        <li>Neticede HHP isteğinin sonraki adımlarında 
-          <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> çağrılıp <code>yedi</code> değeri 
-          atanmış <code>CustomHeaderName</code> başlığını işleme sokması 
-          istenecektir. <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> normalde işini yapmak 
-          için bu yapılandırmayı kullanacaktır. Fakat bundan, bir yönergenin  
-          gerekli olmaması veya kullanımdan kaldırılması ve benzeri nedenlerle 
-          yapılandırmada iptal edilmesi gibi daha karmaşık bir eylemi bir 
+
+        <li>Neticede HHP isteğinin sonraki adımlarında
+          <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> çağrılıp <code>yedi</code> değeri
+          atanmış <code>CustomHeaderName</code> başlığını işleme sokması
+          istenecektir. <code class="module"><a href="./mod/mod_headers.html">mod_headers</a></code> normalde işini yapmak
+          için bu yapılandırmayı kullanacaktır. Fakat bundan, bir yönergenin
+          gerekli olmaması veya kullanımdan kaldırılması ve benzeri nedenlerle
+          yapılandırmada iptal edilmesi gibi daha karmaşık bir eylemi bir
           modülün gerçekleştiremeyeceği anlamı çıkarılmamalıdır.</li>
     </ul>
 
-    <p><code class="directive">Directory</code> ile aynı katıştırma sırasından dolayı 
-      bu durum .htaccess için de geçerlidir. Burada anlaşılması gereken husus, 
-      <code class="directive">Directory</code> ve <code class="directive">FilesMatch</code> 
-      gibi yapılandırma bölümlerinin <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> veya <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> gibi modüle özgü 
-      yönergelerle karşılaştırılmamasıdır, çünkü bunlar farklı seviyelerde 
+    <p><code class="directive">Directory</code> ile aynı katıştırma sırasından dolayı
+      bu durum .htaccess için de geçerlidir. Burada anlaşılması gereken husus,
+      <code class="directive">Directory</code> ve <code class="directive">FilesMatch</code>
+      gibi yapılandırma bölümlerinin <code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code> veya <code class="directive"><a href="./mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> gibi modüle özgü
+      yönergelerle karşılaştırılmamasıdır, çünkü bunlar farklı seviyelerde
       işlem görür.
     </p>
   
diff --git a/docs/manual/style/version.ent b/docs/manual/style/version.ent
index 29e0dfc7..30ec0ddd 100644
--- a/docs/manual/style/version.ent
+++ b/docs/manual/style/version.ent
@@ -19,6 +19,6 @@
 
 <!ENTITY httpd.major "2">
 <!ENTITY httpd.minor "4">
-<!ENTITY httpd.patch "56">
+<!ENTITY httpd.patch "57">
 
 <!ENTITY httpd.docs "2.4">
diff --git a/httpd.spec b/httpd.spec
index c0c788eb..c253895e 100644
--- a/httpd.spec
+++ b/httpd.spec
@@ -4,7 +4,7 @@
 
 Summary: Apache HTTP Server
 Name: httpd
-Version: 2.4.56
+Version: 2.4.57
 Release: 1
 URL: http://httpd.apache.org/
 Vendor: Apache Software Foundation
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index 402c23a3..ace7c43e 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -594,7 +594,7 @@
  * 20120211.124 (2.4.51-dev) Add name_ex to struct proxy_worker_shared
  * 20120211.125 (2.4.55-dev) Export mod_http2.h as public header
  * 20120211.126 (2.4.55-dev) Add additional hcmethod_t enums and PROXY_WORKER_IS_ERROR
- *
+ * 20120211.127 (2.4.56-dev) Add ap_proxy_canonenc_ex
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -602,7 +602,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20120211
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 126                 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 127                 /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
diff --git a/include/ap_release.h b/include/ap_release.h
index c858aaea..a5f511ae 100644
--- a/include/ap_release.h
+++ b/include/ap_release.h
@@ -43,7 +43,7 @@
 
 #define AP_SERVER_MAJORVERSION_NUMBER 2
 #define AP_SERVER_MINORVERSION_NUMBER 4
-#define AP_SERVER_PATCHLEVEL_NUMBER   56
+#define AP_SERVER_PATCHLEVEL_NUMBER   57
 #define AP_SERVER_DEVBUILD_BOOLEAN    0
 
 /* Synchronize the above with docs/manual/style/version.ent */
diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c
index 03d1c411..700f824f 100644
--- a/modules/http/mod_mime.c
+++ b/modules/http/mod_mime.c
@@ -755,7 +755,7 @@ static int find_ct(request_rec *r)
     mime_dir_config *conf;
     apr_array_header_t *exception_list;
     char *ext;
-    const char *fn, *fntmp, *type, *charset = NULL, *resource_name;
+    const char *fn, *fntmp, *type, *charset = NULL, *resource_name, *qm;
     int found_metadata = 0;
 
     if (r->finfo.filetype == APR_DIR) {
@@ -775,6 +775,19 @@ static int find_ct(request_rec *r)
     if (conf->use_path_info & 1) {
         resource_name = apr_pstrcat(r->pool, r->filename, r->path_info, NULL);
     }
+    /*
+     * In the reverse proxy case r->filename might contain a query string if
+     * the nocanon option was used with ProxyPass.
+     * If this is the case cut off the query string as the last parameter in
+     * this query string might end up on an extension we take care about, but
+     * we only want to match against path components not against query
+     * parameters.
+     */
+    else if ((r->proxyreq == PROXYREQ_REVERSE)
+             && (apr_table_get(r->notes, "proxy-nocanon"))
+             && ((qm = ap_strchr_c(r->filename, '?')) != NULL)) {
+        resource_name = apr_pstrmemdup(r->pool, r->filename, qm - r->filename);
+    }
     else {
         resource_name = r->filename;
     }
diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c
index bddbad51..20e94cd8 100644
--- a/modules/http2/h2_request.c
+++ b/modules/http2/h2_request.c
@@ -279,7 +279,7 @@ static request_rec *my_ap_create_request(conn_rec *c)
 apr_bucket *h2_request_create_bucket(const h2_request *req, request_rec *r)
 {
     conn_rec *c = r->connection;
-    apr_table_t *headers = apr_table_copy(r->pool, req->headers);
+    apr_table_t *headers = apr_table_clone(r->pool, req->headers);
     const char *uri = req->path;
 
     AP_DEBUG_ASSERT(req->authority);
@@ -303,7 +303,7 @@ static void assign_headers(request_rec *r, const h2_request *req,
 {
     const char *cl;
 
-    r->headers_in = apr_table_copy(r->pool, req->headers);
+    r->headers_in = apr_table_clone(r->pool, req->headers);
     if (req->authority) {
         /* for internal handling, we have to simulate that :authority
          * came in as Host:, RFC 9113 ch. says that mismatches between
diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c
index aa299b93..5abccab0 100644
--- a/modules/http2/mod_proxy_http2.c
+++ b/modules/http2/mod_proxy_http2.c
@@ -154,29 +154,41 @@ static int proxy_http2_canon(request_rec *r, char *url)
         if (apr_table_get(r->notes, "proxy-nocanon")) {
             path = url;   /* this is the raw path */
         }
-        else {
-            path = ap_proxy_canonenc(r->pool, url, (int)strlen(url),
-                                     enc_path, 0, r->proxyreq);
+        else if (apr_table_get(r->notes, "proxy-noencode")) {
+            path = url;   /* this is the encoded path already */
             search = r->args;
-            if (search && *(ap_scan_vchar_obstext(search))) {
-                /*
-                 * We have a raw control character or a ' ' in r->args.
-                 * Correct encoding was missed.
-                 */
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
-                              "To be forwarded query string contains control "
-                              "characters or spaces");
-                return HTTP_FORBIDDEN;
+        }
+        else {
+            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+            int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+            path = ap_proxy_canonenc_ex(r->pool, url, (int)strlen(url),
+                                        enc_path, flags, r->proxyreq);
+            if (!path) {
+                return HTTP_BAD_REQUEST;
             }
+            search = r->args;
         }
         break;
     case PROXYREQ_PROXY:
         path = url;
         break;
     }
-
-    if (path == NULL) {
-        return HTTP_BAD_REQUEST;
+    /*
+     * If we have a raw control character or a ' ' in nocanon path or
+     * r->args, correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10420)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
+    }
+    if (search && *ap_scan_vchar_obstext(search)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10412)
+                      "To be forwarded query string contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
     }
 
     if (port != def_port) {
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 5195ceee..f93f23f0 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -106,6 +106,8 @@
 #include "mod_rewrite.h"
 #include "ap_expr.h"
 
+#include "test_char.h"
+
 static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL;
 static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
 static const char* really_last_key = "rewrite_really_last";
@@ -174,6 +176,7 @@ static const char* really_last_key = "rewrite_really_last";
 #define RULEFLAG_ESCAPENOPLUS       (1<<18)
 #define RULEFLAG_QSLAST             (1<<19)
 #define RULEFLAG_QSNONE             (1<<20) /* programattic only */
+#define RULEFLAG_ESCAPECTLS         (1<<21)
 
 /* return code of the rewrite rule
  * the result may be escaped - or not
@@ -327,7 +330,8 @@ typedef struct {
     data_item *cookie;               /* added cookies                         */
     int        skip;                 /* number of next rules to skip          */
     int        maxrounds;            /* limit on number of loops with N flag  */
-    char       *escapes;             /* specific backref escapes              */
+    const char *escapes;             /* specific backref escapes              */
+    const char *noescapes;           /* specific backref chars not to escape  */
 } rewriterule_entry;
 
 typedef struct {
@@ -427,7 +431,9 @@ static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
 static const char *rewritemap_mutex_type = "rewrite-map";
 
 /* Optional functions imported from mod_ssl when loaded: */
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus);
+static char *escape_backref(apr_pool_t *p, const char *path,
+                            const char *escapeme, const char *noescapeme,
+                            int flags);
 
 /*
  * +-------------------------------------------------------+
@@ -654,14 +660,21 @@ static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
  * Escapes a backreference in a similar way as php's urlencode does.
  * Based on ap_os_escape_path in server/util.c
  */
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus) {
-    char *copy = apr_palloc(p, 3 * strlen(path) + 3);
+static char *escape_backref(apr_pool_t *p, const char *path,
+                            const char *escapeme, const char *noescapeme,
+                            int flags)
+{
+    char *copy = apr_palloc(p, 3 * strlen(path) + 1);
     const unsigned char *s = (const unsigned char *)path;
     unsigned char *d = (unsigned char *)copy;
-    unsigned c;
+    int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
+    int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
+    unsigned char c;
 
     while ((c = *s)) {
-        if (!escapeme) { 
+        if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
+             || (escapeme && ap_strchr_c(escapeme, c)))
+            && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
             if (apr_isalnum(c) || c == '_') {
                 *d++ = c;
             }
@@ -672,23 +685,8 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem
                 d = c2x(c, '%', d);
             }
         }
-        else { 
-            const char *esc = escapeme;
-            while (*esc) { 
-                if (c == *esc) { 
-                    if (c == ' ' && !noplus) { 
-                        *d++ = '+';
-                    }
-                    else { 
-                        d = c2x(c, '%', d);
-                    }
-                    break;
-                }
-                ++esc;
-            }
-            if (!*esc) { 
-                *d++ = c;
-            }
+        else {
+            *d++ = c;
         }
         ++s;
     }
@@ -2469,7 +2467,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
                     /* escape the backreference */
                     char *tmp2, *tmp;
                     tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
-                    tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags & RULEFLAG_ESCAPENOPLUS);
+                    tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
+                                          entry->flags);
                     rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
                             tmp, tmp2));
 
@@ -3541,13 +3540,24 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
     case 'B':
         if (!*key || !strcasecmp(key, "ackrefescaping")) {
             cfg->flags |= RULEFLAG_ESCAPEBACKREF;
-            if (val && *val) { 
+            if (val && *val) {
                 cfg->escapes = val;
             }
         }
+        else if (!strcasecmp(key, "NE")) {
+            if (val && *val) {
+                cfg->noescapes = val;
+            }
+            else {
+                return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
+            }
+        }
         else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) { 
             cfg->flags |= RULEFLAG_ESCAPENOPLUS;
         }
+        else if (!strcasecmp(key, "CTLS")) {
+            cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF;
+        }
         else {
             ++error;
         }
@@ -3809,7 +3819,6 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
                            "'", NULL);
     }
 
-    /* arg3: optional flags field */
     newrule->forced_mimetype     = NULL;
     newrule->forced_handler      = NULL;
     newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
@@ -3818,6 +3827,9 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
     newrule->cookie = NULL;
     newrule->skip   = 0;
     newrule->maxrounds = REWRITE_MAX_ROUNDS;
+    newrule->escapes = newrule->noescapes = NULL;
+
+    /* arg3: optional flags field */
     if (a3 != NULL) {
         if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
                                       cmd_rewriterule_setflag)) != NULL) {
@@ -3854,6 +3866,7 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
     if (*(a2_end-1) == '?') {
         /* a literal ? at the end of the unsubstituted rewrite rule */
         newrule->flags |= RULEFLAG_QSNONE;
+        *(a2_end-1) = '\0'; /* trailing ? has done its job */
     }
     else if (newrule->flags & RULEFLAG_QSDISCARD) {
         if (NULL == ap_strchr(newrule->output, '?')) {
@@ -4745,13 +4758,19 @@ static int hook_uri2file(request_rec *r)
     }
 
     if (rulestatus) {
-        unsigned skip;
-        apr_size_t flen;
-
-        if (r->args && *(ap_scan_vchar_obstext(r->args))) {
+        unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
+        apr_size_t flen =  r->filename ? strlen(r->filename) : 0;
+        int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
+        int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
+
+        if (r->args
+                && !will_escape
+                && *(ap_scan_vchar_obstext(r->args))) {
             /*
              * We have a raw control character or a ' ' in r->args.
              * Correct encoding was missed.
+             * Correct encoding was missed and we're not going to escape
+             * it before returning.
              */
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410)
                           "Rewritten query string contains control "
@@ -4766,8 +4785,7 @@ static int hook_uri2file(request_rec *r)
             return n;
         }
 
-        flen = r->filename ? strlen(r->filename) : 0;
-        if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
+        if (to_proxyreq) {
             /* it should be go on as an internal proxy request */
 
             /* check if the proxy module is enabled, so
@@ -4809,7 +4827,7 @@ static int hook_uri2file(request_rec *r)
                         r->filename));
             return OK;
         }
-        else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
+        else if (skip_absolute > 0) {
             int n;
 
             /* it was finally rewritten to a remote URL */
@@ -4817,7 +4835,7 @@ static int hook_uri2file(request_rec *r)
             if (rulestatus != ACTION_NOESCAPE) {
                 rewritelog((r, 1, NULL, "escaping %s for redirect",
                             r->filename));
-                r->filename = escape_absolute_uri(r->pool, r->filename, skip);
+                r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
             }
 
             /* append the QUERY_STRING part */
@@ -5041,9 +5059,17 @@ static int hook_fixup(request_rec *r)
      */
     rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory);
     if (rulestatus) {
-        unsigned skip;
+        unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
+        int to_proxyreq = 0;
+        int will_escape = 0;
 
-        if (r->args && *(ap_scan_vchar_obstext(r->args))) {
+        l = strlen(r->filename);
+        to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0;
+        will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
+
+        if (r->args
+               && !will_escape
+               &&  *(ap_scan_vchar_obstext(r->args))) {
             /*
              * We have a raw control character or a ' ' in r->args.
              * Correct encoding was missed.
@@ -5061,8 +5087,7 @@ static int hook_fixup(request_rec *r)
             return n;
         }
 
-        l = strlen(r->filename);
-        if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
+        if (to_proxyreq) {
             /* it should go on as an internal proxy request */
 
             /* make sure the QUERY_STRING and
@@ -5086,7 +5111,7 @@ static int hook_fixup(request_rec *r)
                         "%s [OK]", r->filename));
             return OK;
         }
-        else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
+        else if (skip_absolute > 0) {
             /* it was finally rewritten to a remote URL */
 
             /* because we are in a per-dir context
@@ -5095,7 +5120,7 @@ static int hook_fixup(request_rec *r)
              */
             if (dconf->baseurl != NULL) {
                 /* skip 'scheme://' */
-                cp = r->filename + skip;
+                cp = r->filename + skip_absolute;
 
                 if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) {
                     rewritelog((r, 2, dconf->directory,
@@ -5140,7 +5165,7 @@ static int hook_fixup(request_rec *r)
             if (rulestatus != ACTION_NOESCAPE) {
                 rewritelog((r, 1, dconf->directory, "escaping %s for redirect",
                             r->filename));
-                r->filename = escape_absolute_uri(r->pool, r->filename, skip);
+                r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
             }
 
             /* append the QUERY_STRING part */
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 9225bc9b..537c3c25 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -963,6 +963,8 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
     }
 
     if (found) {
+        unsigned int encoded = ent->flags & PROXYPASS_MAP_ENCODED;
+
         /* A proxy module is assigned this URL, check whether it's interested
          * in the request itself (e.g. proxy_wstunnel cares about Upgrade
          * requests only, and could hand over to proxy_http otherwise).
@@ -982,6 +984,9 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
         if (ent->flags & PROXYPASS_NOQUERY) {
             apr_table_setn(r->notes, "proxy-noquery", "1");
         }
+        if (encoded) {
+            apr_table_setn(r->notes, "proxy-noencode", "1");
+        }
 
         if (servlet_uri) {
             ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10248)
@@ -995,13 +1000,13 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
              */
             AP_DEBUG_ASSERT(strlen(r->uri) >= strlen(servlet_uri));
             strcpy(r->uri, servlet_uri);
-            return DONE;
         }
-
-        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464)
-                      "URI path '%s' matches proxy handler '%s'", r->uri,
-                      found);
-        return OK;
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(03464)
+                          "URI path '%s' matches proxy handler '%s'", r->uri,
+                          found);
+        }
+        return (encoded) ? DONE : OK;
     }
 
     return HTTP_CONTINUE;
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 5c08e99c..c51145e0 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -76,6 +76,10 @@ enum enctype {
     enc_path, enc_search, enc_user, enc_fpath, enc_parm
 };
 
+/* Flags for ap_proxy_canonenc_ex */
+#define PROXY_CANONENC_FORCEDEC 0x01
+#define PROXY_CANONENC_NOENCODEDSLASHENCODING 0x02
+
 typedef enum {
     NONE, TCP, OPTIONS, HEAD, GET, CPING, PROVIDER, OPTIONS11, HEAD11, GET11, EOT
 } hcmethod_t;
@@ -676,6 +680,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_strncpy(char *dst, const char *src,
                                              apr_size_t dlen);
 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x);
 PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x);
+PROXY_DECLARE(char *)ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len, enum enctype t,
+                                          int flags, int proxyreq);
 PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
                                        int forcedec, int proxyreq);
 PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
index e46bd903..65773ce7 100644
--- a/modules/proxy/mod_proxy_ajp.c
+++ b/modules/proxy/mod_proxy_ajp.c
@@ -65,23 +65,37 @@ static int proxy_ajp_canon(request_rec *r, char *url)
     if (apr_table_get(r->notes, "proxy-nocanon")) {
         path = url;   /* this is the raw path */
     }
-    else {
-        path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
-                                 r->proxyreq);
+    else if (apr_table_get(r->notes, "proxy-noencode")) {
+        path = url;   /* this is the encoded path already */
         search = r->args;
-        if (search && *(ap_scan_vchar_obstext(search))) {
-            /*
-             * We have a raw control character or a ' ' in r->args.
-             * Correct encoding was missed.
-             */
-             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406)
-                           "To be forwarded query string contains control "
-                           "characters or spaces");
-             return HTTP_FORBIDDEN;
+    }
+    else {
+        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                    r->proxyreq);
+        if (!path) {
+            return HTTP_BAD_REQUEST;
         }
+        search = r->args;
+    }
+    /*
+     * If we have a raw control character or a ' ' in nocanon path or
+     * r->args, correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10418)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
+    }
+    if (search && *ap_scan_vchar_obstext(search)) {
+         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406)
+                       "To be forwarded query string contains control "
+                       "characters or spaces");
+         return HTTP_FORBIDDEN;
     }
-    if (path == NULL)
-        return HTTP_BAD_REQUEST;
 
     if (port != def_port)
          apr_snprintf(sport, sizeof(sport), ":%d", port);
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
index 7f990084..b8b452d0 100644
--- a/modules/proxy/mod_proxy_balancer.c
+++ b/modules/proxy/mod_proxy_balancer.c
@@ -102,23 +102,37 @@ static int proxy_balancer_canon(request_rec *r, char *url)
     if (apr_table_get(r->notes, "proxy-nocanon")) {
         path = url;   /* this is the raw path */
     }
-    else {
-        path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
-                                 r->proxyreq);
+    else if (apr_table_get(r->notes, "proxy-noencode")) {
+        path = url;   /* this is the encoded path already */
         search = r->args;
-        if (search && *(ap_scan_vchar_obstext(search))) {
-            /*
-             * We have a raw control character or a ' ' in r->args.
-             * Correct encoding was missed.
-             */
-             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10407)
-                           "To be forwarded query string contains control "
-                           "characters or spaces");
-             return HTTP_FORBIDDEN;
+    }
+    else {
+        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                    r->proxyreq);
+        if (!path) {
+            return HTTP_BAD_REQUEST;
         }
+        search = r->args;
+    }
+    /*
+     * If we have a raw control character or a ' ' in nocanon path or
+     * r->args, correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10416)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
+    }
+    if (search && *ap_scan_vchar_obstext(search)) {
+         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10407)
+                       "To be forwarded query string contains control "
+                       "characters or spaces");
+         return HTTP_FORBIDDEN;
     }
-    if (path == NULL)
-        return HTTP_BAD_REQUEST;
 
     r->filename = apr_pstrcat(r->pool, "proxy:" BALANCER_PREFIX, host,
             "/", path, (search) ? "?" : "", (search) ? search : "", NULL);
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
index 3382b9bf..831bd15a 100644
--- a/modules/proxy/mod_proxy_fcgi.c
+++ b/modules/proxy/mod_proxy_fcgi.c
@@ -92,15 +92,30 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
         host = apr_pstrcat(r->pool, "[", host, "]", NULL);
     }
 
-    if (apr_table_get(r->notes, "proxy-nocanon")) {
-        path = url;   /* this is the raw path */
+    if (apr_table_get(r->notes, "proxy-nocanon")
+        || apr_table_get(r->notes, "proxy-noencode")) {
+        path = url;   /* this is the raw/encoded path */
     }
     else {
-        path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
-                             r->proxyreq);
+        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                    r->proxyreq);
+        if (!path) {
+            return HTTP_BAD_REQUEST;
+        }
+    }
+    /*
+     * If we have a raw control character or a ' ' in nocanon path,
+     * correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10414)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
     }
-    if (path == NULL)
-        return HTTP_BAD_REQUEST;
 
     r->filename = apr_pstrcat(r->pool, "proxy:fcgi://", host, sport, "/",
                               path, NULL);
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
index 3237a2ba..a3fb10a9 100644
--- a/modules/proxy/mod_proxy_ftp.c
+++ b/modules/proxy/mod_proxy_ftp.c
@@ -289,6 +289,8 @@ static int proxy_ftp_canon(request_rec *r, char *url)
     apr_pool_t *p = r->pool;
     const char *err;
     apr_port_t port, def_port;
+    core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+    int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
 
     /* */
     if (ap_cstr_casecmpn(url, "ftp:", 4) == 0) {
@@ -327,7 +329,8 @@ static int proxy_ftp_canon(request_rec *r, char *url)
     else
         parms = "";
 
-    path = ap_proxy_canonenc(p, url, strlen(url), enc_path, 0, r->proxyreq);
+    path = ap_proxy_canonenc_ex(p, url, strlen(url), enc_path, flags,
+                                r->proxyreq);
     if (path == NULL)
         return HTTP_BAD_REQUEST;
     if (!ftp_check_string(path))
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
index 51d19a0a..1842c49e 100644
--- a/modules/proxy/mod_proxy_http.c
+++ b/modules/proxy/mod_proxy_http.c
@@ -121,29 +121,42 @@ static int proxy_http_canon(request_rec *r, char *url)
         if (apr_table_get(r->notes, "proxy-nocanon")) {
             path = url;   /* this is the raw path */
         }
-        else {
-            path = ap_proxy_canonenc(r->pool, url, strlen(url),
-                                     enc_path, 0, r->proxyreq);
+        else if (apr_table_get(r->notes, "proxy-noencode")) {
+            path = url;   /* this is the encoded path already */
             search = r->args;
-            if (search && *(ap_scan_vchar_obstext(search))) {
-                /*
-                 * We have a raw control character or a ' ' in r->args.
-                 * Correct encoding was missed.
-                 */
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408)
-                              "To be forwarded query string contains control "
-                              "characters or spaces");
-                return HTTP_FORBIDDEN;
+        }
+        else {
+            core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+            int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+            path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path,
+                                        flags, r->proxyreq);
+            if (!path) {
+                return HTTP_BAD_REQUEST;
             }
+            search = r->args;
         }
         break;
     case PROXYREQ_PROXY:
         path = url;
         break;
     }
-
-    if (path == NULL)
-        return HTTP_BAD_REQUEST;
+    /*
+     * If we have a raw control character or a ' ' in nocanon path or
+     * r->args, correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10415)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
+    }
+    if (search && *ap_scan_vchar_obstext(search)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408)
+                      "To be forwarded query string contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
+    }
 
     if (port != def_port)
         apr_snprintf(sport, sizeof(sport), ":%d", port);
diff --git a/modules/proxy/mod_proxy_scgi.c b/modules/proxy/mod_proxy_scgi.c
index 493757d3..5444a5c4 100644
--- a/modules/proxy/mod_proxy_scgi.c
+++ b/modules/proxy/mod_proxy_scgi.c
@@ -179,6 +179,8 @@ static int scgi_canon(request_rec *r, char *url)
     char *host, sport[sizeof(":65535")];
     const char *err, *path;
     apr_port_t port, def_port;
+    core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+    int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
 
     if (ap_cstr_casecmpn(url, SCHEME "://", sizeof(SCHEME) + 2)) {
         return DECLINED;
@@ -205,8 +207,8 @@ static int scgi_canon(request_rec *r, char *url)
         host = apr_pstrcat(r->pool, "[", host, "]", NULL);
     }
 
-    path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
-                             r->proxyreq);
+    path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                r->proxyreq);
     if (!path) {
         return HTTP_BAD_REQUEST;
     }
diff --git a/modules/proxy/mod_proxy_uwsgi.c b/modules/proxy/mod_proxy_uwsgi.c
index 92e153cc..fd76c955 100644
--- a/modules/proxy/mod_proxy_uwsgi.c
+++ b/modules/proxy/mod_proxy_uwsgi.c
@@ -84,10 +84,29 @@ static int uwsgi_canon(request_rec *r, char *url)
         host = apr_pstrcat(r->pool, "[", host, "]", NULL);
     }
 
-    path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
-                             r->proxyreq);
-    if (!path) {
-        return HTTP_BAD_REQUEST;
+    if (apr_table_get(r->notes, "proxy-nocanon")
+        || apr_table_get(r->notes, "proxy-noencode")) {
+        path = url;   /* this is the raw/encoded path */
+    }
+    else {
+        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                    r->proxyreq);
+        if (!path) {
+            return HTTP_BAD_REQUEST;
+        }
+    }
+    /*
+     * If we have a raw control character or a ' ' in nocanon path,
+     * correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10417)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
     }
 
     r->filename =
diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
index 88f86a49..30ba1b49 100644
--- a/modules/proxy/mod_proxy_wstunnel.c
+++ b/modules/proxy/mod_proxy_wstunnel.c
@@ -110,23 +110,37 @@ static int proxy_wstunnel_canon(request_rec *r, char *url)
     if (apr_table_get(r->notes, "proxy-nocanon")) {
         path = url;   /* this is the raw path */
     }
-    else {
-        path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
-                                 r->proxyreq);
+    else if (apr_table_get(r->notes, "proxy-noencode")) {
+        path = url;   /* this is the encoded path already */
         search = r->args;
-        if (search && *(ap_scan_vchar_obstext(search))) {
-            /*
-             * We have a raw control character or a ' ' in r->args.
-             * Correct encoding was missed.
-             */
-            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409)
-                          "To be forwarded query string contains control "
-                          "characters or spaces");
-            return HTTP_FORBIDDEN;
+    }
+    else {
+        core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
+        int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
+
+        path = ap_proxy_canonenc_ex(r->pool, url, strlen(url), enc_path, flags,
+                                    r->proxyreq);
+        if (!path) {
+            return HTTP_BAD_REQUEST;
         }
+        search = r->args;
+    }
+    /*
+     * If we have a raw control character or a ' ' in nocanon path or
+     * r->args, correct encoding was missed.
+     */
+    if (path == url && *ap_scan_vchar_obstext(path)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10419)
+                      "To be forwarded path contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
+    }
+    if (search && *ap_scan_vchar_obstext(search)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409)
+                      "To be forwarded query string contains control "
+                      "characters or spaces");
+        return HTTP_FORBIDDEN;
     }
-    if (path == NULL)
-        return HTTP_BAD_REQUEST;
 
     if (port != def_port)
         apr_snprintf(sport, sizeof(sport), ":%d", port);
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 8267f1b9..caafde0b 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -200,14 +200,16 @@ PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x)
  * and encodes those which must be encoded, and does not touch
  * those which must not be touched.
  */
-PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
-                                       enum enctype t, int forcedec,
-                                       int proxyreq)
+PROXY_DECLARE(char *)ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len,
+                                          enum enctype t, int flags,
+                                          int proxyreq)
 {
     int i, j, ch;
     char *y;
     char *allowed;  /* characters which should not be encoded */
     char *reserved; /* characters which much not be en/de-coded */
+    int forcedec = flags & PROXY_CANONENC_FORCEDEC;
+    int noencslashesenc = flags & PROXY_CANONENC_NOENCODEDSLASHENCODING;
 
 /*
  * N.B. in addition to :@&=, this allows ';' in an http path
@@ -256,17 +258,29 @@ PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
  * decode it if not already done. do not decode reverse proxied URLs
  * unless specifically forced
  */
-        if ((forcedec || (proxyreq && proxyreq != PROXYREQ_REVERSE)) && ch == '%') {
+        if ((forcedec || noencslashesenc
+            || (proxyreq && proxyreq != PROXYREQ_REVERSE)) && ch == '%') {
             if (!apr_isxdigit(x[i + 1]) || !apr_isxdigit(x[i + 2])) {
                 return NULL;
             }
             ch = ap_proxy_hex2c(&x[i + 1]);
-            i += 2;
             if (ch != 0 && strchr(reserved, ch)) {  /* keep it encoded */
-                ap_proxy_c2hex(ch, &y[j]);
-                j += 2;
+                y[j++] = x[i++];
+                y[j++] = x[i++];
+                y[j] = x[i];
                 continue;
             }
+            if (noencslashesenc && !forcedec && (proxyreq == PROXYREQ_REVERSE)) {
+                /*
+                 * In the reverse proxy case when we only want to keep encoded
+                 * slashes untouched revert back to '%' which will cause
+                 * '%' to be encoded in the following.
+                 */
+                ch = '%';
+            }
+            else {
+                i += 2;
+            }
         }
 /* recode it, if necessary */
         if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
@@ -281,6 +295,22 @@ PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
     return y;
 }
 
+/*
+ * Convert a URL-encoded string to canonical form.
+ * It decodes characters which need not be encoded,
+ * and encodes those which must be encoded, and does not touch
+ * those which must not be touched.
+ */
+PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len,
+                                       enum enctype t, int forcedec,
+                                       int proxyreq)
+{
+    int flags;
+
+    flags = forcedec ? PROXY_CANONENC_FORCEDEC : 0;
+    return ap_proxy_canonenc_ex(p, x, len, t, flags, proxyreq);
+}
+
 /*
  * Parses network-location.
  *    urlp           on input the URL; on output the path, after the leading /
diff --git a/test/README.pytest b/test/README.pytest
index 5949e12b..474030bd 100644
--- a/test/README.pytest
+++ b/test/README.pytest
@@ -72,7 +72,7 @@ Development
 -----------
 
 Adding a test in an existing file is done by adding a method. Its name
-must start with 'test_' and the common practise is to have the name
+must start with 'test_' and the common practice is to have the name
 of the test suite there as well. All http2 tests start with 'test_h2_'.
 
 Following this can be any characters. If you make test cases of a
diff --git a/test/modules/http2/test_004_post.py b/test/modules/http2/test_004_post.py
index 97f05e25..44f31d2c 100644
--- a/test/modules/http2/test_004_post.py
+++ b/test/modules/http2/test_004_post.py
@@ -5,6 +5,7 @@ import json
 import os
 import re
 import sys
+import time
 
 import pytest
 
@@ -173,6 +174,8 @@ CustomLog logs/test_004_30 issue_203
         r = env.curl_get(url, 5, options=["--http2", "-H", "Range: bytes=0-{0}".format(chunk-1)])
         assert 206 == r.response["status"]
         assert chunk == len(r.response["body"].decode('utf-8'))
+        # Wait for log completeness
+        time.sleep(1)
         # now check what response lengths have actually been reported
         lines = open(logfile).readlines()
         log_h2_full = json.loads(lines[-3])
diff --git a/test/modules/http2/test_600_h2proxy.py b/test/modules/http2/test_600_h2proxy.py
index 9591ce57..e93ba1ae 100644
--- a/test/modules/http2/test_600_h2proxy.py
+++ b/test/modules/http2/test_600_h2proxy.py
@@ -78,24 +78,30 @@ class TestH2Proxy:
         conf.install()
         assert env.apache_restart() == 0
         url = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port}/hello.py")
-        r = env.curl_get(url, 5)
-        assert r.response["status"] == 200
-        assert r.json["h2_stream_id"] == "1"
         if enable_reuse == "on":
-            # reuse is not guarantueed for each request, but we expect some
+            # reuse is not guaranteed for each request, but we expect some
             # to do it and run on a h2 stream id > 1
             reused = False
-            for _ in range(10):
-                r = env.curl_get(url, 5)
-                assert r.response["status"] == 200
-                if int(r.json["h2_stream_id"]) > 1:
+            count = 10
+            r = env.curl_raw([url] * count, 5)
+            response = r.response
+            for n in range(count):
+                assert response["status"] == 200
+                if n == (count - 1):
+                    break
+                response = response["previous"]
+            assert r.json[0]["h2_stream_id"] == "1"
+            for n in range(1, count):
+                if int(r.json[n]["h2_stream_id"]) > 1:
                     reused = True
                     break
             assert reused
         else:
-            r = env.curl_get(url, 5)
+            r = env.curl_raw([url, url], 5)
+            assert r.response["previous"]["status"] == 200
             assert r.response["status"] == 200
-            assert r.json["h2_stream_id"] == "1"
+            assert r.json[0]["h2_stream_id"] == "1"
+            assert r.json[1]["h2_stream_id"] == "1"
 
     # do some flexible setup from #235 to proper connection selection
     @pytest.mark.parametrize("enable_reuse", [ "on", "off" ])
@@ -119,16 +125,13 @@ class TestH2Proxy:
         conf.install()
         assert env.apache_restart() == 0
         url = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port}/hello.py")
-        r = env.curl_get(url, 5)
-        assert r.response["status"] == 200
-        assert int(r.json["port"]) == env.http_port
-        # going to another backend port must create a new connection and
-        # we should see stream id one again
-        url = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port2}/hello.py")
-        r = env.curl_get(url, 5)
+        url2 = env.mkurl("https", "cgi", f"/h2proxy/{env.http_port2}/hello.py")
+        r = env.curl_raw([url, url2], 5)
+        assert r.response["previous"]["status"] == 200
+        assert int(r.json[0]["port"]) == env.http_port
         assert r.response["status"] == 200
         exp_port = env.http_port if enable_reuse == "on" else env.http_port2
-        assert int(r.json["port"]) == exp_port
+        assert int(r.json[1]["port"]) == exp_port
 
     # lets do some error tests
     def test_h2_600_30(self, env):
diff --git a/test/pyhttpd/curl.py b/test/pyhttpd/curl.py
index 338e82ce..2b6840b1 100644
--- a/test/pyhttpd/curl.py
+++ b/test/pyhttpd/curl.py
@@ -32,7 +32,7 @@ class CurlPiper:
         return self._r.response if self._r else None
 
     def start(self):
-        self.args, self.headerfile = self.env.curl_complete_args(self.url, timeout=5, options=[
+        self.args, self.headerfile = self.env.curl_complete_args([self.url], timeout=5, options=[
             "-T", "-", "-X", "POST", "--trace-ascii", "%", "--trace-time"])
         sys.stderr.write("starting: {0}\n".format(self.args))
         self.proc = subprocess.Popen(self.args, stdin=subprocess.PIPE,
diff --git a/test/pyhttpd/env.py b/test/pyhttpd/env.py
index af856eff..2c918593 100644
--- a/test/pyhttpd/env.py
+++ b/test/pyhttpd/env.py
@@ -65,6 +65,8 @@ class HttpdTestSetup:
         "proxy_http",
     ]
 
+    CURL_STDOUT_SEPARATOR = "===CURL_STDOUT_SEPARATOR==="
+
     def __init__(self, env: 'HttpdTestEnv'):
         self.env = env
         self._source_dirs = [os.path.dirname(inspect.getfile(HttpdTestSetup))]
@@ -497,14 +499,26 @@ class HttpdTestEnv:
         if not os.path.exists(path):
             return os.makedirs(path)
 
-    def run(self, args, intext=None, debug_log=True):
+    def run(self, args, stdout_list=False, intext=None, debug_log=True):
         if debug_log:
             log.debug(f"run: {args}")
         start = datetime.now()
         p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
                            input=intext.encode() if intext else None)
+        stdout_as_list = None
+        if stdout_list:
+            try:
+                out = p.stdout.decode()
+                if HttpdTestSetup.CURL_STDOUT_SEPARATOR in out:
+                    stdout_as_list = out.split(HttpdTestSetup.CURL_STDOUT_SEPARATOR)
+                    if not stdout_as_list[len(stdout_as_list) - 1]:
+                        stdout_as_list.pop()
+                p.stdout.replace(HttpdTestSetup.CURL_STDOUT_SEPARATOR.encode(), b'')
+            except:
+                pass
         return ExecResult(args=args, exit_code=p.returncode,
                           stdout=p.stdout, stderr=p.stderr,
+                          stdout_as_list=stdout_as_list,
                           duration=datetime.now() - start)
 
     def mkurl(self, scheme, hostname, path='/'):
@@ -637,10 +651,9 @@ class HttpdTestEnv:
                 os.remove(os.path.join(self.gen_dir, fname))
         self._curl_headerfiles_n = 0
 
-    def curl_complete_args(self, urls, timeout=None, options=None,
+    def curl_complete_args(self, urls, stdout_list=False,
+                           timeout=None, options=None,
                            insecure=False, force_resolve=True):
-        if not isinstance(urls, list):
-            urls = [urls]
         u = urlparse(urls[0])
         #assert u.hostname, f"hostname not in url: {urls[0]}"
         headerfile = f"{self.gen_dir}/curl.headers.{self._curl_headerfiles_n}"
@@ -649,6 +662,8 @@ class HttpdTestEnv:
         args = [
             self._curl, "-s", "--path-as-is", "-D", headerfile,
         ]
+        if stdout_list:
+            args.extend(['-w', '%{stdout}' + HttpdTestSetup.CURL_STDOUT_SEPARATOR])
         if u.scheme == 'http':
             pass
         elif insecure:
@@ -731,10 +746,16 @@ class HttpdTestEnv:
 
     def curl_raw(self, urls, timeout=10, options=None, insecure=False,
                  force_resolve=True):
+        if not isinstance(urls, list):
+            urls = [urls]
+        stdout_list = False
+        if len(urls) > 1:
+            stdout_list = True
         args, headerfile = self.curl_complete_args(
-            urls=urls, timeout=timeout, options=options, insecure=insecure,
+            urls=urls, stdout_list=stdout_list,
+            timeout=timeout, options=options, insecure=insecure,
             force_resolve=force_resolve)
-        r = self.run(args)
+        r = self.run(args, stdout_list=stdout_list)
         if r.exit_code == 0:
             self.curl_parse_headerfile(headerfile, r=r)
             if r.json:
diff --git a/test/pyhttpd/nghttp.py b/test/pyhttpd/nghttp.py
index fe4a1aed..f27e40d3 100644
--- a/test/pyhttpd/nghttp.py
+++ b/test/pyhttpd/nghttp.py
@@ -251,7 +251,9 @@ class Nghttp:
             f.write("--DSAJKcd9876\n")
         if not options:
             options = []
-        options.extend(["--data=%s" % reqbody])
+        options.extend([ 
+            "--data=%s" % reqbody, 
+            "-HContent-Type: multipart/form-data; boundary=DSAJKcd9876"])
         return self._raw(url, timeout, options)
 
     def upload(self, url, fpath, timeout=5, options=None):
diff --git a/test/pyhttpd/result.py b/test/pyhttpd/result.py
index 04ea825a..3789461b 100644
--- a/test/pyhttpd/result.py
+++ b/test/pyhttpd/result.py
@@ -6,7 +6,9 @@ from typing import Optional, Dict, List
 class ExecResult:
 
     def __init__(self, args: List[str], exit_code: int,
-                 stdout: bytes, stderr: bytes = None, duration: timedelta = None):
+                 stdout: bytes, stderr: bytes = None,
+                 stdout_as_list: List[bytes] = None,
+                 duration: timedelta = None):
         self._args = args
         self._exit_code = exit_code
         self._stdout = stdout if stdout is not None else b''
@@ -17,7 +19,10 @@ class ExecResult:
         self._assets = []
         # noinspection PyBroadException
         try:
-            out = self._stdout.decode()
+            if stdout_as_list is None:
+                out = self._stdout.decode()
+            else:
+                out = "[" + ','.join(stdout_as_list) + "]"
             self._json_out = json.loads(out)
         except:
             self._json_out = None
diff --git a/test/travis_run_linux.sh b/test/travis_run_linux.sh
index 58370700..f7a72d29 100755
--- a/test/travis_run_linux.sh
+++ b/test/travis_run_linux.sh
@@ -122,8 +122,23 @@ if ! test -v SKIP_TESTING; then
         test -v TEST_INSTALL || make install
         pushd test/perl-framework
             perl Makefile.PL -apxs $PREFIX/bin/apxs
-            make test APACHE_TEST_EXTRA_ARGS="${TEST_ARGS} ${TESTS}"
-            RV=$?
+            make test APACHE_TEST_EXTRA_ARGS="${TEST_ARGS} ${TESTS}" | tee test.log
+            RV=${PIPESTATUS[0]}
+            # re-run failing tests with -v, avoiding set -e
+            if [ $RV -ne 0 ]; then
+                #mv t/logs/error_log t/logs/error_log_save
+                FAILERS=""
+                while read FAILER; do
+                    FAILERS="$FAILERS $FAILER"
+                done < <(awk '/Failed:/{print $1}' test.log)
+                if [ -n "$FAILERS" ]; then
+                    t/TEST -v $FAILERS || true
+                fi
+                # set -e would have killed us after the original t/TEST
+                rm -f test.log
+                #mv t/logs/error_log_save t/logs/error_log
+                false
+            fi
         popd
     fi
 

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: