-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(headers): Origin Header 0.9.x #853
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Add an Origin header so users may properly send CORS requests Addresses #651
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
use header::{Header, Host, HeaderFormat}; | ||
use std::fmt; | ||
use std::str::FromStr; | ||
use header::parsing::from_one_raw_str; | ||
|
||
/// The `Origin` header. | ||
/// | ||
/// The `Origin` header is a version of the `Referer` header that is used for all HTTP fetches and `POST`s whose CORS flag is set. | ||
/// This header is often used to inform recipients of the security context of where the request was initiated. | ||
/// | ||
/// | ||
/// Following the spec, https://fetch.spec.whatwg.org/#origin-header, the value of this header is composed of | ||
/// a String (scheme), header::Host (host/port) | ||
/// | ||
/// # Examples | ||
/// ``` | ||
/// use hyper::header::{Headers, Origin}; | ||
/// | ||
/// let mut headers = Headers::new(); | ||
/// headers.set( | ||
/// Origin::new("http", "hyper.rs", None) | ||
/// ); | ||
/// ``` | ||
/// ``` | ||
/// use hyper::header::{Headers, Origin}; | ||
/// | ||
/// let mut headers = Headers::new(); | ||
/// headers.set( | ||
/// Origin::new("https", "wikipedia.org", Some(443)) | ||
/// ); | ||
/// ``` | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct Origin { | ||
/// The scheme, such as http or https | ||
pub scheme: String, | ||
/// The host, such as Host{hostname: "hyper.rs".to_owned(), port: None} | ||
pub host: Host, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clever. A downside is that to set the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I see the reason for a constructor, by why obstruct access? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might not be important yet. The idea I had was to have But all the other headers are currently wide open. I'll consider a accessor pass before 1.0. |
||
} | ||
|
||
impl Origin { | ||
pub fn new<S: Into<String>, H: Into<String>>(scheme: S, hostname: H, port: Option<u16>) -> Origin{ | ||
Origin { | ||
scheme: scheme.into(), | ||
host: Host { | ||
hostname: hostname.into(), | ||
port: port | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl Header for Origin { | ||
fn header_name() -> &'static str { | ||
static NAME: &'static str = "Origin"; | ||
NAME | ||
} | ||
|
||
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Origin> { | ||
from_one_raw_str(raw) | ||
} | ||
} | ||
|
||
impl FromStr for Origin { | ||
type Err = ::Error; | ||
|
||
fn from_str(s: &str) -> ::Result<Origin> { | ||
let idx = match s.find("://") { | ||
Some(idx) => idx, | ||
None => return Err(::Error::Header) | ||
}; | ||
// idx + 3 because thats how long "://" is | ||
let (scheme, etc) = (&s[..idx], &s[idx + 3..]); | ||
let host = try!(Host::from_str(etc)); | ||
|
||
|
||
Ok(Origin{ | ||
scheme: scheme.to_owned(), | ||
host: host | ||
}) | ||
} | ||
} | ||
|
||
impl HeaderFormat for Origin { | ||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "{}://{}", self.scheme, self.host) | ||
} | ||
} | ||
|
||
impl PartialEq for Origin { | ||
fn eq(&self, other: &Origin) -> bool { | ||
self.scheme == other.scheme && self.host == other.host | ||
} | ||
} | ||
|
||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::Origin; | ||
use header::Header; | ||
|
||
#[test] | ||
fn test_origin() { | ||
let origin = Header::parse_header([b"http://foo.com".to_vec()].as_ref()); | ||
assert_eq!(origin.ok(), Some(Origin::new("http", "foo.com", None))); | ||
|
||
let origin = Header::parse_header([b"https://foo.com:443".to_vec()].as_ref()); | ||
assert_eq!(origin.ok(), Some(Origin::new("https", "foo.com", Some(443)))); | ||
} | ||
} | ||
|
||
bench_header!(bench, Origin, { vec![b"https://foo.com".to_vec()] }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I had noticed that fixme and was going to file a separate issue, but you win!