gpt4 book ai didi

php - gzcompress()随机插入额外的数据?

转载 作者:可可西里 更新时间:2023-10-31 23:50:05 24 4
gpt4 key购买 nike

我整个上午都在研究这个问题,并决定作为最后的努力,也许有人在堆栈溢出有一个“在那里,做了那种”类型的答案为我。
背景最近,我使用过滤器在我们的(面向内部网的)apache(2.2)服务器上实现了压缩,这样所有基于文本的文件(css、js、txt、html等)都通过mod_deflate进行压缩,而没有提到php脚本。在对如何最好地压缩php输出进行了大量研究之后,我决定使用gzcompress()风格,因为php文档表明,使用zlib库和gzip(使用deflate算法,blah blah blah)比ob_gzippanything()更受欢迎。
所以我模仿了别人的方法:

<?php # start each page by enabling output buffering and disabling automatic flushes
ob_start();ob_implicit_flush(0);

(program logic)

print_gzipped_page();

function print_gzipped_page() {
if (headers_sent())
$encoding = false;
elseif(strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'x-gzip') !== false )
$encoding = 'x-gzip';
elseif(strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false )
$encoding = 'gzip';
else
$encoding = false;

if($encoding){
$contents = ob_get_contents(); # get contents of buffer
ob_end_clean(); # turn off OB and flush buffer
$size = strlen($contents);
if ($size < 512) { # too small to be worth a compression
echo $contents;
exit();
} else {
header("Content-Encoding: $encoding");
header('Vary: Accept-Encoding');
# 8-byte file header: g-zip file (1f 8b) compression type deflate (08), next 5 bytes are padding
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0,$size); # faster than not using a substr, oddly
echo $contents;
exit();
}
} else {
ob_end_flush();
exit();
}
}

很标准的东西,对吧?
在我们通过firefox发送的所有php页面请求中,有10%到33%的问题可以正常处理并返回g-zipped,只有firefox显示压缩的ascii而不是解压缩。而且,最奇怪的是,返回的内容大小总是比正确呈现的页面大小大30或31个字节。如中所述,当脚本正确显示时,firebug显示的内容大小为1044;当firefox显示一个巨大的二进制乱码屏幕时,firebug显示的内容大小为1074。
在运行Firefox3.3s的32位Fedora12s上,我们的一些用户也遇到了这种情况…然后发生在一个使用ff5的用户身上,一个使用ff6,还有一些使用新的7.1!无论如何,我一直想将它们全部升级到ff7.1,所以我一直在更新它们,因为它们有问题,但是ff7.1仍然表现出相同的行为,只是频率较低。
诊断我一直在各种计算机上安装firebug来监视头部,这就是我感到困惑的地方:
正常工作的页面响应标题:
http/1.1 200可以
日期:2011年10月21日星期五格林尼治时间18:40:15
服务器:apache/2.2.15(Fedora)
x-powered-by:php/5.3.2
有效期至:1981年11月19日星期四08:52:00 GMT
缓存控制:无存储,无缓存,必须重新验证,后检查=0,前检查=0
pragma:没有缓存
内容编码:gzip
变化:接受编码
内容长度:1045
保持活动:超时=10,最大=75
连接:保持活动
内容类型:text/html;charset=utf-8
(请注意,内容长度是自动生成的)
断开时为同一页:
http/1.1 200可以
(其他都一样)
内容长度:1075
发送的头始终包括接受编码:gzip,deflate
我试图纠正这种行为的事情:
用未压缩和压缩的长度显式声明内容长度
不使用$contents的substr()
删除$contents结尾的校验和
我真的不想使用gzencode,因为我的测试显示它比gzcompress慢得多(9%),可能是因为它生成了额外的校验和,以及我(假设)web浏览器不需要或使用的东西。
我不能在运行Firefox7.1的64位Fedora14框上复制该行为。在实时滚动压缩代码之前的测试中,我从未遇到过这种情况,无论是在chrome还是firefox中。(编辑:发布后,我打开的每30秒发送一次元刷新的一个窗口在Firefox中刷新了大约60次后终于坏了)我们的几个WindowsXP框的行为与Fedora12s相同。这种情况下,但对于3.3之前的版本,所有的gzipped内容都是这样,而我们的apachegzipped css和js文件每次下载和显示都没有错误。
每次返回的内容长度都会变大30/31字节,这一事实让我认为script/gzcompress()中有什么东西在破坏firefox阻塞的响应。很自然,如果你修改echo'd gzip头,firefox就会抛出一个“内容编码错误”,所以我真的倾向于gzcompress()内部的问题。
我注定了吗?我必须放弃这个实现并使用非首选的ob_start(“ob_gzhandler”)方法吗?
我想我的“适用于多种情况”的问题是:在php中的zlib压缩库中是否存在已知的错误,在接收非常特定的输入时会产生一些奇怪的效果?
编辑:坚果。我读了一个firefox下载的未压缩的页面,你瞧!,它完美地回响了一切。=(这意味着这必须是……不,我什么都没有。

最佳答案

好的,首先,您似乎没有设置内容长度头,这将导致问题,相反,您正在使gzip内容更长,以便它与您第一次接收到的内容长度大小相匹配。这会变丑的。我的建议是你把台词换掉

# 8-byte file header: g-zip file (1f 8b) compression type deflate (08), next 5 bytes are padding
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$contents = gzcompress($contents, 9);
$contents = substr($contents, 0,$size); # faster than not using a substr, oddly
echo $contents;

具有
$compressed = gzcompress($contents, 9);
$compressed_length = strlen($compressed); /* contains no nulls i believe */
header("Content-length: $compressed_length");
echo "\x1f\x8b\x08\x00\x00\x00\x00\x00", $compressed;

看看这是否有帮助。

关于php - gzcompress()随机插入额外的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7854127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com