Использование 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 шт):
я несколько раз писал клинентов, которые должны были что то "дёргать" по HTTPS.
И во всех случаях я полагался на готовую libcurl
А если у нас есть такая мощная библиотека - нужно только научиться импортировать её в проект и использовать.
Не поможет ли Вам такой проект, где всё довольно подробно описано?
Правда, на нижнем уровне у Вас получает уже не чистый сокет, а http(s) - соединение. Но у него очень похожие "повадки": можно, например, управлять потоком приёма данных с помощью callback to progress function.