Last active
May 16, 2019 07:40
-
-
Save jige003/615a862d02127ee69f620ed7815fc304 to your computer and use it in GitHub Desktop.
libevent http example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************************************************************* | |
> File Name: http.c | |
> Author: jige003 | |
> Created Time: Thu 16 May 2019 01:13:57 PM CST | |
************************************************************************/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <event.h> | |
#include <evhttp.h> | |
#include <signal.h> | |
#include <getopt.h> | |
#include <string.h> | |
#include <jansson.h> | |
#include <sys/types.h> | |
#define DEFAULT_ADDR "127.0.0.1" | |
#define DEFAULT_PORT 8000 | |
#define Server "jige003" | |
#define BUFSIZE 1024 | |
void xfree(void*ptr); | |
void default_handler(struct evhttp_request *req, void *arg); | |
void json_handler(struct evhttp_request *req, void *arg); | |
void send_json_resp(struct evhttp_request *req, json_t *req_json, struct event_base* base); | |
void xfree(void *ptr){ | |
if (ptr != ((void*)0)) free(ptr); | |
} | |
void default_handler(struct evhttp_request *req, void *arg){ | |
const char *uri; | |
uri = evhttp_request_uri(req); | |
evhttp_add_header(req->output_headers, "Server", Server); | |
evhttp_add_header(req->output_headers, "Content-Type", "text/plain; charset=UTF-8"); | |
//evhttp_add_header(req->output_headers, "Connection", "close"); | |
struct evbuffer *buf; | |
buf = evbuffer_new(); | |
evbuffer_add_printf(buf, "404 Not Found\n"); | |
evbuffer_add_printf(buf, "Yrequest uri is %s\n", uri); | |
evhttp_send_reply(req, HTTP_NOTFOUND, "Not Found", buf); | |
evbuffer_free(buf); | |
} | |
void json_handler(struct evhttp_request *req, void *arg){ | |
struct evbuffer *req_buf; | |
int req_len; | |
char *tmp_req_buf; | |
char error_text[BUFSIZE]; | |
struct event_base *base = (struct event_base *)arg; | |
req_buf = evhttp_request_get_input_buffer(req); | |
req_len = evbuffer_get_length(req_buf); | |
tmp_req_buf = (char *)malloc(req_len * sizeof(char)); | |
memset(tmp_req_buf, 0, req_len); | |
evbuffer_copyout(req_buf, tmp_req_buf, req_len); | |
json_t *req_json; | |
json_error_t error; | |
req_json = json_loadb(tmp_req_buf, req_len, 0, &error); | |
xfree(tmp_req_buf); | |
if (req_json == NULL){ | |
sprintf(error_text, "Iuput error: line: %d : %s\n", error.line, error.text); | |
fprintf(stderr, "%s\n", error_text); | |
}else{ | |
tmp_req_buf = json_dumps(req_json, JSON_INDENT(0)); | |
fprintf(stderr, "request json:\n %s\n", tmp_req_buf); | |
xfree(tmp_req_buf); | |
send_json_resp(req, req_json, base); | |
json_decref(req_json); | |
} | |
//evbuffer_free(req_buf); | |
return; | |
} | |
void send_json_resp(struct evhttp_request *req, json_t *req_json, struct event_base* base){ | |
json_t *resp_json; | |
json_t *_j_uri; | |
char * resp_str_buf; | |
//resp_json = json_object(); | |
resp_json = req_json; | |
_j_uri = json_string(evhttp_request_uri(req)); | |
json_object_set_new(resp_json, "uri", _j_uri); | |
resp_str_buf = json_dumps(resp_json, JSON_INDENT(0)); | |
//json_decref(resp_json); | |
//evhttp_add_header(req->output_headers, "Proxy-Connection", "keep-alive"); | |
evhttp_add_header(req->output_headers, "Content-Type", "application/json"); | |
struct evbuffer *resp_buf; | |
resp_buf = evbuffer_new(); | |
evbuffer_add_printf(resp_buf, "%s\n", resp_str_buf); | |
evhttp_send_reply(req, HTTP_OK, "OK", resp_buf); | |
xfree(resp_str_buf); | |
evbuffer_free(resp_buf); | |
} | |
int main(int c, char **v){ | |
struct options { | |
char *addr; | |
short port; | |
} o; | |
memset(&o, 0, sizeof(o)); | |
o.port = DEFAULT_PORT; | |
int opt; | |
while ((opt = getopt(c, v, "s:p:")) != -1) { | |
switch(opt){ | |
case 's': o.addr = strdup(optarg); break; | |
case 'p': o.port = atoi(optarg); break; | |
default : | |
fprintf(stderr, "Unknown option %c\n", opt); | |
goto end; | |
} | |
} | |
if (o.addr == NULL) { | |
o.addr = strdup(DEFAULT_ADDR); | |
} | |
struct event_base *base = event_base_new(); | |
struct evhttp *http_server = NULL; | |
http_server = evhttp_new(base); | |
evhttp_bind_socket(http_server, o.addr, o.port); | |
fprintf(stderr, "server started, listen %s:%d\n", o.addr, o.port); | |
evhttp_set_gencb(http_server, default_handler ,(void *)base); | |
evhttp_set_cb(http_server, "/json" ,json_handler, (void *)base); | |
event_base_dispatch(base); | |
evhttp_free(http_server); | |
event_base_free(base); | |
fprintf(stderr, "server exit\n"); | |
end: | |
xfree(o.addr); | |
return (0); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
gcc -g -o http http.c -levent -ljansson -lpthread |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- wrk -t100 -c400 -d5s --script=post.lua --latency http://localhost:8000/json | |
wrk.method = "POST" | |
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded" | |
wrk.body = '{"a": "b", "c": [1,2], "d": {"f": "e"}}' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment