【问题标题】:CGI Environment, Read max size is fixed?CGI 环境,读取最大大小是固定的吗?
【发布时间】:2012-11-29 05:05:58
【问题描述】:

在 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 个以上字符的请求时,即使 MY_SIZE 值为 102400,我的 CGI 可执行文件最多读取 1060 个字符。

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

有人有想法吗?

【问题讨论】:

    标签: linux apache cgi


    【解决方案1】:

    来自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;
    }
    

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

    【讨论】:

    • “尝试阅读”的哪一部分不清楚?在读取整个输入之前可以中断读取。男人 2 读
    • 显然我没问题,但我不能投票,因为我没有足够的声誉。下次我会做的。非常感谢您的帮助。
    猜你喜欢
    • 2021-12-01
    • 2019-01-11
    • 1970-01-01
    • 2023-03-12
    • 2010-11-07
    • 2019-05-19
    • 2013-12-24
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多