WinHttp支持HTTPS下载

VC++ MFC环境下基于WinHTTP的HTTP/HTTPS文件传输工具封装实践 HTTP/HTTPS协议是现代网络通信的基石,它定义了客户端与服务器之间请求与响应的标准格式。其核心原理基于TCP连接,通过请求方法、状态码和头部字段等机制实现资源传输。在工程实践中,稳定高效的文件传输功能对许多桌面应用至关重要,尤其是在需要处理大文件或与远程服务器交互的场景中。针对VC++与MFC这类经典Windows桌面开发技术栈,直接使用底层WinHTTP API进行文件上传下载往往涉及复杂的连接管理、SSL/TLS握手、分块读写和错误处理。本文介绍的工具通过封装WinHTTP,提供了面向MFC环境的 阅读详情
#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");
}

MFC项目中基于WinHTTP的HTTP/HTTPS文件传输工具类封装实战 在Windows桌面应用开发中,文件传输是常见的功能需求,尤其是在维护基于MFC框架的遗留系统时。HTTP/HTTPS协议作为互联网通信的基础,其核心原理涉及客户端与服务器的请求-响应模型。通过WinHTTP API,开发者可以在不依赖第三方库的情况下,实现稳定可控的网络通信,这对于保证项目兼容性和降低重构风险具有重要技术价值。在工业控制上位机、企业内部工具等应用场景中,常需处理大文件上传下载HTTPS证书验证及实时进度反馈等具体问题。本文聚焦于MFC生态,深入探讨如何封装一个高效、易用的文件传输工具类, 阅读详情

相关推荐

基于易语言的HTTPS多任务高速下载模块实战

在构建多任务并发系统时,首要任务是建立清晰的任务模型。每一个下载任务都应被封装为一个独立的对象实例,具备明确的数据属性和行为特征。这样的抽象不仅能提升代码的可读性与复用性,也为后续的调度、监控与持久化提供了基础支撑。易语言对Windows操作系统原生线程(Win32 Thread)进行了高度封装,使得开发者无需直接操作复杂且易错的C/C++风格线程API即可实现并发逻辑。然而,这种“低门槛”也带来了对底层机制理解不足的风险。因此,在进入编码实践前,必须准确掌握易语言提供的线程接口及其运行原理。

weixin_35826166的博客 565

fiddler支持https协议

fiddler最新版本,支持最新的https,http协议等等,,,,

易语言-鱼刺类_HTTP v5.27模块

鱼刺类_HTTP v5.27 * WinHttpR 为 WinHttpRequest5.1 COM对象(推荐) * WinHttpW 为 WinHttpApi封装 (HTTP6.0即将从新崛起 比如:解决资源延迟收回导致多线程内存一直在涨 解决在一些情况下会崩溃的问题) * WinInet 为 WinInternet 封装 特别说明: *参考了很多相关代码,完美封装而成。并经过测试和改进了很多微软本身留下的坑。无论是效率上还是稳定性上,不服来战! *本次设计目的并非作为私人使用。所以命名没有采用前缀鱼刺标识。就是想出点货!`(+﹏+)′ *封装命名习惯完全参照了WinHttpRequest。一些新手可能看着费劲(其实就是 Open Send 完事)但建议新手还是习惯下这样的面向对象调用方式。 对以后的开发思维有很大帮助。 *封装了三种不同的网页访问类库,可满足不同环境下的需求。 *Auto模式:可自动补全必要协议头。(无需每次访问都添加一次常用协议头) *AutoCookies模式:自动智能合并Cookie到内部,并可以自由灵活管理Cookies。(取/设/增/删/改)

WinHttp正确下载https文件方法带client证书

WinHttp下载https文件带client证书

如鹿渴慕泉水的专栏 2693

Nginx实现https-文件下载服务器

一、 功能描述 1、 Nginx作为web中间件,可以为我们提供文件下载功能,实现访问强制下载文件。 2、 为nginx实现https,需要我们修改nginx端口,并利用openssl自签证书即可。 3、 准备:nginx服务器一台、域名一个。 二、 实施步骤 1、 实现文件下载功能 Nginx支持文件下载功能,可作为文件下载服务器。只需在server下,定义好根目录,并将文件放在其目录下...

m0_37699444的博客 8021

网络资源下载方式:http/https、ftp/sftp、BT种子、磁力下载、ed2k下载等的区别

http/https、ftp/sftp、BT种子、磁力下载

zhangyifeng_1995的博客 1万+

Android如何通过https协议下载自己的https网站上的文件/apk等

我的服务器端是用Centos6.4+apache搭建的httpsweb

abcdefh123的专栏 6702

鱼刺 winhttp

winhttp com 对象 网页_访问_对象 api wininet 网页访问 下划线命名法 驼峰命名法 小驼峰 JS内置的一些       大驼峰 api 多线程用 coinitialize(0) ’com对象 如果在多线程中使用,必须初始化com库和取消com库 鱼刺 winhttpR com对象 win...

weixin_34324081的博客 1087

winhttp 访问https_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 consolevoid main(){HINTERNET hOpen = 0;H...

weixin_39823676的博客 358

WinHTTP实现文件下载 C++程序

逗是简单粗暴的用C++写的使用WinHTTP实现文件下载,不再被PowerShell安全策略支配(执行*.ps1脚本却忘记修改PowerShell的安全策略允许运行脚本)

这真是有意义的一天啊! 1860

HTTP请求网页(包括HTTPS)

借鉴了网上的,忘记是在哪里看到的了。 增加了对HTTPS支持。用到了MFC的CString,可以自行修改无需MFC。直接贴代码: WebClient.h: #pragma once #include <Windows.h> #include <winhttp.h> #pragma comment(lib, "Winhttp.lib") #i...

amsnkjc13870的博客 376

轻量小巧http框架http库支持https

轻量小巧http框架http库支持https,非原创,整理好也不容易,收1分 eclipse用很合适,不喜欢AS的可以试试

支持https的curl

windows平台下使用的curl,已经测试验证支持https协议

自动获取检测外网IP地址变化并自动发邮件程序

自动获取检测外网IP地址变化并自动发邮件程序,很简单,只需要早config.ini文件中填写邮件地址和密码即可自动定时运行,发送最新的IP地址,地址不变则不发送。 如果有 需要可以发邮件到seno100@139.com寻求技术支持。张莽

C++如何从支持证书或账号认证的https网站上,用账号下载

如题,等会写

xiao_rory的专栏 3823

AutoIt3编译时找不到UserInclude目录下的文件的解决方法

最近接手了别人用AutoIt写的一个程序,上来就遇到一个问题,编译时提示找不到WinHttp.au3文件,检查了一下,这个文件就在UserInclude目录下,网上有人说#include会检查这个目录,没道理找不到啊。但是编译失败就是失败,只好去AutoIt的网站看#include指令的说明,看了才知道这个指令是根据注册表来查找用户自定义的目录的,这下就简单了,首先看看你的注册表里有没有H...

swordinhand的专栏 740
上一篇: OAUTH认证
下一篇: Internet Explorer in Protected Mode – How the Low Integrity Environment Gets Created
萧柚
博客等级 码龄15年 7粉丝 21原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值