Apache RewriteRule 丢弃 SetInputFilter DEFLATE 配置指令
Apache RewriteRule discards SetInputFilter DEFLATE config directive
我有以下(简化的)folder/file结构:
/.htaccess
/test.php
/api/web/index.php
以及 apache 配置中的以下指令:
<IfModule mod_deflate.c>
<IfModule mod_filter.c>
SetInputFilter DEFLATE
</IfModule>
</IfModule>
我正在发送一个 POST 请求,其中包含 gzipped body 和适当的 headers:
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/ [NC,L]
问题是,如果我 post 到 /test.php
,一切都按预期工作,body 已放气,我可以正确访问解压缩的内容。
然而,如果我 post 到被重定向的东西(/api/
或 /api/v1/project
),index.php
脚本不会得到 body 解压。
我想一定是和RewriteRule
指令忽略了SetInputFilter
指令有关,但是,如何避免这种情况呢?
我试图直接在 .htaccess 中添加 SetInputFilter
指令,但没有解决问题(可能是位置不对?)。
你知道我该如何解决这个问题吗?
确实有问题。为了深入调查,我做的第一件事是记录相关模块的踪迹(rewrite
、filter
和 deflate
)。
mod_rewrite 日志 没问题,没有什么可疑之处。为了确保一切正常,我查看了其 source code 的最新版本。再说一次,关于 encoding/decoding(更普遍的是 http request/response headers)没有任何可疑之处。
所以我开始认为问题可能来自 filter
或 deflate
模块,即使它也可能来自其他地方。为了 confirm/infirm 我的想法,我查看了那些模块日志。很快,我能够看到两个测试用例之间的区别:有或没有 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. This ticket called mod_deflate adjusts the headers "too late",说明如下:
When mod_deflate is used to inflate, it must adjust the request
headers (e.g. it needs to remove the "Content-Length" header and
adjust the "Content-Encoding" header).
Currently mod_deflate adjusts the headers when the request body is
read. But this is too late. For example, if a content generator module
needs to look at the request headers before reading the request body,
the content generator module "sees" the old (unmodified) headers.
mod_deflate should adjust the headers in an early stage, for example
in a fixup hook (ap_hook_fixups).
尤里卡!这正是我们面临的问题。现在,好消息是有一个补丁可以解决这个问题。坏消息:它还没有 reviewed/accepted/merged 可用版本。
你有选择:
- 应用此补丁并重新编译您的服务器。它应该起作用,因为所有事情都是有道理的。 但是,要小心...这可能会引入其他 bugs/holes(有时是这种情况,即使 reviewed/accepted)
- 等待它包含在可用版本中(考虑到票据日期,可能需要很长时间)。到那时,使用您的自定义放气 php.
更新
刚刚尝试应用补丁并重新编译 mod_deflate
。看起来它是在正确的轨道上:它吃 Content-Encoding
header。反正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
句柄 sub-requests。我不确定它是否会破坏其他一些模块,但它适用于您的用例(它更像是一个概念证明)。不管怎样,我在上面提到的票上提出了我的补丁。这是结果的屏幕截图:
我有以下(简化的)folder/file结构:
/.htaccess
/test.php
/api/web/index.php
以及 apache 配置中的以下指令:
<IfModule mod_deflate.c>
<IfModule mod_filter.c>
SetInputFilter DEFLATE
</IfModule>
</IfModule>
我正在发送一个 POST 请求,其中包含 gzipped body 和适当的 headers:
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/ [NC,L]
问题是,如果我 post 到 /test.php
,一切都按预期工作,body 已放气,我可以正确访问解压缩的内容。
然而,如果我 post 到被重定向的东西(/api/
或 /api/v1/project
),index.php
脚本不会得到 body 解压。
我想一定是和RewriteRule
指令忽略了SetInputFilter
指令有关,但是,如何避免这种情况呢?
我试图直接在 .htaccess 中添加 SetInputFilter
指令,但没有解决问题(可能是位置不对?)。
你知道我该如何解决这个问题吗?
确实有问题。为了深入调查,我做的第一件事是记录相关模块的踪迹(rewrite
、filter
和 deflate
)。
mod_rewrite 日志 没问题,没有什么可疑之处。为了确保一切正常,我查看了其 source code 的最新版本。再说一次,关于 encoding/decoding(更普遍的是 http request/response headers)没有任何可疑之处。
所以我开始认为问题可能来自 filter
或 deflate
模块,即使它也可能来自其他地方。为了 confirm/infirm 我的想法,我查看了那些模块日志。很快,我能够看到两个测试用例之间的区别:有或没有 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. This ticket called mod_deflate adjusts the headers "too late",说明如下:
When mod_deflate is used to inflate, it must adjust the request headers (e.g. it needs to remove the "Content-Length" header and adjust the "Content-Encoding" header).
Currently mod_deflate adjusts the headers when the request body is read. But this is too late. For example, if a content generator module needs to look at the request headers before reading the request body, the content generator module "sees" the old (unmodified) headers.
mod_deflate should adjust the headers in an early stage, for example in a fixup hook (ap_hook_fixups).
尤里卡!这正是我们面临的问题。现在,好消息是有一个补丁可以解决这个问题。坏消息:它还没有 reviewed/accepted/merged 可用版本。
你有选择:
- 应用此补丁并重新编译您的服务器。它应该起作用,因为所有事情都是有道理的。 但是,要小心...这可能会引入其他 bugs/holes(有时是这种情况,即使 reviewed/accepted)
- 等待它包含在可用版本中(考虑到票据日期,可能需要很长时间)。到那时,使用您的自定义放气 php.
更新
刚刚尝试应用补丁并重新编译 mod_deflate
。看起来它是在正确的轨道上:它吃 Content-Encoding
header。反正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
句柄 sub-requests。我不确定它是否会破坏其他一些模块,但它适用于您的用例(它更像是一个概念证明)。不管怎样,我在上面提到的票上提出了我的补丁。这是结果的屏幕截图: