ANSC_STATUS
HttpTroFinishedByClient
    (
        ANSC_HANDLE                 hThisObject,
        PVOID                       buffer,
        ULONG                       ulSize,
        ANSC_HANDLE                 hBufferContext
    )
{
    ANSC_STATUS                     returnStatus   = ANSC_STATUS_SUCCESS;
    PHTTP_TRANS_RECORD_OBJECT       pMyObject      = (PHTTP_TRANS_RECORD_OBJECT     )hThisObject;
    PHTTP_ADVANCED_PROXY_OBJECT     pAdvancedProxy = (PHTTP_ADVANCED_PROXY_OBJECT   )pMyObject->hOwnerContext;
    PHTTP_WAM_INTERFACE             pWamIf         = (PHTTP_WAM_INTERFACE           )pMyObject->hWamIf;
    PHTTP_SBC_INTERFACE             pSbcIf         = (PHTTP_SBC_INTERFACE           )pMyObject->hSbcIf;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pClientSocket  = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pMyObject->hClientSocket;
    PANSC_BROKER_SOCKET_TCP_OBJECT  pServerSocket  = (PANSC_BROKER_SOCKET_TCP_OBJECT)pMyObject->hServerSocket;
    PHTTP_BMO_REQ_OBJECT            pBmoReq        = (PHTTP_BMO_REQ_OBJECT          )pMyObject->hBmoReq;
    PANSC_BUFFER_DESCRIPTOR         pBufferDesp    = (PANSC_BUFFER_DESCRIPTOR       )hBufferContext;
    ULONG                           ulBmoState     = pBmoReq->GetState((ANSC_HANDLE)pBmoReq);

    if ( (ulBmoState == HTTP_BMO_STATE_COMPLETE   ) ||
         (ulBmoState == HTTP_BMO_STATE_OVER_PACKED) )
    {
        if ( pBufferDesp )
        {
            AnscFreeBdo((ANSC_HANDLE)pBufferDesp);
        }

        return  ANSC_STATUS_UNAPPLICABLE;
    }

    buffer       = AnscBdoGetBlock    (pBufferDesp);
    ulSize       = AnscBdoGetBlockSize(pBufferDesp);
    returnStatus =
        pBmoReq->CloseUp
            (
                (ANSC_HANDLE)pBmoReq,
                (ANSC_HANDLE)pBufferDesp
            );

    return  returnStatus;
}
ANSC_STATUS
HttpWstoFinish
    (
        ANSC_HANDLE                 hThisObject,
        PVOID                       buffer,
        ULONG                       ulSize,
        ANSC_HANDLE                 hBufferContext
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PHTTP_WEBS_TRANS_OBJECT         pMyObject     = (PHTTP_WEBS_TRANS_OBJECT       )hThisObject;
    PHTTP_SIMPLE_SERVER_OBJECT      pSimpleServer = (PHTTP_SIMPLE_SERVER_OBJECT    )pMyObject->hOwnerContext;
    PHTTP_WSP_INTERFACE             pWspIf        = (PHTTP_WSP_INTERFACE           )pMyObject->hWspIf;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pWebSocket    = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pMyObject->hWebSocket;
    PHTTP_BMO_REQ_OBJECT            pBmoReq       = (PHTTP_BMO_REQ_OBJECT          )pMyObject->hBmoReq;
    PANSC_BUFFER_DESCRIPTOR         pBufferDesp   = (PANSC_BUFFER_DESCRIPTOR       )hBufferContext;
    ULONG                           ulBmoState    = pBmoReq->GetState((ANSC_HANDLE)pBmoReq);

    if ( (ulBmoState == HTTP_BMO_STATE_COMPLETE   ) ||
         (ulBmoState == HTTP_BMO_STATE_OVER_PACKED) )
    {
        if ( pBufferDesp )
        {
            AnscFreeBdo((ANSC_HANDLE)pBufferDesp);
        }

        return  ANSC_STATUS_UNAPPLICABLE;
    }

    buffer       = AnscBdoGetBlock    (pBufferDesp);
    ulSize       = AnscBdoGetBlockSize(pBufferDesp);
    returnStatus =
        pBmoReq->CloseUp
            (
                (ANSC_HANDLE)pBmoReq,
                (ANSC_HANDLE)pBufferDesp
            );

    return  returnStatus;
}
ULONG
HttpTroQueryForClient
    (
        ANSC_HANDLE                 hThisObject,
        PVOID                       buffer,
        ULONG                       ulSize,
        ANSC_HANDLE                 hBufferContext
    )
{
    ANSC_STATUS                     returnStatus   = ANSC_STATUS_SUCCESS;
    PHTTP_TRANS_RECORD_OBJECT       pMyObject      = (PHTTP_TRANS_RECORD_OBJECT     )hThisObject;
    PHTTP_ADVANCED_PROXY_OBJECT     pAdvancedProxy = (PHTTP_ADVANCED_PROXY_OBJECT   )pMyObject->hOwnerContext;
    PHTTP_WAM_INTERFACE             pWamIf         = (PHTTP_WAM_INTERFACE           )pMyObject->hWamIf;
    PHTTP_SBC_INTERFACE             pSbcIf         = (PHTTP_SBC_INTERFACE           )pMyObject->hSbcIf;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pClientSocket  = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pMyObject->hClientSocket;
    PANSC_BUFFER_DESCRIPTOR         pBufferDesp    = (PANSC_BUFFER_DESCRIPTOR       )hBufferContext;
    PHTTP_BMO_REQ_OBJECT            pBmoReq        = (PHTTP_BMO_REQ_OBJECT          )pMyObject->hBmoReq;
    ULONG                           ulTroQmode     = HTTP_TRO_QMODE_FORWARD;
    ULONG                           ulBmoState1    = HTTP_BMO_STATE_EMPTY;
    ULONG                           ulBmoState2    = HTTP_BMO_STATE_EMPTY;

    /*
     * If the SBC (Server Behavior Controller) has allowed everything to be relayed internally by
     * the proxy object itself (or simply because there's no SBC registered), we SHALL pass payload
     * data from one socket to the other, whenever there's data available.
     */
    if ( (pMyObject->TransState == HTTP_TRO_STATE_ESTABLISHED) &&
         (pMyObject->SbcPmode   == HTTP_SBC_PMODE_RELAY2     ) )
    {
        return  HTTP_TRO_QMODE_FORWARD;
    }

    /*
     * The decision on how to process the received payload should be made based on two message
     * states: the message state before payload arrival and the state after. The caller must ensure
     * the consistency of the buffer descriptor.
     */
    buffer      = AnscBdoGetBlock    (pBufferDesp);
    ulSize      = AnscBdoGetBlockSize(pBufferDesp);
    ulBmoState1 = pBmoReq->GetState((ANSC_HANDLE)pBmoReq);
    ulBmoState2 =
        pBmoReq->Examine
            (
                (ANSC_HANDLE)pBmoReq,
                buffer,
                ulSize
            );

    switch ( ulBmoState2 )
    {
        case    HTTP_BMO_STATE_EMPTY :
        case    HTTP_BMO_STATE_PART_HEADER :

                ulTroQmode = HTTP_TRO_QMODE_COLLECT;

                break;

        case    HTTP_BMO_STATE_HEADER_ARRIVED :

                ulTroQmode = HTTP_TRO_QMODE_PROCESS;

                break;

        case    HTTP_BMO_STATE_PART_BODY :

                if ( ulBmoState1 == HTTP_BMO_STATE_PART_BODY )
                {
                    if ( AnscBdoGetLeftSize(pBufferDesp) > HTTP_SPO_RECV_BUFFER_ROOM )
                    {
                        ulTroQmode = HTTP_TRO_QMODE_COLLECT;
                    }
                    else
                    {
                        ulTroQmode = HTTP_TRO_QMODE_PROCESS;
                    }
                }
                else
                {
                    ulTroQmode = HTTP_TRO_QMODE_PROCESS;
                }

                break;

        case    HTTP_BMO_STATE_COMPLETE :
        case    HTTP_BMO_STATE_OVER_PACKED :

                ulTroQmode = HTTP_TRO_QMODE_PROCESS;

                break;

        case    HTTP_BMO_STATE_UNKNOWN :

                ulTroQmode = HTTP_TRO_QMODE_PROCESS;

                break;

        default :

                ulTroQmode = HTTP_TRO_QMODE_COLLECT;

                break;
    }

    return  ulTroQmode;
}
ULONG
HttpWstoQuery
    (
        ANSC_HANDLE                 hThisObject,
        PVOID                       buffer,
        ULONG                       ulSize,
        ANSC_HANDLE                 hBufferContext
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PHTTP_WEBS_TRANS_OBJECT         pMyObject     = (PHTTP_WEBS_TRANS_OBJECT       )hThisObject;
    PHTTP_SIMPLE_SERVER_OBJECT      pSimpleServer = (PHTTP_SIMPLE_SERVER_OBJECT    )pMyObject->hOwnerContext;
    PHTTP_WSP_INTERFACE             pWspIf        = (PHTTP_WSP_INTERFACE           )pMyObject->hWspIf;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pWebSocket    = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pMyObject->hWebSocket;
    PANSC_BUFFER_DESCRIPTOR         pBufferDesp   = (PANSC_BUFFER_DESCRIPTOR       )hBufferContext;
    PHTTP_BMO_REQ_OBJECT            pBmoReq       = (PHTTP_BMO_REQ_OBJECT          )pMyObject->hBmoReq;
    ULONG                           ulWstoQmode   = HTTP_WSTO_QMODE_COLLECT;
    ULONG                           ulBmoState1   = HTTP_BMO_STATE_EMPTY;
    ULONG                           ulBmoState2   = HTTP_BMO_STATE_EMPTY;

    /*
     * The decision on how to process the received payload should be made based on two message
     * states: the message state before payload arrival and the state after. The caller must ensure
     * the consistency of the buffer descriptor.
     */
    buffer      = AnscBdoGetBlock    (pBufferDesp);
    ulSize      = AnscBdoGetBlockSize(pBufferDesp);
    ulBmoState1 = pBmoReq->GetState((ANSC_HANDLE)pBmoReq);
    ulBmoState2 =
        pBmoReq->Examine
            (
                (ANSC_HANDLE)pBmoReq,
                buffer,
                ulSize
            );

    switch ( ulBmoState2 )
    {
        case    HTTP_BMO_STATE_EMPTY :
        case    HTTP_BMO_STATE_PART_HEADER :

                ulWstoQmode = HTTP_WSTO_QMODE_COLLECT;

                break;

        case    HTTP_BMO_STATE_HEADER_ARRIVED :

                ulWstoQmode = HTTP_WSTO_QMODE_PROCESS;

                break;

        case    HTTP_BMO_STATE_PART_BODY :

                if ( ulBmoState1 == HTTP_BMO_STATE_PART_BODY )
                {
                    if ( AnscBdoGetLeftSize(pBufferDesp) >= HTTP_SSO_RECV_BUFFER_ROOM )
                    {
                        ulWstoQmode = HTTP_WSTO_QMODE_COLLECT;
                    }
                    else
                    {
                        ulWstoQmode = HTTP_WSTO_QMODE_PROCESS;
                    }
                }
                else
                {
                    ulWstoQmode = HTTP_WSTO_QMODE_PROCESS;
                }

                break;

        case    HTTP_BMO_STATE_COMPLETE :
        case    HTTP_BMO_STATE_OVER_PACKED :

                ulWstoQmode = HTTP_WSTO_QMODE_PROCESS;

                break;

        case    HTTP_BMO_STATE_UNKNOWN :

                ulWstoQmode = HTTP_WSTO_QMODE_PROCESS;

                break;

        default :

                ulWstoQmode = HTTP_WSTO_QMODE_COLLECT;

                break;
    }

    return  ulWstoQmode;
}