PUBLIC ssize espRenderError(HttpConn *conn, int status, cchar *fmt, ...) { va_list args; HttpRx *rx; ssize written; cchar *msg, *title, *text; va_start(args, fmt); rx = conn->rx; written = 0; if (!httpIsFinalized(conn)) { if (status == 0) { status = HTTP_CODE_INTERNAL_SERVER_ERROR; } title = sfmt("Request Error for \"%s\"", rx->pathInfo); msg = mprEscapeHtml(sfmtv(fmt, args)); if (rx->route->flags & HTTP_ROUTE_SHOW_ERRORS) { text = sfmt(\ "<!DOCTYPE html>\r\n<html>\r\n<head><title>%s</title></head>\r\n" \ "<body>\r\n<h1>%s</h1>\r\n" \ " <pre>%s</pre>\r\n" \ " <p>To prevent errors being displayed in the browser, " \ " set <b>ShowErrors off</b> in the appweb.conf file.</p>\r\n", \ "</body>\r\n</html>\r\n", title, title, msg); httpSetHeader(conn, "Content-Type", "text/html"); written += espRenderString(conn, text); espFinalize(conn); mprTrace(4, "Request error (%d) for: \"%s\"", status, rx->pathInfo); } } va_end(args); return written; }
/* Start the request. At this stage, body data may not have been fully received unless the request is a form (POST method and content type is application/x-www-form-urlencoded). Forms are a special case and delay invoking the start callback until all body data is received. WARNING: GC yield */ static void startEsp(HttpQueue *q) { HttpConn *conn; HttpRx *rx; EspReq *req; conn = q->conn; rx = conn->rx; req = conn->reqData; #if ME_WIN_LIKE rx->target = mprGetPortablePath(rx->target); #endif if (req) { mprSetThreadData(req->esp->local, conn); /* WARNING: GC yield */ if (!runAction(conn)) { pruneFlash(conn); } else { if (!conn->error && req->autoFinalize) { if (!conn->tx->responded) { /* WARNING: GC yield */ espRenderDocument(conn, rx->target); } if (req->autoFinalize) { espFinalize(conn); } } pruneFlash(conn); } finalizeFlash(conn); mprSetThreadData(req->esp->local, NULL); } }
PUBLIC void espRenderResult(HttpConn *conn, bool success) { EspReq *req; EdiRec *rec; req = conn->data; rec = getRec(); if (rec && rec->errors) { espRender(conn, "{\"error\": %d, \"feedback\": %s, \"fieldErrors\": %s}", !success, req->feedback ? mprSerialize(req->feedback, MPR_JSON_QUOTES) : "{}", mprSerialize(rec->errors, MPR_JSON_QUOTES)); } else { espRender(conn, "{\"error\": %d, \"feedback\": %s}", !success, req->feedback ? mprSerialize(req->feedback, MPR_JSON_QUOTES) : "{}"); } espFinalize(conn); }
ssize espRenderError(HttpConn *conn, int status, cchar *fmt, ...) { va_list args; HttpRx *rx; EspReq *req; EspRoute *eroute; ssize written; cchar *msg, *title, *text; va_start(args, fmt); rx = conn->rx; req = conn->data; eroute = req->eroute; written = 0; if (!httpIsFinalized(conn)) { if (status == 0) { status = HTTP_CODE_INTERNAL_SERVER_ERROR; } title = sfmt("Request Error for \"%s\"", rx->pathInfo); msg = mprEscapeHtml(sfmtv(fmt, args)); if (eroute->showErrors) { text = sfmt(\ "<!DOCTYPE html>\r\n<html>\r\n<head><title>%s</title></head>\r\n" \ "<body>\r\n<h1>%s</h1>\r\n" \ " <pre>%s</pre>\r\n" \ " <p>To prevent errors being displayed in the browser, " \ " set <b>log.showErrors</b> to false in the ejsrc file.</p>\r\n", \ "</body>\r\n</html>\r\n", title, title, msg); httpSetHeader(conn, "Content-Type", "text/html"); written += espRenderString(conn, text); espFinalize(conn); mprLog(4, "Request error (%d) for: \"%s\"", status, rx->pathInfo); } } va_end(args); return written; }
PUBLIC void finalize() { espFinalize(getStream()); }
/* Run an action (may yield) */ static int runAction(HttpConn *conn) { HttpRx *rx; HttpRoute *route; EspRoute *eroute; EspReq *req; EspAction action; rx = conn->rx; req = conn->reqData; route = rx->route; eroute = route->eroute; assert(eroute); if (eroute->edi && eroute->edi->flags & EDI_PRIVATE) { cloneDatabase(conn); } else { req->edi = eroute->edi; } if (route->sourceName == 0 || *route->sourceName == '\0') { if (eroute->commonController) { (eroute->commonController)(conn); } return 1; } #if !ME_STATIC if (!eroute->combine && (route->update || !mprLookupKey(eroute->actions, rx->target))) { cchar *errMsg, *controllers, *controller; if ((controllers = httpGetDir(route, "CONTROLLERS")) == 0) { controllers = "."; } controllers = mprJoinPath(route->home, controllers); controller = schr(route->sourceName, '$') ? stemplateJson(route->sourceName, rx->params) : route->sourceName; controller = controllers ? mprJoinPath(controllers, controller) : mprJoinPath(route->home, controller); if (espLoadModule(route, conn->dispatcher, "controller", controller, &errMsg) < 0) { if (mprPathExists(controller, R_OK)) { httpError(conn, HTTP_CODE_NOT_FOUND, "%s", errMsg); return 0; } } } #endif /* !ME_STATIC */ assert(eroute->top); action = mprLookupKey(eroute->top->actions, rx->target); if (route->flags & HTTP_ROUTE_XSRF && !(rx->flags & HTTP_GET)) { if (!httpCheckSecurityToken(conn)) { httpSetStatus(conn, HTTP_CODE_UNAUTHORIZED); if (smatch(route->responseFormat, "json")) { httpTrace(conn, "esp.xsrf.error", "error", 0); espRenderString(conn, "{\"retry\": true, \"success\": 0, \"feedback\": {\"error\": \"Security token is stale. Please retry.\"}}"); espFinalize(conn); } else { httpError(conn, HTTP_CODE_UNAUTHORIZED, "Security token is stale. Please reload page."); } return 0; } } if (action) { httpAuthenticate(conn); setupFlash(conn); if (eroute->commonController) { (eroute->commonController)(conn); } if (!httpIsFinalized(conn)) { (action)(conn); } } return 1; }
PUBLIC void finalize() { espFinalize(getConn()); }