Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
static void
handleDirectory(TSession *const sessionP,
                const char *const dirName,
                time_t const fileModTime,
                MIMEType *const mimeTypeP) {

    bool text;
    bool ascending;
    uint16_t sort;    /* 1=by name, 2=by date */
    const char *error;

    determineSortType(sessionP->requestInfo.query,
                      &ascending, &sort, &text, &error);

    if (error) {
        ResponseStatus(sessionP, 400);
        xmlrpc_strfree(error);
    } else if (notRecentlyModified(sessionP, fileModTime)) {
        ResponseStatus(sessionP, 304);
        ResponseWriteStart(sessionP);
    } else {
        TPool pool;
        bool succeeded;
        succeeded = PoolCreate(&pool, 1024);
        if (!succeeded)
            ResponseStatus(sessionP, 500);
        else {
            TList list;
            uint16_t responseStatus;
            const char *error;
            generateListing(&list, dirName, sessionP->requestInfo.uri,
                            &pool, &error, &responseStatus);
            if (error) {
                ResponseStatus(sessionP, responseStatus);
                xmlrpc_strfree(error);
            } else {
                ResponseStatus(sessionP, 200);
                ResponseContentType(sessionP,
                                    text ? "text/plain" : "text/html");

                addLastModifiedHeader(sessionP, fileModTime);

                ResponseChunked(sessionP);
                ResponseWriteStart(sessionP);

                if (sessionP->requestInfo.method != m_head)
                    sendDirectoryDocument(&list, ascending, sort, text,
                                          sessionP->requestInfo.uri, mimeTypeP,
                                          sessionP);

                HTTPWriteEndChunk(sessionP);

                ListFree(&list);
            }
            PoolFree(&pool);
        }
    }
}
Ejemplo n.º 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);
}
Ejemplo n.º 4
0
static abyss_bool
ServerDirectoryHandler(TSession * const r,
                       char *     const z,
                       time_t     const fileModTime,
                       MIMEType * const mimeTypeP) {

    TList list;
    abyss_bool text;
    abyss_bool ascending;
    uint16_t sort;    /* 1=by name, 2=by date */
    TPool pool;
    TDate date;
    const char * error;
    uint16_t responseStatus;
    TDate dirdate;
    const char * imsHdr;
    
    determineSortType(r->request_info.query, &ascending, &sort, &text, &error);

    if (error) {
        ResponseStatus(r,400);
        xmlrpc_strfree(error);
        return TRUE;
    }

    fileDate(r, fileModTime, &dirdate);

    imsHdr = RequestHeaderValue(r, "If-Modified-Since");
    if (imsHdr) {
        if (DateDecode(imsHdr, &date)) {
            if (DateCompare(&dirdate, &date) <= 0) {
                ResponseStatus(r, 304);
                ResponseWrite(r);
                return TRUE;
            }
        }
    }

    if (!PoolCreate(&pool, 1024)) {
        ResponseStatus(r, 500);
        return TRUE;
    }

    generateListing(&list, z, r->request_info.uri,
                    &pool, &error, &responseStatus);
    if (error) {
        ResponseStatus(r, responseStatus);
        xmlrpc_strfree(error);
        PoolFree(&pool);
        return TRUE;
    }

    /* Send something to the user to show that we are still alive */
    ResponseStatus(r, 200);
    ResponseContentType(r, (text ? "text/plain" : "text/html"));

    if (DateToString(&dirdate, z))
        ResponseAddField(r, "Last-Modified", z);
    
    ResponseChunked(r);
    ResponseWrite(r);

    if (r->request_info.method!=m_head)
        sendDirectoryDocument(&list, ascending, sort, text,
                              r->request_info.uri, mimeTypeP, r, z);

    HTTPWriteEndChunk(r);

    /* Free memory and exit */
    ListFree(&list);
    PoolFree(&pool);

    return TRUE;
}
Ejemplo n.º 5
0
abyss_bool
ResponseWriteEnd(TSession * const sessionP) {

    return HTTPWriteEndChunk(sessionP);
}