www.pudn.com > pueblo.zip > ChHTNtfy.cpp


/*---------------------------------------------------------------------------- 
                        _                              _ _        
        /\             | |                            | (_)       
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _  
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` | 
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| | 
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_| 
 
    The contents of this file are subject to the Andromedia Public 
	License Version 1.0 (the "License"); you may not use this file 
	except in compliance with the License. You may obtain a copy of 
	the License at http://www.andromedia.com/APL/ 
 
    Software distributed under the License is distributed on an 
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 
	implied. See the License for the specific language governing 
	rights and limitations under the License. 
 
    The Original Code is Pueblo client code, released November 4, 1998. 
 
    The Initial Developer of the Original Code is Andromedia Incorporated. 
	Portions created by Andromedia are Copyright (C) 1998 Andromedia 
	Incorporated.  All Rights Reserved. 
 
	Andromedia Incorporated                         415.365.6700 
	818 Mission Street - 2nd Floor                  415.365.6701 fax 
	San Francisco, CA 94103 
 
    Contributor(s): 
	-------------------------------------------------------------------------- 
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek, 
	                Coyote Lussier, Pritham Shetty. 
 
					Wrote and designed original codebase. 
 
------------------------------------------------------------------------------ 
 
	This file contains the implementation of the ChHTTPInfo class notification 
	methods. 
----------------------------------------------------------------------------*/ 
 
#include "headers.h" 
 
#include  
#include  
#include  
#include  
#include  
#include  
#include "ChHTPriv.h" 
#include "ChHttpThreadMgr.h"  
 
#if !defined(CH_PUEBLO_PLUGIN) 
#include "resource.h" 
#else 
#include "vwrres.h"	  
#endif 
 
void ChHTTPInfo::UpdateStatusInfo( bool boolActive /* = true */ ) 
{ 
	// Update the num active  
	// Serialize HTTP access  
	if ( m_pSocket ) 
	{ // if we have a socket conn then add to the list 	 
 
 
		// update the bytes read 
		// serialize access to stream state 
		LockHTTP(); 
 
		if ( boolActive && m_boolUpdateInfo ) 
		{ 
			UnlockHTTP(); 
			return; 
		} 
 
		if (  !boolActive && !m_boolUpdateInfo  ) 
		{ 
			UnlockHTTP(); 
			return; 
		} 
 
 
		int 		iActive = 1; 
		chint32		lBytes = m_luBodyLen; 
		 
		if ( !boolActive ) 
		{ 
			iActive = -1; 
			lBytes *= -1;	 
		} 
 
		// Set the state of active info for this connection 
		m_boolUpdateInfo = boolActive; 
 
		if ( GetHTTPConn()->GetConnOptions() & ChHTTPConn::connLocalState) 
		{ 
		 	GetHTTPConn()->m_connState.iTotalActive += iActive; 
			if ( m_luBodyLen != 0xFFFFFFFF ) 
			{ 
		 		GetHTTPConn()->m_connState.luTotalBytes += lBytes; 
			} 
		} 
		else 
		{ 
		 	GetHTTPConn()->m_connState.iTotalActive += iActive; 
		 	GetHTTPConn()->m_connGlobalState.iTotalActive += iActive; 
 
			if ( m_luBodyLen != 0xFFFFFFFF ) 
			{ 
		 		GetHTTPConn()->m_connState.luTotalBytes += lBytes; 
		 		GetHTTPConn()->m_connGlobalState.luTotalBytes += lBytes; 
			} 
		} 
		// Unlock serialization 
		UnlockHTTP(); 
	} 
} 
 
/*---------------------------------------------------------------------------- 
 
	FUNCTION		||	AsyncNotifyProgress 
 
	iError 			|| Error code 
 
-------------------------------DESCRIPTION----------------------------------- 
 
Notify the progress for the request. 
 
----------------------------------------------------------------------------*/ 
void ChHTTPInfo::NotifyProgress(  ) 
{ 
 
	// Serialize HTTP access 	 
	LockHTTP(); 
 
	// update the bytes read 
	if ( GetHTTPConn()->GetConnOptions() & ChHTTPConn::connLocalState) 
	{ 
	 	GetHTTPConn()->m_connState.luTotalReceived += m_luToProcess; 
	} 
	else 
	{ 
	 	GetHTTPConn()->m_connState.luTotalReceived += m_luToProcess; 
	 	GetHTTPConn()->m_connGlobalState.luTotalReceived += m_luToProcess; 
	} 
	// Unlock serialization 
	UnlockHTTP(); 
 
	// If progress message is required, notify 
	if ( GetHTTPConn()->GetConnOptions() &  ChHTTPConn::connNotifyProgress ) 
	{ 
	} 
 
	#if 0 
	if ( !(GetHTTPConn()->GetMsgMask() & ChHTTPSocketConn::msgProgress) ) 
	{ 
	 	return; 
	} 
 
	#if defined( CH_MSW ) 
	if ( GetHTTPConn()->GetNotificationWnd() ) 
	{ 
 
		switch( iMsgType ) 
		{ 
			case ChHTTPInfo::msgBeginProgress : 
			{ 
				break; 
			} 
			case ChHTTPInfo::msgEndProgress : 
			{ 
				ChHTTPNotification* pInfo = new ChHTTPNotification(  
										ChHTTPNotification::msgEndProgress );  
				ASSERT( pInfo ); 
 
				if ( !::PostMessage( GetHTTPConn()->GetNotificationWnd(),  
								WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo ) ) 
				{ 
					TRACE1("Post message failed %ld\n", ::GetLastError() ); 
					delete pInfo; 
				} 
 
				break; 
			} 
 
			case ChHTTPInfo::msgProgress : 
			{ 
				string strMsg; 
 
				strMsg.Format( "Document: Received %ld of %ld bytes",  
										ChHTTPInfo::GetTotalBytesRead(), 
										ChHTTPInfo::GetTotalBytesToRead() ); 
 
				if ( m_luTotalBytes == 0 ) 
				{ 
					m_luTotalBytes = m_luBytesRead; 
				} 
 
				DWORD dwProgress = 100 *  
						ChHTTPInfo::GetTotalBytesRead() / ChHTTPInfo::GetTotalBytesToRead(); 
 
				if ( dwProgress > 100 ) 
				{ 
					dwProgress = 100; 
				} 
 
				ChHTTPNotification* pInfo = new ChHTTPNotification( 
										 ChHTTPNotification::msgMakingProgress, 
										strMsg, dwProgress, 100 );  
				ASSERT( pInfo ); 
 
				if ( !::PostMessage( GetHTTPConn()->GetNotificationWnd(),  
								WM_CHACO_HTTP_MSG, 0, (LPARAM)pInfo ) ) 
				{ 
					TRACE1("Post message failed %ld\n", ::GetLastError() ); 
					delete pInfo; 
				} 
 
				break; 
			} 
		} 
 
	} 
	#endif 
	#endif 
 
}   
 
 
 
/*---------------------------------------------------------------------------- 
 
	FUNCTION		||	InitStream 
 
	iError 			|| Error code 
 
-------------------------------DESCRIPTION----------------------------------- 
 
Stream and notify the request 
----------------------------------------------------------------------------*/ 
 
void ChHTTPInfo::InitStream( ) 
{ 
 
	if ( GetThread() ) 
	{ 
		GetThread()->LockStream(); 
	} 
 
	if (  m_iStreamState == streamUnInitialized && 
			GetStreamMgr() ) 
	{ 
		m_iStreamState = streamInitialized; 
 
 
		m_httpStream.m_uStreamOption = GetStreamMgr()-> 
					NewStream(  GetUserData(), &m_httpStream, false ); 
 
	} 
 
	if ( GetThread() ) 
	{ 
		GetThread()->UnlockStream(); 
	} 
} 
 
 
 
 
 
/*---------------------------------------------------------------------------- 
 
	FUNCTION		||	StreamClose 
 
	iError 			|| Error code 
 
-------------------------------DESCRIPTION----------------------------------- 
 
Stream and notify the request 
----------------------------------------------------------------------------*/ 
 
void ChHTTPInfo::CloseStream( ) 
{   
	// Update the num active  
	// Serialize HTTP access  
	if ( m_pSocket ) 
	{ // if we have a socket conn then add to the list 	 
 
		LockHTTP(); 
 
		if ( m_boolUpdateInfo ) 
		{ 
			UpdateStatusInfo( false ); 
		} 
 
		// Unlock serialization 
		UnlockHTTP(); 
	} 
 
	if ( GetThread() ) 
	{ 
		GetThread()->LockStream(); 
	} 
 
	// if stream is already destroyed, do nothing  
	if (  m_iStreamState != streamDestroyed &&	GetStreamMgr() ) 
	{ 
		// Initialize if not initialized 
		if (  m_iStreamState == streamUnInitialized ) 
		{ 
			m_httpStream.m_uStreamOption = GetStreamMgr()-> 
						NewStream(  GetUserData(), &m_httpStream, false ); 
			m_iStreamState = streamInitialized; 
		} 
 
 
		if (  m_iStreamState == streamInitialized ) 
		{ 
			if ( 0 == GetError() ) 
			{	// stream file if everything is OK 
				if ( m_httpStream.m_uStreamOption & ChHTTPStreamManager::streamAsFile ) 
				{ 
					GetStreamMgr()->StreamAsFile( GetUserData(),  
												&m_httpStream, GetFileName() );	 
				} 
 
			} 
		} 
 
		GetStreamMgr()->DestroyStream( GetUserData(), &m_httpStream, GetError() );	 
 
		m_iStreamState = streamDestroyed; 
	} 
 
	if ( GetThread() ) 
	{ 
		GetThread()->UnlockStream(); 
	} 
 
 
} 
 
/*---------------------------------------------------------------------------- 
 
	FUNCTION		||	StreamURL 
 
	iError 			|| Error code 
 
-------------------------------DESCRIPTION----------------------------------- 
 
Stream and notify the request 
----------------------------------------------------------------------------*/ 
void ChHTTPInfo::StreamURL( ) 
{ 
	if ( !GetStreamMgr() ) 
	{ 
		return; 
	} 
 
 
	if ( GetThread() ) 
	{ 
		GetThread()->LockStream(); 
	} 
 
	m_httpStream.m_uStreamOption = GetStreamMgr()-> 
				NewStream(  GetUserData(), &m_httpStream, false ); 
 
 
 
	if ( 0 == GetError() ) 
	{ 
 		if ( m_httpStream.m_uStreamOption & ChHTTPStreamManager::streamNormal ) 
		{ 
 
			m_iStreamState = streamInData; 
			// Open the file 
			HANDLE hFile = ::CreateFile( 
							    GetFileName(),		// address of name of the file  
							    GENERIC_READ,	// access (read-write) mode  
							    FILE_SHARE_READ,// share mode  
							    NULL,			// address of security descriptor  
							    OPEN_EXISTING,	// how to create  
							    0,				// file attributes  
							    NULL			// handle of file with attributes to copy   
						   ); 
			if ( hFile != INVALID_HANDLE_VALUE ) 
			{ 
 
				DWORD  dwHigh, dwSize; 
 
				dwSize = ::GetFileSize( hFile, &dwHigh ); 
 
				if ( dwSize || dwHigh ) 
				{ 
					// Map if we have a good file 
					HANDLE hFileMap =  ::CreateFileMapping( 
								    			hFile,	// handle of file to map  
								      			NULL,	// optional security attributes  
								    			PAGE_READONLY | SEC_COMMIT,	// protection for mapping object  
								    			0,	// high-order 32 bits of object size   
								    			0,	// low-order 32 bits of object size   
								    			NULL 	// name of file-mapping object  
						   );	 
 
					ASSERT( hFileMap ); 
 
					char* pMappedView = (char*) MapViewOfFile( 
										    hFileMap,		// file-mapping object to map into address space   
										    FILE_MAP_READ,	// access mode  
										    0,	// high-order 32 bits of file offset  
										    0,	// low-order 32 bits of file offset  
										    0 	// number of bytes to map, 0 = Map the whole file 
						   ); 
					ASSERT( pMappedView ); 
	 
					chint32 offset = 0; 
					while ( offset < (chint32)dwSize && !IsAborted()  ) 
					{  // stream all data 
						// See if the plugin is ready 
						chint32 iReady =  GetStreamMgr()->WriteReady( GetUserData(), &m_httpStream, dwSize ); 
						if ( (offset + iReady) > (chint32)dwSize ) 
						{ 
							iReady = dwSize; 
						} 
 
						if ( iReady ) 
						{ 
							 GetStreamMgr()->Write( GetUserData(), &m_httpStream,   
							 						offset, iReady,	 pMappedView ); 
							offset += iReady; 
						} 
						else 
						{ 
							m_iError = CH_HTTP_ERROR_GENERIC; 
							break; 
						} 
 
					} 
					::UnmapViewOfFile( pMappedView ); 
					::CloseHandle( hFileMap ); 
				} 
				::CloseHandle( hFile ); 
			} 
			else 
			{ 
				m_iError = CH_HTTP_ERROR_OPEN_FILE; 
			} 
		} 
		// stream as file if requested 
		if ( m_httpStream.m_uStreamOption & ChHTTPStreamManager::streamAsFile ) 
		{ 
			GetStreamMgr()->StreamAsFile( GetUserData(),  
										&m_httpStream, GetFileName() );	 
		} 
	} 
 
	// close the stream 
	GetStreamMgr()->DestroyStream( GetUserData(), &m_httpStream, GetError() );	 
 
	m_iStreamState = streamDestroyed; 
	 
	if ( GetThread() ) 
	{ 
		GetThread()->UnlockStream(); 
	} 
} 
 
 
/////////////////////////////////////////////////////////////////////////////// 
/////////////  ChHTTPStream 
//////////// 
/////////////////////////////////////////////////////////////////////////////// 
 
ChHTTPConnStream::ChHTTPConnStream() : ChHTTPStream(), 
			m_pUserStreamData(0), 
			m_pHTTPInfo(0), 
 			m_uStreamOption(0) 
 
{ 
 
} 
const string& ChHTTPConnStream::GetURL() 
{ 
	return m_pHTTPInfo->GetURL(); 
} 
 
const string& ChHTTPConnStream::GetMimeType() 
{ 
	return m_pHTTPInfo->GetMimeType(); 
} 
 
const string& ChHTTPConnStream::GetCacheFilename() 
{ 
	return m_pHTTPInfo->GetFileName(); 
} 
 
const string& ChHTTPConnStream::GetContentEncoding() 
{ 
	return m_pHTTPInfo->GetTargetWindowName(); 
} 
 
const string& ChHTTPConnStream::GetLastModified() 
{ 
	return m_pHTTPInfo->GetLastModified(); 
} 
 
const string& ChHTTPConnStream::GetTargetWindowName() 
{ 
	return m_pHTTPInfo->GetTargetWindowName(); 
} 
 
long ChHTTPConnStream::GetContentLength() 
{ 
	return m_pHTTPInfo->GetDataLength(); 
} 
 
 
void* ChHTTPConnStream::GetStreamPrivateData() 
{ 
	return m_pUserStreamData;					 
} 
// Attributes 
void ChHTTPConnStream::SetStreamPrivateData( void *pData ) 
{ 
	m_pUserStreamData = pData; 
} 
 
const char* ChHTTPConnStream::GetErrorMsg() 
{ 
 
	char * pstrBuffer = m_pHTTPInfo->GetBuffer(); 
	if ( !m_pHTTPInfo->GetBufferSize()) 
	{ 
		pstrBuffer = new char[ 250 ]; 
		m_pHTTPInfo->SetBuffer( pstrBuffer ); 
		*pstrBuffer	= 0; 
	} 
 
	HINSTANCE hInst; 
	#if !defined(CH_PUEBLO_PLUGIN) 
	hInst = PuebloDLL.hModule; 
	#else 
	hInst = AfxGetInstanceHandle( ); 
	#endif 
 
 
	ASSERT( pstrBuffer ); 
 
	switch( m_pHTTPInfo->GetError() ) 
	{ 
		case CH_HTTP_ERROR_LOCAL_IN_USE :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_600, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_ABORT :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_601, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_CONNECT :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_602, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_SEND :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_603, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_INVALID_HDR :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_604, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_NOT_CACHED :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_605, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_USER_ABORT :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_606, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_INVALID_DATA :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_607, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_BAD_URL :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_608, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_OPEN_FILE :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_609, pstrBuffer, 250 ); 
			break; 
		} 
		case CH_HTTP_ERROR_GENERIC :		 
		{ 
			::LoadString( hInst, IDS_HTTP_ERR_610, pstrBuffer, 250 ); 
			break; 
		} 
		default : 
		{  // Buffer should contain the error message 
			if ( !pstrBuffer[0] ) 
			{ 
				::wsprintf( pstrBuffer, "HTTP error : %d", m_pHTTPInfo->GetError() ); 
			} 
		} 
	} 
	return pstrBuffer; 
}