http_range_client/
ureq_client.rs

1use crate::error::{HttpError, Result};
2use bytes::Bytes;
3use std::io::Read;
4use std::iter::FromIterator;
5use std::time::Duration;
6
7#[cfg(feature = "ureq-sync")]
8pub(crate) mod sync {
9    use super::*;
10    use crate::range_client::SyncHttpRangeClient;
11
12    impl SyncHttpRangeClient for ureq::Agent {
13        fn get_range(&self, url: &str, range: &str) -> Result<Bytes> {
14            let response = self.get(url).set("Range", range).call()?;
15            if response.status() < 200 || response.status() > 299 {
16                return Err(HttpError::HttpStatus(response.status()));
17            }
18            // TODO: return error instead of dropping remaining bytes
19            let bytes = response.into_reader().bytes().map_while(|val| val.ok());
20            Ok(Bytes::from_iter(bytes))
21        }
22        fn head_response_header(&self, url: &str, header: &str) -> Result<Option<String>> {
23            let response = self.head(url).call()?;
24            Ok(response.header(header).map(|val| val.to_string()))
25        }
26    }
27
28    /// Sync HTTP client for HTTP Range requests with a buffer optimized for sequential reading.
29    pub type UreqHttpReader = crate::SyncBufferedHttpRangeClient<ureq::Agent>;
30
31    impl UreqHttpReader {
32        pub fn new(url: &str) -> Self {
33            let agent = ureq::AgentBuilder::new()
34                .timeout_read(Duration::from_secs(5))
35                .timeout_write(Duration::from_secs(5))
36                .build();
37            Self::with(agent, url)
38        }
39    }
40}
41
42impl From<ureq::Error> for HttpError {
43    fn from(error: ureq::Error) -> Self {
44        use ureq::Error::*;
45        match error {
46            Status(status, _resp) => HttpError::HttpStatus(status),
47            Transport(e) => HttpError::HttpError(e.to_string()),
48        }
49    }
50}