예제 #1
0
LRESULT vmsSniffDllWnd::OnProcessWebPageUrl(LPARAM lp)
{
	LOGFN ("vmsSniffDllWnd::OnProcessWebPageUrl");

	static HANDLE _hmxAccMem = CreateMutex (NULL, FALSE, "FdmFlvSniffDll::mutex::AccMem");

	WaitForSingleObject (_hmxAccMem, INFINITE);

	LOGsnl ("Got mem mutex");

	vmsSharedData sdata ("Fdm::mem::passUrlToFlvSniffDll", TRUE, 0, FILE_MAP_READ);

	if (sdata.getData () == NULL)
	{
		LOGsnl ("Failed to access shared data");
		ReleaseMutex (_hmxAccMem);
		return E_FAIL;
	}

	char *pszUrl = new char [strlen ((LPSTR)sdata.getData ())+1];
	strcpy (pszUrl, (LPSTR)sdata.getData ());

	sdata.Release ();

	LOG ("Got URL: %s", pszUrl);

	ReleaseMutex (_hmxAccMem);

	extern vmsFindFlvDownloadsResultsCache _FlvResCache;

	vmsFindFlvDownloadsResultsCache::ResultPtr result;
	
#ifdef LOG_WEBFILES_TREE
	extern LONG _cInOnGetItBtnClicked;
	InterlockedIncrement (&_cInOnGetItBtnClicked);
#endif
	HRESULT hr = _FlvResCache.FindFlvDownloads (pszUrl, NULL, NULL, NULL, NULL, NULL, result);
#ifdef LOG_WEBFILES_TREE
	InterlockedDecrement (&_cInOnGetItBtnClicked);
#endif

	LOG ("Analyzed");

	if (hr == S_OK && result->pTa->get_FlvDownloadCount () != 0)
	{
		LOGsnl ("Creating transfer to FDM thread");
		result->AddRef ();
		DWORD dw;
		CloseHandle (
			CreateThread (NULL, 0, _threadTransferDldsToFdm, result, 0, &dw));
	}
	else
	{
		LOGsnl ("No downloads found");
	}

	delete [] pszUrl;

	return hr;
}
bool vmsUrlMonRequestCollector::onInternetProtocolRoot_Continue(IInternetProtocolRoot* pProt, PROTOCOLDATA* pProtocolData)
{
	if (pProtocolData == &_protocolData || 
			(pProtocolData->dwState == 0 && pProtocolData->pData == _protocolData_pData && pProtocolData->cbData == 13))
	{
		vmsCriticalSectionAutoLock csal (&m_csReq);
		int nIndex = findRequestIndexByProtocol (pProt);
		assert (nIndex != -1);
		if (nIndex == -1)
		{
			LOGsnl ("WARNING: no request found for pProt in onInternetProtocolRoot_Continue");
			return true;
		}
		Request *req = getRequest (nIndex);

		if (!req->dwthridContinue)
		{
			if (req->dwTicksCompleted)
				req->spProt = NULL;

			req->dwthridContinue = GetCurrentThreadId ();

#ifdef SCL_ENABLE
			LOGsnl ("Update for request:");
			USES_CONVERSION;
			LOG (" URL: %s", W2CA (req->wstrUrl.c_str ()));
			LOG (" thridContinue: %d", req->dwthridContinue);
#endif

			HMODULE hBhoDll = GetModuleHandle (_T ("iefdm2.dll"));
			if (hBhoDll)
			{
				typedef BSTR (WINAPI *FNfdmbho_getTabUrl) (DWORD dwThreadId);
				FNfdmbho_getTabUrl pfn = (FNfdmbho_getTabUrl)GetProcAddress (hBhoDll, "fdmbho_getTabUrl");
				if (pfn)
				{
					BSTR bstrTabUrl = pfn (req->dwthridContinue);
					if (!bstrTabUrl)
						bstrTabUrl = pfn (req->dwthridStart);
					if (bstrTabUrl)
					{
						req->wstrSrcTabUrl = bstrTabUrl;
						SysFreeString (bstrTabUrl);
					}
#ifdef SCL_ENABLE
					LOG (" SRC TAB URL: %s", req->wstrSrcTabUrl.empty () ? "<NOT_FOUND>" : W2CA (req->wstrSrcTabUrl.c_str ()));
#endif
				}
			}
		}
		return true;
	}

	return false;
}
예제 #3
0
void vmsLogHelper::LogHttpDlgTreeList(LPCSTR pszListName, const vector <vmsWinSockHttpDlgTree::TreeItemPtr> &vItems)
{
	LOG ("%s:", pszListName);
	if (vItems.empty ())
	{
		LOGsnl ("|-(empty)");
		return;
	}
	for (size_t i = 0; i < vItems.size (); i++)
		LOG ("|-(%I64d bytes)-%s", (__int64)vItems [i]->spDlg->nContentLength, vItems [i]->spDlg->strRequestUrl.c_str ());
}
예제 #4
0
void vmsLogHelper::LogStringList(LPCSTR pszListName, const vector <string> &v)
{
	LOG ("%s:", pszListName);
	if (v.empty ())
	{
		LOGsnl ("|-(empty)");
		return;
	}
	for (size_t i = 0; i < v.size (); i++)
		LOG ("|-%s", v [i].c_str ());
}
예제 #5
0
void vmsLogHelper::LogHttpDlgList(LPCSTR pszListName, const HTTPDLGLIST &vDlgs)
{
	LOG ("%s:", pszListName);
	if (vDlgs.empty ())
	{
		LOGsnl ("|-(empty)");
		return;
	}
	for (size_t i = 0; i < vDlgs.size (); i++)
		LOG ("|-(%I64d bytes)-%s", (__int64)vDlgs [i]->nContentLength, vDlgs [i]->strRequestUrl.c_str ());
}
예제 #6
0
void WINAPI onNewHttpRequest (LPCSTR pszUrl, LPCSTR pszSrcTabUrl)
{
	assert (pszUrl != NULL && pszSrcTabUrl != NULL);
	if (!pszUrl || !pszSrcTabUrl)
		return;
	LOGsnl ("onNewHttpRequest:");
	LOG (" url: %s", pszUrl);
	LOG (" srcTab: %s", pszSrcTabUrl);
	vmsBrowserSpecialInfo::UrlInfo url;
	url.strUrl = pszUrl;
	url.strSrcTabUrl = pszSrcTabUrl;
	vmsBrowserSpecialInfo::o ().AddUrl (url);
}
void vmsUrlMonRequestCollector::onNewRequest(Request *request)
{
	_BrowsersSharedData.ModifyActiveDownloadsCount (1);

	RemoveTooOldRequests ();

	request->dwTicksStarted = GetTickCount ();

	IServiceProviderPtr spSP (request->spSink);
	assert (spSP != NULL);
	if (spSP != NULL)
		spSP->QueryService (IID_IHttpNegotiate, IID_IHttpNegotiate, (void**)&request->spHttpNegotiate);

	request->dwthridStart = GetCurrentThreadId ();

	if (_IEVersion.m_appVersion.empty () || _IEVersion.m_appVersion [0] < 10)
	{
		BINDINFO bi; DWORD dwBindF;
		ZeroMemory (&bi, sizeof (bi));
		bi.cbSize = sizeof (bi);
		request->spBindInfo->GetBindInfo (&dwBindF, &bi);

		if (bi.dwBindVerb == BINDVERB_POST && bi.cbstgmedData)
		{
			
			if (bi.stgmedData.tymed == TYMED_HGLOBAL)
			{
				LPVOID pData = GlobalLock (bi.stgmedData.hGlobal);
				if (pData)
				{
					request->vbPostData.resize (bi.cbstgmedData);
					CopyMemory (&request->vbPostData [0], pData, bi.cbstgmedData);
					GlobalUnlock (bi.stgmedData.hGlobal);
				}
			}
		}
	}

	vmsCriticalSectionAutoLock csal (&m_csReq);
	m_vReq.push_back (request);

#ifdef SCL_ENABLE
	LOGsnl ("New request:");
	USES_CONVERSION;
	LOG (" URL: %s", W2CA (request->wstrUrl.c_str ()));
	LOG (" thridStart: %d", request->dwthridStart);
	LOG (" post data size: %d", request->vbPostData.size ());
#endif

	request->spSink->Switch (&_protocolData);
}
void vmsUrlMonRequestCollector::onInternetProtocolSink_ReportProgress(IInternetProtocolSink* pSink, ULONG ulStatusCode, LPCWSTR szStatusText)
{
#ifdef SCL_ENABLE
	{USES_CONVERSION;
	vmsCriticalSectionAutoLock csal (&m_csReq);
	int nIndex = findRequestIndexBySink (pSink);
	if (nIndex == -1)
		return;
	Request *req = getRequest (nIndex);
	LOGsnl ("Progress for request:");
	LOG (" URL: %s", W2CA (req->wstrUrl.c_str ()));
	LOG (" ulStatusCode: %d", ulStatusCode);
	LOG (" szStatusText: %s", W2CA (szStatusText));}
#endif

	if (ulStatusCode != BINDSTATUS_REDIRECTING)
		return;

	assert (szStatusText != NULL);
	if (!szStatusText)
		return;

	vmsCriticalSectionAutoLock csal (&m_csReq);
	int nIndex = findRequestIndexBySink (pSink);
	if (nIndex == -1)
		return;
	Request *req = getRequest (nIndex);

	req->wstrRedirectedUrl = szStatusText;

#ifdef SCL_ENABLE
	LOGsnl ("Update for request:");
	USES_CONVERSION;
	LOG (" URL: %s", W2CA (req->wstrUrl.c_str ()));
	LOG (" Redirecting to URL: %s", W2CA (szStatusText));
	LOG (" TICKCOUNT: %d", GetTickCount ());
#endif
}
예제 #9
0
NS_IMETHODIMP CFDMForFirefox::OnHttpRedirect (const PRUnichar *wstrUrl, const PRUnichar *wstrOriginalUrl)
{
	assert (wstrUrl != NULL && wstrOriginalUrl != NULL);
	if (!wstrUrl || !wstrOriginalUrl)
		return NS_ERROR_INVALID_POINTER;
	LOGsnl ("Redirect:");
	LOG (" source: %s", CW2AEX<128> (wstrOriginalUrl));
	LOG (" new: %s", CW2AEX<128> (wstrUrl));
	vmsHttpRedirectList::Redirect r;
	r.dwTicksRegistered = GetTickCount ();
	r.wstrUrl = wstrUrl;
	r.wstrOriginalUrl = wstrOriginalUrl;
	vmsHttpRedirectList::o ().addRedirect (r);
	return NS_OK;
}
void vmsUrlMonRequestCollector::onInternetProtocolSink_ReportData(IInternetProtocolSink* pSink, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
	vmsCriticalSectionAutoLock csal (&m_csReq);
	int nIndex = findRequestIndexBySink (pSink);
	if (nIndex == -1)
		return;
	Request *req = getRequest (nIndex);
	req->dwState |= Request::GotResponse;

#ifdef SCL_ENABLE
	USES_CONVERSION;
	LOGsnl ("Report data for request:");
	LOG (" URL: %s", W2CA (req->wstrUrl.c_str ()));
	LOG (" grfBSCF: %d", grfBSCF);
	LOG (" progress: %d", ulProgress);
	LOG (" progress max: %d", ulProgressMax);
#endif
}
void vmsUrlMonRequestCollector::CloseRequest(Request* request)
{
#ifdef SCL_ENABLE
	LOGsnl ("Close request:");
	USES_CONVERSION;
	LOG (" URL: %s", W2CA (request->wstrUrl.c_str ()));
#endif

	assert (!request->dwTicksCompleted);
	if (request->dwTicksCompleted)
		return;

	_BrowsersSharedData.ModifyActiveDownloadsCount (-1);

	request->dwTicksCompleted = GetTickCount ();
	request->spHttpNegotiate = NULL;
	request->spSink = NULL;
	request->spBindInfo = NULL;
	request->spUri = NULL;
	if (request->dwthridContinue)
		request->spProt = NULL; 
}
void vmsHttpFlvTrafficAnalyzer::FindFlvDownloadInInBetweenDlgs(const vmsHttpTrafficCollector *pTraffic, HTTPDLG pWebPage, LPCSTR pszSwfUrl, LPCSTR pszFlashVars, LPCSTR pszSwfContext, HTTPDLGLIST vFlvs, FindFlvDownloadInInBetweenDlgs_Type enFindType)
{
	LOGFN ("vmsHttpFlvTrafficAnalyzer::FindFlvDownloadInInBetweenDlgs");

	if (!pszSwfUrl)
	{
		assert (pWebPage != NULL);
		if (!pWebPage)
			return;
		pszSwfUrl = pWebPage->strRequestUrl.c_str ();
	}

	string strBody;
	if (!pszSwfContext)
	{
		assert (pWebPage != NULL);
		if (!pWebPage)
			return;
		strBody.assign ((LPSTR)&pWebPage->vbResponseBody [0], pWebPage->vbResponseBody.size ());
		pszSwfContext = strBody.c_str ();
	}	

	int nStartIndex = pWebPage ? pTraffic->getHttpDialogIndex (pWebPage) + 1 : 0;

	
	
	

	HTTPDLGLIST vFlvs2;

	DWORD adwCTs [] = {
		vmsHttpTrafficCollector::HttpDialog::AMF,
		vmsHttpTrafficCollector::HttpDialog::X_WWW_FORM_URL_ENCODED,
		vmsHttpTrafficCollector::HttpDialog::XML,
		vmsHttpTrafficCollector::HttpDialog::HTML,
	};

	for (int iCT = 0; iCT < sizeof (adwCTs) / sizeof (DWORD); iCT++)
	{
		
		HTTPDLGLIST vBetwDlgs;
		pTraffic->GetHttpDialogs (nStartIndex, -1, adwCTs [iCT], vBetwDlgs);

		
		HTTPDLGLIST vBetwDlgs2;
		
		
		
		vector <HTTPDLGLIST>  vBetwToFlvMap;
		
		
		for (size_t iDlg = 0; iDlg < vBetwDlgs.size (); iDlg++)
		{
			HTTPDLG pDlg = vBetwDlgs [iDlg];
			if (pDlg->vbResponseBody.empty ())
				continue; 
			if (pDlg->enCT == vmsHttpTrafficCollector::HttpDialog::HTML &&
					pDlg->vbResponseBody.size () > 1000)
				continue; 

			string strBody; 
			
			if (pDlg->enCT == vmsHttpTrafficCollector::HttpDialog::AMF)
			{
				for (size_t i = 0; i < pDlg->vbResponseBody.size (); i++)
				{
					if (pDlg->vbResponseBody [i] >= ' ')
						strBody += pDlg->vbResponseBody [i];
				}
			}
			else if (pDlg->enCT == vmsHttpTrafficCollector::HttpDialog::X_WWW_FORM_URL_ENCODED)
			{
				
				string str; str.assign ((LPSTR)&pDlg->vbResponseBody [0], pDlg->vbResponseBody.size ());
				vmsHttpHelper::DecodeUrl (str.c_str (), strBody);
			}
			else 
			{
				
				strBody.assign ((LPSTR)&pDlg->vbResponseBody [0], pDlg->vbResponseBody.size ());
			}

			
			if (enFindType == FDT_EXACTURLMATCH)
				FindDialogsByUrlExactMatch (strBody.c_str (), vFlvs, vFlvs2);
			else if (enFindType == FDT_FILEURLMATCH)
				FindDialogsByFileUrlMatch (strBody.c_str (), vFlvs, vFlvs2);
			else if (enFindType == FDT_BYUNIQUEWORDS)
				FindDialogsByUniqueUrlWordsMatch (strBody.c_str (), vFlvs, vFlvs2);
			else
				return;

			if (!vFlvs2.empty ())
			{
				
				vBetwDlgs2.push_back (pDlg);
				vBetwToFlvMap.push_back (vFlvs2);
			}
		}

		
		if (vBetwDlgs2.empty ())
			continue; 

		LOGHTTPDLGLIST ("List of dialogs with FLVs", vBetwDlgs2);

		
		

		LOGsnl ("Found dialogs with FLVs. Find their source.");

		HTTPDLGLIST vBetwDlgsFoundInSwfContext;
		FindDialogsByUrlExactMatch (pszSwfContext, vBetwDlgs2, vBetwDlgsFoundInSwfContext);
		LOGHTTPDLGLIST ("List of these dialogs belonging to source page (exact match)", vBetwDlgsFoundInSwfContext);
		if (vBetwDlgsFoundInSwfContext.empty ())
		{
			FindDialogsByFileUrlMatch (pszSwfContext, vBetwDlgs, vBetwDlgsFoundInSwfContext);
			LOGHTTPDLGLIST ("List of these dialogs belonging to source page (file url match)", vBetwDlgsFoundInSwfContext);
		}
		if (vBetwDlgsFoundInSwfContext.empty ())
		{
			FindDialogsByUniqueUrlWordsMatch (pszSwfContext, vBetwDlgs, vBetwDlgsFoundInSwfContext);
			LOGHTTPDLGLIST ("List of these dialogs belonging to source page (unique url word match)", vBetwDlgsFoundInSwfContext);
		}
		if (vBetwDlgsFoundInSwfContext.empty ())
		{
			FindDialogsByUniqueUrlWordsMatch2 (pszSwfUrl, vBetwDlgs, vBetwDlgsFoundInSwfContext);
			LOGHTTPDLGLIST ("List of these dialogs belonging to source page (unique url words2 match)", vBetwDlgsFoundInSwfContext);
		}

		if (!vBetwDlgsFoundInSwfContext.empty ())
		{
			
			

			
			wstring wstrTitle;
			if (pszFlashVars)
				ExtractTitleFromFlashVars (pWebPage, pszFlashVars, wstrTitle);
			if (wstrTitle.empty () && pWebPage)
				ExtractTitleFromHtml (pWebPage, wstrTitle);

			
			for (size_t i = 0; i < vBetwDlgsFoundInSwfContext.size (); i++)
			{
				
				for (size_t j = 0; j < vBetwDlgs2.size (); j++)
				{
					if (vBetwDlgs2 [j] == vBetwDlgsFoundInSwfContext [i])
					{
						
						HTTPDLG pBetwDlg = vBetwDlgs2 [j];

						
						for (size_t k = 0; k < vBetwToFlvMap [j].size (); k++)
						{
							HTTPDLG pFlvDlg = vBetwToFlvMap [j][k];

							
							wstring wstrTitle2;
							if (pBetwDlg->enCT == vmsHttpTrafficCollector::HttpDialog::X_WWW_FORM_URL_ENCODED)
								ExtractTitleFromXWwwFormUrlEncoded (pBetwDlg, wstrTitle2);
							else if (pBetwDlg->enCT == vmsHttpTrafficCollector::HttpDialog::XML)
								ExtractTitleFromXml (pBetwDlg, wstrTitle2, pFlvDlg);

							if (wstrTitle2.empty ())
								wstrTitle2 = wstrTitle;

							AddFlvDownload (pWebPage, pFlvDlg, wstrTitle2.c_str ());
						}
						break;
					}
				}
			}

			return;
		}
	}
}
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;
	}
}
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);
}
BOOL vmsZlibHelper::DecompressGzip(LPBYTE pbData, UINT nSize, LPBYTE *ppUncompressed, UINT *puUncompressedSize)
{
	LOGFN ("vmsZlibHelper::DecompressGzip");

	UINT uBufSize = nSize * 100;
	LPBYTE pUncompressed;
	do 
	{
		try {
			pUncompressed = NULL;
			pUncompressed = new BYTE [uBufSize];
		}
		catch (...) {}

		if (pUncompressed == NULL)
		{
			uBufSize /= 2;
			if (uBufSize < nSize*3)
			{
				LOGsnl ("Decompress: out of memory");
				return FALSE; 
			}
		}
	}
	while (pUncompressed == NULL);

	
	int err;
    z_stream d_stream;
	
    d_stream.zalloc = Z_NULL;
    d_stream.zfree = Z_NULL;
    d_stream.opaque = Z_NULL;
	
    d_stream.next_in  = pbData;
    d_stream.avail_in = nSize;
	
    d_stream.avail_out = uBufSize;
    d_stream.next_out = pUncompressed;
	
    err = inflateInit2 (&d_stream, 32+MAX_WBITS);
	if (err != 0)
	{
		inflateEnd (&d_stream);
		delete [] pUncompressed;
		return FALSE;
	}
	
    err = inflate (&d_stream, Z_NO_FLUSH);
    if (err == 0 || err == Z_STREAM_END)
    {
        err = inflateEnd (&d_stream);
        if (err != 0)
		{
            delete [] pUncompressed;
			return FALSE;
		}
    }
    else
	{
		inflateEnd (&d_stream);
		delete [] pUncompressed;
		return FALSE;
	}

	*ppUncompressed = pUncompressed;
	*puUncompressedSize = d_stream.total_out;

    return TRUE;
}