示例#1
0
static void openFileHandler(HttpQueue *q)
{
    HttpRx      *rx;
    HttpTx      *tx;
    HttpRoute   *route;
    HttpConn    *conn;
    MprPath     *info;
    char        *date;

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

    if (rx->flags & (HTTP_PUT | HTTP_DELETE)) {
        if (!(route->flags & HTTP_ROUTE_PUT_DELETE_METHODS)) {
            httpError(q->conn, HTTP_CODE_BAD_METHOD, "The \"%s\" method is not supported by file handler", rx->method);
        }
    } else {
        if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST)) {
            if (!(info->valid || info->isDir)) {
                if (rx->referrer) {
                    mprLog(2, "fileHandler: Cannot find filename %s from referrer %s", tx->filename, rx->referrer);
                } else {
                    mprLog(2, "fileHandler: Cannot find filename %s", tx->filename);
                }
                httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot find %s", rx->uri);

            } else if (info->valid) {
                if (!tx->etag) {
                    /* Set the etag for caching in the client */
                    tx->etag = sfmt("\"%Lx-%Lx-%Lx\"", (int64) info->inode, (int64) info->size, (int64) info->mtime);
                }
            }
        }
        if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST) && !conn->error) {
            if (tx->fileInfo.valid && tx->fileInfo.mtime) {
                //  TODO - OPT could cache this
                date = httpGetDateString(&tx->fileInfo);
                httpSetHeader(conn, "Last-Modified", date);
            }
            if (httpContentNotModified(conn)) {
                httpSetStatus(conn, HTTP_CODE_NOT_MODIFIED);
                httpOmitBody(conn);
                tx->length = -1;
            }
            if (!tx->fileInfo.isReg && !tx->fileInfo.isLink) {
                httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot locate document: %s", rx->uri);
                
            } else if (tx->fileInfo.size > conn->limits->transmissionBodySize) {
                httpError(conn, HTTP_ABORT | HTTP_CODE_REQUEST_TOO_LARGE,
                    "Http transmission aborted. File size exceeds max body of %,Ld bytes", 
                        conn->limits->transmissionBodySize);
                
            } else if (!(tx->connector == conn->http->sendConnector)) {
                /*
                    If using the net connector, open the file if a body must be sent with the response. The file will be
                    automatically closed when the request completes.
                 */
                if (!(tx->flags & HTTP_TX_NO_BODY)) {
                    tx->file = mprOpenFile(tx->filename, O_RDONLY | O_BINARY, 0);
                    if (tx->file == 0) {
                        if (rx->referrer) {
                            httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open document: %s from %s", 
                                tx->filename, rx->referrer);
                        } else {
                            httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open document: %s from %s", tx->filename);
                        }
                    }
                }
            }

        } else if (rx->flags & (HTTP_OPTIONS | HTTP_TRACE)) {
            if (route->flags & HTTP_ROUTE_PUT_DELETE_METHODS) {
                httpHandleOptionsTrace(q->conn, "DELETE,GET,HEAD,POST,PUT");
            } else {
                httpHandleOptionsTrace(q->conn, "GET,HEAD,POST");
            }
        }
    }

	
}
示例#2
0
static int openFileHandler(HttpQueue *q)
{
    HttpRx      *rx;
    HttpTx      *tx;
    HttpConn    *conn;
    MprPath     *info;
    char        *date, dbuf[16];
    MprHash     *dateCache;

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

    if (conn->error) {
        return MPR_ERR_CANT_OPEN;
    }
    if (rx->flags & (HTTP_GET | HTTP_HEAD | HTTP_POST)) {
        if (!(info->valid || info->isDir)) {
            httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot find document");
            return 0;
        } 
        if (!tx->etag) {
            /* Set the etag for caching in the client */
            tx->etag = sfmt("\"%llx-%llx-%llx\"", (int64) info->inode, (int64) info->size, (int64) info->mtime);
        }
        if (info->mtime) {
            dateCache = conn->http->dateCache;
            if ((date = mprLookupKey(dateCache, itosbuf(dbuf, sizeof(dbuf), (int64) info->mtime, 10))) == 0) {
                if (!dateCache || mprGetHashLength(dateCache) > 128) {
                    conn->http->dateCache = dateCache = mprCreateHash(0, 0);
                }
                date = httpGetDateString(&tx->fileInfo);
                mprAddKey(dateCache, itosbuf(dbuf, sizeof(dbuf), (int64) info->mtime, 10), date);
            }
            httpSetHeaderString(conn, "Last-Modified", date);
        }
        if (httpContentNotModified(conn)) {
            httpSetStatus(conn, HTTP_CODE_NOT_MODIFIED);
            httpOmitBody(conn);
            tx->length = -1;
        }
        if (!tx->fileInfo.isReg && !tx->fileInfo.isLink) {
            httpTrace(conn, "request.document.error", "error", "msg: 'Document is not a regular file', filename: '%s'", 
                tx->filename);
            httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot serve document");
            
        } else if (tx->fileInfo.size > conn->limits->transmissionBodySize) {
            httpError(conn, HTTP_ABORT | HTTP_CODE_REQUEST_TOO_LARGE,
                "Http transmission aborted. File size exceeds max body of %'lld bytes",
                    conn->limits->transmissionBodySize);
            
        } else if (!(tx->connector == conn->http->sendConnector)) {
            /*
                If using the net connector, open the file if a body must be sent with the response. The file will be
                automatically closed when the request completes.
             */
            if (!(tx->flags & HTTP_TX_NO_BODY)) {
                tx->file = mprOpenFile(tx->filename, O_RDONLY | O_BINARY, 0);
                if (tx->file == 0) {
                    if (rx->referrer && *rx->referrer) {
                        httpTrace(conn, "request.document.error", "error", 
                            "msg: 'Cannot open document', filename: '%s', referrer: '%s'", 
                            tx->filename, rx->referrer);
                    } else {
                        httpTrace(conn, "request.document.error", "error", 
                            "msg: 'Cannot open document', filename: '%s'", tx->filename);
                    }
                    httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open document");
                }
            }
        }
    } else if (rx->flags & (HTTP_DELETE | HTTP_OPTIONS | HTTP_PUT)) {
        ;
    } else {
        httpError(conn, HTTP_CODE_BAD_METHOD, "Unsupported method");
    }
    return 0;
}