Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
读取CGI POST数据是最有效的方法_C_Parsing_Post_Cgi_Storage - Fatal编程技术网

读取CGI POST数据是最有效的方法

读取CGI POST数据是最有效的方法,c,parsing,post,cgi,storage,C,Parsing,Post,Cgi,Storage,我非常需要一种方法来挖掘潜在的大量CGI提供的POST数据 读取GET数据没什么大不了的,因为我可以随时重新请求QUERY\u字符串环境变量,但是使用通过stdin提供的POST数据。我只能读入一次,必须把它存放在某个地方 我目前的方法是读取一个临时文件中的全部POST数据,当程序退出时,这些数据将被删除,然后扫描它以找到我想要的密钥。 在GET解析方法中,我可以在查询字符串上使用strtok(),因为GET数据的限制非常低,所以在RAM中提取是安全的,但是POST数据可以是任何内容,从空到“n

我非常需要一种方法来挖掘潜在的大量CGI提供的POST数据

读取GET数据没什么大不了的,因为我可以随时重新请求
QUERY\u字符串
环境变量,但是使用通过
stdin提供的POST数据。我只能读入一次,必须把它存放在某个地方

我目前的方法是读取一个临时文件中的全部POST数据,当程序退出时,这些数据将被删除,然后扫描它以找到我想要的密钥。 在GET解析方法中,我可以在查询字符串上使用strtok(),因为GET数据的限制非常低,所以在RAM中提取是安全的,但是POST数据可以是任何内容,从空到“name=Bob”,再到4Gbye电影文件

下面是我目前的做法:

int get_post_data(const char *s_key, char *target, size_t target_size)
{
   FILE *tmp;
   int ret_val = -1;

   /* postdata_temp = global variable containing the temporary file name */
   if ((tmp = fopen(postdata_tempfile, "r")) == NULL)
      return -1;
   else
   {
      char *buffer = NULL;
      char *temp_buffer = NULL;
      int buffer_size;
      int i;

      if ((buffer = malloc(BUFFER_SIZE)) == NULL)
         return -1;

      memset(buffer, 0, sizeof(BUFFER_SIZE));
      buffer_size = BUFFER_SIZE;

      for (i = 0;; i++)
      {
         int c = fgetc(tmp);

         if ((c == '&') || feof(tmp))
         {
            char *key = strtok(buffer, "=");
            char *val = strtok(NULL, "");            

            if (key)
            {
               if (strcmp(s_key, key) == 0)
               {
                  if (val)
                  {
                     strncpy(target, val, target_size);
                     ret_val = strlen(val);
                  }
                  else
                  {
                     target = NULL;
                     ret_val = 0;
                  }

                  break;
               }
            }

            if (feof(tmp))
               break;

            memset(buffer, 0, buffer_size);
            i = -1; /* because it will be 0 when the fgetc() is called the 
                     * next time */
         }
         else
         {
            if (!(i < buffer_size))
            {
               buffer_size += BUFFER_SIZE;

               if ((temp_buffer = realloc(buffer, buffer_size)) == NULL)
               {
                  free(temp_buffer);
                  free(buffer);
                  target = NULL;

                  return -1;
               }
               else
                  buffer = temp_buffer;
            }

            buffer[i] = c;
         }

      }

      free(buffer);

      // printf("Final buffer size: %d<br />\n", buffer_size);
   }

   fclose(tmp);

   return ret_val;
}
int get_post_数据(常量字符*s_键,字符*target,大小\u t目标\u大小)
{
文件*tmp;
int ret_val=-1;
/*postdata_temp=包含临时文件名的全局变量*/
if((tmp=fopen(postdata_tempfile,“r”))==NULL)
返回-1;
其他的
{
char*buffer=NULL;
char*temp_buffer=NULL;
int缓冲区大小;
int i;
if((缓冲区=malloc(缓冲区大小))==NULL)
返回-1;
memset(buffer,0,sizeof(buffer_SIZE));
缓冲区大小=缓冲区大小;
对于(i=0;i++)
{
int c=fgetc(tmp);
if((c='&')| | feof(tmp))
{
char*key=strtok(缓冲区“=”);
char*val=strtok(空,“”);
如果(关键)
{
如果(strcmp(s_键,键)==0)
{
if(val)
{
strncpy(目标、val、目标大小);
ret_val=strlen(val);
}
其他的
{
target=NULL;
ret_val=0;
}
打破
}
}
if(feof(tmp))
打破
memset(缓冲区,0,缓冲区大小);
i=-1;/*因为当调用fgetc()时,它将是0
*下次*/
}
其他的
{
如果(!(i<缓冲区大小))
{
缓冲区大小+=缓冲区大小;
if((临时缓冲区=realloc(缓冲区,缓冲区大小))==NULL)
{
空闲(临时缓冲);
自由(缓冲);
target=NULL;
返回-1;
}
其他的
缓冲区=临时缓冲区;
}
缓冲区[i]=c;
}
}
自由(缓冲);
//printf(“最终缓冲区大小:%d
\n”,缓冲区大小); } fclose(tmp); 返回返回值; }
这确实有效,我可以调用
get_post_数据(“user_password”,pass,sizeof(pass)),检查返回值(0=数据长度),但它似乎太胖了。我是说。。我想搜索的每个POST参数都有巨大的IO开销,只是为了不让整个字符串都在我的RAM中,用于上传可能较大的文件


Stackoverflow是怎么想的?

我认为如果拒绝大于设置限制(比如2MB)的POST请求会更容易

这样:

  • 您有一个可管理的数据块要处理
  • 您可以防止恶意4GB POST请求

我认为拒绝大于设定限制(比如2MB)的POST请求会更容易

这样:

  • 您有一个可管理的数据块要处理
  • 您可以防止恶意4GB POST请求

如果您想避免将大文件加载到RAM中,可以使用内存映射文件-不可移植,但这是正确的方法。如果您的平台是POSIX,则可以使用
mmap()
来实现此目的


顺便说一句,我没有完全阅读或测试您的代码,但我想知道使用
strok()
是否是正确的做法,因为它会在运行时破坏数据。如果您的数据可能是二进制文件,我还想知道如何使用
str…()
函数,但我不知道CGI部分如何工作,所以您可能就在那里。

如果您想避免将大文件加载到RAM中,可以使用内存映射文件-不可移植,但这是正确的方法。如果您的平台是POSIX,则可以使用
mmap()
来实现此目的


顺便说一句,我没有完全阅读或测试您的代码,但我想知道使用
strok()
是否是正确的做法,因为它会在运行时破坏数据。如果您的数据可能是二进制文件,我还想知道如何使用
str…()
函数,但我不知道CGI部分如何工作,所以您可能就在那里。

数据以“key=value”的形式到达,我使用
strok()
来分割键和值。实际上,只有值是二进制的,并且将不经修改地传递给调用者:)@LukeN:有任何帮助吗?数据以“key=value”的形式到达,我使用
strtok()
来分割键和值。实际上,只有值是二进制的,并且将不经修改地传递给调用方:)@LukeN:这些有帮助吗?我尽量不限制我的程序可以接受什么。在这种特殊情况下(文本文章),2MB就足够了,但我编写模块的方式使我能够在任何情况下使用它们,就像上传文件,2MB只是杯水车薪。:)我尽量不限制我的程序可以接受的内容。在这种特殊情况下(文本文章),2MB就足够了,但我编写模块的方式使我能够在任何情况下使用它们,就像上传文件,2MB只是杯水车薪。:)