最近使用这个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 结构:
简单实现代码如下:
//解析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解析完成。