use dragonfly_api::common::v2::Range;
use dragonfly_client_core::{
error::{ErrorType, OrErr},
Error, Result,
};
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use std::collections::HashMap;
pub mod basic_auth;
pub mod query_params;
pub fn headermap_to_hashmap(header: &HeaderMap<HeaderValue>) -> HashMap<String, String> {
let mut hashmap: HashMap<String, String> = HashMap::with_capacity(header.len());
for (k, v) in header {
if let Ok(v) = v.to_str() {
hashmap.insert(k.to_string(), v.to_string());
}
}
hashmap
}
pub fn hashmap_to_headermap(header: &HashMap<String, String>) -> Result<HeaderMap<HeaderValue>> {
let mut headermap = HeaderMap::with_capacity(header.len());
for (k, v) in header {
let name = HeaderName::from_bytes(k.as_bytes()).or_err(ErrorType::ParseError)?;
let value = HeaderValue::from_bytes(v.as_bytes()).or_err(ErrorType::ParseError)?;
headermap.insert(name, value);
}
Ok(headermap)
}
pub fn header_vec_to_hashmap(raw_header: Vec<String>) -> Result<HashMap<String, String>> {
let mut header = HashMap::with_capacity(raw_header.len());
for h in raw_header {
if let Some((k, v)) = h.split_once(':') {
header.insert(k.trim().to_string(), v.trim().to_string());
}
}
Ok(header)
}
pub fn header_vec_to_headermap(raw_header: Vec<String>) -> Result<HeaderMap> {
hashmap_to_headermap(&header_vec_to_hashmap(raw_header)?)
}
pub fn get_range(header: &HeaderMap, content_length: u64) -> Result<Option<Range>> {
match header.get(reqwest::header::RANGE) {
Some(range) => {
let range = range.to_str().or_err(ErrorType::ParseError)?;
Ok(Some(parse_range_header(range, content_length)?))
}
None => Ok(None),
}
}
pub fn parse_range_header(range_header_value: &str, content_length: u64) -> Result<Range> {
let parsed_ranges =
http_range_header::parse_range_header(range_header_value).or_err(ErrorType::ParseError)?;
let valid_ranges = parsed_ranges
.validate(content_length)
.or_err(ErrorType::ParseError)?;
let valid_range = valid_ranges
.first()
.ok_or_else(|| Error::EmptyHTTPRangeError)?;
let start = valid_range.start().to_owned();
let length = valid_range.end() - start + 1;
Ok(Range { start, length })
}
#[cfg(test)]
mod tests {
use super::*;
use reqwest::header::{HeaderMap, HeaderValue};
#[test]
fn test_headermap_to_hashmap() {
let mut header = HeaderMap::new();
header.insert("Content-Type", HeaderValue::from_static("application/json"));
header.insert("Authorization", HeaderValue::from_static("Bearer token"));
let hashmap = headermap_to_hashmap(&header);
assert_eq!(hashmap.get("content-type").unwrap(), "application/json");
assert_eq!(hashmap.get("authorization").unwrap(), "Bearer token");
assert_eq!(hashmap.get("foo"), None);
}
#[test]
fn test_hashmap_to_headermap() {
let mut hashmap = HashMap::new();
hashmap.insert("Content-Type".to_string(), "application/json".to_string());
hashmap.insert("Authorization".to_string(), "Bearer token".to_string());
let header = hashmap_to_headermap(&hashmap).unwrap();
assert_eq!(header.get("Content-Type").unwrap(), "application/json");
assert_eq!(header.get("Authorization").unwrap(), "Bearer token");
}
#[test]
fn test_header_vec_to_hashmap() {
let raw_header = vec![
"Content-Type: application/json".to_string(),
"Authorization: Bearer token".to_string(),
];
let hashmap = header_vec_to_hashmap(raw_header).unwrap();
assert_eq!(hashmap.get("Content-Type").unwrap(), "application/json");
assert_eq!(hashmap.get("Authorization").unwrap(), "Bearer token");
}
#[test]
fn test_header_vec_to_headermap() {
let raw_header = vec![
"Content-Type: application/json".to_string(),
"Authorization: Bearer token".to_string(),
];
let header = header_vec_to_headermap(raw_header).unwrap();
assert_eq!(header.get("Content-Type").unwrap(), "application/json");
assert_eq!(header.get("Authorization").unwrap(), "Bearer token");
}
#[test]
fn test_get_range() {
let mut header = HeaderMap::new();
header.insert(
reqwest::header::RANGE,
HeaderValue::from_static("bytes=0-100"),
);
let range = get_range(&header, 200).unwrap().unwrap();
assert_eq!(range.start, 0);
assert_eq!(range.length, 101);
}
#[test]
fn test_parse_range_header() {
let range = parse_range_header("bytes=0-100", 200).unwrap();
assert_eq!(range.start, 0);
assert_eq!(range.length, 101);
}
}