ANSC_STATUS
HttpSpoDestroyBmoReqPool
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_SIMPLE_PROXY_OBJECT       pMyObject    = (PHTTP_SIMPLE_PROXY_OBJECT  )hThisObject;
    PHTTP_SIMPLE_PROXY_PROPERTY     pProperty    = (PHTTP_SIMPLE_PROXY_PROPERTY)&pMyObject->Property;
    PHTTP_BMO_REQ_OBJECT            pBmoReq      = NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry  = NULL;

    AnscAcquireLock(&pMyObject->BmoReqSListLock);

    pSLinkEntry = AnscSListPopEntry(&pMyObject->BmoReqSList);

    while ( pSLinkEntry )
    {
        pBmoReq     = ACCESS_HTTP_BMO_REQ_OBJECT(pSLinkEntry);
        pSLinkEntry = AnscSListPopEntry(&pMyObject->BmoReqSList);

        pBmoReq->Remove((ANSC_HANDLE)pBmoReq);
    }

    AnscReleaseLock(&pMyObject->BmoReqSListLock);

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
WebRooDoPost
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep
    )
{
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PWEB_RESOURCE_OWNER_OBJECT      pMyObject       = (PWEB_RESOURCE_OWNER_OBJECT  )hThisObject;
    PWEB_RESOURCE_OWNER_PROPERTY    pProperty       = (PWEB_RESOURCE_OWNER_PROPERTY)&pMyObject->Property;
    PHTTP_RCP_INTERFACE             pRcpIf          = (PHTTP_RCP_INTERFACE         )pMyObject->hRcpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq         = (PHTTP_BMO_REQ_OBJECT        )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pBmoRep         = (PHTTP_BMO_REP_OBJECT        )hBmoRep;
    PHTTP_REQUEST_INFO              pReqInfo        = (PHTTP_REQUEST_INFO          )pBmoReq->GetReqInfo    ((ANSC_HANDLE)pBmoReq);
    PANSC_TOKEN_CHAIN               pPathTokenChain = (PANSC_TOKEN_CHAIN           )pBmoReq->GetRecvContext((ANSC_HANDLE)pBmoReq);
    PWEB_GENERAL_SESSION_OBJECT     pSession        = (PWEB_GENERAL_SESSION_OBJECT )pBmoRep->GetRecvContext((ANSC_HANDLE)pBmoRep);

    returnStatus =
        pMyObject->ReplyReq
            (
                (ANSC_HANDLE)pMyObject,
                (ANSC_HANDLE)pBmoReq,
                (ANSC_HANDLE)pBmoRep,
                HTTP_STATUS_OK,
                (ANSC_HANDLE)NULL
            );

    return  returnStatus;
}
ANSC_STATUS
HttpSpoReleaseBmoReq
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_SIMPLE_PROXY_OBJECT       pMyObject    = (PHTTP_SIMPLE_PROXY_OBJECT  )hThisObject;
    PHTTP_SIMPLE_PROXY_PROPERTY     pProperty    = (PHTTP_SIMPLE_PROXY_PROPERTY)&pMyObject->Property;
    PHTTP_BMO_REQ_OBJECT            pBmoReq      = (PHTTP_BMO_REQ_OBJECT       )hBmoReq;

    pBmoReq->Reset((ANSC_HANDLE)pBmoReq);

    if ( pMyObject->ProxyMode & HTTP_SPO_MODE_COMPACT )
    {
        pBmoReq->Remove((ANSC_HANDLE)pBmoReq);
    }
    else
    {
        AnscAcquireLock   (&pMyObject->BmoReqSListLock);
        AnscSListPushEntry(&pMyObject->BmoReqSList, &pBmoReq->Linkage);
        AnscReleaseLock   (&pMyObject->BmoReqSListLock);
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
HttpBmoReqCopyStartLineFrom
    (
        ANSC_HANDLE                 hThisObject,
        PVOID                       buffer,
        PULONG                      pulSize
    )
{
    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;
    PHTTP_REQUEST_INFO              pReqInfo        = (PHTTP_REQUEST_INFO  )pMyObject->hReqInfo;
    ULONG                           ulStartLineSize = pMyObject->GetStartLineSize((ANSC_HANDLE)pMyObject);

    if ( *pulSize < ulStartLineSize )
    {
        return  ANSC_STATUS_BAD_SIZE;
    }

    returnStatus =
        pHfpIf->BuildRequestLine
            (
                pHfpIf->hOwnerContext,
                (ANSC_HANDLE)pReqInfo,
                buffer,
                ulStartLineSize
            );

    *pulSize = ulStartLineSize;

    return  returnStatus;
}
ANSC_STATUS
HttpBmoReqRemove
(
    ANSC_HANDLE                 hThisObject
)
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_BMO_REQ_OBJECT            pMyObject    = (PHTTP_BMO_REQ_OBJECT)hThisObject;
    PHTTP_CGI_INTERFACE             pCgiIf       = (PHTTP_CGI_INTERFACE )pMyObject->hCgiIf;
    PHTTP_RCP_INTERFACE             pRcpIf       = (PHTTP_RCP_INTERFACE )pMyObject->hRcpIf;

    pMyObject->Reset((ANSC_HANDLE)pMyObject);

    if ( pCgiIf )
    {
        AnscFreeMemory(pCgiIf);
    }

    if ( pRcpIf )
    {
        AnscFreeMemory(pRcpIf);
    }

    if ( pMyObject->RcpDpad )
    {
        AnscFreeMemory(pMyObject->RcpDpad);
    }

    HttpBmoRemove((ANSC_HANDLE)pMyObject);

    return  ANSC_STATUS_SUCCESS;
}
char*
HttpBmoReqRcpGetServerName
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_BMO_REQ_OBJECT            pMyObject    = (PHTTP_BMO_REQ_OBJECT         )hThisObject;

    return  pMyObject->GetServerName((ANSC_HANDLE)pMyObject);
}
USHORT
HttpBmoReqRcpGetServerPort
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_BMO_REQ_OBJECT            pMyObject    = (PHTTP_BMO_REQ_OBJECT         )hThisObject;

    /*return  pMyObject->GetServerPort((ANSC_HANDLE)pMyObject);*/
    return  pMyObject->GetDaemonPort((ANSC_HANDLE)pMyObject);
}
ANSC_STATUS
WebRooDoConnect
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep
    )
{
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PWEB_RESOURCE_OWNER_OBJECT      pMyObject       = (PWEB_RESOURCE_OWNER_OBJECT  )hThisObject;
    PWEB_RESOURCE_OWNER_PROPERTY    pProperty       = (PWEB_RESOURCE_OWNER_PROPERTY)&pMyObject->Property;
    PHTTP_RCP_INTERFACE             pRcpIf          = (PHTTP_RCP_INTERFACE         )pMyObject->hRcpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq         = (PHTTP_BMO_REQ_OBJECT        )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pBmoRep         = (PHTTP_BMO_REP_OBJECT        )hBmoRep;
    PHTTP_REQUEST_INFO              pReqInfo        = (PHTTP_REQUEST_INFO          )pBmoReq->GetReqInfo    ((ANSC_HANDLE)pBmoReq);
    PANSC_TOKEN_CHAIN               pPathTokenChain = (PANSC_TOKEN_CHAIN           )pBmoReq->GetRecvContext((ANSC_HANDLE)pBmoReq);
    PWEB_GENERAL_SESSION_OBJECT     pSession        = (PWEB_GENERAL_SESSION_OBJECT )pBmoRep->GetRecvContext((ANSC_HANDLE)pBmoRep);
    PHTTP_HFO_ALLOW                 pHttpHfoAllow   = NULL;

    pHttpHfoAllow = (PHTTP_HFO_ALLOW)AnscAllocateMemory(sizeof(HTTP_HFO_ALLOW));

    if ( !pHttpHfoAllow )
    {
        return  ANSC_STATUS_RESOURCES;
    }
    else
    {
        pHttpHfoAllow->HashIndex      = 0;
        pHttpHfoAllow->Flags          = 0;
        pHttpHfoAllow->HeaderId       = HTTP_HEADER_ID_ALLOW;

        pHttpHfoAllow->MethodCount    = 4;
        pHttpHfoAllow->MethodArray[0] = HTTP_METHOD_CODE_OPTIONS;
        pHttpHfoAllow->MethodArray[1] = HTTP_METHOD_CODE_GET;
        pHttpHfoAllow->MethodArray[2] = HTTP_METHOD_CODE_HEAD;
        pHttpHfoAllow->MethodArray[3] = HTTP_METHOD_CODE_POST;
    }

    returnStatus =
        pMyObject->ReplyReq
            (
                (ANSC_HANDLE)pMyObject,
                (ANSC_HANDLE)pBmoReq,
                (ANSC_HANDLE)pBmoRep,
                HTTP_STATUS_METHOD_NOT_ALLOWED,
                (ANSC_HANDLE)pHttpHfoAllow
            );

    return  returnStatus;
}
ANSC_STATUS
HttpTroRecvFromClient
    (
        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;
    PANSC_BUFFER_DESCRIPTOR         pBufferDesp    = (PANSC_BUFFER_DESCRIPTOR       )hBufferContext;
    PHTTP_BMO_REQ_OBJECT            pBmoReq        = (PHTTP_BMO_REQ_OBJECT          )pMyObject->hBmoReq;
    ULONG                           ulBmoState     = HTTP_BMO_STATE_EMPTY;

    /*
     * At time like this, you will always have two options on how to proceed with the message
     * processing:
     *
     *      $ Examine the current object states and the content of the message payload
     *        to make the processing decisions in this object.
     *
     *      $ Offload the examination and certain state-transition functions to another
     *        object and provide an interface to be notified when something happens.
     *
     * Guess which one we're using here ...
     */
    buffer       = AnscBdoGetBlock    (pBufferDesp);
    ulSize       = AnscBdoGetBlockSize(pBufferDesp);
    returnStatus =
        pBmoReq->Process
            (
                (ANSC_HANDLE)pBmoReq,
                (ANSC_HANDLE)pBufferDesp
            );

    if ( (returnStatus != ANSC_STATUS_SUCCESS    ) &&
         (returnStatus != ANSC_STATUS_DO_IT_AGAIN) )
    {
        pMyObject->TransState = HTTP_TRO_STATE_FINISHED;
    }

    return  returnStatus;
}
ANSC_STATUS
HttpSpoManufactureBmoReqPool
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_SIMPLE_PROXY_OBJECT       pMyObject    = (PHTTP_SIMPLE_PROXY_OBJECT  )hThisObject;
    PHTTP_SIMPLE_PROXY_PROPERTY     pProperty    = (PHTTP_SIMPLE_PROXY_PROPERTY)&pMyObject->Property;
    PHTTP_HFP_INTERFACE             pHfpIf       = (PHTTP_HFP_INTERFACE        )pMyObject->hHfpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq      = NULL;
    ULONG                           i            = 0;

    if ( pMyObject->ProxyMode & HTTP_SPO_MODE_COMPACT )
    {
        return  ANSC_STATUS_SUCCESS;
    }

    for ( i = 0; i < HTTP_SPO_INITIAL_BMO_NUMBER; i++ )
    {
        pBmoReq =
            (PHTTP_BMO_REQ_OBJECT)HttpCreateBmoReq
                (
                    pMyObject->hContainerContext,
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)NULL
                );

        if ( !pBmoReq )
        {
            continue;
        }
        else
        {
            pBmoReq->SetHfpIf      ((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)pHfpIf);
            pBmoReq->SetRecvContext((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)NULL  );
            pBmoReq->SetSendContext((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)NULL  );
        }

        AnscAcquireLock   (&pMyObject->BmoReqSListLock);
        AnscSListPushEntry(&pMyObject->BmoReqSList, &pBmoReq->Linkage);
        AnscReleaseLock   (&pMyObject->BmoReqSListLock);
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_HANDLE
HttpSpoAcquireBmoReq
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_SIMPLE_PROXY_OBJECT       pMyObject    = (PHTTP_SIMPLE_PROXY_OBJECT  )hThisObject;
    PHTTP_SIMPLE_PROXY_PROPERTY     pProperty    = (PHTTP_SIMPLE_PROXY_PROPERTY)&pMyObject->Property;
    PHTTP_HFP_INTERFACE             pHfpIf       = (PHTTP_HFP_INTERFACE        )pMyObject->hHfpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq      = NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry  = NULL;

    AnscAcquireLock(&pMyObject->BmoReqSListLock);
    pSLinkEntry = AnscSListPopEntry(&pMyObject->BmoReqSList);
    AnscReleaseLock(&pMyObject->BmoReqSListLock);

    if ( pSLinkEntry )
    {
        pBmoReq = ACCESS_HTTP_BMO_REQ_OBJECT(pSLinkEntry);

        return  (ANSC_HANDLE)pBmoReq;
    }

    pBmoReq =
        (PHTTP_BMO_REQ_OBJECT)HttpCreateBmoReq
            (
                pMyObject->hContainerContext,
                (ANSC_HANDLE)pMyObject,
                (ANSC_HANDLE)NULL
            );

    if ( !pBmoReq )
    {
        return  (ANSC_HANDLE)NULL;
    }
    else
    {
        pBmoReq->SetHfpIf      ((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)pHfpIf);
        pBmoReq->SetRecvContext((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)NULL  );
        pBmoReq->SetSendContext((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)NULL  );
    }

    return  (ANSC_HANDLE)pBmoReq;
}
ANSC_STATUS
BwspWsoDoHead
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep
    )
{
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PBWSP_WEB_SERVLET_OBJECT        pMyObject       = (PBWSP_WEB_SERVLET_OBJECT   )hThisObject;
    PBWSP_WEB_SERVLET_PROPERTY      pProperty       = (PBWSP_WEB_SERVLET_PROPERTY )&pMyObject->Property;
    PBWSP_WSH_INTERFACE             pBwspWshIf      = (PBWSP_WSH_INTERFACE        )pMyObject->hBwspWshIf;
    PHTTP_RCP_INTERFACE             pRcpIf          = (PHTTP_RCP_INTERFACE        )pMyObject->hRcpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq         = (PHTTP_BMO_REQ_OBJECT       )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pBmoRep         = (PHTTP_BMO_REP_OBJECT       )hBmoRep;
    PHTTP_REQUEST_INFO              pReqInfo        = (PHTTP_REQUEST_INFO         )pBmoReq->GetReqInfo    ((ANSC_HANDLE)pBmoReq);
    PANSC_TOKEN_CHAIN               pPathTokenChain = (PANSC_TOKEN_CHAIN          )pBmoReq->GetRecvContext((ANSC_HANDLE)pBmoReq);
    PWEB_GENERAL_SESSION_OBJECT     pSession        = (PWEB_GENERAL_SESSION_OBJECT)pBmoRep->GetRecvContext((ANSC_HANDLE)pBmoRep);

    if ( pBwspWshIf->DoHead )
    {
        returnStatus =
            pBwspWshIf->DoHead
                (
                    pBwspWshIf->hOwnerContext,
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)pBmoReq,
                    (ANSC_HANDLE)pBmoRep
                );
    }
    else
    {
        returnStatus =
            pMyObject->ReplyReq
                (
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)pBmoReq,
                    (ANSC_HANDLE)pBmoRep,
                    HTTP_STATUS_OK,
                    (ANSC_HANDLE)NULL
                );
    }

    return  returnStatus;
}
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;
}
ANSC_HANDLE
WebVhoIdentifyGso
(
    ANSC_HANDLE                 hThisObject,
    ANSC_HANDLE                 hBmoReq
)
{
    ANSC_STATUS                     returnStatus   = ANSC_STATUS_SUCCESS;
    PWEB_VIRTUAL_HOST_OBJECT        pMyObject      = (PWEB_VIRTUAL_HOST_OBJECT   )hThisObject;
    PWEB_VIRTUAL_HOST_PROPERTY      pProperty      = (PWEB_VIRTUAL_HOST_PROPERTY )&pMyObject->Property;
    PHTTP_HFP_INTERFACE             pHfpIf         = (PHTTP_HFP_INTERFACE        )pMyObject->hHfpIf;
    PWEB_LSM_INTERFACE              pLsmIf         = (PWEB_LSM_INTERFACE         )pMyObject->hLsmIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq        = (PHTTP_BMO_REQ_OBJECT       )hBmoReq;
    PHTTP_HFO_COOKIE                pHttpHfoCookie = (PHTTP_HFO_COOKIE           )NULL;
    PHTTP_COOKIE_CONTENT            pCookieContent = (PHTTP_COOKIE_CONTENT       )NULL;
    PWEB_GENERAL_SESSION_OBJECT     pSession       = (PWEB_GENERAL_SESSION_OBJECT)NULL;
    ULONG                           ulSessionId    = (ULONG                      )0xFFFFFFFF;
    char*                           pLsmIdentifier = (char*                      )NULL;
    char                            pEmptyLsmId[]  = {0};
    BOOL                            bLsmIdAlloc    = (BOOL                       )FALSE;
    ULONG                           ulClientAddr   = (ULONG                      )AnscReadUlong(pBmoReq->GetClientAddr((ANSC_HANDLE)pBmoReq));
    USHORT                          usClientPort   = (USHORT                     )pBmoReq->GetClientPort((ANSC_HANDLE)pBmoReq);
    BOOL                            bGotSessionId  = (BOOL                       )FALSE;
    BOOL                            bGotLsmId      = (BOOL                       )FALSE;
    ULONG                           i              = 0;
    ULONG                           ulCookieIndex  = 0;

    if ( !pProperty->bEnableSessionTracking )
    {
        return  (ANSC_HANDLE)NULL;
    }

    pHttpHfoCookie =
        (PHTTP_HFO_COOKIE)pBmoReq->GetHeaderField2
        (
            (ANSC_HANDLE)pBmoReq,
            HTTP_HEADER_ID_COOKIE,
            ulCookieIndex ++
        );

    while ( pHttpHfoCookie )
    {
        for ( i = 0; i < pHttpHfoCookie->CookieCount; i++ )
        {
            pCookieContent = &pHttpHfoCookie->CookieArray[i];

            if ( !bGotSessionId     &&
                    AnscEqualString
                    (
                        pCookieContent->Name,
                        pProperty->VhoCookieName,
                        TRUE
                    ) )
            {
                PUCHAR              pCookieValue = pCookieContent->Value;

                /* Some clients will use double quote in cookie value
                 * although we don't specify in Set-Cookie.
                 */
                if ( pCookieValue[0] == '"' )
                {
                    pCookieValue ++;
                }

                ulSessionId = (ULONG)_ansc_atol(pCookieValue);
                bGotSessionId = TRUE;
            }
            else if ( !bGotLsmId      &&
                      AnscEqualString
                      (
                          pCookieContent->Name,
                          pProperty->LsmCookieName,
                          TRUE
                      ) )
            {
                bGotLsmId      = TRUE;
                pLsmIdentifier = pCookieContent->Value;

                /* Some clients will use double quote in cookie value
                 * although we don't specify in Set-Cookie. This may
                 * cause session match failure, and therefore authentication
                 * may fail.
                 */

                if ( pLsmIdentifier )
                {
                    ULONG           ulLen = (ULONG)AnscSizeOfString(pLsmIdentifier);

                    if ( ulLen == 2 && *pLsmIdentifier == '"' && *(pLsmIdentifier + 1) == '"' )
                    {
                        pLsmIdentifier = pEmptyLsmId;
                    }
                    else if ( ulLen > 2 && *pLsmIdentifier == '"' && *(pLsmIdentifier + ulLen - 1) == '"' )
                    {
                        pLsmIdentifier = AnscAllocateMemory(ulLen);
                        AnscCopyMemory(pLsmIdentifier, pCookieContent->Value + 1, ulLen - 2);
                        pLsmIdentifier[ulLen - 2] = 0;
                        bLsmIdAlloc = TRUE;
                    }
                }
            }
        }

        if ( bGotSessionId && bGotLsmId )
        {
            break;
        }

        pHttpHfoCookie =
            (PHTTP_HFO_COOKIE)pBmoReq->GetHeaderField2
            (
                (ANSC_HANDLE)pBmoReq,
                HTTP_HEADER_ID_COOKIE,
                ulCookieIndex ++
            );
    }

    pSession =
        (PWEB_GENERAL_SESSION_OBJECT)pMyObject->GetGso
        (
            (ANSC_HANDLE)pMyObject,
            ulSessionId,
            pLsmIdentifier,
            (PUCHAR)&ulClientAddr,
            usClientPort
        );

    if ( bLsmIdAlloc && pLsmIdentifier )
    {
        AnscFreeMemory(pLsmIdentifier);
    }

    return  (ANSC_HANDLE)pSession;
}
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;
}
static void
HttpScoSetCookie
    (
        ANSC_HANDLE                 hHfpIf,
        ANSC_HANDLE                 hResponse,
        ANSC_HANDLE                 hRequest
    )
{
    PHTTP_HFP_INTERFACE             pHttpHfpIf  = (PHTTP_HFP_INTERFACE)hHfpIf;
    PHTTP_BMO_REP_OBJECT            pResponse   = (PHTTP_BMO_REP_OBJECT)hResponse;
    PHTTP_BMO_REQ_OBJECT            pRequest    = (PHTTP_BMO_REQ_OBJECT)hRequest;
    char*                           pSetCookie  = NULL;
    BOOL                            bSetCookie2 = FALSE;
    ULONG                           ulCount1    = 0;
    ULONG                           ulCount2    = 0;
    PHTTP_HEADER_FIELD              pHttpHfo     = NULL;

    pRequest->DelHeaderField((ANSC_HANDLE)pRequest, HTTP_HEADER_ID_COOKIE);

    while ( TRUE )
    {
        pSetCookie = pResponse->GetHeaderValueByName2((ANSC_HANDLE)pResponse, "Set-Cookie2", ulCount1++);
        if ( !pSetCookie )
        {
            pSetCookie = pResponse->GetHeaderValueByName2((ANSC_HANDLE)pResponse, "Set-Cookie", ulCount2++);
            bSetCookie2 = TRUE;
        }

        if ( !pSetCookie )
        {
            break;
        }
        else
        {
            char*                       pCookie = NULL;
            ULONG                       ulCookieSize    = AnscSizeOfString(pSetCookie) + 64;

            pCookie = (char *)AnscAllocateMemory(ulCookieSize);

            if ( pCookie )
            {
                PHTTP_HFO_SET_COOKIE    pHfoSetCookie = NULL;

                if ( bSetCookie2 )
                {
                    _ansc_sprintf(pCookie, "Set-Cookie2: %s", pSetCookie);
                }
                else
                {
                    _ansc_sprintf(pCookie, "Set-Cookie: %s", pSetCookie);
                }

                pHfoSetCookie = (PHTTP_HFO_SET_COOKIE)pHttpHfpIf->ParseHeader(pHttpHfpIf->hOwnerContext, pCookie, AnscSizeOfString(pCookie));

                if ( pHfoSetCookie )
                {
                    char*               pCookieValue = NULL;

                    pHfoSetCookie->HeaderId = HTTP_HEADER_ID_COOKIE;
                    pHfoSetCookie->Flags &= ~HTTP_FIELD_FLAG_VALUE_PRESENT;
                    pHfoSetCookie->Flags &= ~HTTP_FIELD_FLAG_LINE_PRESENT;

                    ulCookieSize = pHttpHfpIf->GetHeaderSize(pHttpHfpIf->hOwnerContext, (ANSC_HANDLE)pHfoSetCookie);
                    pHttpHfpIf->BuildHeader(pHttpHfpIf->hOwnerContext, (ANSC_HANDLE)pHfoSetCookie, pCookie, ulCookieSize);
                    pCookie[ulCookieSize] = 0;

                    if ( pCookie )
                    {
                        pRequest->SetHeaderValueByName((ANSC_HANDLE)pRequest, "Cookie", pCookie + 8);
                    }

                    AnscFreeMemory(pHfoSetCookie);
                }

                AnscFreeMemory(pCookie);
            }
        }
    }
}
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
WebRooProcess
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep
    )
{
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PWEB_RESOURCE_OWNER_OBJECT      pMyObject       = (PWEB_RESOURCE_OWNER_OBJECT  )hThisObject;
    PWEB_RESOURCE_OWNER_PROPERTY    pProperty       = (PWEB_RESOURCE_OWNER_PROPERTY)&pMyObject->Property;
    PHTTP_RCP_INTERFACE             pRcpIf          = (PHTTP_RCP_INTERFACE         )pMyObject->hRcpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq         = (PHTTP_BMO_REQ_OBJECT        )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pBmoRep         = (PHTTP_BMO_REP_OBJECT        )hBmoRep;
    PHTTP_REQUEST_INFO              pReqInfo        = (PHTTP_REQUEST_INFO          )pBmoReq->GetReqInfo    ((ANSC_HANDLE)pBmoReq);
    PANSC_TOKEN_CHAIN               pPathTokenChain = (PANSC_TOKEN_CHAIN           )pBmoReq->GetRecvContext((ANSC_HANDLE)pBmoReq);
    PWEB_GENERAL_SESSION_OBJECT     pSession        = (PWEB_GENERAL_SESSION_OBJECT )pBmoRep->GetRecvContext((ANSC_HANDLE)pBmoRep);
    PWEB_AUTH_SERVER_OBJECT         pAuthServer     = (PWEB_AUTH_SERVER_OBJECT     )pMyObject->hAuthServer;
    BOOL                            bAuthenticated  = TRUE;

    pBmoReq->SetRcpIf     ((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)pRcpIf   );
    pBmoRep->SetWebServlet((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)pMyObject);

    if ( pReqInfo->MajorVersion != HTTP_CURRENT_MAJOR_VERSION )
    {
        returnStatus =
            pMyObject->ReplyReq
                (
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)pBmoReq,
                    (ANSC_HANDLE)pBmoRep,
                    HTTP_STATUS_VERSION_NOT_SUPPORTED,
                    (ANSC_HANDLE)NULL
                );

        goto  EXIT1;
    }

    if ( pAuthServer )
    {
        returnStatus = 
            pAuthServer->AuthenticateReq
                (
                    (ANSC_HANDLE)pAuthServer,
                    (ANSC_HANDLE)pBmoReq,
                    (ANSC_HANDLE)pBmoRep
                );

        bAuthenticated  = ( returnStatus == ANSC_STATUS_SUCCESS );
        returnStatus = ANSC_STATUS_SUCCESS;
    }

    if ( bAuthenticated )
    {
        switch ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) )
        {
            case    HTTP_METHOD_CODE_OPTIONS :

                    returnStatus =
                        pMyObject->DoOptions
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_GET :

                    returnStatus =
                        pMyObject->DoGet
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_HEAD :

                    returnStatus =
                        pMyObject->DoHead
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_POST :

                    returnStatus =
                        pMyObject->DoPost
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_PUT :

                    returnStatus =
                        pMyObject->DoPut
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_DELETE :

                    returnStatus =
                        pMyObject->DoDelete
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_TRACE :

                    returnStatus =
                        pMyObject->DoTrace
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            case    HTTP_METHOD_CODE_CONNECT :

                    returnStatus =
                        pMyObject->DoConnect
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep
                            );

                    break;

            default :

                    if ( pProperty->OwnerFlag & WEB_ROO_FLAG_UPNP_SUPPORT )
                    {
                        if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) == HTTP_METHOD_CODE_NOTIFY )
                        {
                            returnStatus =
                                pMyObject->DoNotify
                                    (
                                        (ANSC_HANDLE)pMyObject,
                                        (ANSC_HANDLE)pBmoReq,
                                        (ANSC_HANDLE)pBmoRep
                                    );

                            break;
                        }
                        else if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) == HTTP_METHOD_CODE_SEARCH )
                        {
                            returnStatus =
                                pMyObject->DoSearch
                                    (
                                        (ANSC_HANDLE)pMyObject,
                                        (ANSC_HANDLE)pBmoReq,
                                        (ANSC_HANDLE)pBmoRep
                                    );

                            break;
                        }
                        else if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) == HTTP_METHOD_CODE_M_SEARCH )
                        {
                            returnStatus =
                                pMyObject->DoMSearch
                                    (
                                        (ANSC_HANDLE)pMyObject,
                                        (ANSC_HANDLE)pBmoReq,
                                        (ANSC_HANDLE)pBmoRep
                                    );

                            break;
                        }
                        else if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) == HTTP_METHOD_CODE_M_POST )
                        {
                            returnStatus =
                                pMyObject->DoMPost
                                    (
                                        (ANSC_HANDLE)pMyObject,
                                        (ANSC_HANDLE)pBmoReq,
                                        (ANSC_HANDLE)pBmoRep
                                    );

                            break;
                        }
                        else if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) == HTTP_METHOD_CODE_SUBSCRIBE )
                        {
                            returnStatus =
                                pMyObject->DoSubscribe
                                    (
                                        (ANSC_HANDLE)pMyObject,
                                        (ANSC_HANDLE)pBmoReq,
                                        (ANSC_HANDLE)pBmoRep
                                    );

                            break;
                        }
                        else if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) == HTTP_METHOD_CODE_UNSUBSCRIBE )
                        {
                            returnStatus =
                                pMyObject->DoUnsubscribe
                                    (
                                        (ANSC_HANDLE)pMyObject,
                                        (ANSC_HANDLE)pBmoReq,
                                        (ANSC_HANDLE)pBmoRep
                                    );

                            break;
                        }
                    }

                    returnStatus =
                        pMyObject->ReplyReq
                            (
                                (ANSC_HANDLE)pMyObject,
                                (ANSC_HANDLE)pBmoReq,
                                (ANSC_HANDLE)pBmoRep,
                                HTTP_STATUS_NOT_IMPLEMENTED,
                                (ANSC_HANDLE)NULL
                            );

                    break;
        }
    }

    /******************************************************************
                GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS
    ******************************************************************/

EXIT1:

    AnscDelTokenChain((ANSC_HANDLE)pPathTokenChain);
    AnscFreeMemory   ((ANSC_HANDLE)pPathTokenChain);

    return  returnStatus;
}
ANSC_STATUS
HttpTroResumeTransaction
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hReserved,
        ULONG                       ulSbcPmode
    )
{
    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_ADVANCED_PROXY_PROPERTY   pSpoProperty   = (PHTTP_ADVANCED_PROXY_PROPERTY )&pAdvancedProxy->Property;
    PHTTP_WAM_INTERFACE             pWamIf         = (PHTTP_WAM_INTERFACE           )pMyObject->hWamIf;
    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;

    if ( pMyObject->SbcPmode != HTTP_SBC_PMODE_QUEUE )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else if ( (ulSbcPmode != HTTP_SBC_PMODE_RELAY1) &&
              (ulSbcPmode != HTTP_SBC_PMODE_RELAY2) &&
              (ulSbcPmode != HTTP_SBC_PMODE_STORE ) )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }

    pMyObject->AcquireAccess((ANSC_HANDLE)pMyObject);

    if ( !pServerSocket )
    {
        returnStatus =
            pMyObject->SetUpConnection
                (
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)NULL
                );
    }

    if ( returnStatus != ANSC_STATUS_SUCCESS )
    {
        pMyObject->ReleaseAccess((ANSC_HANDLE)pMyObject);

        return  returnStatus;
    }
    else
    {
        pMyObject->SbcPmode = ulSbcPmode;
        returnStatus        =
            pMyObject->SendToServer
                (
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)pBmoReq,
                    HTTP_TRO_SFLAG_HEADERS | HTTP_TRO_SFLAG_BODY
                );
    }

    if ( (ulSbcPmode == HTTP_SBC_PMODE_RELAY1) ||
         (ulSbcPmode == HTTP_SBC_PMODE_RELAY2) )
    {
        pBmoReq->SetMboMode((ANSC_HANDLE)pBmoReq, HTTP_MBO_MODE_RELAY);
    }
    else
    {
        pBmoReq->SetMboMode((ANSC_HANDLE)pBmoReq, HTTP_MBO_MODE_STORE);
    }

    pMyObject->ReleaseAccess((ANSC_HANDLE)pMyObject);

    return  returnStatus;
}
ANSC_STATUS
HttpBmoSaveFormAsFile
    (
        ANSC_HANDLE                 hThisObject,
        char*                       param_name,
        char*                       file_name,
        BOOL                        bFlushBody
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PHTTP_BASIC_MESSAGE_OBJECT      pMyObject    = (PHTTP_BASIC_MESSAGE_OBJECT)hThisObject;
    PHTTP_BMO_REQ_OBJECT            pBmoReq      = (PHTTP_BMO_REQ_OBJECT      )pMyObject;
    PHTTP_HFP_INTERFACE             pHfpIf       = (PHTTP_HFP_INTERFACE       )pMyObject->hHfpIf;
    PHTTP_TMH_INTERFACE             pTmhIf       = (PHTTP_TMH_INTERFACE       )pMyObject->hTmhIf;
    PHTTP_BCC_INTERFACE             pBccIf       = (PHTTP_BCC_INTERFACE       )pMyObject->hBccIf;
    PHTTP_RCP_INTERFACE             pRcpIf       = (PHTTP_RCP_INTERFACE          )pBmoReq->hRcpIf;
    PHTTP_FUM_INTERFACE             pFumIf       = (PHTTP_FUM_INTERFACE       )pMyObject->hFumIf;
    PHTTP_MDH_INTERFACE             pMdhIf       = (PHTTP_MDH_INTERFACE       )NULL;
    PHTTP_MESSAGE_BODY_OBJECT       pMessageBody = (PHTTP_MESSAGE_BODY_OBJECT )pMyObject->hMessageBody;
    char*                           pBoundaryStr = NULL;
    ULONG                           ulEncType    = HTTP_HFP_FORM_ENCTYPE_URLENCODED;
    ULONG                           ulMediaType  = IANA_MEDIA_TYPE_CODE_APPLICATION;
    ULONG                           ulSubType    = IANA_MT_AP_STYPE_CODE_X_FORM_URLENCODED;
    char*                           pReqUri      = pRcpIf->GetPathInfo(pRcpIf->hOwnerContext, (ANSC_HANDLE)pMyObject);

    pMdhIf = (PHTTP_MDH_INTERFACE)pFumIf->GetMdhIf(pFumIf->hOwnerContext, pReqUri);

    if ( pMdhIf )
    {
        return
            pMdhIf->SaveFileAs
                (
                    pMdhIf->hOwnerContext,
                    pBmoReq->GetWebSessionId((ANSC_HANDLE)pBmoReq),
                    pReqUri,
                    param_name,
                    file_name
                );
    }

    if ( !pMessageBody || (pMyObject->Oid != HTTP_BMO_REQ_OID) )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else if ( pBmoReq->GetMethod((ANSC_HANDLE)pBmoReq) != HTTP_METHOD_CODE_POST )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }

    if ( TRUE )
    {
        returnStatus =
        	HttpBmoReqCgiGetContentType
                (
                    (ANSC_HANDLE)pBmoReq,
                    &ulMediaType,
                    &ulSubType
                );

        if ( (ulMediaType == IANA_MEDIA_TYPE_CODE_APPLICATION       ) &&
             (ulSubType   == IANA_MT_AP_STYPE_CODE_X_FORM_URLENCODED) )
        {
            ulEncType = HTTP_HFP_FORM_ENCTYPE_URLENCODED;
        }
        else if ( (ulMediaType == IANA_MEDIA_TYPE_CODE_MULTIPART ) &&
                  (ulSubType   == IANA_MT_MP_STYPE_CODE_FORM_DATA) )
        {
            ulEncType    = HTTP_HFP_FORM_ENCTYPE_MULTIPART;
            pBoundaryStr = HttpBmoReqCgiGetBoundaryDelimiter((ANSC_HANDLE)pBmoReq);

            if ( !pBoundaryStr )
            {
                return  ANSC_STATUS_UNAPPLICABLE;
            }
        }
        else
        {
            return  ANSC_STATUS_UNAPPLICABLE;
        }
    }

    returnStatus =
        pHfpIf->SaveFormPartAsFile
            (
                pHfpIf->hOwnerContext,
                param_name,
                file_name,
                ulEncType,
                pBoundaryStr,
                (ANSC_HANDLE)pMessageBody,
                bFlushBody
            );

    if ( pBoundaryStr )
    {
        AnscFreeMemory(pBoundaryStr);
    }

    return  returnStatus;
}
ANSC_STATUS
HttpWstoRecv
    (
        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                           ulBmoState    = HTTP_BMO_STATE_EMPTY;

    pBmoReq->SetFumIf((ANSC_HANDLE)pBmoReq, pSimpleServer->GetFumIf((ANSC_HANDLE)pSimpleServer));

    pBmoReq->SetWebSessionId((ANSC_HANDLE)pBmoReq, (ULONG)pMyObject->hWebsSession);

    /*
     * At time like this, you will always have two options on how to proceed with the message
     * processing:
     *
     *      $ Examine the current object states and the content of the message payload
     *        to make the processing decisions in this object.
     *
     *      $ Offload the examination and certain state-transition functions to another
     *        object and provide an interface to be notified when something happens.
     *
     * Guess which one we're using here ...
     */
    buffer       = AnscBdoGetBlock    (pBufferDesp);
    ulSize       = AnscBdoGetBlockSize(pBufferDesp);
    returnStatus =
        pBmoReq->Process
            (
                (ANSC_HANDLE)pBmoReq,
                (ANSC_HANDLE)pBufferDesp
            );

    if ( (returnStatus != ANSC_STATUS_SUCCESS    ) &&
         (returnStatus != ANSC_STATUS_DO_IT_AGAIN) )
    {
        pMyObject->TransState = HTTP_WSTO_STATE_FINISHED;
    }

    if ( (pMyObject->TransState == HTTP_WSTO_STATE_ESTABLISHED) ||
         (pMyObject->TransState == HTTP_WSTO_STATE_FINISHED   ) )
    {
        /*
         * To avoid unnessary memory consumption, we release the resources allocated for this
         * transaction right away...
         */
        pMyObject->Close((ANSC_HANDLE)pMyObject);
    }

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpAcscoHttpBspBrowse
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep,
        ANSC_HANDLE                 hReqContext
    )
{
    ANSC_STATUS                     returnStatus      = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject         = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PHTTP_BMO_REQ_OBJECT            pHttpBmoReq       = (PHTTP_BMO_REQ_OBJECT      )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pHttpBmoRep       = (PHTTP_BMO_REP_OBJECT      )hBmoRep;
    PANSC_ACS_INTERN_HTTP_CONTENT   pHttpGetReq       = (PANSC_ACS_INTERN_HTTP_CONTENT )hReqContext;
    PHTTP_RESPONSE_INFO             pHttpRepInfo      = (PHTTP_RESPONSE_INFO       )pHttpBmoRep->GetRepInfo ((ANSC_HANDLE)pHttpBmoRep);
    ULONG                           ulResponseSize    = (ULONG                     )pHttpBmoRep->GetBodySize((ANSC_HANDLE)pHttpBmoRep);
    char*                           pHttpResponse     = (char*                     )NULL;
    char*                           pHeaderLocation   = NULL;
    char*                           pCookie           = NULL;
    ULONG                           ulCode            = 0;
    char*                           pCookieHeader     = NULL;
    ULONG                           ulCookieIndex     = 0;
    BOOL                            bCookiesRemoved   = FALSE;

    if ( pHttpGetReq == NULL)
    {
        return ANSC_STATUS_FAILURE;
    }

    ulCode = pHttpBmoRep->GetCode((ANSC_HANDLE)pHttpBmoRep);

    if( HTTP_STATUS_NO_CONTENT == ulCode) /* ACS has nothing to say */
    {
        if( pHttpGetReq != NULL)
        {
            pHttpGetReq->ulContentSize = 0;
            pHttpGetReq->pContent      = NULL;
            pHttpGetReq->bIsRedirect   = FALSE;
        }

        returnStatus = ANSC_STATUS_SUCCESS;

        goto EXIT1;
    }
    else if( HTTP_STATUS_MOVED_PERMANENTLY != ulCode &&
             HTTP_STATUS_FOUND != ulCode             &&
             HTTP_STATUS_OK != ulCode                &&
             HTTP_STATUS_UNAUTHORIZED != ulCode		 &&
			 HTTP_STATUS_TEMP_REDIRECT != ulCode
           )
    {
        returnStatus = ANSC_STATUS_FAILURE;

        CcspTr069PaTraceDebug(("HttpClient returned code: %d\n", (int)ulCode));

        goto  EXIT1;
    }

    /* save Authorization header value */
    if ( TRUE )
    {
        char*                       pAuthHeaderValue   = NULL;

        /* Authorization header in request */
        pAuthHeaderValue = pHttpBmoReq->GetHeaderValueById((ANSC_HANDLE)pHttpBmoReq, HTTP_HEADER_ID_AUTHORIZATION);

        if ( pMyObject->AuthHeaderValue ) CcspTr069PaFreeMemory(pMyObject->AuthHeaderValue);
        pMyObject->AuthHeaderValue = CcspTr069PaCloneString(pAuthHeaderValue);
    }

    /* look for Set-Cookie headers */
    pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE2, ulCookieIndex);

    if ( pCookie && AnscSizeOfString(pCookie) > 0 )
    {
        /*
        pMyObject->RemoveCookies((ANSC_HANDLE)pMyObject);
        bCookiesRemoved = TRUE;
        */

        while ( pCookie != NULL && AnscSizeOfString(pCookie) > 0)
        {
            pCookieHeader = CcspTr069PaAllocateMemory(AnscSizeOfString(pCookie) + 16);

            if ( pCookieHeader )
                _ansc_sprintf(pCookieHeader, "Set-Cookie2: %s", pCookie);

            pMyObject->AddCookie((ANSC_HANDLE)pMyObject, pCookieHeader);
            CcspTr069PaFreeMemory(pCookieHeader);

            pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE2, ++ulCookieIndex);
        }
    }

    /* If Set-Cookie and Set-Cookie2 co-exist happily, we save them all */
    ulCookieIndex = 0;
    pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE, ulCookieIndex);

    if( pCookie != NULL && AnscSizeOfString(pCookie) > 0)
    {
        /*
        if ( !bCookiesRemoved )
        {
            pMyObject->RemoveCookies((ANSC_HANDLE)pMyObject);
            bCookiesRemoved = TRUE;
        }
        */

        while ( pCookie && AnscSizeOfString(pCookie) )
        {
            pCookieHeader = CcspTr069PaAllocateMemory(AnscSizeOfString(pCookie) + 16);

            if ( pCookieHeader )
                _ansc_sprintf(pCookieHeader, "Set-Cookie: %s", pCookie);

            pMyObject->AddCookie((ANSC_HANDLE)pMyObject, pCookieHeader);
            CcspTr069PaFreeMemory(pCookieHeader);

            pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE, ++ulCookieIndex);
        }
    }

    /*
    if ( !bCookiesRemoved )
    {
        CcspTr069PaTraceDebug(("No Cookie in the response.\n"));

        if( pMyObject->NumCookies != 0)
        {
            for ( i = 0; i < pMyObject->NumCookies; i ++ )
            {
                CcspTr069PaTraceDebug(("Keep the old cookie: %s\n", pMyObject->Cookies[i]));
            }
        }
        else
        {
            CcspTr069PaTraceDebug(("???No cookie exists...\n"));
        }
    }
    */

    if( HTTP_STATUS_UNAUTHORIZED == ulCode)
    {
        /* make sure if server sends back challenge, terminates the session if otherwise */
        char*                       pWwwAuth = NULL;

        pHttpGetReq->bUnauthorized = TRUE;
        
        pWwwAuth = pHttpBmoRep->GetHeaderValueByName((ANSC_HANDLE)pHttpBmoRep, "WWW-Authenticate");
        if ( pWwwAuth )
        {
            returnStatus = ANSC_STATUS_DO_IT_AGAIN; /* ANSC_STATUS_SUCCESS; */
        }
        else
        {
            returnStatus = ANSC_STATUS_FAILURE;
        }

        goto EXIT1;
    }

    if( ulCode == HTTP_STATUS_MOVED_PERMANENTLY || HTTP_STATUS_FOUND == ulCode || HTTP_STATUS_TEMP_REDIRECT == ulCode)
    {
        pHeaderLocation     = pHttpBmoRep->GetHeaderValueByName((ANSC_HANDLE)pHttpBmoRep, "Location"     );

        if( pHeaderLocation == NULL || AnscSizeOfString(pHeaderLocation) == 0)
        {
            returnStatus = ANSC_STATUS_FAILURE;

            goto  EXIT1;
        }

        CcspTr069PaTraceInfo(("ACS URL moved (HTTP code=%u) to: %s\n", ulCode, pHeaderLocation));

        pHttpGetReq->ulContentSize = AnscSizeOfString(pHeaderLocation);
        pHttpGetReq->pContent      = CcspTr069PaCloneString(pHeaderLocation);
        pHttpGetReq->bIsRedirect   = TRUE;

        /* notify underlying HTTP Webc Transaction object to clearn request
         * otherwise, in case ACS closes the socket first, we will get notified
         * again and current session will be terminated prematurely.
         */
        returnStatus = ANSC_STATUS_NO_MORE_DATA;
    }
    else
    {
        if ( ulResponseSize == 0 )
        {
             returnStatus = ANSC_STATUS_FAILURE;

            goto  EXIT1;
        }
        else
        {
            pHttpResponse = (char*)CcspTr069PaAllocateMemory(ulResponseSize + 1);  /* we must leave room for the NULL terminator */

            if ( !pHttpResponse )
            {
                returnStatus = ANSC_STATUS_RESOURCES;

                goto  EXIT1;
            }
            else
            {
                returnStatus =
                    pHttpBmoRep->CopyBodyFrom
                        (
                            (ANSC_HANDLE)pHttpBmoRep,
                            pHttpResponse,
                            &ulResponseSize
                        );
            }
        }

        pHttpGetReq->ulContentSize = ulResponseSize;
        pHttpGetReq->pContent      = (PVOID)pHttpResponse;
        pHttpGetReq->bIsRedirect   = FALSE;
    }

    /******************************************************************
                GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS
    ******************************************************************/

EXIT1:

    if ( pHttpGetReq )
    {
        pHttpGetReq->CompleteStatus = 
            (returnStatus == ANSC_STATUS_DO_IT_AGAIN || returnStatus == ANSC_STATUS_NO_MORE_DATA) ? ANSC_STATUS_SUCCESS : returnStatus;

        AnscSetEvent(&pHttpGetReq->CompleteEvent);
    }

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpAcscoHttpBspPolish
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hReqContext
    )
{
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject       = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PANSC_ACS_INTERN_HTTP_CONTENT    pHttpGetReq     = (PANSC_ACS_INTERN_HTTP_CONTENT)hReqContext;
    ANSC_STATUS                      returnStatus    = ANSC_STATUS_SUCCESS;
    PHTTP_BMO_REQ_OBJECT             pBmoReqObj      = (PHTTP_BMO_REQ_OBJECT)hBmoReq;
    char                             pBuffer[64]     = { 0 };
    ULONG                            i, len          = 0;

    /* add Authorization header - last good one */
    if ( pMyObject->AuthHeaderValue )
    {
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Authorization", pMyObject->AuthHeaderValue);
    }

    /*
     * If there's a cookie returned, add the cookie
     */
    for ( i = 0; i < pMyObject->NumCookies; i ++ )
    {
    	if ( pMyObject->Cookies[i] == NULL )
    		break;

    	len += _ansc_strlen(pMyObject->Cookies[i]);
    }

    if ( pMyObject->NumCookies == 0 )
    {
        CcspTr069PaTraceDebug(("No Cookie will be added.\n"));
    }
    else
    {
    	char *cookies = (char *)CcspTr069PaAllocateMemory(len + pMyObject->NumCookies*2);

    	if (cookies) {
        	AnscZeroMemory(cookies, len + pMyObject->NumCookies*2);

            for ( i = 0; i < pMyObject->NumCookies; i ++ )
            {
            	if ( pMyObject->Cookies[i] == NULL )
            		break;

            	_ansc_strcat(cookies, pMyObject->Cookies[i]);
            	if ( i < pMyObject->NumCookies - 1 )
            		_ansc_strcat(cookies, "; ");
            }

            pBmoReqObj->SetHeaderValueByName
				(
					(ANSC_HANDLE)pBmoReqObj,
					"Cookie",
					cookies
				);

			CcspTr069PaTraceDebug(("Add Cookie into message: %s\n", cookies));
			CcspTr069PaFreeMemory(cookies);
    	}

    }

    /* When there is more than one envelope in a single HTTP Request,
     * when there is a SOAP response in an HTTP Request, or when there is a
     * SOAP Fault response in an HTTP Request, the SOAPAction header in the
     * HTTP Request MUST have no value (with no quotes), indicating that this
     * header provides no information as to the intent of the message."
     */
    if( pHttpGetReq ==NULL || pHttpGetReq->SoapMessage == NULL || AnscSizeOfString(pHttpGetReq->SoapMessage) == 0)
    {
        /*
         * An empty HTTP POST MUST NOT contain a SOAPAction header.
         * An empty HTTP POST MUST NOT contain a Content-Type header.
         */
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Length", "0");
        /* pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Type", "text/xml;charset=utf-8"); */
    }
    else
    {
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Type", "text/xml;charset=utf-8");

        _ansc_sprintf(pBuffer, "%u", (unsigned int)AnscSizeOfString(pHttpGetReq->SoapMessage));
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Length", pBuffer);

        if( pHttpGetReq->MethodName == NULL || AnscSizeOfString(pHttpGetReq->MethodName) == 0)
        {
            pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "SOAPAction", "");
        }
        else
        {
            _ansc_sprintf(pBuffer, "\"%s\"", pHttpGetReq->MethodName);
            pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "SOAPAction", pBuffer);
        }

        returnStatus =
            pBmoReqObj->AppendBody
                (
                    pBmoReqObj,
                    pHttpGetReq->SoapMessage,
                    AnscSizeOfString(pHttpGetReq->SoapMessage)
                );
    }

    return  returnStatus;
}
ANSC_STATUS
BwspWsoDoConnect
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep
    )
{
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PBWSP_WEB_SERVLET_OBJECT        pMyObject       = (PBWSP_WEB_SERVLET_OBJECT   )hThisObject;
    PBWSP_WEB_SERVLET_PROPERTY      pProperty       = (PBWSP_WEB_SERVLET_PROPERTY )&pMyObject->Property;
    PBWSP_WSH_INTERFACE             pBwspWshIf      = (PBWSP_WSH_INTERFACE        )pMyObject->hBwspWshIf;
    PHTTP_RCP_INTERFACE             pRcpIf          = (PHTTP_RCP_INTERFACE        )pMyObject->hRcpIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq         = (PHTTP_BMO_REQ_OBJECT       )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pBmoRep         = (PHTTP_BMO_REP_OBJECT       )hBmoRep;
    PHTTP_REQUEST_INFO              pReqInfo        = (PHTTP_REQUEST_INFO         )pBmoReq->GetReqInfo    ((ANSC_HANDLE)pBmoReq);
    PANSC_TOKEN_CHAIN               pPathTokenChain = (PANSC_TOKEN_CHAIN          )pBmoReq->GetRecvContext((ANSC_HANDLE)pBmoReq);
    PWEB_GENERAL_SESSION_OBJECT     pSession        = (PWEB_GENERAL_SESSION_OBJECT)pBmoRep->GetRecvContext((ANSC_HANDLE)pBmoRep);
    PHTTP_HFO_ALLOW                 pHttpHfoAllow   = NULL;
    ULONG                           j               = 0;

    if ( pBwspWshIf->DoConnect )
    {
        returnStatus =
            pBwspWshIf->DoConnect
                (
                    pBwspWshIf->hOwnerContext,
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)pBmoReq,
                    (ANSC_HANDLE)pBmoRep
                );
    }
    else
    {
        pHttpHfoAllow = (PHTTP_HFO_ALLOW)AnscAllocateMemory(sizeof(HTTP_HFO_ALLOW));

        if ( !pHttpHfoAllow )
        {
            return  ANSC_STATUS_RESOURCES;
        }
        else
        {
            pHttpHfoAllow->HashIndex        = 0;
            pHttpHfoAllow->Flags            = 0;
            pHttpHfoAllow->HeaderId         = HTTP_HEADER_ID_ALLOW;

            j                               = 0;
            pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_OPTIONS;
            pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_GET;
            pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_HEAD;

            if ( pBwspWshIf->DoPost )
            {
                pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_POST;
            }

            if ( pBwspWshIf->DoPut )
            {
                pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_PUT;
            }

            if ( pBwspWshIf->DoDelete )
            {
                pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_DELETE;
            }

            if ( pBwspWshIf->DoTrace )
            {
                pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_TRACE;
            }

            if ( pBwspWshIf->DoConnect )
            {
                pHttpHfoAllow->MethodArray[j++] = HTTP_METHOD_CODE_CONNECT;
            }

            pHttpHfoAllow->MethodCount = j;
        }

        returnStatus =
            pMyObject->ReplyReq
                (
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)pBmoReq,
                    (ANSC_HANDLE)pBmoRep,
                    HTTP_STATUS_METHOD_NOT_ALLOWED,
                    (ANSC_HANDLE)pHttpHfoAllow
                );
    }

    return  returnStatus;
}
ANSC_STATUS
HttpWstoOpen
    (
        ANSC_HANDLE                 hThisObject
    )
{
    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;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pWebSocket    = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pMyObject->hWebSocket;
    PHTTP_HFP_INTERFACE             pHfpIf        = (PHTTP_HFP_INTERFACE           )pMyObject->hHfpIf;
    PHTTP_TMH_INTERFACE             pTmhIf        = (PHTTP_TMH_INTERFACE           )pMyObject->hTmhIf;
    PHTTP_BMO_REQ_OBJECT            pBmoReq       = (PHTTP_BMO_REQ_OBJECT          )pMyObject->hBmoReq;
    PHTTP_BMO_REP_OBJECT            pBmoRep       = (PHTTP_BMO_REP_OBJECT          )pMyObject->hBmoRep;
    HTTP_SIMPLE_SERVER_PROPERTY     httpSsoProperty;

    returnStatus =
        pSimpleServer->GetProperty
            (
                (ANSC_HANDLE)pSimpleServer,
                (ANSC_HANDLE)&httpSsoProperty
            );

    if ( !pBmoReq )
    {
        pBmoReq = (PHTTP_BMO_REQ_OBJECT)pSimpleServer->AcquireBmoReq((ANSC_HANDLE)pSimpleServer);

        if ( !pBmoReq )
        {
            return  ANSC_STATUS_RESOURCES;
        }
        else
        {
            pMyObject->hBmoReq = (ANSC_HANDLE)pBmoReq;
        }

        pBmoReq->SetHfpIf        ((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)pHfpIf            );
        pBmoReq->SetTmhIf        ((ANSC_HANDLE)pBmoReq, (ANSC_HANDLE)pTmhIf            );
        pBmoReq->SetTransactionId((ANSC_HANDLE)pBmoReq, 0                              );
        pBmoReq->SetClientAddr   ((ANSC_HANDLE)pBmoReq, pWebSocket->PeerAddress.Dot    );
        pBmoReq->SetClientPort   ((ANSC_HANDLE)pBmoReq, pWebSocket->PeerPort           );
        pBmoReq->SetDaemonAddr   ((ANSC_HANDLE)pBmoReq, httpSsoProperty.HostAddress.Dot);
        pBmoReq->SetDaemonPort   ((ANSC_HANDLE)pBmoReq, httpSsoProperty.HostPort       );
        pBmoReq->SetServerMode   ((ANSC_HANDLE)pBmoReq, pSimpleServer->ServerMode      );
    }

    if ( !pBmoRep )
    {
        pBmoRep = (PHTTP_BMO_REP_OBJECT)pSimpleServer->AcquireBmoRep((ANSC_HANDLE)pSimpleServer);

        if ( !pBmoRep )
        {
            return  ANSC_STATUS_RESOURCES;
        }
        else
        {
            pMyObject->hBmoRep = (ANSC_HANDLE)pBmoRep;
        }

        pBmoRep->SetHfpIf        ((ANSC_HANDLE)pBmoRep, (ANSC_HANDLE)pHfpIf);
        pBmoRep->SetTmhIf        ((ANSC_HANDLE)pBmoRep, (ANSC_HANDLE)pTmhIf);
        pBmoRep->SetTransactionId((ANSC_HANDLE)pBmoRep, 0                  );
    }

    return  ANSC_STATUS_SUCCESS;
}
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;
}