关于如果通过libevent写一个http服务参看《使用libevent实现简单http服务(一)》,此处仅对请求处理函数做了更改,源码如下:
......
std::string add(const char *uri_str)
{
std::string reply;
evkeyvalq keyvals;
evhttp_parse_query(uri_str, &keyvals);
do {
auto str = evhttp_find_header(&keyvals, "a");
if (str == nullptr) break;
auto a = atoi(str);
str = evhttp_find_header(&keyvals, "b");
if (str == nullptr) break;
auto b = atoi(str);
auto c = a + b;
reply = std::to_string(c);
} while (false);
evhttp_clear_headers(&keyvals);
return reply;
}
void process(struct evhttp_request *ctx)
{
std::string reply;
const char *uri_str = nullptr;
evbuffer *evbuf = nullptr;
evhttp_add_header(evhttp_request_get_output_headers(ctx), "Content-Type", "text/html");
switch (evhttp_request_get_command(ctx)) {
case EVHTTP_REQ_GET:
uri_str = evhttp_request_get_uri(ctx);
if (strncmp(uri_str, "/add", 4) == 0) {
reply = add(uri_str);
}
if (!reply.empty()) {
evbuf = evbuffer_new();
if (evbuf == nullptr) break;
evbuffer_add(evbuf, reply.c_str(), reply.size());
evhttp_send_reply(ctx, 200, "OK", evbuf);
}
else {
evhttp_send_error(ctx, 400, "Document Not Found !");
}
break;
case EVHTTP_REQ_POST:
case EVHTTP_REQ_HEAD:
case EVHTTP_REQ_PUT:
case EVHTTP_REQ_DELETE:
case EVHTTP_REQ_OPTIONS:
case EVHTTP_REQ_TRACE:
case EVHTTP_REQ_CONNECT:
case EVHTTP_REQ_PATCH:
evhttp_send_error(ctx, 400, "Document Not Found !");
break;
}
fprintf(stdout, "INFO process %d recv request!\n", m_identify);
if (evbuf != nullptr)
evbuffer_free(evbuf);
}
......
使用libevent解析get请求参数,一定要注意一个问题,即调用evhttp_parse_query后,一定要调用evhttp_clear_headers释放结果,否则会产生内存泄漏。