Merge branch 'master' into websockets

master
Nicolas Favre-Felix 13 years ago
commit da8c888f88

@ -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 $@ $<

@ -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;
}

@ -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"},
};

@ -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) {

@ -22,6 +22,9 @@ struct conf {
/* daemonize process, off by default */
int daemonize;
/* WebSocket support, off by default */
int websockets;
/* database number */
int database;

@ -78,11 +78,12 @@ 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);
}
} else {
/* compute ETag */

@ -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");
@ -131,13 +132,31 @@ 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) {
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);
@ -145,13 +164,15 @@ http_response_write(struct http_response *r, int fd) {
(void)ret;
p = r->out;
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 if(!r->chunked) {
} else {
http_response_set_header(r, "Content-Length", "0");
}
}
for(i = 0; i < r->header_count; ++i) {
/* "Key: Value\r\n" */
@ -190,9 +211,20 @@ 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;
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);
}
}
/* send buffer to client */
@ -245,6 +277,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 {
@ -273,25 +306,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);
}

@ -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);

@ -9,6 +9,7 @@
"threads": 3,
"daemonize": false,
"websockets": false,
"database": 0,

Loading…
Cancel
Save