示例#1
0
void
CHTTPDemux::DetectHandler(HTTPMessage* pMsg)
{
    INT32 nProxyEnabled = 0;

    if (SUCCEEDED(m_proc->pc->registry->GetInt(REGISTRY_RTSPPROXY_ENABLED, &nProxyEnabled, m_proc)))
    {
        m_pResponse = new HTTPProtocol();
        m_pResponse->AddRef();
        return;
    }

    HTTPMessage::Tag tag = pMsg->tag();
    if (tag == HTTPMessage::T_GET || tag == HTTPMessage::T_POST)
    {
        HTTPRequestMessage* pReq = (HTTPRequestMessage*)pMsg;
        const char* pUrl = pReq->url();
        if (strncmp(pUrl, "/SmpDsBhgRl", 11) == 0)
        {
            if (tag == HTTPMessage::T_GET)
            {
                m_pResponse = new CRN1CloakGETHandler();
                m_pResponse->AddRef();
            }
            else
            {
                m_pResponse = new CRN1CloakPOSTHandler();
                m_pResponse->AddRef();
            }
            return;
        }

#ifdef HELIX_FEATURE_SERVER_CLOAKV2

        CloakV2SignatureEnforcer pEnforcer;

        if (SUCCEEDED(pEnforcer.EnforceCloakSignature(pReq)))
        {
            if (tag == HTTPMessage::T_GET)
            {
                m_pResponse = new CRN1CloakFallbackGETHandler();
                m_pResponse->AddRef();
            }
            else
            {
                m_pResponse = new CRN1CloakFallbackPOSTHandler();
                m_pResponse->AddRef();
            }
            return;
        }

#endif //defined HELIX_FEATURE_SERVER_CLOAKV2

	/*
	 * If the Accept or Content-type header has
	 * application/x-rtsp-tunnelled its a quicktime cloaked connection
	 */
	MIMEHeader* pUserAgentHdr = pMsg->getHeader("User-Agent");
        MIMEHeader* pSessionHdr = pMsg->getHeader("x-sessioncookie");
	if (pSessionHdr)
	{
	    MIMEHeader* pAcceptHdr = pMsg->getHeader("Accept");
	    MIMEHeader* pContentTypeHdr = pMsg->getHeader("Content-type");
	    CHXString strValue;
	    if (pAcceptHdr != NULL)
	    {
		strValue.Empty();
		pAcceptHdr->asString(strValue);
		if (strncmp(strValue, "application/x-rtsp-tunnelled", 28) == 0)
		{
		    if (tag == HTTPMessage::T_GET)
		    {
			m_pResponse = new CQTCloakGETHandler();
			m_pResponse->AddRef();
		    }
		    else 
		    {
			m_pResponse = new CQTCloakPOSTHandler();
			m_pResponse->AddRef();
		    }
		    return;
		}
	    }
	    if (pContentTypeHdr != NULL)
	    {
		strValue.Empty();
		pContentTypeHdr->asString(strValue);
		if (strncmp(strValue, "application/x-rtsp-tunnelled", 28) == 0)
		{
		    if (tag == HTTPMessage::T_POST)
		    {
			m_pResponse = new CQTCloakPOSTHandler();
			m_pResponse->AddRef();
		    }
		    else
		    {
			m_pResponse = new CQTCloakGETHandler();
			m_pResponse->AddRef();
		    }
		    return;
		}
	    }
	    /*
	     * If the User-Agent begins with "QTS " and there is an
	     * x-sessioncookie header, it's a QT cloaking request.
	     */
	    if (pUserAgentHdr != NULL)
	    {
		pUserAgentHdr->asString(strValue);
		if (strncasecmp(strValue, "QTS ", 4) == 0)
		{
		     if (tag == HTTPMessage::T_GET)
		     {
			m_pResponse = new CQTCloakGETHandler();
			m_pResponse->AddRef();
		     }
		     else
		     {
			m_pResponse = new CQTCloakPOSTHandler();
			m_pResponse->AddRef();
		     }
		     return;
		}
	    }
	}
#if defined(HELIX_FEATURE_SERVER_WMT_MMS)
        if (IsWMTHTTP(pUrl, pUserAgentHdr))
        {
            m_pResponse = new WMTHttpProtocol();
            m_pResponse->AddRef();
            return;
        }
#endif
    }
    m_pResponse = new HTTPProtocol();
    m_pResponse->AddRef();
}
示例#2
0
void
CHTTPDemux::handleInput(IHXBuffer* pBuf)
{
    UINT32 ulBufLen = 0;
    if (pBuf)
    {
	ulBufLen = pBuf->GetSize();
	if (m_ulMsgLen+ulBufLen > MAX_HTTP_MSG_SIZE)
	{
	    if (m_pSock)
	    {
		IHXSockAddr* pAddr = 0;
		m_pSock->GetPeerAddr(&pAddr);
		if (pAddr)
		{
		    IHXBuffer* pAddrBuf = 0;
		    pAddr->GetAddr(&pAddrBuf);
		    if (pAddrBuf)
		    {
			fprintf(stderr, "W: Large HTTP message (greater than 64K) being received from addr <%s>.\n"
			    "   Possible DOS attack!\n", 
			    (const char *)pAddrBuf->GetBuffer());
			pAddrBuf->Release();
		    }
		    pAddr->Release();
		}
	    }
	    Close(HXR_FAIL);
	    return;
	}
    }
    if (m_pFragBuf == NULL)
    {
        pBuf->AddRef();
    }
    else
    {
        IHXBuffer* pNewBuf = new CHXBuffer();
        pNewBuf->AddRef();
        pNewBuf->SetSize(m_pFragBuf->GetSize() + ulBufLen);
        memcpy(pNewBuf->GetBuffer(), m_pFragBuf->GetBuffer(), m_pFragBuf->GetSize());
	memcpy(pNewBuf->GetBuffer()+m_pFragBuf->GetSize(), pBuf->GetBuffer(), ulBufLen);
        HX_RELEASE(m_pFragBuf);
        pBuf = pNewBuf;
    }

    while (pBuf != NULL && !m_bClosed)
    {
        BYTE* pData = pBuf->GetBuffer();
        UINT32 uDataLen = pBuf->GetSize();
        UINT32 uDataUsed = 0;
        IHXBuffer* pNewBuf = NULL;
        IHXBuffer* pContentBuf = NULL;
        BOOL bFirstRun = FALSE;
	BOOL bMsgTooLarge = FALSE;

        if (m_ReadState == DEMUX_READ_MSG)
        {
            HTTPMessage* pMsg = NULL;
            uDataUsed = uDataLen;
            pMsg = m_pParser->parse((const char*)pData, uDataUsed, bMsgTooLarge);
            if (pMsg == NULL)
            {
		if (bMsgTooLarge)
		{
		    if (pBuf)
			pBuf->Release();
		    if (m_pSock)
		    {
			IHXSockAddr* pAddr = 0;
			m_pSock->GetPeerAddr(&pAddr);
			if (pAddr)
			{
			    IHXBuffer* pAddrBuf = 0;
			    pAddr->GetAddr(&pAddrBuf);
			    if (pAddrBuf)
			    {
				fprintf(stderr, "W: Large amount of HTTP data being received from addr <%s>.\n"
				    "   Possible DOS attack!\n", 
				    (const char *)pAddrBuf->GetBuffer());
				pAddrBuf->Release();
			    }
			    pAddr->Release();
			}
		    }
		    Close(HXR_FAIL);
		    return;
		}
                break;
            }

            // Remove used data from the buffer
            if (uDataUsed == uDataLen)
            {
                HX_RELEASE(pBuf);
            }
            else
            {
                pNewBuf = new CHXStaticBuffer(pBuf, uDataUsed,
                                              uDataLen-uDataUsed);
                pNewBuf->AddRef();
                HX_RELEASE(pBuf);
                pBuf = pNewBuf;
            }

            if (m_pResponse == NULL)
            {
                DetectHandler(pMsg);
                HX_ASSERT(m_pResponse != NULL);
                m_pResponse->Init(this);
                bFirstRun = TRUE;
            }

            if (m_pResponse->GetFeatureFlags() & HTTP_FEATURE_IGNORE_CONTENT_LENGTH)
            {
                // Cloaking V2.
                if (m_pResponse->GetFeatureFlags() & ( HTTP_FEATURE_V11_SUPPORT
                                                     | HTTP_FEATURE_CHUNKED_ENCODING_SUPPORT))
                {
                    m_uContentRemain = 0;

                    CHXString strEncoding = pMsg->getHeaderValue("Transfer-Encoding");

                    if (strEncoding == "chunked")
                    {
                        m_ReadState = DEMUX_READ_DATA;
                    }
                }
                else // Far less strict for non-persistent HTTP/1.0 connections.
                {
                    m_uContentRemain = 0;
                    m_ReadState = DEMUX_READ_DATA;                
                }
            }
            else
            {
                MIMEHeader* pHdr = pMsg->getHeader("Content-Length");

                if (!pHdr)
                {
                    m_uContentRemain = 0;
                }
                else
                {
                    CHXString strLen;
                    pHdr->asString(strLen);
                    int iLen = atoi(strLen);
                    if (iLen < 0 || iLen > 0xffff)
                    {
                        DPRINTF(D_ERROR, ("HTTP: Bad content length %d\n", iLen));
			if (pBuf)
			    pBuf->Release();
                        Close(HXR_FAIL);
                        return;
                    }
                    
                    m_uContentRemain = (UINT32)iLen;
                    m_ReadState = DEMUX_READ_DATA;
                }
            }

            if (bFirstRun && m_pResponse->AutoDispatch())
            {
                m_pSavedMessage = pMsg;
                static_cast<CHXServSocket*>(m_pSock)->Dispatch();
                break;
            }

            DispatchMessage(pMsg);
            delete pMsg;
        }
        else if (m_ReadState == DEMUX_READ_DATA)
        {
            BOOL bEnforceContentLength = FALSE;

            if (m_pResponse->GetFeatureFlags() & HTTP_FEATURE_IGNORE_CONTENT_LENGTH)           
            {
                HX_ASSERT(m_uContentRemain == 0); // This value not used.
                pContentBuf = pBuf;
                pBuf = NULL;
            }
            else
            {
                if (m_uContentRemain >= pBuf->GetSize())
                {
                    pContentBuf = pBuf;
                    m_uContentRemain -= pBuf->GetSize();
                    pBuf = NULL;
                }
                else
                {
                    pContentBuf = new CHXStaticBuffer(pBuf, 0, m_uContentRemain);
                    pContentBuf->AddRef();

                    pNewBuf = new CHXStaticBuffer(pBuf, m_uContentRemain, pBuf->GetSize()-m_uContentRemain);
                    pNewBuf->AddRef();
                    HX_RELEASE(pBuf);
                    pBuf = pNewBuf;

                    m_uContentRemain = 0;
                    m_ReadState = DEMUX_READ_MSG;
                }
            }

            m_pResponse->OnData(pContentBuf);
            HX_RELEASE(pContentBuf);
        }
    }

    if (pBuf != NULL)
    {
        m_pFragBuf = pBuf;
        m_pFragBuf->AddRef();
    }

    HX_RELEASE(pBuf);
}