/* Test if the request matches. This may delegate the request to the dirHandler if a directory listing is required. */ static int matchFileHandler(HttpConn *conn, HttpRoute *route, int dir) { HttpRx *rx; HttpTx *tx; HttpUri *prior; MprPath *info, zipInfo; cchar *index; char *path, *pathInfo, *uri, *zipfile; int next; printf("\n matchFileHandler \n"); rx = conn->rx; tx = conn->tx; rx = conn->rx; prior = rx->parsedUri; info = &tx->fileInfo; httpMapFile(conn, route); assure(info->checked); if (rx->flags & (HTTP_DELETE | HTTP_PUT)) { return HTTP_ROUTE_OK; } if (info->isDir) { /* Manage requests for directories */ if (!sends(rx->pathInfo, "/")) { /* Append "/" and do an external redirect */ pathInfo = sjoin(rx->pathInfo, "/", NULL); uri = httpFormatUri(prior->scheme, prior->host, prior->port, pathInfo, prior->reference, prior->query, 0); httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri); return HTTP_ROUTE_OK; } if (route->indicies) { /* Ends with a "/" so do internal redirection to an index file */ for (ITERATE_ITEMS(route->indicies, index, next)) { /* Internal directory redirections. Transparently append index. Test indicies in order. */ path = mprJoinPath(tx->filename, index); if (mprPathExists(path, R_OK)) { pathInfo = sjoin(rx->scriptName, rx->pathInfo, index, NULL); uri = httpFormatUri(prior->scheme, prior->host, prior->port, pathInfo, prior->reference, prior->query, 0); httpSetUri(conn, uri); tx->filename = path; tx->ext = httpGetExt(conn); mprGetPathInfo(tx->filename, info); return HTTP_ROUTE_REROUTE; } } } /* If a directory, test if a directory listing should be rendered. If so, delegate to the dirHandler. Cannot use the sendFile handler and must use the netConnector. */ if (info->isDir && maRenderDirListing(conn)) { tx->handler = conn->http->dirHandler; tx->connector = conn->http->netConnector; return HTTP_ROUTE_OK; } } if (!info->valid && (route->flags & HTTP_ROUTE_GZIP) && rx->acceptEncoding && strstr(rx->acceptEncoding, "gzip") != 0) { /* If the route accepts zipped data and a zipped file exists, then transparently respond with it. */ zipfile = sfmt("%s.gz", tx->filename); if (mprGetPathInfo(zipfile, &zipInfo) == 0) { tx->filename = zipfile; tx->fileInfo = zipInfo; httpSetHeader(conn, "Content-Encoding", "gzip"); } } if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST) && info->valid && !info->isDir && tx->length < 0) { /* The sendFile connector is optimized on some platforms to use the sendfile() system call. Set the entity length for the sendFile connector to utilize. */ httpSetEntityLength(conn, tx->fileInfo.size); } printf("\n-------------------------\n"); printf("tx->filename:\t%s",tx->filename); printf("\n-------------------------\n"); return HTTP_ROUTE_OK; }
static int handleDirectory(HttpConn *conn) { HttpRx *rx; HttpTx *tx; HttpRoute *route; HttpUri *req; MprPath *info; cchar *index, *pathInfo, *uri; char *path; int next; rx = conn->rx; tx = conn->tx; req = rx->parsedUri; route = rx->route; info = &tx->fileInfo; /* Manage requests for directories */ if (!sends(req->path, "/")) { /* Append "/" and do an external redirect. Use the original request URI. */ pathInfo = sjoin(req->path, "/", NULL); uri = httpFormatUri(req->scheme, req->host, req->port, pathInfo, req->reference, req->query, 0); httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, uri); return HTTP_ROUTE_OK; } if (route->indexes) { /* Ends with a "/" so do internal redirection to an index file */ for (ITERATE_ITEMS(route->indexes, index, next)) { /* Internal directory redirections. Transparently append index. Test indexes in order. */ path = mprJoinPath(tx->filename, index); if (mprPathExists(path, R_OK)) { pathInfo = sjoin(rx->scriptName, rx->pathInfo, index, NULL); uri = httpFormatUri(req->scheme, req->host, req->port, pathInfo, req->reference, req->query, 0); httpSetUri(conn, uri); tx->filename = path; tx->ext = httpGetExt(conn); mprGetPathInfo(tx->filename, info); return HTTP_ROUTE_REROUTE; } } } #if ME_COM_DIR /* Directory Listing. If a directory, test if a directory listing should be rendered. If so, delegate to the dirHandler. Cannot use the sendFile handler and must use the netConnector. */ if (info->isDir && httpRenderDirListing(conn)) { tx->handler = conn->http->dirHandler; tx->connector = conn->http->netConnector; return HTTP_ROUTE_OK; } #endif return HTTP_ROUTE_OK; }