我正在尝试在CGI中提供文件上传的实时解析,并在屏幕上显示数据。
然而,在发送CGI应用程序之前,Apache2似乎想要等待完整的POST完成。
如何强制Apache2停止缓冲POST到我的CGI应用程序?
修改
看起来它实际上是被缓冲的CGI的输出。我开始将数据流式传输到临时文件以观察其进度。那,我还有另外一个问题。
1)输出正在缓冲。我已经尝试了SetEnvIf(简称SetEnv)为“!nogzip”,“nogzip”和“!gzip”而没有成功(在CGI目录定义中)。
2)在CGI进程退出之前,Apache2似乎没有读取CGI的输出?我注意到我的CGI应用程序(正在刷新与否)在80K左右的“fwrite(...,stdout)”行中永久挂起。
修改
好的,Firefox正在搞乱我。如果我发送150K文件,那么80K左右就没有CGI锁定。如果文件是2G,则有一个锁定。因此,Firefox在尝试发送文件时不会从服务器读取输出...是否有任何标题或替代内容类型可以更改该行为?
修改
好吧,我认为大文件上的CGI输出锁定实际上并不重要。我不需要回显文件!我正在调试由调试辅助工具引起的问题。 :)
我觉得这个效果还不错。谢谢!
最终注释
就像一个注释......我认为Apache2缓冲输入的原因是我总是得到一个“Content-Length”环境变量。我猜FireFox足够聪明,可以预先计算多部分表单上传的内容长度,而Apache2正在传递它。我认为Apache2正在缓冲输入并报告长度本身。
答案 0 :(得分:3)
你确定这是缓冲输入的问题吗?如果您的调试方法只是print
响应,那么输出缓冲问题就更常见了,并且可能无法与输入缓冲区分开来。
(输出缓冲通常由脚本中的未刷新stdout
或过滤器引起。通常的罪魁祸首是DEFLATE
过滤器,通常用于压缩所有text/
响应,它们是来自静态文件还是脚本。一般来说,压缩脚本的输出是一个好主意,但副作用是它会使响应完全缓冲。如果你需要立即响应,你会需要通过将AddOutputFilterByType
的应用程序限制为特定<Directory>
或使用mod_setenvif
设置!nogzip
注释来关闭该脚本或所有脚本。 )
类似地,输入过滤器(包括,再次DEFLATE
)可能会导致CGI输入被缓冲,如果您使用任何。但它们的使用不太广泛。
编辑:暂时,只需注释掉你启用了deflate过滤器的任何httpd conf。一旦你对没有它的IO没有缓冲感到高兴,你可以有选择地把它放回去。
我注意到我的CGI应用程序(正在刷新与否)在80K左右的“fwrite(...,stdout)”行中永久挂起。
是的...如果你没有读完所有的输入,你可以在尝试写输出时死锁,如果写得太多。您可以阻止输出调用,等待网络缓冲区取消阻塞,以便您可以发送您已获得的新数据,但它们永远不会,因为浏览器在开始读取输出之前尝试发送所有数据。
你在这做什么工作?一般来说,编写progress-info输出以响应直接表单POST是没有意义的,因为浏览器通常不会显示它。如果你想在普通的HTML表单提交上提供上传进度反馈,这通常是通过查看AJAX连接以查看上传的方式(这意味着必须共享进度信息,例如在数据库中)来实现的。 ),或使用Flash上传组件。
答案 1 :(得分:0)
来自Apache HTTP Server手册的(旧版本):
每次你的脚本执行“刷新” 输出数据,数据被中继 对客户。一些脚本 语言,例如Perl,有 他们自己的输出缓冲 - 这个 可以通过设置$ |来禁用 特殊变量1.当然这个 确实增加了总数 正在传输的数据包,可以 导致一种缓慢的感觉 最终用户。
你是否尝试过冲洗STDOUT或检查你使用的语言是否有缓冲你可以禁用?
答案 2 :(得分:0)
这是在服务器端使用perl时控制缓冲的有用指南:
http://perl.plover.com/FAQs/Buffering.html
许多想法和概念也适用于其他语言,例如使用缓冲和无缓冲输出,原始系统调用来读取和写入数据,而I / O库则执行自己的缓冲。