/// Content-Range, described in [RFC7233](https://tools.ietf.org/html/rfc7233#section-4.2) /// /// # ABNF /// /// ```text /// Content-Range = byte-content-range /// / other-content-range /// /// byte-content-range = bytes-unit SP /// ( byte-range-resp / unsatisfied-range ) /// /// byte-range-resp = byte-range "/" ( complete-length / "*" ) /// byte-range = first-byte-pos "-" last-byte-pos /// unsatisfied-range = "*/" complete-length /// /// complete-length = 1*DIGIT /// /// other-content-range = other-range-unit SP other-range-resp /// other-range-resp = *CHAR /// ``` /// /// # Example /// /// ``` /// # extern crate headers; /// use headers::ContentRange; /// /// // 100 bytes (included byte 199), with a full length of 3,400 /// let cr = ContentRange::bytes(100..200, 3400).unwrap(); /// ``` //NOTE: only supporting bytes-content-range, YAGNI the extension #[derive(Clone, Debug, PartialEq)] pubstruct ContentRange { /// First and last bytes of the range, omitted if request could not be /// satisfied
range: Option<(u64, u64)>,
/// Total length of the instance, can be omitted if unknown
complete_length: Option<u64>,
}
error_type!(InvalidContentRange);
impl ContentRange { /// Construct a new `Content-Range: bytes ..` header. pubfn bytes(
range: impl RangeBounds<u64>,
complete_length: impl Into<Option<u64>>,
) -> Result<ContentRange, InvalidContentRange> { let complete_length = complete_length.into();
let start = match range.start_bound() {
Bound::Included(&s) => s,
Bound::Excluded(&s) => s + 1,
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(&e) => e,
Bound::Excluded(&e) => e - 1,
Bound::Unbounded => match complete_length {
Some(max) => max - 1,
None => return Err(InvalidContentRange { _inner: () }),
},
};
/// Create a new `ContentRange` stating the range could not be satisfied. /// /// The passed argument is the complete length of the entity. pubfn unsatisfied_bytes(complete_length: u64) -> Self {
ContentRange {
range: None,
complete_length: Some(complete_length),
}
}
/// Get the byte range if satisified. /// /// Note that these byte ranges are inclusive on both ends. pubfn bytes_range(&self) -> Option<(u64, u64)> { self.range
}
/// Get the bytes complete length if available. pubfn bytes_len(&self) -> Option<u64> { self.complete_length
}
}
fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, ::Error> {
values
.next()
.and_then(|v| v.to_str().ok())
.and_then(|s| split_in_two(s, ' '))
.and_then(|(unit, spec)| { if unit != "bytes" { // For now, this only supports bytes-content-range. nani? return None;
}
let (range, complete_length) = split_in_two(spec, '/')?;
let complete_length = if complete_length == "*" {
None
} else {
Some(complete_length.parse().ok()?)
};
let range = if range == "*" {
None
} else { let (first_byte, last_byte) = split_in_two(range, '-')?; let first_byte = first_byte.parse().ok()?; let last_byte = last_byte.parse().ok()?; if last_byte < first_byte { return None;
}
Some((first_byte, last_byte))
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.