1 pub mod pb { 2 tonic::include_proto!("grpc.examples.echo"); 3 } 4 5 use futures::Stream; 6 use pb::{EchoRequest, EchoResponse}; 7 use std::pin::Pin; 8 use tonic::{metadata::MetadataValue, transport::Server, Request, Response, Status, Streaming}; 9 10 type EchoResult<T> = Result<Response<T>, Status>; 11 type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>; 12 13 #[derive(Default)] 14 pub struct EchoServer; 15 16 #[tonic::async_trait] 17 impl pb::echo_server::Echo for EchoServer { 18 async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> { 19 let message = request.into_inner().message; 20 Ok(Response::new(EchoResponse { message })) 21 } 22 23 type ServerStreamingEchoStream = ResponseStream; 24 25 async fn server_streaming_echo( 26 &self, 27 _: Request<EchoRequest>, 28 ) -> EchoResult<Self::ServerStreamingEchoStream> { 29 Err(Status::unimplemented("not implemented")) 30 } 31 32 async fn client_streaming_echo( 33 &self, 34 _: Request<Streaming<EchoRequest>>, 35 ) -> EchoResult<EchoResponse> { 36 Err(Status::unimplemented("not implemented")) 37 } 38 39 type BidirectionalStreamingEchoStream = ResponseStream; 40 41 async fn bidirectional_streaming_echo( 42 &self, 43 _: Request<Streaming<EchoRequest>>, 44 ) -> EchoResult<Self::BidirectionalStreamingEchoStream> { 45 Err(Status::unimplemented("not implemented")) 46 } 47 } 48 49 #[tokio::main] 50 async fn main() -> Result<(), Box<dyn std::error::Error>> { 51 let addr = "[::1]:50051".parse().unwrap(); 52 let server = EchoServer::default(); 53 54 let svc = pb::echo_server::EchoServer::with_interceptor(server, check_auth); 55 56 Server::builder().add_service(svc).serve(addr).await?; 57 58 Ok(()) 59 } 60 61 fn check_auth(req: Request<()>) -> Result<Request<()>, Status> { 62 let token = MetadataValue::from_str("Bearer some-secret-token").unwrap(); 63 64 match req.metadata().get("authorization") { 65 Some(t) if token == t => Ok(req), 66 _ => Err(Status::unauthenticated("No valid auth token")), 67 } 68 } 69