欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

ob_end_flush() failed to send buffer of zlib output compression (1) in wordpress

6年前

最近修改于9个月前

#18525 新的缺陷(bug) 

服务器中的zlib.output_compression“on”与autoupdate冲突

报告人:avidre拥有者: 
里程碑:正在等待审核优先:正常
严重性:正常版:3.2.1
零件:引导/负载关键词:has-patch dev-feedback
  

说明 

如果服务器(我的vps服务器)中的zlib.output_compression为“on”,则自动更新工作,但没有详细输出或任何安装指示已成功。

所有自动更新WordPress应用程序和所有插件的此错误是一致的。

它不是一个插件冲突。发生在不同的服务器上。

测试已经确认,当zlib.output_compression返回到“off”时,更新按预期工作。

在我看来,这是一个小错误,可能在自述文件中的一个注释就足够了。

谢谢,

Neil Miller 
zx @ ...

附件(6)

18525.diff (2.6 KB通过添加- )kurtpayne 6年前。 
18525.2.diff (2.6 KB通过添加- )kurtpayne 6年前。 
用ob_end_flush()替换ob_get_flush()。
18525.3.diff (2.8 KB通过添加- )kurtpayne 6年前。 
重新修复补丁11020,将填充更改为html注释
18525.4.diff (3.0 KB通过添加- )kurtpayne 6年前。 
使用带有空字节的HTML注释进行填充
18525.5.diff (2.9 KB通过添加- )kurtpayne 6年前。 
禁止ob_end_flush通知,在CLI模式下保存
18525.6.diff (3.7 KB通过添加- )kurtpayne 6年前。 
与ob_gzhandler的兼容性

将所有附件下载为:.zip

      
 
 

变更历史(32)

#1@SergeyBiryukovCore Committer6年前 


 

可能相关:#18239

#2@DD32首席开发6年 


 

如果服务器(我的vps服务器)中的zlib.output_compression为“on”,则自动更新工作,但没有详细输出或任何安装指示已成功。

您仍然应该看到所有的消息,并且它已经完成。

在PHP或服务器级别的zlib有缺点,它创建一个输出缓冲区,并等待整个页面生成,然后才能将其发送到客户端,结果是页面从未传递到浏览器,直到WordPress已经完成更新。然而,您应该看到页面一旦完成生成..你看到不同的东西?

这是可以在抄写簿上记录的东西,但是还没有太多的可以说或完成,不同的服务器配置将会影响不同的应用程序 - 大多数用户甚至不知道zlib是什么..

#3@kurtpayne6年前


 

有没有我们可以不使用原因的ini_set()打开相应的值关在wp_ob_end_flush_all() 

未验证的例子:

ini_set('zlib.output_handler','');
ini_set('zlib.output_compression',0);
ini_set('output_handler','');
ini_set('output_buffering',false);
ini_set('implicit_flush',true);

#4@kurtpayne6年前


 

次要测试表明这两行导致“头已发送”警告:

ini_set('zlib.output_handler','');
ini_set('zlib.output_compression',0);

删除它们后,修改后的示例如下所示:

ini_set('output_handler','');
ini_set('output_buffering',false);
ini_set('implicit_flush',true);

kurtpayne 
6年前

 

#5@kurtpayne6年前


 
  • 关键字 has-patch dev-feedback被添加

18525.diff将禁用的gzip(上的Apache2,IIS未测试)和PHP的zlib压缩。它还将发送一个4K块的空字节,以试图击败分块。似乎没有任何其他方法强制apache2停止分块输出,而不发送内容长度头。

还有一个修改,强制主题/插件更新在每个步骤后立即刷新。

6年 后续: @dd32Lead Developer6年前 


 

ob_get_flush()超过ob_end_flush()的任何原因? 

尽管我认为,似乎ini_set('zlib.output_handler',''); 确实做了分组说的话,也可以在页面加载的任何一点调用它。

对于$ disable_compression,我们应该能够处理一次每页负载,如果函数调用,我们现在要刷新,不需要它是一个变量。如果我们在函数中使用一个静态变量,我们可以确保我们只能对每个页面加载一次额外的处理。

你有一个文件/参考文献,解释了4k的空字节?考虑到在页面加载中间会输出,我不完全确定了什么?或者是将其推到块边界上,以便将块发送到浏览器,而不是等待下一个?

#7 回复: ↑6@kurtpayne6年前


 

回复dd32

ob_get_flush()超过ob_end_flush()的任何原因? 

谢谢,好抓。这是从较早版本的代码。

尽管我认为,似乎ini_set('zlib.output_handler',''); 确实做了分组说的话,也可以在页面加载的任何一点调用它。

只要你当前没有缓冲输出。否则,您无法正确清除输出缓冲区。这是从我自己的经验和从这里的第一个评论。

对于$ disable_compression,我们应该能够处理一次每页负载,如果函数调用,我们现在要刷新,不需要它是一个变量。如果我们在函数中使用一个静态变量,我们可以确保我们只能对每个页面加载一次额外的处理。

虽然这个功能被注册为关机挂钩。我们并不总是想使用$ disable_compression标志,对吧?只是当绝对有必要提供即时反馈?

你有一个文件/参考文献,解释了4k的空字节?考虑到在页面加载中间会输出,我不完全确定了什么?或者是将其推到块边界上,以便将块发送到浏览器,而不是等待下一个?

很高兴你质疑了这一点。我可以用眼睛。从我的研究中,它看起来像apache2使用chunked编码为任何HTTP 1.1响应,除非你指定一个内容长度标题,否则你不能关闭它。由于输出不是手头已知的,这是不可能的。

http://serverfault.com/questions/222148/how-to-disable-chunking-in-apache 
http://bytes.com/topic/php/answers/10395-chunked-encoding-php-apache2

从我的测试(apache2 / mod_php)看,它似乎正在缓冲输出,甚至拉出这个补丁中的所有其他技巧。发送一个4K字节的空字节不应该对输出有任何影响,但确实使得响应变得更加快速

可能也成为一个需要被渲染输出前要填充的浏览器的缓冲区。如php.net所述

Microsoft Internet Explorer的某些版本只有在接收到256字节的输出后才会开始显示该页面,因此您可能需要在刷新之前发送额外的空格以使这些浏览器显示该页面。

通常,对于WordPress页面,将达到256字节限制,但浏览器缓冲是我想要牢记的一个概念。

kurtpayne 
6年前

 

用ob_end_flush()替换ob_get_flush()。

#8@DD32首席开发6年 


 

虽然这个功能被注册为关机挂钩。我们并不总是想使用$ disable_compression标志,对吧?只是当绝对有必要提供即时反馈?

我没有意识到这一点..似乎在所有诚实中都没有用。我相信有一个理由。

从我的测试(apache2 / mod_php)看,它似乎正在缓冲输出,甚至拉出这个补丁中的所有其他技巧。发送一个4K字节的空字节不应该对输出有任何影响,但确实使得响应变得更加快速。

我会在一个独立的脚本上进行一些测试,看看我能想出来的。通常几个循环,放置好的sleep()将会给你一个关于发生什么的解释。

#9 follow-up: @dd32Lead Developer6年前 


 

补丁回复[11020] - 就是说,不知道原来的通知很难说。
Trunk将会发出一个注意事项:注意:ob_end_flush()[ref.outcontrol]:当调用该函数时,无法删除缓冲区zlib输出压缩,您的代码/还原代码也将产生它,只能将其隐藏显示。

我已经玩了一下,它肯定有助于推出内容在所有配置中使用某种形式的缓冲。

发现一个奇怪的错误,但Opera无法处理nullbytes ..或至少,当它是源代码的一部分,在HTML注释标签,他们没事。我相信我已经看到一个类似于Safari的错误,其中一个空字节在一个块边界上,它可能导致页面的其余部分“丢失”(只是没有渲染)。(我会链接一个例子,但是我无法在我的vps上运行一个5+的第二个脚本,搜索引擎会击中:))

在HTML注释中输出Nullbytes会显示出来:

foreach(range(1,5)as $ i){
	echo $ i。'<br />';
	echo'<! - '。str_repeat(chr(0),4096))。' - >';
	睡眠(2);
}

4k似乎是正确的大小,用于Apache的分块处理程序,并且应该足够大,以满足其他Web服务器的希望。

还要注意,PHPDoc 在内联时不能被解析,我不相信,所以最好把@links放在函数文档而不是内联中。

kurtpayne 
6年前

 

重新修复补丁11020,将填充更改为html注释

#10 回复: ↑9@kurtpayne6年前


 

回复dd32

补丁恢复[11020]

固定。谢谢。

Trunk将会发出一个注意事项:注意:ob_end_flush()[ref.outcontrol]:当调用该函数时,无法删除缓冲区zlib输出压缩,您的代码/还原代码也将产生它,只能将其隐藏显示。

即使使用E_ALL,我也无法再现。你使用什么设置?

发现一个奇怪的错误,但Opera无法处理nullbytes ..或至少,当它是源代码的一部分,在HTML注释标签,他们没事。我相信我已经看到一个类似于Safari的错误,其中一个空字节在一个块边界上,它可能导致页面的其余部分“丢失”(只是没有渲染)。

改为补丁,只是发出<! - - >一次。我已经看到了不同的方法...一些使用一个大的html评论,一些喜欢空格,一些使用小的评论等。 这个补丁使用字母表。

还要注意,PHPDoc 在内联时不能被解析,我不相信,所以最好把@links放在函数文档而不是内联中。

固定。WP在任何地方生成文档?我认为这些块对于读者来说更有意义,但我同意phpdoc / docblox / etc。不会拾起他们。

#11@kurtpayne6年前


 

仅供参考,在进行渲染之前,我确实遇到了一些高达512字节的缓冲区。它看起来像是用于MIME类型的嗅探。

看起来这是ajax处理程序中已知的问题,它发送X-Content-Type-Options:nosniff标题。

http://code.google.com/p/chromium/issues/detail?id=31410

#12 跟进: @dd32Lead Developer6年前 


 

即使使用E_ALL,我也无法再现。你使用什么设置?

E_ALL(嗯,这并不重要,WordPress的WP_DEBUG覆盖了PHP错误报告级别),启用了zlib PHP压缩。ob_get_level()将返回> 1,ob_end_flush()不能关闭该样式的输出缓冲区。您可能还需要运行PHP 5.3,因为我也看过其他报告,php 5.3 + zlib是我知道的唯一组合

改为补丁,只是发出<! - - >一次。

个人而言,我喜欢<! - NULLNULL .. - >,因为我测试的浏览器在源视图中不包含一吨额外的标记(因为空字节字符不能显示)。只要它在一个HTML标签/注释中,浏览器似乎正确地处理它。

固定。WP在任何地方生成文档?

http://xref.wordpress.org/

在进行渲染之前,我确实遇到了一些情况,最多可以达到512个字节。

可能值得检查的是,插件升级器iframes的头部长度至少为512字节,然后输出步骤,但它是一个旧错误,所以希望不会影响任何当前的一代浏览器。

kurtpayne 
6年前

 

使用带有空字节的HTML注释进行填充

#13 回复: ↑12@kurtpayne6年前


 

回复dd32

E_ALL(那没关系,WordPress的WP_DEBUG会覆盖PHP错误报告级别)

哈。错过了,谢谢。

启用zlib PHP压缩。ob_get_level()将返回> 1,ob_end_flush()不能关闭该样式的输出缓冲区。

在函数顶部的缓冲区冲洗应该解决这个问题。这样在zlib关闭之前缓冲区是空的。根据我看到的文档,这是正确的操作顺序。

您可能还需要运行PHP 5.3,因为我也看过其他报告,php 5.3 + zlib是我知道的唯一组合

尝试使用WP_DEBUG在5.3上与apache 2.2在两台不同的机器上运行。我无法重现您所看到的通知。你运行在cgi / suphp / fastcgi设置下?

个人而言,我喜欢<! - NULLNULL .. - >,因为我测试的浏览器在源视图中不包含一吨额外的标记

改变。还添加了一个链接到这个线程的任何人读取代码和划伤他们的头。

在输出步骤之前,可能需要检查插件升级程序iframes的头部长度至少为512bytes

在我的测试网站上,一个插件更新在iframe中生成> 11K的输出。看起来很安全。

我在野外看到一些wpshell / wp-cli项目?如果这个补丁包含一些代码来包装检查以确保sapi不是CLI的4K回显?还是那个细了?

if('cli'!= php_sapi_name(){
    echo'<! - '。str_repeat(chr(0),4089))。' - >'; // 4096个字节
}

#14 follow-up: @dd32Lead Developer6年前 


 

你运行在cgi / suphp / fastcgi设置下吗?

可以这样,我在这里运行一个FastCGI设置。

启用zlib PHP压缩。ob_get_level()将返回> 1,ob_end_flush()不能关闭该样式的输出缓冲区。

在函数顶部的缓冲区冲洗应该解决这个问题。这样在zlib关闭之前缓冲区是空的。根据我看到的文档,这是正确的操作顺序。

登录页面的底部以及ajax加载是我看到的主要位置。最终,@ob_end_clean(); 可能是最好的解决方案。

我在野外看到一些wpshell / wp-cli项目?如果这个补丁包含一些代码来包装检查以确保sapi不是CLI的4K回显?

如果包含任何内容,我将早期从函数返回(即,在您的额外的禁用缓存IF块之前)

kurtpayne 
6年前

 

禁止ob_end_flush通知,在CLI模式下保存

#15 回复: ↑14@kurtpayne6年前


 

回复dd32

登录页面的底部以及ajax加载是我看到的主要位置。最终,@ob_end_clean(); 可能是最好的解决方案。

谢谢。ajax页面显示了我的通知。我专注于主页面和安装程序/更新页面。

我使用ob_list_handlers()ob_get_status()ob_get_length()来进一步看这个。看起来缓冲区中有数据(ob_get_length()返回> 0),ob_end_flush()结束缓冲(ob_get_level()不会导致无限循环),并将数据放在线上(您可以看到它在屏幕),但是它没有完全刷新缓冲区,因为数据没有从缓冲区中成功删除,因此通知。

最终,@ob_end_clean(); 可能是最好的解决方案。

我同意。我没有看到这样的代码。我在php.net评论或谷歌中找不到任何东西。

我通过使用ob_start(“ob_gzhandler”)堆叠mod_deflate进行测试后,提交补丁的重构版本。 ob_gzhandler发送自己的标题,所以它不是可以编码的东西。

参考:http: //us.php.net/ob_gzhandler 第二到最后的评论

如果在ob_start(“ob_gzhandler”)后调用ob_end_clean(),“Content-Encoding:gzip”头仍然会被发送(假设浏览器支持编码)。如果您不再使用ob_gzhandler回调函数调用ob_start(),则输出将不会被压缩,但是头将会说明。这会导致mozilla(从构建2002032808)显示一个空白页。

kurtpayne 
6年前

 

与ob_gzhandler的兼容性

#16 跟进: @ryanLead Tester5年前 


 

使用trunk r21645,PHP 5.4.4发布以下通知:

PHP注意:ob_end_flush():无法在第2508行的/.../trunk/wp-includes/functions.php中发送zlib输出压缩(0)的缓冲区

18525.6.diff避免通知。

#17@SergeyBiryukovCore Committer5年前 


 

#22430被标记为重复。

#18@SergeyBiryukov核心提交者5年 


 

#22430被标记为重复。

#19@SergeyBiryukovCore Committer5年前 


 

#22430被标记为重复。

#20@nacin首席开发5年 


 

#22430被标记为重复。

#21@nacin首席开发4年 


 

我们应该调查是否需要调用wp_ob_end_flush_all()。如果我记得正确的是,这是为了部分解决PHP 4对PHP 5中的对象销毁排序异常问题。

#22@nacin首席开发3年 


 
  • 组件 从常规更改为引导/加载

#23 回复: ↑16@harmr3年前


 

回复瑞恩

使用trunk r21645,PHP 5.4.4发布以下通知:

PHP注意:ob_end_flush():无法在第2508行的/.../trunk/wp-includes/functions.php中发送zlib输出压缩(0)的缓冲区

18525.6.diff避免通知。

有没有机会把这个补丁变成4.1?

#24@selnomeria2年前


 

解决方案到目前为止我已经遇到了:

======================== 解决方案1 ====================

在插件(或某处)中,您可能有以下代码:

ini_set('zlib.output_compression','1'); 

所以我替换了那个代码 

if(!is_admin())ob_start('ob_gzhandler'); //因为在管理页面中,它会导致插件安装冻结

压缩将仍然保持ON

======================== 解决方案2 ==================== 
你可能必须使用:

remove_action('shutdown','wp_ob_end_flush_all',1);

但在这种情况下阅读笔记:https//core.trac.wordpress.org/ticket/22430#comment : 4

最后编辑2年前 由selnomeria()(diff

来自  https://core.trac.wordpress.org/ticket/18525



#18525 new defect (bug)

zlib.output_compression "on" in server conflicts with autoupdate

Reported by:avidreOwned by: 
Milestone:Awaiting ReviewPriority:normal
Severity:normalVersion:3.2.1
Component:Bootstrap/LoadKeywords:has-patch dev-feedback
  

Description 

If zlib.output_compression is "on" in server (my vps server), then auto-update works, but without verbose output or any indication that install has succeeded.

This error is consistent for all auto-updates WordPress Application and all plugins.

It is NOT a plugin conflict. Occurs on different servers.

Testing has confirmed that when zlib.output_compression is returned to "off", then updates work as expected.

In my opinion this is a minor bug and probably a note in the readme file will suffice.

Thank You,

Neil Miller
zx@…

Attachments (6)

18525.diff (2.6 KB) - added by kurtpayne 6 years ago.
18525.2.diff (2.6 KB) - added by kurtpayne 6 years ago.
Replaced ob_get_flush() with ob_end_flush().
18525.3.diff (2.8 KB) - added by kurtpayne 6 years ago.
Re-reverted patch 11020, changed padding to html comments
18525.4.diff (3.0 KB) - added by kurtpayne 6 years ago.
Using an HTML comment with null bytes for padding
18525.5.diff (2.9 KB) - added by kurtpayne 6 years ago.
Suppressing ob_end_flush notices, bailing during CLI mode
18525.6.diff (3.7 KB) - added by kurtpayne 6 years ago.
Compatibility with ob_gzhandler

Download all attachments as: .zip

      
 
 

Change History (32)

#1@SergeyBiryukovCore Committer 
6 years ago

 

Possibly related: #18239

#2@dd32Lead Developer 
6 years ago

 

If zlib.output_compression is "on" in server (my vps server), then auto-update works, but without verbose output or any indication that install has succeeded.

You should still see all the messages, and that it's completed.

zlib at the PHP, or server level, has the disadvantage that it creates an output buffer, and waits for the entire page to be generated before it can send it to the client, as a result, The page is never delivered to the browser until WordPress has finished the updates. You should however, see the page once it finishes generating.. Are you seeing something different?

This is something that could be documented on the codex, but there isn't really much more that can be said or done, different server configurations will affect different applications differently - Most users will not even know what zlib is..

#3@kurtpayne 
6 years ago

 

Is there a reason we can't use ini_set() to turn the appropriate values off in wp_ob_end_flush_all() ?

Untested example:

ini_set('zlib.output_handler', '');
ini_set('zlib.output_compression', 0);
ini_set('output_handler', '');
ini_set('output_buffering', false);
ini_set('implicit_flush', true);

#4@kurtpayne 
6 years ago

 

Minor testing indicates that these two lines cause a "headers already sent" warning:

ini_set('zlib.output_handler', '');
ini_set('zlib.output_compression', 0);

After removing them, the modified example looks like:

ini_set('output_handler', '');
ini_set('output_buffering', false);
ini_set('implicit_flush', true);

@kurtpayne 
6 years ago

 

#5@kurtpayne 
6 years ago

 
  • Keywords has-patch dev-feedback added

18525.diff will disable gzip (on apache2, IIS not tested) and php's zlib compression. It will also send a 4K block of null bytes in an attempt to defeat chunking. There doesn't seem to be any other way to force apache2 to stop chunking output without sending a content-length header.

There's also a modification to force theme/plugin updates to flush immediately after each step.

#6 follow-up: @dd32Lead Developer 
6 years ago

 

Any reason for ob_get_flush() over ob_end_flush()? 

Despite what I thought, it appears that ini_set('zlib.output_handler', ''); does indeed do what the packet says, and it can be called at any point of the pageload too.

as for $disable_compression, we should be able to process that once per page load, if the function's called, we want to flush now, no need for it to be a variable.. If we use a static variable within the function, we can make sure that we only do that extra processing once per pageload too.

Do you have a document/reference which explains the 4k null bytes? Given that'll be output during the middle of the pageload, I'm not entirely sure what that achieves? or is it to just push it over the block boundary so a chunk is sent to the browser rather than waiting for the next?

#7 in reply to: ↑ 6@kurtpayne 
6 years ago

 

Replying to dd32:

Any reason for ob_get_flush() over ob_end_flush()? 

Thanks, good catch. This was from an earlier version of the code.

Despite what I thought, it appears that ini_set('zlib.output_handler', ''); does indeed do what the packet says, and it can be called at any point of the pageload too.

As long as you're not currently buffering output. Otherwise, you can never clear the output buffer properly. This is from my own experience and from the first comment here.

as for $disable_compression, we should be able to process that once per page load, if the function's called, we want to flush now, no need for it to be a variable.. If we use a static variable within the function, we can make sure that we only do that extra processing once per pageload too.

This function is registered as a shutdown hook, though. We don't always want to use the $disable_compression flag, right? Just when it's absolutely necessary to give instant feedback?

Do you have a document/reference which explains the 4k null bytes? Given that'll be output during the middle of the pageload, I'm not entirely sure what that achieves? or is it to just push it over the block boundary so a chunk is sent to the browser rather than waiting for the next?

Glad you questioned this. I can use eyes on it. From my research, it looks like apache2 uses chunked encoding for any HTTP 1.1 response and you can't turn it off unless you specify a content-length header. Since the output isn't known before-hand, this isn't possible.

http://serverfault.com/questions/222148/how-to-disable-chunking-in-apache
http://bytes.com/topic/php/answers/10395-chunked-encoding-php-apache2

From my testing (apache2 / mod_php), it does seem like the output is being buffered, even pulling out all of the other tricks in this patch. Sending a 4K block of null bytes shouldn't have any affect on the output, but does make the responses feel snappier.

There could also be a buffer in the browser that needs to be filled before output is rendered. As noted on php.net:

Some versions of Microsoft Internet Explorer will only start to display the page after they have received 256 bytes of output, so you may need to send extra whitespace before flushing to get those browsers to display the page.

Generally, for WordPress pages, the 256 byte limit will be reached, but browser-buffering is a concept I wanted to keep in mind.

@kurtpayne 
6 years ago

 

Replaced ob_get_flush() with ob_end_flush().

#8@dd32Lead Developer 
6 years ago

 

This function is registered as a shutdown hook, though. We don't always want to use the $disable_compression flag, right? Just when it's absolutely necessary to give instant feedback?

I wasn't aware of that.. Seems rather useless in all honesty.. I'm sure there's a reason for it though.

From my testing (apache2 / mod_php), it does seem like the output is being buffered, even pulling out all of the other tricks in this patch. Sending a 4K block of null bytes shouldn't have any affect on the output, but does make the responses feel snappier.

I'll do some testing on a stand-alone script, see what I can come up with. Usually a few loops, well placed sleep()'s will give you a explanation as to what's happening where.. 

#9 follow-up: @dd32Lead Developer 
6 years ago

 

The patch reverts [11020] - that being said, without knowing the original Notice it's hard to tell.
Trunk will currently emmit a Notice: Notice: ob_end_flush() [ref.outcontrol]: failed to delete buffer zlib output compression when that function is called, your code/reverted code will produce it too, just hide it from display.

I've played with it a bit, and it certainly helps push the content out in all configurations where some form of buffering is in use.

Found a weird bug though, Opera can't handle the nullbytes.. or at least, not when it's part of the source, within HTML comment tags they're fine. I believe I've seen a similar bug for Safari, where a Null byte is on a chunk boundary, it can cause the rest of the page to be "lost" (just not rendered). (I'd link to an example, but I can't afford to have a 5+ second script running on my vps that search engines will hit :))

Outputting the Nullbytes within HTML comments appears to get around it:

foreach ( range(1, 5) as $i ) {
	echo $i . '<br />';
	echo '<!--' . str_repeat(chr(0), 4096) . '-->';
	sleep(2);
}

4k does appear to be the correct sizing to use for Apache's chunked handler as well, and should serve to be large enough for other web servers hopefully.

also note, PHPDoc can't be parsed when it's inline like that I don't believe, so best to puts @links in the function docs rather than inline.

@kurtpayne 
6 years ago

 

Re-reverted patch 11020, changed padding to html comments

#10 in reply to: ↑ 9@kurtpayne 
6 years ago

 

Replying to dd32:

The patch reverts [11020]

Fixed. Thanks.

Trunk will currently emmit a Notice: Notice: ob_end_flush() [ref.outcontrol]: failed to delete buffer zlib output compression when that function is called, your code/reverted code will produce it too, just hide it from display.

I'm not able to reproduce this even using E_ALL. What setup are you using?

Found a weird bug though, Opera can't handle the nullbytes.. or at least, not when it's part of the source, within HTML comment tags they're fine. I believe I've seen a similar bug for Safari, where a Null byte is on a chunk boundary, it can cause the rest of the page to be "lost" (just not rendered).

Changed the patch to just emit <!-- -> a bunch of times instead. I've seen different approaches to this ... some use one big html comment, some prefer whitespace, some use small comments, etc. This patch uses the alphabet.

also note, PHPDoc can't be parsed when it's inline like that I don't believe, so best to puts @links in the function docs rather than inline.

Fixed. Does WP generate documentation anywhere? I thought these blocks made more sense to the reader inline, but I agree that phpdoc/docblox/etc. wouldn't pick up on them.

#11@kurtpayne 
6 years ago

 

Just for reference, I did come across a case of chromium doing some buffering up to 512 bytes before rendering. It looks like this is for mime type sniffing.

It seems like this is a known issue in the ajax handler, which sends the X-Content-Type-Options: nosniff header.

http://code.google.com/p/chromium/issues/detail?id=31410

#12 follow-up: @dd32Lead Developer 
6 years ago

 

I'm not able to reproduce this even using E_ALL. What setup are you using?

E_ALL (Well, that doesn't really matter, WordPress's WP_DEBUG overrides the PHP error reporting level) with zlib PHP compression enabled. ob_get_level() will return > 1, and ob_end_flush() can't turn off that style of output buffer. You may also need to be running PHP 5.3 as I've seen other reports about it too, php 5.3+zlib is the only combination that i'm aware of amongst them

Changed the patch to just emit <!-- -> a bunch of times instead.

Personally I prefered <!-- NULLNULL.. --> as that way the browsers I tested don't include a tonne of extra markup in the source view (Since the null byte character can't be displayed). As long as it's within a HTML tag/comment browsers seem to handle it properly.

Fixed. Does WP generate documentation anywhere?

http://xref.wordpress.org/

I did come across a case of chromium doing some buffering up to 512 bytes before rendering.

Might be worth checking that the headers of the plugin upgrader iframes have at least 512bytes of length before it outputs the steps then, but it's an old bug, so hopefully doesn't affect any current generation browsers.

@kurtpayne 
6 years ago

 

Using an HTML comment with null bytes for padding

#13 in reply to: ↑ 12@kurtpayne 
6 years ago

 

Replying to dd32:

E_ALL (Well, that doesn't really matter, WordPress's WP_DEBUG overrides the PHP error reporting level)

Ha. Missed that, thanks.

with zlib PHP compression enabled. ob_get_level() will return > 1, and ob_end_flush() can't turn off that style of output buffer.

The buffer flush at the top of the function should solve this. That way the buffer is empty before zlib is turned off. According to the docs I've seen, that's the correct order of operations.

You may also need to be running PHP 5.3 as I've seen other reports about it too, php 5.3+zlib is the only combination that i'm aware of amongst them

Tried running with WP_DEBUG on on 5.3 with apache 2.2 on two different machines. I cannot reproduce the notice you're seeing. Are you running under a cgi/suphp/fastcgi setup?

Personally I prefered <!-- NULLNULL.. --> as that way the browsers I tested don't include a tonne of extra markup in the source view

Changed. Also added a link to this thread for anyone who reads the code and scratches their head.

Might be worth checking that the headers of the plugin upgrader iframes have at least 512bytes of length before it outputs the steps then

On my test site, one plugin update generated > 11K of output in the iframe. Looks like it's safe.

I've seen some wpshell / wp-cli projects in the wild ... should this patch include some code to wrap the 4K echo that checks to make sure the sapi isn't CLI? Or is that just too detailed?

if ('cli' != php_sapi_name() {
    echo '<!--' . str_repeat(chr(0), 4089) . '-->'; // 4096 bytes
}

#14 follow-up: @dd32Lead Developer 
6 years ago

 

Are you running under a cgi/suphp/fastcgi setup?

That could be it, I'm running a FastCGI setup here.

with zlib PHP compression enabled. ob_get_level() will return > 1, and ob_end_flush() can't turn off that style of output buffer. 

The buffer flush at the top of the function should solve this. That way the buffer is empty before zlib is turned off. According to the docs I've seen, that's the correct order of operations.

The bottom of the login page, as well as ajax loads are the main locations I see it. Ultimately, @ob_end_clean(); might be the best solution unfortunately.

I've seen some wpshell / wp-cli projects in the wild ... should this patch include some code to wrap the 4K echo that checks to make sure the sapi isn't CLI?

If anything was included of that, I'd return from the function early (ie. before your additional disable cache IF block)

@kurtpayne 
6 years ago

 

Suppressing ob_end_flush notices, bailing during CLI mode

#15 in reply to: ↑ 14@kurtpayne 
6 years ago

 

Replying to dd32:

The bottom of the login page, as well as ajax loads are the main locations I see it. Ultimately, @ob_end_clean(); might be the best solution unfortunately.

Thanks. The ajax pages made the notices show up for me. I was focused on the main pages and the installer/updater pages.

I used ob_list_handlers()ob_get_status(), and ob_get_length() to look at this a bit further. It looks like there is data in the buffer (ob_get_length() returns > 0) and ob_end_flush() does end buffering (ob_get_level() doesn't result in an infinite loop) and put the data on the wire (you see it on the screen), but it doesn't completely flush the buffer because the data isn't successfully deleted from the buffer, hence the notice.

Ultimately, @ob_end_clean(); might be the best solution unfortunately.

I agree. I don't see a way to code around this. I couldn't find anything in php.net comments or on google either.

I'm submitting a refactored version of the patch after testing it by stacking mod_deflate with with ob_start("ob_gzhandler");ob_gzhandler sends its own headers, so it's not something that can be coded around.

Reference: http://us.php.net/ob_gzhandler second-to-last comment

if you call ob_end_clean() after ob_start("ob_gzhandler"), the "Content-Encoding: gzip" header will still get sent (assuming the browser supports the encoding). if you don't call ob_start() again with the ob_gzhandler callback function, the output will not be compressed, but the header will say it is. this causes mozilla (as of build 2002032808) to display a blank page.

@kurtpayne 
6 years ago

 

Compatibility with ob_gzhandler

#16 follow-up: @ryanLead Tester 
5 years ago

 

With trunk r21645 the following notice is issued with PHP 5.4.4:

PHP Notice:  ob_end_flush(): failed to send buffer of zlib output compression (0) in /.../trunk/wp-includes/functions.php on line 2508

18525.6.diff avoids the notice.

#17@SergeyBiryukovCore Committer 
5 years ago

 

#22430 was marked as a duplicate.

#18@SergeyBiryukovCore Committer 
5 years ago

 

#22430 was marked as a duplicate.

#19@SergeyBiryukovCore Committer 
5 years ago

 

#22430 was marked as a duplicate.

#20@nacinLead Developer 
5 years ago

 

#22430 was marked as a duplicate.

#21@nacinLead Developer 
4 years ago

 

We should investigate if calling wp_ob_end_flush_all() is necessary anymore. If I recall correctly, this was to partially work around object destruction ordering weirdness in PHP 4 versus PHP 5.

#22@nacinLead Developer 
3 years ago

 
  • Component changed from General to Bootstrap/Load

#23 in reply to: ↑ 16@harmr 
3 years ago

 

Replying to ryan:

With trunk r21645 the following notice is issued with PHP 5.4.4:

PHP Notice:  ob_end_flush(): failed to send buffer of zlib output compression (0) in /.../trunk/wp-includes/functions.php on line 2508

18525.6.diff avoids the notice.

is there a chance that this patch makes it into 4.1?

#24@selnomeria 
2 years ago

 

SOLUTIONS I have came across so far:

======================== SOLUTION 1 ====================

In plugins (or somewhere) you probably have this code:

ini_set('zlib.output_compression', '1'); 

so, I replaced that code with 

if (!is_admin()) ob_start('ob_gzhandler');     //because, in admin pages, it causes plugin installation freezing

and Compression will be remained still ON.

======================== SOLUTION 2 ====================
You may have to use:

remove_action( 'shutdown', 'wp_ob_end_flush_all', 1 );

but read notes in such case: https://core.trac.wordpress.org/ticket/22430#comment:4

Last edited 2 years ago by selnomeria (previous) (diff)

#25@simonbcn 
13 months ago

 

I have the same problem with PHP 7.0


来自  https://core.trac.wordpress.org/ticket/18525


普通分类: