#include NEOERR* render_cb(void *vctx, char *data){ evapp_ctx *ctx = vctx; evbuffer_add_printf(evapp_response(ctx), "%s", data); /* XXX: I don't think this buys us anything until * we return back to the event loop :-/ * evhttp_send_reply_chunk(evapp_request(ctx), evapp_response(ctx)); */ return STATUS_OK; } bool template_load(evapp_ctx *ctx, HDF *hdf, const char *base, const char *dbname, CSPARSE **csp) { // XXX: Caching this is _probably_ safe :-P static evapp_db *db = NULL; DBT key, data; static char template_key[256]; NEOERR *err = NULL; assert(ctx != NULL && base != NULL && dbname != NULL); if (!db) { db = evapp_db_select(ctx, "templates"); if (!db) return false; } // XXX: check for truncation template_key[0] = '\0'; // don't double the slashes. if (base[strlen(base)-1] == '/' || dbname[0] == '/') snprintf(template_key, sizeof(template_key), "%s%s", base, dbname); else snprintf(template_key, sizeof(template_key), "%s/%s", base, dbname); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.data = template_key; key.size = strlen(key.data)+1; data.flags = DB_DBT_MALLOC; db->p->get(db->p, NULL, &key, &data, 0); if (data.size == 0) { return false; } // XXX: just the nll... if (data.size == 1) { free(data.data); return false; } // cs takes ownership of data.data from here on out. // XXX: set hdf defaults here, like escaping mode cs_init(csp, hdf); err = cs_parse_string(*csp, data.data, strlen(data.data)); if (err != STATUS_OK) { //nerr_log_error(err); nerr_ignore(&err); cs_destroy(csp); // XXX: is this ideal? return false; } return true; } bool template_render(evapp_ctx *ctx, HDF *hdf, char *prefix, char *dbname) { CSPARSE *csp = NULL; bool loaded = false; assert(ctx); assert(hdf && prefix && dbname); loaded = template_load(ctx, hdf, prefix, dbname, &csp); // load _default.cs from the current prefix if there is no // template. if (!loaded && evapp_get_default_templates(ctx)) loaded = template_load(ctx, hdf, prefix, "_default", &csp); if (!loaded) return false; //evhttp_send_reply_start(evapp_request(ctx), HTTP_OK, "OK"); cs_render(csp, ctx, render_cb); //evhttp_send_reply_end(evapp_request(ctx)); cs_destroy(&csp); if (EVBUFFER_LENGTH(evapp_response(ctx)) == 0) return false; evhttp_send_reply(evapp_request(ctx), HTTP_OK, "OK", evapp_response(ctx)); return true; }