【问题标题】:Apache RewriteRule discards SetInputFilter DEFLATE config directiveApache RewriteRule 丢弃 SetInputFilter DEFLATE 配置指令
【发布时间】:2017-12-10 14:56:32
【问题描述】:

我有以下(简化的)文件夹/文件结构:

/.htaccess
/test.php
/api/web/index.php

以及 apache config 中的以下指令:

<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        SetInputFilter DEFLATE
   </IfModule>
</IfModule>

我正在发送一个 POST 请求,其中包含一个带有适当标头的压缩正文:

POST /test.php HTTP/1.1
Host: 192.168.1.248
Authorization: Bearer ed717c077e4bf81201196011adb457731b24e19d
Content-Type: application/json
Content-Encoding: gzip

我对 .htaccess 文件有以下配置:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^api/(.*) api/web/index.php/$1 [NC,L]

问题是,如果我向/test.php 发帖,一切都会按预期进行,正文已泄气,我可以正确访问解压缩的内容。

但是,如果我发布到被重定向的内容(/api//api/v1/project),index.php 脚本不会解压缩正文。

我认为它必须与忽略SetInputFilter 指令的RewriteRule 指令有关,但是,我怎样才能避免这种情况呢?

我尝试直接在 .htaccess 中添加 SetInputFilter 指令,但没有解决问题(可能是位置不对?)。

你知道我该如何解决这个问题吗?

【问题讨论】:

  • 您是否检查过以确保您在虚拟主机配置中设置了AllowOverride All
  • @HalfCrazed AllowOverride All 处于活动状态。而且我认为它工作正常,因为我在 .htaccess 中定义的重定向正在工作,但忽略了它在 apache.conf 文件中的 SetInputFilter 指令。
  • 我也遇到了这个问题。请问有没有人提出解决方案?
  • @FrederickZhang 我在 Apache 邮件列表 (mail-archives.apache.org/mod_mbox/httpd-users/201707.mbox/…) 和论坛 (apachelounge.com/viewtopic.php?t=7686) 上发布了这个问题,但没有成功。我选择自己给身体放气,但我仍然相信 Apache 的解决方案会在未来某个时候出现:)
  • /api/web/ 是什么?一个已知的 CMS 还是你自己的东西?事实上,POST 数据在重写时与请求一起传递,我猜对于解压缩的内容应该是相同的。另外,你检查你的服务器日志了吗?你可能会在那里发现一些有趣的东西

标签: php apache .htaccess mod-rewrite mod-deflate


【解决方案1】:

确实有问题。我做深入调查的第一件事是记录相关模块的痕迹(rewritefilterdeflate)。

mod_rewrite 日志 没问题,没有任何可疑之处。为了确保一切正常,我查看了其source code 的最新版本。再一次,没有关于编码/解码的可疑之处(更一般地说,也没有 http 请求/响应标头)。

所以我开始认为问题可能来自filterdeflate 模块,即使它也可能来自其他地方。为了确认/确认我的想法,我查看了这些模块日志。很快,我就看到了两个测试用例之间的区别:有无 mod_rewrite 参与。

不涉及mod_rewrite

mod_deflate.c(1421): [client 127.0.0.1:53000] AH01393: Zlib: Inflated 35 to 41 : URL /test.php
mod_filter.c(188): [client 127.0.0.1:53000] Content-Type condition for 'deflate' matched

我把这个作为参考来比较下面的下一个案例

涉及mod_rewrite

mod_filter.c(188): [client 127.0.0.1:53002] Content-Type condition for 'deflate' matched

有趣。实际上,看起来mod_deflate 是问题所在。我怀疑它的行动是正确的时刻之后。这就是为什么在这种情况下您看不到它的实际效果。

解决方案

到目前为止,一切都很好。所以呢 ?好吧,用关键字mod_deflate too late 快速搜索Apache 的已知错误列表,我偶然发现了what I was searching for。这张票名为mod_deflate adjusts the headers "too late",声明如下:

当mod_deflate用于inflate时,必须调整request 标头(例如,它需要删除“Content-Length”标头和 调整“Content-Encoding”标头)。

目前 mod_deflate 会在请求正文为 读。但这为时已晚。例如,如果一个内容生成器模块 在读取请求正文之前需要查看请求标头, 内容生成器模块“看到”旧的(未修改的)标题。

mod_deflate 应该在早期阶段调整标题,例如 在修复挂钩 (ap_hook_fixups) 中。

尤里卡!这正是我们面临的问题。现在,好消息是有一个补丁可以解决这个问题。坏消息:它尚未在可用版本中进行审查/接受/合并。

您可以选择

  1. 应用此补丁并重新编译您的服务器。它应该起作用,因为一切都是有意义的。 但是,要小心...这可能会引入其他错误/漏洞(有时会出现这种情况,即使经过审核/接受也是如此)
  2. 等待它包含在可用版本中(可能需要很长时间,考虑到票日期)。届时,请使用您的自定义 deflate 和 php。

更新

刚刚尝试应用补丁并重新编译mod_deflate。看起来它在正确的轨道上:它吃Content-Encoding 标题。不管怎样,Content-Length 还在。结果:还没有解压。所以,还有一些事情要做和适应,但问题肯定出在那个领域。

更新 2(工作)

我终于成功了。这是我应用于 Apache (httpd version 2.4.34) 的补丁:

diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c
index 1428460..cc8c0cb 100644
--- a/modules/filters/mod_deflate.c
+++ b/modules/filters/mod_deflate.c
@@ -1099,10 +1099,10 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,

         if (!ctx) {
             /* only work on main request/no subrequests */
-            if (!ap_is_initial_req(r)) {
+            /*if (!ap_is_initial_req(r)) {
                 ap_remove_input_filter(f);
                 return ap_get_brigade(f->next, bb, mode, block, readbytes);
-            }
+            }*/

             /* We can't operate on Content-Ranges */
             if (apr_table_get(r->headers_in, "Content-Range") != NULL) {

实际上,我也让mod_deflate 处理子请求。我不确定它不会破坏其他一些模块,但它适用于您的用例(它更像是一个概念证明)。无论如何,我在上面提到的票上提出了我的补丁。这是结果的截图:

【讨论】:

  • 哇,很好的答案!遗憾的是,这样一个古老的问题在 Apache 中没有得到解决。我猜mod_deflate 主要是为 WebDAV 设计的,并没有在不同的场景中得到彻底的测试,因为很少有客户端真正支持请求有效负载压缩。我认为至少现在直接在像 OP 这样的代码中解决这个问题对我来说更好。
  • 是的,很伤心。欢迎来到开源世界!但它也有很多优点,所以让我们高兴吧。对于您的解决方案,实际上等待 apache 版本的正式更改更为谨慎。我通过提交补丁重新启动了线程(票证),让我们看看是否有什么变化。我希望它会很快恢复活力。
  • @JustinIurman 哇,干得好,你简直一针见血。
  • 谢谢大家,很高兴我为你们两位带来了关于这个非常古老的问题的解释。未回答的问题和未解决的问题很痛苦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 2020-10-07
  • 2013-07-18
  • 2015-03-10
相关资源
最近更新 更多