runner_core/packs/resolver/
http.rs

1use std::io::copy;
2
3use anyhow::{Context, Result};
4use reqwest::blocking::Client;
5use tempfile::NamedTempFile;
6
7use super::{FetchResponse, PackResolver};
8
9pub struct HttpResolver {
10    scheme: &'static str,
11    client: Client,
12}
13
14impl HttpResolver {
15    pub fn new(scheme: &'static str) -> Result<Self> {
16        Ok(Self {
17            scheme,
18            client: Client::builder().build()?,
19        })
20    }
21}
22
23impl PackResolver for HttpResolver {
24    fn scheme(&self) -> &'static str {
25        self.scheme
26    }
27
28    fn fetch(&self, locator: &str) -> Result<FetchResponse> {
29        let mut response = self
30            .client
31            .get(locator)
32            .send()
33            .with_context(|| format!("failed to download {}", locator))?
34            .error_for_status()
35            .with_context(|| format!("download failed {}", locator))?;
36
37        let mut temp = NamedTempFile::new().context("failed to allocate temp file for download")?;
38        {
39            let mut writer = temp.as_file_mut();
40            copy(&mut response, &mut writer).context("failed to stream HTTP content")?;
41        }
42        Ok(FetchResponse::from_temp(temp.into_temp_path()))
43    }
44}