1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
 * Copyright Stalwart Labs Ltd. See the COPYING
 * file at the top-level directory of this distribution.
 *
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
 * option. This file may not be copied, modified, or distributed
 * except according to those terms.
 */

use reqwest::header::CONTENT_TYPE;

use crate::{client::Client, core::session::URLPart};

#[cfg(feature = "blocking")]
use reqwest::blocking::Client as HttpClient;
#[cfg(feature = "async")]
use reqwest::Client as HttpClient;

impl Client {
    #[maybe_async::maybe_async]
    pub async fn download(&self, blob_id: &str) -> crate::Result<Vec<u8>> {
        let account_id = self.default_account_id();
        let mut download_url = String::with_capacity(
            self.session().download_url().len() + account_id.len() + blob_id.len(),
        );

        for part in self.download_url() {
            match part {
                URLPart::Value(value) => {
                    download_url.push_str(value);
                }
                URLPart::Parameter(param) => match param {
                    super::URLParameter::AccountId => {
                        download_url.push_str(account_id);
                    }
                    super::URLParameter::BlobId => {
                        download_url.push_str(blob_id);
                    }
                    super::URLParameter::Name => {
                        download_url.push_str("none");
                    }
                    super::URLParameter::Type => {
                        download_url.push_str("application/octet-stream");
                    }
                },
            }
        }

        let mut headers = self.headers().clone();
        headers.remove(CONTENT_TYPE);

        Client::handle_error(
            HttpClient::builder()
                .timeout(self.timeout())
                .danger_accept_invalid_certs(self.accept_invalid_certs)
                .redirect(self.redirect_policy())
                .default_headers(headers)
                .build()?
                .get(download_url)
                .send()
                .await?,
        )
        .await?
        .bytes()
        .await
        .map(|bytes| bytes.to_vec())
        .map_err(|err| err.into())
    }
}