Skip to content

Instantly share code, notes, and snippets.

@Neopallium
Created March 20, 2011 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Neopallium/878195 to your computer and use it in GitHub Desktop.
Save Neopallium/878195 to your computer and use it in GitHub Desktop.
mongrel2 using yajl.
#include <yajl/yajl_gen.h>
#define B(K, V) if((V) != NULL) { \
yajl_gen_string(json_gen, (unsigned char *)bdata(K), blength(K)); \
yajl_gen_string(json_gen, (unsigned char *)bdata(V), blength(V)); \
}
bstring Request_to_payload(Request *req, bstring uuid, int fd, const char *buf, size_t len)
{
static const yajl_gen_config gen_config = { .beautify = 0, .indentString = "" };
yajl_gen json_gen;
bstring result = NULL;
int id = Register_id_for_fd(fd);
bstring key = NULL;
hnode_t *i = NULL;
hscan_t scan;
struct bstrList *val_list = NULL;
const unsigned char *head;
unsigned int head_len;
int x;
json_gen = yajl_gen_alloc(&gen_config, NULL);
yajl_gen_map_open(json_gen);
B(&HTTP_PATH, req->path);
check(id != -1, "Asked to generate a paylod for an fd that doesn't exist: %d", fd);
hash_scan_begin(&scan, req->headers);
for(i = hash_scan_next(&scan); i != NULL; i = hash_scan_next(&scan)) {
val_list = hnode_get(i);
key = (bstring)hnode_getkey(i);
if(val_list->qty > 1) {
#if 1
yajl_gen_string(json_gen, (unsigned char *)bdata(key), blength(key));
yajl_gen_array_open(json_gen);
// TODO:
// join all the values together as a json array then add that to the key
for(x = 0; x < val_list->qty; x++) {
yajl_gen_string(json_gen, (unsigned char *)bdata(val_list->entry[x]), blength(val_list->entry[x]));
}
yajl_gen_array_close(json_gen);
#endif
} else {
B(key, val_list->entry[0]);
}
}
// these come after so that if anyone attempts to hijack these somehow, most
// hash algorithms languages have will replace the browser ones with ours
if(Request_is_json(req)) {
B(&HTTP_METHOD, &JSON_METHOD);
} else if(Request_is_xml(req)) {
B(&HTTP_METHOD, &XML_METHOD);
} else {
B(&HTTP_METHOD, req->request_method);
}
B(&HTTP_VERSION, req->version);
B(&HTTP_URI, req->uri);
B(&HTTP_QUERY, req->query_string);
B(&HTTP_FRAGMENT, req->fragment);
B(&HTTP_PATTERN, req->pattern);
yajl_gen_map_close(json_gen);
yajl_gen_get_buf(json_gen, &head, &head_len);
result = bformat("%s %d %s %d:%s,%d:", bdata(uuid), id,
bdata(Request_path(req)),
head_len, head, len);
bcatblk(result, buf, len);
bconchar(result, ',');
check(result, "Failed to construct payload result.");
yajl_gen_free(json_gen);
//bdestroy(headers);
return result;
error:
yajl_gen_free(json_gen);
//bdestroy(headers);
bdestroy(result);
return NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment