use rama_core::extensions::{Extensions, ExtensionsRef};
use rama_core::matcher::Matcher;
use rama_net::address::SocketAddress;
use rama_net::stream::matcher::{
IpNetMatcher, LoopbackMatcher, PortMatcher, PrivateIpNetMatcher, SocketAddressMatcher,
SocketMatcher,
};
use rama_net::stream::{Socket, SocketInfo};
use crate::Request;
struct PeerSocket(Option<SocketAddress>);
impl Socket for PeerSocket {
#[inline]
fn local_addr(&self) -> std::io::Result<SocketAddress> {
Err(std::io::Error::from(std::io::ErrorKind::AddrNotAvailable))
}
#[inline]
fn peer_addr(&self) -> std::io::Result<SocketAddress> {
self.0
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::AddrNotAvailable))
}
}
macro_rules! impl_request_matcher {
($matcher:ty) => {
impl<Body> Matcher<Request<Body>> for $matcher {
fn matches(&self, _ext: Option<&Extensions>, req: &Request<Body>) -> bool {
let peer = req
.extensions()
.get_ref::<SocketInfo>()
.map(|info| info.peer_addr());
self.matches(None, &PeerSocket(peer))
}
}
};
}
impl_request_matcher!(SocketAddressMatcher);
impl_request_matcher!(IpNetMatcher);
impl_request_matcher!(LoopbackMatcher);
impl_request_matcher!(PortMatcher);
impl_request_matcher!(PrivateIpNetMatcher);
impl<Body: 'static> Matcher<Request<Body>> for SocketMatcher<Request<Body>> {
fn matches(&self, ext: Option<&Extensions>, req: &Request<Body>) -> bool {
self.matches_input(ext, req)
}
}