static cchar *getValue(HttpConn *conn, cchar *fieldName, MprHash *options) { EdiRec *record; MprKey *field; cchar *value, *msg; record = conn->record; value = 0; if (record) { value = ediGetFieldValue(record, fieldName); if (record->errors) { for (ITERATE_KEY_DATA(record->errors, field, msg)) { if (smatch(field->key, fieldName)) { httpInsertOption(options, "class", ESTYLE("field-error")); } } } } if (value == 0) { value = httpGetOption(options, "value", 0); } if (httpGetOption(options, "escape", 0)) { value = mprEscapeHtml(value); } return value; }
static cchar *escapeValue(cchar *value, MprHash *options) { if (httpGetOption(options, "escape", 0)) { return mprEscapeHtml(value); } return value; }
static void makeAltBody(HttpConn *conn, int status) { HttpRx *rx; HttpTx *tx; cchar *statusMsg, *msg; rx = conn->rx; tx = conn->tx; assert(rx && tx); statusMsg = httpLookupStatus(conn->http, status); msg = ""; if (rx && (!rx->route || rx->route->flags & HTTP_ROUTE_SHOW_ERRORS)) { msg = conn->errorMsg; } if (rx && scmp(rx->accept, "text/plain") == 0) { tx->altBody = sfmt("Access Error: %d -- %s\r\n%s\r\n", status, statusMsg, msg); } else { tx->altBody = sfmt("<!DOCTYPE html>\r\n" "<head>\r\n" " <title>%s</title>\r\n" " <link rel=\"shortcut icon\" href=\"data:image/x-icon;,\" type=\"image/x-icon\">\r\n" "</head>\r\n" "<body>\r\n<h2>Access Error: %d -- %s</h2>\r\n<pre>%s</pre>\r\n</body>\r\n</html>\r\n", statusMsg, status, statusMsg, mprEscapeHtml(msg)); } tx->length = slen(tx->altBody); }
/* HTML escape a string function escapeHtml(str: String): String */ static EjsObj *web_escapeHtml(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { EjsString *str; str = (EjsString*) argv[0]; return (EjsObj*) ejsCreateStringFromAsc(ejs, mprEscapeHtml(str->value)); }
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; }
/* * Run the Ejscript request. The routine runs when all input data has been received. */ static void runEjs(MaQueue *q) { MaConn *conn; MaRequest *req; EjsWeb *web; char msg[MPR_MAX_STRING]; conn = q->conn; req = conn->request; web = q->queueData = conn->response->handlerData; maSetHeader(conn, 0, "Last-Modified", req->host->currentDate); maDontCacheResponse(conn); maPutForService(q, maCreateHeaderPacket(conn), 0); if (ejsRunWebRequest(web) < 0) { // TODO - refactor. Want request failed to have an option which says send this output to the client also. if (web->flags & EJS_WEB_FLAG_BROWSER_ERRORS) { // TODO - this API should allocate a buffer and not use a static buffer mprEscapeHtml(msg, sizeof(msg), web->error); maFormatBody(conn, "Request Failed", "<h1>Ejscript error for \"%s\"</h1>\r\n<h2>%s</h2>\r\n" "<p>To prevent errors being displayed in the browser, " "use <b>\"EjsErrors log\"</b> in the config file.</p>\r\n", web->url, web->error); } maFailRequest(conn, MPR_HTTP_CODE_BAD_GATEWAY, web->error); } maPutForService(q, maCreateEndPacket(conn), 1); }
PUBLIC ssize espRenderSafe(HttpConn *conn, cchar *fmt, ...) { va_list args; cchar *s; va_start(args, fmt); s = mprEscapeHtml(sfmtv(fmt, args)); va_end(args); return espRenderBlock(conn, s, slen(s)); }
static bool okEscapeHtml(MprTestGroup *gp, char *html, char *expectedHtml) { char *escaped; escaped = mprEscapeHtml(html); if (strcmp(expectedHtml, escaped) == 0) { return 1; } mprLog(0, "HTML \"%s\" is escaped to be \n" "\"%s\" instead of \n" "\"%s\"\n", html, escaped, expectedHtml); return 0; }
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; }
static void outputLine(HttpQueue *q, MprDirEntry *ep, cchar *path, int nameSize) { MprPath info; MprTime when; Dir *dir; char *newPath, sizeBuf[16], timeBuf[48], *icon; struct tm tm; bool isDir; int len; cchar *ext, *mimeType; char *dirSuffix; char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; path = mprEscapeHtml(path); dir = q->conn->data; if (ep->size >= (1024 * 1024 * 1024)) { fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024 * 1024 * 1024, "G"); } else if (ep->size >= (1024 * 1024)) { fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024 * 1024, "M"); } else if (ep->size >= 1024) { fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024, "K"); } else { fmt(sizeBuf, sizeof(sizeBuf), "%6d", (int) ep->size); } newPath = mprJoinPath(path, ep->name); if (mprGetPathInfo(newPath, &info) < 0) { when = mprGetTime(); isDir = 0; } else { isDir = info.isDir ? 1 : 0; when = (MprTime) info.mtime * MPR_TICKS_PER_SEC; } if (isDir) { icon = "folder"; dirSuffix = "/"; } else { ext = mprGetPathExt(ep->name); if (ext && (mimeType = mprLookupMime(q->conn->rx->route->mimeTypes, ext)) != 0) { if (strcmp(ext, "es") == 0 || strcmp(ext, "ejs") == 0 || strcmp(ext, "php") == 0) { icon = "text"; } else if (strstr(mimeType, "text") != 0) { icon = "text"; } else { icon = "compressed"; } } else { icon = "compressed"; } dirSuffix = ""; } mprDecodeLocalTime(&tm, when); fmt(timeBuf, sizeof(timeBuf), "%02d-%3s-%4d %02d:%02d", tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min); len = (int) strlen(ep->name) + (int) strlen(dirSuffix); if (dir->fancyIndexing == 2) { httpWrite(q, "<tr><td valign=\"top\">"); httpWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[ ]\", /></td>", icon); httpWrite(q, "<td><a href=\"%s%s\">%s%s</a></td>", ep->name, dirSuffix, ep->name, dirSuffix); httpWrite(q, "<td>%s</td><td>%s</td></tr>\r\n", timeBuf, sizeBuf); } else if (dir->fancyIndexing == 1) { httpWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[ ]\", /> ", icon); httpWrite(q, "<a href=\"%s%s\">%s%s</a>%-*s %17s %4s\r\n", ep->name, dirSuffix, ep->name, dirSuffix, nameSize - len, "", timeBuf, sizeBuf); } else { httpWrite(q, "<li><a href=\"%s%s\"> %s%s</a></li>\r\n", ep->name, dirSuffix, ep->name, dirSuffix); } }
static void outputHeader(HttpQueue *q, cchar *path, int nameSize) { Dir *dir; char *parent, *parentSuffix; int reverseOrder, fancy, isRootDir; dir = q->conn->data; fancy = 1; path = mprEscapeHtml(path); httpWrite(q, "<!DOCTYPE HTML PUBLIC \"-/*W3C//DTD HTML 3.2 Final//EN\">\r\n"); httpWrite(q, "<html>\r\n <head>\r\n <title>Index of %s</title>\r\n", path); httpWrite(q, " </head>\r\n"); httpWrite(q, "<body>\r\n"); httpWrite(q, "<h1>Index of %s</h1>\r\n", path); if (dir->sortOrder > 0) { reverseOrder = 'D'; } else { reverseOrder = 'A'; } if (dir->fancyIndexing == 0) { fancy = '0'; } else if (dir->fancyIndexing == 1) { fancy = '1'; } else if (dir->fancyIndexing == 2) { fancy = '2'; } parent = mprGetPathDir(path); if (parent[strlen(parent) - 1] != '/') { parentSuffix = "/"; } else { parentSuffix = ""; } isRootDir = (strcmp(path, "/") == 0); if (dir->fancyIndexing == 2) { httpWrite(q, "<table><tr><th><img src=\"/icons/blank.gif\" alt=\"[ICO]\" /></th>"); httpWrite(q, "<th><a href=\"?C=N;O=%c;F=%c\">Name</a></th>", reverseOrder, fancy); httpWrite(q, "<th><a href=\"?C=M;O=%c;F=%c\">Last modified</a></th>", reverseOrder, fancy); httpWrite(q, "<th><a href=\"?C=S;O=%c;F=%c\">Size</a></th>", reverseOrder, fancy); httpWrite(q, "<th><a href=\"?C=D;O=%c;F=%c\">Description</a></th>\r\n", reverseOrder, fancy); httpWrite(q, "</tr><tr><th colspan=\"5\"><hr /></th></tr>\r\n"); if (! isRootDir) { httpWrite(q, "<tr><td valign=\"top\"><img src=\"/icons/back.gif\""); httpWrite(q, "alt=\"[DIR]\" /></td><td><a href=\"%s%s\">", parent, parentSuffix); httpWrite(q, "Parent Directory</a></td>"); httpWrite(q, "<td align=\"right\"> - </td></tr>\r\n"); } } else if (dir->fancyIndexing == 1) { httpWrite(q, "<pre><img src=\"/icons/space.gif\" alt=\"Icon\" /> "); httpWrite(q, "<a href=\"?C=N;O=%c;F=%c\">Name</a>%*s", reverseOrder, fancy, nameSize - 3, " "); httpWrite(q, "<a href=\"?C=M;O=%c;F=%c\">Last modified</a> ", reverseOrder, fancy); httpWrite(q, "<a href=\"?C=S;O=%c;F=%c\">Size</a> ", reverseOrder, fancy); httpWrite(q, "<a href=\"?C=D;O=%c;F=%c\">Description</a>\r\n", reverseOrder, fancy); httpWrite(q, "<hr />"); if (! isRootDir) { httpWrite(q, "<img src=\"/icons/parent.gif\" alt=\"[DIR]\" />"); httpWrite(q, " <a href=\"%s%s\">Parent Directory</a>\r\n", parent, parentSuffix); } } else { httpWrite(q, "<ul>\n"); if (! isRootDir) { httpWrite(q, "<li><a href=\"%s%s\"> Parent Directory</a></li>\r\n", parent, parentSuffix); } } }
static void reportFailure(MaConn *conn, int code, cchar *fmt, va_list args) { MaResponse *resp; MaRequest *req; cchar *url, *status; char *emsg, *msg, *filename; mprAssert(fmt); if (conn->requestFailed) { return; } conn->requestFailed = 1; if (fmt == 0) { fmt = ""; } req = conn->request; resp = conn->response; maDontCacheResponse(conn); msg = mprVasprintf(conn, MA_BUFSIZE, fmt, args); if (resp == 0 || req == 0) { mprLog(conn, 2, "\"%s\", code %d: %s.", mprGetHttpCodeString(conn, code), code, msg); } else { resp->code = code; filename = resp->filename ? resp->filename : 0; /* 711 is a custom error used by the test suite. */ if (code != 711) { mprLog(resp, 2, "Error: \"%s\", code %d for URI \"%s\", file \"%s\": %s.", mprGetHttpCodeString(conn, code), code, req->url ? req->url : "", filename ? filename : "", msg); } /* * Use an error document rather than standard error boilerplate. */ if (req->location) { url = maLookupErrorDocument(req->location, code); if (url && *url) { maRedirect(conn, 302, url); mprFree(msg); return; } } /* * If the headers have already been filled, this alternate response body will be ignored. */ if (resp->altBody == 0) { status = mprGetHttpCodeString(conn, code); /* * For security, escape the message */ emsg = mprEscapeHtml(resp, msg); resp->altBody = mprAsprintf(resp, -1, "<!DOCTYPE html>\r\n" "<html><head><title>Document Error: %s</title></head>\r\n" "<body><h2>Access Error: %d -- %s</h2>\r\n<p>%s</p>\r\n</body>\r\n</html>\r\n", status, code, status, emsg); } resp->flags |= MA_RESP_NO_BODY; } mprFree(msg); }
ssize espRenderSafeString(HttpConn *conn, cchar *s) { s = mprEscapeHtml(s); return espRenderBlock(conn, s, slen(s)); }
PUBLIC ssize httpWriteSafeString(HttpQueue *q, cchar *s) { return httpWriteString(q, mprEscapeHtml(s)); }