Apache RewriteRule丢弃SetInputFilter DEFLATE配置指令

问题描述 投票:2回答:1

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

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

以及apache配置中的以下指令:

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

我发送一个带有gzipped正文的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脚本不会让身体解压缩。

我认为它必须与忽略RewriteRule指令的SetInputFilter指令相关,但是,我该如何避免这种情况呢?

我试图直接在.htaccess中添加SetInputFilter指令而不解决问题(可能它不在正确的位置?)。

你知道我怎么解决这个问题?

php apache .htaccess mod-rewrite mod-deflate
1个回答
2
投票

的确,存在一个问题。我做更深入调查的第一件事是记录有关模块的痕迹(rewritefilterdeflate)。

mod_rewrite日志没关系,没有什么可疑的。为了确保一切都很好,我看了它的source code的最后一个版本。再一次,没有任何关于编码/解码的可疑信息(也不是一般的http请求/响应标头)。

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

mod_rewrite not involved

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 involved

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

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

Solution

到现在为止还挺好。所以呢 ?好吧,快速搜索Apache的已知错误列表,关键字qazxsw poi,给了我机会qazxsw poi。这张名为mod_deflate too late的票据说明如下:

当mod_deflate用于膨胀时,它必须调整请求标头(例如,它需要删除“Content-Length”标头并调整“Content-Encoding”标头)。

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

mod_deflate应该在早期阶段调整标题,例如在fixup hook(ap_hook_fixups)中。

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

你有选择:

  1. 应用此修补程序并重新编译服务器。它应该工作,因为所有的事情都有意义。但是,要小心......这可能会引入其他错误/漏洞(有时甚至在审核/接受时都会出现这种情况)
  2. 等待它包含在可用版本中(考虑到票证日期,可能需要很长时间)。到那时,使用你的自定义deflate与PHP。

Update

只是尝试应用补丁并重新编译what I was searching for。看起来它在正确的轨道上:它吃mod_deflate adjusts the headers "too late"标题。无论如何,mod_deflate仍在那里。结果:尚未解压缩。所以,仍然有一些事情要做并适应,但问题肯定在那个领域。

Update 2 (working)

我终于成功了。这是我应用于Apache(Content-Encoding)的补丁:

Content-Length

实际上,我也让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) {

© www.soinside.com 2019 - 2024. All rights reserved.