relay-core-lib 0.3.0

[Internal] Transport and interception engine for relay-core-runtime. Use `relay-core-runtime` instead.
Documentation
use crate::rule::model::{Filter, Rule, StringMatcher};
use crate::rule::engine::compiled::{CompiledRule, CompiledFilter, CompiledStringMatcher};
use ipnetwork::IpNetwork;
use regex::Regex;
use glob::Pattern;
use std::str::FromStr;

pub fn compile_rule(rule: Rule) -> CompiledRule {
    let filter = compile_filter(&rule.filter);
    CompiledRule {
        original: rule,
        filter,
    }
}

pub fn compile_filter(filter: &Filter) -> CompiledFilter {
    match filter {
        Filter::All => CompiledFilter::All,
        Filter::SrcIp(cidr) => IpNetwork::from_str(cidr).map(CompiledFilter::SrcIp).unwrap_or(CompiledFilter::Invalid),
        Filter::DstPort(p) => CompiledFilter::DstPort(*p),
        Filter::Protocol(p) => CompiledFilter::Protocol(p.clone()),
        Filter::TransparentMode(enabled) => CompiledFilter::TransparentMode(*enabled),
        Filter::Url(m) => CompiledFilter::Url(compile_matcher(m)),
        Filter::Host(m) => CompiledFilter::Host(compile_matcher(m)),
        Filter::Path(m) => CompiledFilter::Path(compile_matcher(m)),
        Filter::Method(m) => CompiledFilter::Method(compile_matcher(m)),
        Filter::RequestHeader { name, value } => CompiledFilter::RequestHeader {
            name: name.clone(),
            value: value.as_ref().map(compile_matcher),
        },
        Filter::ResponseHeader { name, value } => CompiledFilter::ResponseHeader {
            name: name.clone(),
            value: value.as_ref().map(compile_matcher),
        },
        Filter::StatusCode(c) => CompiledFilter::StatusCode(*c),
        Filter::ResponseBody(m) => CompiledFilter::ResponseBody(compile_matcher(m)),
        Filter::WebSocketMessage(m) => CompiledFilter::WebSocketMessage(compile_matcher(m)),
        Filter::And(filters) => CompiledFilter::And(filters.iter().map(compile_filter).collect()),
        Filter::Or(filters) => CompiledFilter::Or(filters.iter().map(compile_filter).collect()),
        Filter::Not(f) => CompiledFilter::Not(Box::new(compile_filter(f))),
    }
}

pub fn compile_matcher(matcher: &StringMatcher) -> CompiledStringMatcher {
    match matcher {
        StringMatcher::Exact(s) => CompiledStringMatcher::Exact(s.clone()),
        StringMatcher::Contains(s) => CompiledStringMatcher::Contains(s.clone()),
        StringMatcher::Prefix(s) => CompiledStringMatcher::Prefix(s.clone()),
        StringMatcher::Suffix(s) => CompiledStringMatcher::Suffix(s.clone()),
        StringMatcher::Regex(s) => Regex::new(s).map(CompiledStringMatcher::Regex).unwrap_or(CompiledStringMatcher::Invalid),
        StringMatcher::Glob(s) => Pattern::new(s).map(CompiledStringMatcher::Glob).unwrap_or(CompiledStringMatcher::Invalid),
    }
}