📄 hxcloakedtcp.cpp
字号:
* if the 16k padding was not received in one big packet
* delete the remaining padding
*/
if (m_bDeletePadding && m_uPadLength > 0)
{
UINT16 len = (m_uPadLength <= count ? m_uPadLength : count);
BYTE* tmpBuf = new BYTE[len];
m_pReceiveGetTCP->DeQueue(tmpBuf, len);
m_uPadLength -= len;
if (m_uPadLength == 0)
{
m_bDeletePadding = FALSE;
}
HX_VECTOR_DELETE(tmpBuf);
count = m_pReceiveGetTCP->GetQueuedItemCount();
}
if (!theErr && !m_bHTTPGetHeaderReadDone && count >= 2 )
{
char* pEndLineLocation = 0;
if (!m_pHTTPHeaderBuffer || m_nHTTPHeaderBufferLength < count+1)
{
HX_VECTOR_DELETE(m_pHTTPHeaderBuffer);
m_nHTTPHeaderBufferLength = count+1 > DEFAULT_HTTP_HEADER_LENGTH ?
count+1 : DEFAULT_HTTP_HEADER_LENGTH;
m_pHTTPHeaderBuffer = new char[m_nHTTPHeaderBufferLength];
if (!m_pHTTPHeaderBuffer)
{
theErr = HXR_OUTOFMEMORY;
goto exit;
}
}
m_pReceiveGetTCP->DeQueue(m_pHTTPHeaderBuffer, count);
m_pHTTPHeaderBuffer[count] = '\0';
if ((pEndLineLocation = (char*) HXFindString(m_pHTTPHeaderBuffer, "\n\n")) ||
(pEndLineLocation = (char*) HXFindString(m_pHTTPHeaderBuffer, "\r\r")) )
{
pStartAfterDoubleReturn = pEndLineLocation+2;
m_bHTTPGetHeaderReadDone = TRUE;
}
else if (count >= 4 &&
(pEndLineLocation = (char*) HXFindString(m_pHTTPHeaderBuffer, "\r\n\r\n")))
{
pStartAfterDoubleReturn = pEndLineLocation+4;
m_bHTTPGetHeaderReadDone = TRUE;
}
else
{
/* Put back everything in receive queue*/
m_pReceiveGetTCP->EnQueue(m_pHTTPHeaderBuffer, count);
goto exit;
}
// determine whether we need to issue re-GET to the same serverIP
// from the POST response
if (!m_bGetResponsed && !m_bConnectToSameServerIP)
{
m_bGetResponsed = TRUE;
GetServerIPFromResponse(TRUE, m_pHTTPHeaderBuffer);
if (m_pszGetServerIP && m_pszPutServerIP)
{
m_bReconnectToSameServerIP = strcasecmp(m_pszGetServerIP, m_pszPutServerIP);
}
if (m_bReconnectToSameServerIP)
{
theErr = ReconnectToSameServerIP();
goto quit;
}
}
/* If we have read the complete header, see if the content is OK..*/
char* pFound = (char*) HXFindString(m_pHTTPHeaderBuffer, "HTTP/1.0 200 OK");
if (!pFound)
{
pFound = (char*) HXFindString(m_pHTTPHeaderBuffer, "200 OK");
}
// XXX HP we are phasing out PNM protocol
// m_pCloakValues is only set in RTSP so we use this to exclude
// support for redirect in PNM Cloaking
if (!pFound)
{
if (m_pCloakValues)
{
pFound = (char*) HXFindString(m_pHTTPHeaderBuffer, "HTTP/1.0 302");
if (pFound)
{
strncpy(pFound, "RTSP", 4); /* Flawfinder: ignore */
IHXBuffer* pBuffer = new CHXBuffer;
pBuffer->AddRef();
pBuffer->Set((UCHAR*) m_pHTTPHeaderBuffer, count);
m_pTCPResponse->ReadDone(HXR_OK, pBuffer);
pBuffer->Release();
goto exit;
}
}
theErr = HXR_DOC_MISSING;
}
if (!theErr)
{
m_pReceiveGetTCP->EnQueue(pStartAfterDoubleReturn,
(m_pHTTPHeaderBuffer + count) - pStartAfterDoubleReturn);
count = m_pReceiveGetTCP->GetQueuedItemCount();
}
}
/* hmmm... time to read options */
if (!theErr && count > 0 && !m_bOptionsReceived && m_bHTTPGetHeaderReadDone)
{
/* There needs to be atleast 4 bytes to have the response
* reponse_opcode(HTTP_RV_RESPONSE), response len,
* actual response(minimum one byte)
*/
if (count < 3)
{
goto exit;
}
m_pReceiveGetTCP->DeQueue(m_pInBuf, count);
if (m_pInBuf[0] == HTTP_RESPONSE)
{
m_bOptionsReceived = TRUE;
UINT16 nOptionLen = m_pInBuf[1];
/* Place any data after the response back in Receive queue.
* This data needs to be sent to the user*/
if (count > 2+nOptionLen)
{
m_pReceiveGetTCP->EnQueue(m_pInBuf+2+nOptionLen, (count - (2+nOptionLen)));
}
theErr = HandleHTTPResponse((UCHAR) m_pInBuf[2]);
if (!theErr)
{
count = m_pReceiveGetTCP->GetQueuedItemCount();
}
}
else if (m_pInBuf[0] == HTTP_RV_RESPONSE)
{
if (count < 9)
{
m_pReceiveGetTCP->EnQueue(m_pInBuf, count);
goto exit;
}
/*
* this involves receiving a message from the server of the format:
* HTTP/1.0 200 OK
* ...
* Content-length:2147483000
* r...O?...16k padding of ZEROs...e
*
* r -- HTTP_RV_RESPONSE (same as the 5.0 player)
* O -- HTTP_OPTION_RESPONSE
* e -- HTTP_OPT_RESPONSE_END
*/
BYTE* ptr = (BYTE *)m_pInBuf;
m_bOptionsReceived = TRUE;
ptr += 2;
UINT16 nOptionLen = *ptr;
ptr++;
theErr = HandleHTTPResponse((UCHAR)*ptr);
ptr++;
if (!theErr)
{
ptr++; // get past the HTTP_OPTION_RESPONSE char 'O'
m_uPadLength = (UINT16)getshort(ptr);
ptr += 2;
// skip over the short padding option
m_uPadLength += 1; // for the 'e' at the end of the 16k padding
m_pReceiveGetTCP->EnQueue(ptr,
(m_uPadLength <= (count - (ptr - (BYTE *)m_pInBuf))
? m_uPadLength : (count - (ptr - (BYTE *)m_pInBuf))));
count = m_pReceiveGetTCP->GetQueuedItemCount();
// get rid of the padding sent with the first response
UINT16 len = (m_uPadLength <= count ? m_uPadLength : count);
BYTE* tmpBuf = new BYTE[len];
m_pReceiveGetTCP->DeQueue(tmpBuf, len);
m_uPadLength -= len;
if (m_uPadLength > 0)
{
m_bDeletePadding = TRUE;
}
// if we got more than the 16k initial buffer, put it back
if (len && len < count)
m_pReceiveGetTCP->EnQueue(&m_pInBuf[len], count-len);
HX_VECTOR_DELETE(tmpBuf);
count = m_pReceiveGetTCP->GetQueuedItemCount();
}
}
else
{
theErr = HXR_BAD_SERVER;
goto exit;
}
}
if (!theErr && 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();
}
}
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);
}
}
}
if (!m_LastError)
{
DoPutWrite();
DoRead();
}
quit:
m_pMutex->Unlock();
return HXR_OK;
}
HX_RESULT
HXClientCloakedTCPSocket::DoPutReadDone(HX_RESULT status, IHXBuffer* pInBuffer)
{
HX_RESULT rc = HXR_OK;
UINT16 count = 0;
m_bPutReadPending = FALSE;
if (HXR_OK != status)
{
rc = status;
goto cleanup;
}
// stop processing either we already processed one PUT response or
// we are in multi-post mode
if (!m_bPutResponsed && !m_bMustCloseHTTP)
{
if (!m_pReceivePutTCP)
{
m_pReceivePutTCP = new CByteGrowingQueue(QUEUE_START_SIZE,1);
if (!m_pReceivePutTCP || !m_pReceivePutTCP->IsQueueValid())
{
rc = HXR_OUTOFMEMORY;
goto cleanup;
}
m_pReceivePutTCP->SetMaxSize(TCP_BUF_SIZE);
}
if (pInBuffer)
{
m_pReceivePutTCP->EnQueue(pInBuffer->GetBuffer(), (UINT16) pInBuffer->GetSize());
}
count = m_pReceivePutTCP->GetQueuedItemCount();
if (count >= 2)
{
char* pEndLineLocation = 0;
if (!m_pHTTPHeaderBuffer || m_nHTTPHeaderBufferLength < count+1)
{
HX_VECTOR_DELETE(m_pHTTPHeaderBuffer);
m_nHTTPHeaderBufferLength = count+1 > DEFAULT_HTTP_HEADER_LENGTH ?
count+1 : DEFAULT_HTTP_HEADER_LENGTH;
m_pHTTPHeaderBuffer = new char[m_nHTTPHeaderBufferLength];
if (!m_pHTTPHeaderBuffer)
{
rc = HXR_OUTOFMEMORY;
goto cleanup;
}
}
m_pReceivePutTCP->DeQueue(m_pHTTPHeaderBuffer, count);
m_pHTTPHeaderBuffer[count] = '\0';
if ((pEndLineLocation = (char*) HXFindString(m_pHTTPHeaderBuffer, "\n\n")) ||
(pEndLineLocation = (char*) HXFindString(m_pHTTPHeaderBuffer, "\r\r")) )
{
m_bHTTPPutHeaderReadDone = TRUE;
}
else if (count >= 4 &&
(pEndLineLocation = (char*) HXFindString(m_pHTTPHeaderBuffer, "\r\n\r\n")))
{
m_bHTTPPutHeaderReadDone = TRUE;
}
else
{
/* Put back everything in receive queue*/
m_pReceivePutTCP->EnQueue(m_pHTTPHeaderBuffer, count);
goto cleanup;
}
m_bPutResponsed = TRUE;
GetServerIPFromResponse(FALSE, m_pHTTPHeaderBuffer);
if (m_bConnectToSameServerIP)
{
rc = ActualConnect();
}
else
{
if (m_pszPutServerIP && m_pPreferredTransport)
{
m_pPreferredTransport->SetHTTPNG(TRUE);
}
// determine whether we need to issue re-GET to the same serverIP
// from the POST response
if (m_pszGetServerIP && m_pszPutServerIP)
{
m_bReconnectToSameServerIP = strcasecmp(m_pszGetServerIP, m_pszPutServerIP);
}
if (m_bReconnectToSameServerIP)
{
rc = ReconnectToSameServerIP();
}
}
}
}
cleanup:
return rc;
}
void
HXClientCloakedTCPSocket::TransferBuffers()
{
IHXBuffer* pBuffer = 0;
HX_RESULT theErr = HXR_OK;
if (m_bInTransferBuffers)
{
return;
}
m_bInTransferBuffers = TRUE;
/*This is where we need to add POST header for multiple POST case*/
while (m_PendingWriteBuffers.GetCount() > 0)
{
pBuffer = (IHXBuffer*) m_PendingWriteBuffers.GetHead();
if ((UINT16) pBuffer->GetSize() < m_pPreEncodedSendHTTP->GetMaxAvailableElements())
{
m_pPreEncodedSendHTTP->EnQueue(pBuffer->GetBuffer(),
(UINT16) pBuffer->GetSize());
pBuffer->Release();
m_PendingWriteBuffers.RemoveHead();
}
else
{
break;
}
}
UINT16 nCount = m_pPreEncodedSendHTTP->GetQueuedItemCount();
if (nCount > 0)
{
if (m_bCloseHttpAfterWrite)
{
ENQUEUE_BYTE(m_pPreEncodedSendHTTP, HTTP_POSTDONE);
nCount++;
}
if (m_bMustCloseHTTP && m_pPutCtrl)
{
m_pPutCtrl->Release();
m_pPutCtrl = 0;
m_bPutConnectDone = FALSE;
m_pNetworkServices->CreateTCPSocket(&m_pPutCtrl);
if (!m_pPutCtrl)
{
m_LastError = HXR_OUTOFMEMORY;
m_bInTransferBuffers = FALSE;
return;
}
m_pPutCtrl->Init(m_pPutCtrlResponse);
const char* pActualHost = m_pForiegnHost;
UINT16 nActualPort = m_nForeignPort;
if (m_pProxyHostName)
{
pActualHost = m_pProxyHostName;
nActualPort = m_nProxyPortNumber;
}
m_pPutCtrl->Connect(pActualHost,nActualPort);
}
m_pPreEncodedSendHTTP->DeQueue(m_pOutBuf, nCount);
UINT16 nEncodedCount = TCP_BUF_SIZE;
EncodeBase64((UCHAR*) m_pOutBuf, nCount, (UCHAR*) m_pOutEncodedBuf, nEncodedCount);
HX_ASSERT(nEncodedCount <= TCP_BUF_SIZE);
if (m_bCloseHttpAfterWrite)
{
theErr = PreparePostMessage((UCHAR*) m_pOutEncodedBuf, nEncodedCount);
}
else
{
ENQUEUE_DATA(m_pPostEncodedSendHTTP,m_pOutEncodedBuf, nEncodedCount);
}
}
m_bInTransferBuffers = FALSE;
}
/***************************General routines*******/
HX_RESULT
HXClientCloakedTCPSocket::PreparePostMessage(const UCHAR *inData, UINT16 inLength)
{
HX_RESULT theErr = HXR_OK;
int count = 0;
UINT16 postLength = inLength;
// create a temp buffer to help build the HTTP POST message
char* s = new char[MAX_HTTP_METHOD_BUFSIZE];
if(s == NULL)
{
return HXR_OUTOFMEMORY;
}
// build the HTTP POST message
if(m_pProxyHostName)
{
if (m_nForeignPort)
{
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"POST http://%s:%d/SmpDsBhgRl",m_pForiegnHost, m_nForeignPort);
}
else
{
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"POST http://%s/SmpDsBhgRl",m_pForiegnHost);
}
}
else
{
//count = sprintf(s,"POST /SmpDsBhgRl"); /* Flawfinder: ignore */
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"POST /SmpDsBhgRl"); /* Flawfinder: ignore */
}
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
// enqueue the remainder of the POST line
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE," HTTP/1.0\r\n"); /* Flawfinder: ignore */
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"User-Agent: RealPlayer G2\r\n"); /* Flawfinder: ignore */
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"Pragma: no-cache\r\n"); /* Flawfinder: ignore */
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"Expires: Mon, 18 May 1974 00:00:00 GMT\r\n"); /* Flawfinder: ignore */
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"Accept: application/x-rtsp-tunnelled, */*\r\n"); /* Flawfinder: ignore */
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"Content-type: application/x-pncmd\r\n"); /* Flawfinder: ignore */
ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count);
CHXString strAuth;
ObtainAuthenticationInformation(strAuth);
if (!strAuth.IsEmpty())
{
strAuth += "\r\n";
ENQUEUE_DATA(m_pPostEncodedSendHTTP, (void*)(const char*)strAuth,
(UINT16)strAuth.GetLength());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -