Приветствую.
Нужно скачать с http сервера файл и посчитать его md5, взял из документации пример, все в нем работает пока не вставляю в него свой кривой код вместо cout - в зависимости от размера файла получаю то корректные данные, то нет
#include <openssl/md5.h>
#include <fstream>
#include <iomanip>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
bool HTTPDownload(const std::string & host, const std::string & port, const std::string & file_src, const char * file_dst, const std::string & md5)
{
std::ofstream outfile(file_dst, std::ios::binary);
if (!outfile.is_open())
{
fprintf(stderr, "ERROR %s\n", file_dst);
return false;
}
MD5_CTX md5Context;
MD5_Init(&md5Context);
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(host, port);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
{
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << file_src << " HTTP/1.0\r\n"
<< "Host: " << host << "\r\n"
<< "Accept: */*\r\n"
<< "Connection: close\r\n\r\n";
boost::asio::write(socket, request);
}
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
fputs("ERROR HTTP response\n", stderr);
return false;
}
if (status_code != 200)
{
fprintf(stderr, "ERROR %u\n", status_code);
return false;
}
boost::asio::read_until(socket, response, "\r\n\r\n");
std::string header;
while (std::getline(response_stream, header) && header != "\r") fprintf(stdout, "%s\n", header.c_str());
fputc('\n', stdout);
boost::system::error_code error;
while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error));;
if (error != boost::asio::error::eof) return false;
if (response.size() > 0)
{
auto response_data = boost::asio::buffer_cast<const char*>(response.data());
MD5_Update(&md5Context, response_data, response.size());
outfile << response_data;
}
else return false;
}
catch (std::exception& e)
{
fprintf(stderr, "ERROR [%s]: %s\n", file_dst, e.what());
return false;
}
unsigned char md5hash[MD5_DIGEST_LENGTH];
MD5_Final(md5hash, &md5Context);
std::stringstream md5ss;
md5ss << std::hex << std::setfill('0');
for (const auto & byte: md5hash) md5ss << std::setw(2) << (int)byte;
fprintf(stdout, "\n%s\n", md5ss.str().c_str());
return true;
}