Apache 如何从 CGI 脚本中缓冲 STDOUT?

Apache 如何从 CGI 脚本中缓冲 STDOUT?

作为我正在开发的内容管理系统的一部分,我有一个脚本,它可以响应浏览器对 URL 的 GETing 操作来检索图像文件(JPEG、GIF、PNG 等)http://myserver/getimage.cgi/virtual/path/to/image。在服务器上,图像文件以随机命名的 blob 形式存储在 DOCUMENT_ROOT 之外,数据库会跟踪元数据,特别是虚拟路径、blob 文件名和 MIME 类型之间的对应关系。该脚本如下所示:-

#!/usr/bin/perl

use CGI::Simple;
use File::Copy;
use MYSTUFF 'dblookup';

my $q = new CGI::Simple;
my ($mimetype, $filepath) = dblookup($q->path_info);

$| = 1; # enable autoflush so header is output before calling copy()
print $q->header(-type=>$mimetype);
copy($filepath, \*STDOUT);

dblookup函数由 MYSTUFF.pm 导出,并提取通过标准 CGI $PATH_INFO 环境变量传入的虚拟路径的 mimetype 和文件路径。

我关心的是 Apache 服务器在开始将 CGI 脚本的输出发送回浏览器之前如何对其进行假脱机处理。如果服务器将整个输出都假脱机处理,则服务器上可能需要大量的假脱机空间,因为图像文件的大小可能是 10 或 100 MB,而当我开始支持视频文件时,它们的大小可能会达到 GB。

Apache 服务器是否足够明智,将 CGI 脚本中的 STDOUT 流缓冲到获得所有标头(即由 生成的第一个“\n\n”)为止$q->header(),然后开始将数据从 STDOUT 逐个缓冲区复制到连接到 HTTP 连接的任何套接字,再将其返回到浏览器?文件::复制表明它将使用 1K 缓冲区,因此如果 Apache 按照我所概述的方式运行,那么我实际上就没有问题,因为 IPC 套接字/管道将对我的 CGI 脚本强制执行流量控制,从而无需除已经存在的缓冲区之外的任何进一步的假脱机空间??

答案1

我不确定 Apache 如何处理这个问题。但是,如果你是出于性能原因询问这个问题,那么我很好奇你为什么一开始就使用 CGI...

您可能需要考虑以下几种替代方案:

  • 将文件放在文档根目录中,mod_negotiate根据服务器和客户端配置选择正确的 MIME 类型
  • 用于mod_rewrite告诉 Apache 读取特定文件以响应特定请求。可以根据 cookie 或请求设置的其他内容改变此处生成的结果;有关更多详细信息,请参阅mod_rewrite 文档
  • 如果你的脚本不仅仅是从磁盘读取文件,并且上述两个选项都不起作用,请查看美味可口适用于不需要 CGI 的现代 Perl Web 框架。

相关内容