Skip to main content

pkg/net_backend/
reqwest_backend.rs

1use std::{
2    cell::RefCell,
3    io::{Read, Write},
4    rc::Rc,
5    time::Duration,
6};
7
8use super::{Callback, DownloadBackend, DownloadError};
9use crate::net_backend::DownloadBackendWriter;
10use reqwest::blocking::Client;
11
12/// Network backend
13#[derive(Clone)]
14pub struct ReqwestBackend {
15    client: Client,
16}
17
18impl DownloadBackend for ReqwestBackend {
19    fn new() -> Result<Self, DownloadError> {
20        let client = Client::builder()
21            .connect_timeout(Duration::new(5, 0))
22            .build()?;
23        Ok(Self { client })
24    }
25
26    fn download(
27        &self,
28        remote_path: &str,
29        remote_len: Option<u64>,
30        writer: &mut DownloadBackendWriter,
31        callback: Rc<RefCell<dyn Callback>>,
32    ) -> Result<(), DownloadError> {
33        let mut callback = callback.borrow_mut();
34
35        let mut resp = self.client.get(remote_path).send()?.error_for_status()?;
36
37        callback.download_start(remote_len.unwrap_or(0), remote_path);
38
39        let mut data = [0; 8192];
40        loop {
41            let count = resp.read(&mut data)?;
42            writer.write(&data[..count])?;
43            if count == 0 {
44                break;
45            }
46            callback.download_increment(count as u64);
47        }
48        writer.flush()?;
49
50        callback.download_end();
51
52        Ok(())
53    }
54}