evhttp接口说明
evhttp *evhttp_new(struct event_base *base);
void evhttp_free(struct evhttp *http);
int evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port);
void evhttp_set_gencb(struct evhttp *http, void (*cb)(struct evhttp_request *, void *), void *arg);
evhttp_uri *evhttp_request_get_evhttp_uri(const struct evhttp_request *req);
const char *evhttp_request_get_uri(const struct evhttp_request *req);
enum evhttp_cmd_type evhttp_request_get_command(const struct evhttp_request *req);
evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req);
evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req);
int evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *value);
struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req);
void evhttp_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *databuf);
Http Server
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/http.h>
#include <event2/keyvalq_struct.h>
#include <event2/buffer.h>
using namespace std;
#defin ROOTDIR "."
void http_cb(struct evhttp_request *req, void *arg)
{
const char *uri = evhttp_request_get_uri(req);
cout << "uri:" << uri << endl;
string cmdtype;
switch(evhttp_request_get_command(req))
{
case EVHTTP_REQ_GET:
cmdtype = "GET";
break;
case EVHTTP_REQ_POST:
cmdtype = "POST";
break;
default
break;
}
evkeyvalq *headers = evhttp_request_get_input_headers(req);
cout << "headers:" << endl;
for(evkeyvalq *i = headers->tqh_first; i != NULL; i = i->next.tqe_next)
{
cout << i->key << ":" << i->value << endl;
}
evbuffer *evb = evhttp_request_get_input_buffer(req);
char buf[1024] = {0};
while(evbuffer_get_length(evb))
{
int len = evbuffer_remove(evb, buf, sizeof(buf)-1);
if(len > 0)
{
buf[len] = 0;
cout << buf << endl;
}
}
string filepath = ROOTDIR;
filepath += uri;
if(strcmp(uri, "/")==0)
{
filepath += "index.html";
}
evkeyvalq *outheaders = evhttp_request_get_output_headers(req);
int pos = filepath.rfind('.');
string postfix = filepath.substr(pos+1, filepath.size() - (pos + 1));
if(postfix == "jpg" || postfix == "gif" || postfix == "png")
{
string tmp = "image/" + postfix;
evhttp_add_header(outheaders, "Content-Type", tmp.c_str());
}
else if(postfix == "zip")
{
evhttp_add_header(outheaders, "Content-Type", "application/zip");
}
else if(postfix == "html")
{
evhttp_add_header(outheaders, "Content-Type", "text/html");
}
else if(postfix == "css")
{
evhttp_add_header(outheaders, "Content-Type", "text/css");
}
FILE *fp = fopen(filepath.c_str(), "rb");
if(fp)
{
evbuffer *outbuf = evhttp_request_get_output_buffer(req);
int len = 0;
char data[1024] = {0};
do
{
len = fread(data, 1, sizeof(data), fp);
evbuffer_add(outbuf, data, len);
}while(len > 0);
fclose(fp);
evhttp_send_reply(req, HTTP_OK, "success", outbuf);
}
else
{
evhttp_send_reply(req, HTTP_NOTFOUND, "", 0);
}
}
int main()
{
event_base *base = event_base_new();
evhttp *evh = evhttp_new(base);
int ret = evhttp_bind_socket(evh, "127.0.0.1", 8080);
if(ret)
cerr << "evhttp_bind_socket error" << endl;
evhttp_set_gencb(evh, http_cb, 0);
event_base_dispatch(base);
event_base_free(base);
evhttp_free(evh);
return 0;
}
Http Client
void con_cb(struct evhttp_request *req, void *ctx)
{
event_base *base = (event_base *)ctx;
if(req == NULL)
{
int errcode = EVUTIL_SOCKET_ERROR();
cout << evutil_socket_error_to_string(errcode) << endl;;
return;
}
const char *path = evhttp_request_get_uri(req);
string filepath = ".";
filepath += path;
FILE *fp = fopen(filepath.c_str(), "wb");
if(!fp)
{
cout << "file error" << endl;
}
cout << evhttp_request_get_response_code(req) << endl;
cout << evhttp_request_get_response_code_line(req) << endl;
char buf[1024] = {0};
evbuffer *input = evhttp_request_get_input_buffer(req);
for(;;)
{
int len = evbuffer_remove(input, buf, sizeof(buf));
if(len <=0 )
break;
if(!fp)
continue;
fwrite(buf, 1, len, fp);
}
if(fp)
fclose(fp);
event_base_loopbreak(base);
}
void HttpGet()
{
event_base *base = event_base_new();
string url = "http://127.0.0.1:8080/index.html";
evhttp_uri *uri = evhttp_uri_parse(url.c_str());
const char *scheme = evhttp_uri_get_scheme(uri);
cout << scheme << endl;
const char *host = evhttp_uri_get_host(uri);
cout << host << endl;
int port = evhttp_uri_get_port(uri);
if(port < 0)
{
if(strcmp(scheme, "http")==0)
{
port = 80;
}
}
cout << port << endl;
const char *path = evhttp_uri_get_path(uri);
if(!path || strlen(path)==0)
{
path = "/";
}
cout << path << endl;
const char *query = evhttp_uri_get_query(uri);
if(query)
{
cout << query << endl;
}
bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
evhttp_connection *evcon = evhttp_connection_base_bufferevent_new(base, NULL, bev, host, port);
evhttp_request *req = evhttp_request_new(con_cb, base);
evkeyvalq *headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "Host", host);
evhttp_make_request(evcon, req, EVHTTP_REQ_GET, path);
event_base_dispatch(base);
event_base_free(base);
}
void HttpPost()
{
event_base *base = event_base_new();
string url = "http://127.0.0.1:8080/index.html";
evhttp_uri *uri = evhttp_uri_parse(url.c_str());
const char *scheme = evhttp_uri_get_scheme(uri);
cout << scheme << endl;
const char *host = evhttp_uri_get_host(uri);
cout << host << endl;
int port = evhttp_uri_get_port(uri);
if(port < 0)
{
if(strcmp(scheme, "http")==0)
{
port = 80;
}
}
cout << port << endl;
const char *path = evhttp_uri_get_path(uri);
if(!path || strlen(path)==0)
{
path = "/";
}
cout << path << endl;
const char *query = evhttp_uri_get_query(uri);
if(query)
{
cout << query << endl;
}
bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
evhttp_connection *evcon = evhttp_connection_base_bufferevent_new(base, NULL, bev, host, port);
evhttp_request *req = evhttp_request_new(con_cb, base);
evkeyvalq *headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "Host", host);
evbuffer *output = evhttp_request_get_output_buffer(req);
evbuffer_add_printf(output, "id=%d&name=%s", 1, "abc");
evhttp_make_request(evcon, req, EVHTTP_REQ_POST, path);
event_base_dispatch(base);
event_base_free(base);
}
int main()
{
HttpGet();
HttpPost();
return 0;
}