libevent踩坑之evhttp正确处理POST数据带源码

 最近使用这个evhttp做个小玩意,需要接受POST数据,网上流传的方法是:char *post_data = (char *) EVBUFFER_DATA(req->input_buffer);

这是一个坑,这里因为evhttp的处理机制问题,他读取的是evhttp预留的整个内存空间的内容,这样就会造成你获取到正确内容后面跟着一堆垃圾内容。

普通处理还好,遇到加密解密就头疼了,参考了下面大神的办法,完美处理。

转载自:http://blog.sina.com.cn/s/blog_a82c4d0a01010yur.html

evhttp是libevent提供的一个轻量级的基于消息驱动的HTTP Server。

在使用过程中,发现找不到接口访问POST的消息体中的数据。难道evhttpd不支持POST还是需要自已单独处理?
咱们先来看一下GET请求的操作:
例如:
http://www.m.com/?name=ok

evhttp_request_uri: 解析HTTP请求中的ur,得到/?name=ok
evhttp_parse_query: 解析名值对,得到一个evkeyvalq结构,里面包含了键值数据.

evhttp_request 结构:

[原创]evhttp处理POST方法数据带源码

简单实现代码如下:

//解析URI的参数(即GET方法的参数)
char *decode_uri = strdup((char*) evhttp_request_uri(req));
struct evkeyvalq http_query_get;
evhttp_parse_query(decode_uri, &http_query_get);
free(decode_uri);
const char *http_get_name = evhttp_find_header(&http_query_get, "name");

然后看POST,读取input_buffer数据时,发现与GET方法时evhttp_request_uri得到的数据格式不一样。
所以咱们尝试将格式处理成一致,然后用evhttp_parse_query解析。

简单实现代码如下:

//获取POST方法的数据
struct evkeyvalq http_query_post;
char decode_post_uri[1024] = {0};
int buffer_data_len = EVBUFFER_LENGTH(req->input_buffer);
char *post_data = (char *) malloc(buffer_data_len + 1);
memset(post_data, ‘\0’, buffer_data_len + 1);
memcpy(post_data, EVBUFFER_DATA(req->input_buffer), buffer_data_len);
sprintf(decode_post_uri,"/?%s",post_data);  //处理数据格式
evhttp_parse_query(decode_post_uri, &http_query_post);
const char *http_post_name = evhttp_find_header(&http_query_post, "name");

也许evhttp不提供直接接口的因为,应该就是留给开发者按标准格式处理数据,然后用evhttp_parse_query解析完成。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注