Calling an API with Boost
I am new to c++ and I was trying to call an api hosted at blockstream.info just for practice and when I run the below code I get:
Error reading from blockstream.info: Connection reset by peer
Error reading from blockstream.info: Connection reset by peer I am not sure but I believe this means I am at least resolving, connecting, and writing to their api. Does anyone know how to handle the reading?
using ResolveResult = boost::asio::ip::tcp::resolver::results_type;
using Endpoint = boost::asio::ip::tcp::endpoint;
struct Request {
explicit Request(boost::asio::io_context& io_context, std::string host)
: resolver{ io_context },
socket{ io_context },
host{ std::move(host) } {
std::stringstream request_stream;
request_stream << "GET /api/blocks/tip/hash HTTP/1.1\r\n"
"Host: " << this->host << "\r\n"
"Accept: */*\r\n"
"Accept-Language: en-us\r\n"
"Accept-Encoding: gzip\r\n"
"Connection: keep-alive\r\n\r\n";
request = request_stream.str();
resolver.async_resolve(this->host, "https",
[this] (boost::system::error_code ec, const ResolveResult& results){
resolution_handler(ec, results);
});
}
void resolution_handler(boost::system::error_code ec,
const ResolveResult& results){
if(ec){
std::cerr << "Error resolving " << host << ": " << ec << std::endl;
return;
}
boost::asio::async_connect(socket, results,
[this] (boost::system::error_code ec, const Endpoint& endpoint){
connection_handler(ec, endpoint);
});
}
void connection_handler(boost::system::error_code ec, const Endpoint& endpoint){
if (ec) {
std::cerr << "Error connecting to " << host << ": "
<< ec.message() << std::endl;
return;
}
boost::asio::async_write(socket, boost::asio::buffer(request),
[this] (boost::system::error_code ec, size_t transferred){
write_handler(ec, transferred);
});
}
void write_handler(boost::system::error_code ec, size_t transferred){
if (ec){
std::cerr << "Error writing to " << host << ": " << ec.message()
<< std::endl;
} else if (request.size() != transferred) {
request.erase(0, transferred);
boost::asio:: async_write(socket, boost::asio::dynamic_buffer(response),
[this] (boost::system::error_code ec,
size_t transferred){
write_handler(ec, transferred);
});
} else {
boost::asio::async_read(socket, boost::asio::dynamic_buffer(response),
[this](boost::system::error_code ec, size_t transferred){
read_handler(ec, transferred);
});
}
}
void read_handler(boost::system::error_code ec, size_t transferred){
if (ec && ec.value() != 2){
std::cerr << "Error reading from " << host << ": "
<< ec.message() << std::endl;
}
}
const std::string& get_response() const noexcept {
return response;
}
private:
boost::asio::ip::tcp::resolver resolver;
boost::asio::ip::tcp::socket socket;
std::string request, response;
const std::string host;
};
int main() {
boost::asio::io_context io_context;
Request request{ io_context, "blockstream.info" };
io_context.run();
std::cout << request.get_response() << std::endl;
}
Posted Jun 4, 2020, 11:24 PM UTC
111