-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #491 from pyfisch/ifrangeheader
feat(headers): Add If-Range header
- Loading branch information
Showing
2 changed files
with
76 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use header::{self, EntityTag, HttpDate}; | ||
|
||
/// `If-Range` header, defined in [RFC7233](http://tools.ietf.org/html/rfc7233#section-3.2) | ||
/// | ||
/// If a client has a partial copy of a representation and wishes to have | ||
/// an up-to-date copy of the entire representation, it could use the | ||
/// Range header field with a conditional GET (using either or both of | ||
/// If-Unmodified-Since and If-Match.) However, if the precondition | ||
/// fails because the representation has been modified, the client would | ||
/// then have to make a second request to obtain the entire current | ||
/// representation. | ||
/// | ||
/// The `If-Range` header field allows a client to \"short-circuit\" the | ||
/// second request. Informally, its meaning is as follows: if the | ||
/// representation is unchanged, send me the part(s) that I am requesting | ||
/// in Range; otherwise, send me the entire representation. | ||
/// | ||
/// # ABNF | ||
/// ```plain | ||
/// If-Range = entity-tag / HTTP-date | ||
/// ``` | ||
/// | ||
/// # Example values | ||
/// * `Sat, 29 Oct 1994 19:43:31 GMT` | ||
/// * `\"xyzzy\"` | ||
#[derive(Clone, Debug, PartialEq)] | ||
pub enum IfRange { | ||
/// The entity-tag the client has of the resource | ||
EntityTag(EntityTag), | ||
/// The date when the client retrieved the resource | ||
Date(HttpDate), | ||
} | ||
|
||
impl header::Header for IfRange { | ||
fn header_name() -> &'static str { | ||
"If-Range" | ||
} | ||
fn parse_header(raw: &[Vec<u8>]) -> Option<IfRange> { | ||
let etag: Option<EntityTag> = header::parsing::from_one_raw_str(raw); | ||
if etag != None { | ||
return Some(IfRange::EntityTag(etag.unwrap())); | ||
} | ||
let date: Option<HttpDate> = header::parsing::from_one_raw_str(raw); | ||
if date != None { | ||
return Some(IfRange::Date(date.unwrap())); | ||
} | ||
None | ||
} | ||
} | ||
|
||
impl header::HeaderFormat for IfRange { | ||
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||
match self { | ||
&IfRange::EntityTag(ref x) => write!(f, "{}", x), | ||
&IfRange::Date(ref x) => write!(f, "{}", x), | ||
} | ||
} | ||
} | ||
|
||
impl ::std::fmt::Display for IfRange { | ||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||
use header::HeaderFormat; | ||
self.fmt_header(f) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test_range { | ||
use header::*; | ||
use super::IfRange as HeaderField; | ||
test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); | ||
test_header!(test2, vec![b"\"xyzzy\""]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters