agent/browser/ie/pagetest/PagetestReporting.cpp
/*-----------------------------------------------------------------------------
	Copy the necessary data about resources (i.e. headers, response bodies,
	etc) into the PagespeedInput structure.
-----------------------------------------------------------------------------*/
Copy the necessary data about resources  into the PagespeedInput structure.
Copy the necessary data about resources into the PagespeedInput structure .
void CPagetestReporting::PopulatePageSpeedInput(pagespeed::PagespeedInput* input)
{
	ATLTRACE(_T("[Pagetest] - PopulatePageSpeedInput\n"));
	POSITION pos = events.GetHeadPosition();
	while( pos )
	{
		CTrackedEvent * e = events.GetNext(pos);
		if( e && e->type == CTrackedEvent::etWinInetRequest )
		{
			CWinInetRequest * w = (CWinInetRequest *)e;
			pagespeed::Resource* resource = new pagespeed::Resource();
			const std::string response_body(reinterpret_cast<char*>(w->body), w->bodyLen);
			resource->SetResponseBody(response_body);
			if ( w->start > 0 )
			{
				int startMillis = (int)((w->start - start)/msFreq);
				resource->SetRequestStartTimeMillis(startMillis);
			}
			resource->SetRequestMethod(static_cast<LPSTR>(CT2CA(w->verb)));
			CString obUrl = w->scheme;
			obUrl.TrimRight(':');
			obUrl += _T("://") + w->host + w->object;
			resource->SetRequestUrl(static_cast<LPSTR>(CT2CA(obUrl)));
			resource->SetResponseStatusCode(w->result);
			int headerPos = 0;
			CString key, value;
			w->outHeaders.Tokenize(_T("\r\n"), headerPos);
			if (headerPos >= 0) 
			{
				while (GetNextHttpHeader(w->outHeaders, &headerPos, &key, &value)) 
				{
					resource->AddRequestHeader(
						static_cast<LPSTR>(CT2CA(key)),
						static_cast<LPSTR>(CT2CA(value)));
				}
			}
			headerPos = 0;
			w->inHeaders.Tokenize(_T("\r\n"), headerPos);
			if (headerPos >= 0) 
			{
				while (GetNextHttpHeader(w->inHeaders, &headerPos, &key, &value)) 
				{
					resource->AddResponseHeader(
						static_cast<LPSTR>(CT2CA(key)),
						static_cast<LPSTR>(CT2CA(value)));
				}
			}
			headerPos = 0;
			w->cachedInHeaders.Tokenize(_T("\r\n"), headerPos);
			if (headerPos >= 0) 
			{
				while (GetNextHttpHeader(w->cachedInHeaders, &headerPos, &key, &value)) 
				{
					if (resource->GetResponseHeader(static_cast<LPSTR>(CT2CA(key))).empty()) {
						resource->AddResponseHeader(
							static_cast<LPSTR>(CT2CA(key)),
							static_cast<LPSTR>(CT2CA(value)));
					}
				}
			}
			if (resource->GetResponseHeader("Date").empty())
			{
				CString dateStr = SynthesizeDateHeaderForResource(obUrl);
				if (!dateStr.IsEmpty())
				{
					resource->AddResponseHeader("Date", static_cast<LPSTR>(CT2CA(dateStr)));
				}
			}
			if (input->AddResource(resource)) {
				if (w->basePage)
					input->SetPrimaryResourceUrl(resource->GetRequestUrl());
			}
		}
	}
	if (endDoc > 0) {
		if (endDoc > start) {
			input->SetOnloadTimeMillis((int)((endDoc - start)/msFreq));
		}
	} else {
		input->SetOnloadState(pagespeed::PagespeedInput::ONLOAD_NOT_YET_FIRED);
	}
	pos = browsers.GetHeadPosition();
	while( pos )
	{
		CBrowserTracker tracker = browsers.GetNext(pos);
		if( tracker.threadId == GetCurrentThreadId() && tracker.browser )
		{
			CComPtr<IDispatch> spDoc;
			if( SUCCEEDED(tracker.browser->get_Document(&spDoc)) && spDoc )
			{
				CComQIPtr<IHTMLDocument3> doc = spDoc;
				if ( doc )
				{
					pagespeed::DomDocument* psDoc = pagespeed::ie::CreateDocument(doc);
					if ( psDoc ) 
					{
						input->AcquireDomDocument(psDoc);
						break;
					}
				}
			}
		}
	}
	ATLTRACE(_T("[Pagetest] - CPagetestReporting::PopulatePageSpeedInput - complete\n"));
}
void CPagetestReporting :: PopulatePageSpeedInput ( pagespeed :: PagespeedInput * input ) { ATLTRACE ( _T ( " \n " ) ) ; POSITION pos = events . GetHeadPosition ( ) ; while ( pos ) { CTrackedEvent * e = events . GetNext ( pos ) ; if ( e && e -> type == CTrackedEvent :: etWinInetRequest ) { CWinInetRequest * w = ( CWinInetRequest * ) e ; pagespeed :: Resource * resource = new pagespeed :: Resource ( ) ; const std :: string response_body ( reinterpret_cast < char * > ( w -> body ) , w -> bodyLen ) ; resource -> SetResponseBody ( response_body ) ; if ( w -> start > 0 ) { int startMillis = ( int ) ( ( w -> start - start ) / msFreq ) ; resource -> SetRequestStartTimeMillis ( startMillis ) ; } resource -> SetRequestMethod ( static_cast < LPSTR > ( CT2CA ( w -> verb ) ) ) ; CString obUrl = w -> scheme ; obUrl . TrimRight ( ' ' ) ; obUrl += _T ( " " ) + w -> host + w -> object ; resource -> SetRequestUrl ( static_cast < LPSTR > ( CT2CA ( obUrl ) ) ) ; resource -> SetResponseStatusCode ( w -> result ) ; int headerPos = 0 ; CString key , value ; w -> outHeaders . Tokenize ( _T ( " \r \n " ) , headerPos ) ; if ( headerPos >= 0 ) { while ( GetNextHttpHeader ( w -> outHeaders , & headerPos , & key , & value ) ) { resource -> AddRequestHeader ( static_cast < LPSTR > ( CT2CA ( key ) ) , static_cast < LPSTR > ( CT2CA ( value ) ) ) ; } } headerPos = 0 ; w -> inHeaders . Tokenize ( _T ( " \r \n " ) , headerPos ) ; if ( headerPos >= 0 ) { while ( GetNextHttpHeader ( w -> inHeaders , & headerPos , & key , & value ) ) { resource -> AddResponseHeader ( static_cast < LPSTR > ( CT2CA ( key ) ) , static_cast < LPSTR > ( CT2CA ( value ) ) ) ; } } headerPos = 0 ; w -> cachedInHeaders . Tokenize ( _T ( " \r \n " ) , headerPos ) ; if ( headerPos >= 0 ) { while ( GetNextHttpHeader ( w -> cachedInHeaders , & headerPos , & key , & value ) ) { if ( resource -> GetResponseHeader ( static_cast < LPSTR > ( CT2CA ( key ) ) ) . empty ( ) ) { resource -> AddResponseHeader ( static_cast < LPSTR > ( CT2CA ( key ) ) , static_cast < LPSTR > ( CT2CA ( value ) ) ) ; } } } if ( resource -> GetResponseHeader ( " " ) . empty ( ) ) { CString dateStr = SynthesizeDateHeaderForResource ( obUrl ) ; if ( ! dateStr . IsEmpty ( ) ) { resource -> AddResponseHeader ( " " , static_cast < LPSTR > ( CT2CA ( dateStr ) ) ) ; } } if ( input -> AddResource ( resource ) ) { if ( w -> basePage ) input -> SetPrimaryResourceUrl ( resource -> GetRequestUrl ( ) ) ; } } } if ( endDoc > 0 ) { if ( endDoc > start ) { input -> SetOnloadTimeMillis ( ( int ) ( ( endDoc - start ) / msFreq ) ) ; } } else { input -> SetOnloadState ( pagespeed :: PagespeedInput :: ONLOAD_NOT_YET_FIRED ) ; } pos = browsers . GetHeadPosition ( ) ; while ( pos ) { CBrowserTracker tracker = browsers . GetNext ( pos ) ; if ( tracker . threadId == GetCurrentThreadId ( ) && tracker . browser ) { CComPtr < IDispatch > spDoc ; if ( SUCCEEDED ( tracker . browser -> get_Document ( & spDoc ) ) && spDoc ) { CComQIPtr < IHTMLDocument3 > doc = spDoc ; if ( doc ) { pagespeed :: DomDocument * psDoc = pagespeed :: ie :: CreateDocument ( doc ) ; if ( psDoc ) { input -> AcquireDomDocument ( psDoc ) ; break ; } } } } } ATLTRACE ( _T ( " \n " ) ) ; }
Copy the necessary data about resources (i.e.
Copy the necessary data about resources ( i . e .
// TODO: should we skip e->ignore responses? 
 // NOTE: the scheme sometimes includes a colon, which we trim.
 // Populate HTTP request headers.
 // Skip the first header line (e.g. GET /foo HTTP/1.1).
 // Populate HTTP response headers.
 // Skip the first header line (e.g. HTTP/1.1 200 OK).
 // Next, merge the cached response headers from wininet.
 //
 // Note that by default wininet removes certain headers. See 
 // http://code.google.com/p/page-speed/issues/detail?id=321 for
 // information on how this impacts Page Speed.
 // Skip the first header line (e.g. HTTP/1.1 200 OK).
 // Only add a cached header if it wasn't already present in the network
 // headers.
 // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.3 
 // for additional information about merging response headers.
 // Check to see if the response includes a Date header. Responses 
 // served from the wininet cache have their Date header removed. Since
 // Page Speed wants to compute freshness lifetimes of resources, it needs
 // a Date header.
 // Onload didn't fire yet.
