/* * Manage requests to directories. This will either do an external redirect back to the browser or do an internal * (transparent) redirection and serve different content back to the browser. This routine may modify the requested * URI and/or the request handler. */ static void processDirectory(MaConn *conn, bool *rescan) { MaRequest *req; MaResponse *resp; MprFileInfo *info; char path[MPR_MAX_FNAME], urlBuf[MPR_MAX_FNAME], *index; int len; req = conn->request; resp = conn->response; info = &resp->fileInfo; mprAssert(info->isDir); index = req->dir->indexName; if (req->url[strlen(req->url) - 1] == '/') { /* * Internal directory redirections */ len = (int) strlen(resp->filename); if (resp->filename[len - 1] == '/') { resp->filename[len - 1] = '\0'; } path[0] = '\0'; mprAssert(resp->filename && *resp->filename); mprAssert(index && *index); mprStrcat(path, sizeof(path), NULL, resp->filename, "/", index, NULL); if (mprAccess(resp, path, R_OK)) { /* * Index file exists, so do an internal redirect to it. Client will not be aware of this happening. * Must rematch the handler on return. */ maSetRequestUri(conn, addIndex(conn, urlBuf, sizeof(urlBuf), index)); resp->filename = mprStrdup(resp, path); mprGetFileInfo(conn, resp->filename, &resp->fileInfo); resp->extension = getExtension(conn); if ((resp->mimeType = (char*) maLookupMimeType(conn->host, resp->extension)) == 0) { resp->mimeType = (char*) "text/html"; } *rescan = 1; } return; } /* * External redirect. Ask the client to re-issue a request for a new location. See if an index exists and if so, * construct a new location for the index. If the index can't be accessed, just append a "/" to the URI and redirect. */ if (req->parsedUri->query && req->parsedUri->query[0]) { mprSprintf(path, sizeof(path), "%s/%s?%s", req->url, index, req->parsedUri->query); } else { mprSprintf(path, sizeof(path), "%s/%s", req->url, index); } if (!mprAccess(resp, path, R_OK)) { mprSprintf(path, sizeof(path), "%s/", req->url); } maRedirect(conn, MPR_HTTP_CODE_MOVED_PERMANENTLY, path); resp->handler = conn->http->passHandler; }
int maSetRequestUri(MaConn *conn, cchar *uri, cchar *query) { MaRequest *req; MaResponse *resp; MaHost *host; MprUri *prior; char *cp; if (uri == 0 || *uri == 0) { uri = "/"; } host = conn->host; req = conn->request; resp = conn->response; prior = req->parsedUri; if ((req->parsedUri = mprParseUri(req, uri)) == 0) { return MPR_ERR_BAD_ARGS; } if (prior) { if ((cp = strstr(uri, "://")) == 0) { req->parsedUri->scheme = prior->scheme; req->parsedUri->host = prior->host; } else if (strchr(&cp[3], ':') == 0) { req->parsedUri->port = prior->port; } } if (query == 0 && prior) { req->parsedUri->query = prior->query; } else if (*query) { req->parsedUri->query = mprStrdup(req->parsedUri, query); } req->url = mprValidateUrl(req, mprUrlDecode(req, req->parsedUri->url)); req->alias = maGetAlias(host, req->url); resp->filename = maMakeFilename(conn, req->alias, req->url, 1); if ((req->dir = maLookupBestDir(req->host, resp->filename)) != 0) { if (req->dir->auth) { req->auth = req->dir->auth; } } req->location = maLookupBestLocation(host, req->url); if (req->auth == 0) { req->auth = req->location->auth; } mprGetPathInfo(conn, resp->filename, &resp->fileInfo); resp->extension = maGetExtension(conn); if ((resp->mimeType = (char*) maLookupMimeType(host, resp->extension)) == 0) { resp->mimeType = (char*) "text/html"; } return 0; }
static void setEnv(MaConn *conn) { MaRequest *req; MaResponse *resp; MaStage *handler; MprFileInfo *info; req = conn->request; resp = conn->response; handler = resp->handler; setPathInfo(conn); if (resp->extension == 0) { resp->extension = getExtension(conn); } if (resp->filename == 0) { resp->filename = makeFilename(conn, req->alias, req->url, 1); } if ((resp->mimeType = (char*) maLookupMimeType(conn->host, resp->extension)) == 0) { resp->mimeType = (char*) "text/html"; } if (!(resp->handler->flags & MA_STAGE_VIRTUAL)) { /* * Define an Etag for physical entities. Redo the file info if not valid now that extra path has been removed. */ info = &resp->fileInfo; if (!info->valid) { mprGetFileInfo(conn, resp->filename, info); } if (info->valid) { mprAllocSprintf(resp, &resp->etag, -1, "%x-%Lx-%Lx", info->inode, info->size, info->mtime); } } if (handler->flags & MA_STAGE_FORM_VARS) { req->formVars = mprCreateHash(req, MA_VAR_HASH_SIZE); if (req->parsedUri->query) { maAddFormVars(conn, req->parsedUri->query, (int) strlen(req->parsedUri->query)); } } if (handler->flags & MA_STAGE_ENV_VARS) { maCreateEnvVars(conn); } }
static void outputLine(MaQueue *q, MprDirEntry *ep, cchar *path, int nameSize) { MprPath info; Dir *dir; MprTime when; MaHost *host; 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" }; dir = q->stage->stageData; 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 { mprSprintf(sizeBuf, sizeof(sizeBuf), "%6d", (int) ep->size); } newPath = mprJoinPath(q, path, ep->name); if (mprGetPathInfo(q, newPath, &info) < 0) { when = mprGetTime(q); isDir = 0; } else { isDir = info.isDir ? 1 : 0; when = (MprTime) info.mtime * MPR_TICKS_PER_SEC; } mprFree(newPath); if (isDir) { icon = "folder"; dirSuffix = "/"; } else { host = q->conn->host; ext = mprGetPathExtension(q, ep->name); if ((mimeType = maLookupMimeType(host, 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(q, &tm, when); mprSprintf(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) { maWrite(q, "<tr><td valign=\"top\">"); maWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[ ]\", /></td>", icon); maWrite(q, "<td><a href=\"%s%s\">%s%s</a></td>", ep->name, dirSuffix, ep->name, dirSuffix); maWrite(q, "<td>%s</td><td>%s</td></tr>\r\n", timeBuf, sizeBuf); } else if (dir->fancyIndexing == 1) { maWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[ ]\", /> ", icon); maWrite(q, "<a href=\"%s%s\">%s%s</a>%-*s %17s %4s\r\n", ep->name, dirSuffix, ep->name, dirSuffix, nameSize - len, "", timeBuf, sizeBuf); } else { maWrite(q, "<li><a href=\"%s%s\"> %s%s</a></li>\r\n", ep->name, dirSuffix, ep->name, dirSuffix); } }