1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-10 17:29:36 +00:00

clippy warnings

This commit is contained in:
Nikolay Kim 2018-04-29 09:09:08 -07:00
parent d98d723f97
commit c72d1381a6
62 changed files with 1742 additions and 818 deletions

View file

@ -8,11 +8,11 @@ cache:
matrix:
include:
- rust: 1.22.1
- rust: stable
- rust: beta
- rust: nightly
allow_failures:
- rust: 1.21.0
- rust: nightly
env:

View file

@ -1,7 +1,5 @@
max_width = 89
reorder_imports = true
#reorder_imports_in_group = true
#reorder_imported_names = true
wrap_comments = true
fn_args_density = "Compressed"
use_small_heuristics = false
#use_small_heuristics = false

View file

@ -111,7 +111,12 @@ impl<S: 'static> HttpHandler for HttpApplication<S> {
let mut req = req.with_state(Rc::clone(&self.state), self.router.clone());
let tp = self.get_handler(&mut req);
let inner = Rc::clone(&self.inner);
Ok(Box::new(Pipeline::new(req, Rc::clone(&self.middlewares), inner, tp)))
Ok(Box::new(Pipeline::new(
req,
Rc::clone(&self.middlewares),
inner,
tp,
)))
} else {
Err(req)
}
@ -449,14 +454,20 @@ where
}
let parts = self.parts.as_mut().expect("Use after finish");
parts.handlers.push((path, Box::new(WrapHandler::new(handler))));
parts
.handlers
.push((path, Box::new(WrapHandler::new(handler))));
}
self
}
/// Register a middleware.
pub fn middleware<M: Middleware<S>>(mut self, mw: M) -> App<S> {
self.parts.as_mut().expect("Use after finish").middlewares.push(Box::new(mw));
self.parts
.as_mut()
.expect("Use after finish")
.middlewares
.push(Box::new(mw));
self
}
@ -611,8 +622,9 @@ mod tests {
#[test]
fn test_default_resource() {
let mut app =
App::new().resource("/test", |r| r.f(|_| HttpResponse::Ok())).finish();
let mut app = App::new()
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
.finish();
let req = TestRequest::with_uri("/test").finish();
let resp = app.run(req);
@ -620,14 +632,20 @@ mod tests {
let req = TestRequest::with_uri("/blah").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
let mut app = App::new()
.default_resource(|r| r.f(|_| HttpResponse::MethodNotAllowed()))
.finish();
let req = TestRequest::with_uri("/blah").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::METHOD_NOT_ALLOWED);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::METHOD_NOT_ALLOWED
);
}
#[test]
@ -641,8 +659,9 @@ mod tests {
#[test]
fn test_state() {
let mut app =
App::with_state(10).resource("/", |r| r.f(|_| HttpResponse::Ok())).finish();
let mut app = App::with_state(10)
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
.finish();
let req =
HttpRequest::default().with_state(Rc::clone(&app.state), app.router.clone());
let resp = app.run(req);
@ -674,7 +693,9 @@ mod tests {
#[test]
fn test_handler() {
let mut app = App::new().handler("/test", |_| HttpResponse::Ok()).finish();
let mut app = App::new()
.handler("/test", |_| HttpResponse::Ok())
.finish();
let req = TestRequest::with_uri("/test").finish();
let resp = app.run(req);
@ -690,16 +711,24 @@ mod tests {
let req = TestRequest::with_uri("/testapp").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
let req = TestRequest::with_uri("/blah").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
}
#[test]
fn test_handler2() {
let mut app = App::new().handler("test", |_| HttpResponse::Ok()).finish();
let mut app = App::new()
.handler("test", |_| HttpResponse::Ok())
.finish();
let req = TestRequest::with_uri("/test").finish();
let resp = app.run(req);
@ -715,11 +744,17 @@ mod tests {
let req = TestRequest::with_uri("/testapp").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
let req = TestRequest::with_uri("/blah").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
}
#[test]
@ -743,41 +778,68 @@ mod tests {
let req = TestRequest::with_uri("/prefix/testapp").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
let req = TestRequest::with_uri("/prefix/blah").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
}
#[test]
fn test_route() {
let mut app = App::new()
.route("/test", Method::GET, |_: HttpRequest| HttpResponse::Ok())
.route("/test", Method::POST, |_: HttpRequest| HttpResponse::Created())
.route("/test", Method::GET, |_: HttpRequest| {
HttpResponse::Ok()
})
.route("/test", Method::POST, |_: HttpRequest| {
HttpResponse::Created()
})
.finish();
let req = TestRequest::with_uri("/test").method(Method::GET).finish();
let req = TestRequest::with_uri("/test")
.method(Method::GET)
.finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::OK);
let req = TestRequest::with_uri("/test").method(Method::POST).finish();
let req = TestRequest::with_uri("/test")
.method(Method::POST)
.finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::CREATED);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::CREATED
);
let req = TestRequest::with_uri("/test").method(Method::HEAD).finish();
let req = TestRequest::with_uri("/test")
.method(Method::HEAD)
.finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
}
#[test]
fn test_handler_prefix() {
let mut app =
App::new().prefix("/app").handler("/test", |_| HttpResponse::Ok()).finish();
let mut app = App::new()
.prefix("/app")
.handler("/test", |_| HttpResponse::Ok())
.finish();
let req = TestRequest::with_uri("/test").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
let req = TestRequest::with_uri("/app/test").finish();
let resp = app.run(req);
@ -793,10 +855,16 @@ mod tests {
let req = TestRequest::with_uri("/app/testapp").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
let req = TestRequest::with_uri("/app/blah").finish();
let resp = app.run(req);
assert_eq!(resp.as_response().unwrap().status(), StatusCode::NOT_FOUND);
assert_eq!(
resp.as_response().unwrap().status(),
StatusCode::NOT_FOUND
);
}
}

View file

@ -258,7 +258,9 @@ impl Responder for Binary {
type Error = Error;
fn respond_to(self, _: HttpRequest) -> Result<HttpResponse, Error> {
Ok(HttpResponse::Ok().content_type("application/octet-stream").body(self))
Ok(HttpResponse::Ok()
.content_type("application/octet-stream")
.body(self))
}
}

View file

@ -94,17 +94,13 @@ pub struct Pause {
impl Pause {
/// Create message with pause duration parameter
pub fn new(time: Duration) -> Pause {
Pause {
time: Some(time),
}
Pause { time: Some(time) }
}
}
impl Default for Pause {
fn default() -> Pause {
Pause {
time: None,
}
Pause { time: None }
}
}
@ -431,7 +427,8 @@ impl ClientConnector {
} else {
0
};
self.acquired_per_host.insert(key.clone(), per_host + 1);
self.acquired_per_host
.insert(key.clone(), per_host + 1);
}
fn release_key(&mut self, key: &Key) {
@ -442,7 +439,8 @@ impl ClientConnector {
return;
};
if per_host > 1 {
self.acquired_per_host.insert(key.clone(), per_host - 1);
self.acquired_per_host
.insert(key.clone(), per_host - 1);
} else {
self.acquired_per_host.remove(key);
}
@ -518,7 +516,9 @@ impl ClientConnector {
fn collect_periodic(&mut self, ctx: &mut Context<Self>) {
self.collect(true);
// re-schedule next collect period
ctx.run_later(Duration::from_secs(1), |act, ctx| act.collect_periodic(ctx));
ctx.run_later(Duration::from_secs(1), |act, ctx| {
act.collect_periodic(ctx)
});
// send stats
let stats = mem::replace(&mut self.stats, ClientConnectorStats::default());
@ -583,7 +583,10 @@ impl ClientConnector {
wait,
conn_timeout,
};
self.waiters.entry(key).or_insert_with(VecDeque::new).push_back(waiter);
self.waiters
.entry(key)
.or_insert_with(VecDeque::new)
.push_back(waiter);
rx
}
}
@ -828,7 +831,7 @@ impl fut::ActorFuture for Maintenance {
act.collect_waiters();
// check waiters
let tmp: &mut ClientConnector = unsafe { mem::transmute(act as &mut _) };
let tmp: &mut ClientConnector = unsafe { &mut *(act as *mut _) };
for (key, waiters) in &mut tmp.waiters {
while let Some(waiter) = waiters.pop_front() {
@ -1102,7 +1105,10 @@ impl Pool {
if self.to_close.borrow().is_empty() {
None
} else {
Some(mem::replace(&mut *self.to_close.borrow_mut(), Vec::new()))
Some(mem::replace(
&mut *self.to_close.borrow_mut(),
Vec::new(),
))
}
}
@ -1110,7 +1116,10 @@ impl Pool {
if self.to_release.borrow().is_empty() {
None
} else {
Some(mem::replace(&mut *self.to_release.borrow_mut(), Vec::new()))
Some(mem::replace(
&mut *self.to_release.borrow_mut(),
Vec::new(),
))
}
}

View file

@ -123,7 +123,7 @@ impl HttpResponseParser {
let (len, version, status, headers_len) = {
let b = unsafe {
let b: &[u8] = buf;
mem::transmute(b)
&*(b as *const _)
};
let mut resp = httparse::Response::new(&mut headers);
match resp.parse(b)? {

View file

@ -269,7 +269,11 @@ impl Pipeline {
#[inline]
fn parse(&mut self) -> Poll<ClientResponse, HttpResponseParserError> {
if let Some(ref mut conn) = self.conn {
match self.parser.as_mut().unwrap().parse(conn, &mut self.parser_buf) {
match self.parser
.as_mut()
.unwrap()
.parse(conn, &mut self.parser_buf)
{
Ok(Async::Ready(resp)) => {
// check content-encoding
if self.should_decompress {
@ -301,7 +305,7 @@ impl Pipeline {
return Ok(Async::Ready(None));
}
let conn: &mut Connection =
unsafe { mem::transmute(self.conn.as_mut().unwrap()) };
unsafe { &mut *(self.conn.as_mut().unwrap() as *mut _) };
let mut need_run = false;
@ -465,7 +469,9 @@ impl Pipeline {
}
// flush io but only if we need to
match self.writer.poll_completed(self.conn.as_mut().unwrap(), false) {
match self.writer
.poll_completed(self.conn.as_mut().unwrap(), false)
{
Ok(Async::Ready(_)) => {
if self.disconnected
|| (self.body_completed && self.writer.is_completed())

View file

@ -499,7 +499,10 @@ impl ClientRequestBuilder {
jar.add(cookie.into_owned());
self.cookies = Some(jar)
} else {
self.cookies.as_mut().unwrap().add(cookie.into_owned());
self.cookies
.as_mut()
.unwrap()
.add(cookie.into_owned());
}
self
}
@ -591,7 +594,11 @@ impl ClientRequestBuilder {
if self.default_headers {
// enable br only for https
let https = if let Some(parts) = parts(&mut self.request, &self.err) {
parts.uri.scheme_part().map(|s| s == &uri::Scheme::HTTPS).unwrap_or(true)
parts
.uri
.scheme_part()
.map(|s| s == &uri::Scheme::HTTPS)
.unwrap_or(true)
} else {
true
};
@ -603,7 +610,9 @@ impl ClientRequestBuilder {
}
}
let mut request = self.request.take().expect("cannot reuse request builder");
let mut request = self.request
.take()
.expect("cannot reuse request builder");
// set cookies
if let Some(ref mut jar) = self.cookies {
@ -648,7 +657,9 @@ impl ClientRequestBuilder {
S: Stream<Item = Bytes, Error = E> + 'static,
E: Into<Error>,
{
self.body(Body::Streaming(Box::new(stream.map_err(|e| e.into()))))
self.body(Body::Streaming(Box::new(
stream.map_err(|e| e.into()),
)))
}
/// Set an empty body and generate `ClientRequest`

View file

@ -103,7 +103,12 @@ impl ClientResponse {
impl fmt::Debug for ClientResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let res = writeln!(f, "\nClientResponse {:?} {}", self.version(), self.status());
let res = writeln!(
f,
"\nClientResponse {:?} {}",
self.version(),
self.status()
);
let _ = writeln!(f, " headers:");
for (key, val) in self.headers().iter() {
let _ = writeln!(f, " {:?}: {:?}", key, val);
@ -133,12 +138,14 @@ mod tests {
#[test]
fn test_debug() {
let resp = ClientResponse::new(ClientMessage::default());
resp.as_mut()
.headers
.insert(header::COOKIE, HeaderValue::from_static("cookie1=value1"));
resp.as_mut()
.headers
.insert(header::COOKIE, HeaderValue::from_static("cookie2=value2"));
resp.as_mut().headers.insert(
header::COOKIE,
HeaderValue::from_static("cookie1=value1"),
);
resp.as_mut().headers.insert(
header::COOKIE,
HeaderValue::from_static("cookie2=value2"),
);
let dbg = format!("{:?}", resp);
assert!(dbg.contains("ClientResponse"));

View file

@ -114,7 +114,10 @@ impl HttpClientWriter {
self.buffer,
"{} {} {:?}\r",
msg.method(),
msg.uri().path_and_query().map(|u| u.as_str()).unwrap_or("/"),
msg.uri()
.path_and_query()
.map(|u| u.as_str())
.unwrap_or("/"),
msg.version()
)?;
@ -250,8 +253,10 @@ fn content_encoder(buf: SharedBytes, req: &mut ClientRequest) -> ContentEncoder
}
let mut b = BytesMut::new();
let _ = write!(b, "{}", bytes.len());
req.headers_mut()
.insert(CONTENT_LENGTH, HeaderValue::try_from(b.freeze()).unwrap());
req.headers_mut().insert(
CONTENT_LENGTH,
HeaderValue::try_from(b.freeze()).unwrap(),
);
TransferEncoding::eof(buf)
}
Body::Streaming(_) | Body::Actor(_) => {
@ -274,8 +279,10 @@ fn content_encoder(buf: SharedBytes, req: &mut ClientRequest) -> ContentEncoder
};
if encoding.is_compression() {
req.headers_mut()
.insert(CONTENT_ENCODING, HeaderValue::from_static(encoding.as_str()));
req.headers_mut().insert(
CONTENT_ENCODING,
HeaderValue::from_static(encoding.as_str()),
);
}
req.replace_body(body);

View file

@ -41,9 +41,7 @@ pub struct PathDeserializer<'de, S: 'de> {
impl<'de, S: 'de> PathDeserializer<'de, S> {
pub fn new(req: &'de HttpRequest<S>) -> Self {
PathDeserializer {
req,
}
PathDeserializer { req }
}
}
@ -204,12 +202,11 @@ impl<'de> de::MapAccess<'de> for ParamsDeserializer<'de> {
where
K: de::DeserializeSeed<'de>,
{
self.current =
self.params.next().map(|&(ref k, ref v)| (k.as_ref(), v.as_ref()));
self.current = self.params
.next()
.map(|&(ref k, ref v)| (k.as_ref(), v.as_ref()));
match self.current {
Some((key, _)) => Ok(Some(seed.deserialize(Key {
key,
})?)),
Some((key, _)) => Ok(Some(seed.deserialize(Key { key })?)),
None => Ok(None),
}
}
@ -219,9 +216,7 @@ impl<'de> de::MapAccess<'de> for ParamsDeserializer<'de> {
V: de::DeserializeSeed<'de>,
{
if let Some((_, value)) = self.current.take() {
seed.deserialize(Value {
value,
})
seed.deserialize(Value { value })
} else {
Err(de::value::Error::custom("unexpected item"))
}
@ -377,7 +372,9 @@ impl<'de> Deserializer<'de> for Value<'de> {
where
V: Visitor<'de>,
{
Err(de::value::Error::custom("unsupported type: tuple struct"))
Err(de::value::Error::custom(
"unsupported type: tuple struct",
))
}
unsupported_type!(deserialize_any, "any");
@ -419,9 +416,7 @@ impl<'de> de::EnumAccess<'de> for ValueEnum<'de> {
V: de::DeserializeSeed<'de>,
{
Ok((
seed.deserialize(Key {
key: self.value,
})?,
seed.deserialize(Key { key: self.value })?,
UnitVariant,
))
}

View file

@ -68,7 +68,12 @@ impl fmt::Debug for Error {
if let Some(bt) = self.cause.backtrace() {
write!(f, "{:?}\n\n{:?}", &self.cause, bt)
} else {
write!(f, "{:?}\n\n{:?}", &self.cause, self.backtrace.as_ref().unwrap())
write!(
f,
"{:?}\n\n{:?}",
&self.cause,
self.backtrace.as_ref().unwrap()
)
}
}
}
@ -302,7 +307,10 @@ pub enum HttpRangeError {
/// Return `BadRequest` for `HttpRangeError`
impl ResponseError for HttpRangeError {
fn error_response(&self) -> HttpResponse {
HttpResponse::with_body(StatusCode::BAD_REQUEST, "Invalid Range header provided")
HttpResponse::with_body(
StatusCode::BAD_REQUEST,
"Invalid Range header provided",
)
}
}

View file

@ -110,9 +110,7 @@ where
result(
de::Deserialize::deserialize(PathDeserializer::new(&req))
.map_err(|e| e.into())
.map(|inner| Path {
inner,
}),
.map(|inner| Path { inner }),
)
}
}
@ -248,7 +246,12 @@ where
#[inline]
fn from_request(req: &HttpRequest<S>, cfg: &Self::Config) -> Self::Result {
Box::new(UrlEncoded::new(req.clone()).limit(cfg.limit).from_err().map(Form))
Box::new(
UrlEncoded::new(req.clone())
.limit(cfg.limit)
.from_err()
.map(Form),
)
}
}
@ -293,9 +296,7 @@ impl FormConfig {
impl Default for FormConfig {
fn default() -> Self {
FormConfig {
limit: 262_144,
}
FormConfig { limit: 262_144 }
}
}
@ -336,7 +337,11 @@ impl<S: 'static> FromRequest<S> for Bytes {
return Either::A(result(Err(e)));
}
Either::B(Box::new(MessageBody::new(req.clone()).limit(cfg.limit).from_err()))
Either::B(Box::new(
MessageBody::new(req.clone())
.limit(cfg.limit)
.from_err(),
))
}
}
@ -382,14 +387,18 @@ impl<S: 'static> FromRequest<S> for String {
// check charset
let encoding = match req.encoding() {
Err(_) => {
return Either::A(result(Err(ErrorBadRequest("Unknown request charset"))))
return Either::A(result(Err(ErrorBadRequest(
"Unknown request charset",
))))
}
Ok(encoding) => encoding,
};
Either::B(Box::new(
MessageBody::new(req.clone()).limit(cfg.limit).from_err().and_then(
move |body| {
MessageBody::new(req.clone())
.limit(cfg.limit)
.from_err()
.and_then(move |body| {
let enc: *const Encoding = encoding as *const Encoding;
if enc == UTF_8 {
Ok(str::from_utf8(body.as_ref())
@ -400,8 +409,7 @@ impl<S: 'static> FromRequest<S> for String {
.decode(&body, DecoderTrap::Strict)
.map_err(|_| ErrorBadRequest("Can not decode body"))?)
}
},
),
}),
))
}
}
@ -477,7 +485,8 @@ mod tests {
fn test_bytes() {
let cfg = PayloadConfig::default();
let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "11").finish();
req.payload_mut().unread_data(Bytes::from_static(b"hello=world"));
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
match Bytes::from_request(&req, &cfg).poll().unwrap() {
Async::Ready(s) => {
@ -491,7 +500,8 @@ mod tests {
fn test_string() {
let cfg = PayloadConfig::default();
let mut req = TestRequest::with_header(header::CONTENT_LENGTH, "11").finish();
req.payload_mut().unread_data(Bytes::from_static(b"hello=world"));
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
match String::from_request(&req, &cfg).poll().unwrap() {
Async::Ready(s) => {
@ -508,7 +518,8 @@ mod tests {
"application/x-www-form-urlencoded",
).header(header::CONTENT_LENGTH, "11")
.finish();
req.payload_mut().unread_data(Bytes::from_static(b"hello=world"));
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
let mut cfg = FormConfig::default();
cfg.limit(4096);
@ -562,11 +573,17 @@ mod tests {
let mut resource = ResourceHandler::<()>::default();
resource.name("index");
let mut routes = Vec::new();
routes.push((Resource::new("index", "/{key}/{value}/"), Some(resource)));
routes.push((
Resource::new("index", "/{key}/{value}/"),
Some(resource),
));
let (router, _) = Router::new("", ServerSettings::default(), routes);
assert!(router.recognize(&mut req).is_some());
match Path::<MyStruct>::from_request(&req, &()).poll().unwrap() {
match Path::<MyStruct>::from_request(&req, &())
.poll()
.unwrap()
{
Async::Ready(s) => {
assert_eq!(s.key, "name");
assert_eq!(s.value, "user1");
@ -574,7 +591,10 @@ mod tests {
_ => unreachable!(),
}
match Path::<(String, String)>::from_request(&req, &()).poll().unwrap() {
match Path::<(String, String)>::from_request(&req, &())
.poll()
.unwrap()
{
Async::Ready(s) => {
assert_eq!(s.0, "name");
assert_eq!(s.1, "user1");
@ -600,7 +620,10 @@ mod tests {
_ => unreachable!(),
}
match Path::<(String, u8)>::from_request(&req, &()).poll().unwrap() {
match Path::<(String, u8)>::from_request(&req, &())
.poll()
.unwrap()
{
Async::Ready(s) => {
assert_eq!(s.0, "name");
assert_eq!(s.1, 32);
@ -608,9 +631,15 @@ mod tests {
_ => unreachable!(),
}
match Path::<Vec<String>>::from_request(&req, &()).poll().unwrap() {
match Path::<Vec<String>>::from_request(&req, &())
.poll()
.unwrap()
{
Async::Ready(s) => {
assert_eq!(s.into_inner(), vec!["name".to_owned(), "32".to_owned()]);
assert_eq!(
s.into_inner(),
vec!["name".to_owned(), "32".to_owned()]
);
}
_ => unreachable!(),
}

208
src/fs.rs
View file

@ -15,7 +15,7 @@ use bytes::{BufMut, Bytes, BytesMut};
use futures::{Async, Future, Poll, Stream};
use futures_cpupool::{CpuFuture, CpuPool};
use mime;
use mime_guess::{guess_mime_type, get_mime_type};
use mime_guess::{get_mime_type, guess_mime_type};
use error::Error;
use handler::{Handler, Reply, Responder, RouteHandler, WrapHandler};
@ -203,24 +203,29 @@ impl Responder for NamedFile {
if self.status_code != StatusCode::OK {
let mut resp = HttpResponse::build(self.status_code);
resp.if_some(self.path().extension(), |ext, resp| {
resp.set(header::ContentType(get_mime_type(&ext.to_string_lossy())));
resp.set(header::ContentType(get_mime_type(
&ext.to_string_lossy(),
)));
}).if_some(self.path().file_name(), |file_name, resp| {
let mime_type = guess_mime_type(self.path());
let inline_or_attachment = match mime_type.type_() {
mime::IMAGE | mime::TEXT => "inline",
_ => "attachment",
};
resp.header(
"Content-Disposition",
format!("{inline_or_attachment}; filename={filename}",
inline_or_attachment=inline_or_attachment,
filename=file_name.to_string_lossy())
);
});
let mime_type = guess_mime_type(self.path());
let inline_or_attachment = match mime_type.type_() {
mime::IMAGE | mime::TEXT => "inline",
_ => "attachment",
};
resp.header(
"Content-Disposition",
format!(
"{inline_or_attachment}; filename={filename}",
inline_or_attachment = inline_or_attachment,
filename = file_name.to_string_lossy()
),
);
});
let reader = ChunkedReadFile {
size: self.md.len(),
offset: 0,
cpu_pool: self.cpu_pool.unwrap_or_else(|| req.cpu_pool().clone()),
cpu_pool: self.cpu_pool
.unwrap_or_else(|| req.cpu_pool().clone()),
file: Some(self.file),
fut: None,
};
@ -263,24 +268,30 @@ impl Responder for NamedFile {
let mut resp = HttpResponse::build(self.status_code);
resp.if_some(self.path().extension(), |ext, resp| {
resp.set(header::ContentType(get_mime_type(&ext.to_string_lossy())));
resp.set(header::ContentType(get_mime_type(
&ext.to_string_lossy(),
)));
}).if_some(self.path().file_name(), |file_name, resp| {
let mime_type = guess_mime_type(self.path());
let inline_or_attachment = match mime_type.type_() {
mime::IMAGE | mime::TEXT => "inline",
_ => "attachment",
};
resp.header(
"Content-Disposition",
format!("{inline_or_attachment}; filename={filename}",
inline_or_attachment=inline_or_attachment,
filename=file_name.to_string_lossy())
);
}).if_some(last_modified, |lm, resp| {
let mime_type = guess_mime_type(self.path());
let inline_or_attachment = match mime_type.type_() {
mime::IMAGE | mime::TEXT => "inline",
_ => "attachment",
};
resp.header(
"Content-Disposition",
format!(
"{inline_or_attachment}; filename={filename}",
inline_or_attachment = inline_or_attachment,
filename = file_name.to_string_lossy()
),
);
})
.if_some(last_modified, |lm, resp| {
resp.set(header::LastModified(lm));
}).if_some(etag, |etag, resp| {
resp.set(header::ETag(etag));
});
})
.if_some(etag, |etag, resp| {
resp.set(header::ETag(etag));
});
if precondition_failed {
return Ok(resp.status(StatusCode::PRECONDITION_FAILED).finish());
@ -294,7 +305,8 @@ impl Responder for NamedFile {
let reader = ChunkedReadFile {
size: self.md.len(),
offset: 0,
cpu_pool: self.cpu_pool.unwrap_or_else(|| req.cpu_pool().clone()),
cpu_pool: self.cpu_pool
.unwrap_or_else(|| req.cpu_pool().clone()),
file: Some(self.file),
fut: None,
};
@ -362,10 +374,7 @@ pub struct Directory {
impl Directory {
pub fn new(base: PathBuf, path: PathBuf) -> Directory {
Directory {
base,
path,
}
Directory { base, path }
}
fn can_list(&self, entry: &io::Result<DirEntry>) -> bool {
@ -435,7 +444,9 @@ impl Responder for Directory {
</ul></body>\n</html>",
index_of, index_of, body
);
Ok(HttpResponse::Ok().content_type("text/html; charset=utf-8").body(html))
Ok(HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(html))
}
}
@ -560,12 +571,13 @@ impl<S: 'static> Handler<S> for StaticFiles<S> {
if !self.accessible {
Ok(self.default.handle(req))
} else {
let relpath =
match req.match_info().get("tail").map(|tail| PathBuf::from_param(tail))
{
Some(Ok(path)) => path,
_ => return Ok(self.default.handle(req)),
};
let relpath = match req.match_info()
.get("tail")
.map(|tail| PathBuf::from_param(tail))
{
Some(Ok(path)) => path,
_ => return Ok(self.default.handle(req)),
};
// full filepath
let path = self.directory.join(&relpath).canonicalize()?;
@ -615,8 +627,9 @@ mod tests {
#[test]
fn test_named_file_text() {
assert!(NamedFile::open("test--").is_err());
let mut file =
NamedFile::open("Cargo.toml").unwrap().set_cpu_pool(CpuPool::new(1));
let mut file = NamedFile::open("Cargo.toml")
.unwrap()
.set_cpu_pool(CpuPool::new(1));
{
file.file();
let _f: &File = &file;
@ -626,17 +639,23 @@ mod tests {
}
let resp = file.respond_to(HttpRequest::default()).unwrap();
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "text/x-toml");
assert_eq!(
resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
resp.headers().get(header::CONTENT_TYPE).unwrap(),
"text/x-toml"
);
assert_eq!(
resp.headers()
.get(header::CONTENT_DISPOSITION)
.unwrap(),
"inline; filename=Cargo.toml"
);
}
#[test]
fn test_named_file_image() {
let mut file =
NamedFile::open("tests/test.png").unwrap().set_cpu_pool(CpuPool::new(1));
let mut file = NamedFile::open("tests/test.png")
.unwrap()
.set_cpu_pool(CpuPool::new(1));
{
file.file();
let _f: &File = &file;
@ -646,17 +665,23 @@ mod tests {
}
let resp = file.respond_to(HttpRequest::default()).unwrap();
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "image/png");
assert_eq!(
resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
resp.headers().get(header::CONTENT_TYPE).unwrap(),
"image/png"
);
assert_eq!(
resp.headers()
.get(header::CONTENT_DISPOSITION)
.unwrap(),
"inline; filename=test.png"
);
}
#[test]
fn test_named_file_binary() {
let mut file =
NamedFile::open("tests/test.binary").unwrap().set_cpu_pool(CpuPool::new(1));
let mut file = NamedFile::open("tests/test.binary")
.unwrap()
.set_cpu_pool(CpuPool::new(1));
{
file.file();
let _f: &File = &file;
@ -666,9 +691,14 @@ mod tests {
}
let resp = file.respond_to(HttpRequest::default()).unwrap();
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "application/octet-stream");
assert_eq!(
resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
resp.headers().get(header::CONTENT_TYPE).unwrap(),
"application/octet-stream"
);
assert_eq!(
resp.headers()
.get(header::CONTENT_DISPOSITION)
.unwrap(),
"attachment; filename=test.binary"
);
}
@ -688,9 +718,14 @@ mod tests {
}
let resp = file.respond_to(HttpRequest::default()).unwrap();
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "text/x-toml");
assert_eq!(
resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
resp.headers().get(header::CONTENT_TYPE).unwrap(),
"text/x-toml"
);
assert_eq!(
resp.headers()
.get(header::CONTENT_DISPOSITION)
.unwrap(),
"inline; filename=Cargo.toml"
);
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
@ -735,7 +770,9 @@ mod tests {
req.match_info_mut().add("tail", "");
st.show_index = true;
let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap();
let resp = st.handle(req)
.respond_to(HttpRequest::default())
.unwrap();
let resp = resp.as_response().expect("HTTP Response");
assert_eq!(
resp.headers().get(header::CONTENT_TYPE).unwrap(),
@ -751,18 +788,28 @@ mod tests {
let mut req = HttpRequest::default();
req.match_info_mut().add("tail", "tests");
let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap();
let resp = st.handle(req)
.respond_to(HttpRequest::default())
.unwrap();
let resp = resp.as_response().expect("HTTP Response");
assert_eq!(resp.status(), StatusCode::FOUND);
assert_eq!(resp.headers().get(header::LOCATION).unwrap(), "/tests/index.html");
assert_eq!(
resp.headers().get(header::LOCATION).unwrap(),
"/tests/index.html"
);
let mut req = HttpRequest::default();
req.match_info_mut().add("tail", "tests/");
let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap();
let resp = st.handle(req)
.respond_to(HttpRequest::default())
.unwrap();
let resp = resp.as_response().expect("HTTP Response");
assert_eq!(resp.status(), StatusCode::FOUND);
assert_eq!(resp.headers().get(header::LOCATION).unwrap(), "/tests/index.html");
assert_eq!(
resp.headers().get(header::LOCATION).unwrap(),
"/tests/index.html"
);
}
#[test]
@ -771,7 +818,9 @@ mod tests {
let mut req = HttpRequest::default();
req.match_info_mut().add("tail", "tools/wsload");
let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap();
let resp = st.handle(req)
.respond_to(HttpRequest::default())
.unwrap();
let resp = resp.as_response().expect("HTTP Response");
assert_eq!(resp.status(), StatusCode::FOUND);
assert_eq!(
@ -791,13 +840,23 @@ mod tests {
let request = srv.get().uri(srv.url("/public")).finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::FOUND);
let loc = response.headers().get(header::LOCATION).unwrap().to_str().unwrap();
let loc = response
.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap();
assert_eq!(loc, "/public/Cargo.toml");
let request = srv.get().uri(srv.url("/public/")).finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::FOUND);
let loc = response.headers().get(header::LOCATION).unwrap().to_str().unwrap();
let loc = response
.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap();
assert_eq!(loc, "/public/Cargo.toml");
}
@ -810,13 +869,23 @@ mod tests {
let request = srv.get().uri(srv.url("/test")).finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::FOUND);
let loc = response.headers().get(header::LOCATION).unwrap().to_str().unwrap();
let loc = response
.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap();
assert_eq!(loc, "/test/Cargo.toml");
let request = srv.get().uri(srv.url("/test/")).finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::FOUND);
let loc = response.headers().get(header::LOCATION).unwrap().to_str().unwrap();
let loc = response
.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap();
assert_eq!(loc, "/test/Cargo.toml");
}
@ -826,7 +895,10 @@ mod tests {
App::new().handler("test", StaticFiles::new(".").index_file("Cargo.toml"))
});
let request = srv.get().uri(srv.url("/test/%43argo.toml")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test/%43argo.toml"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::OK);
}

View file

@ -296,13 +296,14 @@ where
#[inline]
fn respond_to(self, req: HttpRequest) -> Result<Reply, Error> {
let fut = self.map_err(|e| e.into()).then(move |r| match r.respond_to(req) {
Ok(reply) => match reply.into().0 {
ReplyItem::Message(resp) => ok(resp),
_ => panic!("Nested async replies are not supported"),
},
Err(e) => err(e),
});
let fut = self.map_err(|e| e.into())
.then(move |r| match r.respond_to(req) {
Ok(reply) => match reply.into().0 {
ReplyItem::Message(resp) => ok(resp),
_ => panic!("Nested async replies are not supported"),
},
Err(e) => err(e),
});
Ok(Reply::async(fut))
}
}

View file

@ -57,10 +57,7 @@ impl EntityTag {
/// If the tag contains invalid characters.
pub fn new(weak: bool, tag: String) -> EntityTag {
assert!(check_slice_validity(&tag), "Invalid tag: {:?}", tag);
EntityTag {
weak,
tag,
}
EntityTag { weak, tag }
}
/// Constructs a new weak EntityTag.
@ -199,7 +196,11 @@ mod tests {
fn test_etag_parse_failures() {
// Expected failures
assert!("no-dquotes".parse::<EntityTag>().is_err());
assert!("w/\"the-first-w-is-case-sensitive\"".parse::<EntityTag>().is_err());
assert!(
"w/\"the-first-w-is-case-sensitive\""
.parse::<EntityTag>()
.is_err()
);
assert!("".parse::<EntityTag>().is_err());
assert!("\"unmatched-dquotes1".parse::<EntityTag>().is_err());
assert!("unmatched-dquotes2\"".parse::<EntityTag>().is_err());
@ -208,14 +209,26 @@ mod tests {
#[test]
fn test_etag_fmt() {
assert_eq!(format!("{}", EntityTag::strong("foobar".to_owned())), "\"foobar\"");
assert_eq!(format!("{}", EntityTag::strong("".to_owned())), "\"\"");
assert_eq!(
format!("{}", EntityTag::strong("foobar".to_owned())),
"\"foobar\""
);
assert_eq!(
format!("{}", EntityTag::strong("".to_owned())),
"\"\""
);
assert_eq!(
format!("{}", EntityTag::weak("weak-etag".to_owned())),
"W/\"weak-etag\""
);
assert_eq!(format!("{}", EntityTag::weak("\u{0065}".to_owned())), "W/\"\x65\"");
assert_eq!(format!("{}", EntityTag::weak("".to_owned())), "W/\"\"");
assert_eq!(
format!("{}", EntityTag::weak("\u{0065}".to_owned())),
"W/\"\x65\""
);
assert_eq!(
format!("{}", EntityTag::weak("".to_owned())),
"W/\"\""
);
}
#[test]

View file

@ -64,7 +64,11 @@ impl IntoHeaderValue for HttpDate {
fn try_into(self) -> Result<HeaderValue, Self::Error> {
let mut wrt = BytesMut::with_capacity(29).writer();
write!(wrt, "{}", self.0.rfc822()).unwrap();
unsafe { Ok(HeaderValue::from_shared_unchecked(wrt.get_mut().take().freeze())) }
unsafe {
Ok(HeaderValue::from_shared_unchecked(
wrt.get_mut().take().freeze(),
))
}
}
}
@ -100,12 +104,24 @@ mod tests {
#[test]
fn test_date() {
assert_eq!("Sun, 07 Nov 1994 08:48:37 GMT".parse::<HttpDate>().unwrap(), NOV_07);
assert_eq!(
"Sunday, 07-Nov-94 08:48:37 GMT".parse::<HttpDate>().unwrap(),
"Sun, 07 Nov 1994 08:48:37 GMT"
.parse::<HttpDate>()
.unwrap(),
NOV_07
);
assert_eq!(
"Sunday, 07-Nov-94 08:48:37 GMT"
.parse::<HttpDate>()
.unwrap(),
NOV_07
);
assert_eq!(
"Sun Nov 7 08:48:37 1994"
.parse::<HttpDate>()
.unwrap(),
NOV_07
);
assert_eq!("Sun Nov 7 08:48:37 1994".parse::<HttpDate>().unwrap(), NOV_07);
assert!("this-is-no-date".parse::<HttpDate>().is_err());
}
}

View file

@ -47,10 +47,7 @@ impl<T> QualityItem<T> {
/// The item can be of any type.
/// The quality should be a value in the range [0, 1].
pub fn new(item: T, quality: Quality) -> QualityItem<T> {
QualityItem {
item,
quality,
}
QualityItem { item, quality }
}
}
@ -66,7 +63,11 @@ impl<T: fmt::Display> fmt::Display for QualityItem<T> {
match self.quality.0 {
1000 => Ok(()),
0 => f.write_str("; q=0"),
x => write!(f, "; q=0.{}", format!("{:03}", x).trim_right_matches('0')),
x => write!(
f,
"; q=0.{}",
format!("{:03}", x).trim_right_matches('0')
),
}
}
}
@ -119,7 +120,10 @@ 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");
debug_assert!(
f >= 0f32 && f <= 1f32,
"q value must be between 0.0 and 1.0"
);
Quality((f * 1000f32) as u16)
}
@ -152,7 +156,10 @@ mod internal {
impl IntoQuality for f32 {
fn into_quality(self) -> Quality {
assert!(self >= 0f32 && self <= 1f32, "float must be between 0.0 and 1.0");
assert!(
self >= 0f32 && self <= 1f32,
"float must be between 0.0 and 1.0"
);
super::from_f32(self)
}
}
@ -288,6 +295,10 @@ mod tests {
#[test]
fn test_fuzzing_bugs() {
assert!("99999;".parse::<QualityItem<String>>().is_err());
assert!("\x0d;;;=\u{d6aa}==".parse::<QualityItem<String>>().is_err())
assert!(
"\x0d;;;=\u{d6aa}=="
.parse::<QualityItem<String>>()
.is_err()
)
}
}

View file

@ -190,8 +190,16 @@ mod tests {
// trailing slashes
let params = vec![
("/resource1", "", StatusCode::OK),
("/resource1/", "/resource1", StatusCode::MOVED_PERMANENTLY),
("/resource2", "/resource2/", StatusCode::MOVED_PERMANENTLY),
(
"/resource1/",
"/resource1",
StatusCode::MOVED_PERMANENTLY,
),
(
"/resource2",
"/resource2/",
StatusCode::MOVED_PERMANENTLY,
),
("/resource2/", "", StatusCode::OK),
("/resource1?p1=1&p2=2", "", StatusCode::OK),
(
@ -214,7 +222,11 @@ mod tests {
if !target.is_empty() {
assert_eq!(
target,
r.headers().get(header::LOCATION).unwrap().to_str().unwrap()
r.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap()
);
}
}
@ -226,7 +238,11 @@ mod tests {
.resource("/resource1", |r| r.method(Method::GET).f(index))
.resource("/resource2/", |r| r.method(Method::GET).f(index))
.default_resource(|r| {
r.h(NormalizePath::new(false, true, StatusCode::MOVED_PERMANENTLY))
r.h(NormalizePath::new(
false,
true,
StatusCode::MOVED_PERMANENTLY,
))
})
.finish();
@ -260,14 +276,46 @@ mod tests {
// trailing slashes
let params = vec![
("/resource1/a/b", "", StatusCode::OK),
("/resource1/", "/resource1", StatusCode::MOVED_PERMANENTLY),
("/resource1//", "/resource1", StatusCode::MOVED_PERMANENTLY),
("//resource1//a//b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("//resource1//a//b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("//resource1//a//b//", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("///resource1//a//b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("/////resource1/a///b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("/////resource1/a//b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
(
"/resource1/",
"/resource1",
StatusCode::MOVED_PERMANENTLY,
),
(
"/resource1//",
"/resource1",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource1//a//b",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource1//a//b/",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource1//a//b//",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"///resource1//a//b",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"/////resource1/a///b",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"/////resource1/a//b/",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
("/resource1/a/b?p=1", "", StatusCode::OK),
(
"//resource1//a//b?p=1",
@ -308,7 +356,11 @@ mod tests {
if !target.is_empty() {
assert_eq!(
target,
r.headers().get(header::LOCATION).unwrap().to_str().unwrap()
r.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap()
);
}
}
@ -327,24 +379,88 @@ mod tests {
// trailing slashes
let params = vec![
("/resource1/a/b", "", StatusCode::OK),
("/resource1/a/b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("//resource2//a//b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("//resource2//a//b/", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("//resource2//a//b//", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("///resource1//a//b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("///resource1//a//b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("/////resource1/a///b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("/////resource1/a///b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY),
("/resource2/a/b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
(
"/resource1/a/b/",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource2//a//b",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource2//a//b/",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource2//a//b//",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"///resource1//a//b",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"///resource1//a//b/",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"/////resource1/a///b",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"/////resource1/a///b/",
"/resource1/a/b",
StatusCode::MOVED_PERMANENTLY,
),
(
"/resource2/a/b",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
("/resource2/a/b/", "", StatusCode::OK),
("//resource2//a//b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("//resource2//a//b/", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("///resource2//a//b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("///resource2//a//b/", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("/////resource2/a///b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
("/////resource2/a///b/", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY),
(
"//resource2//a//b",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource2//a//b/",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"///resource2//a//b",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"///resource2//a//b/",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"/////resource2/a///b",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
(
"/////resource2/a///b/",
"/resource2/a/b/",
StatusCode::MOVED_PERMANENTLY,
),
("/resource1/a/b?p=1", "", StatusCode::OK),
("/resource1/a/b/?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY),
(
"/resource1/a/b/?p=1",
"/resource1/a/b?p=1",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource2//a//b?p=1",
"/resource2/a/b/?p=1",
@ -380,7 +496,11 @@ mod tests {
"/resource1/a/b?p=1",
StatusCode::MOVED_PERMANENTLY,
),
("/resource2/a/b?p=1", "/resource2/a/b/?p=1", StatusCode::MOVED_PERMANENTLY),
(
"/resource2/a/b?p=1",
"/resource2/a/b/?p=1",
StatusCode::MOVED_PERMANENTLY,
),
(
"//resource2//a//b?p=1",
"/resource2/a/b/?p=1",
@ -420,7 +540,11 @@ mod tests {
if !target.is_empty() {
assert_eq!(
target,
r.headers().get(header::LOCATION).unwrap().to_str().unwrap()
r.headers()
.get(header::LOCATION)
.unwrap()
.to_str()
.unwrap()
);
}
}

View file

@ -245,7 +245,10 @@ impl HttpResponse {
STATIC_RESP!(Ok, StatusCode::OK);
STATIC_RESP!(Created, StatusCode::CREATED);
STATIC_RESP!(Accepted, StatusCode::ACCEPTED);
STATIC_RESP!(NonAuthoritativeInformation, StatusCode::NON_AUTHORITATIVE_INFORMATION);
STATIC_RESP!(
NonAuthoritativeInformation,
StatusCode::NON_AUTHORITATIVE_INFORMATION
);
STATIC_RESP!(NoContent, StatusCode::NO_CONTENT);
STATIC_RESP!(ResetContent, StatusCode::RESET_CONTENT);
@ -270,7 +273,10 @@ impl HttpResponse {
STATIC_RESP!(Forbidden, StatusCode::FORBIDDEN);
STATIC_RESP!(MethodNotAllowed, StatusCode::METHOD_NOT_ALLOWED);
STATIC_RESP!(NotAcceptable, StatusCode::NOT_ACCEPTABLE);
STATIC_RESP!(ProxyAuthenticationRequired, StatusCode::PROXY_AUTHENTICATION_REQUIRED);
STATIC_RESP!(
ProxyAuthenticationRequired,
StatusCode::PROXY_AUTHENTICATION_REQUIRED
);
STATIC_RESP!(RequestTimeout, StatusCode::REQUEST_TIMEOUT);
STATIC_RESP!(Conflict, StatusCode::CONFLICT);
STATIC_RESP!(Gone, StatusCode::GONE);
@ -278,7 +284,10 @@ impl HttpResponse {
STATIC_RESP!(PreconditionFailed, StatusCode::PRECONDITION_FAILED);
STATIC_RESP!(PayloadTooLarge, StatusCode::PAYLOAD_TOO_LARGE);
STATIC_RESP!(UriTooLong, StatusCode::URI_TOO_LONG);
STATIC_RESP!(UnsupportedMediaType, StatusCode::UNSUPPORTED_MEDIA_TYPE);
STATIC_RESP!(
UnsupportedMediaType,
StatusCode::UNSUPPORTED_MEDIA_TYPE
);
STATIC_RESP!(RangeNotSatisfiable, StatusCode::RANGE_NOT_SATISFIABLE);
STATIC_RESP!(ExpectationFailed, StatusCode::EXPECTATION_FAILED);
@ -287,8 +296,14 @@ impl HttpResponse {
STATIC_RESP!(BadGateway, StatusCode::BAD_GATEWAY);
STATIC_RESP!(ServiceUnavailable, StatusCode::SERVICE_UNAVAILABLE);
STATIC_RESP!(GatewayTimeout, StatusCode::GATEWAY_TIMEOUT);
STATIC_RESP!(VersionNotSupported, StatusCode::HTTP_VERSION_NOT_SUPPORTED);
STATIC_RESP!(VariantAlsoNegotiates, StatusCode::VARIANT_ALSO_NEGOTIATES);
STATIC_RESP!(
VersionNotSupported,
StatusCode::HTTP_VERSION_NOT_SUPPORTED
);
STATIC_RESP!(
VariantAlsoNegotiates,
StatusCode::VARIANT_ALSO_NEGOTIATES
);
STATIC_RESP!(InsufficientStorage, StatusCode::INSUFFICIENT_STORAGE);
STATIC_RESP!(LoopDetected, StatusCode::LOOP_DETECTED);
}

View file

@ -96,8 +96,10 @@ pub trait HttpMessage {
/// `size` is full size of response (file).
fn range(&self, size: u64) -> Result<Vec<HttpRange>, HttpRangeError> {
if let Some(range) = self.headers().get(header::RANGE) {
HttpRange::parse(unsafe { str::from_utf8_unchecked(range.as_bytes()) }, size)
.map_err(|e| e.into())
HttpRange::parse(
unsafe { str::from_utf8_unchecked(range.as_bytes()) },
size,
).map_err(|e| e.into())
} else {
Ok(Vec::new())
}
@ -323,7 +325,10 @@ where
));
}
self.fut.as_mut().expect("UrlEncoded could not be used second time").poll()
self.fut
.as_mut()
.expect("UrlEncoded could not be used second time")
.poll()
}
}
@ -380,7 +385,8 @@ where
if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
return Err(UrlencodedError::ContentType);
}
let encoding = req.encoding().map_err(|_| UrlencodedError::ContentType)?;
let encoding = req.encoding()
.map_err(|_| UrlencodedError::ContentType)?;
// future
let limit = self.limit;
@ -409,7 +415,10 @@ where
self.fut = Some(Box::new(fut));
}
self.fut.as_mut().expect("UrlEncoded could not be used second time").poll()
self.fut
.as_mut()
.expect("UrlEncoded could not be used second time")
.poll()
}
}
@ -479,13 +488,19 @@ mod tests {
#[test]
fn test_encoding_error() {
let req = TestRequest::with_header("content-type", "applicatjson").finish();
assert_eq!(Some(ContentTypeError::ParseError), req.encoding().err());
assert_eq!(
Some(ContentTypeError::ParseError),
req.encoding().err()
);
let req = TestRequest::with_header(
"content-type",
"application/json; charset=kkkttktk",
).finish();
assert_eq!(Some(ContentTypeError::UnknownEncoding), req.encoding().err());
assert_eq!(
Some(ContentTypeError::UnknownEncoding),
req.encoding().err()
);
}
#[test]
@ -606,7 +621,8 @@ mod tests {
"application/x-www-form-urlencoded",
).header(header::CONTENT_LENGTH, "11")
.finish();
req.payload_mut().unread_data(Bytes::from_static(b"hello=world"));
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
let result = req.urlencoded::<Info>().poll().ok().unwrap();
assert_eq!(
@ -621,7 +637,8 @@ mod tests {
"application/x-www-form-urlencoded; charset=utf-8",
).header(header::CONTENT_LENGTH, "11")
.finish();
req.payload_mut().unread_data(Bytes::from_static(b"hello=world"));
req.payload_mut()
.unread_data(Bytes::from_static(b"hello=world"));
let result = req.urlencoded().poll().ok().unwrap();
assert_eq!(
@ -647,14 +664,16 @@ mod tests {
}
let mut req = HttpRequest::default();
req.payload_mut().unread_data(Bytes::from_static(b"test"));
req.payload_mut()
.unread_data(Bytes::from_static(b"test"));
match req.body().poll().ok().unwrap() {
Async::Ready(bytes) => assert_eq!(bytes, Bytes::from_static(b"test")),
_ => unreachable!("error"),
}
let mut req = HttpRequest::default();
req.payload_mut().unread_data(Bytes::from_static(b"11111111111111"));
req.payload_mut()
.unread_data(Bytes::from_static(b"11111111111111"));
match req.body().limit(5).poll().err().unwrap() {
PayloadError::Overflow => (),
_ => unreachable!("error"),

View file

@ -327,7 +327,12 @@ impl<S> HttpRequest<S> {
let path = self.router().unwrap().resource_path(name, elements)?;
if path.starts_with('/') {
let conn = self.connection_info();
Ok(Url::parse(&format!("{}://{}{}", conn.scheme(), conn.host(), path))?)
Ok(Url::parse(&format!(
"{}://{}{}",
conn.scheme(),
conn.host(),
path
))?)
} else {
Ok(Url::parse(&path)?)
}
@ -677,8 +682,10 @@ mod tests {
let mut resource = ResourceHandler::<()>::default();
resource.name("index");
let routes =
vec![(Resource::new("index", "/user/{name}.{ext}"), Some(resource))];
let routes = vec![(
Resource::new("index", "/user/{name}.{ext}"),
Some(resource),
)];
let (router, _) = Router::new("/", ServerSettings::default(), routes);
assert!(router.has_route("/user/test.html"));
assert!(!router.has_route("/test/unknown"));
@ -707,8 +714,10 @@ mod tests {
let mut resource = ResourceHandler::<()>::default();
resource.name("index");
let routes =
vec![(Resource::new("index", "/user/{name}.{ext}"), Some(resource))];
let routes = vec![(
Resource::new("index", "/user/{name}.{ext}"),
Some(resource),
)];
let (router, _) = Router::new("/prefix/", ServerSettings::default(), routes);
assert!(router.has_route("/user/test.html"));
assert!(!router.has_route("/prefix/user/test.html"));
@ -736,6 +745,9 @@ mod tests {
let req = req.with_state(Rc::new(()), router);
let url = req.url_for("youtube", &["oHg5SJYRHA0"]);
assert_eq!(url.ok().unwrap().as_str(), "https://youtube.com/watch/oHg5SJYRHA0");
assert_eq!(
url.ok().unwrap().as_str(),
"https://youtube.com/watch/oHg5SJYRHA0"
);
}
}

View file

@ -150,7 +150,10 @@ impl HttpResponse {
if let Some(reason) = self.get_ref().reason {
reason
} else {
self.get_ref().status.canonical_reason().unwrap_or("<unknown status code>")
self.get_ref()
.status
.canonical_reason()
.unwrap_or("<unknown status code>")
}
}
@ -463,7 +466,10 @@ impl HttpResponseBuilder {
jar.add(cookie.into_owned());
self.cookies = Some(jar)
} else {
self.cookies.as_mut().unwrap().add(cookie.into_owned());
self.cookies
.as_mut()
.unwrap()
.add(cookie.into_owned());
}
self
}
@ -528,7 +534,9 @@ impl HttpResponseBuilder {
if let Some(e) = self.err.take() {
return Error::from(e).into();
}
let mut response = self.response.take().expect("cannot reuse response builder");
let mut response = self.response
.take()
.expect("cannot reuse response builder");
if let Some(ref jar) = self.cookies {
for cookie in jar.delta() {
match HeaderValue::from_str(&cookie.to_string()) {
@ -550,7 +558,9 @@ impl HttpResponseBuilder {
S: Stream<Item = Bytes, Error = E> + 'static,
E: Into<Error>,
{
self.body(Body::Streaming(Box::new(stream.map_err(|e| e.into()))))
self.body(Body::Streaming(Box::new(
stream.map_err(|e| e.into()),
)))
}
/// Set a json body and generate `HttpResponse`
@ -633,7 +643,9 @@ impl Responder for HttpResponseBuilder {
impl From<&'static str> for HttpResponse {
fn from(val: &'static str) -> Self {
HttpResponse::Ok().content_type("text/plain; charset=utf-8").body(val)
HttpResponse::Ok()
.content_type("text/plain; charset=utf-8")
.body(val)
}
}
@ -650,7 +662,9 @@ impl Responder for &'static str {
impl From<&'static [u8]> for HttpResponse {
fn from(val: &'static [u8]) -> Self {
HttpResponse::Ok().content_type("application/octet-stream").body(val)
HttpResponse::Ok()
.content_type("application/octet-stream")
.body(val)
}
}
@ -667,7 +681,9 @@ impl Responder for &'static [u8] {
impl From<String> for HttpResponse {
fn from(val: String) -> Self {
HttpResponse::Ok().content_type("text/plain; charset=utf-8").body(val)
HttpResponse::Ok()
.content_type("text/plain; charset=utf-8")
.body(val)
}
}
@ -703,7 +719,9 @@ impl<'a> Responder for &'a String {
impl From<Bytes> for HttpResponse {
fn from(val: Bytes) -> Self {
HttpResponse::Ok().content_type("application/octet-stream").body(val)
HttpResponse::Ok()
.content_type("application/octet-stream")
.body(val)
}
}
@ -720,7 +738,9 @@ impl Responder for Bytes {
impl From<BytesMut> for HttpResponse {
fn from(val: BytesMut) -> Self {
HttpResponse::Ok().content_type("application/octet-stream").body(val)
HttpResponse::Ok()
.content_type("application/octet-stream")
.body(val)
}
}
@ -752,7 +772,9 @@ impl<'a> From<&'a ClientResponse> for HttpResponseBuilder {
impl<'a, S> From<&'a HttpRequest<S>> for HttpResponseBuilder {
fn from(req: &'a HttpRequest<S>) -> HttpResponseBuilder {
if let Some(router) = req.router() {
router.server_settings().get_response_builder(StatusCode::OK)
router
.server_settings()
.get_response_builder(StatusCode::OK)
} else {
HttpResponse::Ok()
}
@ -800,7 +822,9 @@ thread_local!(static POOL: Rc<UnsafeCell<HttpResponsePool>> = HttpResponsePool::
impl HttpResponsePool {
pub fn pool() -> Rc<UnsafeCell<HttpResponsePool>> {
Rc::new(UnsafeCell::new(HttpResponsePool(VecDeque::with_capacity(128))))
Rc::new(UnsafeCell::new(HttpResponsePool(
VecDeque::with_capacity(128),
)))
}
#[inline]
@ -951,7 +975,9 @@ mod tests {
#[test]
fn test_force_close() {
let resp = HttpResponse::build(StatusCode::OK).force_close().finish();
let resp = HttpResponse::build(StatusCode::OK)
.force_close()
.finish();
assert!(!resp.keep_alive().unwrap())
}
@ -960,7 +986,10 @@ mod tests {
let resp = HttpResponse::build(StatusCode::OK)
.content_type("text/plain")
.body(Body::Empty);
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/plain")
assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(),
"text/plain"
)
}
#[test]
@ -1044,7 +1073,10 @@ mod tests {
HeaderValue::from_static("application/octet-stream")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(b"test".as_ref()));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from(b"test".as_ref())
);
let resp: HttpResponse = b"test".as_ref().respond_to(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
@ -1053,7 +1085,10 @@ mod tests {
HeaderValue::from_static("application/octet-stream")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(b"test".as_ref()));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from(b"test".as_ref())
);
let resp: HttpResponse = "test".to_owned().into();
assert_eq!(resp.status(), StatusCode::OK);
@ -1062,16 +1097,26 @@ mod tests {
HeaderValue::from_static("text/plain; charset=utf-8")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from("test".to_owned()));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from("test".to_owned())
);
let resp: HttpResponse = "test".to_owned().respond_to(req.clone()).ok().unwrap();
let resp: HttpResponse = "test"
.to_owned()
.respond_to(req.clone())
.ok()
.unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(),
HeaderValue::from_static("text/plain; charset=utf-8")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from("test".to_owned()));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from("test".to_owned())
);
let resp: HttpResponse = (&"test".to_owned()).into();
assert_eq!(resp.status(), StatusCode::OK);
@ -1080,17 +1125,25 @@ mod tests {
HeaderValue::from_static("text/plain; charset=utf-8")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(&"test".to_owned()));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from(&"test".to_owned())
);
let resp: HttpResponse =
(&"test".to_owned()).respond_to(req.clone()).ok().unwrap();
let resp: HttpResponse = (&"test".to_owned())
.respond_to(req.clone())
.ok()
.unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(),
HeaderValue::from_static("text/plain; charset=utf-8")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(&"test".to_owned()));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from(&"test".to_owned())
);
let b = Bytes::from_static(b"test");
let resp: HttpResponse = b.into();
@ -1126,7 +1179,10 @@ mod tests {
HeaderValue::from_static("application/octet-stream")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(BytesMut::from("test")));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from(BytesMut::from("test"))
);
let b = BytesMut::from("test");
let resp: HttpResponse = b.respond_to(req.clone()).ok().unwrap();
@ -1136,7 +1192,10 @@ mod tests {
HeaderValue::from_static("application/octet-stream")
);
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(BytesMut::from("test")));
assert_eq!(
resp.body().binary().unwrap(),
&Binary::from(BytesMut::from("test"))
);
}
#[test]

View file

@ -53,8 +53,8 @@ impl<'a> ConnectionInfo<'a> {
// scheme
if scheme.is_none() {
if let Some(h) =
req.headers().get(HeaderName::from_str(X_FORWARDED_PROTO).unwrap())
if let Some(h) = req.headers()
.get(HeaderName::from_str(X_FORWARDED_PROTO).unwrap())
{
if let Ok(h) = h.to_str() {
scheme = h.split(',').next().map(|v| v.trim());
@ -74,8 +74,8 @@ impl<'a> ConnectionInfo<'a> {
// host
if host.is_none() {
if let Some(h) =
req.headers().get(HeaderName::from_str(X_FORWARDED_HOST).unwrap())
if let Some(h) = req.headers()
.get(HeaderName::from_str(X_FORWARDED_HOST).unwrap())
{
if let Ok(h) = h.to_str() {
host = h.split(',').next().map(|v| v.trim());
@ -98,8 +98,8 @@ impl<'a> ConnectionInfo<'a> {
// remote addr
if remote.is_none() {
if let Some(h) =
req.headers().get(HeaderName::from_str(X_FORWARDED_FOR).unwrap())
if let Some(h) = req.headers()
.get(HeaderName::from_str(X_FORWARDED_FOR).unwrap())
{
if let Ok(h) = h.to_str() {
remote = h.split(',').next().map(|v| v.trim());
@ -189,8 +189,10 @@ mod tests {
assert_eq!(info.remote(), Some("192.0.2.60"));
let mut req = HttpRequest::default();
req.headers_mut()
.insert(header::HOST, HeaderValue::from_static("rust-lang.org"));
req.headers_mut().insert(
header::HOST,
HeaderValue::from_static("rust-lang.org"),
);
let info = ConnectionInfo::new(&req);
assert_eq!(info.scheme(), "http");

View file

@ -308,7 +308,10 @@ where
self.fut = Some(Box::new(fut));
}
self.fut.as_mut().expect("JsonBody could not be used second time").poll()
self.fut
.as_mut()
.expect("JsonBody could not be used second time")
.poll()
}
}
@ -359,7 +362,10 @@ mod tests {
fn test_json_body() {
let req = HttpRequest::default();
let mut json = req.json::<MyObject>();
assert_eq!(json.poll().err().unwrap(), JsonPayloadError::ContentType);
assert_eq!(
json.poll().err().unwrap(),
JsonPayloadError::ContentType
);
let mut req = HttpRequest::default();
req.headers_mut().insert(
@ -367,15 +373,20 @@ mod tests {
header::HeaderValue::from_static("application/text"),
);
let mut json = req.json::<MyObject>();
assert_eq!(json.poll().err().unwrap(), JsonPayloadError::ContentType);
assert_eq!(
json.poll().err().unwrap(),
JsonPayloadError::ContentType
);
let mut req = HttpRequest::default();
req.headers_mut().insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static("application/json"),
);
req.headers_mut()
.insert(header::CONTENT_LENGTH, header::HeaderValue::from_static("10000"));
req.headers_mut().insert(
header::CONTENT_LENGTH,
header::HeaderValue::from_static("10000"),
);
let mut json = req.json::<MyObject>().limit(100);
assert_eq!(json.poll().err().unwrap(), JsonPayloadError::Overflow);
@ -384,9 +395,12 @@ mod tests {
header::CONTENT_TYPE,
header::HeaderValue::from_static("application/json"),
);
req.headers_mut()
.insert(header::CONTENT_LENGTH, header::HeaderValue::from_static("16"));
req.payload_mut().unread_data(Bytes::from_static(b"{\"name\": \"test\"}"));
req.headers_mut().insert(
header::CONTENT_LENGTH,
header::HeaderValue::from_static("16"),
);
req.payload_mut()
.unread_data(Bytes::from_static(b"{\"name\": \"test\"}"));
let mut json = req.json::<MyObject>();
assert_eq!(
json.poll().ok().unwrap(),
@ -403,7 +417,12 @@ mod tests {
let mut handler = With::new(|data: Json<MyObject>| data, cfg);
let req = HttpRequest::default();
let err = handler.handle(req).as_response().unwrap().error().is_some();
let err = handler
.handle(req)
.as_response()
.unwrap()
.error()
.is_some();
assert!(err);
let mut req = HttpRequest::default();
@ -411,10 +430,18 @@ mod tests {
header::CONTENT_TYPE,
header::HeaderValue::from_static("application/json"),
);
req.headers_mut()
.insert(header::CONTENT_LENGTH, header::HeaderValue::from_static("16"));
req.payload_mut().unread_data(Bytes::from_static(b"{\"name\": \"test\"}"));
let ok = handler.handle(req).as_response().unwrap().error().is_none();
req.headers_mut().insert(
header::CONTENT_LENGTH,
header::HeaderValue::from_static("16"),
);
req.payload_mut()
.unread_data(Bytes::from_static(b"{\"name\": \"test\"}"));
let ok = handler
.handle(req)
.as_response()
.unwrap()
.error()
.is_none();
assert!(ok)
}
}

View file

@ -275,7 +275,9 @@ impl Cors {
/// `ResourceHandler::middleware()` method, but in that case *Cors*
/// middleware wont be able to handle *OPTIONS* requests.
pub fn register<S: 'static>(self, resource: &mut ResourceHandler<S>) {
resource.method(Method::OPTIONS).h(|_| HttpResponse::Ok());
resource
.method(Method::OPTIONS)
.h(|_| HttpResponse::Ok());
resource.middleware(self);
}
@ -302,7 +304,9 @@ impl Cors {
fn validate_allowed_method<S>(
&self, req: &mut HttpRequest<S>,
) -> Result<(), CorsError> {
if let Some(hdr) = req.headers().get(header::ACCESS_CONTROL_REQUEST_METHOD) {
if let Some(hdr) = req.headers()
.get(header::ACCESS_CONTROL_REQUEST_METHOD)
{
if let Ok(meth) = hdr.to_str() {
if let Ok(method) = Method::try_from(meth) {
return self.inner
@ -324,8 +328,8 @@ impl Cors {
match self.inner.headers {
AllOrSome::All => Ok(()),
AllOrSome::Some(ref allowed_headers) => {
if let Some(hdr) =
req.headers().get(header::ACCESS_CONTROL_REQUEST_HEADERS)
if let Some(hdr) = req.headers()
.get(header::ACCESS_CONTROL_REQUEST_HEADERS)
{
if let Ok(headers) = hdr.to_str() {
let mut hdrs = HashSet::new();
@ -367,8 +371,8 @@ impl<S> Middleware<S> for Cors {
.as_str()[1..],
).unwrap(),
)
} else if let Some(hdr) =
req.headers().get(header::ACCESS_CONTROL_REQUEST_HEADERS)
} else if let Some(hdr) = req.headers()
.get(header::ACCESS_CONTROL_REQUEST_HEADERS)
{
Some(hdr.clone())
} else {
@ -819,13 +823,17 @@ impl<S: 'static> CorsBuilder<S> {
}
if let AllOrSome::Some(ref origins) = cors.origins {
let s = origins.iter().fold(String::new(), |s, v| s + &v.to_string());
let s = origins
.iter()
.fold(String::new(), |s, v| s + &v.to_string());
cors.origins_str = Some(HeaderValue::try_from(s.as_str()).unwrap());
}
if !self.expose_hdrs.is_empty() {
cors.expose_hdrs = Some(
self.expose_hdrs.iter().fold(String::new(), |s, v| s + v.as_str())[1..]
self.expose_hdrs
.iter()
.fold(String::new(), |s, v| s + v.as_str())[1..]
.to_owned(),
);
}
@ -903,19 +911,27 @@ mod tests {
#[test]
#[should_panic(expected = "Credentials are allowed, but the Origin is set to")]
fn cors_validates_illegal_allow_credentials() {
Cors::build().supports_credentials().send_wildcard().finish();
Cors::build()
.supports_credentials()
.send_wildcard()
.finish();
}
#[test]
#[should_panic(expected = "No resources are registered")]
fn no_resource() {
Cors::build().supports_credentials().send_wildcard().register();
Cors::build()
.supports_credentials()
.send_wildcard()
.register();
}
#[test]
#[should_panic(expected = "Cors::for_app(app)")]
fn no_resource2() {
Cors::build().resource("/test", |r| r.f(|_| HttpResponse::Ok())).register();
Cors::build()
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
.register();
}
#[test]
@ -952,18 +968,27 @@ mod tests {
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(header::ACCESS_CONTROL_REQUEST_HEADERS, "AUTHORIZATION,ACCEPT")
.header(
header::ACCESS_CONTROL_REQUEST_HEADERS,
"AUTHORIZATION,ACCEPT",
)
.method(Method::OPTIONS)
.finish();
let resp = cors.start(&mut req).unwrap().response();
assert_eq!(
&b"*"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes()
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
assert_eq!(
&b"3600"[..],
resp.headers().get(header::ACCESS_CONTROL_MAX_AGE).unwrap().as_bytes()
resp.headers()
.get(header::ACCESS_CONTROL_MAX_AGE)
.unwrap()
.as_bytes()
);
//assert_eq!(
// &b"authorization,accept,content-type"[..],
@ -980,7 +1005,9 @@ mod tests {
#[test]
#[should_panic(expected = "MissingOrigin")]
fn test_validate_missing_origin() {
let cors = Cors::build().allowed_origin("https://www.example.com").finish();
let cors = Cors::build()
.allowed_origin("https://www.example.com")
.finish();
let mut req = HttpRequest::default();
cors.start(&mut req).unwrap();
@ -989,7 +1016,9 @@ mod tests {
#[test]
#[should_panic(expected = "OriginNotAllowed")]
fn test_validate_not_allowed_origin() {
let cors = Cors::build().allowed_origin("https://www.example.com").finish();
let cors = Cors::build()
.allowed_origin("https://www.example.com")
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.unknown.com")
.method(Method::GET)
@ -999,7 +1028,9 @@ mod tests {
#[test]
fn test_validate_origin() {
let cors = Cors::build().allowed_origin("https://www.example.com").finish();
let cors = Cors::build()
.allowed_origin("https://www.example.com")
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::GET)
@ -1015,7 +1046,11 @@ mod tests {
let mut req = TestRequest::default().method(Method::GET).finish();
let resp: HttpResponse = HttpResponse::Ok().into();
let resp = cors.response(&mut req, resp).unwrap().response();
assert!(resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).is_none());
assert!(
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.is_none()
);
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
@ -1023,7 +1058,10 @@ mod tests {
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"https://www.example.com"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes()
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
}
@ -1046,12 +1084,19 @@ mod tests {
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"*"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes()
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
assert_eq!(
&b"Origin"[..],
resp.headers().get(header::VARY).unwrap().as_bytes()
);
assert_eq!(&b"Origin"[..], resp.headers().get(header::VARY).unwrap().as_bytes());
let resp: HttpResponse =
HttpResponse::Ok().header(header::VARY, "Accept").finish();
let resp: HttpResponse = HttpResponse::Ok()
.header(header::VARY, "Accept")
.finish();
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"Accept, Origin"[..],
@ -1066,7 +1111,10 @@ mod tests {
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"https://www.example.com"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes()
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
}

View file

@ -89,7 +89,10 @@ fn origin(headers: &HeaderMap) -> Option<Result<Cow<str>, CsrfError>> {
headers
.get(header::ORIGIN)
.map(|origin| {
origin.to_str().map_err(|_| CsrfError::BadOrigin).map(|o| o.into())
origin
.to_str()
.map_err(|_| CsrfError::BadOrigin)
.map(|o| o.into())
})
.or_else(|| {
headers.get(header::REFERER).map(|referer| {
@ -258,8 +261,9 @@ mod tests {
fn test_upgrade() {
let strict_csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
let lax_csrf =
CsrfFilter::new().allowed_origin("https://www.example.com").allow_upgrade();
let lax_csrf = CsrfFilter::new()
.allowed_origin("https://www.example.com")
.allow_upgrade();
let mut req = TestRequest::with_header("Origin", "https://cswsh.com")
.header("Connection", "Upgrade")

View file

@ -112,7 +112,9 @@ mod tests {
};
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
let resp = HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish();
let resp = HttpResponse::Ok()
.header(CONTENT_TYPE, "0002")
.finish();
let resp = match mw.response(&mut req, resp) {
Ok(Response::Done(resp)) => resp,
_ => panic!(),

View file

@ -164,9 +164,7 @@ pub struct IdentityService<T> {
impl<T> IdentityService<T> {
/// Create new identity service with specified backend.
pub fn new(backend: T) -> Self {
IdentityService {
backend,
}
IdentityService { backend }
}
}
@ -181,13 +179,15 @@ impl<S: 'static, T: IdentityPolicy<S>> Middleware<S> for IdentityService<T> {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
let mut req = req.clone();
let fut = self.backend.from_request(&mut req).then(move |res| match res {
Ok(id) => {
req.extensions().insert(IdentityBox(Box::new(id)));
FutOk(None)
}
Err(err) => FutErr(err),
});
let fut = self.backend
.from_request(&mut req)
.then(move |res| match res {
Ok(id) => {
req.extensions().insert(IdentityBox(Box::new(id)));
FutOk(None)
}
Err(err) => FutErr(err),
});
Ok(Started::Future(Box::new(fut)))
}

View file

@ -254,9 +254,10 @@ impl FormatText {
"-".fmt(fmt)
}
}
FormatText::RequestTime => {
entry_time.strftime("[%d/%b/%Y:%H:%M:%S %z]").unwrap().fmt(fmt)
}
FormatText::RequestTime => entry_time
.strftime("[%d/%b/%Y:%H:%M:%S %z]")
.unwrap()
.fmt(fmt),
FormatText::RequestHeader(ref name) => {
let s = if let Some(val) = req.headers().get(name) {
if let Ok(s) = val.to_str() {
@ -313,8 +314,10 @@ mod tests {
let logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test");
let mut headers = HeaderMap::new();
headers
.insert(header::USER_AGENT, header::HeaderValue::from_static("ACTIX-WEB"));
headers.insert(
header::USER_AGENT,
header::HeaderValue::from_static("ACTIX-WEB"),
);
let mut req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
@ -351,8 +354,10 @@ mod tests {
let format = Format::default();
let mut headers = HeaderMap::new();
headers
.insert(header::USER_AGENT, header::HeaderValue::from_static("ACTIX-WEB"));
headers.insert(
header::USER_AGENT,
header::HeaderValue::from_static("ACTIX-WEB"),
);
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
@ -360,7 +365,9 @@ mod tests {
headers,
None,
);
let resp = HttpResponse::build(StatusCode::OK).force_close().finish();
let resp = HttpResponse::build(StatusCode::OK)
.force_close()
.finish();
let entry_time = time::now();
let render = |fmt: &mut Formatter| {
@ -381,7 +388,9 @@ mod tests {
HeaderMap::new(),
None,
);
let resp = HttpResponse::build(StatusCode::OK).force_close().finish();
let resp = HttpResponse::build(StatusCode::OK)
.force_close()
.finish();
let entry_time = time::now();
let render = |fmt: &mut Formatter| {

View file

@ -202,13 +202,16 @@ impl<S: 'static, T: SessionBackend<S>> Middleware<S> for SessionStorage<T, S> {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
let mut req = req.clone();
let fut = self.0.from_request(&mut req).then(move |res| match res {
Ok(sess) => {
req.extensions().insert(Arc::new(SessionImplBox(Box::new(sess))));
FutOk(None)
}
Err(err) => FutErr(err),
});
let fut = self.0
.from_request(&mut req)
.then(move |res| match res {
Ok(sess) => {
req.extensions()
.insert(Arc::new(SessionImplBox(Box::new(sess))));
FutOk(None)
}
Err(err) => FutErr(err),
});
Ok(Started::Future(Box::new(fut)))
}

View file

@ -122,7 +122,11 @@ where
if let Some(err) = self.error.take() {
Err(err)
} else if self.safety.current() {
self.inner.as_mut().unwrap().borrow_mut().poll(&self.safety)
self.inner
.as_mut()
.unwrap()
.borrow_mut()
.poll(&self.safety)
} else {
Ok(Async::NotReady)
}
@ -671,7 +675,10 @@ mod tests {
}
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_TYPE, header::HeaderValue::from_static("test"));
headers.insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static("test"),
);
match Multipart::boundary(&headers) {
Err(MultipartError::ParseContentType) => (),

View file

@ -94,7 +94,8 @@ impl<'a, 'b, 'c: 'a> Index<&'b str> for &'c Params<'a> {
type Output = str;
fn index(&self, name: &'b str) -> &str {
self.get(name).expect("Value for parameter is not available")
self.get(name)
.expect("Value for parameter is not available")
}
}
@ -201,9 +202,18 @@ mod tests {
PathBuf::from_param("/test/*tt"),
Err(UriSegmentError::BadStart('*'))
);
assert_eq!(PathBuf::from_param("/test/tt:"), Err(UriSegmentError::BadEnd(':')));
assert_eq!(PathBuf::from_param("/test/tt<"), Err(UriSegmentError::BadEnd('<')));
assert_eq!(PathBuf::from_param("/test/tt>"), Err(UriSegmentError::BadEnd('>')));
assert_eq!(
PathBuf::from_param("/test/tt:"),
Err(UriSegmentError::BadEnd(':'))
);
assert_eq!(
PathBuf::from_param("/test/tt<"),
Err(UriSegmentError::BadEnd('<'))
);
assert_eq!(
PathBuf::from_param("/test/tt>"),
Err(UriSegmentError::BadEnd('>'))
);
assert_eq!(
PathBuf::from_param("/seg1/seg2/"),
Ok(PathBuf::from_iter(vec!["seg1", "seg2"]))

View file

@ -47,9 +47,7 @@ impl Payload {
PayloadSender {
inner: Rc::downgrade(&shared),
},
Payload {
inner: shared,
},
Payload { inner: shared },
)
}
@ -536,7 +534,10 @@ mod tests {
assert_eq!(format!("{}", err.cause().unwrap()), "ParseError");
let err = PayloadError::Incomplete;
assert_eq!(format!("{}", err), "A payload reached EOF, but is not complete.");
assert_eq!(
format!("{}", err),
"A payload reached EOF, but is not complete."
);
}
#[test]
@ -670,7 +671,10 @@ mod tests {
let (mut sender, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
assert_eq!(Async::NotReady, payload.read_until(b"ne").ok().unwrap());
assert_eq!(
Async::NotReady,
payload.read_until(b"ne").ok().unwrap()
);
sender.feed_data(Bytes::from("line1"));
sender.feed_data(Bytes::from("line2"));

View file

@ -796,15 +796,18 @@ mod tests {
.unwrap()
.run(lazy(|| {
let mut info = PipelineInfo::new(HttpRequest::default());
Completed::<(), Inner<()>>::init(&mut info).is_none().unwrap();
Completed::<(), Inner<()>>::init(&mut info)
.is_none()
.unwrap();
let req = HttpRequest::default();
let mut ctx = HttpContext::new(req.clone(), MyActor);
let addr: Addr<Unsync, _> = ctx.address();
let mut info = PipelineInfo::new(req);
info.context = Some(Box::new(ctx));
let mut state =
Completed::<(), Inner<()>>::init(&mut info).completed().unwrap();
let mut state = Completed::<(), Inner<()>>::init(&mut info)
.completed()
.unwrap();
assert!(state.poll(&mut info).is_none());
let pp = Pipeline(info, PipelineState::Completed(state));

View file

@ -181,7 +181,11 @@ pub fn Header<S: 'static>(
}
#[doc(hidden)]
pub struct HeaderPredicate<S>(header::HeaderName, header::HeaderValue, PhantomData<S>);
pub struct HeaderPredicate<S>(
header::HeaderName,
header::HeaderValue,
PhantomData<S>,
);
impl<S: 'static> Predicate<S> for HeaderPredicate<S> {
fn check(&self, req: &mut HttpRequest<S>) -> bool {

View file

@ -132,7 +132,10 @@ impl<S: 'static> ResourceHandler<S> {
/// ```
pub fn method(&mut self, method: Method) -> &mut Route<S> {
self.routes.push(Route::default());
self.routes.last_mut().unwrap().filter(pred::Method(method))
self.routes
.last_mut()
.unwrap()
.filter(pred::Method(method))
}
/// Register a new route and add handler object.
@ -185,7 +188,9 @@ impl<S: 'static> ResourceHandler<S> {
/// This is similar to `App's` middlewares, but
/// middlewares get invoked on resource level.
pub fn middleware<M: Middleware<S>>(&mut self, mw: M) {
Rc::get_mut(&mut self.middlewares).unwrap().push(Box::new(mw));
Rc::get_mut(&mut self.middlewares)
.unwrap()
.push(Box::new(mw));
}
pub(crate) fn handle(

View file

@ -1,6 +1,6 @@
use futures::{Async, Future, Poll};
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;
use error::Error;
@ -180,14 +180,22 @@ impl<S: 'static> Route<S> {
{
let cfg1 = ExtractorConfig::default();
let cfg2 = ExtractorConfig::default();
self.h(With2::new(handler, Clone::clone(&cfg1), Clone::clone(&cfg2)));
self.h(With2::new(
handler,
Clone::clone(&cfg1),
Clone::clone(&cfg2),
));
(cfg1, cfg2)
}
/// Set handler function, use request extractor for all paramters.
pub fn with3<T1, T2, T3, F, R>(
&mut self, handler: F,
) -> (ExtractorConfig<S, T1>, ExtractorConfig<S, T2>, ExtractorConfig<S, T3>)
) -> (
ExtractorConfig<S, T1>,
ExtractorConfig<S, T2>,
ExtractorConfig<S, T3>,
)
where
F: Fn(T1, T2, T3) -> R + 'static,
R: Responder + 'static,
@ -210,12 +218,14 @@ impl<S: 'static> Route<S> {
/// `RouteHandler` wrapper. This struct is required because it needs to be
/// shared for resource level middlewares.
struct InnerHandler<S>(Rc<Box<RouteHandler<S>>>);
struct InnerHandler<S>(Rc<UnsafeCell<Box<RouteHandler<S>>>>);
impl<S: 'static> InnerHandler<S> {
#[inline]
fn new<H: Handler<S>>(h: H) -> Self {
InnerHandler(Rc::new(Box::new(WrapHandler::new(h))))
InnerHandler(Rc::new(UnsafeCell::new(Box::new(WrapHandler::new(
h,
)))))
}
#[inline]
@ -226,16 +236,15 @@ impl<S: 'static> InnerHandler<S> {
R: Responder + 'static,
E: Into<Error> + 'static,
{
InnerHandler(Rc::new(Box::new(AsyncHandler::new(h))))
InnerHandler(Rc::new(UnsafeCell::new(Box::new(AsyncHandler::new(
h,
)))))
}
#[inline]
pub fn handle(&self, req: HttpRequest<S>) -> Reply {
// reason: handler is unique per thread,
// handler get called from async code only
#[allow(mutable_transmutes)]
#[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
let h: &mut Box<RouteHandler<S>> = unsafe { mem::transmute(self.0.as_ref()) };
// reason: handler is unique per thread, handler get called from async code only
let h = unsafe { &mut *self.0.as_ref().get() };
h.handle(req)
}
}
@ -290,10 +299,7 @@ impl<S: 'static> Compose<S> {
};
let state = StartMiddlewares::init(&mut info);
Compose {
state,
info,
}
Compose { state, info }
}
}

View file

@ -1,6 +1,5 @@
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::mem;
use std::rc::Rc;
use regex::{escape, Regex};
@ -79,12 +78,8 @@ impl Router {
if self.0.prefix_len > req.path().len() {
return None;
}
let path: &str = unsafe { mem::transmute(&req.path()[self.0.prefix_len..]) };
let route_path = if path.is_empty() {
"/"
} else {
path
};
let path = unsafe { &*(&req.path()[self.0.prefix_len..] as *const str) };
let route_path = if path.is_empty() { "/" } else { path };
for (idx, pattern) in self.0.patterns.iter().enumerate() {
if pattern.match_with_params(route_path, req.match_info_mut()) {
@ -102,11 +97,7 @@ impl Router {
/// following path would be recognizable `/test/name` but `has_route()` call
/// would return `false`.
pub fn has_route(&self, path: &str) -> bool {
let path = if path.is_empty() {
"/"
} else {
path
};
let path = if path.is_empty() { "/" } else { path };
for pattern in &self.0.patterns {
if pattern.is_match(path) {
@ -391,19 +382,34 @@ mod tests {
#[test]
fn test_recognizer() {
let routes = vec![
(Resource::new("", "/name"), Some(ResourceHandler::default())),
(Resource::new("", "/name/{val}"), Some(ResourceHandler::default())),
(
Resource::new("", "/name"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "/name/{val}"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "/name/{val}/index.html"),
Some(ResourceHandler::default()),
),
(Resource::new("", "/file/{file}.{ext}"), Some(ResourceHandler::default())),
(
Resource::new("", "/file/{file}.{ext}"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "/v{val}/{val2}/index.html"),
Some(ResourceHandler::default()),
),
(Resource::new("", "/v/{tail:.*}"), Some(ResourceHandler::default())),
(Resource::new("", "{test}/index.html"), Some(ResourceHandler::default())),
(
Resource::new("", "/v/{tail:.*}"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "{test}/index.html"),
Some(ResourceHandler::default()),
),
];
let (rec, _) = Router::new::<()>("", ServerSettings::default(), routes);
@ -432,7 +438,10 @@ mod tests {
let mut req = TestRequest::with_uri("/v/blah-blah/index.html").finish();
assert_eq!(rec.recognize(&mut req), Some(5));
assert_eq!(req.match_info().get("tail").unwrap(), "blah-blah/index.html");
assert_eq!(
req.match_info().get("tail").unwrap(),
"blah-blah/index.html"
);
let mut req = TestRequest::with_uri("/bbb/index.html").finish();
assert_eq!(rec.recognize(&mut req), Some(6));
@ -442,8 +451,14 @@ mod tests {
#[test]
fn test_recognizer_2() {
let routes = vec![
(Resource::new("", "/index.json"), Some(ResourceHandler::default())),
(Resource::new("", "/{source}.json"), Some(ResourceHandler::default())),
(
Resource::new("", "/index.json"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "/{source}.json"),
Some(ResourceHandler::default()),
),
];
let (rec, _) = Router::new::<()>("", ServerSettings::default(), routes);
@ -457,8 +472,14 @@ mod tests {
#[test]
fn test_recognizer_with_prefix() {
let routes = vec![
(Resource::new("", "/name"), Some(ResourceHandler::default())),
(Resource::new("", "/name/{val}"), Some(ResourceHandler::default())),
(
Resource::new("", "/name"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "/name/{val}"),
Some(ResourceHandler::default()),
),
];
let (rec, _) = Router::new::<()>("/test", ServerSettings::default(), routes);
@ -475,8 +496,14 @@ mod tests {
// same patterns
let routes = vec![
(Resource::new("", "/name"), Some(ResourceHandler::default())),
(Resource::new("", "/name/{val}"), Some(ResourceHandler::default())),
(
Resource::new("", "/name"),
Some(ResourceHandler::default()),
),
(
Resource::new("", "/name/{val}"),
Some(ResourceHandler::default()),
),
];
let (rec, _) = Router::new::<()>("/test2", ServerSettings::default(), routes);
@ -545,8 +572,14 @@ mod tests {
#[test]
fn test_request_resource() {
let routes = vec![
(Resource::new("r1", "/index.json"), Some(ResourceHandler::default())),
(Resource::new("r2", "/test.json"), Some(ResourceHandler::default())),
(
Resource::new("r1", "/index.json"),
Some(ResourceHandler::default()),
),
(
Resource::new("r2", "/test.json"),
Some(ResourceHandler::default()),
),
];
let (router, _) = Router::new::<()>("", ServerSettings::default(), routes);

View file

@ -1,6 +1,6 @@
use std::net::{Shutdown, SocketAddr};
use std::rc::Rc;
use std::{io, mem, ptr, time};
use std::{io, ptr, time};
use bytes::{Buf, BufMut, Bytes, BytesMut};
use futures::{Async, Future, Poll};
@ -93,12 +93,12 @@ where
let el = self as *mut _;
self.node = Some(Node::new(el));
let _ = match self.proto {
Some(HttpProtocol::H1(ref mut h1)) => {
self.node.as_ref().map(|n| h1.settings().head().insert(n))
}
Some(HttpProtocol::H2(ref mut h2)) => {
self.node.as_ref().map(|n| h2.settings().head().insert(n))
}
Some(HttpProtocol::H1(ref mut h1)) => self.node
.as_ref()
.map(|n| h1.settings().head().insert(n)),
Some(HttpProtocol::H2(ref mut h2)) => self.node
.as_ref()
.map(|n| h2.settings().head().insert(n)),
Some(HttpProtocol::Unknown(ref mut settings, _, _, _)) => {
self.node.as_ref().map(|n| settings.head().insert(n))
}
@ -168,8 +168,9 @@ where
if let Some(HttpProtocol::Unknown(settings, addr, io, buf)) = self.proto.take() {
match kind {
ProtocolKind::Http1 => {
self.proto =
Some(HttpProtocol::H1(h1::Http1::new(settings, io, addr, buf)));
self.proto = Some(HttpProtocol::H1(h1::Http1::new(
settings, io, addr, buf,
)));
return self.poll();
}
ProtocolKind::Http2 => {
@ -210,10 +211,11 @@ impl<T> Node<T> {
&mut *(next2.as_ref().unwrap() as *const _ as *mut _);
n.prev = Some(next as *const _ as *mut _);
}
let slf: &mut Node<T> = mem::transmute(self);
let slf: &mut Node<T> = &mut *(self as *const _ as *mut _);
slf.next = Some(next as *const _ as *mut _);
let next: &mut Node<T> = mem::transmute(next);
let next: &mut Node<T> = &mut *(next as *const _ as *mut _);
next.prev = Some(slf as *const _ as *mut _);
}
}
@ -249,12 +251,12 @@ impl Node<()> {
loop {
if let Some(n) = next {
unsafe {
let n: &Node<()> = mem::transmute(n.as_ref().unwrap());
let n: &Node<()> = &*(n.as_ref().unwrap() as *const _);
next = n.next.as_ref();
if !n.element.is_null() {
let ch: &mut HttpChannel<T, H> =
mem::transmute(&mut *(n.element as *mut _));
&mut *(&mut *(n.element as *mut _) as *mut () as *mut _);
ch.shutdown();
}
}
@ -278,9 +280,7 @@ where
T: AsyncRead + AsyncWrite + 'static,
{
pub fn new(io: T) -> Self {
WrapperStream {
io,
}
WrapperStream { io }
}
}

View file

@ -763,7 +763,8 @@ impl TransferEncoding {
return Ok(*remaining == 0);
}
let len = cmp::min(*remaining, msg.len() as u64);
self.buffer.extend(msg.take().split_to(len as usize).into());
self.buffer
.extend(msg.take().split_to(len as usize).into());
*remaining -= len as u64;
Ok(*remaining == 0)
@ -855,8 +856,10 @@ impl AcceptEncoding {
/// Parse a raw Accept-Encoding header value into an ordered list.
pub fn parse(raw: &str) -> ContentEncoding {
let mut encodings: Vec<_> =
raw.replace(' ', "").split(',').map(|l| AcceptEncoding::new(l)).collect();
let mut encodings: Vec<_> = raw.replace(' ', "")
.split(',')
.map(|l| AcceptEncoding::new(l))
.collect();
encodings.sort();
for enc in encodings {
@ -876,7 +879,9 @@ mod tests {
fn test_chunked_te() {
let bytes = SharedBytes::default();
let mut enc = TransferEncoding::chunked(bytes.clone());
assert!(!enc.encode(Binary::from(b"test".as_ref())).ok().unwrap());
assert!(!enc.encode(Binary::from(b"test".as_ref()))
.ok()
.unwrap());
assert!(enc.encode(Binary::from(b"".as_ref())).ok().unwrap());
assert_eq!(
bytes.get_mut().take().freeze(),

View file

@ -1,10 +1,8 @@
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
use std::collections::VecDeque;
use std::io;
use std::net::SocketAddr;
use std::rc::Rc;
use std::time::Duration;
use std::{io, mem};
use actix::Arbiter;
use bytes::{BufMut, BytesMut};
@ -153,28 +151,25 @@ where
if !self.flags.intersects(Flags::ERROR)
&& self.tasks.len() < MAX_PIPELINED_MESSAGES && self.can_read()
{
match self.read() {
Ok(true) | Err(_) => {
// notify all tasks
self.stream.disconnected();
for entry in &mut self.tasks {
entry.pipe.disconnected()
}
// kill keepalive
self.flags.remove(Flags::KEEPALIVE);
self.keepalive_timer.take();
// on parse error, stop reading stream but tasks need to be
// completed
self.flags.insert(Flags::ERROR);
if let Some(ref mut payload) = self.payload {
payload.set_error(PayloadError::Incomplete);
}
if self.read() {
// notify all tasks
self.stream.disconnected();
for entry in &mut self.tasks {
entry.pipe.disconnected()
}
Ok(false) => {
self.parse();
// kill keepalive
self.flags.remove(Flags::KEEPALIVE);
self.keepalive_timer.take();
// on parse error, stop reading stream but tasks need to be
// completed
self.flags.insert(Flags::ERROR);
if let Some(ref mut payload) = self.payload {
payload.set_error(PayloadError::Incomplete);
}
} else {
self.parse();
}
}
}
@ -186,7 +181,7 @@ where
let mut io = false;
let mut idx = 0;
while idx < self.tasks.len() {
let item: &mut Entry = unsafe { mem::transmute(&mut self.tasks[idx]) };
let item: &mut Entry = unsafe { &mut *(&mut self.tasks[idx] as *mut _) };
// only one task can do io operation in http/1
if !io && !item.flags.contains(EntryFlags::EOF) {
@ -210,7 +205,8 @@ where
self.stream.reset();
if ready {
item.flags.insert(EntryFlags::EOF | EntryFlags::FINISHED);
item.flags
.insert(EntryFlags::EOF | EntryFlags::FINISHED);
} else {
item.flags.insert(EntryFlags::FINISHED);
}
@ -252,7 +248,10 @@ where
// cleanup finished tasks
let max = self.tasks.len() >= MAX_PIPELINED_MESSAGES;
while !self.tasks.is_empty() {
if self.tasks[0].flags.contains(EntryFlags::EOF | EntryFlags::FINISHED) {
if self.tasks[0]
.flags
.contains(EntryFlags::EOF | EntryFlags::FINISHED)
{
self.tasks.pop_front();
} else {
break;
@ -277,7 +276,7 @@ where
// deal with keep-alive
if self.tasks.is_empty() {
// no keep-alive situations
// no keep-alive
if self.flags.contains(Flags::ERROR)
|| (!self.flags.contains(Flags::KEEPALIVE)
|| !self.settings.keep_alive_enabled())
@ -304,10 +303,7 @@ where
pub fn parse(&mut self) {
'outer: loop {
match self.decoder.decode(&mut self.buf, &self.settings) {
Ok(Some(Message::Message {
msg,
payload,
})) => {
Ok(Some(Message::Message { msg, payload })) => {
self.flags.insert(Flags::STARTED);
if payload {
@ -377,7 +373,7 @@ where
}
#[inline]
fn read(&mut self) -> io::Result<bool> {
fn read(&mut self) -> bool {
loop {
unsafe {
if self.buf.remaining_mut() < LW_BUFFER_SIZE {
@ -386,16 +382,16 @@ where
match self.stream.get_mut().read(self.buf.bytes_mut()) {
Ok(n) => {
if n == 0 {
return Ok(true);
return true;
} else {
self.buf.advance_mut(n);
}
}
Err(e) => {
return if e.kind() == io::ErrorKind::WouldBlock {
Ok(false)
false
} else {
Err(e)
true
};
}
}
@ -420,19 +416,13 @@ mod tests {
impl Message {
fn message(self) -> SharedHttpInnerMessage {
match self {
Message::Message {
msg,
payload: _,
} => msg,
Message::Message { msg, payload: _ } => msg,
_ => panic!("error"),
}
}
fn is_payload(&self) -> bool {
match *self {
Message::Message {
msg: _,
payload,
} => payload,
Message::Message { msg: _, payload } => payload,
_ => panic!("error"),
}
}
@ -628,7 +618,10 @@ mod tests {
assert_eq!(req.version(), Version::HTTP_11);
assert_eq!(*req.method(), Method::GET);
assert_eq!(req.path(), "/test");
assert_eq!(req.headers().get("test").unwrap().as_bytes(), b"value");
assert_eq!(
req.headers().get("test").unwrap().as_bytes(),
b"value"
);
}
Ok(_) | Err(_) => unreachable!("Error during parsing http request"),
}
@ -850,7 +843,12 @@ mod tests {
assert!(!req.keep_alive());
assert!(req.upgrade());
assert_eq!(
reader.decode(&mut buf, &settings).unwrap().unwrap().chunk().as_ref(),
reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.chunk()
.as_ref(),
b"some raw data"
);
}
@ -907,14 +905,30 @@ mod tests {
buf.extend(b"4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n");
assert_eq!(
reader.decode(&mut buf, &settings).unwrap().unwrap().chunk().as_ref(),
reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.chunk()
.as_ref(),
b"data"
);
assert_eq!(
reader.decode(&mut buf, &settings).unwrap().unwrap().chunk().as_ref(),
reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.chunk()
.as_ref(),
b"line"
);
assert!(reader.decode(&mut buf, &settings).unwrap().unwrap().eof());
assert!(
reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.eof()
);
}
#[test]
@ -995,7 +1009,13 @@ mod tests {
assert!(reader.decode(&mut buf, &settings).unwrap().is_none());
buf.extend(b"\r\n");
assert!(reader.decode(&mut buf, &settings).unwrap().unwrap().eof());
assert!(
reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.eof()
);
}
#[test]
@ -1013,9 +1033,17 @@ mod tests {
assert!(req.chunked().unwrap());
buf.extend(b"4;test\r\ndata\r\n4\r\nline\r\n0\r\n\r\n"); // test: test\r\n\r\n")
let chunk = reader.decode(&mut buf, &settings).unwrap().unwrap().chunk();
let chunk = reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.chunk();
assert_eq!(chunk, Bytes::from_static(b"data"));
let chunk = reader.decode(&mut buf, &settings).unwrap().unwrap().chunk();
let chunk = reader
.decode(&mut buf, &settings)
.unwrap()
.unwrap()
.chunk();
assert_eq!(chunk, Bytes::from_static(b"line"));
let msg = reader.decode(&mut buf, &settings).unwrap().unwrap();
assert!(msg.eof());

View file

@ -41,9 +41,7 @@ impl From<io::Error> for DecoderError {
impl H1Decoder {
pub fn new() -> H1Decoder {
H1Decoder {
decoder: None,
}
H1Decoder { decoder: None }
}
pub fn decode<H>(
@ -61,7 +59,9 @@ impl H1Decoder {
}
}
match self.parse_message(src, settings).map_err(DecoderError::Error)? {
match self.parse_message(src, settings)
.map_err(DecoderError::Error)?
{
Async::Ready((msg, decoder)) => {
if let Some(decoder) = decoder {
self.decoder = Some(decoder);
@ -415,9 +415,10 @@ impl ChunkedState {
match byte!(rdr) {
b'\n' if *size > 0 => Ok(Async::Ready(ChunkedState::Body)),
b'\n' if *size == 0 => Ok(Async::Ready(ChunkedState::EndCr)),
_ => {
Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk size LF"))
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk size LF",
)),
}
}
@ -450,33 +451,37 @@ impl ChunkedState {
fn read_body_cr(rdr: &mut BytesMut) -> Poll<ChunkedState, io::Error> {
match byte!(rdr) {
b'\r' => Ok(Async::Ready(ChunkedState::BodyLf)),
_ => {
Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk body CR"))
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk body CR",
)),
}
}
fn read_body_lf(rdr: &mut BytesMut) -> Poll<ChunkedState, io::Error> {
match byte!(rdr) {
b'\n' => Ok(Async::Ready(ChunkedState::Size)),
_ => {
Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk body LF"))
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk body LF",
)),
}
}
fn read_end_cr(rdr: &mut BytesMut) -> Poll<ChunkedState, io::Error> {
match byte!(rdr) {
b'\r' => Ok(Async::Ready(ChunkedState::EndLf)),
_ => {
Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk end CR"))
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk end CR",
)),
}
}
fn read_end_lf(rdr: &mut BytesMut) -> Poll<ChunkedState, io::Error> {
match byte!(rdr) {
b'\n' => Ok(Async::Ready(ChunkedState::End)),
_ => {
Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk end LF"))
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid chunk end LF",
)),
}
}
}

View file

@ -117,7 +117,8 @@ impl<T: AsyncWrite, H: 'static> Writer for H1Writer<T, H> {
let version = msg.version().unwrap_or_else(|| req.version);
if msg.upgrade() {
self.flags.insert(Flags::UPGRADE);
msg.headers_mut().insert(CONNECTION, HeaderValue::from_static("upgrade"));
msg.headers_mut()
.insert(CONNECTION, HeaderValue::from_static("upgrade"));
}
// keep-alive
else if self.flags.contains(Flags::KEEPALIVE) {
@ -126,7 +127,8 @@ impl<T: AsyncWrite, H: 'static> Writer for H1Writer<T, H> {
.insert(CONNECTION, HeaderValue::from_static("keep-alive"));
}
} else if version >= Version::HTTP_11 {
msg.headers_mut().insert(CONNECTION, HeaderValue::from_static("close"));
msg.headers_mut()
.insert(CONNECTION, HeaderValue::from_static("close"));
}
let body = msg.replace_body(Body::Empty);

View file

@ -107,7 +107,8 @@ impl<H: 'static> Writer for H2Writer<H> {
);
}
Body::Empty => {
msg.headers_mut().insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
msg.headers_mut()
.insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
}
_ => (),
}
@ -119,7 +120,9 @@ impl<H: 'static> Writer for H2Writer<H> {
resp.headers_mut().insert(key, value.clone());
}
match self.respond.send_response(resp, self.flags.contains(Flags::EOF)) {
match self.respond
.send_response(resp, self.flags.contains(Flags::EOF))
{
Ok(stream) => self.stream = Some(stream),
Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "err")),
}

View file

@ -96,8 +96,9 @@ const DEC_DIGITS_LUT: &[u8] = b"0001020304050607080910111213141516171819\
8081828384858687888990919293949596979899";
pub(crate) fn write_status_line(version: Version, mut n: u16, bytes: &mut BytesMut) {
let mut buf: [u8; 13] =
[b'H', b'T', b'T', b'P', b'/', b'1', b'.', b'1', b' ', b' ', b' ', b' ', b' '];
let mut buf: [u8; 13] = [
b'H', b'T', b'T', b'P', b'/', b'1', b'.', b'1', b' ', b' ', b' ', b' ', b' ',
];
match version {
Version::HTTP_2 => buf[5] = b'2',
Version::HTTP_10 => buf[7] = b'0',
@ -250,33 +251,63 @@ mod tests {
let mut bytes = BytesMut::new();
bytes.reserve(50);
write_content_length(0, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 0\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 0\r\n"[..]
);
bytes.reserve(50);
write_content_length(9, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 9\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 9\r\n"[..]
);
bytes.reserve(50);
write_content_length(10, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 10\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 10\r\n"[..]
);
bytes.reserve(50);
write_content_length(99, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 99\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 99\r\n"[..]
);
bytes.reserve(50);
write_content_length(100, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 100\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 100\r\n"[..]
);
bytes.reserve(50);
write_content_length(101, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 101\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 101\r\n"[..]
);
bytes.reserve(50);
write_content_length(998, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 998\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 998\r\n"[..]
);
bytes.reserve(50);
write_content_length(1000, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 1000\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 1000\r\n"[..]
);
bytes.reserve(50);
write_content_length(1001, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 1001\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 1001\r\n"[..]
);
bytes.reserve(50);
write_content_length(5909, &mut bytes);
assert_eq!(bytes.take().freeze(), b"\r\ncontent-length: 5909\r\n"[..]);
assert_eq!(
bytes.take().freeze(),
b"\r\ncontent-length: 5909\r\n"[..]
);
}
}

View file

@ -255,7 +255,10 @@ mod tests {
#[test]
fn test_date_len() {
assert_eq!(DATE_VALUE_LENGTH, "Sun, 06 Nov 1994 08:49:37 GMT".len());
assert_eq!(
DATE_VALUE_LENGTH,
"Sun, 06 Nov 1994 08:49:37 GMT".len()
);
}
#[test]

View file

@ -219,7 +219,10 @@ where
if let Some(e) = err.take() {
Err(e)
} else {
Err(io::Error::new(io::ErrorKind::Other, "Can not bind to address."))
Err(io::Error::new(
io::ErrorKind::Other,
"Can not bind to address.",
))
}
} else {
Ok(self)
@ -375,7 +378,10 @@ impl<H: IntoHttpHandler> HttpServer<H> {
/// Start listening for incoming tls connections.
pub fn start_tls(mut self, acceptor: TlsAcceptor) -> io::Result<Addr<Syn, Self>> {
if self.sockets.is_empty() {
Err(io::Error::new(io::ErrorKind::Other, "No socket addresses are bound"))
Err(io::Error::new(
io::ErrorKind::Other,
"No socket addresses are bound",
))
} else {
let (tx, rx) = mpsc::unbounded();
let addrs: Vec<(net::SocketAddr, net::TcpListener)> =
@ -424,7 +430,10 @@ impl<H: IntoHttpHandler> HttpServer<H> {
mut self, mut builder: SslAcceptorBuilder,
) -> io::Result<Addr<Syn, Self>> {
if self.sockets.is_empty() {
Err(io::Error::new(io::ErrorKind::Other, "No socket addresses are bound"))
Err(io::Error::new(
io::ErrorKind::Other,
"No socket addresses are bound",
))
} else {
// alpn support
if !self.no_http2 {
@ -554,35 +563,17 @@ impl<H: IntoHttpHandler> Handler<signal::Signal> for HttpServer<H> {
signal::SignalType::Int => {
info!("SIGINT received, exiting");
self.exit = true;
Handler::<StopServer>::handle(
self,
StopServer {
graceful: false,
},
ctx,
);
Handler::<StopServer>::handle(self, StopServer { graceful: false }, ctx);
}
signal::SignalType::Term => {
info!("SIGTERM received, stopping");
self.exit = true;
Handler::<StopServer>::handle(
self,
StopServer {
graceful: true,
},
ctx,
);
Handler::<StopServer>::handle(self, StopServer { graceful: true }, ctx);
}
signal::SignalType::Quit => {
info!("SIGQUIT received, exiting");
self.exit = true;
Handler::<StopServer>::handle(
self,
StopServer {
graceful: false,
},
ctx,
);
Handler::<StopServer>::handle(self, StopServer { graceful: false }, ctx);
}
_ => (),
}
@ -706,9 +697,7 @@ impl<H: IntoHttpHandler> Handler<StopServer> for HttpServer<H> {
let tx2 = tx.clone();
worker
.1
.send(StopWorker {
graceful: dur,
})
.send(StopWorker { graceful: dur })
.into_actor(self)
.then(move |_, slf, ctx| {
slf.workers.pop();
@ -758,8 +747,9 @@ fn start_accept_thread(
// start accept thread
#[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
let _ = thread::Builder::new().name(format!("Accept on {}", addr)).spawn(
move || {
let _ = thread::Builder::new()
.name(format!("Accept on {}", addr))
.spawn(move || {
const SRV: mio::Token = mio::Token(0);
const CMD: mio::Token = mio::Token(1);
@ -784,9 +774,12 @@ fn start_accept_thread(
}
// Start listening for incoming commands
if let Err(err) =
poll.register(&reg, CMD, mio::Ready::readable(), mio::PollOpt::edge())
{
if let Err(err) = poll.register(
&reg,
CMD,
mio::Ready::readable(),
mio::PollOpt::edge(),
) {
panic!("Can not register Registration: {}", err);
}
@ -917,8 +910,7 @@ fn start_accept_thread(
}
}
}
},
);
});
(readiness, tx)
}

View file

@ -77,7 +77,9 @@ impl<H: HttpHandler + 'static> Worker<H> {
fn update_time(&self, ctx: &mut Context<Self>) {
self.settings.update_date();
ctx.run_later(time::Duration::new(1, 0), |slf, ctx| slf.update_time(ctx));
ctx.run_later(time::Duration::new(1, 0), |slf, ctx| {
slf.update_time(ctx)
});
}
fn shutdown_timeout(
@ -122,7 +124,8 @@ where
if self.tcp_ka.is_some() && msg.io.set_keepalive(self.tcp_ka).is_err() {
error!("Can not set socket keep-alive option");
}
self.handler.handle(Rc::clone(&self.settings), &self.hnd, msg);
self.handler
.handle(Rc::clone(&self.settings), &self.hnd, msg);
}
}
@ -174,57 +177,52 @@ impl StreamHandlerType {
}
#[cfg(feature = "tls")]
StreamHandlerType::Tls(ref acceptor) => {
let Conn {
io,
peer,
http2,
} = msg;
let Conn { io, peer, http2 } = msg;
let _ = io.set_nodelay(true);
let io = TcpStream::from_stream(io, hnd)
.expect("failed to associate TCP stream");
hnd.spawn(TlsAcceptorExt::accept_async(acceptor, io).then(move |res| {
match res {
Ok(io) => {
Arbiter::handle().spawn(HttpChannel::new(h, io, peer, http2))
}
Err(err) => {
trace!("Error during handling tls connection: {}", err)
}
};
future::result(Ok(()))
}));
hnd.spawn(
TlsAcceptorExt::accept_async(acceptor, io).then(move |res| {
match res {
Ok(io) => Arbiter::handle()
.spawn(HttpChannel::new(h, io, peer, http2)),
Err(err) => {
trace!("Error during handling tls connection: {}", err)
}
};
future::result(Ok(()))
}),
);
}
#[cfg(feature = "alpn")]
StreamHandlerType::Alpn(ref acceptor) => {
let Conn {
io,
peer,
..
} = msg;
let Conn { io, peer, .. } = msg;
let _ = io.set_nodelay(true);
let io = TcpStream::from_stream(io, hnd)
.expect("failed to associate TCP stream");
hnd.spawn(SslAcceptorExt::accept_async(acceptor, io).then(move |res| {
match res {
Ok(io) => {
let http2 = if let Some(p) =
io.get_ref().ssl().selected_alpn_protocol()
{
p.len() == 2 && &p == b"h2"
} else {
false
};
Arbiter::handle()
.spawn(HttpChannel::new(h, io, peer, http2));
}
Err(err) => {
trace!("Error during handling tls connection: {}", err)
}
};
future::result(Ok(()))
}));
hnd.spawn(
SslAcceptorExt::accept_async(acceptor, io).then(move |res| {
match res {
Ok(io) => {
let http2 = if let Some(p) =
io.get_ref().ssl().selected_alpn_protocol()
{
p.len() == 2 && &p == b"h2"
} else {
false
};
Arbiter::handle()
.spawn(HttpChannel::new(h, io, peer, http2));
}
Err(err) => {
trace!("Error during handling tls connection: {}", err)
}
};
future::result(Ok(()))
}),
);
}
}
}

View file

@ -170,22 +170,14 @@ impl TestServer {
if uri.starts_with('/') {
format!(
"{}://{}{}",
if self.ssl {
"https"
} else {
"http"
},
if self.ssl { "https" } else { "http" },
self.addr,
uri
)
} else {
format!(
"{}://{}/{}",
if self.ssl {
"https"
} else {
"http"
},
if self.ssl { "https" } else { "http" },
self.addr,
uri
)
@ -358,14 +350,17 @@ pub struct TestApp<S = ()> {
impl<S: 'static> TestApp<S> {
fn new(state: S) -> TestApp<S> {
let app = App::with_state(state);
TestApp {
app: Some(app),
}
TestApp { app: Some(app) }
}
/// Register handler for "/"
pub fn handler<H: Handler<S>>(&mut self, handler: H) {
self.app = Some(self.app.take().unwrap().resource("/", |r| r.h(handler)));
self.app = Some(
self.app
.take()
.unwrap()
.resource("/", |r| r.h(handler)),
);
}
/// Register middleware

View file

@ -44,10 +44,7 @@ impl Url {
pub fn new(uri: Uri) -> Url {
let path = DEFAULT_QUOTER.requote(uri.path().as_bytes());
Url {
uri,
path,
}
Url { uri, path }
}
pub fn uri(&self) -> &Uri {

View file

@ -307,8 +307,10 @@ where
Async::Ready(item) => {
self.item = Some(item);
self.fut1.take();
self.fut2 =
Some(Box::new(T2::from_request(&self.req, self.cfg2.as_ref())));
self.fut2 = Some(Box::new(T2::from_request(
&self.req,
self.cfg2.as_ref(),
)));
}
Async::NotReady => return Ok(Async::NotReady),
}
@ -508,8 +510,10 @@ where
Async::Ready(item) => {
self.item1 = Some(item);
self.fut1.take();
self.fut2 =
Some(Box::new(T2::from_request(&self.req, self.cfg2.as_ref())));
self.fut2 = Some(Box::new(T2::from_request(
&self.req,
self.cfg2.as_ref(),
)));
}
Async::NotReady => return Ok(Async::NotReady),
}
@ -520,8 +524,10 @@ where
Async::Ready(item) => {
self.item2 = Some(item);
self.fut2.take();
self.fut3 =
Some(Box::new(T3::from_request(&self.req, self.cfg3.as_ref())));
self.fut3 = Some(Box::new(T3::from_request(
&self.req,
self.cfg3.as_ref(),
)));
}
Async::NotReady => return Ok(Async::NotReady),
}
@ -533,13 +539,15 @@ where
};
let hnd: &mut F = unsafe { &mut *self.hnd.get() };
let item =
match (*hnd)(self.item1.take().unwrap(), self.item2.take().unwrap(), item)
.respond_to(self.req.drop_state())
{
Ok(item) => item.into(),
Err(err) => return Err(err.into()),
};
let item = match (*hnd)(
self.item1.take().unwrap(),
self.item2.take().unwrap(),
item,
).respond_to(self.req.drop_state())
{
Ok(item) => item.into(),
Err(err) => return Err(err.into()),
};
match item.into() {
ReplyItem::Message(resp) => return Ok(Async::Ready(resp)),

View file

@ -142,8 +142,9 @@ impl Client {
U: IntoIterator<Item = V> + 'static,
V: AsRef<str>,
{
let mut protos =
protos.into_iter().fold(String::new(), |acc, s| acc + s.as_ref() + ",");
let mut protos = protos
.into_iter()
.fold(String::new(), |acc, s| acc + s.as_ref() + ",");
protos.pop();
self.protocols = Some(protos);
self
@ -217,7 +218,8 @@ impl Client {
self.request.upgrade();
self.request.set_header(header::UPGRADE, "websocket");
self.request.set_header(header::CONNECTION, "upgrade");
self.request.set_header(header::SEC_WEBSOCKET_VERSION, "13");
self.request
.set_header(header::SEC_WEBSOCKET_VERSION, "13");
self.request.with_connector(self.conn.clone());
if let Some(protocols) = self.protocols.take() {
@ -392,7 +394,10 @@ impl Future for ClientHandshake {
encoded,
key
);
return Err(ClientError::InvalidChallengeResponse(encoded, key.clone()));
return Err(ClientError::InvalidChallengeResponse(
encoded,
key.clone(),
));
}
} else {
trace!("Missing SEC-WEBSOCKET-ACCEPT header");
@ -411,9 +416,7 @@ impl Future for ClientHandshake {
inner: Rc::clone(&inner),
max_size: self.max_size,
},
ClientWriter {
inner,
},
ClientWriter { inner },
)))
}
}
@ -533,13 +536,23 @@ impl ClientWriter {
/// Send ping frame
#[inline]
pub fn ping(&mut self, message: &str) {
self.write(Frame::message(Vec::from(message), OpCode::Ping, true, true));
self.write(Frame::message(
Vec::from(message),
OpCode::Ping,
true,
true,
));
}
/// Send pong frame
#[inline]
pub fn pong(&mut self, message: &str) {
self.write(Frame::message(Vec::from(message), OpCode::Pong, true, true));
self.write(Frame::message(
Vec::from(message),
OpCode::Pong,
true,
true,
));
}
/// Send close frame

View file

@ -2,7 +2,6 @@ use futures::sync::oneshot::Sender;
use futures::unsync::oneshot;
use futures::{Async, Poll};
use smallvec::SmallVec;
use std::mem;
use actix::dev::{ContextImpl, SyncEnvelope, ToEnvelope};
use actix::fut::ActorFuture;
@ -156,13 +155,23 @@ where
/// Send ping frame
#[inline]
pub fn ping(&mut self, message: &str) {
self.write(Frame::message(Vec::from(message), OpCode::Ping, true, false));
self.write(Frame::message(
Vec::from(message),
OpCode::Ping,
true,
false,
));
}
/// Send pong frame
#[inline]
pub fn pong(&mut self, message: &str) {
self.write(Frame::message(Vec::from(message), OpCode::Pong, true, false));
self.write(Frame::message(
Vec::from(message),
OpCode::Pong,
true,
false,
));
}
/// Send close frame
@ -190,7 +199,9 @@ where
if self.stream.is_none() {
self.stream = Some(SmallVec::new());
}
self.stream.as_mut().map(|s| s.push(frame));
if let Some(s) = self.stream.as_mut() {
s.push(frame)
}
self.inner.modify();
}
@ -214,8 +225,7 @@ where
}
fn poll(&mut self) -> Poll<Option<SmallVec<[ContextFrame; 4]>>, Error> {
let ctx: &mut WebsocketContext<A, S> =
unsafe { mem::transmute(self as &mut WebsocketContext<A, S>) };
let ctx: &mut WebsocketContext<A, S> = unsafe { &mut *(self as *mut _) };
if self.inner.alive() && self.inner.poll(ctx).is_err() {
return Err(ErrorInternalServerError("error"));

View file

@ -1,8 +1,9 @@
#![cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
use byteorder::{BigEndian, ByteOrder, NetworkEndian};
use bytes::{BufMut, Bytes, BytesMut};
use futures::{Async, Poll, Stream};
use rand;
use std::{fmt, mem, ptr};
use std::{fmt, ptr};
use body::Binary;
use error::PayloadError;
@ -122,7 +123,9 @@ impl Frame {
None
};
Ok(Async::Ready(Some((idx, finished, opcode, length, mask))))
Ok(Async::Ready(Some((
idx, finished, opcode, length, mask,
))))
}
fn read_chunk_md(
@ -257,10 +260,9 @@ impl Frame {
// unmask
if let Some(mask) = mask {
#[allow(mutable_transmutes)]
let p: &mut [u8] = unsafe {
let ptr: &[u8] = &data;
mem::transmute(ptr)
&mut *(ptr as *const _ as *mut _)
};
apply_mask(p, mask);
}

View file

@ -1,4 +1,5 @@
//! This is code from [Tungstenite project](https://github.com/snapview/tungstenite-rs)
#![cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))]
use std::cmp::min;
use std::mem::uninitialized;
use std::ptr::copy_nonoverlapping;
@ -28,11 +29,7 @@ fn apply_mask_fast32(buf: &mut [u8], mask_u32: u32) {
// Possible first unaligned block.
let head = min(len, (8 - (ptr as usize & 0x7)) & 0x3);
let mask_u32 = if head > 0 {
let n = if head > 4 {
head - 4
} else {
head
};
let n = if head > 4 { head - 4 } else { head };
let mask_u32 = if n > 0 {
unsafe {

View file

@ -133,24 +133,24 @@ pub enum HandshakeError {
impl ResponseError for HandshakeError {
fn error_response(&self) -> HttpResponse {
match *self {
HandshakeError::GetMethodRequired => {
HttpResponse::MethodNotAllowed().header(header::ALLOW, "GET").finish()
}
HandshakeError::GetMethodRequired => HttpResponse::MethodNotAllowed()
.header(header::ALLOW, "GET")
.finish(),
HandshakeError::NoWebsocketUpgrade => HttpResponse::BadRequest()
.reason("No WebSocket UPGRADE header found")
.finish(),
HandshakeError::NoConnectionUpgrade => {
HttpResponse::BadRequest().reason("No CONNECTION upgrade").finish()
}
HandshakeError::NoConnectionUpgrade => HttpResponse::BadRequest()
.reason("No CONNECTION upgrade")
.finish(),
HandshakeError::NoVersionHeader => HttpResponse::BadRequest()
.reason("Websocket version header is required")
.finish(),
HandshakeError::UnsupportedVersion => {
HttpResponse::BadRequest().reason("Unsupported version").finish()
}
HandshakeError::BadWebsocketKey => {
HttpResponse::BadRequest().reason("Handshake error").finish()
}
HandshakeError::UnsupportedVersion => HttpResponse::BadRequest()
.reason("Unsupported version")
.finish(),
HandshakeError::BadWebsocketKey => HttpResponse::BadRequest()
.reason("Handshake error")
.finish(),
}
}
}
@ -216,7 +216,9 @@ pub fn handshake<S>(
}
// check supported version
if !req.headers().contains_key(header::SEC_WEBSOCKET_VERSION) {
if !req.headers()
.contains_key(header::SEC_WEBSOCKET_VERSION)
{
return Err(HandshakeError::NoVersionHeader);
}
let supported_ver = {
@ -353,7 +355,10 @@ mod tests {
HeaderMap::new(),
None,
);
assert_eq!(HandshakeError::GetMethodRequired, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::GetMethodRequired,
handshake(&req).err().unwrap()
);
let req = HttpRequest::new(
Method::GET,
@ -362,10 +367,16 @@ mod tests {
HeaderMap::new(),
None,
);
assert_eq!(HandshakeError::NoWebsocketUpgrade, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::NoWebsocketUpgrade,
handshake(&req).err().unwrap()
);
let mut headers = HeaderMap::new();
headers.insert(header::UPGRADE, header::HeaderValue::from_static("test"));
headers.insert(
header::UPGRADE,
header::HeaderValue::from_static("test"),
);
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
@ -373,10 +384,16 @@ mod tests {
headers,
None,
);
assert_eq!(HandshakeError::NoWebsocketUpgrade, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::NoWebsocketUpgrade,
handshake(&req).err().unwrap()
);
let mut headers = HeaderMap::new();
headers.insert(header::UPGRADE, header::HeaderValue::from_static("websocket"));
headers.insert(
header::UPGRADE,
header::HeaderValue::from_static("websocket"),
);
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
@ -384,11 +401,20 @@ mod tests {
headers,
None,
);
assert_eq!(HandshakeError::NoConnectionUpgrade, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::NoConnectionUpgrade,
handshake(&req).err().unwrap()
);
let mut headers = HeaderMap::new();
headers.insert(header::UPGRADE, header::HeaderValue::from_static("websocket"));
headers.insert(header::CONNECTION, header::HeaderValue::from_static("upgrade"));
headers.insert(
header::UPGRADE,
header::HeaderValue::from_static("websocket"),
);
headers.insert(
header::CONNECTION,
header::HeaderValue::from_static("upgrade"),
);
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),
@ -396,11 +422,20 @@ mod tests {
headers,
None,
);
assert_eq!(HandshakeError::NoVersionHeader, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::NoVersionHeader,
handshake(&req).err().unwrap()
);
let mut headers = HeaderMap::new();
headers.insert(header::UPGRADE, header::HeaderValue::from_static("websocket"));
headers.insert(header::CONNECTION, header::HeaderValue::from_static("upgrade"));
headers.insert(
header::UPGRADE,
header::HeaderValue::from_static("websocket"),
);
headers.insert(
header::CONNECTION,
header::HeaderValue::from_static("upgrade"),
);
headers.insert(
header::SEC_WEBSOCKET_VERSION,
header::HeaderValue::from_static("5"),
@ -412,11 +447,20 @@ mod tests {
headers,
None,
);
assert_eq!(HandshakeError::UnsupportedVersion, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::UnsupportedVersion,
handshake(&req).err().unwrap()
);
let mut headers = HeaderMap::new();
headers.insert(header::UPGRADE, header::HeaderValue::from_static("websocket"));
headers.insert(header::CONNECTION, header::HeaderValue::from_static("upgrade"));
headers.insert(
header::UPGRADE,
header::HeaderValue::from_static("websocket"),
);
headers.insert(
header::CONNECTION,
header::HeaderValue::from_static("upgrade"),
);
headers.insert(
header::SEC_WEBSOCKET_VERSION,
header::HeaderValue::from_static("13"),
@ -428,17 +472,28 @@ mod tests {
headers,
None,
);
assert_eq!(HandshakeError::BadWebsocketKey, handshake(&req).err().unwrap());
assert_eq!(
HandshakeError::BadWebsocketKey,
handshake(&req).err().unwrap()
);
let mut headers = HeaderMap::new();
headers.insert(header::UPGRADE, header::HeaderValue::from_static("websocket"));
headers.insert(header::CONNECTION, header::HeaderValue::from_static("upgrade"));
headers.insert(
header::UPGRADE,
header::HeaderValue::from_static("websocket"),
);
headers.insert(
header::CONNECTION,
header::HeaderValue::from_static("upgrade"),
);
headers.insert(
header::SEC_WEBSOCKET_VERSION,
header::HeaderValue::from_static("13"),
);
headers
.insert(header::SEC_WEBSOCKET_KEY, header::HeaderValue::from_static("13"));
headers.insert(
header::SEC_WEBSOCKET_KEY,
header::HeaderValue::from_static("13"),
);
let req = HttpRequest::new(
Method::GET,
Uri::from_str("/").unwrap(),

View file

@ -72,7 +72,10 @@ fn test_with_query_parameter() {
})
});
let request = srv.get().uri(srv.url("/?qp=5").as_str()).finish().unwrap();
let request = srv.get()
.uri(srv.url("/?qp=5").as_str())
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -121,8 +124,10 @@ fn test_client_gzip_encoding() {
});
// client request
let request =
srv.post().content_encoding(http::ContentEncoding::Gzip).body(STR).unwrap();
let request = srv.post()
.content_encoding(http::ContentEncoding::Gzip)
.body(STR)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -162,7 +167,10 @@ fn test_client_gzip_encoding_large() {
#[test]
fn test_client_gzip_encoding_large_random() {
let data = rand::thread_rng().gen_ascii_chars().take(100_000).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(100_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| {
app.handler(|req: HttpRequest| {
@ -220,7 +228,10 @@ fn test_client_brotli_encoding() {
#[cfg(feature = "brotli")]
#[test]
fn test_client_brotli_encoding_large_random() {
let data = rand::thread_rng().gen_ascii_chars().take(70_000).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| {
app.handler(|req: HttpRequest| {
@ -264,8 +275,10 @@ fn test_client_deflate_encoding() {
});
// client request
let request =
srv.post().content_encoding(http::ContentEncoding::Deflate).body(STR).unwrap();
let request = srv.post()
.content_encoding(http::ContentEncoding::Deflate)
.body(STR)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -277,7 +290,10 @@ fn test_client_deflate_encoding() {
#[cfg(feature = "brotli")]
#[test]
fn test_client_deflate_encoding_large_random() {
let data = rand::thread_rng().gen_ascii_chars().take(70_000).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| {
app.handler(|req: HttpRequest| {
@ -322,7 +338,9 @@ fn test_client_streaming_explicit() {
let body = once(Ok(Bytes::from_static(STR.as_ref())));
let request = srv.get().body(Body::Streaming(Box::new(body))).unwrap();
let request = srv.get()
.body(Body::Streaming(Box::new(body)))
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -395,8 +413,11 @@ fn test_client_cookie_handling() {
})
});
let request =
srv.get().cookie(cookie1.clone()).cookie(cookie2.clone()).finish().unwrap();
let request = srv.get()
.cookie(cookie1.clone())
.cookie(cookie2.clone())
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
let c1 = response.cookie("cookie1").expect("Missing cookie1");

View file

@ -26,7 +26,10 @@ fn test_path_extractor() {
});
// client request
let request = srv.get().uri(srv.url("/test/index.html")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test/index.html"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -44,7 +47,10 @@ fn test_query_extractor() {
});
// client request
let request = srv.get().uri(srv.url("/index.html?username=test")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/index.html?username=test"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -53,7 +59,10 @@ fn test_query_extractor() {
assert_eq!(bytes, Bytes::from_static(b"Welcome test!"));
// client request
let request = srv.get().uri(srv.url("/index.html")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/index.html"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}
@ -69,8 +78,10 @@ fn test_path_and_query_extractor() {
});
// client request
let request =
srv.get().uri(srv.url("/test1/index.html?username=test2")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test1/index.html?username=test2"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -79,7 +90,10 @@ fn test_path_and_query_extractor() {
assert_eq!(bytes, Bytes::from_static(b"Welcome test1 - test2!"));
// client request
let request = srv.get().uri(srv.url("/test1/index.html")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test1/index.html"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}
@ -88,15 +102,18 @@ fn test_path_and_query_extractor() {
fn test_path_and_query_extractor2() {
let mut srv = test::TestServer::new(|app| {
app.resource("/{username}/index.html", |r| {
r.route().with3(|_: HttpRequest, p: Path<PParam>, q: Query<PParam>| {
format!("Welcome {} - {}!", p.username, q.username)
})
r.route()
.with3(|_: HttpRequest, p: Path<PParam>, q: Query<PParam>| {
format!("Welcome {} - {}!", p.username, q.username)
})
});
});
// client request
let request =
srv.get().uri(srv.url("/test1/index.html?username=test2")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test1/index.html?username=test2"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -105,7 +122,10 @@ fn test_path_and_query_extractor2() {
assert_eq!(bytes, Bytes::from_static(b"Welcome test1 - test2!"));
// client request
let request = srv.get().uri(srv.url("/test1/index.html")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test1/index.html"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
}
@ -117,7 +137,10 @@ fn test_non_ascii_route() {
});
// client request
let request = srv.get().uri(srv.url("/中文/index.html")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/中文/index.html"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -135,12 +158,17 @@ fn test_unsafe_path_route() {
});
// client request
let request =
srv.get().uri(srv.url("/test/http%3A%2F%2Fexample.com")).finish().unwrap();
let request = srv.get()
.uri(srv.url("/test/http%3A%2F%2Fexample.com"))
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(b"success: http:%2F%2Fexample.com"));
assert_eq!(
bytes,
Bytes::from_static(b"success: http:%2F%2Fexample.com")
);
}

View file

@ -131,9 +131,7 @@ fn test_shutdown() {
.finish()
.unwrap();
let response = sys.run_until_complete(req.send()).unwrap();
srv_addr.do_send(server::StopServer {
graceful: true,
});
srv_addr.do_send(server::StopServer { graceful: true });
assert!(response.status().is_success());
}
@ -206,7 +204,9 @@ fn test_body() {
fn test_body_gzip() {
let mut srv = test::TestServer::new(|app| {
app.handler(|_| {
HttpResponse::Ok().content_encoding(http::ContentEncoding::Gzip).body(STR)
HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Gzip)
.body(STR)
})
});
@ -254,7 +254,10 @@ fn test_body_gzip_large() {
#[test]
fn test_body_gzip_large_random() {
let data = rand::thread_rng().gen_ascii_chars().take(70_000).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
let srv_data = Arc::new(data.clone());
let mut srv = test::TestServer::new(move |app| {
@ -335,7 +338,11 @@ fn test_body_br_streaming() {
#[test]
fn test_head_empty() {
let mut srv = test::TestServer::new(|app| {
app.handler(|_| HttpResponse::Ok().content_length(STR.len() as u64).finish())
app.handler(|_| {
HttpResponse::Ok()
.content_length(STR.len() as u64)
.finish()
})
});
let request = srv.head().finish().unwrap();
@ -343,7 +350,10 @@ fn test_head_empty() {
assert!(response.status().is_success());
{
let len = response.headers().get(http::header::CONTENT_LENGTH).unwrap();
let len = response
.headers()
.get(http::header::CONTENT_LENGTH)
.unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
}
@ -368,7 +378,10 @@ fn test_head_binary() {
assert!(response.status().is_success());
{
let len = response.headers().get(http::header::CONTENT_LENGTH).unwrap();
let len = response
.headers()
.get(http::header::CONTENT_LENGTH)
.unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
}
@ -392,7 +405,10 @@ fn test_head_binary2() {
assert!(response.status().is_success());
{
let len = response.headers().get(http::header::CONTENT_LENGTH).unwrap();
let len = response
.headers()
.get(http::header::CONTENT_LENGTH)
.unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
}
}
@ -448,7 +464,9 @@ fn test_body_chunked_explicit() {
fn test_body_deflate() {
let mut srv = test::TestServer::new(|app| {
app.handler(|_| {
HttpResponse::Ok().content_encoding(http::ContentEncoding::Deflate).body(STR)
HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Deflate)
.body(STR)
})
});
@ -472,7 +490,9 @@ fn test_body_deflate() {
fn test_body_brotli() {
let mut srv = test::TestServer::new(|app| {
app.handler(|_| {
HttpResponse::Ok().content_encoding(http::ContentEncoding::Br).body(STR)
HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Br)
.body(STR)
})
});
@ -556,7 +576,10 @@ fn test_gzip_encoding_large() {
#[test]
fn test_reading_gzip_encoding_large_random() {
let data = rand::thread_rng().gen_ascii_chars().take(60_000).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(60_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| {
app.handler(|req: HttpRequest| {
@ -607,8 +630,10 @@ fn test_reading_deflate_encoding() {
let enc = e.finish().unwrap();
// client request
let request =
srv.post().header(http::header::CONTENT_ENCODING, "deflate").body(enc).unwrap();
let request = srv.post()
.header(http::header::CONTENT_ENCODING, "deflate")
.body(enc)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -637,8 +662,10 @@ fn test_reading_deflate_encoding_large() {
let enc = e.finish().unwrap();
// client request
let request =
srv.post().header(http::header::CONTENT_ENCODING, "deflate").body(enc).unwrap();
let request = srv.post()
.header(http::header::CONTENT_ENCODING, "deflate")
.body(enc)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -649,7 +676,10 @@ fn test_reading_deflate_encoding_large() {
#[test]
fn test_reading_deflate_encoding_large_random() {
let data = rand::thread_rng().gen_ascii_chars().take(160_000).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(160_000)
.collect::<String>();
let mut srv = test::TestServer::new(|app| {
app.handler(|req: HttpRequest| {
@ -668,8 +698,10 @@ fn test_reading_deflate_encoding_large_random() {
let enc = e.finish().unwrap();
// client request
let request =
srv.post().header(http::header::CONTENT_ENCODING, "deflate").body(enc).unwrap();
let request = srv.post()
.header(http::header::CONTENT_ENCODING, "deflate")
.body(enc)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -699,8 +731,10 @@ fn test_brotli_encoding() {
let enc = e.finish().unwrap();
// client request
let request =
srv.post().header(http::header::CONTENT_ENCODING, "br").body(enc).unwrap();
let request = srv.post()
.header(http::header::CONTENT_ENCODING, "br")
.body(enc)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -730,8 +764,10 @@ fn test_brotli_encoding_large() {
let enc = e.finish().unwrap();
// client request
let request =
srv.post().header(http::header::CONTENT_ENCODING, "br").body(enc).unwrap();
let request = srv.post()
.header(http::header::CONTENT_ENCODING, "br")
.body(enc)
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
@ -749,29 +785,30 @@ fn test_h2() {
let handle = core.handle();
let tcp = TcpStream::connect(&addr, &handle);
let tcp = tcp.then(|res| h2client::handshake(res.unwrap())).then(move |res| {
let (mut client, h2) = res.unwrap();
let tcp = tcp.then(|res| h2client::handshake(res.unwrap()))
.then(move |res| {
let (mut client, h2) = res.unwrap();
let request = Request::builder()
.uri(format!("https://{}/", addr).as_str())
.body(())
.unwrap();
let (response, _) = client.send_request(request, false).unwrap();
let request = Request::builder()
.uri(format!("https://{}/", addr).as_str())
.body(())
.unwrap();
let (response, _) = client.send_request(request, false).unwrap();
// Spawn a task to run the conn...
handle.spawn(h2.map_err(|e| println!("GOT ERR={:?}", e)));
// Spawn a task to run the conn...
handle.spawn(h2.map_err(|e| println!("GOT ERR={:?}", e)));
response.and_then(|response| {
assert_eq!(response.status(), http::StatusCode::OK);
response.and_then(|response| {
assert_eq!(response.status(), http::StatusCode::OK);
let (_, body) = response.into_parts();
let (_, body) = response.into_parts();
body.fold(BytesMut::new(), |mut b, c| -> Result<_, h2::Error> {
b.extend(c);
Ok(b)
body.fold(BytesMut::new(), |mut b, c| -> Result<_, h2::Error> {
b.extend(c);
Ok(b)
})
})
})
});
});
let _res = core.run(tcp);
// assert_eq!(res.unwrap(), Bytes::from_static(STR.as_ref()));
}
@ -795,20 +832,28 @@ struct MiddlewareTest {
impl<S> middleware::Middleware<S> for MiddlewareTest {
fn start(&self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
self.start.store(self.start.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
self.start.store(
self.start.load(Ordering::Relaxed) + 1,
Ordering::Relaxed,
);
Ok(middleware::Started::Done)
}
fn response(
&self, _: &mut HttpRequest<S>, resp: HttpResponse,
) -> Result<middleware::Response> {
self.response
.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
self.response.store(
self.response.load(Ordering::Relaxed) + 1,
Ordering::Relaxed,
);
Ok(middleware::Response::Done(resp))
}
fn finish(&self, _: &mut HttpRequest<S>, _: &HttpResponse) -> middleware::Finished {
self.finish.store(self.finish.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
self.finish.store(
self.finish.load(Ordering::Relaxed) + 1,
Ordering::Relaxed,
);
middleware::Finished::Done
}
}

View file

@ -44,7 +44,12 @@ fn test_simple() {
writer.binary(b"text".as_ref());
let (item, reader) = srv.execute(reader.into_future()).unwrap();
assert_eq!(item, Some(ws::Message::Binary(Bytes::from_static(b"text").into())));
assert_eq!(
item,
Some(ws::Message::Binary(
Bytes::from_static(b"text").into()
))
);
writer.ping("ping");
let (item, reader) = srv.execute(reader.into_future()).unwrap();
@ -52,7 +57,10 @@ fn test_simple() {
writer.close(Some(ws::CloseCode::Normal.into()));
let (item, _) = srv.execute(reader.into_future()).unwrap();
assert_eq!(item, Some(ws::Message::Close(Some(ws::CloseCode::Normal.into()))));
assert_eq!(
item,
Some(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
);
}
#[test]
@ -79,7 +87,10 @@ fn test_close_description() {
#[test]
fn test_large_text() {
let data = rand::thread_rng().gen_ascii_chars().take(65_536).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(65_536)
.collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req| ws::start(req, Ws)));
let (mut reader, mut writer) = srv.ws().unwrap();
@ -94,7 +105,10 @@ fn test_large_text() {
#[test]
fn test_large_bin() {
let data = rand::thread_rng().gen_ascii_chars().take(65_536).collect::<String>();
let data = rand::thread_rng()
.gen_ascii_chars()
.take(65_536)
.collect::<String>();
let mut srv = test::TestServer::new(|app| app.handler(|req| ws::start(req, Ws)));
let (mut reader, mut writer) = srv.ws().unwrap();
@ -103,7 +117,10 @@ fn test_large_bin() {
writer.binary(data.clone());
let (item, r) = srv.execute(reader.into_future()).unwrap();
reader = r;
assert_eq!(item, Some(ws::Message::Binary(Binary::from(data.clone()))));
assert_eq!(
item,
Some(ws::Message::Binary(Binary::from(data.clone())))
);
}
}
@ -207,20 +224,26 @@ fn test_ws_server_ssl() {
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_private_key_file("tests/key.pem", SslFiletype::PEM).unwrap();
builder.set_certificate_chain_file("tests/cert.pem").unwrap();
builder
.set_private_key_file("tests/key.pem", SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file("tests/cert.pem")
.unwrap();
let mut srv = test::TestServer::build().ssl(builder.build()).start(|app| {
app.handler(|req| {
ws::start(
req,
Ws2 {
count: 0,
bin: false,
},
)
})
});
let mut srv = test::TestServer::build()
.ssl(builder.build())
.start(|app| {
app.handler(|req| {
ws::start(
req,
Ws2 {
count: 0,
bin: false,
},
)
})
});
let (mut reader, _writer) = srv.ws().unwrap();
let data = Some(ws::Message::Text("0".repeat(65_536)));

View file

@ -61,8 +61,12 @@ fn main() {
let sample_rate = parse_u64_default(matches.value_of("sample-rate"), 1) as usize;
let perf_counters = Arc::new(PerfCounters::new());
let payload =
Arc::new(thread_rng().gen_ascii_chars().take(payload_size).collect::<String>());
let payload = Arc::new(
thread_rng()
.gen_ascii_chars()
.take(payload_size)
.collect::<String>(),
);
let sys = actix::System::new("ws-client");
@ -78,40 +82,43 @@ fn main() {
let perf = perf_counters.clone();
let addr = Arbiter::new(format!("test {}", t));
addr.do_send(actix::msgs::Execute::new(move || -> Result<(), ()> {
for _ in 0..concurrency {
let pl2 = pl.clone();
let perf2 = perf.clone();
let ws2 = ws.clone();
addr.do_send(actix::msgs::Execute::new(
move || -> Result<(), ()> {
for _ in 0..concurrency {
let pl2 = pl.clone();
let perf2 = perf.clone();
let ws2 = ws.clone();
Arbiter::handle().spawn(
ws::Client::new(&ws)
.write_buffer_capacity(0)
.connect()
.map_err(|e| {
println!("Error: {}", e);
//Arbiter::system().do_send(actix::msgs::SystemExit(0));
()
})
.map(move |(reader, writer)| {
let addr: Addr<Syn, _> = ChatClient::create(move |ctx| {
ChatClient::add_stream(reader, ctx);
ChatClient {
url: ws2,
conn: writer,
payload: pl2,
bin: bin,
ts: time::precise_time_ns(),
perf_counters: perf2,
sent: 0,
max_payload_size: max_payload_size,
}
});
}),
);
}
Ok(())
}));
Arbiter::handle().spawn(
ws::Client::new(&ws)
.write_buffer_capacity(0)
.connect()
.map_err(|e| {
println!("Error: {}", e);
//Arbiter::system().do_send(actix::msgs::SystemExit(0));
()
})
.map(move |(reader, writer)| {
let addr: Addr<Syn, _> =
ChatClient::create(move |ctx| {
ChatClient::add_stream(reader, ctx);
ChatClient {
url: ws2,
conn: writer,
payload: pl2,
bin: bin,
ts: time::precise_time_ns(),
perf_counters: perf2,
sent: 0,
max_payload_size: max_payload_size,
}
});
}),
);
}
Ok(())
},
));
}
let res = sys.run();
@ -119,7 +126,10 @@ fn main() {
fn parse_u64_default(input: Option<&str>, default: u64) -> u64 {
input
.map(|v| v.parse().expect(&format!("not a valid number: {}", v)))
.map(|v| {
v.parse()
.expect(&format!("not a valid number: {}", v))
})
.unwrap_or(default)
}
@ -139,13 +149,15 @@ impl Actor for Perf {
impl Perf {
fn sample_rate(&self, ctx: &mut Context<Self>) {
ctx.run_later(Duration::new(self.sample_rate_secs as u64, 0), |act, ctx| {
let req_count = act.counters.pull_request_count();
if req_count != 0 {
let conns = act.counters.pull_connections_count();
let latency = act.counters.pull_latency_ns();
let latency_max = act.counters.pull_latency_max_ns();
println!(
ctx.run_later(
Duration::new(self.sample_rate_secs as u64, 0),
|act, ctx| {
let req_count = act.counters.pull_request_count();
if req_count != 0 {
let conns = act.counters.pull_connections_count();
let latency = act.counters.pull_latency_ns();
let latency_max = act.counters.pull_latency_max_ns();
println!(
"rate: {}, conns: {}, throughput: {:?} kb, latency: {}, latency max: {}",
req_count / act.sample_rate_secs,
conns / act.sample_rate_secs,
@ -154,10 +166,11 @@ impl Perf {
time::Duration::nanoseconds((latency / req_count as u64) as i64),
time::Duration::nanoseconds(latency_max as i64)
);
}
}
act.sample_rate(ctx);
});
act.sample_rate(ctx);
},
);
}
}
@ -301,7 +314,8 @@ impl PerfCounters {
loop {
let current = self.lat_max.load(Ordering::SeqCst);
if current >= nanos
|| self.lat_max.compare_and_swap(current, nanos, Ordering::SeqCst)
|| self.lat_max
.compare_and_swap(current, nanos, Ordering::SeqCst)
== current
{
break;