rest-server: PeerAddr trait, drop proxmox-http dep

We pulled in proxmox-http with the client feature solely to
implement the `Service` trait on
`SslStream<RateLimitedStream<TcpStream>>`.

All those `Service` impls are the same: provide a peer
address and return an `ApiService`.
Let's put the `peer_addr()` call into a trait and build from
there.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2023-01-24 11:15:22 +01:00
parent 01436ae30f
commit e377909bee
2 changed files with 24 additions and 66 deletions

View File

@ -38,7 +38,6 @@ proxmox-async.workspace = true
proxmox-compression.workspace = true proxmox-compression.workspace = true
proxmox-io.workspace = true proxmox-io.workspace = true
proxmox-lang.workspace = true proxmox-lang.workspace = true
proxmox-http = { workspace = true, features = [ "client" ] }
proxmox-router.workspace = true proxmox-router.workspace = true
proxmox-schema = { workspace = true, features = [ "api-macro", "upid-api-impl" ] } proxmox-schema = { workspace = true, features = [ "api-macro", "upid-api-impl" ] }
proxmox-time.workspace = true proxmox-time.workspace = true

View File

@ -28,8 +28,6 @@ use proxmox_router::{
}; };
use proxmox_schema::{ObjectSchemaType, ParameterSchema}; use proxmox_schema::{ObjectSchemaType, ParameterSchema};
use proxmox_http::client::RateLimitedStream;
use proxmox_async::stream::AsyncReaderStream; use proxmox_async::stream::AsyncReaderStream;
use proxmox_compression::{DeflateEncoder, Level}; use proxmox_compression::{DeflateEncoder, Level};
@ -78,9 +76,7 @@ impl RestServer {
} }
} }
impl Service<&Pin<Box<tokio_openssl::SslStream<RateLimitedStream<tokio::net::TcpStream>>>>> impl<T: PeerAddress> Service<&T> for RestServer {
for RestServer
{
type Response = ApiService; type Response = ApiService;
type Error = Error; type Error = Error;
type Future = Pin<Box<dyn Future<Output = Result<ApiService, Error>> + Send>>; type Future = Pin<Box<dyn Future<Output = Result<ApiService, Error>> + Send>>;
@ -89,82 +85,45 @@ impl Service<&Pin<Box<tokio_openssl::SslStream<RateLimitedStream<tokio::net::Tcp
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn call( fn call(&mut self, ctx: &T) -> Self::Future {
&mut self, let result = match ctx.peer_addr() {
ctx: &Pin<Box<tokio_openssl::SslStream<RateLimitedStream<tokio::net::TcpStream>>>>, Err(err) => Err(format_err!("unable to get peer address - {}", err)),
) -> Self::Future { Ok(peer) => Ok(ApiService {
match ctx.get_ref().peer_addr() {
Err(err) => future::err(format_err!("unable to get peer address - {}", err)).boxed(),
Ok(peer) => future::ok(ApiService {
peer, peer,
api_config: self.api_config.clone(), api_config: self.api_config.clone(),
}) }),
.boxed(), };
} Box::pin(async move { result })
} }
} }
impl Service<&Pin<Box<tokio_openssl::SslStream<tokio::net::TcpStream>>>> for RestServer { pub trait PeerAddress {
type Response = ApiService; fn peer_addr(&self) -> Result<std::net::SocketAddr, Error>;
type Error = Error; }
type Future = Pin<Box<dyn Future<Output = Result<ApiService, Error>> + Send>>;
fn poll_ready(&mut self, _cx: &mut Context) -> Poll<Result<(), Self::Error>> { impl<T: PeerAddress> PeerAddress for tokio_openssl::SslStream<T> {
Poll::Ready(Ok(())) fn peer_addr(&self) -> Result<std::net::SocketAddr, Error> {
} self.get_ref().peer_addr()
fn call(
&mut self,
ctx: &Pin<Box<tokio_openssl::SslStream<tokio::net::TcpStream>>>,
) -> Self::Future {
match ctx.get_ref().peer_addr() {
Err(err) => future::err(format_err!("unable to get peer address - {}", err)).boxed(),
Ok(peer) => future::ok(ApiService {
peer,
api_config: self.api_config.clone(),
})
.boxed(),
}
} }
} }
impl Service<&hyper::server::conn::AddrStream> for RestServer { impl PeerAddress for tokio::net::TcpStream {
type Response = ApiService; fn peer_addr(&self) -> Result<std::net::SocketAddr, Error> {
type Error = Error; Ok(self.peer_addr()?)
type Future = Pin<Box<dyn Future<Output = Result<ApiService, Error>> + Send>>;
fn poll_ready(&mut self, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, ctx: &hyper::server::conn::AddrStream) -> Self::Future {
let peer = ctx.remote_addr();
future::ok(ApiService {
peer,
api_config: self.api_config.clone(),
})
.boxed()
} }
} }
impl Service<&tokio::net::UnixStream> for RestServer { impl PeerAddress for hyper::server::conn::AddrStream {
type Response = ApiService; fn peer_addr(&self) -> Result<std::net::SocketAddr, Error> {
type Error = Error; Ok(self.remote_addr())
type Future = Pin<Box<dyn Future<Output = Result<ApiService, Error>> + Send>>;
fn poll_ready(&mut self, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
} }
}
fn call(&mut self, _ctx: &tokio::net::UnixStream) -> Self::Future { impl PeerAddress for tokio::net::UnixStream {
fn peer_addr(&self) -> Result<std::net::SocketAddr, Error> {
// TODO: Find a way to actually represent the vsock peer in the ApiService struct - for now // TODO: Find a way to actually represent the vsock peer in the ApiService struct - for now
// it doesn't really matter, so just use a fake IP address // it doesn't really matter, so just use a fake IP address
let fake_peer = "0.0.0.0:807".parse().unwrap(); Ok(([0, 0, 0, 0], 807).into())
future::ok(ApiService {
peer: fake_peer,
api_config: self.api_config.clone(),
})
.boxed()
} }
} }