📄 hxcloakedtcp.cpp
字号:
{ 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; }voidHXClientCloakedTCPSocket::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_RESULTHXClientCloakedTCPSocket::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()); } UINT16 guidSize = ::strlen(m_pGuid); if(m_bUseExactContentLength) { // add in the size of the GUID (which was not base64 encoded) postLength += guidSize + 2; // 2 is for the \r\n at the end of the GUID! // we must report the exact size of the post data in the Content-length parameter count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"Content-length: %hu\r\n",postLength); /* Flawfinder: ignore */ } else { count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"Content-length: 32767\r\n"); /* Flawfinder: ignore */ } ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count); // enqueue the CR LF to indicate end of the POST header count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"\r\n"); /* Flawfinder: ignore */ ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count); // enqueue the GUID (Must be sent with every POST and not base64 encoded) ENQUEUE_DATA(m_pPostEncodedSendHTTP,&m_pGuid[0],guidSize); // enqueue the CR LF to indicate end of the GUID count = SafeSprintf(s,MAX_HTTP_METHOD_BUFSIZE,"\r\n"); /* Flawfinder: ignore */ ENQUEUE_DATA(m_pPostEncodedSendHTTP,s,count); if(inLength > 0) { // enqueue the actual POST data ENQUEUE_DATA(m_pPostEncodedSendHTTP,(char *)inData,inLength); } // clean up allocated buffers if(s) { delete [] s; } return theErr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -