📄 hxcloakedtcp.cpp
字号:
m_pTCPResponse->WriteReady(HXR_OK);
return HXR_OK;
}
STDMETHODIMP HXClientCloakedTCPSocket::GetLocalAddress(ULONG32& lAddress)
{
return HXR_NOTIMPL;
}
STDMETHODIMP HXClientCloakedTCPSocket::GetForeignAddress(ULONG32& lAddress)
{
if(m_bConnected && m_lForeignAddress)
{
lAddress = m_lForeignAddress;
return HXR_OK;
}
return HXR_FAIL;
}
STDMETHODIMP HXClientCloakedTCPSocket::GetLocalPort(UINT16& port)
{
return HXR_NOTIMPL;
}
STDMETHODIMP HXClientCloakedTCPSocket::GetForeignPort(UINT16& port)
{
if(m_bConnected)
{
port = m_nForeignPort;
return HXR_OK;
}
return HXR_FAIL;
}
/*
* IHXHTTPProxy methods
*
* Network addresses and ports are in native byte order
*
*/
STDMETHODIMP HXClientCloakedTCPSocket::SetProxy(
const char* /*IN*/ pProxyHostName,
UINT16 /*IN*/ nPort)
{
if(pProxyHostName == 0 || *pProxyHostName == 0)
{
return HXR_FAILED;
}
HX_VECTOR_DELETE(m_pProxyHostName);
m_pProxyHostName = new char[::strlen(pProxyHostName) + 1];
if (!m_pProxyHostName)
{
return HXR_OUTOFMEMORY;
}
::strcpy(m_pProxyHostName, pProxyHostName); /* Flawfinder: ignore */
m_nProxyPortNumber = nPort;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXCloakedTCPSocket::InitCloak
*/
STDMETHODIMP
HXClientCloakedTCPSocket::InitCloak(IHXValues* /*IN*/ pValues, IUnknown* pUnknown)
{
HX_RESULT rc = HXR_OK;
if (pValues)
{
m_pCloakValues = pValues;
m_pCloakValues->AddRef();
}
if (pUnknown)
{
m_pCloakContext = pUnknown;
m_pCloakContext->AddRef();
}
return rc;
}
HX_RESULT
HXClientCloakedTCPSocket::DoRead()
{
HX_RESULT theErr = HXR_OK;
char* pStartAfterDoubleReturn = 0;
UINT16 count = 0;
if(m_bInDoRead)
{
return HXR_OK;
}
m_bInDoRead = TRUE;
if (m_LastError)
{
goto exit;
}
// m_pReceivePutTCP is only initialized if we receive POST response
// from the server
if (m_pReceivePutTCP)
{
count = m_pReceivePutTCP->GetMaxAvailableElements();
}
else
{
count = TCP_BUF_SIZE;
}
// attempt to read from PUT if:
// * we haven't initiated PUT read already AND
// * we haven't received the complete POST response header AND
// * we are not in multi-POST mode
if (count > 0 &&
!m_bPutReadPending &&
!m_bHTTPPutHeaderReadDone &&
!m_bMustCloseHTTP)
{
// attempt to read data from TCP link
m_bPutReadPending = TRUE;
theErr = m_pPutCtrl->Read(count);
}
// check how much room we have in TCP receive queue
count = m_pReceiveGetTCP->GetMaxAvailableElements();
if (count > 0 && !m_bGetReadPending)
{
// attempt to read data from TCP link
m_bGetReadPending = TRUE;
theErr = m_pGetCtrl->Read(count);
switch(theErr)
{
case HXR_AT_INTERRUPT:
case HXR_WOULD_BLOCK:
case HXR_OK:
// mask out these errors
theErr = HXR_OK;
break;
default:
theErr = ConvertNetworkError(theErr);
break;
}
}
exit:
if (theErr && !m_LastError)
{
m_LastError = theErr;
}
if (m_LastError)
{
if (m_bReadPending)
{
if (IsSafe())
{
m_bReadPending = FALSE;
m_pTCPResponse->ReadDone(m_LastError, 0);
}
}
}
else
{
count = m_pReceiveGetTCP->GetQueuedItemCount();
if (m_bReadPending && count > 0 && m_bOptionsReceived
&& m_bHTTPGetHeaderReadDone)
{
/* mask any kind of errors */
theErr = HXR_OK;
if (IsSafe())
{
m_bReadPending = FALSE;
if (m_nRequired < count)
{
count = m_nRequired;
}
CHXBuffer* pBuffer = new CHXBuffer;
pBuffer->AddRef();
m_pReceiveGetTCP->DeQueue(m_pInBuf, count);
pBuffer->Set((UCHAR*) m_pInBuf, count);
m_pTCPResponse->ReadDone(HXR_OK, pBuffer);
pBuffer->Release();
}
}
if (m_pSchedulerCallback && m_bReadPending)
{
m_pSchedulerCallback->ScheduleCallback(CLOAKED_TCP_READ_COMMAND, m_pScheduler, SCHED_GRANULARITY);
}
}
m_bInDoRead = FALSE;
return theErr;
}
HX_RESULT
HXClientCloakedTCPSocket::DoGetWrite()
{
HX_RESULT theErr = HXR_OK;
if (m_bInDoGetWrite)
{
return HXR_OK;
}
m_bInDoGetWrite = TRUE;
// check how data we have in TCP send queue
UINT16 count = m_pSendTCP->GetQueuedItemCount();
UINT16 actual = count;
if(count > 0)
{
m_pSendTCP->DeQueue(m_pOutBuf,count);
CHXBuffer* pBuffer = new CHXBuffer;
pBuffer->AddRef();
pBuffer->Set((UCHAR*) m_pOutBuf, (ULONG32) count);
theErr = m_pGetCtrl->Write(pBuffer);
pBuffer->Release();
}
if (theErr)
{
switch(theErr)
{
case HXR_AT_INTERRUPT:
case HXR_WOULD_BLOCK:
m_pSendTCP->EnQueue(m_pOutBuf, count);
// mask out these errors
theErr = HXR_OK;
break;
default:
theErr = ConvertNetworkError(theErr);
break;
}
}
if (!theErr && !m_bInDestructor &&
m_pSendTCP->GetQueuedItemCount() > 0 ) {
m_pSchedulerCallback->ScheduleCallback(CLOAKED_TCP_GETWRITE_COMMAND, m_pScheduler, SCHED_GRANULARITY);
}
m_bInDoGetWrite = FALSE;
return theErr;
}
HX_RESULT
HXClientCloakedTCPSocket::DoPutWrite()
{
HX_RESULT theErr = HXR_OK;
if (m_bInDoPutWrite)
{
return HXR_OK;
}
m_bInDoPutWrite = TRUE;
/* Transfer pending buffers to TCP send queue */
if (m_bOptionsReceived && m_pPostEncodedSendHTTP->GetQueuedItemCount() == 0 && !m_bPutWantWritePending)
{
TransferBuffers();
}
if (!m_bPutConnectDone)
{
goto exit;
}
// check how data we have in TCP send queue
UINT16 count;
UINT16 actual;
count = m_pPostEncodedSendHTTP->GetQueuedItemCount();
actual = count;
if(count > 0)
{
m_pPostEncodedSendHTTP->DeQueue(m_pOutEncodedBuf,count);
CHXBuffer* pBuffer = new CHXBuffer;
pBuffer->AddRef();
pBuffer->Set((UCHAR*) m_pOutEncodedBuf, (ULONG32) count);
theErr = m_pPutCtrl->Write(pBuffer);
pBuffer->Release();
m_bPutWantWritePending = TRUE;
m_pPutCtrl->WantWrite();
}
if (theErr)
{
switch(theErr)
{
case HXR_AT_INTERRUPT:
case HXR_WOULD_BLOCK:
m_pPostEncodedSendHTTP->EnQueue(m_pOutEncodedBuf, count);
// mask out these errors
theErr = HXR_OK;
break;
default:
theErr = ConvertNetworkError(theErr);
break;
}
}
exit:
if (!theErr && !m_bInDestructor &&
(m_pPostEncodedSendHTTP->GetQueuedItemCount() > 0 ||
m_PendingWriteBuffers.GetCount() > 0)){
m_pSchedulerCallback->ScheduleCallback(CLOAKED_TCP_PUTWRITE_COMMAND, m_pScheduler, SCHED_GRANULARITY);
}
if (!theErr)
{
theErr = DoGetWrite();
}
m_bInDoPutWrite = FALSE;
return theErr;
}
void
HXClientCloakedTCPSocket::GetConnectDone(BOOL bResult)
{
m_bGetConnectDone = TRUE;
if (!m_bInDestructor)
{
AddRef();
}
if (bResult == TRUE)
{
m_bGetConnectSuccessful = TRUE;
m_pGetCtrl->GetForeignAddress(m_lForeignAddress);
}
else
{
m_bGetConnectSuccessful = FALSE;
}
// PUT connection has to been done at this point
if (m_bPutConnectDone && m_bConnectResponsePending)
{
m_bConnectResponsePending = FALSE;
// either its HTTP-NG server or we are in re-GET mode
// where we send GET to the same serverIP returned from
// POST response
if (m_bConnectToSameServerIP || m_bReconnectToSameServerIP)
{
if (m_bPutConnectSuccessful && m_bGetConnectSuccessful)
{
m_bConnected = TRUE;
m_pMutex->Lock();
PrepareGetMessage();
DoGetWrite();
Read(TCP_BUF_SIZE);
m_pMutex->Unlock();
if (m_bConnectToSameServerIP)
{
// we haven't call ConnectDone yet
m_pTCPResponse->ConnectDone(HXR_OK);
}
else if (m_bReconnectToSameServerIP)
{
// we already called ConnectDone upon the initial
// GET/POST connect done
Read(TCP_BUF_SIZE);
}
}
else
{
m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
}
}
// don't know the server type yet, keep the old behavior
// where we send both GET and POST
else
{
if (m_bPutConnectSuccessful && m_bGetConnectSuccessful)
{
m_bConnected = TRUE;
m_pMutex->Lock();
PreparePostMessage(NULL, 0);
DoPutWrite();
PrepareGetMessage();
DoGetWrite();
m_pMutex->Unlock();
m_pTCPResponse->ConnectDone(HXR_OK);
}
else
{
m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
}
}
}
if (!m_bInDestructor)
{
Release();
}
}
void
HXClientCloakedTCPSocket::PutConnectDone(BOOL bResult)
{
HX_RESULT theErr = HXR_OK;
m_bPutConnectDone = TRUE;
if (!m_bInDestructor)
{
AddRef();
}
if (bResult == TRUE)
{
m_bPutConnectSuccessful = TRUE;
}
else
{
m_bPutConnectSuccessful = FALSE;
}
// it's HTTP-NG server, we send POST first
if (m_bConnectToSameServerIP)
{
if (m_bPutConnectSuccessful)
{
m_pMutex->Lock();
PreparePostMessage(NULL, 0);
DoPutWrite();
if (!m_bPutReadPending)
{
m_bPutReadPending = TRUE;
m_pPutCtrl->Read(TCP_BUF_SIZE);
}
m_pMutex->Unlock();
}
else
{
m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
}
}
// don't know the server type yet, so we send both POST
// and GET
else if (m_bGetConnectDone && m_bConnectResponsePending)
{
m_bConnectResponsePending = FALSE;
if (m_bPutConnectSuccessful && m_bGetConnectSuccessful)
{
m_bConnected = TRUE;
m_pMutex->Lock();
PreparePostMessage(NULL, 0);
DoPutWrite();
PrepareGetMessage();
theErr = DoGetWrite();
m_pMutex->Unlock();
m_pTCPResponse->ConnectDone(HXR_OK);
}
else
{
m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
}
}
if (!m_bInDestructor)
{
Release();
}
if (m_bConnected && m_pPostEncodedSendHTTP->GetQueuedItemCount() > 0)
{
m_pMutex->Lock();
DoPutWrite();
m_pMutex->Unlock();
}
}
HX_RESULT
HXClientCloakedTCPSocket::DoGetReadDone(HX_RESULT status, IHXBuffer* pInBuffer)
{
HX_RESULT theErr = HXR_OK;
char* pStartAfterDoubleReturn = 0;
UINT16 count = 0;
if (AuthenticationRequired(status, pInBuffer))
{
return HXR_OK;
}
m_pMutex->Lock();
m_bGetReadPending = FALSE;
if (status != HXR_OK && m_LastError == HXR_OK)
{
m_LastError = status;
}
if (m_LastError)
{
goto exit;
}
if (pInBuffer)
{
m_pReceiveGetTCP->EnQueue(pInBuffer->GetBuffer(), (UINT16) pInBuffer->GetSize());
}
count = m_pReceiveGetTCP->GetQueuedItemCount();
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -