Permalink
Browse files

Better client/cmd relationship.

  • Loading branch information...
nicolasff committed Jan 25, 2011
1 parent 1073b84 commit a298d3c16bfde9966e816a61da8e6f531eaebe13
Showing with 53 additions and 45 deletions.
  1. +3 −0 client.c
  2. +2 −0 client.h
  3. +6 −5 cmd.c
  4. +1 −2 cmd.h
  5. +13 −11 formats/common.c
  6. +4 −2 formats/common.h
  7. +7 −7 formats/custom-type.c
  8. +14 −14 formats/json.c
  9. +1 −1 formats/json.h
  10. +2 −3 formats/raw.c
View
@@ -118,6 +118,9 @@ http_client_cleanup(struct http_client *c) {
memset(&c->verb, 0, sizeof(c->verb));
+ cmd_free(c->cmd);
+ c->cmd = NULL;
+
c->state = CLIENT_WAITING;
}
View
@@ -7,6 +7,7 @@
#include "http.h"
struct server;
+struct cmd;
typedef enum {
CLIENT_WAITING,
@@ -21,6 +22,7 @@ struct http_client {
struct event ev;
struct server *s;
client_state state;
+ struct cmd *cmd;
/* http parser */
http_parser_settings settings;
View
11 cmd.c
@@ -14,11 +14,10 @@
#include <ctype.h>
struct cmd *
-cmd_new(struct http_client *client, int count) {
+cmd_new(int count) {
struct cmd *c = calloc(1, sizeof(struct cmd));
- c->client = client;
c->count = count;
c->argv = calloc(count, sizeof(char*));
@@ -31,6 +30,8 @@ cmd_new(struct http_client *client, int count) {
void
cmd_free(struct cmd *c) {
+ if(!c) return;
+
free(c->argv);
free(c->argv_len);
@@ -95,7 +96,7 @@ cmd_run(struct server *s, struct http_client *client,
param_count++;
}
- cmd = cmd_new(client, param_count);
+ client->cmd = cmd = cmd_new(param_count);
/* get output formatting function */
uri_len = cmd_select_format(client, cmd, uri, uri_len, &f_format);
@@ -128,7 +129,7 @@ cmd_run(struct server *s, struct http_client *client,
/* no args (e.g. INFO command) */
if(!slash) {
- redisAsyncCommandArgv(s->ac, f_format, cmd, 1, cmd->argv, cmd->argv_len);
+ redisAsyncCommandArgv(s->ac, f_format, client, 1, cmd->argv, cmd->argv_len);
return 0;
}
p = slash + 1;
@@ -156,7 +157,7 @@ cmd_run(struct server *s, struct http_client *client,
}
/* push command to Redis. */
- redisAsyncCommandArgv(s->ac, f_format, cmd, cmd->count, cmd->argv, cmd->argv_len);
+ redisAsyncCommandArgv(s->ac, f_format, client, cmd->count, cmd->argv, cmd->argv_len);
for(i = 1; i < cur_param; ++i) {
free((char*)cmd->argv[i]);
View
3 cmd.h
@@ -18,7 +18,6 @@ struct cmd {
int count;
const char **argv;
size_t *argv_len;
- struct http_client *client;
int started_responding;
@@ -33,7 +32,7 @@ struct subscription {
};
struct cmd *
-cmd_new(struct http_client *client, int count);
+cmd_new(int count);
void
cmd_free(struct cmd *c);
View
@@ -30,43 +30,45 @@ char *etag_new(const char *p, size_t sz) {
}
void
-format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content_type) {
+format_send_reply(struct http_client *client, const char *p, size_t sz, const char *content_type) {
int free_cmd = 1;
+ struct cmd *cmd = client->cmd;
+
if(cmd_is_subscribe(cmd)) {
free_cmd = 0;
/* start streaming */
if(cmd->started_responding == 0) {
const char *ct = cmd->mime?cmd->mime:content_type;
cmd->started_responding = 1;
- http_set_header(&cmd->client->output_headers.content_type, ct, strlen(ct));
- http_send_reply_start(cmd->client, 200, "OK");
+ http_set_header(&client->output_headers.content_type, ct, strlen(ct));
+ http_send_reply_start(client, 200, "OK");
}
- http_send_reply_chunk(cmd->client, p, sz);
+ http_send_reply_chunk(client, p, sz);
} else {
/* compute ETag */
char *etag = etag_new(p, sz);
- const char *if_none_match = cmd->client->input_headers.if_none_match.s;
+ const char *if_none_match = client->input_headers.if_none_match.s;
/* check If-None-Match */
- if(if_none_match && strncmp(if_none_match, etag, cmd->client->input_headers.if_none_match.sz) == 0) {
+ if(if_none_match && strncmp(if_none_match, etag, client->input_headers.if_none_match.sz) == 0) {
/* SAME! send 304. */
- http_send_reply(cmd->client, 304, "Not Modified", NULL, 0);
+ http_send_reply(client, 304, "Not Modified", NULL, 0);
} else {
const char *ct = cmd->mime?cmd->mime:content_type;
- http_set_header(&cmd->client->output_headers.content_type, ct, strlen(ct));
- http_set_header(&cmd->client->output_headers.etag, etag, strlen(etag));
- http_send_reply(cmd->client, 200, "OK", p, sz);
+ http_set_header(&client->output_headers.content_type, ct, strlen(ct));
+ http_set_header(&client->output_headers.etag, etag, strlen(etag));
+ http_send_reply(client, 200, "OK", p, sz);
}
free(etag);
}
/* cleanup */
if(free_cmd) {
- cmd_free(cmd);
+ cmd_free(client->cmd);
}
}
View
@@ -3,9 +3,11 @@
#include <stdlib.h>
-struct cmd;
+struct http_client;
void
-format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content_type);
+format_send_reply(struct http_client *client,
+ const char *p, size_t sz,
+ const char *content_type);
#endif
View
@@ -12,7 +12,7 @@ void
custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
- struct cmd *cmd = privdata;
+ struct http_client *client = privdata;
(void)c;
char int_buffer[50];
int int_len;
@@ -21,26 +21,26 @@ custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
return;
}
- if(cmd->mime) { /* use the given content-type, but only for strings */
+ if(client->cmd->mime) { /* use the given content-type, but only for strings */
switch(reply->type) {
case REDIS_REPLY_NIL: /* or nil values */
- format_send_reply(cmd, "", 0, cmd->mime);
+ format_send_reply(client, "", 0, client->cmd->mime);
return;
case REDIS_REPLY_STRING:
- format_send_reply(cmd, reply->str, reply->len, cmd->mime);
+ format_send_reply(client, reply->str, reply->len, client->cmd->mime);
return;
case REDIS_REPLY_INTEGER:
int_len = sprintf(int_buffer, "%lld", reply->integer);
- format_send_reply(cmd, int_buffer, int_len, cmd->mime);
+ format_send_reply(client, int_buffer, int_len, client->cmd->mime);
return;
}
}
/* couldn't make sense of what the client wanted. */
- http_send_reply(cmd->client, 400, "Bad request", NULL, 0);
- cmd_free(cmd);
+ http_send_reply(client, 400, "Bad request", NULL, 0);
+ cmd_free(client->cmd);
}
View
@@ -15,12 +15,12 @@ void
json_reply(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
- struct cmd *cmd = privdata;
+ struct http_client *client = privdata;
json_t *j;
char *jstr;
(void)c;
- if(cmd == NULL) {
+ if(client->cmd == NULL) {
/* broken connection */
return;
}
@@ -30,13 +30,15 @@ json_reply(redisAsyncContext *c, void *r, void *privdata) {
}
/* encode redis reply as JSON */
- j = json_wrap_redis_reply(cmd, r);
+ j = json_wrap_redis_reply(client->cmd, r);
/* get JSON as string, possibly with JSONP wrapper */
- jstr = json_string_output(j, cmd);
+ jstr = json_string_output(j,
+ client->query_string.jsonp.s,
+ client->query_string.jsonp.sz);
/* send reply */
- format_send_reply(cmd, jstr, strlen(jstr), "application/json");
+ format_send_reply(client, jstr, strlen(jstr), "application/json");
/* cleanup */
json_decref(j);
@@ -107,22 +109,20 @@ json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) {
char *
-json_string_output(json_t *j, struct cmd *cmd) {
+json_string_output(json_t *j, const char *jsonp, size_t jsonp_len) {
char *json_reply = json_dumps(j, JSON_COMPACT);
/* check for JSONP */
- if(cmd->client->query_string.jsonp.s) {
-
+ if(jsonp) {
size_t json_len = strlen(json_reply);
- size_t val_len = cmd->client->query_string.jsonp.sz;
- size_t ret_len = val_len + 1 + json_len + 3;
+ size_t ret_len = jsonp_len + 1 + json_len + 3;
char *ret = calloc(1 + ret_len, 1);
- memcpy(ret, cmd->client->query_string.jsonp.s, val_len);
- ret[val_len]='(';
- memcpy(ret + val_len + 1, json_reply, json_len);
- memcpy(ret + val_len + 1 + json_len, ");\n", 3);
+ memcpy(ret, jsonp, jsonp_len);
+ ret[jsonp_len]='(';
+ memcpy(ret + jsonp_len + 1, json_reply, json_len);
+ memcpy(ret + jsonp_len + 1 + json_len, ");\n", 3);
free(json_reply);
return ret;
View
@@ -11,6 +11,6 @@ void
json_reply(redisAsyncContext *c, void *r, void *privdata);
char *
-json_string_output(json_t *j, struct cmd *cmd);
+json_string_output(json_t *j, const char *jsonp, size_t jsonp_len);
#endif
View
@@ -1,5 +1,4 @@
#include "raw.h"
-#include "cmd.h"
#include "common.h"
#include "http.h"
@@ -14,7 +13,7 @@ void
raw_reply(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
- struct cmd *cmd = privdata;
+ struct http_client *client = privdata;
char *raw_out;
size_t sz;
(void)c;
@@ -26,7 +25,7 @@ raw_reply(redisAsyncContext *c, void *r, void *privdata) {
raw_out = raw_wrap(r, &sz);
/* send reply */
- format_send_reply(cmd, raw_out, sz, "binary/octet-stream");
+ format_send_reply(client, raw_out, sz, "binary/octet-stream");
/* cleanup */
free(raw_out);

0 comments on commit a298d3c

Please sign in to comment.