1. 程式人生 > >WinHttp支援HTTPS下載

WinHttp支援HTTPS下載

#include "windows.h"
#include "winhttp.h"
#include "wchar.h"
#pragma comment(lib,"Winhttp.lib")
// SSL (Secure Sockets Layer) example
// compile for console
void main()
{
	HINTERNET hOpen = 0;
	HINTERNET hConnect = 0;
	HINTERNET hRequest = 0;
	IStream *stream = NULL;
	HRESULT hr;
	while (1)
	{
		hOpen = WinHttpOpen(L"Aurora Console App", 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, L"raw.github.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
		if (!hConnect) {
			wprintf(L"WinHttpConnect failed (0x%.8X)\n", GetLastError());
			break;
		}
		LPCWSTR types[2];
		types[0] = L"text/html";
		types[1] = 0;
		// use flag WINHTTP_FLAG_SECURE to initiate SSL
		hRequest = WinHttpOpenRequest(hConnect, L"GET", L"zpfzzz/test/master/README.md",
				NULL, WINHTTP_NO_REFERER, &types[0], 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
		wchar_t szContentLength[32];
		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);
		// read the response into memory stream
		hr = CreateStreamOnHGlobal(0, true, &stream);
		if (hr) {
			wprintf(L"CreateStreamOnHGlobal failed (0x%.8X)\n", hr);
			break;
		}
		// allocate buffer for streaming received data
		char *p = new char[4096];
		if (!p)
		{
			wprintf(L"failed to allocate buffer\n");
			break;
		}
		// to receive all data, we need to enter a loop
		DWORD dwReceivedTotal = 0;
		while (WinHttpQueryDataAvailable(hRequest, &cch) && cch)
		{
			if (cch > 4096) cch = 4096;
			dwReceivedTotal += cch;
			// display number of received bytes
			if (haveContentLength)
			{
				wprintf(L"received %d of %d (%d%%)%c", dwReceivedTotal, dwContentLength, 
					dwReceivedTotal*100/dwContentLength, 13);
			}
			else {
				wprintf(L"received %d (unknown length)%c", dwReceivedTotal, 10);
			}
			WinHttpReadData(hRequest, p, cch, &cch);
			// write into stream
			hr = stream->Write(p, cch, NULL);
			if (hr)
			{
				wprintf(L"failed to write data to stream (0x%.8X)\n", hr);
			}
		}
		delete [] p;
		wprintf(L"\n\nreceived all data.\n");
		// terminate the sream with a NULL
		p = NULL;
		stream->Write(&p, 1, NULL);
		// get pointer to stream bytes
		wprintf(L"getting HGLOBAL from stream...\n");
		HGLOBAL hgl;
		hr = GetHGlobalFromStream(stream, &hgl);
		if (hr) {
			wprintf(L"GetHGlobalFromStream failed (0x%.8X)\n", hr);
			break;
		}
		wprintf(L"locking memory...\n");
		p = (char*)GlobalLock(hgl);
		if (!p)
		{
			wprintf(L"GlobalLock failed (0x%.8X)\n", GetLastError());
			break;
		}
		wprintf(L"displaying received data...\n");
		// terminate the string at 1024 bytes (MessageBox lag)
		//if (dwReceivedTotal > 1024) dwReceivedTotal = 1024;
		//*p[dwReceivedTotal] = 0;
		MessageBoxA(0, p, "", 0);
		GlobalUnlock(hgl);
		break;
	}
	// delete stream and close handles
	if (stream) stream->Release();
	if (hRequest) WinHttpCloseHandle(hRequest);
	if (hConnect) WinHttpCloseHandle(hConnect);
	if (hOpen) WinHttpCloseHandle(hOpen);
	system("pause");
}