vc實現https檔案下載

輕箬笠發表於2018-04-23

不多說廢話,直接上程式碼。

.h檔案

#pragma once
class CDownloadHttps
{
public:
	CDownloadHttps();
	~CDownloadHttps();

	static BOOL DownloadFile(std::wstring serverName, std::wstring objectName, std::wstring path);
};

.cpp檔案

#include "stdafx.h"
#include "DownloadHttps.h"
#include "windows.h"
#include "winhttp.h"

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

CDownloadHttps::CDownloadHttps()
{
}


CDownloadHttps::~CDownloadHttps()
{
}

BOOL CDownloadHttps::DownloadFile(std::wstring serverName, std::wstring objectName, std::wstring path)
{
	HINTERNET hOpen = 0;
	HINTERNET hConnect = 0;
	HINTERNET hRequest = 0;
	BOOL bResult = FALSE;

	do {
		hOpen = WinHttpOpen(_T("DownloadFile"), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
			WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
		if (!hOpen) {
			wprintf(L"WinHttpOpen failed (0x%.8X)\n", GetLastError());
			break;
		}
		hConnect = WinHttpConnect(hOpen, serverName.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0);
		if (!hConnect) {
			wprintf(L"WinHttpConnect failed (0x%.8X)\n", GetLastError());
			break;
		}
		// use flag WINHTTP_FLAG_SECURE to initiate SSL
		hRequest = WinHttpOpenRequest(hConnect, L"GET", objectName.c_str(),
			NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
		if (!hRequest)
		{
			wprintf(L"WinHttpOpenRequest failed (0x%.8X)\n", GetLastError());
			break;
		}
		if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
		{
			wprintf(L"WinHttpSendRequest failed (0x%.8X)\n", GetLastError());
			break;
		}
		if (!WinHttpReceiveResponse(hRequest, 0))
		{
			wprintf(L"WinHttpReceiveResponse failed (0x%.8X)\n", GetLastError());
			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 = _wtoi(szContentLength);

		BYTE Buffer[4096];
		HANDLE hFile = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
		if (hFile == INVALID_HANDLE_VALUE) {
			wprintf(L"CreateFile(%s) failed (0x%.8X)\n", path.c_str(), GetLastError());
			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);
		}
		CloseHandle(hFile);
		bResult = TRUE;
	} while (FALSE);

	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);
	if (hOpen) WinHttpCloseHandle(hOpen);

	return bResult;
}

參考了http://www.cppblog.com/zhupf/archive/2013/07/02/201459.aspx的內容,稍微改了下。轉載請註明出處。

相關文章