Merge pull request #127 from jgillich/enum

namespaced enums
This commit is contained in:
Jonathan Reem
2014-11-19 14:45:20 -08:00
14 changed files with 594 additions and 566 deletions

View File

@@ -6,7 +6,7 @@ use std::io::net::ip::Ipv4Addr;
static PHRASE: &'static [u8] = b"Hello World!"; static PHRASE: &'static [u8] = b"Hello World!";
fn hyper_handle(mut incoming: hyper::server::Incoming) { fn hyper_handle(mut incoming: hyper::server::Incoming) {
let mut pool = TaskPool::new(100); let pool = TaskPool::new(100);
for conn in incoming { for conn in incoming {
pool.execute(proc() { pool.execute(proc() {

View File

@@ -3,13 +3,16 @@ use std::io::{BufferedWriter, IoResult};
use url::Url; use url::Url;
use method::{mod, Get, Post, Delete, Put, Patch, Head, Options}; use method;
use method::Method::{Get, Post, Delete, Put, Patch, Head, Options};
use header::Headers; use header::Headers;
use header::common::{mod, Host}; use header::common::{mod, Host};
use net::{NetworkStream, NetworkConnector, HttpStream, Fresh, Streaming}; use net::{NetworkStream, NetworkConnector, HttpStream, Fresh, Streaming};
use http::{HttpWriter, ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter, LINE_ENDING}; use HttpError::HttpUriError;
use http::{HttpWriter, LINE_ENDING};
use http::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter};
use version; use version;
use {HttpResult, HttpUriError}; use HttpResult;
use client::Response; use client::Response;
@@ -69,7 +72,7 @@ impl Request<Fresh> {
method: method, method: method,
headers: headers, headers: headers,
url: url, url: url,
version: version::Http11, version: version::HttpVersion::Http11,
body: stream body: stream
}) })
} }
@@ -141,7 +144,7 @@ impl Request<Fresh> {
let encodings = match self.headers.get_mut::<common::TransferEncoding>() { let encodings = match self.headers.get_mut::<common::TransferEncoding>() {
Some(&common::TransferEncoding(ref mut encodings)) => { Some(&common::TransferEncoding(ref mut encodings)) => {
//TODO: check if chunked is already in encodings. use HashSet? //TODO: check if chunked is already in encodings. use HashSet?
encodings.push(common::transfer_encoding::Chunked); encodings.push(common::transfer_encoding::Encoding::Chunked);
false false
}, },
None => true None => true
@@ -149,7 +152,7 @@ impl Request<Fresh> {
if encodings { if encodings {
self.headers.set::<common::TransferEncoding>( self.headers.set::<common::TransferEncoding>(
common::TransferEncoding(vec![common::transfer_encoding::Chunked])) common::TransferEncoding(vec![common::transfer_encoding::Encoding::Chunked]))
} }
} }
@@ -206,7 +209,7 @@ mod tests {
use std::boxed::BoxAny; use std::boxed::BoxAny;
use std::str::from_utf8; use std::str::from_utf8;
use url::Url; use url::Url;
use method::{Get, Head}; use method::Method::{Get, Head};
use mock::MockStream; use mock::MockStream;
use super::Request; use super::Request;

View File

@@ -3,12 +3,13 @@ use std::io::{BufferedReader, IoResult};
use header; use header;
use header::common::{ContentLength, TransferEncoding}; use header::common::{ContentLength, TransferEncoding};
use header::common::transfer_encoding::Chunked; use header::common::transfer_encoding::Encoding::Chunked;
use net::{NetworkStream, HttpStream}; use net::{NetworkStream, HttpStream};
use http::{read_status_line, HttpReader, SizedReader, ChunkedReader, EofReader}; use http::{read_status_line, HttpReader};
use http::HttpReader::{SizedReader, ChunkedReader, EofReader};
use status; use status;
use version; use version;
use {HttpResult}; use HttpResult;
/// 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> {
@@ -85,7 +86,7 @@ mod tests {
use std::io::BufferedReader; use std::io::BufferedReader;
use header::Headers; use header::Headers;
use http::EofReader; use http::HttpReader::EofReader;
use mock::MockStream; use mock::MockStream;
use net::NetworkStream; use net::NetworkStream;
use status; use status;
@@ -97,9 +98,9 @@ mod tests {
#[test] #[test]
fn test_unwrap() { fn test_unwrap() {
let res = Response { let res = Response {
status: status::Ok, status: status::StatusCode::Ok,
headers: Headers::new(), headers: Headers::new(),
version: version::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>))
}; };

View File

@@ -3,6 +3,8 @@ use std::fmt::{mod, Show};
use std::str::FromStr; use std::str::FromStr;
use super::util::{from_comma_delimited, fmt_comma_delimited}; use super::util::{from_comma_delimited, fmt_comma_delimited};
use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
/// The `Connection` header. /// The `Connection` header.
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Connection(pub Vec<ConnectionOption>); pub struct Connection(pub Vec<ConnectionOption>);

View File

@@ -3,6 +3,8 @@ use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use super::util::{from_comma_delimited, fmt_comma_delimited}; use super::util::{from_comma_delimited, fmt_comma_delimited};
use self::Encoding::{Chunked, Gzip, Deflate, Compress, EncodingExt};
/// The `Transfer-Encoding` header. /// The `Transfer-Encoding` header.
/// ///
/// This header describes the encoding of the message body. It can be /// This header describes the encoding of the message body. It can be
@@ -32,7 +34,6 @@ pub struct TransferEncoding(pub Vec<Encoding>);
pub enum Encoding { pub enum Encoding {
/// The `chunked` encoding. /// The `chunked` encoding.
Chunked, Chunked,
/// The `gzip` encoding. /// The `gzip` encoding.
Gzip, Gzip,
/// The `deflate` encoding. /// The `deflate` encoding.

View File

@@ -3,6 +3,8 @@ use std::fmt::{mod, Show};
use std::str::FromStr; use std::str::FromStr;
use super::util::{from_comma_delimited, fmt_comma_delimited}; use super::util::{from_comma_delimited, fmt_comma_delimited};
use self::Protocol::{WebSocket, ProtocolExt};
/// The `Upgrade` header. /// The `Upgrade` header.
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Upgrade(Vec<Protocol>); pub struct Upgrade(Vec<Protocol>);

View File

@@ -9,9 +9,15 @@ use url::Url;
use method; use method;
use status; use status;
use uri; use uri;
use version::{HttpVersion, Http09, Http10, Http11, Http20}; use uri::RequestUri::{AbsolutePath, AbsoluteUri, Authority, Star};
use {HttpResult, HttpMethodError, HttpVersionError, HttpIoError, HttpUriError}; use version::HttpVersion;
use {HttpHeaderError, HttpStatusError}; use version::HttpVersion::{Http09, Http10, Http11, Http20};
use HttpError::{HttpHeaderError, HttpIoError, HttpMethodError, HttpStatusError,
HttpUriError, HttpVersionError};
use HttpResult;
use self::HttpReader::{SizedReader, ChunkedReader, EofReader};
use self::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter};
/// Readers to handle different Transfer-Encodings. /// Readers to handle different Transfer-Encodings.
/// ///
@@ -321,21 +327,21 @@ pub fn read_method<R: Reader>(stream: &mut R) -> HttpResult<method::Method> {
let mut buf = [SP, ..16]; let mut buf = [SP, ..16];
if !try!(read_until_space(stream, &mut buf)) { if !try!(read_until_space(stream, &mut buf)) {
return Err(HttpMethodError); return Err(HttpMethodError);
} }
debug!("method buf = {}", buf[].to_ascii()); debug!("method buf = {}", buf[].to_ascii());
let maybe_method = match buf[0..7] { let maybe_method = match buf[0..7] {
b"GET " => Some(method::Get), b"GET " => Some(method::Method::Get),
b"PUT " => Some(method::Put), b"PUT " => Some(method::Method::Put),
b"POST " => Some(method::Post), b"POST " => Some(method::Method::Post),
b"HEAD " => Some(method::Head), b"HEAD " => Some(method::Method::Head),
b"PATCH " => Some(method::Patch), b"PATCH " => Some(method::Method::Patch),
b"TRACE " => Some(method::Trace), b"TRACE " => Some(method::Method::Trace),
b"DELETE " => Some(method::Delete), b"DELETE " => Some(method::Method::Delete),
b"CONNECT" => Some(method::Connect), b"CONNECT" => Some(method::Method::Connect),
b"OPTIONS" => Some(method::Options), b"OPTIONS" => Some(method::Method::Options),
_ => None, _ => None,
}; };
@@ -343,10 +349,10 @@ pub fn read_method<R: Reader>(stream: &mut R) -> HttpResult<method::Method> {
match (maybe_method, buf[]) { match (maybe_method, buf[]) {
(Some(method), _) => Ok(method), (Some(method), _) => Ok(method),
(None, ext) if is_valid_method(buf) => { (None, ext) if is_valid_method(&buf) => {
use std::str::raw; use std::str::raw;
// We already checked that the buffer is ASCII // We already checked that the buffer is ASCII
Ok(method::Extension(unsafe { raw::from_utf8(ext) }.trim().into_string())) Ok(method::Method::Extension(unsafe { raw::from_utf8(ext) }.trim().into_string()))
}, },
_ => Err(HttpMethodError) _ => Err(HttpMethodError)
} }
@@ -367,7 +373,7 @@ pub fn read_uri<R: Reader>(stream: &mut R) -> HttpResult<uri::RequestUri> {
let mut s = String::new(); let mut s = String::new();
if b == STAR { if b == STAR {
try!(expect(stream.read_byte(), SP)); try!(expect(stream.read_byte(), SP));
return Ok(uri::Star) return Ok(Star)
} else { } else {
s.push(b as char); s.push(b as char);
loop { loop {
@@ -386,10 +392,10 @@ pub fn read_uri<R: Reader>(stream: &mut R) -> HttpResult<uri::RequestUri> {
debug!("uri buf = {}", s); debug!("uri buf = {}", s);
if s.as_slice().starts_with("/") { if s.as_slice().starts_with("/") {
Ok(uri::AbsolutePath(s)) Ok(AbsolutePath(s))
} else if s.as_slice().contains("/") { } else if s.as_slice().contains("/") {
match Url::parse(s.as_slice()) { match Url::parse(s.as_slice()) {
Ok(u) => Ok(uri::AbsoluteUri(u)), Ok(u) => Ok(AbsoluteUri(u)),
Err(_e) => { Err(_e) => {
debug!("URL err {}", _e); debug!("URL err {}", _e);
Err(HttpUriError) Err(HttpUriError)
@@ -401,7 +407,7 @@ pub fn read_uri<R: Reader>(stream: &mut R) -> HttpResult<uri::RequestUri> {
match Url::parse(temp.as_slice()) { match Url::parse(temp.as_slice()) {
Ok(_u) => { Ok(_u) => {
todo!("compare vs u.authority()"); todo!("compare vs u.authority()");
Ok(uri::Authority(s)) Ok(Authority(s))
} }
Err(_e) => { Err(_e) => {
debug!("URL err {}", _e); debug!("URL err {}", _e);
@@ -608,11 +614,14 @@ fn expect(r: IoResult<u8>, expected: u8) -> HttpResult<()> {
mod tests { mod tests {
use std::io::{mod, MemReader, MemWriter}; use std::io::{mod, MemReader, MemWriter};
use test::Bencher; use test::Bencher;
use uri::{RequestUri, Star, AbsoluteUri, AbsolutePath, Authority}; use uri::RequestUri;
use uri::RequestUri::{Star, AbsoluteUri, AbsolutePath, Authority};
use method; use method;
use status; use status;
use version::{HttpVersion, Http10, Http11, Http20}; use version::HttpVersion;
use {HttpResult, HttpVersionError}; use version::HttpVersion::{Http10, Http11, Http20};
use HttpError::HttpVersionError;
use HttpResult;
use url::Url; use url::Url;
use super::{read_method, read_uri, read_http_version, read_header, RawHeaderLine, read_status}; use super::{read_method, read_uri, read_http_version, read_header, RawHeaderLine, read_status};
@@ -620,22 +629,22 @@ mod tests {
fn mem(s: &str) -> MemReader { fn mem(s: &str) -> MemReader {
MemReader::new(s.as_bytes().to_vec()) MemReader::new(s.as_bytes().to_vec())
} }
#[test] #[test]
fn test_read_method() { fn test_read_method() {
fn read(s: &str, m: method::Method) { fn read(s: &str, m: method::Method) {
assert_eq!(read_method(&mut mem(s)), Ok(m)); assert_eq!(read_method(&mut mem(s)), Ok(m));
} }
read("GET /", method::Get); read("GET /", method::Method::Get);
read("POST /", method::Post); read("POST /", method::Method::Post);
read("PUT /", method::Put); read("PUT /", method::Method::Put);
read("HEAD /", method::Head); read("HEAD /", method::Method::Head);
read("OPTIONS /", method::Options); read("OPTIONS /", method::Method::Options);
read("CONNECT /", method::Connect); read("CONNECT /", method::Method::Connect);
read("TRACE /", method::Trace); read("TRACE /", method::Method::Trace);
read("PATCH /", method::Patch); read("PATCH /", method::Method::Patch);
read("FOO /", method::Extension("FOO".to_string())); read("FOO /", method::Method::Extension("FOO".to_string()));
} }
#[test] #[test]
@@ -671,7 +680,7 @@ mod tests {
assert_eq!(read_status(&mut mem(s)), result); assert_eq!(read_status(&mut mem(s)), result);
} }
read("200 OK\r\n", Ok(status::Ok)); read("200 OK\r\n", Ok(status::StatusCode::Ok));
} }
#[test] #[test]
@@ -687,7 +696,7 @@ mod tests {
#[test] #[test]
fn test_write_chunked() { fn test_write_chunked() {
use std::str::from_utf8; use std::str::from_utf8;
let mut w = super::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().unwrap();
@@ -698,7 +707,7 @@ mod tests {
#[test] #[test]
fn test_write_sized() { fn test_write_sized() {
use std::str::from_utf8; use std::str::from_utf8;
let mut w = super::SizedWriter(MemWriter::new(), 8); let mut w = super::HttpWriter::SizedWriter(MemWriter::new(), 8);
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))));
@@ -710,7 +719,7 @@ mod tests {
#[bench] #[bench]
fn bench_read_method(b: &mut Bencher) { fn bench_read_method(b: &mut Bencher) {
b.bytes = b"CONNECT ".len() as u64; b.bytes = b"CONNECT ".len() as u64;
b.iter(|| assert_eq!(read_method(&mut mem("CONNECT ")), Ok(method::Connect))); b.iter(|| assert_eq!(read_method(&mut mem("CONNECT ")), Ok(method::Method::Connect)));
} }
} }

View File

@@ -140,8 +140,8 @@ extern crate cookie;
pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port}; pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
pub use mimewrapper::mime; pub use mimewrapper::mime;
pub use url::Url; pub use url::Url;
pub use method::{Get, Head, Post, Delete}; pub use method::Method::{Get, Head, Post, Delete};
pub use status::{Ok, BadRequest, NotFound}; pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server; pub use server::Server;
use std::fmt; use std::fmt;
@@ -150,6 +150,8 @@ use std::io::IoError;
use std::rt::backtrace; use std::rt::backtrace;
use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError,
HttpHeaderError, HttpStatusError, HttpIoError};
macro_rules! todo( macro_rules! todo(
($($arg:tt)*) => (if cfg!(not(ndebug)) { ($($arg:tt)*) => (if cfg!(not(ndebug)) {

View File

@@ -2,6 +2,9 @@
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use self::Method::{Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch,
Extension};
/// The Request Method (VERB) /// The Request Method (VERB)
/// ///
/// Currently includes 8 variants representing the 8 methods defined in /// Currently includes 8 variants representing the 8 methods defined in

View File

@@ -16,6 +16,8 @@ use typeable::Typeable;
use openssl::ssl::{SslStream, SslContext, Sslv23}; use openssl::ssl::{SslStream, SslContext, Sslv23};
use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed}; use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed};
use self::HttpStream::{Http, Https};
/// The write-status indicating headers have not been written. /// The write-status indicating headers have not been written.
pub struct Fresh; pub struct Fresh;

View File

@@ -11,7 +11,8 @@ use method;
use header::Headers; use header::Headers;
use header::common::ContentLength; use header::common::ContentLength;
use http::{read_request_line}; use http::{read_request_line};
use http::{HttpReader, SizedReader, ChunkedReader}; use http::HttpReader;
use http::HttpReader::{SizedReader, ChunkedReader};
use net::NetworkStream; use net::NetworkStream;
use uri::RequestUri; use uri::RequestUri;

View File

@@ -8,7 +8,8 @@ use time::now_utc;
use header; use header;
use header::common; use header::common;
use http::{CR, LF, LINE_ENDING, HttpWriter, ThroughWriter, ChunkedWriter, SizedWriter}; use http::{CR, LF, LINE_ENDING, HttpWriter};
use http::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter};
use status; use status;
use net::{NetworkStream, Fresh, Streaming}; use net::{NetworkStream, Fresh, Streaming};
use version; use version;
@@ -52,8 +53,8 @@ impl Response<Fresh> {
/// Creates a new Response that can be used to write to a network stream. /// Creates a new Response that can be used to write to a network stream.
pub fn new<S: NetworkStream>(stream: S) -> Response<Fresh> { pub fn new<S: NetworkStream>(stream: S) -> Response<Fresh> {
Response { Response {
status: status::Ok, status: status::StatusCode::Ok,
version: version::Http11, version: version::HttpVersion::Http11,
headers: header::Headers::new(), headers: header::Headers::new(),
body: ThroughWriter(BufferedWriter::new(box stream as Box<NetworkStream + Send>)) body: ThroughWriter(BufferedWriter::new(box stream as Box<NetworkStream + Send>))
} }
@@ -85,7 +86,7 @@ impl Response<Fresh> {
let encodings = match self.headers.get_mut::<common::TransferEncoding>() { let encodings = match self.headers.get_mut::<common::TransferEncoding>() {
Some(&common::TransferEncoding(ref mut encodings)) => { Some(&common::TransferEncoding(ref mut encodings)) => {
//TODO: check if chunked is already in encodings. use HashSet? //TODO: check if chunked is already in encodings. use HashSet?
encodings.push(common::transfer_encoding::Chunked); encodings.push(common::transfer_encoding::Encoding::Chunked);
false false
}, },
None => true None => true
@@ -93,7 +94,7 @@ impl Response<Fresh> {
if encodings { if encodings {
self.headers.set::<common::TransferEncoding>( self.headers.set::<common::TransferEncoding>(
common::TransferEncoding(vec![common::transfer_encoding::Chunked])) common::TransferEncoding(vec![common::transfer_encoding::Encoding::Chunked]))
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,8 @@
//! the `HttpVersion` enum. //! the `HttpVersion` enum.
use std::fmt; use std::fmt;
use self::HttpVersion::{Http09, Http10, Http11, Http20};
/// Represents a version of the HTTP spec. /// Represents a version of the HTTP spec.
#[deriving(PartialEq, PartialOrd)] #[deriving(PartialEq, PartialOrd)]
pub enum HttpVersion { pub enum HttpVersion {