1

在 Apache2 提供的 CGI 环境中,我使用 C 编写的 cgi 可执行文件

cgi.c:

#define         MY_SIZE                 102400
#define         MY_SIZE_OUT             (2 + (MY_SIZE * 2))

    int main()
{
char          buf[SIZE + 2];
int           n;

if (write(1, "Content-type: text/html\n\n", 25) == -1)
        {
          puts("An internal error occured, please report the bug #005");
          goto EXIT;
        }
      if ((n = read(0, buf, MY_SIZE)) == -1)
        {
          puts("An internal error occured, please report the bug #004");
          goto EXIT;
        }

      buf[n] = '\n';
      buf[n + 1] = 0;

      printf("Size of input = %i |--| |%s| max size = %i\n", n, buf, MY_SIZE);

     EXIT:
      return 1;
}

我的 POST 请求由 Ajax 代码发送:

ajaxRequest.onreadystatechange = function(){
            if(ajaxRequest.readyState == 4){
                var text;
                var exp;
            text = ajaxRequest.responseText;

            exp = new RegExp("([^ ]+)", "g");
            text = text.replace(exp, "<a class='wd' onClick='man_wd(this);'>$1</a>");
            document.getElementById("out").innerHTML = text;
            }
 }

  document.getElementById("out").innerHTML = "Processing...";
  ajaxRequest.open("POST", "cgi-bin/a.cgi", true);
  ajaxRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 ajaxRequest.setRequestHeader("Content-length", 5 + document.forms['f_main'].ta_in.value.length);
 ajaxRequest.setRequestHeader("Connection", "close");

  ajaxRequest.send(getPrefix() + " " + document.forms['f_main'].ta_in.value);

我的问题是,当我发送一个包含 N 个以上字符的请求时,我的 CGI 可执行文件读取最多 1060 个字符,即使 MY_SIZE 值为 102400。

我遇到了 php.ini 但限制 POST 大小为 8Mb

有人有想法吗?

4

1 回答 1

0

read手册页:

read() 尝试将文件描述符 fd 中的 count 个字节读入缓冲区,从 buf 开始。

因此,可能需要多次调用 read。

Unix Network Programming Vol 1 中,Stevens 建议使用这个包装器来阅读:

ssize_t readn (int fd, void *vptr, size_t n)
{
    size_t ret;
    size_t nleft;
    ssize_t nread;
    char *ptr;

    /* Initialize local variables */
    ptr = (char*)vptr;
    nleft = n;
    while (nleft > 0)
    {
        if ((nread = read (fd, ptr, nleft)) < 0)
        {
            if (errno == EINTR)
            {
                /* Read interrupted by system call, call read() again */
                nread = 0;
            }
            else
            {
                /* Other type of errors, return */
                return -1;
            }
        }
        else if (nread == 0)
        {
            /* No more data to read, exit */
            break;
        }

        /* Update counters and call read again */
        nleft -= nread;
        ptr += nread;
    }
    ret = n - nleft;

    return ret;
}

它多次调用 read 并且仅在读取所需数量的数据或输入真正结束时停止。

于 2012-12-11T16:10:10.743 回答