use crate::{InnerErrorCode, MeowError, TransferTask};
use reqwest::header::HeaderMap;
pub struct DownloadHeadCtx<'a> {
pub task: &'a TransferTask,
pub base: &'a mut HeaderMap,
}
pub struct DownloadRangeGetCtx<'a> {
pub task: &'a TransferTask,
pub range_value: &'a str,
pub base: &'a mut HeaderMap,
}
pub trait BreakpointDownload: Send + Sync {
fn head_url(&self, task: &TransferTask) -> String {
task.url().to_string()
}
fn merge_head_headers(&self, _ctx: DownloadHeadCtx<'_>) -> Result<(), MeowError> {
Ok(())
}
fn merge_range_get_headers(&self, ctx: DownloadRangeGetCtx<'_>) -> Result<(), MeowError> {
let _ = self;
crate::http_breakpoint::insert_header(ctx.base, "Range", ctx.range_value);
let accept = ctx
.task
.breakpoint_download_http()
.map(|c| c.range_accept.as_str())
.unwrap_or(crate::http_breakpoint::DEFAULT_RANGE_ACCEPT);
crate::http_breakpoint::insert_header(ctx.base, "Accept", accept);
Ok(())
}
fn total_size_from_head(&self, headers: &HeaderMap) -> Result<u64, MeowError> {
headers
.get(reqwest::header::CONTENT_LENGTH)
.and_then(|v| v.to_str().ok())
.and_then(|s| s.parse::<u64>().ok())
.filter(|&n| n > 0)
.ok_or_else(|| {
MeowError::from_code_str(
InnerErrorCode::MissingOrInvalidContentLengthFromHead,
"missing or invalid content-length from HEAD",
)
})
}
}