读取CGI POST数据是最有效的方法
我非常需要一种方法来挖掘潜在的大量CGI提供的POST数据 读取GET数据没什么大不了的,因为我可以随时重新请求读取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
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只是杯水车薪。:)