Merge branch 'master' into ry

master
Nicolas Favre-Felix 14 years ago
commit 9538f9f3f9

@ -33,6 +33,8 @@ curl -d "GET/hello" http://127.0.0.1:7379/
* Logs, with a configurable verbosity.
* Cross-origin requests, usable with XMLHttpRequest2 (Cross-Origin Resource Sharing - CORS).
* File upload with PUT.
* With the JSON output, the return value of INFO is parsed and transformed into an object.
* Optional daemonize.
# Ideas, TODO...
* Fix crash on ACL rejection.

@ -34,6 +34,7 @@ conf_read(const char *filename) {
conf->group = getgid();
conf->logfile = "webdis.log";
conf->verbosity = WEBDIS_NOTICE;
conf->daemonize = 0;
j = json_load_file(filename, 0, &error);
if(!j) {
@ -75,6 +76,8 @@ conf_read(const char *filename) {
if(tmp < 0) conf->verbosity = WEBDIS_ERROR;
else if(tmp > (int)WEBDIS_DEBUG) conf->verbosity = WEBDIS_DEBUG;
else conf->verbosity = (log_level)tmp;
} else if(strcmp(json_object_iter_key(kv), "daemonize") == 0 && json_typeof(jtmp) == JSON_TRUE) {
conf->daemonize = 1;
}
}

@ -15,6 +15,9 @@ struct conf {
char *http_host;
short http_port;
/* daemonize process, off by default */
int daemonize;
/* ACL */
struct acl *perms;

@ -45,6 +45,50 @@ json_reply(redisAsyncContext *c, void *r, void *privdata) {
free(jstr);
}
/**
* Parse info message and return object.
*/
static json_t *
json_info_reply(const char *s) {
const char *p = s;
size_t sz = strlen(s);
json_t *jroot = json_object();
/* TODO: handle new format */
while(p < s + sz) {
char *key, *val, *nl, *colon;
/* find key */
colon = strchr(p, ':');
if(!colon) {
break;
}
key = calloc(colon - p + 1, 1);
memcpy(key, p, colon - p);
p = colon + 1;
/* find value */
nl = strchr(p, '\r');
if(!nl) {
free(key);
break;
}
val = calloc(nl - p + 1, 1);
memcpy(val, p, nl - p);
p = nl + 1;
if(*p == '\n') p++;
/* add to object */
json_object_set_new(jroot, key, json_string(val));
free(key);
free(val);
}
return jroot;
}
static json_t *
json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) {
@ -61,6 +105,7 @@ json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) {
verb = strdup("");
}
switch(r->type) {
case REDIS_REPLY_STATUS:
case REDIS_REPLY_ERROR:
@ -72,7 +117,11 @@ json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) {
break;
case REDIS_REPLY_STRING:
json_object_set_new(jroot, verb, json_string(r->str));
if(strcasecmp(verb, "INFO") == 0) {
json_object_set_new(jroot, verb, json_info_reply(r->str));
} else {
json_object_set_new(jroot, verb, json_string(r->str));
}
break;
case REDIS_REPLY_INTEGER:

@ -187,10 +187,31 @@ on_possible_accept(int fd, short event, void *ctx) {
http_client_serve(c);
}
/* Taken from Redis. */
void
server_daemonize(void) {
int fd;
if (fork() != 0) exit(0); /* parent exits */
setsid(); /* create a new session */
/* Every output goes to /dev/null. */
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > STDERR_FILENO) close(fd);
}
}
void
server_start(struct server *s) {
if(s->cfg->daemonize) {
server_daemonize();
}
/* ignore sigpipe */
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);

@ -7,6 +7,8 @@
"http_host": "0.0.0.0",
"http_port": 7379,
"daemonize": false,
"acl": [
{
"disabled": ["DEBUG"]

Loading…
Cancel
Save