VC++ 使用https下载文件

BOOL CMyMFCDlg::DownloadFile(const wchar_t*  serverName, const wchar_t*  objectName,const char * path)
{
	if (NULL == serverName || NULL == objectName || NULL == path)
	{
         MessageBox("parameter is null ");
		 return FALSE;
	}
	HINTERNET hOpen = 0;
	HINTERNET hConnect = 0;
	HINTERNET hRequest = 0;
	BOOL bResult = FALSE;
	TCHAR buffer[BUFFER_LEN];
	ZeroMemory(buffer,BUFFER_LEN);
	int tmp = 0;
	do {
		hOpen = WinHttpOpen(NULL,
			WINHTTP_ACCESS_TYPE_NO_PROXY,
			WINHTTP_NO_PROXY_NAME,
			WINHTTP_NO_PROXY_BYPASS,
			0);
		if (!hOpen) 
		{
			wprintf(L"WinHttpOpen failed (0x%.8X)\n", GetLastError());
			MessageBox("WinHttpOpen failed");
			break;
		}

		// Specify an HTTP server.
		hConnect = WinHttpConnect(hOpen, 
			serverName,  //不要加http:// 
			INTERNET_DEFAULT_HTTPS_PORT, //INTERNET_DEFAULT_HTTPS_PORT
			0);
		tmp = GetLastError();
		if (!hConnect) 
		{
	        ZeroMemory(buffer,BUFFER_LEN);
			StringCchPrintf(buffer,BUFFER_LEN-1,"WinHttpConnect failed (%d)",tmp);
			MessageBox(buffer);
			break;
		}
		// use flag WINHTTP_FLAG_SECURE to initiate SSL
		hRequest = WinHttpOpenRequest(hConnect, 
			L"GET", 
			objectName,
			NULL, 
			WINHTTP_NO_REFERER,
			WINHTTP_DEFAULT_ACCEPT_TYPES, 
			WINHTTP_FLAG_SECURE);
		if (!hRequest)
		{
			wprintf(L"WinHttpOpenRequest failed (0x%.8X)\n", GetLastError());
			MessageBox("WinHttpOpenRequest failed");
			break;
		}

		//以下几行在https的下载中一定要加,否则WinHttpSendRequest 会出现12175的错误
		DWORD dwFlags;
		DWORD dwBuffLen = sizeof(dwFlags);           
		WinHttpQueryOption (hRequest, WINHTTP_OPTION_SECURITY_FLAGS,
			(LPVOID)&dwFlags, &dwBuffLen);
		dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
		dwFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
		dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;	
		WinHttpSetOption (hRequest, WINHTTP_OPTION_SECURITY_FLAGS,
        &dwFlags, sizeof (dwFlags) );

		
        
		BOOL ret = FALSE;
		ret = WinHttpSendRequest(hRequest, 
			WINHTTP_NO_ADDITIONAL_HEADERS,
			0, 
			WINHTTP_NO_REQUEST_DATA, 
			0,
			0, 
			0);
		tmp = GetLastError();
		if (!ret)
		{
			wprintf(L"WinHttpSendRequest failed (0x%.8X)\n", GetLastError());
			ZeroMemory(buffer,BUFFER_LEN);
			StringCchPrintf(buffer,BUFFER_LEN-1,"WinHttpSendRequest failed (%d)",tmp);
			MessageBox(buffer);
			break;
		}

		ret = WinHttpReceiveResponse(hRequest, 0);
		tmp = GetLastError();
		if (!ret)
		{
			wprintf(L"WinHttpReceiveResponse failed (0x%.8X)\n", GetLastError());
			ZeroMemory(buffer,BUFFER_LEN);
			StringCchPrintf(buffer,BUFFER_LEN-1,"WinHttpReceiveResponse failed (%d)",tmp);
			MessageBox(buffer);
			break;
		}
		// query remote file size, set haveContentLength on success and dwContentLength to the length
		TCHAR szContentLength[32] = { 0 };
		DWORD cch = 64;
		DWORD dwHeaderIndex = WINHTTP_NO_HEADER_INDEX;
		BOOL haveContentLength = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH, NULL,
			&szContentLength, &cch, &dwHeaderIndex);
		DWORD dwContentLength;
		if (haveContentLength) 
            dwContentLength = strtol(szContentLength,NULL,10);
		
		BYTE Buffer[4096];
		HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
		if (hFile == INVALID_HANDLE_VALUE) {
			wprintf(L"CreateFile(%s) failed (0x%.8X)\n", path, GetLastError());
			MessageBox("CreateFile failed");
			break;
		}
		
		DWORD dwSize, dwWrite;
		while (WinHttpQueryDataAvailable(hRequest, &dwSize) && dwSize) {
			//if (dwSize > 4096) dwSize = 4096;
			
			WinHttpReadData(hRequest, Buffer, dwSize, &dwSize);
			WriteFile(hFile, Buffer, dwSize, &dwWrite, NULL);
            ZeroMemory(Buffer,4096);
		}
		CloseHandle(hFile);
		bResult = TRUE;
	} while (FALSE);
	
	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);
	if (hOpen) WinHttpCloseHandle(hOpen);
	
	return bResult;
}

调用

   wchar_t *p = L"www.xxx.com";
   DownloadFile(p,L"com/com.zip","D:/com.zip");

参考链接:https://blog.csdn.net/housecarl/article/details/80049962

你可能感兴趣的:(VC++ 使用https下载文件)