From a0b0c0cb3098960e99bb1bdaf56580dd21c29aa8 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Fri, 2 Sep 2011 22:57:26 +0100 Subject: [PATCH 1/7] Fixed pub/sub regression (Github issue #32) --- http.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/http.c b/http.c index 05efd33..4879a08 100644 --- a/http.c +++ b/http.c @@ -19,6 +19,7 @@ http_response_init(struct worker *w, int code, const char *msg) { r->code = code; r->msg = msg; r->w = w; + r->keep_alive = 0; /* default */ http_response_set_header(r, "Server", "Webdis"); @@ -137,7 +138,7 @@ http_response_write(struct http_response *r, int fd) { char *p; int i, ret; - r->keep_alive = 0; + /*r->keep_alive = 0;*/ r->out_sz = sizeof("HTTP/1.x xxx ")-1 + strlen(r->msg) + 2; r->out = calloc(r->out_sz + 1, 1); @@ -245,6 +246,7 @@ http_send_error(struct http_client *c, short code, const char *msg) { */ void http_response_set_keep_alive(struct http_response *r, int enabled) { + r->keep_alive = enabled; if(enabled) { http_response_set_header(r, "Connection", "Keep-Alive"); } else { @@ -277,6 +279,7 @@ http_response_write_chunk(int fd, struct worker *w, const char *p, size_t sz) { size_t out_sz; int chunk_size; struct http_response *r = http_response_init(w, 0, NULL); + r->keep_alive = 1; /* chunks are always keep-alive */ /* calculate format size */ chunk_size = sprintf(tmp, "%x\r\n", (int)sz); From ebe4282d4a1dd7f254eba72ca7e37892ae4e94e7 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Tue, 6 Sep 2011 13:25:21 +0100 Subject: [PATCH 2/7] Extracted chunk_format function --- formats/common.c | 7 ++++--- http.c | 43 +++++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/formats/common.c b/formats/common.c index f9dbcd0..43f137a 100644 --- a/formats/common.c +++ b/formats/common.c @@ -78,12 +78,13 @@ format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content http_response_set_header(resp, "Content-Type", ct); http_response_set_keep_alive(resp, 1); http_response_set_header(resp, "Transfer-Encoding", "chunked"); + http_response_set_body(resp, p, sz); http_response_write(resp, cmd->fd); + } else { + /* Asynchronous chunk write. */ + http_response_write_chunk(cmd->fd, cmd->w, p, sz); } - /* Asynchronous chunk write. */ - http_response_write_chunk(cmd->fd, cmd->w, p, sz); - } else { /* compute ETag */ char *etag = etag_new(p, sz); diff --git a/http.c b/http.c index 4879a08..9270892 100644 --- a/http.c +++ b/http.c @@ -132,6 +132,24 @@ http_schedule_write(int fd, struct http_response *r) { } +static char * +format_chunk(const char *p, size_t sz, size_t *out_sz) { + + char *out, tmp[64]; + int chunk_size; + + /* calculate format size */ + chunk_size = sprintf(tmp, "%x\r\n", (int)sz); + + *out_sz = chunk_size + sz + 2; + out = malloc(*out_sz); + memcpy(out, tmp, chunk_size); + memcpy(out + chunk_size, p, sz); + memcpy(out + chunk_size + sz, "\r\n", 2); + + return out; +} + void http_response_write(struct http_response *r, int fd) { @@ -191,9 +209,11 @@ http_response_write(struct http_response *r, int fd) { /* append body if there is one. */ if(r->body && r->body_len) { - r->out = realloc(r->out, r->out_sz + r->body_len); - memcpy(r->out + r->out_sz, r->body, r->body_len); - r->out_sz += r->body_len; + if(r->chunked) { + r->out = realloc(r->out, r->out_sz + r->body_len); + memcpy(r->out + r->out_sz, r->body, r->body_len); + r->out_sz += r->body_len; + } } /* send buffer to client */ @@ -275,26 +295,13 @@ http_send_options(struct http_client *c) { void http_response_write_chunk(int fd, struct worker *w, const char *p, size_t sz) { - char *out, tmp[64]; - size_t out_sz; - int chunk_size; struct http_response *r = http_response_init(w, 0, NULL); r->keep_alive = 1; /* chunks are always keep-alive */ - /* calculate format size */ - chunk_size = sprintf(tmp, "%x\r\n", (int)sz); - - out_sz = chunk_size + sz + 2; - out = malloc(out_sz); - memcpy(out, tmp, chunk_size); - memcpy(out + chunk_size, p, sz); - memcpy(out + chunk_size + sz, "\r\n", 2); - + /* format packet */ + r->out = format_chunk(p, sz, &r->out_sz); /* send async write */ - r->out = out; - r->out_sz = out_sz; - http_schedule_write(fd, r); } From eedff7af47d053b7d5273c0c357cd19a1ee0fcf8 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Tue, 6 Sep 2011 13:43:13 +0100 Subject: [PATCH 3/7] Fixed chunk issue with pub/sub clients --- http.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/http.c b/http.c index 9270892..b04f87c 100644 --- a/http.c +++ b/http.c @@ -164,12 +164,14 @@ http_response_write(struct http_response *r, int fd) { (void)ret; p = r->out; - if(r->code == 200 && r->body) { - char content_length[10]; - sprintf(content_length, "%zd", r->body_len); - http_response_set_header(r, "Content-Length", content_length); - } else if(!r->chunked) { - http_response_set_header(r, "Content-Length", "0"); + if(!r->chunked) { + if(r->code == 200 && r->body) { + char content_length[10]; + sprintf(content_length, "%zd", r->body_len); + http_response_set_header(r, "Content-Length", content_length); + } else { + http_response_set_header(r, "Content-Length", "0"); + } } for(i = 0; i < r->header_count; ++i) { @@ -209,10 +211,19 @@ http_response_write(struct http_response *r, int fd) { /* append body if there is one. */ if(r->body && r->body_len) { - if(r->chunked) { - r->out = realloc(r->out, r->out_sz + r->body_len); - memcpy(r->out + r->out_sz, r->body, r->body_len); - r->out_sz += r->body_len; + + char *tmp = (char*)r->body; + size_t tmp_len = r->body_len; + if(r->chunked) { /* replace body with formatted chunk */ + tmp = format_chunk(r->body, r->body_len, &tmp_len); + } + + r->out = realloc(r->out, r->out_sz + tmp_len); + memcpy(r->out + r->out_sz, tmp, tmp_len); + r->out_sz += tmp_len; + + if(r->chunked) { /* need to free the chunk */ + free(tmp); } } From 2eba190a0d89b66ada90d0d5f7684b8f5c8ce411 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Tue, 6 Sep 2011 19:13:54 +0100 Subject: [PATCH 4/7] Fixed daemonize issue --- server.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/server.c b/server.c index cf0baf4..ae559a2 100644 --- a/server.c +++ b/server.c @@ -126,18 +126,18 @@ server_can_accept(int fd, short event, void *ptr) { */ static 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); - } + 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); + } } @@ -145,6 +145,10 @@ int server_start(struct server *s) { int i; + + /* initialize libevent */ + s->base = event_base_new(); + if(s->cfg->daemonize) { server_daemonize(); @@ -172,9 +176,6 @@ server_start(struct server *s) { return -1; } - /* initialize libevent */ - s->base = event_base_new(); - /* start http server */ event_set(&s->ev, s->fd, EV_READ | EV_PERSIST, server_can_accept, s); event_base_set(s->base, &s->ev); From 33f9a2f01e34baf690b565fbc32302c07f1aeac1 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Tue, 6 Sep 2011 21:47:00 +0100 Subject: [PATCH 5/7] Disabled Websockets by default. Due to a possible crash, WebSockets are disabled until their implementation is completed. --- client.c | 2 +- conf.c | 2 ++ conf.h | 3 +++ webdis.json | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client.c b/client.c index 7d4e32a..301dc44 100644 --- a/client.c +++ b/client.c @@ -180,7 +180,7 @@ http_client_on_message_complete(struct http_parser *p) { } c->http_version = c->parser.http_minor; - if(p->upgrade) { /* WebSocket, don't execute just yet */ + if(p->upgrade && c->w->s->cfg->websockets) { /* WebSocket, don't execute just yet */ c->is_websocket = 1; return 0; } diff --git a/conf.c b/conf.c index 30d43f6..4717ce2 100644 --- a/conf.c +++ b/conf.c @@ -83,6 +83,8 @@ conf_read(const char *filename) { else conf->verbosity = (log_level)tmp; } else if(strcmp(json_object_iter_key(kv), "daemonize") == 0 && json_typeof(jtmp) == JSON_TRUE) { conf->daemonize = 1; + } else if(strcmp(json_object_iter_key(kv), "websockets") == 0 && json_typeof(jtmp) == JSON_TRUE) { + conf->websockets = 1; } else if(strcmp(json_object_iter_key(kv), "database") == 0 && json_typeof(jtmp) == JSON_INTEGER) { conf->database = json_integer_value(jtmp); } else if(strcmp(json_object_iter_key(kv), "pool_size") == 0 && json_typeof(jtmp) == JSON_INTEGER) { diff --git a/conf.h b/conf.h index af06bb5..93258a4 100644 --- a/conf.h +++ b/conf.h @@ -22,6 +22,9 @@ struct conf { /* daemonize process, off by default */ int daemonize; + /* WebSocket support, off by default */ + int websockets; + /* database number */ int database; diff --git a/webdis.json b/webdis.json index c7c2c06..b1b7181 100644 --- a/webdis.json +++ b/webdis.json @@ -9,6 +9,7 @@ "threads": 3, "daemonize": false, + "websockets": false, "database": 0, From 7286cfe73fd167c67bd309ec726e8fe498e96965 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Thu, 15 Sep 2011 22:03:05 +0100 Subject: [PATCH 6/7] Send JS in JSON format --- cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd.c b/cmd.c index 1679e9f..d193bf8 100644 --- a/cmd.c +++ b/cmd.c @@ -282,7 +282,7 @@ cmd_select_format(struct http_client *client, struct cmd *cmd, {.s = "jpg", .sz = 3, .f = custom_type_reply, .ct = "image/jpeg"}, {.s = "jpeg", .sz = 4, .f = custom_type_reply, .ct = "image/jpeg"}, - {.s = "js", .sz = 2, .f = custom_type_reply, .ct = "application/javascript"}, + {.s = "js", .sz = 2, .f = json_reply, .ct = "application/javascript"}, {.s = "css", .sz = 3, .f = custom_type_reply, .ct = "text/css"}, }; From 05bcc6098ab7a86428d561b4faf1c6b7c36a5053 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Sat, 19 Nov 2011 22:11:53 +0000 Subject: [PATCH 7/7] Makefile fix, link with LDFLAGS after objects. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2f8cc1d..d69c002 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ INSTALL_DIRS = $(DESTDIR) \ all: $(OUT) Makefile $(OUT): $(OBJS) Makefile - $(CC) $(LDFLAGS) -o $(OUT) $(OBJS) + $(CC) -o $(OUT) $(OBJS) $(LDFLAGS) %.o: %.c %.h Makefile $(CC) -c $(CFLAGS) -o $@ $<