ANSC_STATUS
HttpBmoReqParseStartLine
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PHTTP_BMO_REQ_OBJECT            pMyObject     = (PHTTP_BMO_REQ_OBJECT   )hThisObject;
    PHTTP_HFP_INTERFACE             pHfpIf        = (PHTTP_HFP_INTERFACE    )pMyObject->hHfpIf;
    PANSC_BUFFER_DESCRIPTOR         pHeaderBdo    = (PANSC_BUFFER_DESCRIPTOR)pMyObject->hHeaderBdo;
    PHTTP_REQUEST_INFO              pReqInfo      = (PHTTP_REQUEST_INFO     )pMyObject->hReqInfo;
    PVOID                           pHeaderBuffer = NULL;
    ULONG                           ulBufferSize  = 0;
    char*                           pHfStart      = NULL;
    ULONG                           ulSkipSize    = 0;
    char*                           pRawHfLine    = NULL;
    char*                           pStdHfLine    = (char*)pMyObject->ScratchPad1;
    ULONG                           ulRawLineSize = 0;
    ULONG                           ulStdLineSize = 0;

    pMyObject->DelStartLine((ANSC_HANDLE)pMyObject);

    if ( !pHeaderBdo )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else
    {
        pHeaderBuffer = AnscBdoGetBlock    (pHeaderBdo);
        ulBufferSize  = AnscBdoGetBlockSize(pHeaderBdo);
    }

    AnscHttpFindHfStart(pHeaderBuffer, ulBufferSize, pHfStart);

    if ( !pHfStart )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else
    {
        ulSkipSize    = (ULONG)pHfStart - (ULONG)pHeaderBuffer;
        ulBufferSize -= ulSkipSize;
        pRawHfLine    = pHfStart;
    }

    AnscHttpGetHfLineSize(pRawHfLine, ulBufferSize, ulRawLineSize);

    if ( ulRawLineSize <= pMyObject->PadSize1 )
    {
        AnscHttpPrepareHeader(pRawHfLine, ulRawLineSize, pStdHfLine, ulStdLineSize);

        pStdHfLine[ulStdLineSize + 0] = HTTP_CARRIAGE_RETURN;
        pStdHfLine[ulStdLineSize + 1] = HTTP_LINE_FEED;

        pReqInfo =
            (PHTTP_REQUEST_INFO)pHfpIf->ParseRequestLine
                (
                    pHfpIf->hOwnerContext,
                    pStdHfLine,
                    ulStdLineSize
                );
    }
    else
    {
        pReqInfo = NULL;
    }

    if ( !pReqInfo )
    {
        return  ANSC_STATUS_BAD_PAYLOAD;
    }
    else
    {
        pMyObject->hReqInfo = (ANSC_HANDLE)pReqInfo;
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
HttpBmoParseHeaders
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PHTTP_BASIC_MESSAGE_OBJECT      pMyObject     = (PHTTP_BASIC_MESSAGE_OBJECT)hThisObject;
    PHTTP_HFP_INTERFACE             pHfpIf        = (PHTTP_HFP_INTERFACE       )pMyObject->hHfpIf;
    PANSC_BUFFER_DESCRIPTOR         pHeaderBdo    = (PANSC_BUFFER_DESCRIPTOR   )pMyObject->hHeaderBdo;
    PHTTP_HEADER_FIELD              pHttpHfo      = NULL;
    PVOID                           pHeaderBuffer = NULL;
    ULONG                           ulBufferSize  = 0;
    char*                           pHfStart      = NULL;
    ULONG                           ulSkipSize    = 0;
    char*                           pRawHfLine    = NULL;
    char*                           pStdHfLine    = (char*)pMyObject->ScratchPad1;
    ULONG                           ulRawLineSize = 0;
    ULONG                           ulStdLineSize = 0;

    pMyObject->DelStartLine((ANSC_HANDLE)pMyObject);
    pMyObject->DelAllHfos  ((ANSC_HANDLE)pMyObject);

    returnStatus = pMyObject->ParseStartLine((ANSC_HANDLE)pMyObject);

    if ( returnStatus != ANSC_STATUS_SUCCESS )
    {
        return  returnStatus;
    }
    else if ( !pHeaderBdo )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else
    {
        pHeaderBuffer = AnscBdoGetBlock    (pHeaderBdo);
        ulBufferSize  = AnscBdoGetBlockSize(pHeaderBdo);
    }

    AnscHttpFindHfStart(pHeaderBuffer, ulBufferSize, pHfStart);

    if ( !pHfStart )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else
    {
        ulSkipSize    = (ULONG)pHfStart - (ULONG)pHeaderBuffer;
        ulBufferSize -= ulSkipSize;
        pRawHfLine    = pHfStart;
    }

    /*
     * Skip the first line, which is the start line: request-line in client message and status-line
     * in server message.
     */
    AnscHttpGetHfLineSize(pRawHfLine, ulBufferSize, ulRawLineSize);

    pRawHfLine   += ulRawLineSize;
    ulBufferSize -= ulRawLineSize;

    /*
     * We don't have to verify the completeness of the header fields, since the caller SHOULD have
     * done so already. We create a separate HTTP Header Field Object for each header line and add
     * it into the distributed hash table. The end of header fields is signalled by the presece of
     * a CRLF pair.
     */
    while ( (ulBufferSize > 0) && pRawHfLine && !AnscHttpIsCr(*pRawHfLine) && !AnscHttpIsLf(*pRawHfLine) )
    {
        AnscHttpGetHfLineSize(pRawHfLine, ulBufferSize, ulRawLineSize);

        if ( ulRawLineSize <= pMyObject->PadSize1 )
        {
            AnscHttpPrepareHeader(pRawHfLine, ulRawLineSize, pStdHfLine, ulStdLineSize);

            pStdHfLine[ulStdLineSize + 0] = HTTP_CARRIAGE_RETURN;
            pStdHfLine[ulStdLineSize + 1] = HTTP_LINE_FEED;

            pHttpHfo =
                (PHTTP_HEADER_FIELD)pHfpIf->ParseHeader
                    (
                        pHfpIf->hOwnerContext,
                        pStdHfLine,
                        ulStdLineSize
                    );

            if ( pHttpHfo )
            {
                returnStatus =
                    pMyObject->AddHeaderField
                        (
                            (ANSC_HANDLE)pMyObject,
                            (ANSC_HANDLE)pHttpHfo
                        );
            }
        }

        pRawHfLine   += ulRawLineSize;
        ulBufferSize -= ulRawLineSize;
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
HttpMboChkParseTrailer
    (
        ANSC_HANDLE                 hThisObject,
        char*                       pRawTrailer,
        ULONG                       ulTrailerSize
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PHTTP_MBO_CHUNKED_OBJECT        pMyObject     = (PHTTP_MBO_CHUNKED_OBJECT)hThisObject;
    PHTTP_HFP_INTERFACE             pHfpIf        = (PHTTP_HFP_INTERFACE     )pMyObject->hHfpIf;
    PHTTP_BCC_INTERFACE             pBccIf        = (PHTTP_BCC_INTERFACE     )pMyObject->hBccIf;
    PHTTP_HEADER_FIELD              pHttpHfo      = NULL;
    char*                           pHfStart      = (char*)pRawTrailer;
    char*                           pRawHfLine    = (char*)pRawTrailer;
    char*                           pStdHfLine    = (char*)pMyObject->ScratchPad2;
    ULONG                           ulRawLineSize = 0;
    ULONG                           ulStdLineSize = 0;
    ULONG                           ulBufferSize  = ulTrailerSize;

    if ( ulTrailerSize == 2 )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pHfStart   = pRawTrailer;
        pRawHfLine = pHfStart;
    }

    /*
     * Skip the first line, which is the start line: request-line in client message and status-line
     * in server message.
     */
    AnscHttpGetHfLineSize(pRawHfLine, ulBufferSize, ulRawLineSize);

    pRawHfLine   += ulRawLineSize;
    ulBufferSize -= ulRawLineSize;

    /*
     * We don't have to verify the completeness of the header fields, since the caller SHOULD have
     * done so already. We create a separate HTTP Header Field Object for each header line and add
     * it into the distributed hash table. The end of header fields is signalled by the presece of
     * a CRLF pair.
     */
    while ( (ulBufferSize > 0) && pRawHfLine && !AnscHttpIsCr(*pRawHfLine) && !AnscHttpIsLf(*pRawHfLine) )
    {
        AnscHttpGetHfLineSize(pRawHfLine, ulBufferSize, ulRawLineSize);

        if ( ulRawLineSize <= pMyObject->PadSize1 )
        {
            AnscHttpPrepareHeader(pRawHfLine, ulRawLineSize, pStdHfLine, ulStdLineSize);

            pStdHfLine[ulStdLineSize + 0] = HTTP_CARRIAGE_RETURN;
            pStdHfLine[ulStdLineSize + 1] = HTTP_LINE_FEED;

            pHttpHfo =
                (PHTTP_HEADER_FIELD)pHfpIf->ParseHeader
                    (
                        pHfpIf->hOwnerContext,
                        pStdHfLine,
                        ulStdLineSize
                    );

            if ( !pHttpHfo )
            {
                return  ANSC_STATUS_BAD_PAYLOAD;
            }
            else
            {
                returnStatus =
                    pBccIf->AddHeaderField
                        (
                            pBccIf->hOwnerContext,
                            (ANSC_HANDLE)pHttpHfo
                        );
            }
        }

        pRawHfLine   += ulRawLineSize;
        ulBufferSize -= ulRawLineSize;
    }

    return  ANSC_STATUS_SUCCESS;
}