tower_allowed_hosts

Crates.iotower_allowed_hosts
lib.rstower_allowed_hosts
version0.8.0
sourcesrc
created_at2023-08-07 14:01:16.379865
updated_at2024-10-14 11:26:37.79156
descriptiontower allowed hosts layer
homepagehttps://github.com/iamsauravsharma/tower_allowed_hosts
repositoryhttps://github.com/iamsauravsharma/tower_allowed_hosts
max_upload_size
id937956
size32,342
Saurav Sharma (iamsauravsharma)

documentation

README

TOWER ALLOWED HOSTS

Project status & info:

License Crates Version Docs
License: MIT Crate Docs

Tower service which limits request from only specified hosts All hostnames are automatically converted to lowercase before matching.

Add as dependencies

In your Cargo.toml file, add tower_allowed_hosts as a dependency:

[dependencies]
tower_allowed_hosts = "0.8.0"

Usage

Basic

To restrict access to specific basic hosts, you can use the following code:

let tower_layer = tower_allowed_hosts::AllowedHostLayer::default()
    .extend_hosts(&["127.0.0.1".to_string()]);

Wildcard

If you need wildcard-based host matching, enable the wildcard feature in your Cargo.toml:

[dependencies]
tower_allowed_hosts = { version = "0.8.0", features = ["wildcard"] }

You can then restrict hosts using wildcards:

let tower_layer = tower_allowed_hosts::AllowedHostLayer::default()
    .extend_hosts(&[wildmatch::WildMatch::new("127.0.0.*")]);

Regex

If you need regex-based host matching, enable the regex feature in your Cargo.toml:

[dependencies]
tower_allowed_hosts = { version = "0.8.0", features = ["regex"] }

You can then restrict hosts using regex patterns:

let tower_layer = tower_allowed_hosts::AllowedHostLayer::new(&[regex::Regex::new("^127.0.0.1$")?]);

Integrating with a Tower-Compatible Library

After creating the AllowedHostLayer, it can be integrated into any library that supports tower components. Here's an example of how to use this layer in an axum application. You will also need to handle errors properly using HandleErrorLayer:

use axum::{
    error_handling::HandleErrorLayer,
    http::StatusCode,
    Router
};
use tower::ServiceBuilder;
use tower_allowed_hosts::AllowedHostLayer;

fn router() -> Router {
    let handle_error_layer = HandleErrorLayer::new(handle_box_error);

    let allowed_hosts_layer = AllowedHostLayer::default()
        .extend_hosts(&[wildmatch::WildMatch::new("127.0.0.*")]);

     let layer = ServiceBuilder::new()
        .layer(handle_error_layer)
        .layer(allowed_hosts_layer);

    Router::new().layer(layer)
}

async fn handle_box_error(err: tower::BoxError) -> (StatusCode, String) {
    if err.is::<tower_allowed_hosts::error::Error>() {
        return (StatusCode::BAD_REQUEST, err.to_string());
    }
    return (StatusCode::INTERNAL_SERVER_ERROR, "".to_string())
}

There is also extension added after successfully parsing allowed host and allowing host which can be access using tower_allowed_hosts::Host struct Extension

Commit count: 61

cargo fmt