📄 hxcloakedtcp.cpp
字号:
}
cleanup:
return rc;
}
HX_RESULT
HXClientCloakedTCPSocket::CleanUpAndReInitializeStuff(void)
{
HX_RESULT rc = HXR_OK;
IHXBuffer* pBuffer = NULL;
m_pMutex->Lock();
const char* pActualHost = m_pForiegnHost;
UINT16 nActualPort = m_nForeignPort;
if (m_pProxyHostName)
{
pActualHost = m_pProxyHostName;
nActualPort = m_nProxyPortNumber;
}
if (m_pReceiveGetTCP)
{
m_pReceiveGetTCP->FlushQueue();
}
/* Send a final HTTP done message */
if (m_bHttpInitialized)
{
SendHTTPDone();
}
if (m_pSchedulerCallback)
{
m_pSchedulerCallback->Unschedule(m_pScheduler);
}
if (m_pNonInterruptCallback)
{
m_pNonInterruptCallback->Unschedule(m_pScheduler);
}
HX_RELEASE(m_pGetCtrl);
HX_RELEASE(m_pPutCtrl);
m_bHTTPGetHeaderReadDone = FALSE;
m_bOptionsReceived = FALSE;
m_bReadPending = FALSE;
m_bGetReadPending = FALSE;
m_bGetConnectDone = FALSE;
m_bGetConnectSuccessful = FALSE;
m_bConnectResponsePending = TRUE;
m_bConnected = FALSE;
m_bPutConnectDone = FALSE;
m_bPutReadPending = FALSE;
m_bInAuthenticationKludge = TRUE;
// OK, clean up is done so now we re-initialize.
// use serverIP from PUT response for GET reconnect
if (HXR_OK != m_pNetworkServices->CreateTCPSocket(&m_pGetCtrl))
{
rc = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != m_pGetCtrl->Init(m_pGetCtrlResponse))
{
rc = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != m_pGetCtrl->Bind(HXR_INADDR_ANY, 0))
{
rc = HXR_FAILED;
goto cleanup;
}
rc = m_pGetCtrl->Connect(pActualHost, nActualPort);
if (HXR_OK != rc)
{
goto cleanup;
}
if (HXR_OK != m_pNetworkServices->CreateTCPSocket(&m_pPutCtrl))
{
rc = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != m_pPutCtrl->Init(m_pPutCtrlResponse))
{
rc = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != m_pPutCtrl->Bind(HXR_INADDR_ANY, 0))
{
rc = HXR_FAILED;
goto cleanup;
}
rc = m_pPutCtrl->Connect(pActualHost, nActualPort);
if (HXR_OK != rc) goto cleanup;
cleanup:
m_pMutex->Unlock();
return rc;
}
HX_RESULT
HXClientCloakedTCPSocket::ReconnectToSameServerIP(void)
{
HX_RESULT rc = HXR_OK;
IHXBuffer* pBuffer = NULL;
m_pMutex->Lock();
if (m_pReceiveGetTCP)
{
m_pReceiveGetTCP->FlushQueue();
}
/* Send a final HTTP done message */
if (m_bHttpInitialized)
{
SendHTTPDone();
}
if (m_pSchedulerCallback)
{
m_pSchedulerCallback->Unschedule(m_pScheduler);
}
if (m_pNonInterruptCallback)
{
m_pNonInterruptCallback->Unschedule(m_pScheduler);
}
HX_RELEASE(m_pGetCtrl);
HX_RELEASE(m_pGetCtrlResponse);
m_bHTTPGetHeaderReadDone = FALSE;
m_bOptionsReceived = FALSE;
m_bReadPending = FALSE;
m_bGetReadPending = FALSE;
m_bGetConnectDone = FALSE;
m_bGetConnectSuccessful = FALSE;
m_bConnectResponsePending = TRUE;
m_bConnected = FALSE;
HX_VECTOR_DELETE(m_pForiegnHost);
// use serverIP from PUT response for GET reconnect
m_pForiegnHost = new char [strlen(m_pszPutServerIP) + 1];
if (!m_pForiegnHost)
{
rc = HXR_OUTOFMEMORY;
goto cleanup;
}
::strcpy(m_pForiegnHost, m_pszPutServerIP); /* Flawfinder: ignore */
if (HXR_OK != m_pNetworkServices->CreateTCPSocket(&m_pGetCtrl))
{
rc = HXR_FAILED;
goto cleanup;
}
m_pGetCtrlResponse = new HTTPCloakTCPResponse(this, TRUE);
if (!m_pGetCtrlResponse)
{
rc = HXR_FAILED;
goto cleanup;
}
m_pGetCtrlResponse->AddRef();
if (HXR_OK != m_pGetCtrl->Init(m_pGetCtrlResponse))
{
rc = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != m_pGetCtrl->Bind(HXR_INADDR_ANY, 0))
{
rc = HXR_FAILED;
goto cleanup;
}
rc = ActualConnect();
cleanup:
m_pMutex->Unlock();
return rc;
}
BOOL
HXClientCloakedTCPSocket::AuthenticationRequired(HX_RESULT status, IHXBuffer* pInBuffer)
{
if (!pInBuffer)
{
return FALSE;
}
// start of authenticated proxy logic.
HTTPParser Parser;
char* pBufferContents = (char*)(const char*)pInBuffer->GetBuffer();
ULONG32 nMsgLen = pInBuffer->GetSize();
HTTPResponseMessage* pMessage = (HTTPResponseMessage*)Parser.parse( pBufferContents, nMsgLen );
// ignore non-HTTP responses which will be processed by the response object:
// RTSPClientProtocol
if (HTTPMessage::T_UNKNOWN == pMessage->tag())
{
return FALSE;
}
ULONG32 ulHTTPStatus = 0;
if (strlen(pMessage->errorCode()) > 0)
{
ulHTTPStatus = atoi(pMessage->errorCode());
}
if (ulHTTPStatus == 401 || ulHTTPStatus == 407)
{
#ifdef _MACINTOSH
if (!IsMacInCooperativeThread())
{
// xxxbobclark Since there's UI involved with authentication,
// we'll ensure that we're not at interrupt time.
if (m_pAuthenticationCallback && !m_pAuthenticationCallback->m_ulPendingCallbackID)
{
m_pAuthenticationCallback->m_ulPendingCallbackID =
m_pScheduler->RelativeEnter(m_pAuthenticationCallback, 0);
m_pAuthenticationCallback->m_Status = status;
pInBuffer->AddRef();
m_pAuthenticationCallback->m_pInBuffer = pInBuffer;
}
HX_DELETE(pMessage);
return TRUE;
}
#endif
IHXRequest* pRequest = NULL;
IHXCommonClassFactory* pCCF;
HX_RESULT retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&pCCF);
if (SUCCEEDED(retVal))
{
retVal = pCCF->CreateInstance(CLSID_IHXRequest, (void**)&pRequest);
if(retVal == HXR_OK)
{
PrepareGetMessage(); // set up m_pSendTCP
UINT16 count = m_pSendTCP->GetQueuedItemCount();
m_pSendTCP->DeQueue(m_pOutBuf,count);
retVal = pRequest->SetURL(m_pOutBuf);
IHXKeyValueList* pResponseHeaders = NULL;
pCCF->CreateInstance(CLSID_IHXKeyValueList, (void**)&pResponseHeaders);
MIMEHeaderValue* pHeaderValue = NULL;
MIMEHeader* pHeader = pMessage->getFirstHeader();
while (pHeader)
{
pHeaderValue = pHeader->getFirstHeaderValue();
CHXString strHeader;
while (pHeaderValue)
{
CHXString strTemp;
pHeaderValue->asString(strTemp);
strHeader += strTemp;
pHeaderValue = pHeader->getNextHeaderValue();
if (pHeaderValue)
{
strHeader += ", ";
}
}
IHXBuffer* pBuffer = NULL;
CHXBuffer::FromCharArray((const char*)strHeader, &pBuffer);
pResponseHeaders->AddKeyValue(pHeader->name(), pBuffer);
HX_RELEASE(pBuffer);
pHeader = pMessage->getNextHeader();
}
IHXValues* pResponseValues = NULL;
if (HXR_OK == pResponseHeaders->QueryInterface(IID_IHXValues, (void**)&pResponseValues))
{
pRequest->SetResponseHeaders(pResponseValues);
}
HandleAuthentication(pRequest, pMessage, m_pForiegnHost, m_pProxyHostName);
HX_RELEASE(pResponseValues);
HX_RELEASE(pResponseHeaders);
}
HX_RELEASE(pCCF);
}
HX_DELETE(pMessage);
return TRUE;
}
HX_DELETE(pMessage);
return FALSE;
}
#define CLOAKED_WWW_AUTHENTICATION_RECENT_KEY "authentication.http.realm.recent"
#define CLOAKED_PROXY_AUTHENTICATION_RECENT_KEY "proxy-authentication.http.realm.recent"
void
HXClientCloakedTCPSocket::ObtainAuthenticationInformation(CHXString& strAuth)
{
IHXBuffer* pBuffer = NULL;
CHXString key("no-authentication-information");
CHXString recentAuthRealmInfo;
CHXString recentProxyAuthRealmInfo;
IHXBuffer* pHeaderBuffer = NULL;
HX_RESULT theErr = HXR_OK;
IHXRegistry* pRegistry = NULL;
m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry);
HX_ASSERT(pRegistry);
if (!pRegistry) return;
theErr = pRegistry->GetStrByName(CLOAKED_WWW_AUTHENTICATION_RECENT_KEY, pHeaderBuffer);
if (SUCCEEDED(theErr))
{
HX_ASSERT(pHeaderBuffer);
recentAuthRealmInfo = CHXString((const char*)pHeaderBuffer->GetBuffer(), pHeaderBuffer->GetSize());
HX_RELEASE(pHeaderBuffer);
}
theErr = pRegistry->GetStrByName(CLOAKED_PROXY_AUTHENTICATION_RECENT_KEY, pHeaderBuffer);
if (SUCCEEDED(theErr))
{
HX_ASSERT(pHeaderBuffer);
recentProxyAuthRealmInfo = CHXString((const char*)pHeaderBuffer->GetBuffer(), pHeaderBuffer->GetSize());
HX_RELEASE(pHeaderBuffer);
}
key = "proxy-authentication.http:";
key += m_pProxyHostName;
key += ":";
key += recentProxyAuthRealmInfo;
if (HXR_OK == pRegistry->GetStrByName((const char*)key, pBuffer) )
{
if (pBuffer)
{
CHXString authString((const char*)pBuffer->GetBuffer(), pBuffer->GetSize());
strAuth = "Proxy-Authorization: ";
strAuth += (const char*)authString;
}
}
HX_RELEASE(pBuffer);
HX_RELEASE(pRegistry);
}
HX_RESULT
HXClientCloakedTCPSocket::HandleAuthentication(IHXRequest* pRequest, HTTPResponseMessage* pMessage,
const char* pHost, const char* pProxyHost)
{
HX_RESULT ResultStatus = HXR_OK;
UINT32 ulAltURL = 0;
CHXString sConnection;
IHXValues* pNewHeaders = NULL;
// xxxbobclark The reason we need to extract the IHXPlayer is that
// later on the authenticator smart pointer needs a context which knows
// about authentication conversations. this->m_pContext does not know
// about the authentication conversation. That's why we have to iterate
// through the players looking for someone. Sheesh.
if (!pRequest)
{
return HXR_UNEXPECTED;
}
HX_RESULT retVal = HXR_OK;
IHXRegistry* pRegistry = NULL;
retVal = m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry);
if (SUCCEEDED(retVal))
{
IHXCommonClassFactory* pCCF;
retVal = m_pCloakContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&pCCF);
if (SUCCEEDED(retVal))
{
IHXValues* pResponseHeaders = NULL;
HX_ASSERT(pRequest);
if (HXR_OK == pRequest->GetResponseHeaders(pResponseHeaders))
{
IHXBuffer* pServerHeaderBuffer = NULL;
HX_ASSERT(pHost);
if (pHost)
{
retVal = pCCF->CreateInstance(CLSID_IHXBuffer,
(void**)&pServerHeaderBuffer);
if (SUCCEEDED(retVal))
{
UINT32 ulHTTPStatus = atoi(pMessage->errorCode());
if (ulHTTPStatus == 407 && pProxyHost)
{
pServerHeaderBuffer->Set((UCHAR*)pProxyHost, strlen(pProxyHost)+1);
}
else
{
pServerHeaderBuffer->Set((UCHAR*)pHost, strlen(pHost)+1);
}
pResponseHeaders->SetPropertyCString("_server", pServerHeaderBuffer);
HX_RELEASE(pServerHeaderBuffer);
}
}
// Add the protocol to the response headers because TLC needs it
IHXBuffer* pProtocol = NULL;
if (SUCCEEDED(pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pProtocol)))
{
pProtocol->Set((UCHAR*)"http", strlen("http") + 1);
pResponseHeaders->SetPropertyCString("_protocol", pProtocol);
HX_RELEASE(pProtocol);
}
}
if (!spClientAuthConversationAuthenticator.IsValid())
{
DECLARE_SMART_POINTER_UNKNOWN spUnknownAuthenticator;
DECLARE_SMART_POINTER
(
IHXObjectConfiguration
) spObjectConfigurationAuthenticator;
DECLARE_SMART_POINTER
(
IHXCommonClassFactory
) spCommonClassFactoryHXCore;
spCommonClassFactoryHXCore = m_pCloakContext;
// Starting conversation
ResultStatus = spCommonClassFactoryHXCore->CreateInstance
(
CLSID_CHXClientAuthenticator,
(void**)&spUnknownAuthenticator
);
if ( SUCCEEDED(ResultStatus) && spUnknownAuthenticator.IsValid() )
{
spObjectConfigurationAuthenticator =
(
spUnknownAuthenticator
);
spObjectConfigurationAuthenticator->SetContext(m_pCloakContext);
spClientAuthConversationAuthenticator =
(
spUnknownAuthenticator
);
}
}
if ( spClientAuthConversationAuthenticator.IsValid()
&& !spClientAuthConversationAuthenticator->IsDone() )
{
HX_ASSERT(pRequest);
if (pRequest)
{
ResultStatus =
(
spClientAuthConversationAuthenticator->MakeResponse
(
this,
pRequest
)
);
// Flow continues in ResponseReady()
}
else
{
// Auth Failed!
spClientAuthConversationAuthenticator->Authenticated(FALSE);
ResponseReady(HXR_NOT_AUTHORIZED, pRequest);
}
}
HX_RELEASE(pCCF);
}
HX_RELEASE(pRegistry);
}
return ResultStatus;
}
// IHXClientAuthResponse
STDMETHODIMP
HXClientCloakedTCPSocket::ResponseReady( HX_RESULT Re
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -