This source file includes following definitions.
- ProcessPageTimeRequests
- SetSite
- OnDocumentComplete
- ProcessPageTimeRequests
- ErrorExit
#include "stdafx.h"
#include "MeasurePageLoadTimeBHO.h"
#define MAX_URL 1024
#define MAX_PAGELOADTIME (4*60*1000)
#define PORT 42492
static DWORD WINAPI ProcessPageTimeRequests(LPVOID pThis) {
reinterpret_cast<CMeasurePageLoadTimeBHO*>(pThis)->ProcessPageTimeRequests();
return 0;
}
STDMETHODIMP CMeasurePageLoadTimeBHO::SetSite(IUnknown* pUnkSite)
{
if (pUnkSite != NULL)
{
HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
if (SUCCEEDED(hr))
{
hr = DispEventAdvise(m_spWebBrowser);
if (SUCCEEDED(hr))
{
m_fAdvised = TRUE;
}
CComGITPtr<IWebBrowser2> git(m_spWebBrowser);
m_dwCookie = git.Detach();
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE hThread = CreateThread(NULL, 0, ::ProcessPageTimeRequests, this, 0, NULL);
}
}
else
{
if (m_fAdvised)
{
DispEventUnadvise(m_spWebBrowser);
m_fAdvised = FALSE;
}
m_spWebBrowser.Release();
}
return IObjectWithSiteImpl<CMeasurePageLoadTimeBHO>::SetSite(pUnkSite);
}
void STDMETHODCALLTYPE CMeasurePageLoadTimeBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
if (pDisp == m_spWebBrowser)
{
SetEvent(m_hEvent);
}
}
void CMeasurePageLoadTimeBHO::ProcessPageTimeRequests()
{
CoInitialize(NULL);
WaitForSingleObject(m_hEvent, MAX_PAGELOADTIME);
CComGITPtr<IWebBrowser2> git(m_dwCookie);
IWebBrowser2* browser;
git.CopyTo(&browser);
m_sockListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_sockListen == SOCKET_ERROR)
ErrorExit();
BOOL on = TRUE;
if (setsockopt(m_sockListen, SOL_SOCKET, SO_REUSEADDR,
(const char*)&on, sizeof(on)))
ErrorExit();
SOCKADDR_IN addrBind;
addrBind.sin_family = AF_INET;
addrBind.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addrBind.sin_port = htons(PORT);
if (bind(m_sockListen, (sockaddr*)&addrBind, sizeof(addrBind)))
ErrorExit();
if (listen(m_sockListen, 1))
ErrorExit();
unsigned long nNonblocking = 0;
if (ioctlsocket(m_sockListen, FIONBIO, &nNonblocking))
ErrorExit();
m_sockTransport = 0;
while(1)
{
SOCKADDR_IN addrConnected;
int sConnected = sizeof(addrConnected);
m_sockTransport = accept(
m_sockListen, (sockaddr*)&addrConnected, &sConnected);
if (m_sockTransport == SOCKET_ERROR)
ErrorExit();
char pbBuffer[MAX_URL], strURL[MAX_URL];
DWORD cbRead, cbWritten;
bool fDone = false;
while (!fDone)
{
*strURL = '\0';
bool fReceivedCR = false;
do
{
cbRead = recv(m_sockTransport, pbBuffer, MAX_URL-1, MSG_PEEK);
if (cbRead == 0)
{
fDone = true;
break;
}
pbBuffer[cbRead] = '\0';
if(char* pchFirstCR = strchr(pbBuffer, '\n'))
{
cbRead = (DWORD)(pchFirstCR - pbBuffer + 1);
fReceivedCR = true;
}
recv(m_sockTransport, pbBuffer, cbRead, 0);
pbBuffer[cbRead] = '\0';
strcat_s(strURL, sizeof(strURL), pbBuffer);
} while (!fReceivedCR);
if (fDone)
break;
int i;
for (i = (int)strlen(strURL)-1; i >= 0 && isspace(strURL[i]); i--)
{
strURL[i] = '\0';
}
if (i < 0)
{
fDone = true;
}
else
{
CComVariant vNavFlags( navNoReadFromCache );
CComVariant vTargetFrame("_self");
CComVariant vPostData("");
CComVariant vHTTPHeaders("");
ResetEvent(m_hEvent);
DWORD dwStartTime = GetTickCount();
HRESULT hr = browser->Navigate(
CComBSTR(strURL),
&vNavFlags,
&vTargetFrame,
&vPostData,
&vHTTPHeaders
);
if (WaitForSingleObject(m_hEvent, MAX_PAGELOADTIME) == WAIT_TIMEOUT)
{
sprintf_s(pbBuffer, sizeof(pbBuffer), "%s,timeout\n", strURL);
browser->Stop();
}
else
{
DWORD dwLoadTime = GetTickCount() - dwStartTime;
sprintf_s(
pbBuffer, sizeof(pbBuffer), "%s,%d\n", strURL, dwLoadTime);
}
char *chSend = pbBuffer;
while (*chSend)
{
cbWritten = send(
m_sockTransport, chSend, (int)strlen(chSend), 0);
if (cbWritten == 0)
{
fDone = true;
break;
}
chSend += cbWritten;
}
}
}
closesocket(m_sockTransport);
m_sockTransport = 0;
}
}
void CMeasurePageLoadTimeBHO::ErrorExit()
{
SetSite(NULL);
if (m_sockTransport && m_sockTransport != SOCKET_ERROR)
{
closesocket(m_sockTransport);
m_sockTransport = 0;
}
if (m_sockListen && m_sockListen != SOCKET_ERROR)
{
closesocket(m_sockListen);
m_sockListen = 0;
}
TerminateThread(GetCurrentThread(), -1);
}