Apache RewriteRule丢弃SetInputFilter DEFLATE配置指令 - php

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

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

以及apache config中的以下指令:

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

我正在发送带有适当标题的带有gzip压缩正文的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指令,而没有解决问题(可能是在不正确的位置?)。

你知道我该怎么解决吗?

参考方案

确实存在问题。我要做的更深入研究的第一件事是记录有关模块(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进行充气时,它必须调整请求
标头(例如,它需要删除“ Content-Length”标头和
调整“ Content-Encoding”标题)。

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

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

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

您可以选择:

应用此修补程序并重新编译服务器。它应该起作用,因为一切都有意义。但是,请小心...这可能会引入其他错误/漏洞(即使经过审核/接受,有时也是如此)
等待它包含在可用版本中(考虑到票证日期,可能需要很长时间)。届时,将自定义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 RewriteRule丢弃SetInputFilter DEFLATE配置指令 - php

PHP getallheaders替代 - php

我正在尝试从服务器上的apache切换到nginx。唯一的问题是我在PHP脚本中使用的getallheaders()函数,该函数不适用于Nginx。我已经尝试过用户在getallheaders函数上的php站点上提供的注释,但这并不返回所有请求标头。请告诉我如何解决这个问题。我真的想切换到Nginx。 参考方案 您仍然可以使用它,但是您必须像这里一样重新定义…

如何使用PHP和Apache在请求中查找HTTP版本 - php

我需要确定在我的PHP脚本中运行的HTTP请求是HTTP / 1.0还是HTTP / 1.1请求,该脚本在Apache下运行。有没有办法查询此信息? 参考方案 $_SERVER['SERVER_PROTOCOL'],位于$_SERVERDocs: 'SERVER_PROTOCOL' 请求页面的信息协议的名称和修订版;即…

Apache + PHP同时使用多个脚本 - php

美好的一天。首先,对不起我的英语不好=)所以。我创建了脚本:<? sleep(10); ?> 我的Apache有MPM模块,很明显我没有在此脚本中使用会话,只是..只是sleep(10)。当我在浏览器中同时打开2个标签时,第一个标签会在10秒内加载,第二个标签会在20秒内加载。但。当我同时在2个不同的浏览器中打开此脚本时,它将在10秒后加载到每个…

Easy PHP的Apache意外结束 - php

我的EasyPHP服务器突然停止工作,这已经发生过,我将端口更改为8080,但是现在它不再起作用。我使用netstat检查了使用端口的进程,但是没有使用该端口的应用程序。以下是日志中写的内容:18/08 15:43:25 EasyPHP Apache CreateProcess "C:\PROGRA~2\EasyPHP\binaries\apach…

PHP-将日期插入日期时间字段 - php

我已在数据库中使用datetime字段存储日期,使用PHP将“今天的日期”插入该字段的正确方法是什么?干杯, 参考方案 我认为您可以使用php date()函数