【发布时间】:2010-07-14 02:07:47
【问题描述】:
我非常需要一种方法来挖掘潜在的大量 CGI 提供的 POST 数据。
读取 GET 数据没什么大不了的,因为我可以根据需要随时重新请求 QUERY_STRING 环境变量,但使用通过 stdin 提供的 POST 数据。我只能读取一次,并且必须将其存储在某个地方。
我当前的方法包括读取临时文件中的全部 POST 数据,该文件将在程序退出时删除并扫描它以找到我想要找到的键。 在 GET 解析方法中,我可以只在 QUERY_STRING 上使用 strtok(),因为 GET 数据的限制非常低,因此可以安全地在 RAM 中获取,但 POST 数据可以是从空到“name=Bob”到 4 Gigabye 电影的任何内容文件。
所以,这是我目前的方法:
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;
}
这确实有效,我可以调用get_post_data("user_password", pass, sizeof(pass));,检查返回值(0 = 数据长度),但它似乎过于肥胖。我的意思是.. 我想搜索的每个 POST 参数的巨大 IO 开销只是为了不让我的 RAM 中的整个字符串用于可能上传的大文件?
Stackoverflow 是怎么想的?
【问题讨论】:
标签: c parsing post cgi storage