void vmsWinSockHttpTrafficCollector::OnDataSent(SOCKET s, const char *pData, int nLen)
{
	LOGFN ("vmsWinSockHttpTrafficCollector::OnDataSent");

	

	EnterCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);

	int nIndex = m_pHttpTraffic->FindDialogIndexBySocket (s);
	vmsHttpTrafficCollector::HttpDialogPtr spDlg;

	if (nIndex != -1)
	{
		spDlg = m_pHttpTraffic->m_vDialogsInProgress [nIndex];
		if (spDlg->enState >= vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_HEADERS)
		{
			m_pHttpTraffic->CloseDialog (spDlg);
			spDlg = NULL;
			nIndex = -1;
		}
	}

	LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);

	if (nIndex == -1)
	{
		
		if (nLen < 5)
		{
			LOGsnl (" too small size");
			return; 
		}
		if (strnicmp (pData, "GET ", 4) && strnicmp (pData, "POST ", 5))
		{
			LOGsnl (" not a GET or POST request");
			char *p = new char [nLen + 1];
			memcpy (p, pData, nLen);
			p [nLen] = 0;
			LOG ("  (contains: %s)", p);
			delete [] p;
			return; 
		}
		if (strstrn (pData, "HTTP/1.", nLen) == NULL)
		{
			LOGsnl (" HTTP/1. not found");
			return; 
		}
		
		
		spDlg = m_pHttpTraffic->CreateHttpDialogStore ();
		LOGsnl (" new dialog store is created.");
#ifdef _DEBUG
		spDlg->enProvider = vmsHttpTrafficCollector::HttpDialog::Provider::PROV_WINSOCK;
#endif
		spDlg->s = s;
		spDlg->enState = vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_HEADERS;
		EnterCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);
		m_pHttpTraffic->m_vDialogsInProgress.push_back (spDlg);
		LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);
	}

	switch (spDlg->enState)
	{
	case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_HEADERS:
	{
		LPCSTR pszHdrEnd = strstrn (pData, "\r\n\r\n", nLen);
		if (pszHdrEnd == NULL)
			spDlg->strRequestHeaders.append (pData, nLen);
		else
			spDlg->strRequestHeaders.append (pData, pszHdrEnd-pData+4);
		if (pszHdrEnd != NULL)
		{
			m_pHttpTraffic->onHttpRequestHdrsAvailable (spDlg);
			m_pHttpTraffic->ExtractRequestUrlFromSocket (spDlg);

			pszHdrEnd += 4;
			spDlg->enState = vmsHttpTrafficCollector::HttpDialog::REQUEST_HEADERS_SENT;

			if (pszHdrEnd-pData < nLen)
			{
				spDlg->enState = vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY;
				int l = nLen-(pszHdrEnd-pData);
				if (l <= vmsHttpTrafficCollector::RequestBodyMaxSize)
				{
					spDlg->vbRequestBody.resize (l);
					if (l)
						CopyMemory (&spDlg->vbRequestBody[0], pszHdrEnd, l);
				}
				else
				{
					m_pHttpTraffic->DeleteDialogFromListByID (spDlg->nID);
					return;
				}
			}
		}
		break;
	}

	case vmsHttpTrafficCollector::HttpDialog::REQUEST_HEADERS_SENT:
		spDlg->enState = vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY;
		

	case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY:
	{
		int l = spDlg->vbRequestBody.size ();
		if (l + nLen <= vmsHttpTrafficCollector::RequestBodyMaxSize)
		{
			spDlg->vbRequestBody.resize (l + nLen);
			CopyMemory (&spDlg->vbRequestBody[l], pData, nLen);
		}
		else
		{
			m_pHttpTraffic->DeleteDialogFromListByID (spDlg->nID);
			return;
		}
		break;
	}

	default:
		assert (false); 
		return;
	}
}
コード例 #2
0
void vmsHttpFlvTrafficAnalyzer::ExtractTitleFromXml(const vmsHttpTrafficCollector::HttpDialog *pDlg, wstring &wstrTitle, const vmsHttpTrafficCollector::HttpDialog* pFlvDlg)
{
	extern LPCSTR strstrni (LPCSTR pszSrc, LPCSTR pszSrch, int lenSrc);
	extern LPCSTR strstrn (LPCSTR pszSrc, LPCSTR pszSrch, int lenSrc);

	wstrTitle = L"";
	
	assert (pDlg != NULL);
	if (!pDlg)
		return;
	assert (pDlg->enCT == vmsHttpTrafficCollector::HttpDialog::XML);
	
	if (pDlg->vbResponseBody.empty ())
		return;

	LPCSTR pszXml = (LPCSTR)&pDlg->vbResponseBody [0];
	int iXmlLen = pDlg->vbResponseBody.size ();

	

	LPCSTR pszXml2 = strstrni (pszXml, "encoding=\"", iXmlLen);
	if (!pszXml2)
		return;
	
	pszXml2 += 10;
	iXmlLen -= pszXml2 - pszXml;
	pszXml = pszXml2;
	if (iXmlLen < 5)
		return;

	if (strnicmp (pszXml, "utf-8", 5))
		return;

	

	USES_CONVERSION;
	tstring tstrRequestUrl = A2CT (pFlvDlg->strRequestUrl.c_str ());
	
	
	string strUrl = vmsXmlHelper::toUtf8noEncode (tstrRequestUrl);
	pszXml2 = strstrn (pszXml, strUrl.c_str (), iXmlLen);

	if (!pszXml2)
	{
		
		strUrl = vmsXmlHelper::toUtf8 (tstrRequestUrl);
		pszXml2 = strstrn (pszXml, strUrl.c_str (), iXmlLen);
		if (!pszXml2)
		{
			
			strUrl = pFlvDlg->strRequestUrl;
			pszXml2 = strstrn (pszXml, strUrl.c_str (), iXmlLen);
		}
	}

	

	LPCSTR pszVideoSectionTag = pszXml;

	if (pszXml2)
	{
		

		bool bAsAttr = pszXml2 [-1] != '>'; 

		if (bAsAttr)
		{
			
			
			while (pszXml2 > pszXml && *pszXml2 != '"')
				pszXml2--;
			pszXml2--;
			if (pszXml2 > pszXml)
			{
				bool bInQ = false;
				while (pszXml2 > pszXml)
				{
					if (*pszXml2 == '"')
						bInQ = !bInQ;
					else if (*pszXml2 == '<' && bInQ == false)
						break;
					pszXml2--;
				}
				if (pszXml2 > pszXml)
					pszVideoSectionTag = pszXml2;
			}
		}
		else
		{
			
			

			
			while (pszXml2 > pszXml && *pszXml2 != '<')
				pszXml2--;
			pszXml2--;
			if (pszXml2 > pszXml)
			{
				
				bool bInT = false; 
				while (pszXml2 > pszXml)
				{
					if (*pszXml2 == '<')
					{
						if (bInT)
						{
							
							bInT = false;
						}
						else
						{
							if (pszXml2 [1] == '/')
							{
								bInT = true; 
							}
							else
							{
								
								
								break;
							}
						}
					}
					pszXml2--;
				}
				if (pszXml2 > pszXml)
					pszVideoSectionTag = pszXml2;
			}
		}
	}

	

	int iXmlLen2 = iXmlLen - (pszVideoSectionTag - pszXml);

	LPCSTR apszTags [] = {"title=\"", "<title>", "name=\"", "<name>"};
	int iTag;
	LPCSTR pszTitle = NULL;
	
	do
	{	
		for (iTag = 0; iTag < sizeof (apszTags)/sizeof (LPCSTR) && pszTitle == NULL; iTag++)
			pszTitle = strstrni (pszVideoSectionTag, apszTags [iTag], iXmlLen2);
		if (!pszTitle)
		{
			if (pszVideoSectionTag != pszXml)
			{
				
				pszVideoSectionTag = pszXml;
				iXmlLen2 = iXmlLen;
			}
			else
			{
				return; 
			}			
		}
	}
	while (pszTitle == NULL);

	pszTitle += strlen (apszTags [iTag]);

	LPCSTR pszTitleE = pszTitle;
	int iXmlLen3 = iXmlLen - (pszTitle - pszXml);
	char chEnd = pszTitle [-1] == '>' ? '<' : '"';
	while (*pszTitleE != chEnd && iXmlLen3)
	{
		pszTitleE++;
		iXmlLen3--;
	}
	if (!iXmlLen3)
		return; 
	string strTitle; strTitle.assign (pszTitle, pszTitleE-pszTitle);

	int n = MultiByteToWideChar (CP_UTF8, 0, strTitle.c_str (), -1, NULL, 0);
	assert (n != 0);
	LPWSTR pwsz = new WCHAR [n+1]; *pwsz = 0;
	MultiByteToWideChar (CP_UTF8, 0, strTitle.c_str (), -1, pwsz, n);
	wstrTitle = pwsz;
	delete [] pwsz;
}
void vmsWinSockHttpTrafficCollector::OnDataRcvd(SOCKET s, const char *pData, int nLen)
{
	LOGFN ("vmsWinSockHttpTrafficCollector::OnDataRcvd");

	

	EnterCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);

	int nIndex = m_pHttpTraffic->FindDialogIndexBySocket (s);
	if (nIndex == -1)
	{
		LOGsnl (" no dialog found for the specified socket");
		LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);
		return;
	}

	vmsHttpTrafficCollector::HttpDialogPtr spDlg = m_pHttpTraffic->m_vDialogsInProgress [nIndex];

	LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector);

	assert (spDlg != NULL);

	if (!nLen)
	{
		if (spDlg->enState < vmsHttpTrafficCollector::HttpDialog::RESPONSE_HEADERS_RCVD)
			return;
		if (spDlg->nContentLength != _UI64_MAX)
			return; 
		m_pHttpTraffic->MoveDialogToCompleted (spDlg);
		return;
	}

	switch (spDlg->enState)
	{
	case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_HEADERS:
		LOGsnl (" invalid dialog state");
		assert (false); 
		return;

	case vmsHttpTrafficCollector::HttpDialog::REQUEST_HEADERS_SENT:
	case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY:
		spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_HEADERS;
		

	case vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_HEADERS:
	{
		assert (spDlg->strResponseHeaders.empty () == false || strncmp (pData, "HTTP/", 5) == 0);
		LPCSTR pszHdrEnd = strstrn (pData, "\r\n\r\n", nLen);
		if (pszHdrEnd == NULL)
			spDlg->strResponseHeaders.append (pData, nLen);
		else
			spDlg->strResponseHeaders.append (pData, pszHdrEnd-pData+4);
		if (pszHdrEnd != NULL)
		{
			pszHdrEnd += 4;
			spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RESPONSE_HEADERS_RCVD;

			m_pHttpTraffic->onHttpResponseHdrsAvailable (spDlg);

			if (!m_pHttpTraffic->isNeedBody (spDlg))
			{
				m_pHttpTraffic->MoveDialogToCompleted (spDlg);
			}
			else if (pszHdrEnd-pData < nLen)
			{
				spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_BODY;
				int l = nLen-(pszHdrEnd-pData);
				spDlg->vbResponseBody.resize (l);
				if (l)
					CopyMemory (&spDlg->vbResponseBody[0], pszHdrEnd, l);
			}
		}
		break;
	}

	case vmsHttpTrafficCollector::HttpDialog::RESPONSE_HEADERS_RCVD:
		assert (spDlg->bSaveResponseBody || (spDlg->dwFlags & vmsHttpTrafficCollector::HttpDialog::CHECK_REAL_CONTENT_TYPE) != 0);
		spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_BODY;
		
		
	case vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_BODY:
		assert (spDlg->bSaveResponseBody || (spDlg->dwFlags & vmsHttpTrafficCollector::HttpDialog::CHECK_REAL_CONTENT_TYPE) != 0);
		int l; l = spDlg->vbResponseBody.size ();
		spDlg->vbResponseBody.resize (l + nLen);
		CopyMemory (&spDlg->vbResponseBody [l], pData, nLen);
		break;

	case vmsHttpTrafficCollector::HttpDialog::DONE:
		break; 
		
	default:
		assert (false); 
		return;
	}

	m_pHttpTraffic->onDataReceived (spDlg);
}