Created
March 20, 2011 08:42
-
-
Save Neopallium/878205 to your computer and use it in GitHub Desktop.
mongrel2 yajl with print callback.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <yajl/yajl_gen.h> | |
//#define bassert(bcode) if((bcode) != BSTR_OK) abort() | |
#define bassert(bcode) (bcode) | |
#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)); \ | |
} | |
static void header_str_append(void *ctx, const char * str, unsigned int len) { | |
bstring *p_headers = (bstring *)ctx; | |
bstring headers = *p_headers; | |
if (headers == NULL) { | |
headers = blk2bstr(str, len); | |
*p_headers = headers; | |
return; | |
} | |
bassert(bcatblk(headers, str, len)); | |
} | |
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 headers = NULL; | |
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; | |
int x; | |
json_gen = yajl_gen_alloc2(header_str_append, &gen_config, NULL, &headers); | |
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); | |
// 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); | |
result = bformat("%s %d %s %d:%s,%d:", bdata(uuid), id, | |
bdata(Request_path(req)), | |
blength(headers), bdata(headers), 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