⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myhttpclient.cpp

📁 自定义HttpClient类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}

	return szUni ;
}

// comparison function (used by STL multimap)
bool CHttpToolA::operator () (LPCSTR szKey1, LPCSTR szKey2) const
	throw ()
{
	// return true if the two strings are null
	if ( szKey1 == NULL && szKey2 == NULL )
		return true ;

	if ( szKey1 == NULL )
		return true ;

	if ( szKey2 == NULL )
		return false ;

	// case insensitive
	return ::stricmp (szKey1, szKey2) < 0 ;
}

// Initializes a internet handle.
HINTERNET CHttpToolA::OpenInternet (LPCSTR szUserAgent, DWORD dwAccessType
									, LPCSTR szProxyName, LPCSTR szProxyBypass, DWORD dwFlags)
	throw (Exception &)
{
	HINTERNET		hInternet ;

	if ( NULL == (hInternet = ::InternetOpenA (
			szUserAgent				// user agent
			, dwAccessType			// use direct connection or proxy connection
			, szProxyName
			, szProxyBypass
			, dwFlags)
		) )
		ThrowException (HTTPCLIENT_ERR_INTERNETOPEN_FAILED, ::GetLastError ()) ;

	return hInternet ;
}

// Closes a internet handle
void CHttpToolA::CloseInternet (HINTERNET & hInternet)
	throw ()
{
	if ( hInternet == NULL )
		return ;

	// Ignore any errors while closing the handle
	::InternetCloseHandle (hInternet) ;
	hInternet = NULL ;
}

// Returns a connection handle
// The hInternet must be a valid internet handle.
HINTERNET CHttpToolA::OpenConnection (HINTERNET hInternet, LPCSTR szServerAddr, INTERNET_PORT nPort
											, LPCSTR szUsrName, LPCSTR szUsrPwd)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hInternet != NULL, "CHttpToolA::OpenConnection: hInternet can not be NULL.") ;
	HTTPTOOL_ASSERT (szServerAddr != NULL, "CHttpToolA::OpenConnection: szServerAddr can not be NULL.") ;
	HTTPTOOL_ASSERT (::strlen (szServerAddr) != 0, "CHttpToolA::OpenConnection: szServerAddr can not be an empty string.") ;

	HINTERNET			hConnection ;

	if ( NULL == (hConnection = ::InternetConnectA (
			hInternet
			, szServerAddr
			, nPort
			, szUsrName
			, szUsrPwd
			, INTERNET_SERVICE_HTTP
			, 0
			, NULL)
		) )
		ThrowException (HTTPCLIENT_ERR_INTERNETCONNECT_FAILED, ::GetLastError ()) ;

	return hConnection ;
}

// Closes a connection handle
void CHttpToolA::CloseConnection (HINTERNET & hConnection)
	throw ()
{
	if ( hConnection == NULL )
		return ;

	// Ignore any errors while closing the handle
	::InternetCloseHandle (hConnection) ;
	hConnection = NULL ;
}

// Returns a HTTP request handle
HINTERNET CHttpToolA::OpenRequest (HINTERNET hConnection, LPCSTR szMethod, LPCSTR szObjectName
										 , DWORD dwFlags, LPCSTR szReferer, UINT /* CodePage */)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hConnection != NULL, "CHttpToolA::OpenRequest: hConnection can not be NULL.") ;
	HTTPTOOL_ASSERT (szObjectName != NULL, "CHttpToolA::OpenRequest: szObjectName can not be NULL.") ;
	HTTPTOOL_ASSERT (::strlen (szObjectName) != 0, "CHttpToolA::OpenRequest: szObjectName can not be an empty string.") ;

	static LPCSTR			szAcceptedType[] = {
		"*/*"
		, NULL
	} ;

	HINTERNET		hRequest = NULL ;

	// Opens a HTTP request handle
	if ( NULL == (hRequest = ::HttpOpenRequestA (
			hConnection
			, szMethod				// HTTP Method
			, szObjectName			// Target object
			, "HTTP/1.1"			// HTTP/1.1
			, szReferer				// referer
			, szAcceptedType		// Accepts any type.
			, dwFlags				// Flags
			, NULL					// Doesn't use any context value.
			)
		) )
		ThrowException (HTTPCLIENT_ERR_HTTPOPENREQUEST_FAILED, ::GetLastError ()) ;

	return hRequest ;
}

// Closes a request handle
void CHttpToolA::CloseRequest (HINTERNET & hRequest)
	throw ()
{
	if ( hRequest == NULL )
		return ;

	// Ignore any errors while closing the handle
	::InternetCloseHandle (hRequest) ;
	hRequest = NULL ;
}

void CHttpToolA::AddHeader (HINTERNET hRequest, LPCSTR szName, LPCSTR szValue, UINT /* CodePage */)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::AddHeader: hRequest can not be NULL.") ;
	HTTPTOOL_ASSERT (szName != NULL, "CHttpToolA::AddHeader: szName can not be NULL.") ;

	::SafeInt<size_t>		cbHeader ;
	::SafeInt<DWORD>		cchHeader ;

	try {
		cbHeader = ::strlen (szName) ;
		cbHeader += szValue ? ::strlen (szValue) : 0 ;
		cbHeader += (4 + 1) ;	// for ": ", "\r\n", '\0'
		cchHeader = cbHeader - 1 ;
	} catch (::SafeIntException & e) {
		ThrowException (e) ;
	}

	PSTR		szHeader = (PSTR) ::malloc (sizeof (CHAR) * (cbHeader.Value ())) ;
	if ( szHeader == NULL )
		ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;

	::strcpy (szHeader, szName) ;
	::strcat (szHeader, ": ") ;
	::strcat (szHeader, szValue ? szValue : "") ;
	::strcat (szHeader, "\r\n") ;

	// Adds a header
	if ( !::HttpAddRequestHeadersA (
			hRequest
			, szHeader								// headers to append to the request.
			, cchHeader.Value ()					// header length
			, HTTP_ADDREQ_FLAG_ADD					// flags
			)
		) {
		SAFEFREE (szHeader) ;
		ThrowException (HTTPCLIENT_ERR_HTTPADDREQUESTHEADERS_FAILED, ::GetLastError ()) ;
	}

	SAFEFREE (szHeader) ;
}

void CHttpToolA::SendRequest (HINTERNET hRequest, LPCSTR szPosted, UINT /* CodePage */)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::SendRequest: hRequest can not be NULL.") ;

	::SafeInt<DWORD>	cchPosted ;

	try {
		cchPosted = szPosted ? ::strlen (szPosted) : 0 ;
	} catch (::SafeIntException & e) {
		ThrowException (e) ;
	}

	if ( !::HttpSendRequestA (
			hRequest
			, NULL						// Additional header
			, 0							// The length of the additional header
			, (void *) szPosted			// A posted data
			, cchPosted.Value ()		// The length of the posted data
		) )
		ThrowException (HTTPCLIENT_ERR_HTTPSENDREQUEST_FAILED, ::GetLastError ()) ;
}

void CHttpToolA::SendRequestEx (HINTERNET hRequest, DWORD dwPostedSize)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::SendRequestEx: hRequest can not be NULL.") ;

	INTERNET_BUFFERSA BufferIn;

	BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
    BufferIn.Next = NULL; 
    BufferIn.lpcszHeader = NULL;
    BufferIn.dwHeadersLength = 0;
    BufferIn.dwHeadersTotal = 0;
    BufferIn.lpvBuffer = NULL;                
    BufferIn.dwBufferLength = 0;
    BufferIn.dwBufferTotal = dwPostedSize; // This is the only member used other than dwStructSize
    BufferIn.dwOffsetLow = 0;
    BufferIn.dwOffsetHigh = 0;

	if ( !::HttpSendRequestExA (
			hRequest
			, &BufferIn
			, NULL
			, 0
			, 0
		) )
		ThrowException (HTTPCLIENT_ERR_HTTPSENDREQUESTEX_FAILED, ::GetLastError ()) ;
}

void CHttpToolA::InternetWriteFile (HINTERNET hRequest, const BYTE * pbyBuff, DWORD cbyBuff)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::InternetWriteFile: hRequest can not be NULL.") ;
	HTTPTOOL_ASSERT (pbyBuff != NULL, "CHttpToolA::InternetWriteFile: pbyBuff can not be NULL.") ;
	HTTPTOOL_ASSERT (cbyBuff != 0, "CHttpToolA::InternetWriteFile: cbyBuff can not be zero.") ;

	DWORD		dwTotalWritten = 0, dwWritten ;

	while ( dwTotalWritten < cbyBuff ) {
		if ( !::InternetWriteFile (
							hRequest
							, pbyBuff + dwTotalWritten
							, cbyBuff - dwTotalWritten
							, &dwWritten
				)
			)
			ThrowException (HTTPCLIENT_ERR_INTERNETWRITEFILE_FAILED, ::GetLastError ()) ;

		dwTotalWritten += dwWritten ;
	}
}

void CHttpToolA::EndRequest (HINTERNET hRequest)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::EndRequest: hRequest can not be NULL.") ;

	if ( !::HttpEndRequest (
						hRequest
						, NULL
						, 0
						, 0
			)
		)
		ThrowException (HTTPCLIENT_ERR_HTTPENDREQUEST_FAILED, ::GetLastError ()) ;
}

// Checks whether the file exists.
// (Does not throw an exception)
BOOL CHttpToolA::FileExists (LPCSTR szFilePath)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::FileExists: szFilePath can not be NULL.") ;
	
	HANDLE		hFile = ::CreateFileA (
							szFilePath
							, 0
							, FILE_SHARE_READ
							, NULL
							, OPEN_EXISTING
							, FILE_ATTRIBUTE_NORMAL
							, NULL) ;

	if ( hFile != INVALID_HANDLE_VALUE )
	{
		::CloseHandle (hFile) ;
		return TRUE ;
	}

	return FALSE ;
}

// It returns a INVALID_HANDLE_VALUE if the specified file is not valid.
// (Does not throw an exception)
HANDLE CHttpToolA::OpenFile (LPCSTR szFilePath)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::OpenFile: szFilePath can not be NULL.") ;

	return ::CreateFileA (
			szFilePath
			, GENERIC_READ
			, FILE_SHARE_READ
			, NULL
			, OPEN_EXISTING
			, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN
			, NULL) ;
}

// If it fails to create an file, it will return INVALID_HANDLE_VALUE.
// (Does not throw an exception)
HANDLE CHttpToolA::CreateFileAlwaysToWrite (LPCSTR szFilePath)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::CreateFileAlwaysToWrite: szFilePath can not be NULL.") ;

	return ::CreateFileA (
			szFilePath
			, GENERIC_WRITE
			, 0
			, NULL
			, CREATE_ALWAYS
			, FILE_ATTRIBUTE_NORMAL
			, NULL) ;
}




DWORD CHttpToolA::GetFileSize (HANDLE hFile, LPCSTR szFilePath)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hFile != NULL, "CHttpToolA::GetFileSize: hFile can not be NULL.") ;
	HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::GetFileSize: szFilePath can not be NULL.") ;

	DWORD		dwFileSize = ::GetFileSize (hFile, NULL) ;
	if ( dwFileSize == INVALID_FILE_SIZE )
		ThrowException (HTTPCLIENT_ERR_GETFILESIZE_FAILED, ::GetLastError (), szFilePath) ;

	return dwFileSize ;
}

// The file handle must point to BOF. If the file handle is INVALID_HANDLE_VALUE
// The default mime type is returned.
// The returned string must be freed by using the ::free () function.
LPSTR CHttpToolA::GetMimeType (HANDLE hFile, UINT CodePage)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hFile != NULL, "CHttpToolA::GetMimeType: hFile can not be NULL.") ;

	LPSTR		szMimeType = NULL ;
	try {
		szMimeType = CHttpToolW::GetMimeType (hFile, CodePage) ;
	} catch (CHttpToolW::Exception & e) {
		ThrowException (e) ;
	}

	return szMimeType ;
}

// Returns the HTTP status text from the HTTP request handle.
// The returned string must be freed by using the ::free () function.
LPSTR CHttpToolA::GetStatusText (HINTERNET hRequest)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::GetStatusText: hRequest can not be NULL.") ;

	DWORD			cbBuff = 0 ;
	LPSTR			szStatusText = NULL ;

	// Get required buffer size
	if ( !::HttpQueryInfoA (
			hRequest
			, HTTP_QUERY_STATUS_TEXT 		// Get the status text
			, static_cast<void *> (szStatusText)
			, &cbBuff						// Required buffer size (byte)
			, NULL							// Don't use a header index
			)
		)
		if ( ::GetLastError () != ERROR_INSUFFICIENT_BUFFER )
			ThrowException (HTTPCLIENT_ERR_QUERYINFO_FAILED, ::GetLastError ()) ;

	_ASSERTE ( cbBuff != 0 ) ;

	szStatusText = (LPSTR) ::malloc (cbBuff) ;
	if ( szStatusText == NULL )
		ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;

	// Get the status text
	if ( !::HttpQueryInfoA (
			hRequest
			, HTTP_QUERY_STATUS_TEXT 		// Get the status text
			, static_cast<void *> (szStatusText)
			, &cbBuff						// Allocated buffer size (byte)
			, NULL							// Don't use a header index
			)
		) {
		::free (szStatusText) ;
		ThrowException (HTTPCLIENT_ERR_QUERYINFO_FAILED, ::GetLastError ()) ;
	}

	return szStatusText ;
}

// Get the HTTP header which has the name specified by szName from the HTTP request handle.
// If the header is not found, NULL is returned.
// The returned string must be freed by using the ::free () function.
// pnIdx exactly corresponds to the lpdwIndex parameter in the ::HttpQueryInfo function.
// For more information about this parameter, see microsoft's SDK documentation.
LPSTR CHttpToolA::GetHeader (HINTERNET hRequest, LPCSTR szName, DWORD * pnIdx)
	throw (Exception &)
{
	HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::GetHeader: hRequest can not be NULL.") ;
	HTTPTOOL_ASSERT (szName != NULL, "CHttpToolA::GetHeader: szName can not be NULL.") ;

	DWORD			nOrigIdx = 0 ;
	if ( pnIdx )	nOrigIdx = *pnIdx ;

	// Copy the header name
	::SafeInt<DWORD>	cbBuff ;
	try {
		cbBuff = ::strlen (szName) ;
		cbBuff++ ;
		cbBuff *= sizeof (CHAR) ;
	} catch (::SafeIntException & e) {
		ThrowException (e) ;
	}

	PSTR		szHeader = (PSTR) ::malloc (cbBuff.Value ()) ;
	if ( szHeader == NULL )
		ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;
	::strcpy (szHeader, szName) ;

	if ( ::HttpQueryInfoA (
			hRequest
			, HTTP_QUERY_CUSTOM				// Get a custom header
			, static_cast<void *> (szHeader)
			, cbBuff.Ptr ()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -