Использование ssl поверх c++ winsock

У меня есть код запроса по протоколу HTTP(nk_http.hpp):

#define REQ_TO_DOMAIN 1
#define REQ_TO_IP 2
#define REQ_GET 3
#define REQ_POST 4
#define REQ_HTTP 5
#define REQ_HTTPS 6

struct {
    bool ok = false;
    char* error = (char*)"noError";
    int req_size = 0;
    int res_size = 0;
    char* request = new char[1024];
    char* response = new char[1024];
} req;


WSADATA wsaData;

char* nk_http_start() {

#ifndef WSASTARTED 

    int wsa = WSAStartup(MAKEWORD(2, 2), &wsaData);

    if (wsa != NO_ERROR) {
        return (char*)"WSAStartup error: " + wsa;
    } else {
        #define WSASTARTED
        return (char*)"OK";
    }

    #define WSASTARTED
#endif
}


void request(int http_type, int method, int ip_type, const char* host, const char* body, const int port) {

    req.ok = false;
    req.error = (char*)"noError";
    req.req_size = 0;


    int iResult;
    int WSAError = -1;
    
    char* ip = (char*)"";

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService;

    const int recv_buf_size = 5120;
    char* recvbuf = new char[recv_buf_size];

    const rsize_t req_buf_size = 500 + strlen(body) + strlen(host);
    char* headers = new char[req_buf_size];


        if (WSAError == -1) {


            ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

            if (ConnectSocket == INVALID_SOCKET) {
                WSAError = WSAGetLastError();
                WSACleanup();
                req.error = (char*)"Socket failed with error: " + WSAError;
            }

        }

        if (WSAError == -1) {

            if (ip_type == REQ_TO_DOMAIN) {

                struct hostent* remoteHost;
                remoteHost = gethostbyname(host);
                ip = inet_ntoa(*(struct in_addr*)remoteHost->h_addr_list[0]);

            } else if (ip_type == REQ_TO_IP) {
                ip = (char*)host;
            } else {
                WSAError = -2;
                req.error = (char*)"Connect error: IP type is wrong";
            }

        }

        if (WSAError == -1) {

            clientService.sin_family = AF_INET;
            clientService.sin_addr.s_addr = inet_addr(ip);
            clientService.sin_port = htons(port);


            iResult = connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService));

            if (iResult == SOCKET_ERROR) {
                WSAError = WSAGetLastError();
                closesocket(ConnectSocket);
                WSACleanup();
                req.error = (char*)"Connect failed with error: " + WSAError;
            }

        }


        if (WSAError == -1) {


            if (method == REQ_GET) {
                
                if(http_type == REQ_HTTP) strcpy_s(headers, req_buf_size, "GET http://");

                if (http_type == REQ_HTTPS) strcpy_s(headers, req_buf_size, "GET https://");

            } else if (method == REQ_POST) {

                if (http_type == REQ_HTTP) strcpy_s(headers, req_buf_size, "POST http://");

                if (http_type == REQ_HTTPS) strcpy_s(headers, req_buf_size, "POST https://");

            } else {
                WSAError = -3;
                req.error = (char*)"Send error: request method  is wrong";
            }

            strcat_s(headers, req_buf_size, (char*)host);
            strcat_s(headers, req_buf_size, (char*)body);
            strcat_s(headers, req_buf_size, "\r\n");
            strcat_s(headers, req_buf_size, "Accept: text/html,application/xhtml+xml,application/xml\r\n");
            strcat_s(headers, req_buf_size, "Accept-Encoding: gzip, deflate, br\r\n");
            strcat_s(headers, req_buf_size, "Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,de;q=0.7\r\n\r\n");
            
            iResult = send(ConnectSocket, headers, req_buf_size, 0);

            if (iResult == SOCKET_ERROR) {
                WSAError = WSAGetLastError();
                closesocket(ConnectSocket);
                WSACleanup();
                req.error = (char*)"Send error: " + WSAError;
            }

            req.request = new char[iResult];
            req.request = headers;
            req.req_size = strlen(req.request);


        }


        if (WSAError == -1) {


            iResult = shutdown(ConnectSocket, SD_SEND);

            if (iResult == SOCKET_ERROR) {
                WSAError = WSAGetLastError();
                closesocket(ConnectSocket);
                WSACleanup();
                req.error = (char*)"Shutdown error: " + WSAError;
            }

        }


        if (WSAError == -1) {


            iResult = recv(ConnectSocket, recvbuf, recv_buf_size, 0);
            req.res_size = iResult;
            recvbuf[iResult] = '\0';

            if (iResult < 0) {
                WSAError = WSAGetLastError();
                req.error = (char*)"Recv error:" + WSAError;
            }

        }

        if (WSAError == -1) {

            iResult = closesocket(ConnectSocket);

            if (iResult == SOCKET_ERROR) {
                WSAError = WSAGetLastError();
                WSACleanup();
                req.error = (char*)"Closing socket error: " + WSAError;
            }

            req.ok = true;

            req.response = new char[req.res_size];

            req.response = recvbuf;

        }
    
}

char* nk_http_stop() {
    #ifdef WSASTARTED 
        WSACleanup();
        #undef WSASTARTED
    #endif
    return (char*)"OK";
}

и основной скрипт(http_test.cpp):

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <iostream>

#include <winsock2.h>
#include <WS2tcpip.h>

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

#include "./nk_http.hpp"

#include <windows.h>

int main() {

    nk_http_start();

    request(REQ_HTTP, REQ_GET, REQ_TO_DOMAIN, "myexternalip.com", "/raw", 80);

    if (req.ok) {
        std::cout << req.response;
        std::cout << "\n\n\nOK" << " | req_size: " << req.req_size << " | res_size: " << req.res_size << "\n";
    } else {
        std::cout << req.error;
    }

    nk_http_stop();
}

Но сколько я не искал инфы по поводу использованию ssl библиотек и тд, ничего нормального я не нашёл, а что пробовал не получилось.Нужно не переделать этот код полностью под openssl или другие библиотеки, а добавить сюда что-то, что сделать использование ssl именно поверх сокетов для https запроса, если так конечно возможно(если нет, то хотя-бы что-то в пример дайте).


Ответы (1 шт):

Автор решения: S.H.

я несколько раз писал клинентов, которые должны были что то "дёргать" по HTTPS.

И во всех случаях я полагался на готовую libcurl

А если у нас есть такая мощная библиотека - нужно только научиться импортировать её в проект и использовать.

Не поможет ли Вам такой проект, где всё довольно подробно описано?

Правда, на нижнем уровне у Вас получает уже не чистый сокет, а http(s) - соединение. Но у него очень похожие "повадки": можно, например, управлять потоком приёма данных с помощью callback to progress function.

→ Ссылка