@@ -187,7 +187,7 @@ impl Request<Streaming> {
|
|||||||
///
|
///
|
||||||
/// Consumes the Request.
|
/// Consumes the Request.
|
||||||
pub fn send(self) -> HttpResult<Response> {
|
pub fn send(self) -> HttpResult<Response> {
|
||||||
let raw = try!(self.body.end()).unwrap();
|
let raw = try!(self.body.end()).into_inner();
|
||||||
Response::new(raw)
|
Response::new(raw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,8 +219,8 @@ mod tests {
|
|||||||
Get, Url::parse("http://example.dom").unwrap()
|
Get, Url::parse("http://example.dom").unwrap()
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let req = req.start().unwrap();
|
let req = req.start().unwrap();
|
||||||
let stream = *req.body.end().unwrap().unwrap().downcast::<MockStream>().unwrap();
|
let stream = *req.body.end().unwrap().into_inner().downcast::<MockStream>().unwrap();
|
||||||
let bytes = stream.write.unwrap();
|
let bytes = stream.write.into_inner();
|
||||||
let s = from_utf8(bytes[]).unwrap();
|
let s = from_utf8(bytes[]).unwrap();
|
||||||
assert!(!s.contains("Content-Length:"));
|
assert!(!s.contains("Content-Length:"));
|
||||||
assert!(!s.contains("Transfer-Encoding:"));
|
assert!(!s.contains("Transfer-Encoding:"));
|
||||||
@@ -232,8 +232,8 @@ mod tests {
|
|||||||
Head, Url::parse("http://example.dom").unwrap()
|
Head, Url::parse("http://example.dom").unwrap()
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let req = req.start().unwrap();
|
let req = req.start().unwrap();
|
||||||
let stream = *req.body.end().unwrap().unwrap().downcast::<MockStream>().unwrap();
|
let stream = *req.body.end().unwrap().into_inner().downcast::<MockStream>().unwrap();
|
||||||
let bytes = stream.write.unwrap();
|
let bytes = stream.write.into_inner();
|
||||||
let s = from_utf8(bytes[]).unwrap();
|
let s = from_utf8(bytes[]).unwrap();
|
||||||
assert!(!s.contains("Content-Length:"));
|
assert!(!s.contains("Content-Length:"));
|
||||||
assert!(!s.contains("Transfer-Encoding:"));
|
assert!(!s.contains("Transfer-Encoding:"));
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ impl Response {
|
|||||||
&self.status_raw
|
&self.status_raw
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwraps the Request to return the NetworkStream underneath.
|
/// Consumes the Request to return the NetworkStream underneath.
|
||||||
pub fn unwrap(self) -> Box<NetworkStream + Send> {
|
pub fn into_inner(self) -> Box<NetworkStream + Send> {
|
||||||
self.body.unwrap().unwrap()
|
self.body.unwrap().into_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +95,9 @@ impl Reader for Response {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::borrow::Borrowed;
|
||||||
use std::boxed::BoxAny;
|
use std::boxed::BoxAny;
|
||||||
use std::io::BufferedReader;
|
use std::io::BufferedReader;
|
||||||
use std::str::Slice;
|
|
||||||
|
|
||||||
use header::Headers;
|
use header::Headers;
|
||||||
use http::HttpReader::EofReader;
|
use http::HttpReader::EofReader;
|
||||||
@@ -117,10 +117,10 @@ mod tests {
|
|||||||
headers: Headers::new(),
|
headers: Headers::new(),
|
||||||
version: version::HttpVersion::Http11,
|
version: version::HttpVersion::Http11,
|
||||||
body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)),
|
body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)),
|
||||||
status_raw: RawStatus(200, Slice("OK"))
|
status_raw: RawStatus(200, Borrowed("OK"))
|
||||||
};
|
};
|
||||||
|
|
||||||
let b = res.unwrap().downcast::<MockStream>().unwrap();
|
let b = res.into_inner().downcast::<MockStream>().unwrap();
|
||||||
assert_eq!(b, box MockStream::new());
|
assert_eq!(b, box MockStream::new());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
//! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
|
//! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::ascii::{AsciiExt, AsciiCast};
|
use std::ascii::{AsciiExt, AsciiCast};
|
||||||
|
use std::borrow::{Borrowed, Owned};
|
||||||
use std::fmt::{mod, Show};
|
use std::fmt::{mod, Show};
|
||||||
use std::intrinsics::TypeId;
|
use std::intrinsics::TypeId;
|
||||||
use std::raw::TraitObject;
|
use std::raw::TraitObject;
|
||||||
use std::str::{SendStr, Slice, Owned};
|
use std::str::SendStr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::{Entries, Occupied, Vacant};
|
use std::collections::hash_map::{Entries, Occupied, Vacant};
|
||||||
use std::sync::RWLock;
|
use std::sync::RWLock;
|
||||||
@@ -95,7 +96,7 @@ fn header_name<T: Header>() -> &'static str {
|
|||||||
/// A map of header fields on requests and responses.
|
/// A map of header fields on requests and responses.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Headers {
|
pub struct Headers {
|
||||||
data: HashMap<CaseInsensitive<SendStr>, RWLock<Item>>
|
data: HashMap<CaseInsensitive, RWLock<Item>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Headers {
|
impl Headers {
|
||||||
@@ -136,7 +137,7 @@ impl Headers {
|
|||||||
///
|
///
|
||||||
/// The field is determined by the type of the value being set.
|
/// The field is determined by the type of the value being set.
|
||||||
pub fn set<H: Header + HeaderFormat>(&mut self, value: H) {
|
pub fn set<H: Header + HeaderFormat>(&mut self, value: H) {
|
||||||
self.data.insert(CaseInsensitive(Slice(header_name::<H>())),
|
self.data.insert(CaseInsensitive(Borrowed(header_name::<H>())),
|
||||||
RWLock::new(Item::typed(box value as Box<HeaderFormat + Send + Sync>)));
|
RWLock::new(Item::typed(box value as Box<HeaderFormat + Send + Sync>)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ impl Headers {
|
|||||||
pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
|
pub fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
|
||||||
self.data
|
self.data
|
||||||
// FIXME(reem): Find a better way to do this lookup without find_equiv.
|
// FIXME(reem): Find a better way to do this lookup without find_equiv.
|
||||||
.get(&CaseInsensitive(Slice(unsafe { mem::transmute::<&str, &str>(name) })))
|
.get(&CaseInsensitive(Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))
|
||||||
.and_then(|item| {
|
.and_then(|item| {
|
||||||
let lock = item.read();
|
let lock = item.read();
|
||||||
if let Some(ref raw) = lock.raw {
|
if let Some(ref raw) = lock.raw {
|
||||||
@@ -177,8 +178,8 @@ impl Headers {
|
|||||||
/// # let mut headers = Headers::new();
|
/// # let mut headers = Headers::new();
|
||||||
/// headers.set_raw("content-length", vec!["5".as_bytes().to_vec()]);
|
/// headers.set_raw("content-length", vec!["5".as_bytes().to_vec()]);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_raw<K: IntoMaybeOwned<'static>>(&mut self, name: K, value: Vec<Vec<u8>>) {
|
pub fn set_raw<K: IntoCow<'static, String, str>>(&mut self, name: K, value: Vec<Vec<u8>>) {
|
||||||
self.data.insert(CaseInsensitive(name.into_maybe_owned()), RWLock::new(Item::raw(value)));
|
self.data.insert(CaseInsensitive(name.into_cow()), RWLock::new(Item::raw(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the header field's value, if it exists.
|
/// Get a reference to the header field's value, if it exists.
|
||||||
@@ -200,7 +201,7 @@ impl Headers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_parse<H: Header + HeaderFormat>(&self) -> Option<&RWLock<Item>> {
|
fn get_or_parse<H: Header + HeaderFormat>(&self) -> Option<&RWLock<Item>> {
|
||||||
self.data.get(&CaseInsensitive(Slice(header_name::<H>()))).and_then(|item| get_or_parse::<H>(item))
|
self.data.get(&CaseInsensitive(Borrowed(header_name::<H>()))).and_then(|item| get_or_parse::<H>(item))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a boolean of whether a certain header is in the map.
|
/// Returns a boolean of whether a certain header is in the map.
|
||||||
@@ -214,13 +215,13 @@ impl Headers {
|
|||||||
/// let has_type = headers.has::<ContentType>();
|
/// let has_type = headers.has::<ContentType>();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn has<H: Header + HeaderFormat>(&self) -> bool {
|
pub fn has<H: Header + HeaderFormat>(&self) -> bool {
|
||||||
self.data.contains_key(&CaseInsensitive(Slice(header_name::<H>())))
|
self.data.contains_key(&CaseInsensitive(Borrowed(header_name::<H>())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a header from the map, if one existed.
|
/// Removes a header from the map, if one existed.
|
||||||
/// Returns true if a header has been removed.
|
/// Returns true if a header has been removed.
|
||||||
pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool {
|
pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool {
|
||||||
self.data.remove(&CaseInsensitive(Slice(Header::header_name(None::<H>)))).is_some()
|
self.data.remove(&CaseInsensitive(Borrowed(Header::header_name(None::<H>)))).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the header fields.
|
/// Returns an iterator over the header fields.
|
||||||
@@ -252,7 +253,7 @@ impl fmt::Show for Headers {
|
|||||||
|
|
||||||
/// An `Iterator` over the fields in a `Headers` map.
|
/// An `Iterator` over the fields in a `Headers` map.
|
||||||
pub struct HeadersItems<'a> {
|
pub struct HeadersItems<'a> {
|
||||||
inner: Entries<'a, CaseInsensitive<SendStr>, RWLock<Item>>
|
inner: Entries<'a, CaseInsensitive, RWLock<Item>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
|
impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
|
||||||
@@ -265,13 +266,13 @@ impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returned with the `HeadersItems` iterator.
|
/// Returned with the `HeadersItems` iterator.
|
||||||
pub struct HeaderView<'a>(&'a CaseInsensitive<SendStr>, &'a RWLock<Item>);
|
pub struct HeaderView<'a>(&'a CaseInsensitive, &'a RWLock<Item>);
|
||||||
|
|
||||||
impl<'a> HeaderView<'a> {
|
impl<'a> HeaderView<'a> {
|
||||||
/// Check if a HeaderView is a certain Header.
|
/// Check if a HeaderView is a certain Header.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is<H: Header>(&self) -> bool {
|
pub fn is<H: Header>(&self) -> bool {
|
||||||
CaseInsensitive(header_name::<H>().into_maybe_owned()) == *self.0
|
CaseInsensitive(header_name::<H>().into_cow()) == *self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the Header name as a slice.
|
/// Get the Header name as a slice.
|
||||||
@@ -432,10 +433,16 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
//#[deriving(Clone)]
|
||||||
struct CaseInsensitive<S: Str>(S);
|
struct CaseInsensitive(SendStr);
|
||||||
|
|
||||||
impl<S: Str> Str for CaseInsensitive<S> {
|
impl Clone for CaseInsensitive {
|
||||||
|
fn clone(&self) -> CaseInsensitive {
|
||||||
|
CaseInsensitive((*self.0).clone().into_cow())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Str for CaseInsensitive {
|
||||||
fn as_slice(&self) -> &str {
|
fn as_slice(&self) -> &str {
|
||||||
let CaseInsensitive(ref s) = *self;
|
let CaseInsensitive(ref s) = *self;
|
||||||
s.as_slice()
|
s.as_slice()
|
||||||
@@ -443,29 +450,27 @@ impl<S: Str> Str for CaseInsensitive<S> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Str> fmt::Show for CaseInsensitive<S> {
|
impl fmt::Show for CaseInsensitive {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.as_slice().fmt(fmt)
|
self.as_slice().fmt(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Str> PartialEq for CaseInsensitive<S> {
|
impl PartialEq for CaseInsensitive {
|
||||||
fn eq(&self, other: &CaseInsensitive<S>) -> bool {
|
fn eq(&self, other: &CaseInsensitive) -> bool {
|
||||||
self.as_slice().eq_ignore_ascii_case(other.as_slice())
|
self.as_slice().eq_ignore_ascii_case(other.as_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Str> Eq for CaseInsensitive<S> {}
|
impl Eq for CaseInsensitive {}
|
||||||
|
|
||||||
impl<S: Str, S2: Str> Equiv<CaseInsensitive<S2>> for CaseInsensitive<S> {
|
impl Equiv<CaseInsensitive> for CaseInsensitive {
|
||||||
fn equiv(&self, other: &CaseInsensitive<S2>) -> bool {
|
fn equiv(&self, other: &CaseInsensitive) -> bool {
|
||||||
let left = CaseInsensitive(self.as_slice());
|
self == other
|
||||||
let right = CaseInsensitive(other.as_slice());
|
|
||||||
left == right
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Str, H: hash::Writer> hash::Hash<H> for CaseInsensitive<S> {
|
impl<H: hash::Writer> hash::Hash<H> for CaseInsensitive {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash(&self, hasher: &mut H) {
|
fn hash(&self, hasher: &mut H) {
|
||||||
for b in self.as_slice().bytes() {
|
for b in self.as_slice().bytes() {
|
||||||
@@ -491,7 +496,7 @@ impl<H: HeaderFormat> Show for HeaderFormatter<H> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::io::MemReader;
|
use std::io::MemReader;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::Slice;
|
use std::borrow::Borrowed;
|
||||||
use std::hash::sip::hash;
|
use std::hash::sip::hash;
|
||||||
use mime::{Mime, Text, Plain};
|
use mime::{Mime, Text, Plain};
|
||||||
use super::CaseInsensitive;
|
use super::CaseInsensitive;
|
||||||
@@ -506,8 +511,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_case_insensitive() {
|
fn test_case_insensitive() {
|
||||||
let a = CaseInsensitive(Slice("foobar"));
|
let a = CaseInsensitive(Borrowed("foobar"));
|
||||||
let b = CaseInsensitive(Slice("FOOBAR"));
|
let b = CaseInsensitive(Borrowed("FOOBAR"));
|
||||||
|
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
assert_eq!(hash(&a), hash(&b));
|
assert_eq!(hash(&a), hash(&b));
|
||||||
|
|||||||
25
src/http.rs
25
src/http.rs
@@ -1,9 +1,10 @@
|
|||||||
//! Pieces pertaining to the HTTP message protocol.
|
//! Pieces pertaining to the HTTP message protocol.
|
||||||
|
use std::borrow::{Borrowed, Owned};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{mod, Reader, IoResult, BufWriter};
|
use std::io::{mod, Reader, IoResult, BufWriter};
|
||||||
use std::num::from_u16;
|
use std::num::from_u16;
|
||||||
use std::str::{mod, SendStr, Slice, Owned};
|
use std::str::{mod, SendStr};
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@@ -559,9 +560,15 @@ pub fn read_request_line<R: Reader>(stream: &mut R) -> HttpResult<RequestLine> {
|
|||||||
pub type StatusLine = (HttpVersion, RawStatus);
|
pub type StatusLine = (HttpVersion, RawStatus);
|
||||||
|
|
||||||
/// The raw status code and reason-phrase.
|
/// The raw status code and reason-phrase.
|
||||||
#[deriving(PartialEq, Show, Clone)]
|
#[deriving(PartialEq, Show)]
|
||||||
pub struct RawStatus(pub u16, pub SendStr);
|
pub struct RawStatus(pub u16, pub SendStr);
|
||||||
|
|
||||||
|
impl Clone for RawStatus {
|
||||||
|
fn clone(&self) -> RawStatus {
|
||||||
|
RawStatus(self.0, (*self.1).clone().into_cow())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Read the StatusLine, such as `HTTP/1.1 200 OK`.
|
/// Read the StatusLine, such as `HTTP/1.1 200 OK`.
|
||||||
///
|
///
|
||||||
/// > The first line of a response message is the status-line, consisting
|
/// > The first line of a response message is the status-line, consisting
|
||||||
@@ -632,7 +639,7 @@ pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<RawStatus> {
|
|||||||
Some(status) => match status.canonical_reason() {
|
Some(status) => match status.canonical_reason() {
|
||||||
Some(phrase) => {
|
Some(phrase) => {
|
||||||
if phrase == reason {
|
if phrase == reason {
|
||||||
Slice(phrase)
|
Borrowed(phrase)
|
||||||
} else {
|
} else {
|
||||||
Owned(reason.into_string())
|
Owned(reason.into_string())
|
||||||
}
|
}
|
||||||
@@ -657,7 +664,7 @@ fn expect(r: IoResult<u8>, expected: u8) -> HttpResult<()> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::io::{mod, MemReader, MemWriter};
|
use std::io::{mod, MemReader, MemWriter};
|
||||||
use std::str::{Slice, Owned};
|
use std::borrow::{Borrowed, Owned};
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
use uri::RequestUri;
|
use uri::RequestUri;
|
||||||
use uri::RequestUri::{Star, AbsoluteUri, AbsolutePath, Authority};
|
use uri::RequestUri::{Star, AbsoluteUri, AbsolutePath, Authority};
|
||||||
@@ -727,8 +734,8 @@ mod tests {
|
|||||||
assert_eq!(read_status(&mut mem(s)), result);
|
assert_eq!(read_status(&mut mem(s)), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
read("200 OK\r\n", Ok(RawStatus(200, Slice("OK"))));
|
read("200 OK\r\n", Ok(RawStatus(200, Borrowed("OK"))));
|
||||||
read("404 Not Found\r\n", Ok(RawStatus(404, Slice("Not Found"))));
|
read("404 Not Found\r\n", Ok(RawStatus(404, Borrowed("Not Found"))));
|
||||||
read("200 crazy pants\r\n", Ok(RawStatus(200, Owned("crazy pants".to_string()))));
|
read("200 crazy pants\r\n", Ok(RawStatus(200, Owned("crazy pants".to_string()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,7 +755,7 @@ mod tests {
|
|||||||
let mut w = super::HttpWriter::ChunkedWriter(MemWriter::new());
|
let mut w = super::HttpWriter::ChunkedWriter(MemWriter::new());
|
||||||
w.write(b"foo bar").unwrap();
|
w.write(b"foo bar").unwrap();
|
||||||
w.write(b"baz quux herp").unwrap();
|
w.write(b"baz quux herp").unwrap();
|
||||||
let buf = w.end().unwrap().unwrap();
|
let buf = w.end().unwrap().into_inner();
|
||||||
let s = from_utf8(buf.as_slice()).unwrap();
|
let s = from_utf8(buf.as_slice()).unwrap();
|
||||||
assert_eq!(s, "7\r\nfoo bar\r\nD\r\nbaz quux herp\r\n0\r\n\r\n");
|
assert_eq!(s, "7\r\nfoo bar\r\nD\r\nbaz quux herp\r\n0\r\n\r\n");
|
||||||
}
|
}
|
||||||
@@ -760,7 +767,7 @@ mod tests {
|
|||||||
w.write(b"foo bar").unwrap();
|
w.write(b"foo bar").unwrap();
|
||||||
assert_eq!(w.write(b"baz"), Err(io::standard_error(io::ShortWrite(1))));
|
assert_eq!(w.write(b"baz"), Err(io::standard_error(io::ShortWrite(1))));
|
||||||
|
|
||||||
let buf = w.end().unwrap().unwrap();
|
let buf = w.end().unwrap().into_inner();
|
||||||
let s = from_utf8(buf.as_slice()).unwrap();
|
let s = from_utf8(buf.as_slice()).unwrap();
|
||||||
assert_eq!(s, "foo barb");
|
assert_eq!(s, "foo barb");
|
||||||
}
|
}
|
||||||
@@ -774,7 +781,7 @@ mod tests {
|
|||||||
#[bench]
|
#[bench]
|
||||||
fn bench_read_status(b: &mut Bencher) {
|
fn bench_read_status(b: &mut Bencher) {
|
||||||
b.bytes = b"404 Not Found\r\n".len() as u64;
|
b.bytes = b"404 Not Found\r\n".len() as u64;
|
||||||
b.iter(|| assert_eq!(read_status(&mut mem("404 Not Found\r\n")), Ok(RawStatus(404, Slice("Not Found")))));
|
b.iter(|| assert_eq!(read_status(&mut mem("404 Not Found\r\n")), Ok(RawStatus(404, Borrowed("Not Found")))));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user