【问题标题】:Why does my simple fastCGI Perl script fail?为什么我的简单 fastCGI Perl 脚本会失败?
【发布时间】:2010-09-25 05:45:37
【问题描述】:

我不属于 Perl 世界,所以其中一些对我来说是新的。我正在运行安装了 apache2 和 mod_fcgid 软件包的 Ubuntu Hardy LTS。我想让 MT4 在 fcgid 而不是 mod-cgi 下运行(使用普通 CGI 似乎可以运行)。

我似乎连一个简单的 Perl 脚本都无法在 fcgid 下运行。我创建了一个简单的“Hello World”应用程序并包含来自this previous question 的代码来测试 FCGI 是否正在运行。

我将脚本命名为 HelloWorld.fcgi(当前 fcgid 设置为仅处理 .fcgi 文件)。代码:

#!/usr/bin/perl

use FCGI;

print "Content-type: text/html\n\n";
print "Hello world.\n\n";
my $request = FCGI::Request();
if ( $request->IsFastCGI ) { 
    print "we're running under FastCGI!\n";
} else { 
    print "plain old boring CGI\n";
}

当从命令行运行时,它会打印“plain old borehole...”当通过对 apache 的 http 请求调用时,我收到 500 Internal Server 错误,并且脚本的输出会打印到 Apache 错误日志中:

Content-type: text/html

Hello world.

we're running under FastCGI!
[Wed Dec 03 22:26:19 2008] [warn] (104)Connection reset by peer: mod_fcgid: read data from fastcgi server error.
[Wed Dec 03 22:26:19 2008] [error] [client 70.23.221.171] Premature end of script headers: HelloWorld.fcgi
[Wed Dec 03 22:26:25 2008] [notice] mod_fcgid: process /www/mt/HelloWorld.fcgi(14189) exit(communication error), terminated by calling exit(), return code: 0

当我运行相同代码的 .cgi 版本时,它运行良好。知道为什么脚本的输出会进入错误日志吗? Apache config 是默认的 mod_fcgid 配置 plus,在 VirtualHost 指令中:

  ServerName test1.example.com
  DocumentRoot /www/example

  <Directory /www/example>
    AllowOverride None
    AddHandler cgi-script .cgi
    AddHandler fcgid-script .fcgi
    Options +ExecCGI +Includes +FollowSymLinks
  </Directory>

【问题讨论】:

    标签: perl fastcgi movabletype mod-fcgid


    【解决方案1】:

    无论如何,根据您服务器的错误日志,看起来 FCGI 正在工作,并且被正确调用,但是您的脚本没有在循环中运行,等待下一个请求出现。所以你的测试脚本确实完成了任务——报告是否配置了 FastCGI。所以现在您应该能够重新配置 MT 以使用 FastCGI。

    【讨论】:

      【解决方案2】:

      问题在于“Content-Type”标头是在请求循环之外发送的。您必须为每个请求打印“Content-Type”标头。如果你移动

      打印“内容类型:文本/html\n\n”;

      到请求循环的顶部,它应该可以解决问题。

      此外,您需要遍历请求,否则您将得不到任何好处,因此请按照第一个发布者的示例:

      my $request = FCGI::Request();
      while($request->Accept() >= 0) {
        print("Content-type: text/html\n\n");
      }
      

      【讨论】:

        【解决方案3】:

        Movable Type 将 CGI::Fast 用于 FastCGI。如mat 所述,典型的FastCGI 脚本循环运行。使用 CGI::Fast 的循环如下所示:

        #!/usr/bin/perl
        
        use strict;
        use CGI::Fast;
        
        my $count = 0;
        while (my $q = CGI::Fast->new) {
            print("Content-Type: text/plain\n\n");
            print("Process ID: $$; Count is: " . ++$count);
        }
        

        我在安装了 FCGI 和 CGI​​::Fast 模块的服务器上测试了这个脚本,并按照您的预期计算增量。如果进程 ID 更改,count 将返回 1,然后在该进程内递增。当然,每个进程都有自己的变量空间。

        对于 MT,启用 FastCGI 只需将 cgi 脚本重命名(或符号链接)为“fcgi”(或将“cgi”脚本的处理程序设置为 fcgid,但这对于 mt-xmlrpc.cgi 不起作用t FastCGI 友好呢)。您还需要在mt-config.cgi 文件中添加一些指令,以便它知道新的脚本名称。像这样:

        AdminScript mt.fcgi
        CommentsScript mt-comments.fcgi
        

        等等。有关 FastCGI 和 Movable Type 的更多文档,请访问 movabletype.org。

        【讨论】:

          【解决方案4】:

          我使用 CGI::Fast 比 FCGI 多,但我认为想法是一样的。快速 cgi 的目标是加载程序一次,并为每个请求循环迭代。

          FCGI 的手册页说:

          use FCGI;
          
          my $count = 0;
          my $request = FCGI::Request();
          
          while($request->Accept() >= 0) {
              print("Content-type: text/html\r\n\r\n", ++$count);
          }
          

          这意味着,您必须先Accept请求,然后才能将任何内容打印回浏览器。

          【讨论】:

          • 试过了,结果相似。还尝试使用简单的 CGI::Fast Hello World - 也失败了。好奇怪……
          猜你喜欢
          • 2010-11-09
          • 1970-01-01
          • 1970-01-01
          • 2011-09-07
          • 2015-04-16
          • 2011-04-30
          • 1970-01-01
          • 1970-01-01
          • 2022-01-05
          相关资源
          最近更新 更多