我不久前写了一个小的WebSocket库,发现添加gzip支持非常简单。我当时并没有完全意识到
componentWillMount()
/ deflate_init()
/ deflate_add()
/ inflate_init()
函数实际上只是PHP 7,而现在我只是#7;我希望能够在PHP 5环境下运行我的WebSocket服务器。
我的问题是,inflate_add()
产生的输出与deflate_add()
略有不同 - 在下面的测试用例中只有一个字符。
基于gzdeflate()
/ deflate_add()
的方法在浏览器中完美运行,因此inflate_add()
的输出不正确。我猜gzdeflate()
/ gzdeflate()
正在使用zlib和不同的底层选项 - 可能与流状态有关吗? - 这导致一切都崩溃了。
最终我想知道我是否可以说服PHP 5-era zlib函数输出"更正"泄密的数据。
首先,我在PHP 7上使用基于gzinflate()
/ deflate_init()
的方法:
deflate_add()
如果我使用$data = "ABC";
$ctx = deflate_init(ZLIB_ENCODING_RAW);
// unfortunately I can't find the gigantic blog post with example code
// that I learned from :(, but it contained the Ruby equivalent of the
// the substr() below. I blinked at it a bit but apparently this is how
// it's done.
$deflated = substr(deflate_add($ctx, $data, ZLIB_SYNC_FLUSH), 0, -4);
// $deflated is now "rtr\6\0"
$ictx = inflate_init(ZLIB_ENCODING_RAW);
$data2 = inflate_add($ictx, $deflated, ZLIB_NO_FLUSH);
// $data2 is now "ABC"
/ gzdeflate()
会发生什么:
gzinflate()
尝试$data = "ABC";
$deflated = gzdeflate($data, 9, ZLIB_ENCODING_RAW);
// $deflated is now "str\6\0"
$output = gzinflate($deflated);
// $output is now "ABC"
gzinflate()
的输出会产生 inflate_add()
。作为TL; DR:
data error
答案 0 :(得分:0)
你所说的正确是不正确的,你所说的不正确是正确的。
使用deflate_add
,您故意创建一个未终止的,即无效的deflate流。为什么,我不知道。 (显然,你也不是,因为这来自一个你无法找到的“巨大的博客文章”。)这是用ZLIB_SYNC_FLUSH
完成当前的deflate块并添加一个空的存储块。 substr(,,-4)
正在删除末尾的大部分空存储块,留下一个不完整的无效膨胀流,过早地在存储块的中间结束。
gzdeflate
正在创建一个正确终止的deflate流,其中一个deflate块被标记为最后一个块。两个流之间的唯一区别是第一个(最低有效)位,它是1以标记最后一个块。
你没有说正确终止的deflate流是如何“导致一切崩溃”。在任何情况下,您都可以使用deflate_add
而不是ZLIB_FINISH
使用ZLIB_SYNC_FLUSH
制作正确终止的deflate流,并放弃substr
。
如果这就是您所要求的,则无法使用gzdeflate
制作无效的deflate流。你不能只改变第一位,因为对于一个更大的字符串,最后一个块可能不是第一个块。