Merge pull request #425 from hyperium/unfeat-core
chore(stability): remove core feature gate
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
//! Client Responses
|
//! Client Responses
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::num::FromPrimitive;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use buffer::BufReader;
|
use buffer::BufReader;
|
||||||
@@ -13,7 +12,6 @@ use http::HttpReader::{SizedReader, ChunkedReader, EofReader};
|
|||||||
use status;
|
use status;
|
||||||
use version;
|
use version;
|
||||||
use HttpResult;
|
use HttpResult;
|
||||||
use HttpError::HttpStatusError;
|
|
||||||
|
|
||||||
/// A response for a client request to a remote server.
|
/// A response for a client request to a remote server.
|
||||||
pub struct Response<S = HttpStream> {
|
pub struct Response<S = HttpStream> {
|
||||||
@@ -39,10 +37,7 @@ impl Response {
|
|||||||
let raw_status = head.subject;
|
let raw_status = head.subject;
|
||||||
let headers = head.headers;
|
let headers = head.headers;
|
||||||
|
|
||||||
let status = match FromPrimitive::from_u16(raw_status.0) {
|
let status = status::StatusCode::from_u16(raw_status.0);
|
||||||
Some(status) => status,
|
|
||||||
None => return Err(HttpStatusError)
|
|
||||||
};
|
|
||||||
debug!("version={:?}, status={:?}", head.version, status);
|
debug!("version={:?}, status={:?}", head.version, status);
|
||||||
debug!("headers={:?}", headers);
|
debug!("headers={:?}", headers);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
use std::any::Any;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::{FromStr, from_utf8};
|
use std::str::{FromStr, from_utf8};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::marker::Reflect;
|
|
||||||
use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline};
|
use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline};
|
||||||
use header::{Header, HeaderFormat};
|
use header::{Header, HeaderFormat};
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ impl<S: Scheme> DerefMut for Authorization<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Scheme + Reflect + 'static> Header for Authorization<S> where <S as FromStr>::Err: 'static {
|
impl<S: Scheme + Any> Header for Authorization<S> where <S as FromStr>::Err: 'static {
|
||||||
fn header_name() -> &'static str {
|
fn header_name() -> &'static str {
|
||||||
"Authorization"
|
"Authorization"
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ impl<S: Scheme + Reflect + 'static> Header for Authorization<S> where <S as From
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Scheme + Reflect + 'static> HeaderFormat for Authorization<S> where <S as FromStr>::Err: 'static {
|
impl<S: Scheme + Any> HeaderFormat for Authorization<S> where <S as FromStr>::Err: 'static {
|
||||||
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match Scheme::scheme(None::<S>) {
|
match Scheme::scheme(None::<S>) {
|
||||||
Some(scheme) => try!(write!(fmt, "{} ", scheme)),
|
Some(scheme) => try!(write!(fmt, "{} ", scheme)),
|
||||||
@@ -71,7 +71,7 @@ impl Scheme for String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self)
|
write!(f, "{}", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
use std::any::Any;
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
|
|
||||||
|
use typeable::Typeable;
|
||||||
|
|
||||||
use super::cell::{OptCell, PtrMapCell};
|
use super::cell::{OptCell, PtrMapCell};
|
||||||
use header::{Header, HeaderFormat};
|
use header::{Header, HeaderFormat};
|
||||||
|
|
||||||
@@ -24,7 +27,7 @@ impl Item {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_typed(ty: Box<HeaderFormat + Send + Sync>) -> Item {
|
pub fn new_typed(ty: Box<HeaderFormat + Send + Sync>) -> Item {
|
||||||
let map = PtrMapCell::new();
|
let map = PtrMapCell::new();
|
||||||
unsafe { map.insert((&*ty).get_type_id(), ty); }
|
unsafe { map.insert((*ty).get_type(), ty); }
|
||||||
Item {
|
Item {
|
||||||
raw: OptCell::new(None),
|
raw: OptCell::new(None),
|
||||||
typed: map,
|
typed: map,
|
||||||
@@ -51,7 +54,7 @@ impl Item {
|
|||||||
&raw[..]
|
&raw[..]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn typed<H: Header + HeaderFormat>(&self) -> Option<&H> {
|
pub fn typed<H: Header + HeaderFormat + Any>(&self) -> Option<&H> {
|
||||||
let tid = TypeId::of::<H>();
|
let tid = TypeId::of::<H>();
|
||||||
match self.typed.get(tid) {
|
match self.typed.get(tid) {
|
||||||
Some(val) => Some(val),
|
Some(val) => Some(val),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use std::iter::{FromIterator, IntoIterator};
|
|||||||
use std::{mem, fmt};
|
use std::{mem, fmt};
|
||||||
|
|
||||||
use {httparse, traitobject};
|
use {httparse, traitobject};
|
||||||
|
use typeable::Typeable;
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
|
|
||||||
use self::internals::Item;
|
use self::internals::Item;
|
||||||
@@ -50,7 +51,7 @@ pub trait Header: Clone + Any + Send + Sync {
|
|||||||
/// A trait for any object that will represent a header field and value.
|
/// A trait for any object that will represent a header field and value.
|
||||||
///
|
///
|
||||||
/// This trait represents the formatting of a Header for output to a TcpStream.
|
/// This trait represents the formatting of a Header for output to a TcpStream.
|
||||||
pub trait HeaderFormat: fmt::Debug + HeaderClone + Any + Send + Sync {
|
pub trait HeaderFormat: fmt::Debug + HeaderClone + Any + Typeable + Send + Sync {
|
||||||
/// Format a header to be output into a TcpStream.
|
/// Format a header to be output into a TcpStream.
|
||||||
///
|
///
|
||||||
/// This method is not allowed to introduce an Err not produced
|
/// This method is not allowed to introduce an Err not produced
|
||||||
@@ -61,12 +62,12 @@ pub trait HeaderFormat: fmt::Debug + HeaderClone + Any + Send + Sync {
|
|||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait HeaderClone {
|
pub trait HeaderClone {
|
||||||
fn clone_box(&self) -> Box<HeaderFormat + Sync + Send>;
|
fn clone_box(&self) -> Box<HeaderFormat + Send + Sync>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: HeaderFormat + Send + Sync + Clone> HeaderClone for T {
|
impl<T: HeaderFormat + Clone> HeaderClone for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone_box(&self) -> Box<HeaderFormat + Sync + Send> {
|
fn clone_box(&self) -> Box<HeaderFormat + Send + Sync> {
|
||||||
Box::new(self.clone())
|
Box::new(self.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::{FromPrimitive, ToPrimitive};
|
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
/// Represents a quality used in quality values.
|
/// Represents a quality used in quality values.
|
||||||
@@ -20,7 +19,7 @@ use std::str;
|
|||||||
/// floating point data type (`f32`) consumes four bytes, hyper uses an `u16` value to store the
|
/// floating point data type (`f32`) consumes four bytes, hyper uses an `u16` value to store the
|
||||||
/// quality internally. For performance reasons you may set quality directly to a value between
|
/// quality internally. For performance reasons you may set quality directly to a value between
|
||||||
/// 0 and 1000 e.g. `Quality(532)` matches the quality `q=0.532`.
|
/// 0 and 1000 e.g. `Quality(532)` matches the quality `q=0.532`.
|
||||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct Quality(pub u16);
|
pub struct Quality(pub u16);
|
||||||
|
|
||||||
impl fmt::Display for Quality {
|
impl fmt::Display for Quality {
|
||||||
@@ -33,43 +32,6 @@ impl fmt::Display for Quality {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for Quality {
|
|
||||||
fn from_i64(n: i64) -> Option<Quality> {
|
|
||||||
match n >= 0 {
|
|
||||||
true => FromPrimitive::from_u64(n as u64),
|
|
||||||
false => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_u64(n: u64) -> Option<Quality> {
|
|
||||||
match n <= 1000 {
|
|
||||||
true => Some(Quality(n as u16)),
|
|
||||||
false => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_f64(n: f64) -> Option<Quality> {
|
|
||||||
match n >= 0f64 && n <= 1f64 {
|
|
||||||
true => Some(Quality((n * 1000f64) as u16)),
|
|
||||||
false => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToPrimitive for Quality {
|
|
||||||
fn to_i64(&self) -> Option<i64> {
|
|
||||||
Some(self.0 as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u64(&self) -> Option<u64> {
|
|
||||||
Some(self.0 as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_f64(&self) -> Option<f64> {
|
|
||||||
Some((self.0 as f64) / 1000f64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Quality {
|
impl Default for Quality {
|
||||||
fn default() -> Quality {
|
fn default() -> Quality {
|
||||||
Quality(1000)
|
Quality(1000)
|
||||||
@@ -91,7 +53,10 @@ impl<T> QualityItem<T> {
|
|||||||
/// The item can be of any type.
|
/// The item can be of any type.
|
||||||
/// The quality should be a value in the range [0, 1].
|
/// The quality should be a value in the range [0, 1].
|
||||||
pub fn new(item: T, quality: Quality) -> QualityItem<T> {
|
pub fn new(item: T, quality: Quality) -> QualityItem<T> {
|
||||||
QualityItem{item: item, quality: quality}
|
QualityItem {
|
||||||
|
item: item,
|
||||||
|
quality: quality
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,12 +101,21 @@ impl<T: str::FromStr> str::FromStr for QualityItem<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
match raw_item.parse::<T>() {
|
match raw_item.parse::<T>() {
|
||||||
Ok(item) => Ok(QualityItem::new(item, FromPrimitive::from_f32(quality).unwrap())),
|
// we already checked above that the quality is within range
|
||||||
|
Ok(item) => Ok(QualityItem::new(item, from_f32(quality))),
|
||||||
Err(_) => return Err(()),
|
Err(_) => return Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_f32(f: f32) -> Quality {
|
||||||
|
// this function is only used internally. A check that `f` is within range
|
||||||
|
// should be done before calling this method. Just in case, this
|
||||||
|
// debug_assert should catch if we were forgetful
|
||||||
|
debug_assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0");
|
||||||
|
Quality((f * 1000f32) as u16)
|
||||||
|
}
|
||||||
|
|
||||||
/// Convinience function to wrap a value in a `QualityItem`
|
/// Convinience function to wrap a value in a `QualityItem`
|
||||||
/// Sets `q` to the default 1.0
|
/// Sets `q` to the default 1.0
|
||||||
pub fn qitem<T>(item: T) -> QualityItem<T> {
|
pub fn qitem<T>(item: T) -> QualityItem<T> {
|
||||||
@@ -150,13 +124,12 @@ pub fn qitem<T>(item: T) -> QualityItem<T> {
|
|||||||
|
|
||||||
/// Convenience function to create a `Quality` fromt a float.
|
/// Convenience function to create a `Quality` fromt a float.
|
||||||
pub fn q(f: f32) -> Quality {
|
pub fn q(f: f32) -> Quality {
|
||||||
FromPrimitive::from_f32(f).expect("q value must be between 0.0 and 1.0")
|
assert!(f >= 0f32 && f <= 1f32, "q value must be between 0.0 and 1.0");
|
||||||
|
from_f32(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::num::FromPrimitive;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::encoding::*;
|
use super::super::encoding::*;
|
||||||
|
|
||||||
@@ -206,25 +179,32 @@ mod tests {
|
|||||||
assert_eq!(x, Err(()));
|
assert_eq!(x, Err(()));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn test_quality_item_from_str6() {
|
||||||
|
let x: Result<QualityItem<Encoding>, ()> = "gzip; q=2".parse();
|
||||||
|
assert_eq!(x, Err(()));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn test_quality_item_ordering() {
|
fn test_quality_item_ordering() {
|
||||||
let x: QualityItem<Encoding> = "gzip; q=0.5".parse().ok().unwrap();
|
let x: QualityItem<Encoding> = "gzip; q=0.5".parse().ok().unwrap();
|
||||||
let y: QualityItem<Encoding> = "gzip; q=0.273".parse().ok().unwrap();
|
let y: QualityItem<Encoding> = "gzip; q=0.273".parse().ok().unwrap();
|
||||||
let comparision_result: bool = x.gt(&y);
|
let comparision_result: bool = x.gt(&y);
|
||||||
assert_eq!(comparision_result, true)
|
assert_eq!(comparision_result, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_quality() {
|
fn test_quality() {
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_f64(0.421f64));
|
assert_eq!(q(0.5), Quality(500));
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_f32(0.421f32));
|
}
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_i16(421i16));
|
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_i32(421i32));
|
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_i64(421i64));
|
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_u16(421u16));
|
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_u32(421u32));
|
|
||||||
assert_eq!(Some(Quality(421)), FromPrimitive::from_u64(421u64));
|
|
||||||
|
|
||||||
assert_eq!(None::<Quality>, FromPrimitive::from_i16(-5i16));
|
#[test]
|
||||||
assert_eq!(None::<Quality>, FromPrimitive::from_i32(5000i32));
|
#[should_panic]
|
||||||
assert_eq!(None::<Quality>, FromPrimitive::from_f32(2.5f32));
|
fn test_quality_invalid() {
|
||||||
|
q(-1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_quality_invalid2() {
|
||||||
|
q(2.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
use std::borrow::{Cow, ToOwned};
|
use std::borrow::{Cow, ToOwned};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::io::{self, Read, Write, BufRead};
|
use std::io::{self, Read, Write, BufRead};
|
||||||
use std::num::FromPrimitive;
|
|
||||||
|
|
||||||
use httparse;
|
use httparse;
|
||||||
|
|
||||||
@@ -378,11 +377,8 @@ impl<'a> TryParse for httparse::Response<'a> {
|
|||||||
Ok(match try!(res.parse(buf)) {
|
Ok(match try!(res.parse(buf)) {
|
||||||
httparse::Status::Complete(len) => {
|
httparse::Status::Complete(len) => {
|
||||||
let code = res.code.unwrap();
|
let code = res.code.unwrap();
|
||||||
let reason = match <StatusCode as FromPrimitive>::from_u16(code) {
|
let reason = match StatusCode::from_u16(code).canonical_reason() {
|
||||||
Some(status) => match status.canonical_reason() {
|
Some(reason) => Cow::Borrowed(reason),
|
||||||
Some(reason) => Cow::Borrowed(reason),
|
|
||||||
None => Cow::Owned(res.reason.unwrap().to_owned())
|
|
||||||
},
|
|
||||||
None => Cow::Owned(res.reason.unwrap().to_owned())
|
None => Cow::Owned(res.reason.unwrap().to_owned())
|
||||||
};
|
};
|
||||||
httparse::Status::Complete((Incoming {
|
httparse::Status::Complete((Incoming {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#![doc(html_root_url = "https://hyperium.github.io/hyper/hyper/index.html")]
|
#![doc(html_root_url = "https://hyperium.github.io/hyper/hyper/index.html")]
|
||||||
#![feature(core)]
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![cfg_attr(test, deny(warnings))]
|
#![cfg_attr(test, deny(warnings))]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::marker::Reflect;
|
|
||||||
|
|
||||||
use openssl::ssl::{Ssl, SslStream, SslContext};
|
use openssl::ssl::{Ssl, SslStream, SslContext};
|
||||||
use openssl::ssl::SslVerifyMode::SslVerifyNone;
|
use openssl::ssl::SslVerifyMode::SslVerifyNone;
|
||||||
@@ -135,7 +134,7 @@ impl NetworkStream + Send {
|
|||||||
/// If the underlying type is T, get a mutable reference to the contained
|
/// If the underlying type is T, get a mutable reference to the contained
|
||||||
/// data.
|
/// data.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn downcast_mut<T: Reflect + 'static>(&mut self) -> Option<&mut T> {
|
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
|
||||||
if self.is::<T>() {
|
if self.is::<T>() {
|
||||||
Some(unsafe { self.downcast_mut_unchecked() })
|
Some(unsafe { self.downcast_mut_unchecked() })
|
||||||
} else {
|
} else {
|
||||||
@@ -144,7 +143,7 @@ impl NetworkStream + Send {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// If the underlying type is T, extract it.
|
/// If the underlying type is T, extract it.
|
||||||
pub fn downcast<T: Reflect + 'static>(self: Box<NetworkStream + Send>)
|
pub fn downcast<T: Any>(self: Box<NetworkStream + Send>)
|
||||||
-> Result<Box<T>, Box<NetworkStream + Send>> {
|
-> Result<Box<T>, Box<NetworkStream + Send>> {
|
||||||
if self.is::<T>() {
|
if self.is::<T>() {
|
||||||
Ok(unsafe { self.downcast_unchecked() })
|
Ok(unsafe { self.downcast_unchecked() })
|
||||||
|
|||||||
318
src/status.rs
318
src/status.rs
@@ -1,6 +1,5 @@
|
|||||||
//! HTTP status codes
|
//! HTTP status codes
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::{FromPrimitive, ToPrimitive};
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
// shamelessly lifted from Teepee. I tried a few schemes, this really
|
// shamelessly lifted from Teepee. I tried a few schemes, this really
|
||||||
@@ -20,11 +19,9 @@ use std::cmp::Ordering;
|
|||||||
/// `self.class().default_code()`:
|
/// `self.class().default_code()`:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(core)]
|
|
||||||
/// # use std::num::FromPrimitive;
|
|
||||||
/// # use hyper::status::StatusCode;
|
/// # use hyper::status::StatusCode;
|
||||||
/// let statusopt: Option<StatusCode> = FromPrimitive::from_u16(137u16);
|
/// let status = StatusCode::Unregistered(123);
|
||||||
/// assert_eq!(statusopt.unwrap().class().default_code(), StatusCode::Continue);
|
/// assert_eq!(status.class().default_code(), StatusCode::Continue);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// IANA maintain the [Hypertext Transfer Protocol (HTTP) Status Code
|
/// IANA maintain the [Hypertext Transfer Protocol (HTTP) Status Code
|
||||||
@@ -225,6 +222,136 @@ pub enum StatusCode {
|
|||||||
|
|
||||||
impl StatusCode {
|
impl StatusCode {
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn from_u16(n: u16) -> StatusCode {
|
||||||
|
match n {
|
||||||
|
100 => StatusCode::Continue,
|
||||||
|
101 => StatusCode::SwitchingProtocols,
|
||||||
|
102 => StatusCode::Processing,
|
||||||
|
200 => StatusCode::Ok,
|
||||||
|
201 => StatusCode::Created,
|
||||||
|
202 => StatusCode::Accepted,
|
||||||
|
203 => StatusCode::NonAuthoritativeInformation,
|
||||||
|
204 => StatusCode::NoContent,
|
||||||
|
205 => StatusCode::ResetContent,
|
||||||
|
206 => StatusCode::PartialContent,
|
||||||
|
207 => StatusCode::MultiStatus,
|
||||||
|
208 => StatusCode::AlreadyReported,
|
||||||
|
226 => StatusCode::ImUsed,
|
||||||
|
300 => StatusCode::MultipleChoices,
|
||||||
|
301 => StatusCode::MovedPermanently,
|
||||||
|
302 => StatusCode::Found,
|
||||||
|
303 => StatusCode::SeeOther,
|
||||||
|
304 => StatusCode::NotModified,
|
||||||
|
305 => StatusCode::UseProxy,
|
||||||
|
307 => StatusCode::TemporaryRedirect,
|
||||||
|
308 => StatusCode::PermanentRedirect,
|
||||||
|
400 => StatusCode::BadRequest,
|
||||||
|
401 => StatusCode::Unauthorized,
|
||||||
|
402 => StatusCode::PaymentRequired,
|
||||||
|
403 => StatusCode::Forbidden,
|
||||||
|
404 => StatusCode::NotFound,
|
||||||
|
405 => StatusCode::MethodNotAllowed,
|
||||||
|
406 => StatusCode::NotAcceptable,
|
||||||
|
407 => StatusCode::ProxyAuthenticationRequired,
|
||||||
|
408 => StatusCode::RequestTimeout,
|
||||||
|
409 => StatusCode::Conflict,
|
||||||
|
410 => StatusCode::Gone,
|
||||||
|
411 => StatusCode::LengthRequired,
|
||||||
|
412 => StatusCode::PreconditionFailed,
|
||||||
|
413 => StatusCode::PayloadTooLarge,
|
||||||
|
414 => StatusCode::UriTooLong,
|
||||||
|
415 => StatusCode::UnsupportedMediaType,
|
||||||
|
416 => StatusCode::RangeNotSatisfiable,
|
||||||
|
417 => StatusCode::ExpectationFailed,
|
||||||
|
418 => StatusCode::ImATeapot,
|
||||||
|
422 => StatusCode::UnprocessableEntity,
|
||||||
|
423 => StatusCode::Locked,
|
||||||
|
424 => StatusCode::FailedDependency,
|
||||||
|
426 => StatusCode::UpgradeRequired,
|
||||||
|
428 => StatusCode::PreconditionRequired,
|
||||||
|
429 => StatusCode::TooManyRequests,
|
||||||
|
431 => StatusCode::RequestHeaderFieldsTooLarge,
|
||||||
|
500 => StatusCode::InternalServerError,
|
||||||
|
501 => StatusCode::NotImplemented,
|
||||||
|
502 => StatusCode::BadGateway,
|
||||||
|
503 => StatusCode::ServiceUnavailable,
|
||||||
|
504 => StatusCode::GatewayTimeout,
|
||||||
|
505 => StatusCode::HttpVersionNotSupported,
|
||||||
|
506 => StatusCode::VariantAlsoNegotiates,
|
||||||
|
507 => StatusCode::InsufficientStorage,
|
||||||
|
508 => StatusCode::LoopDetected,
|
||||||
|
510 => StatusCode::NotExtended,
|
||||||
|
511 => StatusCode::NetworkAuthenticationRequired,
|
||||||
|
_ => StatusCode::Unregistered(n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn to_u16(&self) -> u16 {
|
||||||
|
match *self {
|
||||||
|
StatusCode::Continue => 100,
|
||||||
|
StatusCode::SwitchingProtocols => 101,
|
||||||
|
StatusCode::Processing => 102,
|
||||||
|
StatusCode::Ok => 200,
|
||||||
|
StatusCode::Created => 201,
|
||||||
|
StatusCode::Accepted => 202,
|
||||||
|
StatusCode::NonAuthoritativeInformation => 203,
|
||||||
|
StatusCode::NoContent => 204,
|
||||||
|
StatusCode::ResetContent => 205,
|
||||||
|
StatusCode::PartialContent => 206,
|
||||||
|
StatusCode::MultiStatus => 207,
|
||||||
|
StatusCode::AlreadyReported => 208,
|
||||||
|
StatusCode::ImUsed => 226,
|
||||||
|
StatusCode::MultipleChoices => 300,
|
||||||
|
StatusCode::MovedPermanently => 301,
|
||||||
|
StatusCode::Found => 302,
|
||||||
|
StatusCode::SeeOther => 303,
|
||||||
|
StatusCode::NotModified => 304,
|
||||||
|
StatusCode::UseProxy => 305,
|
||||||
|
StatusCode::TemporaryRedirect => 307,
|
||||||
|
StatusCode::PermanentRedirect => 308,
|
||||||
|
StatusCode::BadRequest => 400,
|
||||||
|
StatusCode::Unauthorized => 401,
|
||||||
|
StatusCode::PaymentRequired => 402,
|
||||||
|
StatusCode::Forbidden => 403,
|
||||||
|
StatusCode::NotFound => 404,
|
||||||
|
StatusCode::MethodNotAllowed => 405,
|
||||||
|
StatusCode::NotAcceptable => 406,
|
||||||
|
StatusCode::ProxyAuthenticationRequired => 407,
|
||||||
|
StatusCode::RequestTimeout => 408,
|
||||||
|
StatusCode::Conflict => 409,
|
||||||
|
StatusCode::Gone => 410,
|
||||||
|
StatusCode::LengthRequired => 411,
|
||||||
|
StatusCode::PreconditionFailed => 412,
|
||||||
|
StatusCode::PayloadTooLarge => 413,
|
||||||
|
StatusCode::UriTooLong => 414,
|
||||||
|
StatusCode::UnsupportedMediaType => 415,
|
||||||
|
StatusCode::RangeNotSatisfiable => 416,
|
||||||
|
StatusCode::ExpectationFailed => 417,
|
||||||
|
StatusCode::ImATeapot => 418,
|
||||||
|
StatusCode::UnprocessableEntity => 422,
|
||||||
|
StatusCode::Locked => 423,
|
||||||
|
StatusCode::FailedDependency => 424,
|
||||||
|
StatusCode::UpgradeRequired => 426,
|
||||||
|
StatusCode::PreconditionRequired => 428,
|
||||||
|
StatusCode::TooManyRequests => 429,
|
||||||
|
StatusCode::RequestHeaderFieldsTooLarge => 431,
|
||||||
|
StatusCode::InternalServerError => 500,
|
||||||
|
StatusCode::NotImplemented => 501,
|
||||||
|
StatusCode::BadGateway => 502,
|
||||||
|
StatusCode::ServiceUnavailable => 503,
|
||||||
|
StatusCode::GatewayTimeout => 504,
|
||||||
|
StatusCode::HttpVersionNotSupported => 505,
|
||||||
|
StatusCode::VariantAlsoNegotiates => 506,
|
||||||
|
StatusCode::InsufficientStorage => 507,
|
||||||
|
StatusCode::LoopDetected => 508,
|
||||||
|
StatusCode::NotExtended => 510,
|
||||||
|
StatusCode::NetworkAuthenticationRequired => 511,
|
||||||
|
StatusCode::Unregistered(n) => n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the standardised `reason-phrase` for this status code.
|
/// Get the standardised `reason-phrase` for this status code.
|
||||||
///
|
///
|
||||||
/// This is mostly here for servers writing responses, but could potentially have application
|
/// This is mostly here for servers writing responses, but could potentially have application
|
||||||
@@ -312,7 +439,7 @@ impl StatusCode {
|
|||||||
|
|
||||||
/// Determine the class of a status code, based on its first digit.
|
/// Determine the class of a status code, based on its first digit.
|
||||||
pub fn class(&self) -> StatusClass {
|
pub fn class(&self) -> StatusClass {
|
||||||
match self.to_u16().unwrap() {
|
match self.to_u16() {
|
||||||
100...199 => StatusClass::Informational,
|
100...199 => StatusClass::Informational,
|
||||||
200...299 => StatusClass::Success,
|
200...299 => StatusClass::Success,
|
||||||
300...399 => StatusClass::Redirection,
|
300...399 => StatusClass::Redirection,
|
||||||
@@ -363,19 +490,9 @@ impl Copy for StatusCode {}
|
|||||||
/// assert_eq!(format!("{}", Unregistered(123)),
|
/// assert_eq!(format!("{}", Unregistered(123)),
|
||||||
/// "123 <unknown status code>");
|
/// "123 <unknown status code>");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
/// If you wish to just include the number, convert to `u16` instead:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// #![feature(core)]
|
|
||||||
/// # use std::num::ToPrimitive;
|
|
||||||
/// # use hyper::status::StatusCode::{ImATeapot, Unregistered};
|
|
||||||
/// assert_eq!(format!("{}", ImATeapot.to_u16().unwrap()), "418");
|
|
||||||
/// assert_eq!(format!("{}", Unregistered(123).to_u16().unwrap()), "123");
|
|
||||||
/// ```
|
|
||||||
impl fmt::Display for StatusCode {
|
impl fmt::Display for StatusCode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{} {}", self.to_u16().unwrap(),
|
write!(f, "{} {}", self.to_u16(),
|
||||||
self.canonical_reason().unwrap_or("<unknown status code>"))
|
self.canonical_reason().unwrap_or("<unknown status code>"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,88 +513,10 @@ impl Clone for StatusCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for StatusCode {
|
|
||||||
fn from_i64(n: i64) -> Option<StatusCode> {
|
|
||||||
if n < 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
FromPrimitive::from_u64(n as u64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_u64(n: u64) -> Option<StatusCode> {
|
|
||||||
if n > 65535 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(match n {
|
|
||||||
100 => StatusCode::Continue,
|
|
||||||
101 => StatusCode::SwitchingProtocols,
|
|
||||||
102 => StatusCode::Processing,
|
|
||||||
200 => StatusCode::Ok,
|
|
||||||
201 => StatusCode::Created,
|
|
||||||
202 => StatusCode::Accepted,
|
|
||||||
203 => StatusCode::NonAuthoritativeInformation,
|
|
||||||
204 => StatusCode::NoContent,
|
|
||||||
205 => StatusCode::ResetContent,
|
|
||||||
206 => StatusCode::PartialContent,
|
|
||||||
207 => StatusCode::MultiStatus,
|
|
||||||
208 => StatusCode::AlreadyReported,
|
|
||||||
226 => StatusCode::ImUsed,
|
|
||||||
300 => StatusCode::MultipleChoices,
|
|
||||||
301 => StatusCode::MovedPermanently,
|
|
||||||
302 => StatusCode::Found,
|
|
||||||
303 => StatusCode::SeeOther,
|
|
||||||
304 => StatusCode::NotModified,
|
|
||||||
305 => StatusCode::UseProxy,
|
|
||||||
307 => StatusCode::TemporaryRedirect,
|
|
||||||
308 => StatusCode::PermanentRedirect,
|
|
||||||
400 => StatusCode::BadRequest,
|
|
||||||
401 => StatusCode::Unauthorized,
|
|
||||||
402 => StatusCode::PaymentRequired,
|
|
||||||
403 => StatusCode::Forbidden,
|
|
||||||
404 => StatusCode::NotFound,
|
|
||||||
405 => StatusCode::MethodNotAllowed,
|
|
||||||
406 => StatusCode::NotAcceptable,
|
|
||||||
407 => StatusCode::ProxyAuthenticationRequired,
|
|
||||||
408 => StatusCode::RequestTimeout,
|
|
||||||
409 => StatusCode::Conflict,
|
|
||||||
410 => StatusCode::Gone,
|
|
||||||
411 => StatusCode::LengthRequired,
|
|
||||||
412 => StatusCode::PreconditionFailed,
|
|
||||||
413 => StatusCode::PayloadTooLarge,
|
|
||||||
414 => StatusCode::UriTooLong,
|
|
||||||
415 => StatusCode::UnsupportedMediaType,
|
|
||||||
416 => StatusCode::RangeNotSatisfiable,
|
|
||||||
417 => StatusCode::ExpectationFailed,
|
|
||||||
418 => StatusCode::ImATeapot,
|
|
||||||
422 => StatusCode::UnprocessableEntity,
|
|
||||||
423 => StatusCode::Locked,
|
|
||||||
424 => StatusCode::FailedDependency,
|
|
||||||
426 => StatusCode::UpgradeRequired,
|
|
||||||
428 => StatusCode::PreconditionRequired,
|
|
||||||
429 => StatusCode::TooManyRequests,
|
|
||||||
431 => StatusCode::RequestHeaderFieldsTooLarge,
|
|
||||||
500 => StatusCode::InternalServerError,
|
|
||||||
501 => StatusCode::NotImplemented,
|
|
||||||
502 => StatusCode::BadGateway,
|
|
||||||
503 => StatusCode::ServiceUnavailable,
|
|
||||||
504 => StatusCode::GatewayTimeout,
|
|
||||||
505 => StatusCode::HttpVersionNotSupported,
|
|
||||||
506 => StatusCode::VariantAlsoNegotiates,
|
|
||||||
507 => StatusCode::InsufficientStorage,
|
|
||||||
508 => StatusCode::LoopDetected,
|
|
||||||
510 => StatusCode::NotExtended,
|
|
||||||
511 => StatusCode::NetworkAuthenticationRequired,
|
|
||||||
_ => StatusCode::Unregistered(n as u16),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for StatusCode {
|
impl PartialOrd for StatusCode {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering> {
|
||||||
self.to_u16().unwrap().partial_cmp(&(other.to_u16().unwrap()))
|
self.to_u16().partial_cmp(&(other.to_u16()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,76 +533,6 @@ impl Ord for StatusCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToPrimitive for StatusCode {
|
|
||||||
fn to_i64(&self) -> Option<i64> {
|
|
||||||
Some(self.to_u64().unwrap() as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u64(&self) -> Option<u64> {
|
|
||||||
Some(match *self {
|
|
||||||
StatusCode::Continue => 100,
|
|
||||||
StatusCode::SwitchingProtocols => 101,
|
|
||||||
StatusCode::Processing => 102,
|
|
||||||
StatusCode::Ok => 200,
|
|
||||||
StatusCode::Created => 201,
|
|
||||||
StatusCode::Accepted => 202,
|
|
||||||
StatusCode::NonAuthoritativeInformation => 203,
|
|
||||||
StatusCode::NoContent => 204,
|
|
||||||
StatusCode::ResetContent => 205,
|
|
||||||
StatusCode::PartialContent => 206,
|
|
||||||
StatusCode::MultiStatus => 207,
|
|
||||||
StatusCode::AlreadyReported => 208,
|
|
||||||
StatusCode::ImUsed => 226,
|
|
||||||
StatusCode::MultipleChoices => 300,
|
|
||||||
StatusCode::MovedPermanently => 301,
|
|
||||||
StatusCode::Found => 302,
|
|
||||||
StatusCode::SeeOther => 303,
|
|
||||||
StatusCode::NotModified => 304,
|
|
||||||
StatusCode::UseProxy => 305,
|
|
||||||
StatusCode::TemporaryRedirect => 307,
|
|
||||||
StatusCode::PermanentRedirect => 308,
|
|
||||||
StatusCode::BadRequest => 400,
|
|
||||||
StatusCode::Unauthorized => 401,
|
|
||||||
StatusCode::PaymentRequired => 402,
|
|
||||||
StatusCode::Forbidden => 403,
|
|
||||||
StatusCode::NotFound => 404,
|
|
||||||
StatusCode::MethodNotAllowed => 405,
|
|
||||||
StatusCode::NotAcceptable => 406,
|
|
||||||
StatusCode::ProxyAuthenticationRequired => 407,
|
|
||||||
StatusCode::RequestTimeout => 408,
|
|
||||||
StatusCode::Conflict => 409,
|
|
||||||
StatusCode::Gone => 410,
|
|
||||||
StatusCode::LengthRequired => 411,
|
|
||||||
StatusCode::PreconditionFailed => 412,
|
|
||||||
StatusCode::PayloadTooLarge => 413,
|
|
||||||
StatusCode::UriTooLong => 414,
|
|
||||||
StatusCode::UnsupportedMediaType => 415,
|
|
||||||
StatusCode::RangeNotSatisfiable => 416,
|
|
||||||
StatusCode::ExpectationFailed => 417,
|
|
||||||
StatusCode::ImATeapot => 418,
|
|
||||||
StatusCode::UnprocessableEntity => 422,
|
|
||||||
StatusCode::Locked => 423,
|
|
||||||
StatusCode::FailedDependency => 424,
|
|
||||||
StatusCode::UpgradeRequired => 426,
|
|
||||||
StatusCode::PreconditionRequired => 428,
|
|
||||||
StatusCode::TooManyRequests => 429,
|
|
||||||
StatusCode::RequestHeaderFieldsTooLarge => 431,
|
|
||||||
StatusCode::InternalServerError => 500,
|
|
||||||
StatusCode::NotImplemented => 501,
|
|
||||||
StatusCode::BadGateway => 502,
|
|
||||||
StatusCode::ServiceUnavailable => 503,
|
|
||||||
StatusCode::GatewayTimeout => 504,
|
|
||||||
StatusCode::HttpVersionNotSupported => 505,
|
|
||||||
StatusCode::VariantAlsoNegotiates => 506,
|
|
||||||
StatusCode::InsufficientStorage => 507,
|
|
||||||
StatusCode::LoopDetected => 508,
|
|
||||||
StatusCode::NotExtended => 510,
|
|
||||||
StatusCode::NetworkAuthenticationRequired => 511,
|
|
||||||
StatusCode::Unregistered(n) => n,
|
|
||||||
} as u64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The class of an HTTP `status-code`.
|
/// The class of an HTTP `status-code`.
|
||||||
///
|
///
|
||||||
/// [RFC 7231, section 6 (Response Status Codes)](https://tools.ietf.org/html/rfc7231#section-6):
|
/// [RFC 7231, section 6 (Response Status Codes)](https://tools.ietf.org/html/rfc7231#section-6):
|
||||||
@@ -669,20 +638,3 @@ impl StatusClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToPrimitive for StatusClass {
|
|
||||||
fn to_i64(&self) -> Option<i64> {
|
|
||||||
Some(self.to_u64().unwrap() as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u64(&self) -> Option<u64> {
|
|
||||||
Some(match *self {
|
|
||||||
StatusClass::Informational => 100,
|
|
||||||
StatusClass::Success => 200,
|
|
||||||
StatusClass::Redirection => 300,
|
|
||||||
StatusClass::ClientError => 400,
|
|
||||||
StatusClass::ServerError => 500,
|
|
||||||
StatusClass::NoClass => 200,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::fmt;
|
|||||||
use self::HttpVersion::{Http09, Http10, Http11, Http20};
|
use self::HttpVersion::{Http09, Http10, Http11, Http20};
|
||||||
|
|
||||||
/// Represents a version of the HTTP spec.
|
/// Represents a version of the HTTP spec.
|
||||||
#[derive(PartialEq, PartialOrd, Copy, Debug)]
|
#[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash, Debug)]
|
||||||
pub enum HttpVersion {
|
pub enum HttpVersion {
|
||||||
/// `HTTP/0.9`
|
/// `HTTP/0.9`
|
||||||
Http09,
|
Http09,
|
||||||
|
|||||||
Reference in New Issue
Block a user