Skip to content

Commit

Permalink
refactor: renamed Chain struct to Middlewares
Browse files Browse the repository at this point in the history
- Improve documentation and fix all doc examples
- Update dependencies
- msrv 1.56.0
  • Loading branch information
joseluisq committed Feb 5, 2024
1 parent 2ac7019 commit 0adf49b
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 110 deletions.
21 changes: 16 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ authors = ["Jose Quintana <https://joseluisq.net>"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/static-web-server/hyper-middleware"
documentation = "https://docs.rs/hyper-middleware"
edition = "2018"
edition = "2021"
rust-version = "1.56.0"
categories = ["network-programming", "web-programming::http-server"]
include = [
"src/**/*.rs",
Expand All @@ -25,12 +26,22 @@ keywords = [
]

[dependencies]
hyper = { version = "0.14.27", default-features = false, features = ["server", "tcp"] }
anyhow = "1.0.75"
thiserror = "1.0.50"
async-trait = "0.1.74"
hyper = { version = "0.14.28", default-features = false, features = ["server", "tcp"] }
anyhow = "1.0.79"
thiserror = "1.0.56"
async-trait = "0.1.77"
async-recursion = "1.0.5"

[dev-dependencies]
hyper = { version = "0.14", features = ["tcp", "server", "http1"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros"], default-features = false }

[profile.release]
codegen-units = 1
debug = false
debug-assertions = false
lto = "fat"
opt-level = 3
panic = "abort"
rpath = false
strip = true
47 changes: 23 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
- Compact Middleware and Handler System inspired by [The Iron Framework](https://github.com/iron/iron).
- Simple [Hyper Service](https://docs.rs/hyper/latest/hyper/service/trait.Service.html) with convenient __Remote Address__ access.
- Convenient `Error` and `Result` types powered by [anyhow](https://github.com/dtolnay/anyhow).
- `Async` support via [async-trait](https://github.com/dtolnay/async-trait).
- Macros to facilitate HTTP response errors or error casting.

## Example

[examples/server.rs](examples/server.rs)

```rust
#![deny(warnings)]

use hyper::{header, Server, StatusCode};
use std::{net::SocketAddr, path::PathBuf};
use hyper_middleware::{
async_trait, AfterMiddleware, BeforeMiddleware, Body, Chain, Error, Handler, Request, Response,
Result, Service,
async_trait, AfterMiddleware, BeforeMiddleware, Body, Error, Handler, Middlewares, Request,
Response, Result, Service,
};
use std::{net::SocketAddr, path::PathBuf};

struct Config {
pub root: PathBuf,
Expand All @@ -39,17 +39,18 @@ struct Application {
impl Handler for Application {
async fn handle(&self, req: &mut Request) -> Result<Response> {
// Access the Hyper incoming Request
println!("Handler - URI Path: {}", req.uri().path());
println!("Application::handle() - URI Path: {}", req.uri().path());

// Access the custom app options
println!("Config Root: {}", self.opts.root.display());

// Access the Remote Address
println!(
"Remote Addr: {}",
req.extensions().get::<SocketAddr>().unwrap()
"Application::handle() - Config Root: {}",
self.opts.root.display()
);

// Access the Remote Address
let remote_addr = req.extensions().get::<SocketAddr>().unwrap();
println!("Application::handle() - Remote Addr: {}", remote_addr);

// Create a Hyper Response and send it back to the middlewares chain
Ok(Response::new(Body::from("¡Hola!")))
}
Expand All @@ -60,10 +61,10 @@ struct FirstMiddleware {}
#[async_trait]
impl BeforeMiddleware for FirstMiddleware {
async fn before(&self, req: &mut Request) -> Result {
println!("First Middleware called!");
println!("FirstMiddleware::before()");

// Access the Hyper incoming Request
println!("First - URI Path: {}", req.uri().path());
println!("FirstMiddleware::before() - URI Path: {}", req.uri().path());

Ok(())
}
Expand All @@ -78,7 +79,7 @@ struct SecondMiddleware {}
#[async_trait]
impl AfterMiddleware for SecondMiddleware {
async fn after(&self, _: &mut Request, mut res: Response) -> Result<Response> {
println!("Second Middleware called!");
println!("SecondMiddleware::after()");

// Mutate the Hyper Response at convenience
// and send it back to other middlewares on the chain
Expand All @@ -105,17 +106,15 @@ async fn main() -> Result {
root: std::env::current_dir().unwrap(),
};

// 1. Create a custom middleware chain
let mut handler = Chain::new(Application { opts });
// 1. Create a custom middleware chain and plug in some custom middlewares
let mut middlewares = Middlewares::new(Application { opts });
middlewares.link_before(FirstMiddleware {});
middlewares.link_after(SecondMiddleware {});

// 2. Plug in some custom middlewares
handler.link_before(FirstMiddleware {});
handler.link_after(SecondMiddleware {});
// 2. Create a Hyper service and set the current handler with its middlewares
let service = Service::new(middlewares);

// 3. Create a Hyper service and set the current handler with its middlewares
let service = Service::new(handler);

// 4. Finally just run server using the service already created
// 3. Finally just run server using the service already created
let addr = ([127, 0, 0, 1], 8787).into();
let server = Server::bind(&addr).serve(service);

Expand All @@ -129,7 +128,7 @@ async fn main() -> Result {

To run the example just type:

```
```sh
cargo run --example server
```

Expand Down
42 changes: 20 additions & 22 deletions examples/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
#![deny(dead_code)]

use hyper::{header, Server, StatusCode};
use std::{net::SocketAddr, path::PathBuf};

use hyper_middleware::{
async_trait, AfterMiddleware, BeforeMiddleware, Body, Chain, Error, Handler, Request, Response,
Result, Service,
async_trait, AfterMiddleware, BeforeMiddleware, Body, Error, Handler, Middlewares, Request,
Response, Result, Service,
};
use std::{net::SocketAddr, path::PathBuf};

struct Config {
pub root: PathBuf,
Expand All @@ -23,17 +22,18 @@ struct Application {
impl Handler for Application {
async fn handle(&self, req: &mut Request) -> Result<Response> {
// Access the Hyper incoming Request
println!("Handler - URI Path: {}", req.uri().path());
println!("Application::handle() - URI Path: {}", req.uri().path());

// Access the custom app options
println!("Config Root: {}", self.opts.root.display());

// Access the Remote Address
println!(
"Remote Addr: {}",
req.extensions().get::<SocketAddr>().unwrap()
"Application::handle() - Config Root: {}",
self.opts.root.display()
);

// Access the Remote Address
let remote_addr = req.extensions().get::<SocketAddr>().unwrap();
println!("Application::handle() - Remote Addr: {}", remote_addr);

// Create a Hyper Response and send it back to the middlewares chain
Ok(Response::new(Body::from("¡Hola!")))
}
Expand All @@ -44,10 +44,10 @@ struct FirstMiddleware {}
#[async_trait]
impl BeforeMiddleware for FirstMiddleware {
async fn before(&self, req: &mut Request) -> Result {
println!("First Middleware called!");
println!("FirstMiddleware::before()");

// Access the Hyper incoming Request
println!("First - URI Path: {}", req.uri().path());
println!("FirstMiddleware::before() - URI Path: {}", req.uri().path());

Ok(())
}
Expand All @@ -62,7 +62,7 @@ struct SecondMiddleware {}
#[async_trait]
impl AfterMiddleware for SecondMiddleware {
async fn after(&self, _: &mut Request, mut res: Response) -> Result<Response> {
println!("Second Middleware called!");
println!("SecondMiddleware::after()");

// Mutate the Hyper Response at convenience
// and send it back to other middlewares on the chain
Expand All @@ -89,17 +89,15 @@ async fn main() -> Result {
root: std::env::current_dir().unwrap(),
};

// 1. Create a custom middleware chain
let mut handler = Chain::new(Application { opts });

// 2. Plug in some custom middlewares
handler.link_before(FirstMiddleware {});
handler.link_after(SecondMiddleware {});
// 1. Create a custom middleware chain and plug in some custom middlewares
let mut middlewares = Middlewares::new(Application { opts });
middlewares.link_before(FirstMiddleware {});
middlewares.link_after(SecondMiddleware {});

// 3. Create a Hyper service and set the current handler with its middlewares
let service = Service::new(handler);
// 2. Create a Hyper service and set the current handler with its middlewares
let service = Service::new(middlewares);

// 4. Finally just run server using the service already created
// 3. Finally just run server using the service already created
let addr = ([127, 0, 0, 1], 8787).into();
let server = Server::bind(&addr).serve(service);

Expand Down
15 changes: 10 additions & 5 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! The custom error module.
//!
//! This module provides a custom [`Error`][`super::Error`] type with HTTP Status functionality as well as useful macros.
//! The `Error` type implements other several common error types
//! to ease conversions while consuming the input value via the [`From`] trait.
//! This module provides a custom [`Error`][`super::Error`] type with HTTP Status functionality as well as useful [macros][macros].
//! The `Error` type implements other several common error types as well
//! to ease conversion while consuming the input value via the [`From`] trait.
//!
//! Additionally, when used in HTTP contexts, the `Error` type can be associated to an [HTTP Status Code][`hyper::StatusCode`].
//! via the [`Error::with_status`][`super::Error::with_status`] method.
//!
//! a. Construct an [`Error`][`super::Error`] from [`hyper::Error`], [`std::io::Error`], [`anyhow::Error`] or an string.
//!
//! ```rust
//! use hyper_middleware::error
//! use hyper_middleware::{Error, error};
//!
//! let err = Error::from("some error type or string");
//! // Or using a shortcut macro
Expand All @@ -21,7 +21,7 @@
//!
//! ```rust
//! use hyper::StatusCode;
//! use hyper_middleware::error
//! use hyper_middleware::{error, http_error_unauthorized};
//!
//! let err = error!("user or password does not match").with_status(StatusCode::UNAUTHORIZED);
//! // Or using a shortcut macro
Expand All @@ -33,9 +33,14 @@ use hyper::StatusCode;
use std::fmt;
use thiserror::Error as ThisError;

/// Macros that provide several facilities for working with HTTP response errors or error casting.
pub mod macros;

/// `Result<T, Error>`
///
/// An alias of [anyhow::Result][anyhow::Result] with defaults.
pub type Result<T = (), E = Error> = anyhow::Result<T, E>;

pub use anyhow::Context;

/// Represents an HTTP Error.
Expand Down
4 changes: 2 additions & 2 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
/// A [`hyper::Body`] type alias.
pub type Body = hyper::Body;

/// A [`hyper::Request<Body>`] type alias.
/// A [`hyper::Request<Body>`] type alias with defaults.
pub type Request<T = Body> = hyper::Request<T>;

/// A [`hyper::Response<Body>`] type alias.
/// A [`hyper::Response<Body>`] type alias with defaults.
pub type Response<T = Body> = hyper::Response<T>;
17 changes: 14 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// #![deny(missing_docs)]
#![deny(missing_docs)]
#![forbid(unsafe_code)]
#![deny(warnings)]
#![deny(rust_2018_idioms)]
#![deny(dead_code)]
#![cfg_attr(docsrs, feature(doc_cfg))]

//! # hyper_middleware
//!
Expand All @@ -10,6 +15,10 @@
//! - Compact [Middleware & Handler System][`middleware`] inspired by [The Iron Framework](https://github.com/iron/iron).
//! - Simple [Hyper Service][`hyper::service::Service`] with [Remote Address][`hyper::server::conn::AddrStream`] access.
//! - Convenient [`Error`] and [`Result`] types powered by [anyhow](https://github.com/dtolnay/anyhow).
//! - `Async` support via [async-trait](https://github.com/dtolnay/async-trait).
//! - Macros to facilitate HTTP response errors or error casting.
//!
//! Check it out [middleware][`middleware`] module for more details.
//!

pub mod error;
Expand All @@ -18,10 +27,12 @@ pub mod middleware;
pub mod remote_addr;
pub mod service;

pub use async_recursion::*;
pub use async_trait::*;
pub use error::{Context, Error, Result};
pub use http::*;
pub use middleware::*;
pub use remote_addr::*;
pub use service::*;

// Re-export crates
pub use async_recursion::*;
pub use async_trait::*;
Loading

0 comments on commit 0adf49b

Please sign in to comment.