ssl client improvements
This commit is contained in:
parent
bab67f70f9
commit
f0eda085f0
|
|
@ -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 "sslclient.h"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <cstdio>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <sstream>
|
#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/POST
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
|
// 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
|
// split url to parts
|
||||||
parseURL(url);
|
parseURL(url);
|
||||||
if (proto != "https")
|
if (proto != "https")
|
||||||
|
|
@ -36,7 +33,7 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
|
||||||
request.append(request_body);
|
request.append(request_body);
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
int bytes_read = sslRequest(server, request); // TODO memory leaks ???
|
int bytes_read = sslRequest(server, request);
|
||||||
if (bytes_read <= 0) {
|
if (bytes_read <= 0) {
|
||||||
std::cerr << "no data read" << std::endl;
|
std::cerr << "no data read" << std::endl;
|
||||||
return std::make_pair(403, "");
|
return std::make_pair(403, "");
|
||||||
|
|
@ -45,19 +42,18 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
|
||||||
|
|
||||||
// get headers
|
// get headers
|
||||||
std::string::size_type position = ssl_read_packet.find("\r\n\r\n");
|
std::string::size_type position = ssl_read_packet.find("\r\n\r\n");
|
||||||
if (position == std::string::npos) {
|
if (position == std::string::npos)
|
||||||
std::cerr << "end of headers not found" << std::endl;
|
throw std::runtime_error("invalid reply, end of headers not found");
|
||||||
// TODO invalid packet, throw exception
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string hdr = ssl_read_packet.substr(0, position);
|
|
||||||
auto status_pos = hdr.find("\r\n");
|
|
||||||
|
|
||||||
const std::string status_str = hdr.substr(0, status_pos);
|
const std::string response = ssl_read_packet.substr(0, position);
|
||||||
const std::string response_headers = hdr.substr(status_pos + 2, hdr.length() - 2 - status_pos);
|
auto status_pos = response.find("\r\n");
|
||||||
|
|
||||||
|
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
|
// parse status code
|
||||||
const int resp_status = responseStatusCode(status_str);
|
const int resp_status = responseStatusCode(status_string);
|
||||||
|
|
||||||
// parse headers
|
// parse headers
|
||||||
responseHeaders(response_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);
|
return std::make_pair(resp_status, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::responseHeaders(const std::string &hdr) {
|
void HttpClient::responseHeaders(const std::string &headers) {
|
||||||
std::istringstream resp(hdr);
|
std::istringstream resp(headers);
|
||||||
std::string header;
|
std::string header;
|
||||||
std::string::size_type index;
|
|
||||||
while (std::getline(resp, header) && header != "\r") {
|
while (std::getline(resp, header) && header != "\r") {
|
||||||
index = header.find(": ", 0);
|
auto index = header.find(": ", 0);
|
||||||
if (index != std::string::npos)
|
if (index != std::string::npos)
|
||||||
headers_map.insert(std::make_pair(header.substr(0, index), header.substr(index + 1)));
|
headers_map.insert(std::make_pair(header.substr(0, index), header.substr(index + 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int HttpClient::responseStatusCode(const std::string &status_str) const {
|
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::regex status_rgx{"^HTTP/\\d\\.\\d (\\d{3}) .+$"};
|
||||||
std::smatch status_matches;
|
std::smatch status_matches;
|
||||||
|
|
@ -89,15 +85,15 @@ int HttpClient::responseStatusCode(const std::string &status_str) const {
|
||||||
if (status_matches.size() > 1)
|
if (status_matches.size() > 1)
|
||||||
resp_status = std::stoi(status_matches[1].str());
|
resp_status = std::stoi(status_matches[1].str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp_status;
|
return resp_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HttpClient::createRequestHeaders(const std::map<std::string, std::string> &headers) {
|
std::string HttpClient::createRequestHeaders(const std::map<std::string, std::string> &headers) {
|
||||||
std::string headers_string;
|
std::string headers_string;
|
||||||
for (const auto & header : headers) {
|
for (const auto & header : headers)
|
||||||
headers_string.append("\r\n" + header.first + ": " + header.second);
|
headers_string.append("\r\n" + header.first + ": " + header.second);
|
||||||
// std::cerr << "KEY: `" << it->first << "`, VALUE: `" << it->second << '`' << std::endl;
|
|
||||||
}
|
|
||||||
return headers_string;
|
return headers_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,6 +150,7 @@ int HttpClient::sslRecvPacket() {
|
||||||
|
|
||||||
int len = 16384;
|
int len = 16384;
|
||||||
char buf[len + 1];
|
char buf[len + 1];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
do {
|
do {
|
||||||
len = SSL_read(ssl, buf, len);
|
len = SSL_read(ssl, buf, len);
|
||||||
if (len >= 0) {
|
if (len >= 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue