diff --git a/Cargo.toml b/Cargo.toml
index 6d85a8159..8b00260c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,10 +21,17 @@ path = "src/lib.rs"
name = "test"
path = "src/main.rs"
+[features]
+default = ["nightly"]
+
+# Enable nightly features
+nightly = []
+
[dependencies]
time = "0.1"
http = "0.1"
httparse = "0.1"
+cookie = { version="0.10", features=["percent-encode"] }
slab = "0.4"
sha1 = "0.2"
url = "1.5"
diff --git a/src/context.rs b/src/context.rs
index 2941d71c8..7a82bf847 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -9,7 +9,7 @@ use actix::fut::ActorFuture;
use actix::dev::{AsyncContextApi, ActorAddressCell, ActorItemsCell, SpawnHandle};
use route::{Route, Frame};
-use httpmessage::{HttpRequest, HttpResponse};
+use httpmessage::HttpResponse;
/// Actor execution context
@@ -102,8 +102,8 @@ impl HttpContext where A: Actor + Route {
}
/// Start response processing
- pub fn start>(&mut self, request: HttpRequest, response: R) {
- self.stream.push_back(Frame::Message(request, response.into()))
+ pub fn start>(&mut self, response: R) {
+ self.stream.push_back(Frame::Message(response.into()))
}
/// Write payload
diff --git a/src/error.rs b/src/error.rs
index b4525b300..57badbf28 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -5,27 +5,15 @@ use std::io::Error as IoError;
use std::str::Utf8Error;
use std::string::FromUtf8Error;
+use cookie;
use httparse;
+use http::{StatusCode, Error as HttpError};
-use self::Error::{
- Method,
- Uri,
- Version,
- Header,
- Status,
- Timeout,
- Io,
- TooLarge,
- Incomplete,
- Utf8
-};
-
-/// Result type often returned from methods that can have error.
-pub type Result = ::std::result::Result;
+use httpmessage::{Body, HttpResponse};
/// A set of errors that can occur parsing HTTP streams.
#[derive(Debug)]
-pub enum Error {
+pub enum ParseError {
/// An invalid `Method`, such as `GE,T`.
Method,
/// An invalid `Uri`, such as `exam ple.domain`.
@@ -43,79 +31,107 @@ pub enum Error {
/// A timeout occurred waiting for an IO event.
#[allow(dead_code)]
Timeout,
+ /// Unexpected EOF during parsing
+ Eof,
/// An `io::Error` that occurred while trying to read or write to a network stream.
Io(IoError),
/// Parsing a field as string failed
Utf8(Utf8Error),
}
-impl fmt::Display for Error {
+impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
- Io(ref e) => fmt::Display::fmt(e, f),
- Utf8(ref e) => fmt::Display::fmt(e, f),
+ ParseError::Io(ref e) => fmt::Display::fmt(e, f),
+ ParseError::Utf8(ref e) => fmt::Display::fmt(e, f),
ref e => f.write_str(e.description()),
}
}
}
-impl StdError for Error {
+impl StdError for ParseError {
fn description(&self) -> &str {
match *self {
- Method => "Invalid Method specified",
- Version => "Invalid HTTP version specified",
- Header => "Invalid Header provided",
- TooLarge => "Message head is too large",
- Status => "Invalid Status provided",
- Incomplete => "Message is incomplete",
- Timeout => "Timeout",
- Uri => "Uri error",
- Io(ref e) => e.description(),
- Utf8(ref e) => e.description(),
+ ParseError::Method => "Invalid Method specified",
+ ParseError::Version => "Invalid HTTP version specified",
+ ParseError::Header => "Invalid Header provided",
+ ParseError::TooLarge => "Message head is too large",
+ ParseError::Status => "Invalid Status provided",
+ ParseError::Incomplete => "Message is incomplete",
+ ParseError::Timeout => "Timeout",
+ ParseError::Uri => "Uri error",
+ ParseError::Eof => "Unexpected eof during parse",
+ ParseError::Io(ref e) => e.description(),
+ ParseError::Utf8(ref e) => e.description(),
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
- Io(ref error) => Some(error),
- Utf8(ref error) => Some(error),
+ ParseError::Io(ref error) => Some(error),
+ ParseError::Utf8(ref error) => Some(error),
_ => None,
}
}
}
-impl From for Error {
- fn from(err: IoError) -> Error {
- Io(err)
+impl From for ParseError {
+ fn from(err: IoError) -> ParseError {
+ ParseError::Io(err)
}
}
-impl From for Error {
- fn from(err: Utf8Error) -> Error {
- Utf8(err)
+impl From for ParseError {
+ fn from(err: Utf8Error) -> ParseError {
+ ParseError::Utf8(err)
}
}
-impl From for Error {
- fn from(err: FromUtf8Error) -> Error {
- Utf8(err.utf8_error())
+impl From for ParseError {
+ fn from(err: FromUtf8Error) -> ParseError {
+ ParseError::Utf8(err.utf8_error())
}
}
-impl From for Error {
- fn from(err: httparse::Error) -> Error {
+impl From for ParseError {
+ fn from(err: httparse::Error) -> ParseError {
match err {
httparse::Error::HeaderName |
httparse::Error::HeaderValue |
httparse::Error::NewLine |
- httparse::Error::Token => Header,
- httparse::Error::Status => Status,
- httparse::Error::TooManyHeaders => TooLarge,
- httparse::Error::Version => Version,
+ httparse::Error::Token => ParseError::Header,
+ httparse::Error::Status => ParseError::Status,
+ httparse::Error::TooManyHeaders => ParseError::TooLarge,
+ httparse::Error::Version => ParseError::Version,
}
}
}
+/// Return BadRequest for ParseError
+impl From for HttpResponse {
+ fn from(err: ParseError) -> Self {
+ HttpResponse::new(StatusCode::BAD_REQUEST,
+ Body::Binary(err.description().into()))
+ }
+}
+
+/// Return InternalServerError for HttpError,
+/// Response generation can return HttpError, so it is internal error
+impl From for HttpResponse {
+ fn from(err: HttpError) -> Self {
+ HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR,
+ Body::Binary(err.description().into()))
+ }
+}
+
+/// Return BadRequest for cookie::ParseError
+impl From for HttpResponse {
+ fn from(err: cookie::ParseError) -> Self {
+ HttpResponse::new(StatusCode::BAD_REQUEST,
+ Body::Binary(err.description().into()))
+ }
+}
+
#[cfg(test)]
mod tests {
use std::error::Error as StdError;
diff --git a/src/httpcodes.rs b/src/httpcodes.rs
index 4e5e65580..76470da18 100644
--- a/src/httpcodes.rs
+++ b/src/httpcodes.rs
@@ -35,8 +35,8 @@ impl StaticResponse {
}
impl RouteHandler for StaticResponse {
- fn handle(&self, req: HttpRequest, _: Payload, _: Rc) -> Task {
- Task::reply(req, HttpResponse::new(self.0, Body::Empty))
+ fn handle(&self, _: HttpRequest, _: Payload, _: Rc) -> Task {
+ Task::reply(HttpResponse::new(self.0, Body::Empty))
}
}
diff --git a/src/httpmessage.rs b/src/httpmessage.rs
index 50c1d25fc..ad2a09ac2 100644
--- a/src/httpmessage.rs
+++ b/src/httpmessage.rs
@@ -1,8 +1,8 @@
//! Pieces pertaining to the HTTP message protocol.
-use std::{io, mem};
-use std::error::Error as StdError;
+use std::{io, mem, str};
use std::convert::Into;
+use cookie;
use bytes::Bytes;
use http::{Method, StatusCode, Version, Uri, HeaderMap, HttpTryFrom, Error};
use http::header::{self, HeaderName, HeaderValue};
@@ -78,6 +78,17 @@ impl HttpRequest {
self.uri.query()
}
+ /// Return request cookie.
+ pub fn cookie(&self) -> Result