20 #include <ripple/net/HTTPDownloader.h>
21 #include <boost/asio/ssl.hpp>
26 boost::asio::io_service& io_service,
33 , sessionActive_(false)
43 boost::filesystem::path
const& dstPath,
58 if (!
strand_.running_in_this_thread())
82 std::placeholders::_1));
92 boost::filesystem::path dstPath,
95 boost::asio::yield_context yield)
98 using namespace boost::beast;
100 boost::system::error_code ec;
106 auto close = [&](
auto p) {
110 stream_->getStream().shutdown(socket_base::shutdown_both, ec);
111 if (ec == boost::asio::error::eof)
112 ec.assign(0, ec.category());
117 JLOG(
j_.
trace()) <<
"shutdown: " << ec.message();
129 auto exit = [
this, &dstPath,
complete] {
138 auto failAndExit = [&exit, &dstPath,
complete, &ec,
this](
140 fail(dstPath, ec, errMsg, p);
151 return failAndExit(
"getParser", p);
162 if (!
stream_->connect(error, host, port, yield))
163 return failAndExit(error, p);
166 http::request<http::empty_body> req{http::verb::head, target, version};
167 req.set(http::field::host, host);
168 req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
177 (boost::format(
"bytes=%llu-") % rangeStart).str());
180 stream_->asyncWrite(req, yield, ec);
182 return failAndExit(
"async_write", p);
186 http::response_parser<http::empty_body> connectParser;
187 connectParser.skip(
true);
190 return failAndExit(
"async_read", p);
193 if (connectParser.get().result() == http::status::range_not_satisfiable)
195 req.erase(http::field::range);
197 stream_->asyncWrite(req, yield, ec);
199 return failAndExit(
"async_write_range_verify", p);
201 http::response_parser<http::empty_body> rangeParser;
202 rangeParser.skip(
true);
206 return failAndExit(
"async_read_range_verify", p);
209 if (rangeParser.content_length() == rangeStart)
212 return failAndExit(
"range_not_satisfiable", p);
216 connectParser.get().result() != http::status::partial_content)
219 boost::system::errc::not_supported,
220 boost::system::generic_category());
222 return failAndExit(
"Range request ignored", p);
224 else if (
auto len = connectParser.content_length())
229 if (*len > space(dstPath.parent_path()).available)
232 "Insufficient disk space for download", p);
245 req.method(http::verb::get);
251 (boost::format(
"bytes=%llu-") % rangeStart).str());
255 stream_->asyncWrite(req, yield, ec);
257 return failAndExit(
"async_write", p);
266 while (!p->is_done())
277 JLOG(
j_.
trace()) <<
"download completed: " << dstPath.string();
312 boost::filesystem::path dstPath,
313 boost::system::error_code
const& ec,
321 else if (ec != boost::asio::error::operation_aborted)
323 JLOG(
j_.
error()) << errMsg <<
": " << ec.message();
336 <<
" in function: " << __func__;