Skip to content

Instantly share code, notes, and snippets.

@jige003
Last active May 16, 2019 07:40
Show Gist options
  • Save jige003/615a862d02127ee69f620ed7815fc304 to your computer and use it in GitHub Desktop.
Save jige003/615a862d02127ee69f620ed7815fc304 to your computer and use it in GitHub Desktop.
libevent http example
/*************************************************************************
> 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);
}
all:
gcc -g -o http http.c -levent -ljansson -lpthread
-- 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