简介
在libevent中,封装了http模块,包括很多相关的接口。
一个http server 的创建步骤
1、初始化event模块
2、启动http服务端
3、设置事件处理函数
4、监听事件
常用接口(按调用顺序排列)
函数名 | 介绍 |
---|---|
struct event_base * event_init(void) | 创建一个event_base,没有event_base是不能创建evhttp的 |
struct evhttp * evhttp_start(const char *address, ev_uint16_t port) | 传入ip和端口创建一个http server |
void evhttp_set_timeout(struct evhttp* http, int timeout) | 设置超时时间 |
int evhttp_set_cb(struct evhttp *http, const char *uri,void (*cb)(struct evhttp_request *, void *), void *cbarg) | 设置不同访问路径对应的回调函数 |
int evhttp_set_gencb(struct evhttp *http,void (*cb)(struct evhttp_request *, void *), void *cbarg) | 设置默认回调函数 |
int event_dispatch(void) | 循环检测时间发生 |
另外还有一些在回调函数中用到的接口
函数 | 介绍 |
---|---|
evhttp_request_get_evhttp_uri(req) | 获取一个http请求的uri |
char * post_data=(char*)EVBUFFER_DATA(req->input_buffer) | 获取http请求的请求体 |
evhttp_uri_join(const_cast<struct evhttp_uri*>(evhttp_uri),url,2020) | 将解析数据中的uri部分连接在一起,形成uri - reference。 |
char post_data=(char)EVBUFFER_DATA(req->input_buffer) | 把请求体转为文本 |
evbuffer_add_printf(retbuff,“Test Get is ok\n”) | 给http响应报文输入数据 |
evhttp_send_reply(req,HTTP_OK,“Client is ok”,retbuff) | 发送http响应报文 |
evbuffer_free(retbuff) | 释放响应报文的缓冲 |
evhttp_uri_get_path(evhttp_uri) | 从之前提取的uri中获取path |
evhttp_uri_get_query(evhttp_uri) | 从之前提取的uri中获取query |
简单的使用
一个用libevent 的evhttp实现的简单http服务器,具有默认uri响应和路径为get和post的响应,并在回调函数中解析http请求内容。
#include<stdio.h>
#include<stdlib.h>
#include<evhttp.h>
#include<event.h>
#include<string.h>
#include"event2/http.h"
#include"event2/event.h"
#include"event2/buffer.h"
#include"event2/bufferevent.h"
#include"event2/bufferevent_compat.h"
#include"event2/http_struct.h"
#include"event2/util.h"
#include"event2/listener.h"
void Test_Get(struct evhttp_request *req,void *arg){
{
//parse
}
struct evbuffer* retbuff=evbuffer_new();
if(retbuff==NULL){
printf("retbuff is NULL\n");
return;
}
evbuffer_add_printf(retbuff,"Test Get is ok\n");
evhttp_send_reply(req,HTTP_OK,"Client is ok",retbuff);
evbuffer_free(retbuff);
}
void Test_Post(struct evhttp_request *req,void* arg){
//get data evbuffer_pullup()
const struct evhttp_uri* uri=evhttp_request_get_evhttp_uri(req);
char * post_data=(char*)EVBUFFER_DATA(req->input_buffer);
const char* path=evhttp_uri_get_path(uri);
const char* query=evhttp_uri_get_query(uri);
printf("path:%s\n",path);
printf("query:%s\n",query);
printf("post data:%s\n",post_data);
struct evbuffer* retbuff=evbuffer_new();
if(retbuff==NULL){
printf("retbuff is NULL\n");
return;
}
evbuffer_add_printf(retbuff,"Test Post is ok\n");
evbuffer_add_printf(retbuff,"path is [%s] and post body is [%s]\n",path,post_data);
evhttp_send_reply(req,HTTP_OK,"Client is ok",retbuff);
evbuffer_free(retbuff);
}
void cb_gen(struct evhttp_request* req,void * arg){
const struct evhttp_uri* evhttp_uri=evhttp_request_get_evhttp_uri(req);
char url[2020];
evhttp_uri_join(const_cast<struct evhttp_uri*>(evhttp_uri),url,2020);
char *post_data=(char*)EVBUFFER_DATA(req->input_buffer);
printf("url: %s\n",url);
printf("path: %s\n",evhttp_uri_get_path(evhttp_uri));
printf("query: %s\n",evhttp_uri_get_query(evhttp_uri));
printf("data: %s\n",post_data);
struct evbuffer* evbuf=evbuffer_new();
evbuffer_add_printf(evbuf,"url is [%s] and post body is [%s]\n",url,post_data);
evhttp_send_reply(req,HTTP_OK,"OK",evbuf);
evbuffer_free(evbuf);
}
int main(){
short http_port=8081;
event_init();
struct evhttp* http_server=evhttp_start(INADDR_ANY,http_port);
if(http_server==NULL){
printf("http server not started\n");
return -1;
}
evhttp_set_timeout(http_server,5);
evhttp_set_cb(http_server,"/post",Test_Post,NULL);
evhttp_set_cb(http_server,"/get",Test_Get,NULL);
evhttp_set_gencb(http_server,cb_gen,NULL);
event_dispatch();
evhttp_free(http_server);
return 0;
}