如何使用 WinInet 发送 HTTPS 请求?
Posted
技术标签:
【中文标题】如何使用 WinInet 发送 HTTPS 请求?【英文标题】:How to send HTTPS request using WinInet? 【发布时间】:2013-09-20 06:45:45 【问题描述】:我想使用 WinInet 发送 HTTPS GET 请求。据我所知,除了我必须使用 INTERNET_DEFAULT_HTTPS_PORT 和 INTERNET_FLAG_SECURE 标志之外,我应该像发送 HTTP 请求一样执行此操作。
所以这是我尝试过的:
#include "stdafx.h"
#include <string>
#include <windows.h>
#include <WinInet.h>
#pragma comment (lib, "Wininet.lib")
using namespace std;
// convert string
wstring CharPToWstring(const char* _charP)
return wstring(_charP, _charP + strlen(_charP));
// send https request
wstring SendHTTPSRequest_GET(const wstring& _server,
const wstring& _page,
const wstring& _params = L"")
char szData[1024];
// initialize WinInet
HINTERNET hInternet = ::InternetOpen(TEXT("WinInet Test"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet != NULL)
// open HTTP session
HINTERNET hConnect = ::InternetConnect(hInternet, _server.c_str(), INTERNET_DEFAULT_HTTPS_PORT, NULL,NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 1);
if (hConnect != NULL)
wstring request = _page +
(_params.empty() ? L"" : (L"?" + _params));
// open request
HINTERNET hRequest = ::HttpOpenRequest(hConnect, L"GET", (LPCWSTR)request.c_str() ,NULL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, 1);
if (hRequest != NULL)
// send request
BOOL isSend = ::HttpSendRequest(hRequest, NULL, 0, NULL, 0);
if (isSend)
for(;;)
// reading data
DWORD dwByteRead;
BOOL isRead = ::InternetReadFile(hRequest, szData, sizeof(szData) - 1, &dwByteRead);
// break cycle if error or end
if (isRead == FALSE || dwByteRead == 0)
break;
// saving result
szData[dwByteRead] = 0;
// close request
::InternetCloseHandle(hRequest);
// close session
::InternetCloseHandle(hConnect);
// close WinInet
::InternetCloseHandle(hInternet);
wstring answer = CharPToWstring(szData);
return answer;
int _tmain(int argc, _TCHAR* argv[])
wstring answer = SendHTTPSRequest_GET(L"www.site.com", L"page.php", L"param1=value1¶m2=value2¶m3=value3¶m4=value4");
return 0;
我的函数返回了一个答案:
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.0.10</center>
</body>
</html>
我做错了什么?
【问题讨论】:
【参考方案1】:INTERNET_FLAG_SECURE
应在 HttpOpenRequest
的标志中使用,而不是 InternetConnect
。
这在the MSDN documentation for WinINet API flags中有解释:
INTERNET_FLAG_SECURE
0x00800000
使用安全事务语义。这转化为使用安全套接字层/私有通信技术 (SSL/PCT),并且仅在 HTTP 请求中有意义。该标志由HttpOpenRequest 和InternetOpenUrl 使用,但如果
https://
出现在URL 中,则这是多余的。 InternetConnect 函数将此标志用于 HTTP 连接;在此连接下创建的所有请求句柄都将继承此标志。
【讨论】:
@IgorSkochinsky,也许你知道如果使用winInet
api 我可以传递与服务器 URL 本身分离的不同 SNI .. 我目前正在使用 winhttp
并没有找到任何设置不同于 URL 的 SNI 值的方法(使用WinHttpConnect
)
@IgorSkochinsky,基本上以下问题使用 winhttp API 讨论了完全相同的问题https://***.com/questions/57479973/starting-https-connection-with-ip-address-and-sni
。它没有任何答案,但我认为如果您可以使用 winhttp 或 wininet 提供任何解决方案,那就太好了:-)以上是关于如何使用 WinInet 发送 HTTPS 请求?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C++ 中使用 wininet 创建 POST 请求
在 C++ 中使用 Wininet 发送 POST 请求时的编码问题