ANSC_STATUS AnscSctoTsaSendTlsMessage ( ANSC_HANDLE hThisObject, ANSC_HANDLE hMessageBdo ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_SIMPLE_CLIENT_TCP_OBJECT pMyObject = (PANSC_SIMPLE_CLIENT_TCP_OBJECT)hThisObject; PANSC_SCTO_WORKER_OBJECT pWorker = (PANSC_SCTO_WORKER_OBJECT )pMyObject->hWorker; PANSC_BUFFER_DESCRIPTOR pPayloadBdo = (PANSC_BUFFER_DESCRIPTOR)hMessageBdo; returnStatus = pMyObject->Send2 ( (ANSC_HANDLE)pMyObject, AnscBdoGetBlock (pPayloadBdo), AnscBdoGetBlockSize(pPayloadBdo), (ANSC_HANDLE)NULL ); AnscFreeBdo((ANSC_HANDLE)pPayloadBdo); return returnStatus; }
ANSC_STATUS AnscDktoTsaSendTlsMessage ( ANSC_HANDLE hThisObject, ANSC_HANDLE hMessageBdo ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_DAEMON_SOCKET_TCP_OBJECT pMyObject = (PANSC_DAEMON_SOCKET_TCP_OBJECT)hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_DAEMON_ENGINE_TCP_OBJECT pEngine = (PANSC_DAEMON_ENGINE_TCP_OBJECT)pMyObject->hDaemonEngine; PANSC_DSTO_WORKER_OBJECT pWorker = (PANSC_DSTO_WORKER_OBJECT )pServer->hWorker; PANSC_BUFFER_DESCRIPTOR pPayloadBdo = (PANSC_BUFFER_DESCRIPTOR )hMessageBdo; if ( pMyObject->bClosed || pMyObject->bBroken ) { return ANSC_STATUS_UNAPPLICABLE; } returnStatus = pEngine->Send2 ( (ANSC_HANDLE)pEngine, (ANSC_HANDLE)pMyObject, AnscBdoGetBlock (pPayloadBdo), AnscBdoGetBlockSize(pPayloadBdo), (ANSC_HANDLE)NULL ); AnscFreeBdo((ANSC_HANDLE)pPayloadBdo); return returnStatus; }
ANSC_STATUS HttpPsoVer2FinishedByClient ( ANSC_HANDLE hThisObject, PVOID buffer, ULONG ulSize, ANSC_HANDLE hBufferContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_PSO_VER2_OBJECT pMyObject = (PHTTP_PSO_VER2_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_TRANS_RECORD_OBJECT pTransRecord = (PHTTP_TRANS_RECORD_OBJECT )pMyObject->GetLastTro((ANSC_HANDLE)pMyObject); if ( !pTransRecord ) { if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } return ANSC_STATUS_INTERNAL_ERROR; } else if ( pTransRecord->GetTransState((ANSC_HANDLE)pTransRecord) == HTTP_TRO_STATE_FINISHED ) { if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); return ANSC_STATUS_UNAPPLICABLE; } buffer = AnscBdoGetBlock (pBufferDesp); ulSize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = pTransRecord->FinishedByClient ( (ANSC_HANDLE)pTransRecord, buffer, ulSize, (ANSC_HANDLE)pBufferDesp ); pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); return returnStatus; }
ANSC_STATUS HttpWssoFinish ( ANSC_HANDLE hThisObject, PVOID buffer, ULONG ulSize, ANSC_HANDLE hBufferContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_WEBS_SESSION_OBJECT pMyObject = (PHTTP_WEBS_SESSION_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_WEBS_TRANS_OBJECT pWebsTrans = (PHTTP_WEBS_TRANS_OBJECT )pMyObject->GetEndWsto((ANSC_HANDLE)pMyObject); if ( !pWebsTrans ) { if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } return ANSC_STATUS_INTERNAL_ERROR; } else if ( pWebsTrans->GetTransState((ANSC_HANDLE)pWebsTrans) == HTTP_WSTO_STATE_FINISHED ) { if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } pWebsTrans->ReleaseAccess((ANSC_HANDLE)pWebsTrans); return ANSC_STATUS_UNAPPLICABLE; } buffer = AnscBdoGetBlock (pBufferDesp); ulSize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = pWebsTrans->Finish ( (ANSC_HANDLE)pWebsTrans, buffer, ulSize, (ANSC_HANDLE)pBufferDesp ); pWebsTrans->ReleaseAccess((ANSC_HANDLE)pWebsTrans); 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 HttpPsoVer2RecvFromClient ( ANSC_HANDLE hThisObject, PVOID buffer, ULONG ulSize, ANSC_HANDLE hBufferContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_PSO_VER2_OBJECT pMyObject = (PHTTP_PSO_VER2_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_TRANS_RECORD_OBJECT pTransRecord = (PHTTP_TRANS_RECORD_OBJECT )pMyObject->GetCurTro((ANSC_HANDLE)pMyObject); if ( !pTransRecord ) { pMyObject->SessionState = HTTP_PSOVER2_STATE_FINISHED; return ANSC_STATUS_INTERNAL_ERROR; } buffer = AnscBdoGetBlock (pBufferDesp); ulSize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = pTransRecord->RecvFromClient ( (ANSC_HANDLE)pTransRecord, buffer, ulSize, (ANSC_HANDLE)pBufferDesp ); if ( (returnStatus != ANSC_STATUS_SUCCESS ) && (returnStatus != ANSC_STATUS_DO_IT_AGAIN) ) { pMyObject->SessionState = HTTP_PSOVER2_STATE_FINISHED; } pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); return returnStatus; }
ANSC_STATUS HttpWssoRecv ( ANSC_HANDLE hThisObject, PVOID buffer, ULONG ulSize, ANSC_HANDLE hBufferContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_WEBS_SESSION_OBJECT pMyObject = (PHTTP_WEBS_SESSION_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_WEBS_TRANS_OBJECT pWebsTrans = (PHTTP_WEBS_TRANS_OBJECT )pMyObject->GetCurWsto((ANSC_HANDLE)pMyObject); if ( !pWebsTrans ) { pMyObject->SessionState = HTTP_WSSO_STATE_FINISHED; return ANSC_STATUS_INTERNAL_ERROR; } buffer = AnscBdoGetBlock (pBufferDesp); ulSize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = pWebsTrans->Recv ( (ANSC_HANDLE)pWebsTrans, buffer, ulSize, (ANSC_HANDLE)pBufferDesp ); if ( (returnStatus != ANSC_STATUS_SUCCESS ) && (returnStatus != ANSC_STATUS_DO_IT_AGAIN) ) { pMyObject->SessionState = HTTP_WSSO_STATE_FINISHED; } pWebsTrans->ReleaseAccess((ANSC_HANDLE)pWebsTrans); 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; }
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; }
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; }
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 HttpSpoPrvwoNotify ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, ULONG ulEvent, ANSC_HANDLE hReserved ) { 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; PANSC_SIMPLE_PROXY_TCP_OBJECT pSimpleProxy = (PANSC_SIMPLE_PROXY_TCP_OBJECT )pMyObject->hSimpleProxy; PANSC_DAEMON_SOCKET_TCP_OBJECT pClientSocket = (PANSC_DAEMON_SOCKET_TCP_OBJECT)hSocket; PANSC_BROKER_SOCKET_TCP_OBJECT pServerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)NULL; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pClientSocket->GetBufferContext((ANSC_HANDLE)pClientSocket); PHTTP_PROXY_SESSION_OBJECT pSession = NULL; AnscTrace ( "Event = %d is indicated on client connection of %d.%d.%d.%d / TCP %d\n", ulEvent, pClientSocket->PeerAddress.Dot[0], pClientSocket->PeerAddress.Dot[1], pClientSocket->PeerAddress.Dot[2], pClientSocket->PeerAddress.Dot[3], pClientSocket->PeerPort ); switch ( ulEvent ) { case ANSC_SPTOWO_EVENT_SOCKET_ERROR : pClientSocket->ToClean((ANSC_HANDLE)pClientSocket, TRUE, HTTP_SPO_SOCKET_TTC); break; case ANSC_SPTOWO_EVENT_SOCKET_CLOSED : AnscAcquireLock(&pMyObject->SyncLock); pSession = (PHTTP_PROXY_SESSION_OBJECT)pClientSocket->GetClientContext((ANSC_HANDLE)pClientSocket); if ( !pSession ) { AnscReleaseLock(&pMyObject->SyncLock); pClientSocket->Finish((ANSC_HANDLE)pClientSocket); break; } else { pSession->AcquireAccess((ANSC_HANDLE)pSession); } AnscReleaseLock(&pMyObject->SyncLock); pBufferDesp->BlockSize += pClientSocket->RecvPacketSize; returnStatus = pClientSocket->SetBufferContext ( (ANSC_HANDLE)pClientSocket, NULL, 0, (ANSC_HANDLE)NULL ); returnStatus = pSession->FinishedByClient ( (ANSC_HANDLE)pSession, AnscBdoGetBlock (pBufferDesp), AnscBdoGetBlockSize(pBufferDesp), (ANSC_HANDLE)pBufferDesp ); pSession->ReleaseAccess((ANSC_HANDLE)pSession); pClientSocket->Finish((ANSC_HANDLE)pClientSocket); break; case ANSC_SPTOWO_EVENT_RESOURCES : break; case ANSC_SPTOWO_EVENT_TIME_OUT : break; default : break; } return ANSC_STATUS_SUCCESS; }
ANSC_STATUS AnscDktoTsaRecvAppMessage ( ANSC_HANDLE hThisObject, ANSC_HANDLE hMessageBdo ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_DAEMON_SOCKET_TCP_OBJECT pMyObject = (PANSC_DAEMON_SOCKET_TCP_OBJECT)hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_DAEMON_ENGINE_TCP_OBJECT pEngine = (PANSC_DAEMON_ENGINE_TCP_OBJECT)pMyObject->hDaemonEngine; PANSC_DSTO_WORKER_OBJECT pWorker = (PANSC_DSTO_WORKER_OBJECT )pServer->hWorker; PANSC_BUFFER_DESCRIPTOR pPayloadBdo = (PANSC_BUFFER_DESCRIPTOR )hMessageBdo; void* pRecvBuffer = (void* )NULL; ANSC_HANDLE hRecvHandle = (ANSC_HANDLE )NULL; ULONG ulRecvSize = (ULONG )0; ULONG ulLeftSize = (ULONG )AnscBdoGetBlockSize(pPayloadBdo); ULONG ulCopySize = (ULONG )0; ULONG ulServingT1 = 0; ULONG ulServingT2 = 0; ULONG ulWaitCount = 0; /* * Since the TLS handshake is done in the asynchronous task instead of the socket_recv task, * it's possible that we start receiving TLS client data traffic (i.e. HTTP) before handshake * task considers the handshaking is done. To accommodate such race condition, we need to sleep * for a while if there's no buffer available. */ while ( !pMyObject->GetRecvBuffer ( (ANSC_HANDLE)pMyObject, &ulRecvSize ) ) { AnscSleep(10); ulWaitCount++; if ( ulWaitCount > 30 ) /* sleep for 300ms */ { returnStatus = ANSC_STATUS_INTERNAL_ERROR; goto EXIT1; } } while ( ulLeftSize > 0 ) { pRecvBuffer = pMyObject->GetRecvBuffer ( (ANSC_HANDLE)pMyObject, &ulRecvSize ); if ( !pRecvBuffer ) { returnStatus = pWorker->Notify ( pWorker->hWorkerContext, (ANSC_HANDLE)pMyObject, ANSC_DSTOWO_EVENT_RESOURCES, (ANSC_HANDLE)NULL ); break; } else if ( ulRecvSize == 0 ) { pMyObject->ToClean((ANSC_HANDLE)pMyObject, TRUE, 2); break; } if ( ulRecvSize >= ulLeftSize ) { ulCopySize = ulLeftSize; } else { ulCopySize = ulRecvSize; } if ( TRUE ) { AnscCopyMemory ( pRecvBuffer, AnscBdoGetBlock(pPayloadBdo), ulCopySize ); AnscBdoShrinkRight(pPayloadBdo, ulCopySize); ulLeftSize -= ulCopySize; } pMyObject->RecvBytesCount += ulCopySize; pMyObject->LastRecvAt = AnscGetTickInSecondsAbs(); /* * We have successfully transferred the received data into the buffer supplied by the * socket owener though may not use up the while buffer. Now is time to notify our loyal * socket owner about this exciting event. */ ulServingT1 = AnscGetTickInMilliSeconds(); returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, pRecvBuffer, ulCopySize ); ulServingT2 = AnscGetTickInMilliSeconds(); pEngine->AvgServingTime = (pEngine->AvgServingTime == 0)? (ulServingT2 - ulServingT1) : ((ulServingT2 - ulServingT1) + pEngine->AvgServingTime * 7) / 8; pEngine->TscCount++; } goto EXIT1; /****************************************************************** GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS ******************************************************************/ EXIT1: if ( pPayloadBdo ) { AnscFreeBdo((ANSC_HANDLE)pPayloadBdo); } 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 HttpBmoCopyHeadersFrom ( ANSC_HANDLE hThisObject, PVOID buffer, PULONG pulSize ) { 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; PSINGLE_LINK_ENTRY pSLinkEntry = NULL; ULONG ulHeadersSize = 0; ULONG ulCopySize = 0; ULONG ulLeftSize = *pulSize; char* pHfStream = (char*)buffer; ULONG i = 0; if ( *pulSize < pMyObject->GetHeadersSize((ANSC_HANDLE)pMyObject) ) { return ANSC_STATUS_BAD_SIZE; } else if ( pHeaderBdo ) { AnscCopyMemory ( buffer, AnscBdoGetBlock (pHeaderBdo), AnscBdoGetBlockSize(pHeaderBdo) ); *pulSize = AnscBdoGetBlockSize(pHeaderBdo); return ANSC_STATUS_SUCCESS; } ulCopySize = ulLeftSize; pHfStream = (char*)((ULONG)buffer + ulHeadersSize); returnStatus = pMyObject->CopyStartLineFrom ( (ANSC_HANDLE)pMyObject, (PVOID)pHfStream, &ulCopySize ); if ( returnStatus != ANSC_STATUS_SUCCESS ) { return returnStatus; } else { pHfStream += ulCopySize; ulHeadersSize += ulCopySize; ulLeftSize -= ulCopySize; pHfStream[0] = HTTP_CARRIAGE_RETURN; pHfStream[1] = HTTP_LINE_FEED; pHfStream += 2; ulHeadersSize += 2; ulLeftSize -= 2; } AnscAcquireLock(&pMyObject->HfoTableLock); for ( i = 0; i < HTTP_BMO_HFO_TABLE_SIZE; i++ ) { pSLinkEntry = AnscQueueGetFirstEntry(&pMyObject->HfoTable[i]); while ( pSLinkEntry ) { pHttpHfo = ACCESS_HTTP_HEADER_FIELD(pSLinkEntry); pSLinkEntry = AnscQueueGetNextEntry(pSLinkEntry); ulCopySize = pHfpIf->GetHeaderSize(pHfpIf->hOwnerContext, (ANSC_HANDLE)pHttpHfo); if ( ulCopySize > 0 ) { returnStatus = pHfpIf->BuildHeader ( pHfpIf->hOwnerContext, (ANSC_HANDLE)pHttpHfo, (PVOID)pHfStream, ulCopySize ); if ( returnStatus != ANSC_STATUS_SUCCESS ) { return returnStatus; } else { pHfStream += ulCopySize; ulHeadersSize += ulCopySize; ulLeftSize -= ulCopySize; pHfStream[0] = HTTP_CARRIAGE_RETURN; pHfStream[1] = HTTP_LINE_FEED; pHfStream += 2; ulHeadersSize += 2; ulLeftSize -= 2; } } } } AnscReleaseLock(&pMyObject->HfoTableLock); pHfStream[0] = HTTP_CARRIAGE_RETURN; pHfStream[1] = HTTP_LINE_FEED; pHfStream += 2; ulHeadersSize += 2; ulLeftSize -= 2; *pulSize = ulHeadersSize; return ANSC_STATUS_SUCCESS; }
ULONG AnscLpccoTcpBwoQuery ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, PVOID buffer, ULONG ulSize, PANSC_HANDLE phQueryContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_LPCCO_TCP_OBJECT pMyObject = (PANSC_LPCCO_TCP_OBJECT )hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pDaemonServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_BROKER_SERVER_TCP_OBJECT pBrokerServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; PANSC_BROKER_SOCKET_TCP_OBJECT pBrokerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pBrokerSocket->GetBufferContext((ANSC_HANDLE)pBrokerSocket); PANSC_BUFFER_DESCRIPTOR pNewBdo = (PANSC_BUFFER_DESCRIPTOR )NULL; PIMCP_HEADER pImcpHeader = (PIMCP_HEADER )NULL; ULONG ulMsgSize = (ULONG )0; ULONG ulCopySize = (ULONG )0; ULONG ulLeftSize = (ULONG )0; ULONG i = 0; if ( !pBufferDesp ) { return ANSC_BSTOWO_PMODE_FINISH; } else { pBufferDesp->BlockSize += ulSize; } if ( AnscBdoGetUsableSize(pBufferDesp) <= sizeof(IMCP_HEADER) ) { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ANSC_LPC_DEF_MESSAGE_SIZE, 0, AnscBdoGetBlockSize(pBufferDesp) ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { ulCopySize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = AnscBdoCopyFrom ( (ANSC_HANDLE)pBufferDesp, AnscBdoGetBlock(pNewBdo), &ulCopySize, 0 ); pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pNewBdo), AnscBdoGetLeftSize (pNewBdo), (ANSC_HANDLE)pNewBdo ); } AnscFreeBdo((ANSC_HANDLE)pBufferDesp); return ANSC_BSTOWO_PMODE_COLLECT; } else if ( AnscBdoGetBlockSize(pBufferDesp) < sizeof(IMCP_HEADER) ) { /* * We need to rollback the block size of the buffer descriptor before we return 'Collect'. * Next time when this Query() function is called, the 'ulSize' parameter will be set to * the total size of un-processed data, not the size of the newly received data. */ pBufferDesp->BlockSize -= ulSize; return ANSC_BSTOWO_PMODE_COLLECT; } else { pImcpHeader = (PIMCP_HEADER)AnscBdoGetBlock(pBufferDesp); ulMsgSize = (ULONG )ImcpGetMsgSize (pImcpHeader); } if ( ulMsgSize == AnscBdoGetBlockSize(pBufferDesp) ) { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ANSC_LPC_DEF_MESSAGE_SIZE, 0, 0 ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pNewBdo), AnscBdoGetLeftSize (pNewBdo), (ANSC_HANDLE)pNewBdo ); } returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pBrokerSocket, (ANSC_HANDLE)pBufferDesp ); return ANSC_BSTOWO_PMODE_DISCARD; } else if ( ulMsgSize < AnscBdoGetBlockSize(pBufferDesp) ) { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ulMsgSize, 0, ulMsgSize ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { ulCopySize = ulMsgSize; returnStatus = AnscBdoCopyFrom ( (ANSC_HANDLE)pBufferDesp, AnscBdoGetBlock(pNewBdo), &ulCopySize, 0 ); } returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pBrokerSocket, (ANSC_HANDLE)pNewBdo ); /* * As Lina discovered, we cannot simply reset the 'BlockSize' to zero and make another * Query() call. If we do and the returned mode is COLLECT, the socket object would be * confused because the data processed in this call is still remembered and its size will * be covered in the next Query() call. We need to follow the steps as listed below to * ensure the packet data in the previous call is cleaned: * * - Set the 'BlockSize' to whatever data left after processing. * - Advance 'Offset' field by the message size. * - Reset the buffer context of the socket object. * - Calling Query() again with 'ulSize' set to zero. */ ulLeftSize = AnscBdoGetBlockSize(pBufferDesp) - ulMsgSize; pBufferDesp->Offset += ulMsgSize; pBufferDesp->BlockSize -= ulMsgSize; pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pBufferDesp), AnscBdoGetLeftSize (pBufferDesp), (ANSC_HANDLE)pBufferDesp ); return pMyObject->BwoQuery ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pBufferDesp), /*AnscBdoGetBlock(pBufferDesp),*/ 0, /*ulLeftSize, */ phQueryContext ); } else if ( ulMsgSize <= AnscBdoGetUsableSize(pBufferDesp) ) { /* * We need to rollback the block size of the buffer descriptor before we return 'Collect'. * Next time when this Query() function is called, the 'ulSize' parameter will be set to * the total size of un-processed data, not the size of the newly received data. */ pBufferDesp->BlockSize -= ulSize; return ANSC_BSTOWO_PMODE_COLLECT; } else { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ulMsgSize, 0, AnscBdoGetBlockSize(pBufferDesp) ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { ulCopySize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = AnscBdoCopyFrom ( (ANSC_HANDLE)pBufferDesp, AnscBdoGetBlock(pNewBdo), &ulCopySize, 0 ); pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pNewBdo), AnscBdoGetLeftSize (pNewBdo), (ANSC_HANDLE)pNewBdo ); } AnscFreeBdo((ANSC_HANDLE)pBufferDesp); return ANSC_BSTOWO_PMODE_COLLECT; } return ANSC_BSTOWO_PMODE_DISCARD; }
ANSC_STATUS HttpApoPubwoNotify ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, ULONG ulEvent, ANSC_HANDLE hReserved ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_ADVANCED_PROXY_OBJECT pMyObject = (PHTTP_ADVANCED_PROXY_OBJECT )hThisObject; PHTTP_ADVANCED_PROXY_PROPERTY pProperty = (PHTTP_ADVANCED_PROXY_PROPERTY )&pMyObject->Property; PANSC_SIMPLE_PROXY_TCP_OBJECT pSimpleProxy = (PANSC_SIMPLE_PROXY_TCP_OBJECT )pMyObject->hSimpleProxy; PANSC_BROKER_SOCKET_TCP_OBJECT pServerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pServerSocket->GetBufferContext((ANSC_HANDLE)pServerSocket); PHTTP_PSO_VER2_OBJECT pPsoVer2 = NULL; PHTTP_TRANS_RECORD_OBJECT pTransRecord = NULL; AnscTrace ( "Event = %d is indicated on server connection of %d.%d.%d.%d / TCP %d\n", ulEvent, pServerSocket->PeerAddress.Dot[0], pServerSocket->PeerAddress.Dot[1], pServerSocket->PeerAddress.Dot[2], pServerSocket->PeerAddress.Dot[3], pServerSocket->PeerPort ); switch ( ulEvent ) { case ANSC_SPTOWO_EVENT_SOCKET_ERROR : pServerSocket->ToClean((ANSC_HANDLE)pServerSocket, TRUE, HTTP_APO_SOCKET_TTC); break; case ANSC_SPTOWO_EVENT_SOCKET_CLOSED : AnscAcquireLock(&pMyObject->SyncLock); pPsoVer2 = (PHTTP_PSO_VER2_OBJECT)pServerSocket->GetClientContext((ANSC_HANDLE)pServerSocket); if ( pPsoVer2 ) { pPsoVer2->AcquireAccess((ANSC_HANDLE)pPsoVer2); pTransRecord = (PHTTP_TRANS_RECORD_OBJECT)pPsoVer2->AskTroBySocket ( (ANSC_HANDLE)pPsoVer2, (ANSC_HANDLE)pServerSocket ); pPsoVer2->ReleaseAccess((ANSC_HANDLE)pPsoVer2); } else { AnscReleaseLock(&pMyObject->SyncLock); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); return ANSC_STATUS_SUCCESS; } if ( !pTransRecord ) { AnscReleaseLock(&pMyObject->SyncLock); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); return ANSC_STATUS_SUCCESS; } AnscReleaseLock(&pMyObject->SyncLock); pBufferDesp->BlockSize += pServerSocket->RecvPacketSize; returnStatus = pServerSocket->SetBufferContext ( (ANSC_HANDLE)pServerSocket, NULL, 0, (ANSC_HANDLE)NULL ); returnStatus = pTransRecord->FinishedByServer ( (ANSC_HANDLE)pTransRecord, AnscBdoGetBlock (pBufferDesp), AnscBdoGetBlockSize(pBufferDesp), (ANSC_HANDLE)pBufferDesp ); pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); break; case ANSC_SPTOWO_EVENT_RESOURCES : break; case ANSC_SPTOWO_EVENT_TIME_OUT : break; default : break; } 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 AnscSctoTsaRecvAppMessage ( ANSC_HANDLE hThisObject, ANSC_HANDLE hMessageBdo ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_SIMPLE_CLIENT_TCP_OBJECT pMyObject = (PANSC_SIMPLE_CLIENT_TCP_OBJECT)hThisObject; PANSC_SCTO_WORKER_OBJECT pWorker = (PANSC_SCTO_WORKER_OBJECT )pMyObject->hWorker; PANSC_BUFFER_DESCRIPTOR pPayloadBdo = (PANSC_BUFFER_DESCRIPTOR )hMessageBdo; void* pRecvBuffer = (void* )NULL; ANSC_HANDLE hRecvHandle = (ANSC_HANDLE )NULL; ULONG ulRecvSize = (ULONG )0; ULONG ulLeftSize = (ULONG )AnscBdoGetBlockSize(pPayloadBdo); ULONG ulCopySize = (ULONG )0; while ( ulLeftSize > 0 ) { pRecvBuffer = pMyObject->GetRecvBuffer ( (ANSC_HANDLE)pMyObject, &ulRecvSize ); if ( !pRecvBuffer ) { returnStatus = pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_RESOURCES, (ANSC_HANDLE)NULL ); break; } if ( ulRecvSize >= ulLeftSize ) { ulCopySize = ulLeftSize; } else { ulCopySize = ulRecvSize; } if ( TRUE ) { AnscCopyMemory ( pRecvBuffer, AnscBdoGetBlock(pPayloadBdo), ulCopySize ); AnscBdoShrinkRight(pPayloadBdo, ulCopySize); ulLeftSize -= ulCopySize; } pMyObject->RecvBytesCount += ulCopySize; pMyObject->LastRecvAt = AnscGetTickInSeconds(); returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, pRecvBuffer, ulCopySize ); } goto EXIT1; /****************************************************************** GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS ******************************************************************/ EXIT1: if ( pPayloadBdo ) { AnscFreeBdo((ANSC_HANDLE)pPayloadBdo); } return returnStatus; }