#include /* XXX: make this fully configurable */ static const char error_page[] = "%s" "" "" "

%s

" "
" "

Requested URL: %s
" "%s %s
" "

" "
" "
" ""; void send_response(evapp_ctx *ctx, int code, const char *code_msg, const char *http_msg, const char *msg) { struct evbuffer *databuf = evbuffer_new(); struct evhttp_request *request = evapp_request(ctx); char *uri = evhttp_htmlescape(request->uri); assert(databuf && code_msg && http_msg && msg); evbuffer_add_printf(databuf, error_page, http_msg, http_msg, uri, msg ? "Details: " : "", msg ? msg : ""); /* Add default browser cacheable at 1 day in seconds if no * cache-control or expires is given. If one of those is missing, * then the caller didn't call response_cacheable. */ if (!evhttp_find_header(request->output_headers, "Cache-Control") || !evhttp_find_header(request->output_headers, "Expires")) response_cacheable(ctx, CACHE_PRIVATE, 86400); evhttp_send_reply(request, code, code_msg, databuf); // XXX: Add real logging and log the msg too! //fprintf(stdout, "[handle_error] request: %s\n", // evhttp_request_uri(request)); free(uri); evbuffer_free(databuf); return; } void send_ok(evapp_ctx *ctx, const char* msg) { send_response(ctx, 200, "OK", "200 OK", msg); return; } void send_not_found(evapp_ctx *ctx, const char* msg) { /* Cache these for a whole day */ // XXX: could be bad if a new page is added ;-) response_cacheable(ctx, CACHE_PUBLIC, 60*60*24); send_response(ctx, HTTP_NOTFOUND, "NOT FOUND", "404 Not Found", msg); return; } void send_error(evapp_ctx *ctx, const char* msg) { /* Cache these for a whole day */ // XXX: could be bad if a new page is added ;-) response_cacheable(ctx, CACHE_NONE, 0); send_response(ctx, 500, "INTERNAL SERVER ERRROR", "500 Server Error", msg); return; } void send_forbidden(evapp_ctx *ctx, const char* msg) { response_cacheable(ctx, CACHE_NONE, 0); send_response(ctx, 403, "FORBIDDEN", "403 Forbidden", msg); return; } void send_created(evapp_ctx *ctx, const char *object_type, uint64_t id) { struct evkeyvalq cookie; static char msg[256]; // should be pleeenty bool secure = true; struct evhttp_request *request = evapp_request(ctx); snprintf(msg, sizeof(msg), "/view/%s/%llu", object_type, id); evhttp_add_header(request->output_headers, "Location", msg); snprintf(msg, sizeof(msg), "/view/%s/%llu", object_type, id, object_type, id); /* Don't cache creations */ response_cacheable(ctx, CACHE_NONE, 0); /* Reset any xsrf tokens here just in case */ TAILQ_INIT(&cookie); evhttp_add_header(&cookie, "token", "0"); secure = !evapp_get_debug_mode(ctx); set_cookie(ctx, &cookie, "/", NULL, 0, secure); evhttp_clear_headers(&cookie); send_response(ctx, 201, "CREATED", "201 CREATED", msg); return; }