add try/catch to PostHTTP

This commit is contained in:
Lion Kortlepel
2021-02-01 23:13:58 +01:00
parent 5f3fecb92c
commit d5541ae154
+67 -67
View File
@@ -71,91 +71,91 @@ std::string HttpRequest(const std::string& host, int port, const std::string& ta
} }
std::string PostHTTP(const std::string& host, const std::string& target, const std::unordered_map<std::string, std::string>& fields, const std::string& body, bool json) { std::string PostHTTP(const std::string& host, const std::string& target, const std::unordered_map<std::string, std::string>& fields, const std::string& body, bool json) {
//try { try {
net::io_context io; net::io_context io;
// The SSL context is required, and holds certificates // The SSL context is required, and holds certificates
ssl::context ctx(ssl::context::tlsv13); ssl::context ctx(ssl::context::tlsv13);
ctx.set_verify_mode(ssl::verify_none); ctx.set_verify_mode(ssl::verify_none);
tcp::resolver resolver(io); tcp::resolver resolver(io);
beast::ssl_stream<beast::tcp_stream> stream(io, ctx); beast::ssl_stream<beast::tcp_stream> stream(io, ctx);
decltype(resolver)::results_type results; decltype(resolver)::results_type results;
auto try_connect_with_protocol = [&](tcp protocol) { auto try_connect_with_protocol = [&](tcp protocol) {
try { try {
results = resolver.resolve(protocol, host, std::to_string(443)); results = resolver.resolve(protocol, host, std::to_string(443));
if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) { if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) {
boost::system::error_code ec { static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() }; boost::system::error_code ec { static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() };
// FIXME: we could throw and crash, if we like // FIXME: we could throw and crash, if we like
// throw boost::system::system_error { ec }; // throw boost::system::system_error { ec };
debug("POST " + host + target + " failed."); debug("POST " + host + target + " failed.");
return false;
}
beast::get_lowest_layer(stream).connect(results);
} catch (const boost::system::system_error&) {
return false; return false;
} }
beast::get_lowest_layer(stream).connect(results); return true;
} catch (const boost::system::system_error&) { };
return false; bool ok = try_connect_with_protocol(tcp::v6());
}
return true;
};
bool ok = try_connect_with_protocol(tcp::v6());
if (!ok) {
debug("IPv6 connect failed, trying IPv4");
ok = try_connect_with_protocol(tcp::v4());
if (!ok) { if (!ok) {
error("failed to resolve or connect in POST " + host + target); debug("IPv6 connect failed, trying IPv4");
return "-1"; ok = try_connect_with_protocol(tcp::v4());
if (!ok) {
error("failed to resolve or connect in POST " + host + target);
return "-1";
}
} }
} stream.handshake(ssl::stream_base::client);
stream.handshake(ssl::stream_base::client); http::request<http::string_body> req { http::verb::post, target, 11 /* http 1.1 */ };
http::request<http::string_body> req { http::verb::post, target, 11 /* http 1.1 */ };
req.set(http::field::host, host); req.set(http::field::host, host);
if (!body.empty()) { if (!body.empty()) {
if (json) { if (json) {
// FIXME: json is untested. // FIXME: json is untested.
req.set(http::field::content_type, "application/json"); req.set(http::field::content_type, "application/json");
} else { } else {
req.set(http::field::content_type, "application/x-www-form-urlencoded"); req.set(http::field::content_type, "application/x-www-form-urlencoded");
}
req.set(http::field::content_length, boost::lexical_cast<std::string>(body.size()));
req.body() = body;
// info("body is " + body + " (" + req.body() + ")");
// info("content size is " + std::to_string(body.size()) + " (" + boost::lexical_cast<std::string>(body.size()) + ")");
}
for (const auto& pair : fields) {
// info("setting " + pair.first + " to " + pair.second);
req.set(pair.first, pair.second);
} }
req.set(http::field::content_length, boost::lexical_cast<std::string>(body.size()));
req.body() = body;
// info("body is " + body + " (" + req.body() + ")");
// info("content size is " + std::to_string(body.size()) + " (" + boost::lexical_cast<std::string>(body.size()) + ")");
}
for (const auto& pair : fields) {
// info("setting " + pair.first + " to " + pair.second);
req.set(pair.first, pair.second);
}
std::stringstream oss; std::stringstream oss;
oss << req; oss << req;
beast::get_lowest_layer(stream).expires_after(std::chrono::seconds(5)); beast::get_lowest_layer(stream).expires_after(std::chrono::seconds(5));
http::write(stream, req); http::write(stream, req);
// used for reading // used for reading
beast::flat_buffer buffer; beast::flat_buffer buffer;
http::response<http::string_body> response; http::response<http::string_body> response;
http::read(stream, buffer, response); http::read(stream, buffer, response);
std::stringstream result; std::stringstream result;
result << response; result << response;
beast::error_code ec; beast::error_code ec;
stream.shutdown(ec); stream.shutdown(ec);
// IGNORING ec // IGNORING ec
// info(result.str()); // info(result.str());
std::string debug_response_str; std::string debug_response_str;
std::getline(result, debug_response_str); std::getline(result, debug_response_str);
debug("POST " + host + target + ": " + debug_response_str); debug("POST " + host + target + ": " + debug_response_str);
return std::string(response.body()); return std::string(response.body());
/*} catch (const std::exception& e) { } catch (const std::exception& e) {
error(e.what()); error(e.what());
return "-1"; return "-1";
}*/ }
} }