ssl client improvements

This commit is contained in:
vaclavt 2022-01-15 13:16:27 +01:00
parent bab67f70f9
commit f0eda085f0
1 changed files with 22 additions and 25 deletions

View File

@ -1,16 +1,11 @@
//============================================================================
// clang++ -o sslclient sslclient.cpp -lssl -lcrypto -L/usr/local/opt/openssl/lib -I/usr/local/opt/openssl/include
//============================================================================
//
#include "sslclient.h"
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <cstdio>
#include <sys/socket.h>
#include <cstdio>
#include <iostream>
#include <regex>
#include <sstream>
@ -20,8 +15,10 @@
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
std::pair<int, std::string> HttpClient::doRequest(const std::string &method, const std::string &url, const std::map<std::string, std::string> &headers, const std::string &request_body) {
// TODO user streams instead of printf's
std::pair<int, std::string> HttpClient::doRequest(const std::string &method, const std::string &url, const std::map<std::string, std::string> &headers, const std::string &request_body) {
// split url to parts
parseURL(url);
if (proto != "https")
@ -36,7 +33,7 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
request.append(request_body);
// read response
int bytes_read = sslRequest(server, request); // TODO memory leaks ???
int bytes_read = sslRequest(server, request);
if (bytes_read <= 0) {
std::cerr << "no data read" << std::endl;
return std::make_pair(403, "");
@ -45,19 +42,18 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
// get headers
std::string::size_type position = ssl_read_packet.find("\r\n\r\n");
if (position == std::string::npos) {
std::cerr << "end of headers not found" << std::endl;
// TODO invalid packet, throw exception
}
if (position == std::string::npos)
throw std::runtime_error("invalid reply, end of headers not found");
const std::string hdr = ssl_read_packet.substr(0, position);
auto status_pos = hdr.find("\r\n");
const std::string response = ssl_read_packet.substr(0, position);
auto status_pos = response.find("\r\n");
const std::string status_str = hdr.substr(0, status_pos);
const std::string response_headers = hdr.substr(status_pos + 2, hdr.length() - 2 - status_pos);
const std::string response_headers = response.substr(status_pos + 2, response.length() - 2 - status_pos);
const std::string status_string = response.substr(0, status_pos);
// parse status code
const int resp_status = responseStatusCode(status_str);
const int resp_status = responseStatusCode(status_string);
// parse headers
responseHeaders(response_headers);
@ -69,19 +65,19 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
return std::make_pair(resp_status, body);
}
void HttpClient::responseHeaders(const std::string &hdr) {
std::istringstream resp(hdr);
void HttpClient::responseHeaders(const std::string &headers) {
std::istringstream resp(headers);
std::string header;
std::string::size_type index;
while (std::getline(resp, header) && header != "\r") {
index = header.find(": ", 0);
auto index = header.find(": ", 0);
if (index != std::string::npos)
headers_map.insert(std::make_pair(header.substr(0, index), header.substr(index + 1)));
}
}
int HttpClient::responseStatusCode(const std::string &status_str) const {
int resp_status = 200; // default is OK
auto resp_status = 200; // default is OK
std::regex status_rgx{"^HTTP/\\d\\.\\d (\\d{3}) .+$"};
std::smatch status_matches;
@ -89,15 +85,15 @@ int HttpClient::responseStatusCode(const std::string &status_str) const {
if (status_matches.size() > 1)
resp_status = std::stoi(status_matches[1].str());
}
return resp_status;
}
std::string HttpClient::createRequestHeaders(const std::map<std::string, std::string> &headers) {
std::string headers_string;
for (const auto & header : headers) {
for (const auto & header : headers)
headers_string.append("\r\n" + header.first + ": " + header.second);
// std::cerr << "KEY: `" << it->first << "`, VALUE: `" << it->second << '`' << std::endl;
}
return headers_string;
}
@ -154,6 +150,7 @@ int HttpClient::sslRecvPacket() {
int len = 16384;
char buf[len + 1];
memset(buf, 0, sizeof(buf));
do {
len = SSL_read(ssl, buf, len);
if (len >= 0) {