add: chunk conten_provider for file download

This commit is contained in:
2021-06-03 19:08:39 +02:00
parent 3baf88ba0a
commit e79de5d92e
5 changed files with 45 additions and 13 deletions

View File

@@ -192,15 +192,32 @@ void Api::file(const httplib::Request& rq, httplib::Response& rs)
sql << fmt::format("SELECT * FROM Files WHERE hash='{}';", file), soci::into(dw);
std::ifstream fs(dw.local_path, std::ios_base::binary);
fs.seekg(0, std::ios_base::end);
auto size = fs.tellg();
fs.seekg(0);
rs.body.resize(static_cast<size_t>(size));
fs.read(&rs.body[0], static_cast<std::streamsize>(size));
auto fs = std::make_shared<std::ifstream>(dw.local_path, std::ios_base::binary | std::ios::in);
fs->seekg(0, std::ios_base::end);
auto size = fs->tellg();
fs->seekg(0);
// rs.body.resize(static_cast<size_t>(size));
// fs.read(&rs.body[0], static_cast<std::streamsize>(size));
rs.set_header("Content-Disposition", fmt::format("attachment; filename={};", dw.filename));
rs.set_header("content-type", fmt::format("application/{}", dw.format));
rs.set_content_provider(
static_cast<size_t>(size),
fmt::format("application/{}", dw.format).c_str(),
[file = fs](size_t offset, size_t length, httplib::DataSink& sink) mutable {
size_t size = std::min(length, (size_t)1024 * 500);
//spdlog::info("Stream offset {} length {}", offset, length);
std::vector<char> data;
data.resize(size);
file->seekg(offset);
file->read(data.data(), data.size());
sink.write(data.data(), data.size());
return true;
});
}
catch (std::exception const& e)
{

View File

@@ -124,12 +124,21 @@ bool Worker::download(Task& task)
args += task.format.value();
}
args += "--restrict-filenames";
args += task.url;
/* ** Download ** */
spdlog::debug("youtube-dl {}", fmt::join(args, " "));
bp::child c("youtube-dl.exe", bp::args(args), bp::std_out > out, bp::std_err > err);
#ifdef __linux__
constexpr std::string_view youtube_dl = "youtube-dl";
#elif _WIN32
constexpr std::string_view youtube_dl = "youtube-dl.exe";
#else
#endif
bp::child c(std::string{youtube_dl}, bp::args(args), bp::std_out > out, bp::std_err > err);
std::string destination_file;

View File

@@ -3,7 +3,7 @@ module Globals exposing (..)
api : String
api =
"http://127.0.0.1/api/"
"/api/"
apiEndpoint : String -> String
@@ -14,6 +14,9 @@ apiEndpoint path =
apiStatus : String -> String
apiStatus id = String.concat [apiEndpoint "status/", id]
apiAdd : String
apiAdd = apiEndpoint "add"
apiDownloadFile : String -> String
apiDownloadFile id = String.concat [apiEndpoint "file/", id]

View File

@@ -14,7 +14,7 @@ import Json.Decode exposing (Decoder, int, string, succeed)
import Json.Decode.Pipeline exposing (required)
import Json.Encode as Encode
import Html.Events exposing (onMouseOver)
import Globals exposing(apiAdd)
type alias Form =
{ url : String
@@ -179,7 +179,7 @@ update navKey msg model =
if not (String.isEmpty form.url) then
( model
, Http.post
{ url = "http://127.0.0.1/api/add"
{ url = apiAdd
, body = Http.jsonBody (formPostEncoder form)
, expect = Http.expectJson PostResult formDecoder
}

View File

@@ -15,5 +15,8 @@ cmake
soci:shared=True
soci:with_boost=True
soci:with_sqlite3=True
soci:with_odbc=True
soci:with_postgresql=True
[imports]
lib, *.so* -> ./bin