Example #1
0
/*
    Open the handler for a new request
 */
static int openCgi(HttpQueue *q)
{
    HttpConn    *conn;
    Cgi         *cgi;
    int         nproc;

    conn = q->conn;
    if ((nproc = (int) httpMonitorEvent(conn, HTTP_COUNTER_ACTIVE_PROCESSES, 1)) >= conn->limits->processMax) {
        httpTrace(conn, "cgi.limit.error", "error", 
            "msg=\"Too many concurrent processes\", activeProcesses=%d, maxProcesses=%d", 
            nproc, conn->limits->processMax);
        httpError(conn, HTTP_CODE_SERVICE_UNAVAILABLE, "Server overloaded");
        httpMonitorEvent(q->conn, HTTP_COUNTER_ACTIVE_PROCESSES, -1);
        return MPR_ERR_CANT_OPEN;
    }
    if ((cgi = mprAllocObj(Cgi, manageCgi)) == 0) {
        /* Normal mem handler recovery */ 
        return MPR_ERR_MEMORY;
    }
    httpTrimExtraPath(conn);
    httpMapFile(conn);
    httpCreateCGIParams(conn);

    q->queueData = q->pair->queueData = cgi;
    cgi->conn = conn;
    cgi->readq = httpCreateQueue(conn, conn->http->cgiConnector, HTTP_QUEUE_RX, 0);
    cgi->writeq = httpCreateQueue(conn, conn->http->cgiConnector, HTTP_QUEUE_TX, 0);
    cgi->readq->pair = cgi->writeq;
    cgi->writeq->pair = cgi->readq;
    cgi->writeq->queueData = cgi->readq->queueData = cgi;
    return 0;
}
Example #2
0
/*
    Open handler for a new request
 */
static void openPhp(HttpQueue *q)
{
    HttpRx      *rx;

    rx = q->conn->rx;

    /*
        PHP will buffer all input. i.e. does not stream. The normal Limits still apply.
     */
    q->max = q->pair->max = MAXINT;
    mprLog(5, "Open php handler");
    httpTrimExtraPath(q->conn);
    if (rx->flags & (HTTP_OPTIONS | HTTP_TRACE)) {
        httpHandleOptionsTrace(q->conn, "DELETE,GET,HEAD,POST,PUT");

    } else if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST | HTTP_PUT)) {
        httpMapFile(q->conn, rx->route);
        if (!q->stage->stageData) {
            if (initializePhp(q->conn->http) < 0) {
                httpError(q->conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP initialization failed");
            }
            q->stage->stageData = mprAlloc(1);
        }
        q->queueData = mprAllocObj(MaPhp, NULL);

    } else {
        httpError(q->conn, HTTP_CODE_BAD_METHOD, "Method not supported by file handler: %s", rx->method);
    }
}
Example #3
0
/*
    Rewrite the request for directories, indexes and compressed content. 
 */
static int rewriteFileHandler(HttpConn *conn)
{
    HttpRx      *rx;
    HttpTx      *tx;
    MprPath     *info;

    rx = conn->rx;
    tx = conn->tx;
    info = &tx->fileInfo;

    httpMapFile(conn);
    assert(info->checked);

    if (rx->flags & (HTTP_DELETE | HTTP_PUT)) {
        return HTTP_ROUTE_OK;
    }
    if (info->isDir) {
        return handleDirectory(conn);
    }
    if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST) && info->valid && 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);
    }
    return HTTP_ROUTE_OK;
}
Example #4
0
/*
    Render a document by mapping a URL target to a document. The target is interpreted relative to route->documents.
    If target exists, then serve that.
    If target + extension exists, serve that.
    If target is a directory and an index.esp, return the index.esp without a redirect.
    If target is a directory without a trailing "/" but with an index.esp, do an external redirect to "URI/".
    If target does not end with ".esp", then do not serve that.
 */
PUBLIC void espRenderDocument(HttpConn *conn, cchar *target)
{
    HttpUri     *up;
    MprKey      *kp;
    cchar       *dest;

    assert(target);

    for (ITERATE_KEYS(conn->rx->route->extensions, kp)) {
        if (kp->key && *kp->key) {
            if ((dest = checkView(conn, target, 0, kp->key)) != 0) {
                espRenderView(conn, dest, 0);
                return;
            }
        }
    }
    if ((dest = checkView(conn, target, 0, "esp")) != 0) {
        espRenderView(conn, dest, 0);
        return;
    }
    if ((dest = checkView(conn, target, "index", "esp")) != 0) {
        /*
            Must do external redirect first if URL does not end with "/"
         */
        if (!sends(conn->rx->parsedUri->path, "/")) {
            up = conn->rx->parsedUri;
            httpRedirect(conn, HTTP_CODE_MOVED_PERMANENTLY, httpFormatUri(up->scheme, up->host,
                up->port, sjoin(up->path, "/", NULL), up->reference, up->query, 0));
            return;
        }
        espRenderView(conn, dest, 0);
        return;
    }
/* 
    Remove in version 6 
*/
#if DEPRECATED || 1
    if ((dest = checkView(conn, sjoin("app/", target, NULL), 0, "esp")) != 0) {
        espRenderView(conn, dest, 0);
        return;
    }
#endif
    /*
        Last chance, forward to the file handler ... not an ESP request. 
        This enables static file requests within ESP routes.
     */
    httpTrace(conn, "esp.handler", "context", "msg: 'Relay to the fileHandler");
    conn->rx->target = &conn->rx->pathInfo[1];
    httpMapFile(conn);
    if (conn->tx->fileInfo.isDir) {
        httpHandleDirectory(conn);
    }
    httpSetFileHandler(conn, 0);
}
Example #5
0
/*
    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;
}