我已经从外壳测试了该程序,并且从文件中还原标准输入时它可以正常工作。但是,当作为CGI程序运行时,它会超时(TimeForCGI hiawatha Web服务器设置设置为30秒)。该程序仅包含在一个文件中。应该注意的是,编写该程序仅是为了物理验证我在阅读的有关CGI的内容,并且我选择了C(或其他会生成二进制可执行文件的东西),因此我可以确保所有解释器都不会触及这些东西,可能会简化它们的抽象。

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <error.h>

int main (void);

int
main
(void)
{
  static char buf[BUFSIZ];
  size_t size;

  if (setvbuf (stdout, NULL, _IOFBF, BUFSIZ) != 0)
    error (EXIT_FAILURE, errno, "setvbuf(), stdout");
  if (setvbuf (stdin, NULL, _IOFBF, BUFSIZ) != 0)
    error (EXIT_FAILURE, errno, "setvbuf(), stdin");
  if (setvbuf (stderr, NULL, _IOLBF, BUFSIZ) != 0)
    error (EXIT_FAILURE, errno, "setvbuf(), stderr");
  printf ("Content-Type: text/plain\n\n");
  if (fflush (stdout) == EOF)
    error (EXIT_FAILURE, errno, "fflush()");
  for (;;)
    {
      size = fread (buf,1, BUFSIZ, stdin);
      if (size == 0)
        {
          if (feof (stdin) != 0)
            goto quit;
          else
            error (EXIT_FAILURE, errno, "fread(), stdin");
        }
      size = fwrite (buf, 1, size, stdout);
      if (size == 0)
        error (EXIT_FAILURE, errno, "write(), stdout");
    }
 quit:
  fflush (stdout);
  return EXIT_SUCCESS;
}


这是相应的html形式;

<html>
  <head>
    <title>Form</title>
  </head>
  <body>
    <form action="form-process.cgi" method="post">
      input_a: <input name="input_a" type="text"><br>
      input_b: <input name="input_b" type="text"><br>
      <input type="submit" value="Submit">
    </form>
  </body>
</html>

最佳答案

您的程序尝试从其标准输入中读取数据,直到到达结束为止。当您从文件重定向输入时,这很好,但是对于CGI程序是不合适的。当到达请求主体的末尾时,运行CGI的Web服务器没有义务在输入中发出文件结束信号。如果没有,则您的程序将在fread()中无限期地阻塞。

有几个原因可能导致在请求正文末尾未发出EOF信号。 RFC明确地假设存在扩展数据,但是服务器将CGI的标准输入直接连接到将要发出请求的网络套接字也是合理的。在此之前,除非客户端关闭它,否则通常不会在其中检测到EOF。连接结束时,许多客户端在请求之间不执行此操作,其余客户端在收到响应后才执行其他操作。

因此,RFC 3875中的CGI规范说“即使有更多数据可用,脚本也绝不能尝试读取超过CONTENT_LENGTH个字节”(4.2节)。假设请求指定一个,则通过该名称的环境变量将CONTENT_LENGTH传送到脚本。您的CGI读取的字节数不得超过变量指定的字节数,并且,如果根本未指定内容长度,则它不得读取任何字节数。另一方面,不需要CGI读取整个请求正文或全部内容。

关于c - 从stdin/stdout读/写时,CGI程序超时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51699016/

10-13 08:13