HTTP下载及URL验证

#include <WinInet.h>

#pragma comment(lib,"Wininet.lib")

BOOL ValidateURL( LPCTSTR lpURL, BOOL* bDomain )
{
	TCHAR HTTP[8] = {0};
	memcpy( HTTP, lpURL,  sizeof(HTTP) - 1 );
	HTTP[7] = 0;
	if( _tcsicmp( HTTP, _T("HTTP://")) != 0 )
		return FALSE;
	
	TCHAR* p = const_cast<TCHAR*>(lpURL) + 6;
	TCHAR* pCur = p + 1;
	int count = 0;
	BOOL bValid = FALSE;
	while( *p++ && count < 3 )
	{
		if( *p == _T('.') )
		{
			if( p - pCur > 3 )
				break;

			if( p - pCur == 3 )
			{ 
				if( *(pCur) > _T('2') ||
					*(pCur) < _T('1') )
					break;
				if( *(pCur + 1) > _T('9') ||
					*(pCur + 1) < _T('0') )
					break;
				if( *(pCur + 2) > _T('9') ||
					*(pCur + 2) < _T('0') )
					break;
			}

			if( p - pCur == 2 )
			{ 
				if( *(pCur) > _T('9') ||
					*(pCur) < _T('1') )
					break;
				if( *(pCur + 1) > _T('9') ||
					*(pCur + 1) < _T('0') )
					break;
			}

			if( p - pCur == 1 )
			{ 
				if( *(pCur) > _T('9') ||
					*(pCur) < _T('0') )
					break;
			}
			pCur = p + 1;
			++count;
			if( count == 3 )
			{
				if( *(p + 1) == _T(':') )
					break;
				else if( *(p + 2) == _T(':') )
				{
					if( *(p + 1) > _T('9') ||
						*(p + 1) < _T('0') )
						break;
					bValid = TRUE;
				}
				else if( *(p + 3) == _T(':') )
				{
					if( *(p + 1) > _T('9') ||
						*(p + 1) < _T('1') )
						break;
					if( *(p + 2) > _T('9') ||
						*(p + 2) < _T('0') )
						break;		
					bValid = TRUE;
				}
				else if( *(p + 4) == _T(':') )
				{
					if( *(p + 1) > _T('2') ||
						*(p + 1) < _T('1') )
						break;
					if( *(p + 2) > _T('9') ||
						*(p + 2) < _T('0') )
						break;
					if( *(p + 3) > _T('9') ||
						*(p + 3) < _T('0') )
						break;
					bValid = TRUE;
				}
				else
					break;
			}
		}
	}
	p = const_cast<TCHAR*>(lpURL) + 6;
	
	bool bOK = FALSE;
	while( *p++ && count < 3 && !bValid )
	{
		if( *p == _T(':') )
		{
			TCHAR* pPort = p + 1;
			while( *p++ )
			{
				if( *p == _T('/') )
				{
					if( pPort - p > 6 )
					{
						bOK = FALSE;
					}
					else
					{		
						bOK = TRUE;
						int bitPort = p - pPort;
						for( int i = 0; i < bitPort; ++i )
						{
							if( *(pPort + i) < _T('0') &&
								*(pPort + i) > _T('9') )
							{
								bOK = FALSE;
								break;
							}
						}
						if( bOK )
						{
							TCHAR* pPortData = new TCHAR[bitPort + 1];
							pPortData[bitPort] = 0;
							CopyMemory( pPortData, pPort, bitPort * sizeof(TCHAR) );

							int port = _wtoi( pPortData );
							delete[] pPortData;
							if( port >= 0xFFFF )
							{
								bOK = FALSE;
							}
						}
					}
					break;
				}
			}
			break;
		}
	}
	if( bOK )
		*bDomain = TRUE;

	if( !bValid )
		return FALSE;
	if( count != 3 )
		return FALSE;
	return TRUE;
}

void PostData( LPCTSTR lpURL, LPCTSTR lpFileName )
{
	BOOL bDomain = FALSE;	
	BOOL bIp = FALSE;
	if( !ValidateURL( lpURL, &bDomain ) )
	{
		if( bDomain == FALSE )
			return;
	}
	else
		bIp = TRUE;
		
	HINTERNET hInternet, hConnect, hRequest;
	BOOL bRet;
	int  iResult = 0;
	char cReadBuffer[BUF_SIZE];
	DWORD lNumberOfBytesRead;

	const TCHAR *pColon = _tcsrchr( lpURL, _T(':') );
	int num =(DWORD)pColon - (DWORD)lpURL - 6 * sizeof(TCHAR);
	TCHAR* pHost = NULL;
	
	pHost = new TCHAR[num];
	ZeroMemory( pHost, num);
	//跳过"HTTP://"
	memcpy( pHost, lpURL + 7, num - sizeof(TCHAR) );
	
	if( !bIp )
	{
		int len = WideCharToMultiByte( CP_ACP, 0, pHost, -1, NULL, 0, NULL, NULL );
		char* pszUrl = new char[len];
		WideCharToMultiByte( CP_ACP, 0, pHost, -1, pszUrl, len, NULL, NULL );
		delete[] pHost;
		pHost = new TCHAR[16];
	
		WORD wVersionRequested = MAKEWORD( 2, 1 );
		WSADATA wsaData;
		WSAStartup( wVersionRequested, &wsaData );
		hostent* pHostAddr = gethostbyname( pszUrl );
		delete[] pszUrl;
		WSACleanup();
	
		if( pHostAddr == NULL )
		{
			delete[] pHost;
		}
		else
			_stprintf( pHost, _T("%d.%d.%d.%d"),
				(pHostAddr->h_addr_list[0][0]&0x00ff),
				(pHostAddr->h_addr_list[0][1]&0x00ff),
				(pHostAddr->h_addr_list[0][2]&0x00ff),
				(pHostAddr->h_addr_list[0][3]&0x00ff));
	}
	TCHAR* p = const_cast<TCHAR*>(pColon);
	while( *(p++) != _T('/') && *p != 0 );
	num = p - pColon;

	TCHAR* pPort = new TCHAR[num];
	ZeroMemory( pPort, num * sizeof(TCHAR) );
	memcpy( pPort, pColon + 1, (num - 2) * sizeof(TCHAR) ); 

	TCHAR *pRequest = const_cast<TCHAR*>(pColon);
	while( *pRequest != '/' && *pRequest != 0 )
	{
		pRequest++;
	}
	
	do 
	{
		//打开环境
		hInternet = InternetOpen(_T("User-Agent"),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);

		if( hInternet == NULL )
			break;
		//连接
		hConnect = InternetConnect( hInternet, pHost, _wtoi(pPort), NULL, 
			_T("HTTP/1.1"), INTERNET_SERVICE_HTTP, 0, 0 );
		
		if( hConnect == NULL )
			break;
		//打开请求句柄	
		
		hRequest = HttpOpenRequest( hConnect, _T("POST"),
			pRequest,
			_T("HTTP/1.1"), NULL, NULL, INTERNET_FLAG_RELOAD, 0 );
		
		if( hRequest == NULL )
			break;

		FILE *pFile = _tfopen( lpFileName, _T("rb") );
		fseek( pFile, 0, SEEK_END );
		int file_length = ftell( pFile );
		fseek( pFile, -file_length, SEEK_END );
		char* pData = new char[file_length];
		fread( pData, 1, file_length, pFile );

		int convert_length = MultiByteToWideChar( CP_ACP, 0, pData, file_length, NULL, 0 );
		wchar_t* pConvertData = new wchar_t[convert_length];
		MultiByteToWideChar( CP_ACP, 0, pData, file_length, pConvertData, convert_length );
		int new_length = WideCharToMultiByte( CP_UTF8, 0, pConvertData, convert_length, NULL, 0, NULL, NULL );
		char* pNewData = new char[new_length];
		WideCharToMultiByte( CP_UTF8, 0, pConvertData, convert_length, pNewData, new_length, NULL, NULL );

		HttpSendRequest( hRequest, NULL, 0, pNewData, new_length );

		delete[] pNewData;
		delete[] pConvertData;
		delete[] pData;

		fclose( pFile );

		FILE * fp = NULL;
		fp = _tfopen( lpFileName, _T("wb") );	

		while( TRUE )
		{
			bRet = InternetReadFile( hRequest, cReadBuffer, sizeof(cReadBuffer) - 1, &lNumberOfBytesRead );
			if( bRet )
			{
				if( lNumberOfBytesRead == 0 )
					break;
				else
				{
					cReadBuffer[lNumberOfBytesRead] = 0;
					fwrite( cReadBuffer, lNumberOfBytesRead, 1, fp );
				}
			}
		}
		fclose(fp);
	} while (FALSE);

	delete[] pHost;
	delete[] pPort;

	if( hRequest )
		InternetCloseHandle( hRequest );
	if( hConnect )
		InternetCloseHandle( hConnect );
	if( hInternet )
		InternetCloseHandle( hInternet );
}
原文地址:https://www.cnblogs.com/LinuxHunter/p/1890716.html