コード例 #1
0
ファイル: passHandler.c プロジェクト: ni-webtech/http
/*
    Handle Trace and Options requests. Handlers can do this themselves if they desire, but typically
    all Trace/Options requests come here.
 */
void httpHandleOptionsTrace(HttpConn *conn)
{
    HttpRx      *rx;
    HttpTx      *tx;
    int         flags;

    tx = conn->tx;
    rx = conn->rx;

    if (rx->flags & HTTP_TRACE) {
        /* The trace method is disabled by default unless 'TraceMethod on' is specified */
        if (!conn->limits->enableTraceMethod) {
            tx->status = HTTP_CODE_NOT_ACCEPTABLE;
            httpFormatResponseBody(conn, "Trace Request Denied", "The TRACE method is disabled on this server.");
        } else {
            httpFormatResponse(conn, "%s %s %s\r\n", rx->method, rx->uri, conn->protocol);
        }
        /* This finalizes output and indicates the request is now complete */
        httpFinalize(conn);

    } else if (rx->flags & HTTP_OPTIONS) {
        flags = tx->traceMethods;
        httpSetHeader(conn, "Allow", "OPTIONS%s%s%s%s%s%s",
            (conn->limits->enableTraceMethod) ? ",TRACE" : "",
            (flags & HTTP_STAGE_GET) ? ",GET" : "",
            (flags & HTTP_STAGE_HEAD) ? ",HEAD" : "",
            (flags & HTTP_STAGE_POST) ? ",POST" : "",
            (flags & HTTP_STAGE_PUT) ? ",PUT" : "",
            (flags & HTTP_STAGE_DELETE) ? ",DELETE" : "");
        httpOmitBody(conn);
        httpSetContentLength(conn, 0);
        httpFinalize(conn);
    }
}
コード例 #2
0
ファイル: ejsHttp.c プロジェクト: soffmodd/ejs-2
/*  
    function finalize(): Void
 */
static EjsObj *http_finalize(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    if (hp->conn) {
        httpFinalize(hp->conn);
    }
    return 0;
}
コード例 #3
0
ファイル: fileHandler.c プロジェクト: satanupup/appweb
/*
    The ready callback is invoked when all body data has been received
 */
static void readyFileHandler(HttpQueue *q)
{
    /*
        The queue already contains a single data packet representing all the output data.
     */
    httpFinalize(q->conn);
}
コード例 #4
0
ファイル: client.c プロジェクト: ni-webtech/http
/*  
    Write upload data. This routine blocks. If you need non-blocking ... cut and paste.
 */
ssize httpWriteUploadData(HttpConn *conn, MprList *fileData, MprList *formData)
{
    char    *path, *pair, *key, *value, *name;
    ssize   rc;
    int     next;

    rc = 0;
    if (formData) {
        for (rc = next = 0; rc >= 0 && (pair = mprGetNextItem(formData, &next)) != 0; ) {
            key = stok(sclone(pair), "=", &value);
            rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"%s\";\r\n", conn->boundary, key);
            rc += httpWrite(conn->writeq, "Content-Type: application/x-www-form-urlencoded\r\n\r\n%s\r\n", value);
        }
    }
    if (fileData) {
        for (rc = next = 0; rc >= 0 && (path = mprGetNextItem(fileData, &next)) != 0; ) {
            name = mprGetPathBase(path);
            rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"file%d\"; filename=\"%s\"\r\n", 
                conn->boundary, next - 1, name);
            rc += httpWrite(conn->writeq, "Content-Type: %s\r\n\r\n", mprLookupMime(MPR->mimeTypes, path));
            rc += blockingFileCopy(conn, path);
            rc += httpWrite(conn->writeq, "\r\n");
        }
    }
    rc += httpWrite(conn->writeq, "%s--\r\n--", conn->boundary);
    httpFinalize(conn);
    return rc;
}
コード例 #5
0
ファイル: server.c プロジェクト: WeiY/appweb-4
static void myaction(HttpConn *conn)
{
    HttpQueue   *q;

    q = conn->writeq;
    /*
        Set the HTTP response status
     */
    httpSetStatus(conn, 200);

    /*
        Add desired headers. "Set" will overwrite, add will create if not already defined.
     */
    httpAddHeaderString(conn, "Content-Type", "text/plain");
    httpSetHeaderString(conn, "Cache-Control", "no-cache");

    httpWrite(q, "<html><title>simpleAction</title><body>\r\n");
    httpWrite(q, "<p>Name: %s</p>\n", httpGetParam(conn, "name", "-"));
    httpWrite(q, "<p>Address: %s</p>\n", httpGetParam(conn, "address", "-"));
    httpWrite(q, "</body></html>\r\n");

    /*
        Call finalize output and close the request.
        Delay closing if you want to do asynchronous output and close later.
     */
    httpFinalize(conn);

#if POSSIBLE
    /*
        Useful things to do in actions
     */
    httpRedirect(conn, 302, "/other-uri");
    httpError(conn, 409, "My message : %d", 5);
#endif
}
コード例 #6
0
ファイル: passHandler.c プロジェクト: ni-webtech/http
static void readyError(HttpQueue *q)
{
    if (!q->conn->error) {
        httpError(q->conn, HTTP_CODE_SERVICE_UNAVAILABLE, "The requested resource is not available");
    }
    httpFinalize(q->conn);
}
コード例 #7
0
ファイル: ejsHttp.c プロジェクト: soffmodd/ejs-2
/*  
    function get(uri: String = null, ...data): Http
    The spec allows GET methods to have body data, but is rarely, if ever, used.
 */
static EjsHttp *http_get(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    startHttpRequest(ejs, hp, "GET", argc, argv);
    if (!ejs->exception && hp->conn) {
        httpFinalize(hp->conn);
    }
    return hp;
}
コード例 #8
0
ファイル: passHandler.c プロジェクト: embedthis/http
static void readyError(HttpQueue *q)
{
    if (!q->stream->error) {
        httpError(q->stream, HTTP_CODE_NOT_FOUND, "The requested resource is not available");
    }
    httpFinalize(q->stream);
    httpScheduleQueue(q);
}
コード例 #9
0
ファイル: espFramework.c プロジェクト: ni-webtech/appweb-4
void espAutoFinalize(HttpConn *conn) 
{
    EspReq  *req;

    req = conn->data;
    if (req->autoFinalize) {
        httpFinalize(conn);
    }
}
コード例 #10
0
ファイル: dirHandler.c プロジェクト: DavidQuan/http
/*
    Start the request (and complete it)
 */
static void startDir(HttpQueue *q)
{
    HttpConn        *conn;
    HttpTx          *tx;
    HttpRx          *rx;
    MprList         *list;
    MprDirEntry     *dp;
    HttpDir         *dir;
    cchar           *path;
    uint            nameSize;
    int             next;

    conn = q->conn;
    rx = conn->rx;
    tx = conn->tx;
    if ((dir = conn->reqData) == 0) {
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot get directory listing");
        return;
    }
    assert(tx->filename);

    if (!(rx->flags & (HTTP_GET | HTTP_HEAD))) {
        httpError(conn, HTTP_CODE_BAD_METHOD, "Bad method");
        return;
    }
    httpSetContentType(conn, "text/html");
    httpSetHeaderString(conn, "Cache-Control", "no-cache");
    httpSetHeaderString(conn, "Last-Modified", conn->http->currentDate);
    parseQuery(conn);

    if ((list = mprGetPathFiles(tx->filename, MPR_PATH_RELATIVE)) == 0) {
        httpWrite(q, "<h2>Cannot get file list</h2>\r\n");
        outputFooter(q);
        return;
    }
    if (dir->pattern) {
        filterDirList(conn, list);
    }
    sortList(conn, list);
    /*
        Get max filename size
     */
    nameSize = 0;
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        nameSize = max((int) strlen(dp->name), nameSize);
    }
    nameSize = max(nameSize, 22);

    path = rx->route->prefix ? sjoin(rx->route->prefix, rx->pathInfo, NULL) : rx->pathInfo;
    outputHeader(q, path, nameSize);
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        outputLine(q, dp, tx->filename, nameSize);
    }
    outputFooter(q);
    httpFinalize(conn);
}
コード例 #11
0
ファイル: ejsHttp.c プロジェクト: soffmodd/ejs-2
/*  
    function close(): Void
 */
static EjsObj *http_close(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    if (hp->conn) {
        httpFinalize(hp->conn);
        sendHttpCloseEvent(ejs, hp);
        httpDestroyConn(hp->conn);
        //  TODO OPT - Better to do this on demand. This consumes a conn until GC.
        hp->conn = httpCreateConn(ejs->http, NULL, ejs->dispatcher);
        httpPrepClientConn(hp->conn, 0);
        httpSetConnNotifier(hp->conn, httpEventChange);
        httpSetConnContext(hp->conn, hp);
    }
    return 0;
}
コード例 #12
0
ファイル: dirHandler.c プロジェクト: varphone/appweb-4
static void processDir(HttpQueue *q)
{
    HttpConn        *conn;
    HttpTx          *tx;
    HttpRx          *rx;
    MprList         *list;
    MprDirEntry     *dp;
    Dir             *dir;
    uint            nameSize;
    int             next;

    conn = q->conn;
    rx = conn->rx;
    tx = conn->tx;
    dir = conn->data;

    mprLog(5, "processDir");
    mprAssert(tx->filename);

    httpSetHeaderString(conn, "Cache-Control", "no-cache");
    httpSetHeaderString(conn, "Last-Modified", conn->http->currentDate);
    parseQuery(conn);

    list = mprGetPathFiles(tx->filename, 1);
    if (list == 0) {
        httpWrite(q, "<h2>Can't get file list</h2>\r\n");
        outputFooter(q);
        return;
    }
    if (dir->pattern) {
        filterDirList(conn, list);
    }
    sortList(conn, list);

    /*
        Get max filename
     */
    nameSize = 0;
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        nameSize = max((int) strlen(dp->name), nameSize);
    }
    nameSize = max(nameSize, 22);

    outputHeader(q, rx->pathInfo, nameSize);
    for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) {
        outputLine(q, dp, tx->filename, nameSize);
    }
    outputFooter(q);
    httpFinalize(conn);
}
コード例 #13
0
ファイル: cgiHandler.c プロジェクト: TryndamereStark/appweb
/*
    Read the output data from the CGI script and return it to the client. This is called by the MPR in response to
    I/O events from the CGI process for stdout/stderr data from the CGI script and for EOF from the CGI's stdin.
    IMPORTANT: This event runs on the connection's dispatcher. (ie. single threaded and safe)
 */
static void cgiCallback(MprCmd *cmd, int channel, void *data)
{
    HttpConn    *conn;
    Cgi         *cgi;
    int         suspended;

    if ((cgi = data) == 0) {
        return;
    }
    if ((conn = cgi->conn) == 0) {
        return;
    }
    conn->lastActivity = conn->http->now;

    switch (channel) {
    case MPR_CMD_STDIN:
        /* Stdin can absorb more data */
        httpResumeQueue(cgi->writeq);
        break;

    case MPR_CMD_STDOUT:
    case MPR_CMD_STDERR:
        readFromCgi(cgi, channel);
        break;
            
    default:
        /* Child death notification */
        if (cmd->status != 0) {
            httpError(cgi->conn, HTTP_CODE_BAD_GATEWAY, "Bad CGI process termination");
        }
        break;
    }
    if (cgi->location) {
        httpRedirect(conn, conn->tx->status, cgi->location);
    }
    if (cmd->complete || cgi->location) {
        cgi->location = 0;
        httpFinalize(conn);
        mprCreateEvent(conn->dispatcher, "cgiComplete", 0, httpIOEvent, conn, 0);
        return;
    } 
    suspended = httpIsQueueSuspended(conn->writeq);
    assert(!suspended || conn->tx->writeBlocked);
    mprEnableCmdOutputEvents(cmd, !suspended);
    mprCreateEvent(conn->dispatcher, "cgi", 0, httpIOEvent, conn, 0);
}
コード例 #14
0
ファイル: cgiHandler.c プロジェクト: fengyingzhuo/appweb
/*
    Read the output data from the CGI script and return it to the client. This is called by the MPR in response to
    I/O events from the CGI process for stdout/stderr data from the CGI script and for EOF from the CGI's stdin.
    IMPORTANT: This event runs on the connection's dispatcher. (ie. single threaded and safe)
 */
static void cgiCallback(MprCmd *cmd, int channel, void *data)
{
    HttpConn    *conn;
    Cgi         *cgi;
    int         suspended;

    if ((cgi = data) == 0) {
        return;
    }
    if ((conn = cgi->conn) == 0) {
        return;
    }
    conn->lastActivity = conn->http->now;
    mprTrace(6, "CGI: cgiCallback event channel %d", channel);

    switch (channel) {
    case MPR_CMD_STDIN:
        /* Stdin can absorb more data */
        httpResumeQueue(cgi->writeq);
        break;

    case MPR_CMD_STDOUT:
    case MPR_CMD_STDERR:
        readFromCgi(cgi, channel);
        break;
            
    default:
        /* Child death notification */
        break;
    }
    if (cgi->location) {
        httpRedirect(conn, conn->tx->status, cgi->location);
    }
    if (cmd->complete || cgi->location) {
        cgi->location = 0;
        httpFinalize(conn);
        mprCreateEvent(conn->dispatcher, "cgiComplete", 0, httpIOEvent, conn, 0);
        return;
    } 
    suspended = httpIsQueueSuspended(conn->writeq);
    mprTrace(6, "CGI: %s CGI: cgiCallback. Conn->writeq %d", suspended ? "DISABLE" : "ENABLE", conn->writeq->count);
    assert(!suspended || conn->tx->writeBlocked);
    mprEnableCmdOutputEvents(cmd, !suspended);
    mprCreateEvent(conn->dispatcher, "cgi", 0, httpIOEvent, conn, 0);
}
コード例 #15
0
ファイル: cache.c プロジェクト: ni-webtech/http
static void readyCacheHandler(HttpQueue *q) 
{
    HttpConn    *conn;
    HttpTx      *tx;
    cchar       *data;

    conn = q->conn;
    tx = conn->tx;

    if (tx->cachedContent) {
        mprLog(3, "cacheHandler: write cached content for '%s'", conn->rx->uri);
        if ((data = setHeadersFromCache(conn, tx->cachedContent)) != 0) {
            tx->length = slen(data);
            httpWriteString(q, data);
        }
    }
    httpFinalize(conn);
}
コード例 #16
0
ファイル: http.c プロジェクト: varphone/ejs-2
static int sendRequest(HttpConn *conn, cchar *method, cchar *url, MprList *files)
{
    if (httpConnect(conn, method, url, app->ssl) < 0) {
        mprError("Can't process request for \"%s\". %s.", url, httpGetError(conn));
        return MPR_ERR_CANT_OPEN;
    }
    /*  
        This program does not do full-duplex writes with reads. ie. if you have a request that sends and receives
        data in parallel -- http will do the writes first then read the response.
     */
    if (app->bodyData || app->formData || files) {
        if (writeBody(conn, files) < 0) {
            mprError("Can't write body data to \"%s\". %s", url, httpGetError(conn));
            return MPR_ERR_CANT_WRITE;
        }
    }
    mprAssert(!mprGetCurrentThread()->yielded);
    httpFinalize(conn);
    return 0;
}
コード例 #17
0
ファイル: cache.c プロジェクト: ni-webtech/http
ssize httpWriteCached(HttpConn *conn)
{
    MprTime     modified;
    cchar       *cacheKey, *data, *content;

    if (!conn->tx->cache) {
        return MPR_ERR_CANT_FIND;
    }
    cacheKey = makeCacheKey(conn);
    if ((content = mprReadCache(conn->host->responseCache, cacheKey, &modified, 0)) == 0) {
        mprLog(3, "No cached data for ", cacheKey);
        return 0;
    }
    mprLog(5, "Used cached ", cacheKey);
    data = setHeadersFromCache(conn, content);
    httpSetHeader(conn, "Etag", mprGetMD5(cacheKey));
    httpSetHeader(conn, "Last-Modified", mprFormatUniversalTime(MPR_HTTP_DATE, modified));
    conn->tx->cacheBuffer = 0;
    httpWriteString(conn->writeq, data);
    httpFinalize(conn);
    return slen(data);
}
コード例 #18
0
ファイル: passHandler.c プロジェクト: embedthis/http
static void handleTraceMethod(HttpStream *stream)
{
    HttpTx      *tx;
    HttpQueue   *q;
    HttpPacket  *traceData;

    tx = stream->tx;
    q = stream->writeq;


    /*
        Create a dummy set of headers to use as the response body. Then reset so the connector will create
        the headers in the normal fashion. Need to be careful not to have a content length in the headers in the body.
     */
    tx->flags |= HTTP_TX_NO_LENGTH;
    httpDiscardData(stream, HTTP_QUEUE_TX);
    traceData = httpCreateDataPacket(q->packetSize);
    httpCreateHeaders1(q, traceData);
    tx->flags &= ~(HTTP_TX_NO_LENGTH | HTTP_TX_HEADERS_CREATED);

    httpSetContentType(stream, "message/http");
    httpPutPacketToNext(q, traceData);
    httpFinalize(stream);
}
コード例 #19
0
ファイル: tx.c プロジェクト: adammendoza/http
/*
    Redirect the user to another web page. The targetUri may or may not have a scheme.
 */
PUBLIC void httpRedirect(HttpConn *conn, int status, cchar *targetUri)
{
    HttpTx          *tx;
    HttpRx          *rx;
    HttpUri         *target, *base;
    HttpEndpoint    *endpoint;
    cchar           *msg;
    char            *dir, *cp;

    assert(targetUri);
    rx = conn->rx;
    tx = conn->tx;

    if (tx->finalized) {
        /* A response has already been formulated */
        return;
    }
    tx->status = status;

    if (schr(targetUri, '$')) {
        targetUri = httpExpandUri(conn, targetUri);
    }
    mprLog(3, "redirect %d %s", status, targetUri);
    msg = httpLookupStatus(conn->http, status);

    if (300 <= status && status <= 399) {
        if (targetUri == 0) {
            targetUri = "/";
        }
        target = httpCreateUri(targetUri, 0);
        base = rx->parsedUri;
        /*
            Support URIs without a host:  https:///path. This is used to redirect onto the same host but with a 
            different scheme. So find a suitable local endpoint to supply the port for the scheme.
        */
        if (!target->port &&
                (!target->host || smatch(base->host, target->host)) &&
                (target->scheme && !smatch(target->scheme, base->scheme))) {
            endpoint = smatch(target->scheme, "https") ? conn->host->secureEndpoint : conn->host->defaultEndpoint;
            if (endpoint) {
                target->port = endpoint->port;
            } else {
                httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot find endpoint for scheme %s", target->scheme);
                return;
            }
        }
        if (target->path && target->path[0] != '/') {
            /*
                Relative file redirection to a file in the same directory as the previous request.
             */
            dir = sclone(rx->pathInfo);
            if ((cp = strrchr(dir, '/')) != 0) {
                /* Remove basename */
                *cp = '\0';
            }
            target->path = sjoin(dir, "/", target->path, NULL);
        }
        target = httpCompleteUri(target, base);
        targetUri = httpUriToString(target, 0);
        httpSetHeader(conn, "Location", "%s", targetUri);
        httpFormatResponse(conn, 
            "<!DOCTYPE html>\r\n"
            "<html><head><title>%s</title></head>\r\n"
            "<body><h1>%s</h1>\r\n<p>The document has moved <a href=\"%s\">here</a>.</p></body></html>\r\n",
            msg, msg, targetUri);
    } else {
        httpFormatResponse(conn, 
            "<!DOCTYPE html>\r\n"
            "<html><head><title>%s</title></head>\r\n"
            "<body><h1>%s</h1>\r\n</body></html>\r\n",
            msg, msg);
    }
    httpFinalize(conn);
}
コード例 #20
0
ファイル: pipeline.c プロジェクト: ni-webtech/http
void httpCreateTxPipeline(HttpConn *conn, HttpRoute *route)
{
    Http        *http;
    HttpTx      *tx;
    HttpRx      *rx;
    HttpQueue   *q;
    HttpStage   *stage, *filter;
    int         next, hasOutputFilters;

    mprAssert(conn);
    mprAssert(route);

    http = conn->http;
    rx = conn->rx;
    tx = conn->tx;

    tx->outputPipeline = mprCreateList(-1, 0);
    if (tx->handler == 0) {
        tx->handler = http->passHandler;
    }
    mprAddItem(tx->outputPipeline, tx->handler);

    hasOutputFilters = 0;
    if (route->outputStages) {
        for (next = 0; (filter = mprGetNextItem(route->outputStages, &next)) != 0; ) {
            if (matchFilter(conn, filter, route, HTTP_STAGE_TX) == HTTP_ROUTE_OK) {
                mprAddItem(tx->outputPipeline, filter);
                mprLog(4, "Select output filter: \"%s\"", filter->name);
                hasOutputFilters = 1;
            }
        }
    }
    if (tx->connector == 0) {
        if (tx->handler == http->fileHandler && (rx->flags & HTTP_GET) && !hasOutputFilters && 
                !conn->secure && httpShouldTrace(conn, HTTP_TRACE_TX, HTTP_TRACE_BODY, tx->ext) < 0) {
            tx->connector = http->sendConnector;
        } else if (route && route->connector) {
            tx->connector = route->connector;
        } else {
            tx->connector = http->netConnector;
        }
    }
    mprAddItem(tx->outputPipeline, tx->connector);
    mprLog(4, "Select connector: \"%s\"", tx->connector->name);

    /*  Create the outgoing queue heads and open the queues */
    q = tx->queue[HTTP_QUEUE_TX];
    for (next = 0; (stage = mprGetNextItem(tx->outputPipeline, &next)) != 0; ) {
        q = httpCreateQueue(conn, stage, HTTP_QUEUE_TX, q);
    }
    conn->writeq = tx->queue[HTTP_QUEUE_TX]->nextQ;
    conn->connectorq = tx->queue[HTTP_QUEUE_TX]->prevQ;
    pairQueues(conn);

    /*
        Put the header before opening the queues incase an open routine actually services and completes the request
        httpHandleOptionsTrace does this when called from openFile() in fileHandler.
     */
    httpPutForService(conn->writeq, httpCreateHeaderPacket(), HTTP_DELAY_SERVICE);
    openQueues(conn);

    /*
        Refinalize if httpFinalize was called before the Tx pipeline was created
     */
    if (conn->refinalize) {
        conn->finalized = 0;
        httpFinalize(conn);
    }
}
コード例 #21
0
ファイル: passHandler.c プロジェクト: embedthis/http
PUBLIC void httpHandleOptions(HttpStream *stream)
{
    httpSetHeaderString(stream, "Allow", httpGetRouteMethods(stream->rx->route));
    httpFinalize(stream);
}
コード例 #22
0
ファイル: passHandler.c プロジェクト: ni-webtech/http
static void readyPass(HttpQueue *q)
{
    httpFinalize(q->conn);
}
コード例 #23
0
ファイル: passHandler.c プロジェクト: embedthis/http
static void readyPass(HttpQueue *q)
{
    httpFinalize(q->stream);
    httpScheduleQueue(q);
}
コード例 #24
0
ファイル: phpHandler.c プロジェクト: satanupup/appweb
/*
    Run the request. This is invoked when all the input data has been received and buffered.
    This routine completely services the request.
 */
static void readyPhp(HttpQueue *q)
{
    HttpConn            *conn;
    HttpRx              *rx;
    HttpTx              *tx;
    MaPhp               *php;
    FILE                *fp;
    cchar               *value;
    char                shebang[MPR_MAX_STRING];
    zend_file_handle    file_handle;

    TSRMLS_FETCH();

    conn = q->conn;
    rx = conn->rx;
    tx = conn->tx;
    if ((php = q->queueData) == 0) {
        return;
    }
    /*
        Set the request context
     */
    zend_first_try {
        php->var_array = 0;
        SG(server_context) = conn;
        if (conn->username) {
            SG(request_info).auth_user = estrdup(conn->username);
        }
        if (conn->password) {
            SG(request_info).auth_password = estrdup(conn->password);
        }
        if ((value = httpGetHeader(conn, "Authorization")) != 0) {
            SG(request_info).auth_digest = estrdup(value);
        }
        SG(request_info).content_type = rx->mimeType;
        SG(request_info).path_translated = tx->filename;
        SG(request_info).content_length = (long) (ssize) rx->length;
        SG(sapi_headers).http_response_code = HTTP_CODE_OK;
        SG(request_info).query_string = rx->parsedUri->query;
        SG(request_info).request_method = rx->method;
        SG(request_info).request_uri = rx->uri;

        /*
            Workaround on MAC OS X where the SIGPROF is given to the wrong thread
         */
        PG(max_input_time) = -1;
        EG(timeout_seconds) = 0;

        /* The readBodyData callback may be invoked during startup */
        php_request_startup(TSRMLS_C);
        CG(zend_lineno) = 0;

    } zend_catch {
        mprError("Cannot start PHP request");
        zend_try {
            php_request_shutdown(0);
        } zend_end_try();
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP initialization failed");
        return;
    } zend_end_try();

    /*
        Execute the script file
     */
    file_handle.filename = tx->filename;
    file_handle.free_filename = 0;
    file_handle.opened_path = 0;

#if LOAD_FROM_FILE
    file_handle.type = ZEND_HANDLE_FILENAME;
#else
    file_handle.type = ZEND_HANDLE_FP;
    if ((fp = fopen(tx->filename, "r")) == NULL) {
        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", tx->filename);
        }
        return;
    }
    /*
        Check for shebang and skip
     */
    file_handle.handle.fp = fp;
    shebang[0] = '\0';
    if (fgets(shebang, sizeof(shebang), file_handle.handle.fp)) {}
    if (shebang[0] != '#' || shebang[1] != '!') {
        fseek(fp, 0L, SEEK_SET);
    }
#endif
    zend_try {
        php_execute_script(&file_handle TSRMLS_CC);
        if (!SG(headers_sent)) {
            sapi_send_headers(TSRMLS_C);
        }
    } zend_catch {
        php_request_shutdown(NULL);
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR,  "PHP script execution failed");
        return;
    } zend_end_try();

    zend_try {
        php_request_shutdown(NULL);
        SG(server_context) = NULL;
    } zend_catch {
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR,  "PHP script shutdown failed");
    } zend_end_try();

    httpFinalize(conn);
}
コード例 #25
0
ファイル: espFramework.c プロジェクト: ni-webtech/appweb-4
void espFinalize(HttpConn *conn) 
{
    httpFinalize(conn);
}
コード例 #26
0
ファイル: ejsHttp.c プロジェクト: soffmodd/ejs-2
/*
    function [get|put|delete|post...](uri = null, ...data): Http
 */
static EjsHttp *startHttpRequest(Ejs *ejs, EjsHttp *hp, char *method, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *data;
    EjsNumber       *written;
    EjsUri          *uriObj;
    HttpConn        *conn;
    ssize           nbytes;

    conn = hp->conn;
    hp->responseCache = 0;
    hp->requestContentCount = 0;
    mprFlushBuf(hp->responseContent);

    if (argc >= 1 && !ejsIs(ejs, argv[0], Null)) {
        uriObj = (EjsUri*) argv[0];
        hp->uri = httpUriToString(uriObj->uri, HTTP_COMPLETE_URI);
    }
    if (argc == 2 && ejsIs(ejs, argv[1], Array)) {
        args = (EjsArray*) argv[1];
        if (args->length > 0) {
            data = ejsCreateByteArray(ejs, -1);
            written = ejsWriteToByteArray(ejs, data, 1, &argv[1]);
            mprPutBlockToBuf(hp->requestContent, (char*) data->value, (int) written->value);
            mprAddNullToBuf(hp->requestContent);
            assert(written > 0);
        }
    }
    if (hp->uri == 0) {
        ejsThrowArgError(ejs, "URL is not defined");
        return 0;
    }
    if (method && strcmp(hp->method, method) != 0) {
        hp->method = sclone(method);
    }
    if (hp->method == 0) {
        ejsThrowArgError(ejs, "HTTP Method is not defined");
        return 0;
    }
    if (hp->certFile) {
        if (!hp->ssl) {
            hp->ssl = mprCreateSsl(0);
        }
        mprSetSslCertFile(hp->ssl, hp->certFile);
        if (!hp->keyFile) {
            ejsThrowStateError(ejs, "Must define a Http.key to use with a certificate");
        }
        mprSetSslKeyFile(hp->ssl, hp->keyFile);
    }
    if (hp->caFile) {
        if (!hp->ssl) {
            hp->ssl = mprCreateSsl(0);
        }
        mprSetSslCaFile(hp->ssl, hp->caFile);
    }
    if (httpConnect(conn, hp->method, hp->uri, hp->ssl) < 0) {
        ejsThrowIOError(ejs, "Cannot issue request for \"%s\"", hp->uri);
        return 0;
    }
    if (mprGetBufLength(hp->requestContent) > 0) {
        nbytes = httpWriteBlock(conn->writeq, mprGetBufStart(hp->requestContent), mprGetBufLength(hp->requestContent),
            HTTP_BLOCK);
        if (nbytes < 0) {
            ejsThrowIOError(ejs, "Cannot write request data for \"%s\"", hp->uri);
            return 0;
        } else if (nbytes > 0) {
            assert(nbytes == mprGetBufLength(hp->requestContent));
            mprAdjustBufStart(hp->requestContent, nbytes);
            hp->requestContentCount += nbytes;
        }
        httpFinalize(conn);
    }
    httpNotify(conn, HTTP_EVENT_WRITABLE, 0);
    if (conn->async) {
        httpEnableConnEvents(hp->conn);
    }
    return hp;
}
コード例 #27
0
ファイル: error.c プロジェクト: adammendoza/http
/*
    The current request has an error and cannot complete as normal. This call sets the Http response status and 
    overrides the normal output with an alternate error message. If the output has alread started (headers sent), then
    the connection MUST be closed so the client can get some indication the request failed.
 */
static void errorv(HttpConn *conn, int flags, cchar *fmt, va_list args)
{
    HttpRx      *rx;
    HttpTx      *tx;
    cchar       *uri;
    int         status;

    assert(fmt);
    rx = conn->rx;
    tx = conn->tx;

    if (conn == 0) {
        return;
    }
    status = flags & HTTP_CODE_MASK;
    if (status == 0) {
        status = HTTP_CODE_INTERNAL_SERVER_ERROR;
    }
    if (flags & (HTTP_ABORT | HTTP_CLOSE)) {
        conn->keepAliveCount = 0;
    }
    if (flags & HTTP_ABORT) {
        conn->connError = 1;
        if (rx) {
            rx->eof = 1;
        }
    }
    if (!conn->error) {
        conn->error = 1;
        httpOmitBody(conn);
        conn->errorMsg = formatErrorv(conn, status, fmt, args);
        mprLog(2, "Error: %s", conn->errorMsg);

        HTTP_NOTIFY(conn, HTTP_EVENT_ERROR, 0);
        if (conn->endpoint) {
            if (status == HTTP_CODE_NOT_FOUND) {
                httpMonitorEvent(conn, HTTP_COUNTER_NOT_FOUND_ERRORS, 1);
            }
            httpMonitorEvent(conn, HTTP_COUNTER_ERRORS, 1);
        }
        httpAddHeaderString(conn, "Cache-Control", "no-cache");
        if (conn->endpoint && tx && rx) {
            if (tx->flags & HTTP_TX_HEADERS_CREATED) {
                /* 
                    If the response headers have been sent, must let the other side of the failure ... aborting
                    the request is the only way as the status has been sent.
                 */
                flags |= HTTP_ABORT;
            } else {
                if (rx->route && (uri = httpLookupRouteErrorDocument(rx->route, tx->status)) && !smatch(uri, rx->uri)) {
                    errorRedirect(conn, uri);
                } else {
                    makeAltBody(conn, status);
                }
            }
        }
        httpFinalize(conn);
    }
    if (flags & HTTP_ABORT) {
        httpDisconnect(conn);
    }
}