Exemplo n.º 1
0
int HttpCgiTool::parseRespHeader( HttpExtConnector * pExtConn,
                                const char * pBuf, int size, int &status )
{
    const char * pEnd = pBuf + size;
    const char * pLineEnd;
    const char * pLineBegin;
    const char * pCur = pBuf;
    const char * pValue;
    while( pCur < pEnd )
    {
        pLineBegin = pCur;
        pLineEnd = (const char *)memchr( pCur, '\n', pEnd - pCur );
        if ( pLineEnd == NULL )
        {
            break;
        }
        pCur = pLineEnd + 1;
        while(( pLineEnd > pLineBegin )&&(*(pLineEnd - 1) == '\r' ))
            --pLineEnd;
        if ( pLineEnd == pLineBegin )
        {   //empty line detected
            status |= HttpReq::HEADER_OK;
            break;
        }
        pValue = pLineBegin;
        while( (pLineEnd > pValue) &&(isspace( pLineEnd[-1] )) )
            --pLineEnd;
        if ( pValue == pLineEnd )
            continue;
        int index;
        if ( (*(pValue+4) == '/') && memcmp( pValue, "HTTP/1.", 7 ) == 0 )
        {
            index = HttpStatusCode::codeToIndex( pValue + 9 );
            if ( index != -1 )
            {
                pExtConn->getHttpConn()->getReq()->updateNoRespBodyByStatus( index );
                status |= HEC_RESP_NPH2;
                if (( status & HEC_RESP_AUTHORIZER )&&( index == SC_200))
                    status |= HEC_RESP_AUTHORIZED;
            }
            continue;
        }
        if ( processHeaderLine( pExtConn, pValue,
                                pLineEnd, status ) == -1 )
            return -1;
    }
    return pCur - pBuf;
}
Exemplo n.º 2
0
abyss_bool
ConnReadHeader(TConn * const connectionP,
               char ** const headerP) {
    /*----------------------------------------------------------------------------
       Read an HTTP header on connection *connectionP.

       An HTTP header is basically a line, except that if a line starts
       with white space, it's a continuation of the previous line.  A line
       is delimited by either LF or CRLF.

       In the course of reading, we read at least one character past the
       line delimiter at the end of the header; we may read much more.  We
       leave everything after the header (and its line delimiter) in the
       internal buffer, with the buffer pointer pointing to it.

       We use stuff already in the internal buffer (perhaps left by a
       previous call to this subroutine) before reading any more from from
       the socket.

       Return as *headerP the header value.  This is in the connection's
       internal buffer.  This contains no line delimiters.
    -----------------------------------------------------------------------------*/
    uint32_t const deadline = time(NULL) + connectionP->server->srvP->timeout;

    abyss_bool retval;
    char * p;
    char * headerStart;
    abyss_bool error;
    abyss_bool gotHeader;

    p = connectionP->buffer + connectionP->bufferpos;
    headerStart = p;

    gotHeader = FALSE;
    error = FALSE;

    while (!gotHeader && !error) {
        int const timeLeft = deadline - time(NULL);

        if (timeLeft <= 0)
            error = TRUE;
        else {
            if (p >= connectionP->buffer + connectionP->buffersize)
                /* Need more data from the socket to chew on */
                error = !ConnRead(connectionP, timeLeft);

            if (!error) {
                assert(connectionP->buffer + connectionP->buffersize > p);
                processHeaderLine(p, headerStart, connectionP, deadline,
                                  &gotHeader, &p, &error);
            }
        }
    }
    if (gotHeader) {
        /* We've consumed this part of the buffer (but be careful --
           you can't reuse that part of the buffer because the string
           we're returning is in it!
        */
        connectionP->bufferpos += p - headerStart;
        *headerP = headerStart;
        retval = TRUE;
    } else
        retval = FALSE;

    return retval;
}