|
|
@ -6,6 +6,20 @@
|
|
|
|
#include <hiredis/adapters/libevent.h>
|
|
|
|
#include <hiredis/adapters/libevent.h>
|
|
|
|
#include <jansson.h>
|
|
|
|
#include <jansson.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct server *
|
|
|
|
|
|
|
|
server_new(const char *filename) {
|
|
|
|
|
|
|
|
struct server *s = calloc(1, sizeof(struct server));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s->cfg = conf_read(filename);
|
|
|
|
|
|
|
|
s->base = event_base_new();
|
|
|
|
|
|
|
|
s->http = evhttp_new(s->base);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
connectCallback(const redisAsyncContext *c) {
|
|
|
|
connectCallback(const redisAsyncContext *c) {
|
|
|
|
((void)c);
|
|
|
|
((void)c);
|
|
|
@ -79,3 +93,58 @@ server_copy(const struct server *s) {
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
on_request(struct evhttp_request *rq, void *ctx) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char *uri = evhttp_request_uri(rq);
|
|
|
|
|
|
|
|
struct server *s = ctx;
|
|
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!s->ac) { /* redis is unavailable */
|
|
|
|
|
|
|
|
printf("503\n");
|
|
|
|
|
|
|
|
evhttp_send_reply(rq, 503, "Service Unavailable", NULL);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* check that the command can be executed */
|
|
|
|
|
|
|
|
switch(rq->type) {
|
|
|
|
|
|
|
|
case EVHTTP_REQ_GET:
|
|
|
|
|
|
|
|
ret = cmd_run(s, rq, 1+uri, strlen(uri)-1);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case EVHTTP_REQ_POST:
|
|
|
|
|
|
|
|
ret = cmd_run(s, rq,
|
|
|
|
|
|
|
|
(const char*)EVBUFFER_DATA(rq->input_buffer),
|
|
|
|
|
|
|
|
EVBUFFER_LENGTH(rq->input_buffer));
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
printf("405\n");
|
|
|
|
|
|
|
|
evhttp_send_reply(rq, 405, "Method Not Allowed", NULL);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
|
|
|
|
evhttp_send_reply(rq, 403, "Forbidden", NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
server_start(struct server *s) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ignore sigpipe */
|
|
|
|
|
|
|
|
#ifdef SIGPIPE
|
|
|
|
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* start http server */
|
|
|
|
|
|
|
|
evhttp_bind_socket(s->http, s->cfg->http_host, s->cfg->http_port);
|
|
|
|
|
|
|
|
evhttp_set_gencb(s->http, on_request, s);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* attach hiredis to libevent base */
|
|
|
|
|
|
|
|
webdis_connect(s);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* loop */
|
|
|
|
|
|
|
|
event_base_dispatch(s->base);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|