rusty_cat/azure-blob-direct/
download.rs1use reqwest::header::{HeaderValue, ACCEPT, RANGE};
2
3use super::constants::DEFAULT_RANGE_ACCEPT;
4use super::signing::{apply_signed_headers, header_value};
5use crate::{BreakpointDownload, DownloadHeadCtx, DownloadRangeGetCtx, MeowError, TransferTask};
6
7#[derive(Clone)]
9pub struct AzureBlobDirectDownload {
10 account_name: String,
11 account_key_b64: String,
12}
13
14impl AzureBlobDirectDownload {
15 pub fn new(account_name: impl Into<String>, account_key_b64: impl Into<String>) -> Self {
16 Self {
17 account_name: account_name.into(),
18 account_key_b64: account_key_b64.into(),
19 }
20 }
21}
22
23impl BreakpointDownload for AzureBlobDirectDownload {
24 fn resume_identity(&self, task: &TransferTask) -> Result<Option<Vec<u8>>, MeowError> {
25 let mut headers = task.headers().clone();
26 if !headers.contains_key(ACCEPT) {
27 headers.insert(ACCEPT, HeaderValue::from_static(DEFAULT_RANGE_ACCEPT));
28 }
29 headers.insert(
30 super::constants::HEADER_MS_VERSION,
31 HeaderValue::from_static(super::constants::MS_VERSION),
32 );
33 let mut context = crate::http_breakpoint::canonical_resume_headers(headers);
34 context.extend_from_slice(b"rusty-cat/azure-blob-direct/v1\0");
35 crate::http_breakpoint::append_resume_identity_field(
36 &mut context,
37 self.account_name.as_bytes(),
38 );
39 Ok(Some(context))
40 }
41
42 fn merge_head_headers(&self, ctx: DownloadHeadCtx<'_>) -> Result<(), MeowError> {
43 apply_signed_headers(
44 ctx.task.url(),
45 "HEAD",
46 ctx.base,
47 self.account_name.as_str(),
48 self.account_key_b64.as_str(),
49 )
50 }
51
52 fn merge_range_get_headers(&self, ctx: DownloadRangeGetCtx<'_>) -> Result<(), MeowError> {
53 ctx.base.insert(RANGE, header_value(ctx.range_value)?);
54 if !ctx.base.contains_key(ACCEPT) {
55 ctx.base
56 .insert(ACCEPT, HeaderValue::from_static(DEFAULT_RANGE_ACCEPT));
57 }
58 apply_signed_headers(
59 ctx.task.url(),
60 "GET",
61 ctx.base,
62 self.account_name.as_str(),
63 self.account_key_b64.as_str(),
64 )
65 }
66}