1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-07-09 04:16:14 +02:00

Compare commits

...

14 Commits

Author SHA1 Message Date
e58b38fd13 deprecate WsWrite from top level mod 2018-05-09 06:12:16 -07:00
b043c34632 bump version 2018-05-09 06:05:44 -07:00
b748bf3b0d make api public 2018-05-09 06:05:16 -07:00
be12d5e6fc make WsWriter trait optional 2018-05-09 05:48:06 -07:00
7c4941f868 update migration doc 2018-05-08 18:48:09 -07:00
d1f5c457c4 Merge branch 'master' of github.com:actix/actix-web 2018-05-08 18:35:52 -07:00
c26c5fd9a4 prep release 2018-05-08 18:34:36 -07:00
4a73d1c8c1 Merge pull request #216 from lcowell/lcowell-scoupe
replace typo `scoupe` with `scope`
2018-05-08 17:47:20 -07:00
7c395fcc83 replace typo scoupe with scope 2018-05-08 17:40:18 -07:00
54c33a7aff Allow to exclude certain endpoints from logging #211 2018-05-08 16:30:34 -07:00
47d80382b2 Fix http/2 payload streaming #215 2018-05-08 15:44:50 -07:00
ba816a8562 Merge pull request #214 from niklasf/de-path-404
let Path::from_request() fail with ErrorNotFound
2018-05-08 14:41:05 -07:00
6f75b0e95e let Path::from_request() fail with ErrorNotFound 2018-05-08 22:59:46 +02:00
b3cc43bb9b Fix connector's default keep-alive and lifetime settings #212 2018-05-08 13:41:04 -07:00
14 changed files with 177 additions and 68 deletions

View File

@ -1,5 +1,21 @@
# Changes
## 0.6.2 (2018-05-09)
* WsWriter trait is optional.
## 0.6.1 (2018-05-08)
* Fix http/2 payload streaming #215
* Fix connector's default `keep-alive` and `lifetime` settings #212
* Send `ErrorNotFound` instead of `ErrorBadRequest` when path extractor fails #214
* Allow to exclude certain endpoints from logging #211
## 0.6.0 (2018-05-08)
* Add route scopes #202

View File

@ -1,6 +1,6 @@
[package]
name = "actix-web"
version = "0.6.0"
version = "0.6.2"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix web is a simple, pragmatic and extremely fast web framework for Rust."
readme = "README.md"

View File

@ -1,5 +1,7 @@
## Migration from 0.5 to 0.6
* `Path<T>` extractor return `ErrorNotFound` on failure instead of `ErrorBadRequest`
* `ws::Message::Close` now includes optional close reason.
`ws::CloseCode::Status` and `ws::CloseCode::Empty` have been removed.
@ -11,6 +13,17 @@
* `HttpRequest::extensions()` returns read only reference to the request's Extension
`HttpRequest::extensions_mut()` returns mutable reference.
* Instead of
`use actix_web::middleware::{
CookieSessionBackend, CookieSessionError, RequestSession,
Session, SessionBackend, SessionImpl, SessionStorage};`
use `actix_web::middleware::session`
`use actix_web::middleware::session{CookieSessionBackend, CookieSessionError,
RequestSession, Session, SessionBackend, SessionImpl, SessionStorage};`
* `FromRequest::from_request()` accepts mutable reference to a request
* `FromRequest::Result` has to implement `Into<Reply<Self>>`
@ -33,6 +46,9 @@
let q = Query::<HashMap<String, String>>::extract(req);
```
* Websocket operations are implemented as `WsWriter` trait.
you need to use `use actix_web::ws::WsWriter`
## Migration from 0.4 to 0.5

View File

@ -223,8 +223,8 @@ impl Default for ClientConnector {
pool: Rc::new(Pool::new(Rc::clone(&_modified))),
pool_modified: _modified,
connector: builder.build().unwrap(),
conn_lifetime: Duration::from_secs(15),
conn_keep_alive: Duration::from_secs(75),
conn_lifetime: Duration::from_secs(75),
conn_keep_alive: Duration::from_secs(15),
limit: 100,
limit_per_host: 0,
acquired: 0,
@ -243,8 +243,8 @@ impl Default for ClientConnector {
subscriber: None,
pool: Rc::new(Pool::new(Rc::clone(&_modified))),
pool_modified: _modified,
conn_lifetime: Duration::from_secs(15),
conn_keep_alive: Duration::from_secs(75),
conn_lifetime: Duration::from_secs(75),
conn_keep_alive: Duration::from_secs(15),
limit: 100,
limit_per_host: 0,
acquired: 0,

View File

@ -11,7 +11,7 @@ use serde::de::{self, DeserializeOwned};
use serde_urlencoded;
use de::PathDeserializer;
use error::{Error, ErrorBadRequest};
use error::{Error, ErrorNotFound, ErrorBadRequest};
use handler::{AsyncResult, FromRequest};
use httpmessage::{HttpMessage, MessageBody, UrlEncoded};
use httprequest::HttpRequest;
@ -108,7 +108,7 @@ where
fn from_request(req: &HttpRequest<S>, _: &Self::Config) -> Self::Result {
let req = req.clone();
de::Deserialize::deserialize(PathDeserializer::new(&req))
.map_err(|e| e.into())
.map_err(ErrorNotFound)
.map(|inner| Path { inner })
}
}

View File

@ -175,6 +175,9 @@ pub use httprequest::HttpRequest;
pub use httpresponse::HttpResponse;
pub use json::Json;
pub use scope::Scope;
#[doc(hidden)]
#[deprecated(since = "0.6.2", note = "please use `use actix_web::ws::WsWriter`")]
pub use ws::WsWriter;
#[cfg(feature = "openssl")]

View File

@ -1,7 +1,7 @@
//! Request logging middleware
use std::collections::HashSet;
use std::env;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::fmt::{self, Display, Formatter};
use libc;
use regex::Regex;
@ -74,6 +74,7 @@ use middleware::{Finished, Middleware, Started};
///
pub struct Logger {
format: Format,
exclude: HashSet<String>,
}
impl Logger {
@ -81,8 +82,15 @@ impl Logger {
pub fn new(format: &str) -> Logger {
Logger {
format: Format::new(format),
exclude: HashSet::new(),
}
}
/// Ignore and do not log access info for specified path.
pub fn exclude<T: Into<String>>(mut self, path: T) -> Self {
self.exclude.insert(path.into());
self
}
}
impl Default for Logger {
@ -94,6 +102,7 @@ impl Default for Logger {
fn default() -> Logger {
Logger {
format: Format::default(),
exclude: HashSet::new(),
}
}
}
@ -102,21 +111,23 @@ struct StartTime(time::Tm);
impl Logger {
fn log<S>(&self, req: &mut HttpRequest<S>, resp: &HttpResponse) {
let entry_time = req.extensions().get::<StartTime>().unwrap().0;
if let Some(entry_time) = req.extensions().get::<StartTime>() {
let render = |fmt: &mut Formatter| {
for unit in &self.format.0 {
unit.render(fmt, req, resp, entry_time)?;
unit.render(fmt, req, resp, entry_time.0)?;
}
Ok(())
};
info!("{}", FormatDisplay(&render));
}
}
}
impl<S> Middleware<S> for Logger {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
if !self.exclude.contains(req.path()) {
req.extensions_mut().insert(StartTime(time::now()));
}
Ok(Started::Done)
}

View File

@ -492,8 +492,8 @@ impl<S: 'static, H> ProcessResponse<S, H> {
if let Some(err) = self.resp.error() {
if self.resp.status().is_server_error() {
error!(
"Error occured during request handling: {}",
err
"Error occured during request handling, status: {} {}",
self.resp.status(), err
);
} else {
warn!(

View File

@ -76,7 +76,7 @@ impl<S: 'static> Scope<S> {
mem::replace(&mut self.filters, Vec::new())
}
/// Add match predicate to scoupe.
/// Add match predicate to scope.
///
/// ```rust
/// # extern crate actix_web;
@ -787,10 +787,10 @@ mod tests {
let mut app = App::new()
.scope("app", |scope| {
scope
.route("/path1", Method::GET, |r: HttpRequest<_>| {
.route("/path1", Method::GET, |_: HttpRequest<_>| {
HttpResponse::Ok()
})
.route("/path1", Method::DELETE, |r: HttpRequest<_>| {
.route("/path1", Method::DELETE, |_: HttpRequest<_>| {
HttpResponse::Ok()
})
})

View File

@ -343,24 +343,27 @@ impl<H: 'static> Entry<H> {
}
fn poll_payload(&mut self) {
if !self.flags.contains(EntryFlags::REOF) {
if self.payload.need_read() == PayloadStatus::Read {
if let Err(err) = self.recv.release_capacity().release_capacity(32_768) {
self.payload.set_error(PayloadError::Http2(err))
}
} else if let Err(err) = self.recv.release_capacity().release_capacity(0) {
self.payload.set_error(PayloadError::Http2(err))
}
while !self.flags.contains(EntryFlags::REOF)
&& self.payload.need_read() == PayloadStatus::Read
{
match self.recv.poll() {
Ok(Async::Ready(Some(chunk))) => {
let l = chunk.len();
self.payload.feed_data(chunk);
if let Err(err) = self.recv.release_capacity().release_capacity(l) {
self.payload.set_error(PayloadError::Http2(err));
break;
}
}
Ok(Async::Ready(None)) => {
self.flags.insert(EntryFlags::REOF);
self.payload.feed_eof();
}
Ok(Async::NotReady) => break,
Err(err) => {
self.payload.set_error(PayloadError::Http2(err));
break;
}
Ok(Async::NotReady) => (),
Err(err) => self.payload.set_error(PayloadError::Http2(err)),
}
}
}

View File

@ -518,24 +518,22 @@ impl ClientWriter {
fn as_mut(&mut self) -> &mut Inner {
unsafe { &mut *self.inner.get() }
}
}
impl WsWriter for ClientWriter {
/// Send text frame
#[inline]
fn text<T: Into<Binary>>(&mut self, text: T) {
pub fn text<T: Into<Binary>>(&mut self, text: T) {
self.write(Frame::message(text.into(), OpCode::Text, true, true));
}
/// Send binary frame
#[inline]
fn binary<B: Into<Binary>>(&mut self, data: B) {
pub fn binary<B: Into<Binary>>(&mut self, data: B) {
self.write(Frame::message(data, OpCode::Binary, true, true));
}
/// Send ping frame
#[inline]
fn ping(&mut self, message: &str) {
pub fn ping(&mut self, message: &str) {
self.write(Frame::message(
Vec::from(message),
OpCode::Ping,
@ -546,7 +544,7 @@ impl WsWriter for ClientWriter {
/// Send pong frame
#[inline]
fn pong(&mut self, message: &str) {
pub fn pong(&mut self, message: &str) {
self.write(Frame::message(
Vec::from(message),
OpCode::Pong,
@ -557,7 +555,39 @@ impl WsWriter for ClientWriter {
/// Send close frame
#[inline]
fn close(&mut self, reason: Option<CloseReason>) {
pub fn close(&mut self, reason: Option<CloseReason>) {
self.write(Frame::close(reason, true));
}
}
impl WsWriter for ClientWriter {
/// Send text frame
#[inline]
fn send_text<T: Into<Binary>>(&mut self, text: T) {
self.text(text)
}
/// Send binary frame
#[inline]
fn send_binary<B: Into<Binary>>(&mut self, data: B) {
self.binary(data)
}
/// Send ping frame
#[inline]
fn send_ping(&mut self, message: &str) {
self.ping(message)
}
/// Send pong frame
#[inline]
fn send_pong(&mut self, message: &str) {
self.pong(message)
}
/// Send close frame
#[inline]
fn send_close(&mut self, reason: Option<CloseReason>) {
self.close(reason);
}
}

View File

@ -149,6 +149,46 @@ where
Drain::new(rx)
}
/// Send text frame
#[inline]
pub fn text<T: Into<Binary>>(&mut self, text: T) {
self.write(Frame::message(text.into(), OpCode::Text, true, false));
}
/// Send binary frame
#[inline]
pub fn binary<B: Into<Binary>>(&mut self, data: B) {
self.write(Frame::message(data, OpCode::Binary, true, false));
}
/// Send ping frame
#[inline]
pub fn ping(&mut self, message: &str) {
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,
));
}
/// Send close frame
#[inline]
pub fn close(&mut self, reason: Option<CloseReason>) {
self.write(Frame::close(reason, false));
}
/// Check if connection still open
#[inline]
pub fn connected(&self) -> bool {
@ -181,42 +221,32 @@ where
{
/// Send text frame
#[inline]
fn text<T: Into<Binary>>(&mut self, text: T) {
self.write(Frame::message(text.into(), OpCode::Text, true, false));
fn send_text<T: Into<Binary>>(&mut self, text: T) {
self.text(text)
}
/// Send binary frame
#[inline]
fn binary<B: Into<Binary>>(&mut self, data: B) {
self.write(Frame::message(data, OpCode::Binary, true, false));
fn send_binary<B: Into<Binary>>(&mut self, data: B) {
self.binary(data)
}
/// Send ping frame
#[inline]
fn ping(&mut self, message: &str) {
self.write(Frame::message(
Vec::from(message),
OpCode::Ping,
true,
false,
));
fn send_ping(&mut self, message: &str) {
self.ping(message)
}
/// Send pong frame
#[inline]
fn pong(&mut self, message: &str) {
self.write(Frame::message(
Vec::from(message),
OpCode::Pong,
true,
false,
));
fn send_pong(&mut self, message: &str) {
self.pong(message)
}
/// Send close frame
#[inline]
fn close(&mut self, reason: Option<CloseReason>) {
self.write(Frame::close(reason, false));
fn send_close(&mut self, reason: Option<CloseReason>) {
self.close(reason)
}
}

View File

@ -343,15 +343,15 @@ where
/// Common writing methods for a websocket.
pub trait WsWriter {
/// Send a text
fn text<T: Into<Binary>>(&mut self, text: T);
fn send_text<T: Into<Binary>>(&mut self, text: T);
/// Send a binary
fn binary<B: Into<Binary>>(&mut self, data: B);
fn send_binary<B: Into<Binary>>(&mut self, data: B);
/// Send a ping message
fn ping(&mut self, message: &str);
fn send_ping(&mut self, message: &str);
/// Send a pong message
fn pong(&mut self, message: &str);
fn send_pong(&mut self, message: &str);
/// Close the connection
fn close(&mut self, reason: Option<CloseReason>);
fn send_close(&mut self, reason: Option<CloseReason>);
}
#[cfg(test)]

View File

@ -809,7 +809,7 @@ fn test_h2() {
})
});
let _res = core.run(tcp);
// assert_eq!(res.unwrap(), Bytes::from_static(STR.as_ref()));
// assert_eq!(_res.unwrap(), Bytes::from_static(STR.as_ref()));
}
#[test]