Skip to main content

fetchr_http/
metadata.rs

1use reqwest::header::{HeaderMap, ACCEPT_RANGES, CONTENT_DISPOSITION, CONTENT_LENGTH, ETAG, LAST_MODIFIED};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct RemoteMetadata {
6    pub final_url: String,
7    pub content_length: Option<u64>,
8    pub accept_ranges: bool,
9    pub content_disposition: Option<String>,
10    pub etag: Option<String>,
11    pub last_modified: Option<String>,
12}
13
14impl RemoteMetadata {
15    pub fn from_headers(final_url: String, headers: &HeaderMap) -> Self {
16        let content_length = headers
17            .get(CONTENT_LENGTH)
18            .and_then(|v| v.to_str().ok())
19            .and_then(|v| v.parse::<u64>().ok());
20
21        let accept_ranges = headers
22            .get(ACCEPT_RANGES)
23            .and_then(|v| v.to_str().ok())
24            .map(|v| v.to_lowercase().contains("bytes"))
25            .unwrap_or(false);
26
27        let content_disposition = headers
28            .get(CONTENT_DISPOSITION)
29            .and_then(|v| v.to_str().ok())
30            .map(|v| v.to_string());
31
32        let etag = headers
33            .get(ETAG)
34            .and_then(|v| v.to_str().ok())
35            .map(|v| v.to_string());
36
37        let last_modified = headers
38            .get(LAST_MODIFIED)
39            .and_then(|v| v.to_str().ok())
40            .map(|v| v.to_string());
41
42        Self {
43            final_url,
44            content_length,
45            accept_ranges,
46            content_disposition,
47            etag,
48            last_modified,
49        }
50    }
51}