12

我想使用 WinInet 发送 HTTPS GET 请求。据我所知,除了必须使用INTERNET_DEFAULT_HTTPS_PORTINTERNET_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&param2=value2&param3=value3&param4=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>

我究竟做错了什么?

4

1 回答 1

14

INTERNET_FLAG_SECURE应该在标志中使用HttpOpenRequest,而不是InternetConnect

这在WinINet API 标志的 MSDN 文档中进行了解释:

INTERNET_FLAG_SECURE

0x00800000

使用安全事务语义。这转化为使用安全套接字层/私有通信技术 (SSL/PCT),并且仅在 HTTP 请求中有意义。此标志由HttpOpenRequestInternetOpenUrlhttps://使用,但如果出现在 URL 中,则这是多余的。InternetConnect函数将此标志用于 HTTP 连接;在此连接下创建的所有请求句柄都将继承此标志。

于 2013-09-20T10:00:57.097 回答