static void
processDataFromClient(TConn *      const connectionP,
                      abyss_bool   const lastReqOnConn,
                      abyss_bool * const keepAliveP) {

    TSession session;

    RequestInit(&session, connectionP);

    session.serverDeniesKeepalive = lastReqOnConn;
        
    RequestRead(&session);
    if (session.status == 0) {
        if (session.version.major >= 2)
            ResponseStatus(&session, 505);
        else if (!RequestValidURI(&session))
            ResponseStatus(&session, 400);
        else
            runUserHandler(&session, connectionP->server->srvP);
    }
    assert(session.status != 0);
    
    if (session.responseStarted)
        HTTPWriteEndChunk(&session);
    else
        ResponseError(&session);

    *keepAliveP = HTTPKeepalive(&session);
    
    SessionLog(&session);

    RequestFree(&session);
}
static void
addConnectionHeaderFld(TSession * const sessionP) {

    struct _TServer * const srvP = ConnServer(sessionP->connP)->srvP;

    if (HTTPKeepalive(sessionP)) {
        const char * keepaliveValue;
        
        ResponseAddField(sessionP, "Connection", "Keep-Alive");

        xmlrpc_asprintf(&keepaliveValue, "timeout=%u, max=%u",
                        srvP->keepalivetimeout, srvP->keepalivemaxconn);

        ResponseAddField(sessionP, "Keep-Alive", keepaliveValue);

        xmlrpc_strfree(keepaliveValue);
    } else
        ResponseAddField(sessionP, "Connection", "close");
}
Beispiel #3
0
static void
processRequestFromClient(TConn *  const connectionP,
                         bool     const lastReqOnConn,
                         uint32_t const timeout,
                         bool *   const keepAliveP) {
/*----------------------------------------------------------------------------
   Get and execute one HTTP request from client connection *connectionP,
   through the connection buffer.  I.e. Some of the request may already be in
   the connection buffer, and we may leave some of later requests in the
   connection buffer.

   In fact, due to timing considerations, we assume the client has begun
   sending the request, which as a practical matter means Caller has already
   deposited some of it in the connection buffer.

   If there isn't one full request in the buffer now, we wait for one full
   request to come through the buffer, up to 'timeout'.

   We return as *keepAliveP whether Caller should keep the connection
   alive for a while for possible future requests from the client, based
   on 'lastReqOnConn' and the content of the HTTP request.

   Executing the request consists primarily of calling the URI handlers that
   are associated with the connection (*connectionP), passing each the request
   information we read.  Each handler can respond according to the HTTP method
   (GET, POST, etc) and URL etc, and that response may be either to
   execute the request and send the response or refuse the request and let
   us call the next one in the list.
-----------------------------------------------------------------------------*/
    TSession session;
    const char * error;
    uint16_t httpErrorCode;

    RequestInit(&session, connectionP);

    session.serverDeniesKeepalive = lastReqOnConn;
        
    RequestRead(&session, timeout, &error, &httpErrorCode);

    if (error) {
        ResponseStatus(&session, httpErrorCode);
        ResponseError2(&session, error);
        xmlrpc_strfree(error);
    } else {
        if (session.version.major >= 2)
            handleReqTooNewHttpVersion(&session);
        else if (!RequestValidURI(&session))
            handleReqInvalidURI(&session);
        else
            runUserHandler(&session, connectionP->server->srvP);
    }

    assert(session.status != 0);

    if (session.responseStarted)
        HTTPWriteEndChunk(&session);
    else
        ResponseError(&session);

    *keepAliveP = HTTPKeepalive(&session);

    SessionLog(&session);

    RequestFree(&session);
}