diff --git a/Cargo.toml b/Cargo.toml index ae0b605..5c28731 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ members = [ "async_ex1", "basics", "cookie-auth", - "cookie-auth-full", "cookie-session", "diesel", "error_handling", diff --git a/actix_redis/src/main.rs b/actix_redis/src/main.rs index d9ccfa8..e8072a2 100644 --- a/actix_redis/src/main.rs +++ b/actix_redis/src/main.rs @@ -3,30 +3,32 @@ extern crate actix_redis; extern crate actix_web; extern crate env_logger; extern crate futures; -#[macro_use] extern crate redis_async; +#[macro_use] +extern crate redis_async; extern crate serde; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; - -use std::sync::Arc; use actix::prelude::*; -use actix_redis::{Command, RedisActor, Error as ARError}; -use actix_web::{middleware, server, App, HttpRequest, HttpResponse, Json, - AsyncResponder, http::Method, Error as AWError}; -use futures::future::{Future, join_all}; +use actix_redis::{Command, Error as ARError, RedisActor}; +use actix_web::{ + http::Method, middleware, server, App, AsyncResponder, Error as AWError, + HttpRequest, HttpResponse, Json, +}; +use futures::future::{join_all, Future}; use redis_async::resp::RespValue; - +use std::sync::Arc; #[derive(Deserialize)] pub struct CacheInfo { one: String, two: String, - three: String + three: String, } - -fn cache_stuff((info, req): (Json, HttpRequest)) - -> impl Future { +fn cache_stuff( + (info, req): (Json, HttpRequest), +) -> impl Future { let info = info.into_inner(); let redis = req.state().redis_addr.clone(); @@ -59,25 +61,33 @@ fn cache_stuff((info, req): (Json, HttpRequest)) .responder() } -fn del_stuff(req: HttpRequest) - -> impl Future { +fn del_stuff( + req: HttpRequest, +) -> impl Future { let redis = req.state().redis_addr.clone(); - redis.send(Command(resp_array!["DEL", "mydomain:one", "mydomain:two", "mydomain:three"])) - .map_err(AWError::from) - .and_then(|res: Result| - match &res { - Ok(RespValue::Integer(x)) if x==&3 => - Ok(HttpResponse::Ok().body("successfully deleted values")), - _ =>{println!("---->{:?}", res); - Ok(HttpResponse::InternalServerError().finish())} - }) + redis + .send(Command(resp_array![ + "DEL", + "mydomain:one", + "mydomain:two", + "mydomain:three" + ])) + .map_err(AWError::from) + .and_then(|res: Result| match &res { + Ok(RespValue::Integer(x)) if x == &3 => { + Ok(HttpResponse::Ok().body("successfully deleted values")) + } + _ => { + println!("---->{:?}", res); + Ok(HttpResponse::InternalServerError().finish()) + } + }) .responder() - } pub struct AppState { - pub redis_addr: Arc> + pub redis_addr: Arc>, } fn main() { @@ -87,20 +97,19 @@ fn main() { server::new(|| { let redis_addr = Arc::new(RedisActor::start("127.0.0.1:6379")); - let app_state = AppState{redis_addr}; + let app_state = AppState { redis_addr }; App::with_state(app_state) .middleware(middleware::Logger::default()) .resource("/stuff", |r| { - r.method(Method::POST) - .with_async(cache_stuff); - r.method(Method::DELETE) - .with_async(del_stuff)}) - - }).bind("0.0.0.0:8080") - .unwrap() - .workers(1) - .start(); + r.method(Method::POST).with_async(cache_stuff); + r.method(Method::DELETE).with_async(del_stuff) + }) + }) + .bind("0.0.0.0:8080") + .unwrap() + .workers(1) + .start(); let _ = sys.run(); } diff --git a/actix_todo/src/api.rs b/actix_todo/src/api.rs index fcb67a0..73c58e3 100644 --- a/actix_todo/src/api.rs +++ b/actix_todo/src/api.rs @@ -32,7 +32,8 @@ pub fn index(req: HttpRequest) -> FutureResponse { session::clear_flash(&req); } - let rendered = req.state() + let rendered = req + .state() .template .render("index.html.tera", &context) .map_err(|e| { @@ -61,7 +62,8 @@ pub fn create( FlashMessage::error("Description cannot be empty"), )?; Ok(redirect_to("/")) - }).responder() + }) + .responder() } else { req.state() .db diff --git a/actix_todo/src/model.rs b/actix_todo/src/model.rs index 3f1afb1..60eb551 100644 --- a/actix_todo/src/model.rs +++ b/actix_todo/src/model.rs @@ -3,7 +3,8 @@ use diesel::pg::PgConnection; use diesel::prelude::*; use schema::{ - tasks, tasks::dsl::{completed as task_completed, tasks as all_tasks}, + tasks, + tasks::dsl::{completed as task_completed, tasks as all_tasks}, }; #[derive(Debug, Insertable)] diff --git a/async_ex1/Cargo.toml b/async_ex1/Cargo.toml index 1c30e0f..69985d7 100644 --- a/async_ex1/Cargo.toml +++ b/async_ex1/Cargo.toml @@ -2,10 +2,13 @@ name = "awc_examples" version = "0.1.0" authors = ["dowwie "] +edition = "2018" +workspace = ".." [dependencies] -actix = "0.7" -actix-web = { version="0.7.3", features=["rust-tls"] } +actix-rt = "0.2" +actix-http = { git="https://github.com/actix/actix-http.git", features=["ssl"] } +actix-web = { git="https://github.com/actix/actix-web.git", branch = "1.0", features=["ssl"] } futures = "0.1" serde = "1.0.43" diff --git a/async_ex1/src/main.rs b/async_ex1/src/main.rs index a3d5a02..4e8c94d 100644 --- a/async_ex1/src/main.rs +++ b/async_ex1/src/main.rs @@ -15,25 +15,17 @@ // There are 2 versions in this example, one that uses Boxed Futures and the // other that uses Impl Future, available since rustc v1.26. -extern crate actix; -extern crate actix_web; -extern crate serde; -#[macro_use] -extern crate serde_derive; -extern crate serde_json; #[macro_use] extern crate validator_derive; -extern crate env_logger; -extern crate futures; -extern crate validator; +#[macro_use] +extern crate serde_derive; -use actix_web::{ - client, http::Method, server, App, AsyncResponder, Error, HttpMessage, HttpResponse, - Json, -}; -use futures::{future::ok as fut_ok, Future}; use std::collections::HashMap; -use std::time::Duration; +use std::io; + +use actix_http::client; +use actix_web::{web, App, Error, HttpMessage, HttpResponse, HttpServer}; +use futures::future::{ok, Future}; use validator::Validate; #[derive(Debug, Validate, Deserialize, Serialize)] @@ -62,38 +54,39 @@ struct HttpBinResponse { /// post json to httpbin, get it back in the response body, return deserialized fn step_x_v1(data: SomeData) -> Box> { + let mut connector = client::Connector::default().service(); + Box::new( client::ClientRequest::post("https://httpbin.org/post") - .json(data).unwrap() - .send() - .conn_timeout(Duration::from_secs(10)) - .map_err(Error::from) // <- convert SendRequestError to an Error - .and_then( - |resp| resp.body() // <- this is MessageBody type, resolves to complete body - .from_err() // <- convert PayloadError to an Error + .json(data) + .unwrap() + .send(&mut connector) + .map_err(Error::from) // <- convert SendRequestError to an Error + .and_then(|mut resp| { + resp.body() // <- this is MessageBody type, resolves to complete body + .from_err() // <- convert PayloadError to an Error .and_then(|body| { - let resp: HttpBinResponse = serde_json::from_slice(&body).unwrap(); - fut_ok(resp.json) + let resp: HttpBinResponse = + serde_json::from_slice(&body).unwrap(); + ok(resp.json) }) - ), + }), ) } fn create_something_v1( - some_data: Json, + some_data: web::Json, ) -> Box> { - step_x_v1(some_data.into_inner()) - .and_then(|some_data_2| { - step_x_v1(some_data_2).and_then(|some_data_3| { - step_x_v1(some_data_3).and_then(|d| { - Ok(HttpResponse::Ok() - .content_type("application/json") - .body(serde_json::to_string(&d).unwrap()) - .into()) - }) + Box::new(step_x_v1(some_data.into_inner()).and_then(|some_data_2| { + step_x_v1(some_data_2).and_then(|some_data_3| { + step_x_v1(some_data_3).and_then(|d| { + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(serde_json::to_string(&d).unwrap()) + .into()) }) }) - .responder() + })) } // --------------------------------------------------------------- @@ -102,23 +95,25 @@ fn create_something_v1( /// post json to httpbin, get it back in the response body, return deserialized fn step_x_v2(data: SomeData) -> impl Future { + let mut connector = client::Connector::default().service(); + client::ClientRequest::post("https://httpbin.org/post") - .json(data).unwrap() - .send() - .conn_timeout(Duration::from_secs(10)) - .map_err(Error::from) // <- convert SendRequestError to an Error - .and_then( - |resp| resp.body() // <- this is MessageBody type, resolves to complete body - .from_err() // <- convert PayloadError to an Error + .json(data) + .unwrap() + .send(&mut connector) + .map_err(Error::from) // <- convert SendRequestError to an Error + .and_then(|mut resp| { + resp.body() // <- this is MessageBody type, resolves to complete body + .from_err() // <- convert PayloadError to an Error .and_then(|body| { let resp: HttpBinResponse = serde_json::from_slice(&body).unwrap(); - fut_ok(resp.json) + ok(resp.json) }) - ) + }) } fn create_something_v2( - some_data: Json, + some_data: web::Json, ) -> impl Future { step_x_v2(some_data.into_inner()).and_then(|some_data_2| { step_x_v2(some_data_2).and_then(|some_data_3| { @@ -132,23 +127,21 @@ fn create_something_v2( }) } -fn main() { - ::std::env::set_var("RUST_LOG", "actix_web=info"); +fn main() -> io::Result<()> { + std::env::set_var("RUST_LOG", "actix_web=info"); env_logger::init(); - let sys = actix::System::new("asyncio_example"); - server::new(move || { + HttpServer::new(|| { App::new() - .resource("/something_v1", |r| { - r.method(Method::POST).with(create_something_v1) - }) - .resource("/something_v2", |r| { - r.method(Method::POST).with_async(create_something_v2) - }) - }).bind("127.0.0.1:8088") - .unwrap() - .start(); - - println!("Started http server: 127.0.0.1:8088"); - let _ = sys.run(); + .service( + web::resource("/something_v1") + .route(web::post().to(create_something_v1)), + ) + .service( + web::resource("/something_v2") + .route(web::post().to_async(create_something_v2)), + ) + }) + .bind("127.0.0.1:8088")? + .run() } diff --git a/cookie-auth-full/Cargo.toml b/cookie-auth-full/Cargo.toml deleted file mode 100644 index 87e6df9..0000000 --- a/cookie-auth-full/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "cookie-auth-full" -version = "0.1.0" -authors = ["Nikolay Kim "] -workspace = "../" - -[dependencies] -actix = "0.7" -actix-web = "0.7" - -cookie = { version="0.11", features=["percent-encode", "secure"] } -futures = "0.1" -time = "0.1" -env_logger = "0.5" diff --git a/cookie-auth-full/src/auth.rs b/cookie-auth-full/src/auth.rs deleted file mode 100644 index 56ec54e..0000000 --- a/cookie-auth-full/src/auth.rs +++ /dev/null @@ -1,274 +0,0 @@ -#![allow(dead_code)] -use std::rc::Rc; - -use cookie::{Cookie, CookieJar, Key}; -use futures::future::{err as FutErr, ok as FutOk, FutureResult}; -use futures::Future; -use time::Duration; - -use actix_web::http::header::{self, HeaderValue}; -use actix_web::middleware::{Middleware, Response, Started}; -use actix_web::{Error, HttpRequest, HttpResponse, Result}; - -/// Trait provides identity service for the request. -pub trait RequestIdentity { - /// Return the claimed identity of the user associated request or - /// ``None`` if no identity can be found associated with the request. - fn identity(&self) -> Option; - - /// Remember identity. - fn remember(&self, identity: String); - - /// This method is used to 'forget' the current identity on subsequent - /// requests. - fn forget(&self); -} - -impl RequestIdentity for HttpRequest { - fn identity(&self) -> Option { - if let Some(id) = self.extensions().get::() { - return id.0.identity().map(|s| s.to_owned()); - } - None - } - - fn remember(&self, identity: String) { - if let Some(id) = self.extensions_mut().get_mut::() { - return id.0.as_mut().remember(identity); - } - } - - fn forget(&self) { - if let Some(id) = self.extensions_mut().get_mut::() { - return id.0.forget(); - } - } -} - -/// An identity -pub trait Identity: 'static { - fn identity(&self) -> Option<&str>; - - fn remember(&mut self, key: String); - - fn forget(&mut self); - - /// Write session to storage backend. - fn write(&mut self, resp: HttpResponse) -> Result; -} - -/// Identity policy definition. -pub trait IdentityPolicy: Sized + 'static { - type Identity: Identity; - type Future: Future; - - /// Parse the session from request and load data from a service identity. - fn from_request(&self, request: &mut HttpRequest) -> Self::Future; -} - -/// Middleware that implements identity service -pub struct IdentityService { - backend: T, -} - -impl IdentityService { - /// Create new identity service with specified backend. - pub fn new(backend: T) -> Self { - IdentityService { backend } - } -} - -struct IdentityBox(Box); - -#[doc(hidden)] -unsafe impl Send for IdentityBox {} -#[doc(hidden)] -unsafe impl Sync for IdentityBox {} - -impl> Middleware for IdentityService { - fn start(&self, req: &HttpRequest) -> Result { - let mut req = req.clone(); - - let fut = self - .backend - .from_request(&mut req) - .then(move |res| match res { - Ok(id) => { - req.extensions_mut().insert(IdentityBox(Box::new(id))); - FutOk(None) - } - Err(err) => FutErr(err), - }); - Ok(Started::Future(Box::new(fut))) - } - - fn response(&self, req: &HttpRequest, resp: HttpResponse) -> Result { - if let Some(mut id) = req.extensions_mut().remove::() { - id.0.write(resp) - } else { - Ok(Response::Done(resp)) - } - } -} - -/// Identity that uses private cookies as identity storage -pub struct CookieIdentity { - changed: bool, - identity: Option, - inner: Rc, -} - -impl Identity for CookieIdentity { - fn identity(&self) -> Option<&str> { - self.identity.as_ref().map(|s| s.as_ref()) - } - - fn remember(&mut self, value: String) { - self.changed = true; - self.identity = Some(value); - } - - fn forget(&mut self) { - self.changed = true; - self.identity = None; - } - - fn write(&mut self, mut resp: HttpResponse) -> Result { - if self.changed { - let _ = self.inner.set_cookie(&mut resp, self.identity.take()); - } - Ok(Response::Done(resp)) - } -} - -struct CookieIdentityInner { - key: Key, - name: String, - path: String, - domain: Option, - secure: bool, - max_age: Option, -} - -impl CookieIdentityInner { - fn new(key: &[u8]) -> CookieIdentityInner { - CookieIdentityInner { - key: Key::from_master(key), - name: "actix-identity".to_owned(), - path: "/".to_owned(), - domain: None, - secure: true, - max_age: None, - } - } - - fn set_cookie(&self, resp: &mut HttpResponse, id: Option) -> Result<()> { - let some = id.is_some(); - { - let id = id.unwrap_or_else(|| String::new()); - let mut cookie = Cookie::new(self.name.clone(), id); - cookie.set_path(self.path.clone()); - cookie.set_secure(self.secure); - cookie.set_http_only(true); - - if let Some(ref domain) = self.domain { - cookie.set_domain(domain.clone()); - } - - if let Some(max_age) = self.max_age { - cookie.set_max_age(max_age); - } - - let mut jar = CookieJar::new(); - if some { - jar.private(&self.key).add(cookie); - } else { - jar.add_original(cookie.clone()); - jar.private(&self.key).remove(cookie); - } - - for cookie in jar.delta() { - let val = HeaderValue::from_str(&cookie.to_string())?; - resp.headers_mut().append(header::SET_COOKIE, val); - } - } - - Ok(()) - } - - fn load(&self, req: &mut HttpRequest) -> Option { - if let Ok(cookies) = req.cookies() { - for cookie in cookies.iter() { - if cookie.name() == self.name { - let mut jar = CookieJar::new(); - jar.add_original(cookie.clone()); - - let cookie_opt = jar.private(&self.key).get(&self.name); - if let Some(cookie) = cookie_opt { - return Some(cookie.value().into()); - } - } - } - } - None - } -} - -/// Use cookies for request identity. -pub struct CookieIdentityPolicy(Rc); - -impl CookieIdentityPolicy { - /// Construct new `CookieIdentityPolicy` instance. - /// - /// Panics if key length is less than 32 bytes. - pub fn new(key: &[u8]) -> CookieIdentityPolicy { - CookieIdentityPolicy(Rc::new(CookieIdentityInner::new(key))) - } - - /// Sets the `path` field in the session cookie being built. - pub fn path>(mut self, value: S) -> CookieIdentityPolicy { - Rc::get_mut(&mut self.0).unwrap().path = value.into(); - self - } - - /// Sets the `name` field in the session cookie being built. - pub fn name>(mut self, value: S) -> CookieIdentityPolicy { - Rc::get_mut(&mut self.0).unwrap().name = value.into(); - self - } - - /// Sets the `domain` field in the session cookie being built. - pub fn domain>(mut self, value: S) -> CookieIdentityPolicy { - Rc::get_mut(&mut self.0).unwrap().domain = Some(value.into()); - self - } - - /// Sets the `secure` field in the session cookie being built. - /// - /// If the `secure` field is set, a cookie will only be transmitted when the - /// connection is secure - i.e. `https` - pub fn secure(mut self, value: bool) -> CookieIdentityPolicy { - Rc::get_mut(&mut self.0).unwrap().secure = value; - self - } - - /// Sets the `max-age` field in the session cookie being built. - pub fn max_age(mut self, value: Duration) -> CookieIdentityPolicy { - Rc::get_mut(&mut self.0).unwrap().max_age = Some(value); - self - } -} - -impl IdentityPolicy for CookieIdentityPolicy { - type Identity = CookieIdentity; - type Future = FutureResult; - - fn from_request(&self, req: &mut HttpRequest) -> Self::Future { - let identity = self.0.load(req); - FutOk(CookieIdentity { - identity, - changed: false, - inner: Rc::clone(&self.0), - }) - } -} diff --git a/cookie-auth-full/src/main.rs b/cookie-auth-full/src/main.rs deleted file mode 100644 index f7a0c09..0000000 --- a/cookie-auth-full/src/main.rs +++ /dev/null @@ -1,49 +0,0 @@ -extern crate actix; -extern crate actix_web; -extern crate cookie; -extern crate env_logger; -extern crate futures; -extern crate time; - -use actix_web::{middleware, server, App, HttpRequest, HttpResponse}; - -mod auth; -use auth::{CookieIdentityPolicy, IdentityService, RequestIdentity}; - -fn index(req: &HttpRequest) -> String { - format!("Hello {}", req.identity().unwrap_or("Anonymous".to_owned())) -} - -fn login(req: &HttpRequest) -> HttpResponse { - req.remember("user1".to_owned()); - HttpResponse::Found().header("location", "/").finish() -} - -fn logout(req: &HttpRequest) -> HttpResponse { - req.forget(); - HttpResponse::Found().header("location", "/").finish() -} - -fn main() { - ::std::env::set_var("RUST_LOG", "actix_web=info"); - env_logger::init(); - let sys = actix::System::new("cookie-auth"); - - server::new(|| { - App::new() - .middleware(middleware::Logger::default()) - .middleware(IdentityService::new( - CookieIdentityPolicy::new(&[0; 32]) - .name("auth-example") - .secure(false), - )) - .resource("/login", |r| r.f(login)) - .resource("/logout", |r| r.f(logout)) - .resource("/", |r| r.f(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); - - println!("Started http server: 127.0.0.1:8080"); - let _ = sys.run(); -} diff --git a/cookie-auth/Cargo.toml b/cookie-auth/Cargo.toml index ceda654..2e7858d 100644 --- a/cookie-auth/Cargo.toml +++ b/cookie-auth/Cargo.toml @@ -5,6 +5,5 @@ authors = ["Nikolay Kim "] workspace = "../" [dependencies] -actix = "0.7" -actix-web = "0.7" +actix-web = { git="https://github.com/actix/actix-web.git" } env_logger = "0.5" diff --git a/cookie-auth/src/main.rs b/cookie-auth/src/main.rs index a744479..82db1da 100644 --- a/cookie-auth/src/main.rs +++ b/cookie-auth/src/main.rs @@ -2,9 +2,9 @@ extern crate actix; extern crate actix_web; extern crate env_logger; -use actix_web::{middleware, server, App, HttpRequest, HttpResponse}; use actix_web::middleware::identity::RequestIdentity; use actix_web::middleware::identity::{CookieIdentityPolicy, IdentityService}; +use actix_web::{middleware, server, App, HttpRequest, HttpResponse}; fn index(req: &HttpRequest) -> String { format!("Hello {}", req.identity().unwrap_or("Anonymous".to_owned())) @@ -36,9 +36,10 @@ fn main() { .resource("/login", |r| r.f(login)) .resource("/logout", |r| r.f(logout)) .resource("/", |r| r.f(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/cookie-session/Cargo.toml b/cookie-session/Cargo.toml index 399a617..2947b95 100644 --- a/cookie-session/Cargo.toml +++ b/cookie-session/Cargo.toml @@ -2,12 +2,13 @@ name = "cookie-session" version = "0.1.0" authors = ["Nikolay Kim "] -workspace = "../" +workspace = ".." +edition = "2018" [dependencies] -actix = "0.7" -actix-web = "^0.7" +actix-web = { git="https://github.com/actix/actix-web.git", branch = "1.0" } +actix-session = { git="https://github.com/actix/actix-web.git", branch = "1.0" } futures = "0.1" time = "0.1" -env_logger = "0.5" +env_logger = "0.6" diff --git a/cookie-session/src/main.rs b/cookie-session/src/main.rs index 94f736f..6e0df12 100644 --- a/cookie-session/src/main.rs +++ b/cookie-session/src/main.rs @@ -5,50 +5,38 @@ //! //! [User guide](https://actix.rs/book/actix-web/sec-9-middlewares.html#user-sessions) -extern crate actix; -extern crate actix_web; -extern crate env_logger; -extern crate futures; - -use actix_web::middleware::session::{self, RequestSession}; -use actix_web::{middleware, server, App, HttpRequest, Result}; -use std::env; +use actix_session::{CookieSession, Session}; +use actix_web::{middleware::Logger, web, App, HttpRequest, HttpServer, Result}; /// simple index handler with session -fn index(req: &HttpRequest) -> Result<&'static str> { +fn index(session: Session, req: HttpRequest) -> Result<&'static str> { println!("{:?}", req); // RequestSession trait is used for session access let mut counter = 1; - if let Some(count) = req.session().get::("counter")? { + if let Some(count) = session.get::("counter")? { println!("SESSION value: {}", count); counter = count + 1; - req.session().set("counter", counter)?; + session.set("counter", counter)?; } else { - req.session().set("counter", counter)?; + session.set("counter", counter)?; } Ok("welcome!") } -fn main() { - env::set_var("RUST_LOG", "actix_web=info"); +fn main() -> std::io::Result<()> { + std::env::set_var("RUST_LOG", "actix_web=info"); env_logger::init(); - let sys = actix::System::new("session-example"); - server::new(|| { + HttpServer::new(|| { App::new() // enable logger - .middleware(middleware::Logger::default()) + .middleware(Logger::default()) // cookie session middleware - .middleware(session::SessionStorage::new( - session::CookieSessionBackend::signed(&[0; 32]).secure(false) - )) - .resource("/", |r| r.f(index)) - }).bind("127.0.0.1:8080") - .expect("Can not bind to 127.0.0.1:8080") - .start(); - - println!("Starting http server: 127.0.0.1:8080"); - let _ = sys.run(); + .middleware(CookieSession::signed(&[0; 32]).secure(false)) + .service(web::resource("/").to(index)) + }) + .bind("127.0.0.1:8080")? + .run() } diff --git a/error_handling/Cargo.toml b/error_handling/Cargo.toml index fe27b1c..f1df6a4 100644 --- a/error_handling/Cargo.toml +++ b/error_handling/Cargo.toml @@ -2,11 +2,13 @@ name = "error_handling" version = "0.1.0" authors = ["dowwie "] +edition = "2018" +workspace = ".." [dependencies] -actix = "0.7.3" -actix-web = "0.7.3" -failure = "0.1.2" +actix-web = { git="https://github.com/actix/actix-web.git", branch = "1.0" } + +derive_more = "0.14.0" futures = "0.1.23" rand = "0.5.4" -env_logger = "0.5.12" +env_logger = "0.6" diff --git a/error_handling/src/main.rs b/error_handling/src/main.rs index 6a1788f..676a8ce 100644 --- a/error_handling/src/main.rs +++ b/error_handling/src/main.rs @@ -1,10 +1,10 @@ /* -The goal of this example is to show how to propagate a custom error type, derived -from the Fail trait, to a web handler that will evaluate the type of error that +The goal of this example is to show how to propagate a custom error type, +to a web handler that will evaluate the type of error that was raised and return an appropriate HTTPResponse. This example uses a 50/50 chance of returning 200 Ok, otherwise one of four possible -http errors will be chosen, each with an equal chance of being selected: +http errors will be chosen, each with an equal chance of being selected: 1. 403 Forbidden 2. 401 Unauthorized 3. 500 InternalServerError @@ -12,128 +12,91 @@ http errors will be chosen, each with an equal chance of being selected: */ - -extern crate actix; -extern crate actix_web; -extern crate env_logger; -#[macro_use] extern crate failure; -extern crate futures; -extern crate rand; - - -use actix_web::{ - http::Method, server, App, AsyncResponder, Error as ActixWebError, - HttpResponse, HttpRequest +use actix_web::{web, App, Error, HttpResponse, HttpServer, ResponseError}; +use derive_more::Display; // naming it clearly for illustration purposes +use futures::future::{err, ok, Future}; +use rand::{ + distributions::{Distribution, Standard}, + thread_rng, Rng, }; -use failure::Error as FailureError; // naming it clearly for illustration purposes -use futures::{ - future::{ - ok as fut_ok, - err as fut_err - }, - Future -}; -use rand::{thread_rng, Rng, distributions::{Distribution, Standard}}; - - -#[derive(Fail, Debug)] +#[derive(Debug, Display)] pub enum CustomError { - #[fail(display = "Custom Error 1")] + #[display(fmt = "Custom Error 1")] CustomOne, - #[fail(display = "Custom Error 2")] + #[display(fmt = "Custom Error 2")] CustomTwo, - #[fail(display = "Custom Error 3")] + #[display(fmt = "Custom Error 3")] CustomThree, - #[fail(display = "Custom Error 4")] - CustomFour + #[display(fmt = "Custom Error 4")] + CustomFour, } - impl Distribution for Standard { fn sample(&self, rng: &mut R) -> CustomError { match rng.gen_range(0, 4) { 0 => CustomError::CustomOne, 1 => CustomError::CustomTwo, 2 => CustomError::CustomThree, - _ => CustomError::CustomFour + _ => CustomError::CustomFour, } } } -/* +/// Actix web uses `ResponseError` for conversion of errors to a response impl ResponseError for CustomError { fn error_response(&self) -> HttpResponse { - HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR) + match self { + CustomError::CustomOne => { + println!("do some stuff related to CustomOne error"); + HttpResponse::Forbidden().finish() + } + + CustomError::CustomTwo => { + println!("do some stuff related to CustomTwo error"); + HttpResponse::Unauthorized().finish() + } + + CustomError::CustomThree => { + println!("do some stuff related to CustomThree error"); + HttpResponse::InternalServerError().finish() + } + + _ => { + println!("do some stuff related to CustomFour error"); + HttpResponse::BadRequest().finish() + } + } } } -*/ - /// randomly returns either () or one of the 4 CustomError variants -//fn do_something_random() -> impl Future, -// Error = ActixWebError> { fn do_something_random() -> impl Future { let mut rng = thread_rng(); // 20% chance that () will be returned by this function - if rng.gen_bool(2.0/10.0) { - return fut_ok(()) + if rng.gen_bool(2.0 / 10.0) { + ok(()) + } else { + err(rand::random::()) } - - let err: CustomError = rand::random(); - return fut_err(err) } - -fn do_something(_req: HttpRequest) - -> impl Future { - - do_something_random() - .then(|result| match result { - Ok(_) => Ok(HttpResponse::Ok() - .body("Nothing interesting happened. Try again.")), - - Err(err) => match err { - CustomError::CustomOne => { - println!("do some stuff related to CustomOne error"); - Ok(HttpResponse::Forbidden().finish()) - }, - - CustomError::CustomTwo => { - println!("do some stuff related to CustomTwo error"); - Ok(HttpResponse::Unauthorized().finish()) - }, - - CustomError::CustomThree => { - println!("do some stuff related to CustomThree error"); - Ok(HttpResponse::InternalServerError().finish()) - }, - - _ => { - println!("do some stuff related to CustomFour error"); - Ok(HttpResponse::BadRequest().finish()) - } - } +fn do_something() -> impl Future { + do_something_random().from_err().and_then(|_| { + HttpResponse::Ok().body("Nothing interesting happened. Try again.") }) - .responder() } - -fn main() { - ::std::env::set_var("RUST_LOG", "actix_web=info"); +fn main() -> std::io::Result<()> { + std::env::set_var("RUST_LOG", "actix_web=info"); env_logger::init(); - let sys = actix::System::new("error_handling_example"); - server::new(move || { - App::new() - .resource("/something", |r| - r.method(Method::GET) - .with_async(do_something)) - }).bind("127.0.0.1:8088") - .unwrap() - .start(); - - println!("Started http server: 127.0.0.1:8088"); - let _ = sys.run(); + HttpServer::new(move || { + App::new().service( + web::resource("/something").route(web::get().to_async(do_something)), + ) + }) + .bind("127.0.0.1:8088")? + .run() } diff --git a/form/src/main.rs b/form/src/main.rs index 615fff2..01f416f 100644 --- a/form/src/main.rs +++ b/form/src/main.rs @@ -18,22 +18,24 @@ fn main() { let _addr = server::new(|| { App::with_state(AppState { foo: "bar".to_string(), - }).middleware(middleware::Logger::default()) - .resource("/", |r| { - r.method(http::Method::GET).with(index); - }) - .resource("/post1", |r| { - r.method(http::Method::POST).with(handle_post_1) - }) - .resource("/post2", |r| { - r.method(http::Method::POST).with(handle_post_2) - }) - .resource("/post3", |r| { - r.method(http::Method::POST).with(handle_post_3) - }) - }).bind("127.0.0.1:8080") - .expect("Can not bind to 127.0.0.1:8080") - .start(); + }) + .middleware(middleware::Logger::default()) + .resource("/", |r| { + r.method(http::Method::GET).with(index); + }) + .resource("/post1", |r| { + r.method(http::Method::POST).with(handle_post_1) + }) + .resource("/post2", |r| { + r.method(http::Method::POST).with(handle_post_2) + }) + .resource("/post3", |r| { + r.method(http::Method::POST).with(handle_post_3) + }) + }) + .bind("127.0.0.1:8080") + .expect("Can not bind to 127.0.0.1:8080") + .start(); println!("Starting http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/hello-world/src/main.rs b/hello-world/src/main.rs index 90d93b7..2d78783 100644 --- a/hello-world/src/main.rs +++ b/hello-world/src/main.rs @@ -19,9 +19,10 @@ fn main() { .middleware(middleware::Logger::default()) .resource("/index.html", |r| r.f(|_| "Hello world!")) .resource("/", |r| r.f(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/http-full-proxy/src/main.rs b/http-full-proxy/src/main.rs index 4d69187..05bfb39 100644 --- a/http-full-proxy/src/main.rs +++ b/http-full-proxy/src/main.rs @@ -87,25 +87,29 @@ fn main() { .value_name("LISTEN ADDR") .index(1) .required(true), - ).arg( + ) + .arg( Arg::with_name("listen_port") .takes_value(true) .value_name("LISTEN PORT") .index(2) .required(true), - ).arg( + ) + .arg( Arg::with_name("forward_addr") .takes_value(true) .value_name("FWD ADDR") .index(3) .required(true), - ).arg( + ) + .arg( Arg::with_name("forward_port") .takes_value(true) .value_name("FWD PORT") .index(4) .required(true), - ).get_matches(); + ) + .get_matches(); let listen_addr = matches.value_of("listen_addr").unwrap(); let listen_port = value_t!(matches, "listen_port", u16).unwrap_or_else(|e| e.exit()); @@ -121,13 +125,15 @@ fn main() { .unwrap() .next() .unwrap() - )).unwrap(); + )) + .unwrap(); server::new(move || { App::with_state(AppState::init(forward_url.clone())).default_resource(|r| { r.f(forward); }) - }).workers(32) + }) + .workers(32) .bind((listen_addr, listen_port)) .expect("Cannot bind listening port") .system_exit() diff --git a/http-proxy/src/main.rs b/http-proxy/src/main.rs index 3785ae6..9d51ace 100644 --- a/http-proxy/src/main.rs +++ b/http-proxy/src/main.rs @@ -12,15 +12,18 @@ use futures::{Future, Stream}; /// Stream client request response and then send body to a server response fn index(_req: &HttpRequest) -> Box> { client::ClientRequest::get("http://127.0.0.1:8081/") - .finish().unwrap() + .finish() + .unwrap() .send() - .map_err(Error::from) // <- convert SendRequestError to an Error - .and_then( - |resp| resp.body() // <- this is MessageBody type, resolves to complete body - .from_err() // <- convert PayloadError to an Error - .and_then(|body| { // <- we got complete body, now send as server response + .map_err(Error::from) // <- convert SendRequestError to an Error + .and_then(|resp| { + resp.body() // <- this is MessageBody type, resolves to complete body + .from_err() // <- convert PayloadError to an Error + .and_then(|body| { + // <- we got complete body, now send as server response Ok(HttpResponse::Ok().body(body)) - })) + }) + }) .responder() } @@ -28,14 +31,16 @@ fn index(_req: &HttpRequest) -> Box> fn streaming(_req: &HttpRequest) -> Box> { // send client request client::ClientRequest::get("https://www.rust-lang.org/en-US/") - .finish().unwrap() - .send() // <- connect to host and send request - .map_err(Error::from) // <- convert SendRequestError to an Error - .and_then(|resp| { // <- we received client response + .finish() + .unwrap() + .send() // <- connect to host and send request + .map_err(Error::from) // <- convert SendRequestError to an Error + .and_then(|resp| { + // <- we received client response Ok(HttpResponse::Ok() - // read one chunk from client response and send this chunk to a server response - // .from_err() converts PayloadError to an Error - .body(Body::Streaming(Box::new(resp.payload().from_err())))) + // read one chunk from client response and send this chunk to a server response + // .from_err() converts PayloadError to an Error + .body(Body::Streaming(Box::new(resp.payload().from_err())))) }) .responder() } @@ -50,10 +55,11 @@ fn main() { .middleware(middleware::Logger::default()) .resource("/streaming", |r| r.f(streaming)) .resource("/", |r| r.f(index)) - }).workers(1) - .bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .workers(1) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/http-proxy/src/server.rs b/http-proxy/src/server.rs index ca1dfb2..11584de 100644 --- a/http-proxy/src/server.rs +++ b/http-proxy/src/server.rs @@ -20,14 +20,15 @@ fn main() { server::new(|| { App::new() - // enable logger + // enable logger .middleware(middleware::Logger::default()) .resource("/index.html", |r| r.f(|_| "Hello world!")) .resource("/", |r| r.f(index)) - }).workers(1) - .bind("127.0.0.1:8081") - .unwrap() - .start(); + }) + .workers(1) + .bind("127.0.0.1:8081") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8081"); let _ = sys.run(); diff --git a/juniper/src/main.rs b/juniper/src/main.rs index d06cc5e..468c093 100644 --- a/juniper/src/main.rs +++ b/juniper/src/main.rs @@ -93,14 +93,17 @@ fn main() { // Start http server server::new(move || { - App::with_state(AppState{executor: addr.clone()}) - // enable logger - .middleware(middleware::Logger::default()) - .resource("/graphql", |r| r.method(http::Method::POST).with(graphql)) - .resource("/graphiql", |r| r.method(http::Method::GET).h(graphiql)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + App::with_state(AppState { + executor: addr.clone(), + }) + // enable logger + .middleware(middleware::Logger::default()) + .resource("/graphql", |r| r.method(http::Method::POST).with(graphql)) + .resource("/graphiql", |r| r.method(http::Method::GET).h(graphiql)) + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/middleware/src/main.rs b/middleware/src/main.rs index 539a307..91ae9d0 100644 --- a/middleware/src/main.rs +++ b/middleware/src/main.rs @@ -16,14 +16,17 @@ fn main() { .middleware(simple::SayHi) // .middleware(redirect::CheckLogin) .resource("/login", |r| { - r.f(|_| "You are on /login. Go to src/redirect.rs to change this behavior.") + r.f(|_| { + "You are on /login. Go to src/redirect.rs to change this behavior." + }) }) .resource("/", |r| { r.f(|_| "Hello, middleware! Check the console where the server is run.") }) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); let _ = sys.run(); } diff --git a/multipart/src/main.rs b/multipart/src/main.rs index 6cea253..37c17bf 100644 --- a/multipart/src/main.rs +++ b/multipart/src/main.rs @@ -101,14 +101,16 @@ fn main() { server::new(|| { App::with_state(AppState { counter: Cell::new(0), - }).middleware(middleware::Logger::default()) - .resource("/", |r| { - r.method(http::Method::GET).with(index); - r.method(http::Method::POST).with(upload); - }) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .middleware(middleware::Logger::default()) + .resource("/", |r| { + r.method(http::Method::GET).with(index); + r.method(http::Method::POST).with(upload); + }) + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Starting http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/protobuf/src/main.rs b/protobuf/src/main.rs index aaae1f1..8322030 100644 --- a/protobuf/src/main.rs +++ b/protobuf/src/main.rs @@ -28,10 +28,10 @@ pub struct MyObj { /// This handler uses `ProtoBufMessage` for loading protobuf object. fn index(req: &HttpRequest) -> Box> { protobuf::ProtoBufMessage::new(req) - .from_err() // convert all errors into `Error` + .from_err() // convert all errors into `Error` .and_then(|val: MyObj| { println!("model: {:?}", val); - Ok(HttpResponse::Ok().protobuf(val)?) // <- send response + Ok(HttpResponse::Ok().protobuf(val)?) // <- send response }) .responder() } @@ -45,10 +45,11 @@ fn main() { App::new() .middleware(middleware::Logger::default()) .resource("/", |r| r.method(http::Method::POST).f(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .shutdown_timeout(1) - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .shutdown_timeout(1) + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/redis-session/src/main.rs b/redis-session/src/main.rs index 3b68ab5..18a68e1 100644 --- a/redis-session/src/main.rs +++ b/redis-session/src/main.rs @@ -35,14 +35,16 @@ fn main() { // enable logger .middleware(middleware::Logger::default()) // redis session middleware - .middleware(SessionStorage::new( - RedisSessionBackend::new("127.0.0.1:6379", &[0; 32]) - )) + .middleware(SessionStorage::new(RedisSessionBackend::new( + "127.0.0.1:6379", + &[0; 32], + ))) // register simple route, handle all methods .resource("/", |r| r.f(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); let _ = sys.run(); } diff --git a/rustls/src/main.rs b/rustls/src/main.rs index 5822021..33bcb53 100644 --- a/rustls/src/main.rs +++ b/rustls/src/main.rs @@ -49,16 +49,19 @@ fn main() { // register simple handler, handle all methods .resource("/index.html", |r| r.f(index)) // with path parameters - .resource("/", |r| r.method(http::Method::GET).f(|_| { - HttpResponse::Found() - .header("LOCATION", "/index.html") - .finish() - })) + .resource("/", |r| { + r.method(http::Method::GET).f(|_| { + HttpResponse::Found() + .header("LOCATION", "/index.html") + .finish() + }) + }) .handler("/static", StaticFiles::new("static").unwrap()) - }).bind_with("127.0.0.1:8443", move || acceptor.clone()) + }) + .bind_with("127.0.0.1:8443", move || acceptor.clone()) .unwrap() .start(); println!("Started http server: 127.0.0.1:8443"); let _ = sys.run(); -} \ No newline at end of file +} diff --git a/simple-auth-server/src/app.rs b/simple-auth-server/src/app.rs index f56be1a..05fdf2f 100644 --- a/simple-auth-server/src/app.rs +++ b/simple-auth-server/src/app.rs @@ -14,8 +14,10 @@ pub struct AppState { /// creates and returns the app after mounting all routes/resources pub fn create_app(db: Addr) -> App { // secret is a random minimum 32 bytes long base 64 string - let secret: String = std::env::var("SECRET_KEY").unwrap_or_else(|_| "0123".repeat(8)); - let domain: String = std::env::var("DOMAIN").unwrap_or_else(|_| "localhost".to_string()); + let secret: String = + std::env::var("SECRET_KEY").unwrap_or_else(|_| "0123".repeat(8)); + let domain: String = + std::env::var("DOMAIN").unwrap_or_else(|_| "localhost".to_string()); App::with_state(AppState { db }) .middleware(Logger::default()) diff --git a/simple-auth-server/src/auth_handler.rs b/simple-auth-server/src/auth_handler.rs index cedfa90..161a951 100644 --- a/simple-auth-server/src/auth_handler.rs +++ b/simple-auth-server/src/auth_handler.rs @@ -1,9 +1,9 @@ use actix::{Handler, Message}; +use actix_web::{middleware::identity::RequestIdentity, FromRequest, HttpRequest}; +use bcrypt::verify; use diesel::prelude::*; use errors::ServiceError; -use models::{DbExecutor, User, SlimUser}; -use bcrypt::verify; -use actix_web::{FromRequest, HttpRequest, middleware::identity::RequestIdentity}; +use models::{DbExecutor, SlimUser, User}; use utils::decode_token; #[derive(Debug, Deserialize)] @@ -19,22 +19,24 @@ impl Message for AuthData { impl Handler for DbExecutor { type Result = Result; fn handle(&mut self, msg: AuthData, _: &mut Self::Context) -> Self::Result { - use schema::users::dsl::{users, email}; + use schema::users::dsl::{email, users}; let conn: &PgConnection = &self.0.get().unwrap(); - let mut items = users - .filter(email.eq(&msg.email)) - .load::(conn)?; + let mut items = users.filter(email.eq(&msg.email)).load::(conn)?; if let Some(user) = items.pop() { match verify(&msg.password, &user.password) { - Ok(matching) => if matching { + Ok(matching) => { + if matching { return Ok(user.into()); - }, + } + } Err(_) => (), } } - Err(ServiceError::BadRequest("Username and Password don't match".into())) + Err(ServiceError::BadRequest( + "Username and Password don't match".into(), + )) } } diff --git a/simple-auth-server/src/auth_routes.rs b/simple-auth-server/src/auth_routes.rs index 48ee15c..90cafec 100644 --- a/simple-auth-server/src/auth_routes.rs +++ b/simple-auth-server/src/auth_routes.rs @@ -1,13 +1,16 @@ -use actix_web::{AsyncResponder, FutureResponse, HttpResponse, HttpRequest, ResponseError, Json}; use actix_web::middleware::identity::RequestIdentity; +use actix_web::{ + AsyncResponder, FutureResponse, HttpRequest, HttpResponse, Json, ResponseError, +}; use futures::future::Future; use utils::create_token; use app::AppState; use auth_handler::{AuthData, LoggedUser}; -pub fn login((auth_data, req): (Json, HttpRequest)) - -> FutureResponse { +pub fn login( + (auth_data, req): (Json, HttpRequest), +) -> FutureResponse { req.state() .db .send(auth_data.into_inner()) @@ -19,7 +22,8 @@ pub fn login((auth_data, req): (Json, HttpRequest)) Ok(HttpResponse::Ok().into()) } Err(err) => Ok(err.error_response()), - }).responder() + }) + .responder() } pub fn logout(req: HttpRequest) -> HttpResponse { diff --git a/simple-auth-server/src/email_service.rs b/simple-auth-server/src/email_service.rs index f1db117..d9854f4 100644 --- a/simple-auth-server/src/email_service.rs +++ b/simple-auth-server/src/email_service.rs @@ -9,8 +9,8 @@ fn get_api_key() -> String { pub fn send_invitation(invitation: &Invitation) { let tm = Transmission::new_eu(get_api_key()); - let sending_email = - std::env::var("SENDING_EMAIL_ADDRESS").expect("SENDING_EMAIL_ADDRESS must be set"); + let sending_email = std::env::var("SENDING_EMAIL_ADDRESS") + .expect("SENDING_EMAIL_ADDRESS must be set"); // new email message with sender name and email let mut email = Message::new(EmailAddress::new(sending_email, "Let's Organise")); @@ -39,7 +39,6 @@ pub fn send_invitation(invitation: &Invitation) { .to_string() ); - // complete the email message with details email .add_recipient(recipient) @@ -51,16 +50,14 @@ pub fn send_invitation(invitation: &Invitation) { // Note that we only print out the error response from email api match result { - Ok(res) => { - match res { - TransmissionResponse::ApiResponse(api_res) => { - println!("API Response: \n {:#?}", api_res); - } - TransmissionResponse::ApiError(errors) => { - println!("Response Errors: \n {:#?}", &errors); - } + Ok(res) => match res { + TransmissionResponse::ApiResponse(api_res) => { + println!("API Response: \n {:#?}", api_res); } - } + TransmissionResponse::ApiError(errors) => { + println!("Response Errors: \n {:#?}", &errors); + } + }, Err(error) => { println!("error \n {:#?}", error); } diff --git a/simple-auth-server/src/errors.rs b/simple-auth-server/src/errors.rs index b65aa4f..0be6312 100644 --- a/simple-auth-server/src/errors.rs +++ b/simple-auth-server/src/errors.rs @@ -1,9 +1,8 @@ use actix_web::{error::ResponseError, HttpResponse}; -use std::convert::From; use diesel::result::{DatabaseErrorKind, Error}; +use std::convert::From; use uuid::ParseError; - #[derive(Fail, Debug)] pub enum ServiceError { #[fail(display = "Internal Server Error")] @@ -20,9 +19,14 @@ pub enum ServiceError { impl ResponseError for ServiceError { fn error_response(&self) -> HttpResponse { match *self { - ServiceError::InternalServerError => HttpResponse::InternalServerError().json("Internal Server Error, Please try later"), - ServiceError::BadRequest(ref message) => HttpResponse::BadRequest().json(message), - ServiceError::Unauthorized => HttpResponse::Unauthorized().json("Unauthorized") + ServiceError::InternalServerError => HttpResponse::InternalServerError() + .json("Internal Server Error, Please try later"), + ServiceError::BadRequest(ref message) => { + HttpResponse::BadRequest().json(message) + } + ServiceError::Unauthorized => { + HttpResponse::Unauthorized().json("Unauthorized") + } } } } @@ -42,12 +46,13 @@ impl From for ServiceError { match error { Error::DatabaseError(kind, info) => { if let DatabaseErrorKind::UniqueViolation = kind { - let message = info.details().unwrap_or_else(|| info.message()).to_string(); + let message = + info.details().unwrap_or_else(|| info.message()).to_string(); return ServiceError::BadRequest(message); } ServiceError::InternalServerError } - _ => ServiceError::InternalServerError + _ => ServiceError::InternalServerError, } } } diff --git a/simple-auth-server/src/invitation_handler.rs b/simple-auth-server/src/invitation_handler.rs index 425e4c0..ac117f7 100644 --- a/simple-auth-server/src/invitation_handler.rs +++ b/simple-auth-server/src/invitation_handler.rs @@ -35,5 +35,3 @@ impl Handler for DbExecutor { Ok(inserted_invitation) } } - - diff --git a/simple-auth-server/src/invitation_routes.rs b/simple-auth-server/src/invitation_routes.rs index 9232c6d..bd6a46c 100644 --- a/simple-auth-server/src/invitation_routes.rs +++ b/simple-auth-server/src/invitation_routes.rs @@ -1,4 +1,6 @@ -use actix_web::{AsyncResponder, FutureResponse, HttpResponse, Json, ResponseError, State}; +use actix_web::{ + AsyncResponder, FutureResponse, HttpResponse, Json, ResponseError, State, +}; use futures::future::Future; use app::AppState; @@ -18,5 +20,6 @@ pub fn register_email( Ok(HttpResponse::Ok().into()) } Err(err) => Ok(err.error_response()), - }).responder() + }) + .responder() } diff --git a/simple-auth-server/src/main.rs b/simple-auth-server/src/main.rs index f5d096b..5c1b3c2 100644 --- a/simple-auth-server/src/main.rs +++ b/simple-auth-server/src/main.rs @@ -1,18 +1,18 @@ // to avoid the warning from diesel macros #![allow(proc_macro_derive_resolution_fallback)] -extern crate bcrypt; extern crate actix; extern crate actix_web; -extern crate env_logger; -extern crate serde; +extern crate bcrypt; extern crate chrono; extern crate dotenv; +extern crate env_logger; extern crate futures; -extern crate r2d2; -extern crate uuid; extern crate jsonwebtoken as jwt; +extern crate r2d2; +extern crate serde; extern crate sparkpost; +extern crate uuid; #[macro_use] extern crate diesel; #[macro_use] @@ -21,26 +21,25 @@ extern crate serde_derive; extern crate failure; mod app; -mod models; -mod schema; -mod errors; mod auth_handler; mod auth_routes; +mod email_service; +mod errors; mod invitation_handler; mod invitation_routes; +mod models; mod register_handler; mod register_routes; +mod schema; mod utils; -mod email_service; -use models::DbExecutor; use actix::prelude::*; use actix_web::server; use diesel::{r2d2::ConnectionManager, PgConnection}; use dotenv::dotenv; +use models::DbExecutor; use std::env; - fn main() { dotenv().ok(); std::env::set_var("RUST_LOG", "simple-auth-server=debug,actix_web=info"); @@ -55,7 +54,8 @@ fn main() { .build(manager) .expect("Failed to create pool."); - let address: Addr = SyncArbiter::start(4, move || DbExecutor(pool.clone())); + let address: Addr = + SyncArbiter::start(4, move || DbExecutor(pool.clone())); server::new(move || app::create_app(address.clone())) .bind("127.0.0.1:3000") diff --git a/simple-auth-server/src/models.rs b/simple-auth-server/src/models.rs index fcafb9c..651ad9f 100644 --- a/simple-auth-server/src/models.rs +++ b/simple-auth-server/src/models.rs @@ -1,11 +1,11 @@ use actix::{Actor, SyncContext}; +use chrono::{Local, NaiveDateTime}; use diesel::pg::PgConnection; use diesel::r2d2::{ConnectionManager, Pool}; -use chrono::{NaiveDateTime, Local}; -use uuid::Uuid; use std::convert::From; +use uuid::Uuid; -use schema::{users, invitations}; +use schema::{invitations, users}; /// This is db executor actor. can be run in parallel pub struct DbExecutor(pub Pool>); @@ -51,8 +51,6 @@ pub struct SlimUser { impl From for SlimUser { fn from(user: User) -> Self { - SlimUser { - email: user.email - } + SlimUser { email: user.email } } } diff --git a/simple-auth-server/src/register_handler.rs b/simple-auth-server/src/register_handler.rs index 7cf98fd..961061b 100644 --- a/simple-auth-server/src/register_handler.rs +++ b/simple-auth-server/src/register_handler.rs @@ -2,9 +2,9 @@ use actix::{Handler, Message}; use chrono::Local; use diesel::prelude::*; use errors::ServiceError; -use models::{DbExecutor, Invitation, User, SlimUser}; -use uuid::Uuid; +use models::{DbExecutor, Invitation, SlimUser, User}; use utils::hash_password; +use uuid::Uuid; // UserData is used to extract data from a post request by the client #[derive(Debug, Deserialize)] @@ -23,11 +23,10 @@ impl Message for RegisterUser { type Result = Result; } - impl Handler for DbExecutor { type Result = Result; fn handle(&mut self, msg: RegisterUser, _: &mut Self::Context) -> Self::Result { - use schema::invitations::dsl::{invitations, id}; + use schema::invitations::dsl::{id, invitations}; use schema::users::dsl::users; let conn: &PgConnection = &self.0.get().unwrap(); @@ -35,7 +34,8 @@ impl Handler for DbExecutor { // return early with error that will be converted to ServiceError let invitation_id = Uuid::parse_str(&msg.invitation_id)?; - invitations.filter(id.eq(invitation_id)) + invitations + .filter(id.eq(invitation_id)) .load::(conn) .map_err(|_db_error| ServiceError::BadRequest("Invalid Invitation".into())) .and_then(|mut result| { @@ -45,9 +45,8 @@ impl Handler for DbExecutor { // try hashing the password, else return the error that will be converted to ServiceError let password: String = hash_password(&msg.password)?; let user = User::with_details(invitation.email, password); - let inserted_user: User = diesel::insert_into(users) - .values(&user) - .get_result(conn)?; + let inserted_user: User = + diesel::insert_into(users).values(&user).get_result(conn)?; return Ok(inserted_user.into()); } @@ -56,5 +55,3 @@ impl Handler for DbExecutor { }) } } - - diff --git a/simple-auth-server/src/register_routes.rs b/simple-auth-server/src/register_routes.rs index 5924ba5..79b9f9a 100644 --- a/simple-auth-server/src/register_routes.rs +++ b/simple-auth-server/src/register_routes.rs @@ -1,22 +1,27 @@ -use actix_web::{AsyncResponder, FutureResponse, HttpResponse, ResponseError, State, Json, Path}; +use actix_web::{ + AsyncResponder, FutureResponse, HttpResponse, Json, Path, ResponseError, State, +}; use futures::future::Future; use app::AppState; use register_handler::{RegisterUser, UserData}; - -pub fn register_user((invitation_id, user_data, state): (Path, Json, State)) - -> FutureResponse { +pub fn register_user( + (invitation_id, user_data, state): (Path, Json, State), +) -> FutureResponse { let msg = RegisterUser { // into_inner() returns the inner string value from Path invitation_id: invitation_id.into_inner(), password: user_data.password.clone(), }; - state.db.send(msg) + state + .db + .send(msg) .from_err() .and_then(|db_response| match db_response { Ok(slim_user) => Ok(HttpResponse::Ok().json(slim_user)), Err(service_error) => Ok(service_error.error_response()), - }).responder() + }) + .responder() } diff --git a/simple-auth-server/src/schema.rs b/simple-auth-server/src/schema.rs index 646632d..95c3703 100644 --- a/simple-auth-server/src/schema.rs +++ b/simple-auth-server/src/schema.rs @@ -14,7 +14,4 @@ table! { } } -allow_tables_to_appear_in_same_query!( - invitations, - users, -); +allow_tables_to_appear_in_same_query!(invitations, users,); diff --git a/static_index/src/main.rs b/static_index/src/main.rs index 25c77c0..df6233d 100644 --- a/static_index/src/main.rs +++ b/static_index/src/main.rs @@ -13,15 +13,18 @@ fn main() { server::new(|| { App::new() - // enable logger - .middleware(middleware::Logger::default()) - .handler( + // enable logger + .middleware(middleware::Logger::default()) + .handler( "/", - fs::StaticFiles::new("./static/").unwrap().index_file("index.html") + fs::StaticFiles::new("./static/") + .unwrap() + .index_file("index.html"), ) - }).bind("127.0.0.1:8080") - .expect("Can not start server on given IP/Port") - .start(); + }) + .bind("127.0.0.1:8080") + .expect("Can not start server on given IP/Port") + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/template_askama/src/main.rs b/template_askama/src/main.rs index 4a34abf..27dc761 100644 --- a/template_askama/src/main.rs +++ b/template_askama/src/main.rs @@ -24,8 +24,9 @@ fn index(query: Query>) -> Result { UserTemplate { name: name, text: "Welcome!", - }.render() - .unwrap() + } + .render() + .unwrap() } else { Index.render().unwrap() }; @@ -38,9 +39,10 @@ fn main() { // start http server server::new(move || { App::new().resource("/", |r| r.method(http::Method::GET).with(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/template_tera/src/main.rs b/template_tera/src/main.rs index e7e2c78..7cbd557 100644 --- a/template_tera/src/main.rs +++ b/template_tera/src/main.rs @@ -44,13 +44,14 @@ fn main() { let tera = compile_templates!(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")); - App::with_state(AppState{template: tera}) + App::with_state(AppState { template: tera }) // enable logger .middleware(middleware::Logger::default()) .resource("/", |r| r.method(http::Method::GET).with(index)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/unix-socket/src/main.rs b/unix-socket/src/main.rs index d999f8e..6a3e3ed 100644 --- a/unix-socket/src/main.rs +++ b/unix-socket/src/main.rs @@ -23,7 +23,8 @@ fn main() { .middleware(middleware::Logger::default()) .resource("/index.html", |r| r.f(|_| "Hello world!")) .resource("/", |r| r.f(index)) - }).start_incoming(listener.incoming(), false); + }) + .start_incoming(listener.incoming(), false); println!("Started http server: /tmp/actix-uds.socket"); let _ = sys.run(); diff --git a/web-cors/backend/src/main.rs b/web-cors/backend/src/main.rs index 8191cee..2fcec25 100644 --- a/web-cors/backend/src/main.rs +++ b/web-cors/backend/src/main.rs @@ -39,10 +39,11 @@ fn main() { }) .register() }) - }).bind("127.0.0.1:8000") - .unwrap() - .shutdown_timeout(2) - .start(); + }) + .bind("127.0.0.1:8000") + .unwrap() + .shutdown_timeout(2) + .start(); let _ = sys.run(); } diff --git a/websocket-chat-broker/src/main.rs b/websocket-chat-broker/src/main.rs index 24ae492..4ddc3bc 100644 --- a/websocket-chat-broker/src/main.rs +++ b/websocket-chat-broker/src/main.rs @@ -52,7 +52,8 @@ impl WsChatSession { } fut::ok(()) - }).spawn(ctx); + }) + .spawn(ctx); } fn list_rooms(&mut self, ctx: &mut ws::WebsocketContext) { @@ -66,7 +67,8 @@ impl WsChatSession { } } fut::ok(()) - }).spawn(ctx); + }) + .spawn(ctx); } fn send_msg(&self, msg: &str) { @@ -158,7 +160,8 @@ fn main() { .unwrap() .index_file("index.html"), ) - }).bind("127.0.0.1:8080") + }) + .bind("127.0.0.1:8080") .unwrap() .start(); diff --git a/websocket-chat/src/main.rs b/websocket-chat/src/main.rs index 477b8e4..8849aba 100644 --- a/websocket-chat/src/main.rs +++ b/websocket-chat/src/main.rs @@ -12,7 +12,7 @@ extern crate tokio_io; extern crate actix; extern crate actix_web; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; use actix::*; use actix_web::server::HttpServer; @@ -185,7 +185,7 @@ impl StreamHandler for WsChatSession { ws::Message::Binary(bin) => println!("Unexpected binary"), ws::Message::Close(_) => { ctx.stop(); - }, + } } } } @@ -202,9 +202,7 @@ impl WsChatSession { println!("Websocket Client heartbeat failed, disconnecting!"); // notify chat server - ctx.state() - .addr - .do_send(server::Disconnect { id: act.id }); + ctx.state().addr.do_send(server::Disconnect { id: act.id }); // stop actor ctx.stop(); @@ -233,19 +231,22 @@ fn main() { }; App::with_state(state) - // redirect to websocket.html - .resource("/", |r| r.method(http::Method::GET).f(|_| { - HttpResponse::Found() - .header("LOCATION", "/static/websocket.html") - .finish() - })) - // websocket + // redirect to websocket.html + .resource("/", |r| { + r.method(http::Method::GET).f(|_| { + HttpResponse::Found() + .header("LOCATION", "/static/websocket.html") + .finish() + }) + }) + // websocket .resource("/ws/", |r| r.route().f(chat_route)) - // static resources + // static resources .handler("/static/", fs::StaticFiles::new("static/").unwrap()) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/websocket-tcp-chat/src/codec.rs b/websocket-tcp-chat/src/codec.rs index 55cf0db..8d36263 100644 --- a/websocket-tcp-chat/src/codec.rs +++ b/websocket-tcp-chat/src/codec.rs @@ -65,7 +65,9 @@ impl Encoder for ChatCodec { type Error = io::Error; fn encode( - &mut self, msg: ChatResponse, dst: &mut BytesMut, + &mut self, + msg: ChatResponse, + dst: &mut BytesMut, ) -> Result<(), Self::Error> { let msg = json::to_string(&msg).unwrap(); let msg_ref: &[u8] = msg.as_ref(); @@ -108,7 +110,9 @@ impl Encoder for ClientChatCodec { type Error = io::Error; fn encode( - &mut self, msg: ChatRequest, dst: &mut BytesMut, + &mut self, + msg: ChatRequest, + dst: &mut BytesMut, ) -> Result<(), Self::Error> { let msg = json::to_string(&msg).unwrap(); let msg_ref: &[u8] = msg.as_ref(); diff --git a/websocket-tcp-chat/src/main.rs b/websocket-tcp-chat/src/main.rs index 099ba8d..dff734c 100644 --- a/websocket-tcp-chat/src/main.rs +++ b/websocket-tcp-chat/src/main.rs @@ -19,7 +19,7 @@ extern crate actix_web; use actix::*; use actix_web::server::HttpServer; use actix_web::{fs, http, ws, App, Error, HttpRequest, HttpResponse}; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; mod codec; mod server; @@ -191,7 +191,7 @@ impl StreamHandler for WsChatSession { ws::Message::Binary(bin) => println!("Unexpected binary"), ws::Message::Close(_) => { ctx.stop(); - }, + } } } } @@ -208,9 +208,7 @@ impl WsChatSession { println!("Websocket Client heartbeat failed, disconnecting!"); // notify chat server - ctx.state() - .addr - .do_send(server::Disconnect { id: act.id }); + ctx.state().addr.do_send(server::Disconnect { id: act.id }); // stop actor ctx.stop(); @@ -247,18 +245,21 @@ fn main() { App::with_state(state) // redirect to websocket.html - .resource("/", |r| r.method(http::Method::GET).f(|_| { - HttpResponse::Found() - .header("LOCATION", "/static/websocket.html") - .finish() - })) + .resource("/", |r| { + r.method(http::Method::GET).f(|_| { + HttpResponse::Found() + .header("LOCATION", "/static/websocket.html") + .finish() + }) + }) // websocket .resource("/ws/", |r| r.route().f(chat_route)) // static resources .handler("/static/", fs::StaticFiles::new("static/").unwrap()) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run(); diff --git a/websocket/src/main.rs b/websocket/src/main.rs index 84aa464..0b9a571 100644 --- a/websocket/src/main.rs +++ b/websocket/src/main.rs @@ -8,7 +8,7 @@ extern crate actix; extern crate actix_web; extern crate env_logger; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; use actix::prelude::*; use actix_web::{ @@ -96,19 +96,24 @@ fn main() { env_logger::init(); let sys = actix::System::new("ws-example"); - server::new( - || App::new() + server::new(|| { + App::new() // enable logger .middleware(middleware::Logger::default()) // websocket route .resource("/ws/", |r| r.method(http::Method::GET).f(ws_index)) // static files - .handler("/", fs::StaticFiles::new("static/") - .unwrap() - .index_file("index.html"))) - // start http server on 127.0.0.1:8080 - .bind("127.0.0.1:8080").unwrap() - .start(); + .handler( + "/", + fs::StaticFiles::new("static/") + .unwrap() + .index_file("index.html"), + ) + }) + // start http server on 127.0.0.1:8080 + .bind("127.0.0.1:8080") + .unwrap() + .start(); println!("Started http server: 127.0.0.1:8080"); let _ = sys.run();