⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxcloakedtcp.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
     * 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 + -