예제 #1
0
파일: pipeline.c 프로젝트: jsjohnst/appweb
/*
 *  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;
}
예제 #2
0
파일: request.c 프로젝트: gamman/appweb-3
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;
}
예제 #3
0
파일: pipeline.c 프로젝트: jsjohnst/appweb
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);
    }
}
예제 #4
0
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);
    }
}