1 use http::header::HeaderName; 2 use structopt::StructOpt; 3 use tonic::body::BoxBody; 4 use tonic::client::GrpcService; 5 use tonic::transport::Server; 6 use tonic::transport::{Identity, ServerTlsConfig}; 7 use tonic_interop::{server, MergeTrailers}; 8 9 #[derive(StructOpt)] 10 struct Opts { 11 #[structopt(long)] 12 use_tls: bool, 13 } 14 15 #[tokio::main] 16 async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> { 17 tonic_interop::trace_init(); 18 19 let matches = Opts::from_args(); 20 21 let addr = "127.0.0.1:10000".parse().unwrap(); 22 23 let mut builder = Server::builder().interceptor_fn(|svc, req| { 24 let echo_header = req 25 .headers() 26 .get("x-grpc-test-echo-initial") 27 .map(Clone::clone); 28 29 let echo_trailer = req 30 .headers() 31 .get("x-grpc-test-echo-trailing-bin") 32 .map(Clone::clone) 33 .map(|v| (HeaderName::from_static("x-grpc-test-echo-trailing-bin"), v)); 34 35 let call = svc.call(req); 36 37 async move { 38 let mut res = call.await?; 39 40 if let Some(echo_header) = echo_header { 41 res.headers_mut() 42 .insert("x-grpc-test-echo-initial", echo_header); 43 } 44 45 Ok(res 46 .map(|b| MergeTrailers::new(b, echo_trailer)) 47 .map(BoxBody::new)) 48 } 49 }); 50 51 if matches.use_tls { 52 let cert = tokio::fs::read("interop/data/server1.pem").await?; 53 let key = tokio::fs::read("interop/data/server1.key").await?; 54 let identity = Identity::from_pem(cert, key); 55 56 builder = builder.tls_config(ServerTlsConfig::new().identity(identity)); 57 } 58 59 let test_service = server::TestServiceServer::new(server::TestService::default()); 60 let unimplemented_service = 61 server::UnimplementedServiceServer::new(server::UnimplementedService::default()); 62 63 builder 64 .add_service(test_service) 65 .add_service(unimplemented_service) 66 .serve(addr) 67 .await?; 68 69 Ok(()) 70 } 71