use std::net::SocketAddr; use bytes::{Buf, BufMut, Bytes, BytesMut}; use hyper::http::{header, StatusCode}; use hyper::{Body, Client, Method, Request, Uri}; use prost::Message; use tokio::net::TcpListener; use tokio_stream::wrappers::TcpListenerStream; use tonic::transport::Server; use integration::pb::{test_server::TestServer, Input, Output}; use integration::Svc; use tonic_web::GrpcWebLayer; #[tokio::test] async fn binary_request() { let server_url = spawn().await; let client = Client::new(); let req = build_request(server_url, "grpc-web", "grpc-web"); let res = client.request(req).await.unwrap(); let content_type = res.headers().get(header::CONTENT_TYPE).unwrap().clone(); let content_type = content_type.to_str().unwrap(); assert_eq!(res.status(), StatusCode::OK); assert_eq!(content_type, "application/grpc-web+proto"); let (message, trailers) = decode_body(res.into_body(), content_type).await; let expected = Output { id: 1, desc: "one".to_owned(), }; assert_eq!(message, expected); assert_eq!(&trailers[..], b"grpc-status:0\r\n"); } #[tokio::test] async fn text_request() { let server_url = spawn().await; let client = Client::new(); let req = build_request(server_url, "grpc-web-text", "grpc-web-text"); let res = client.request(req).await.unwrap(); let content_type = res.headers().get(header::CONTENT_TYPE).unwrap().clone(); let content_type = content_type.to_str().unwrap(); assert_eq!(res.status(), StatusCode::OK); assert_eq!(content_type, "application/grpc-web-text+proto"); let (message, trailers) = decode_body(res.into_body(), content_type).await; let expected = Output { id: 1, desc: "one".to_owned(), }; assert_eq!(message, expected); assert_eq!(&trailers[..], b"grpc-status:0\r\n"); } async fn spawn() -> String { let addr = SocketAddr::from(([127, 0, 0, 1], 0)); let listener = TcpListener::bind(addr).await.expect("listener"); let url = format!("http://{}", listener.local_addr().unwrap()); let listener_stream = TcpListenerStream::new(listener); let _ = tokio::spawn(async move { Server::builder() .accept_http1(true) .layer(GrpcWebLayer::new()) .add_service(TestServer::new(Svc)) .serve_with_incoming(listener_stream) .await .unwrap() }); url } fn encode_body() -> Bytes { let input = Input { id: 1, desc: "one".to_owned(), }; let mut buf = BytesMut::with_capacity(1024); buf.reserve(5); unsafe { buf.advance_mut(5); } input.encode(&mut buf).unwrap(); let len = buf.len() - 5; { let mut buf = &mut buf[..5]; buf.put_u8(0); buf.put_u32(len as u32); } buf.split_to(len + 5).freeze() } fn build_request(base_uri: String, content_type: &str, accept: &str) -> Request
{ use header::{ACCEPT, CONTENT_TYPE, ORIGIN}; let request_uri = format!("{}/{}/{}", base_uri, "test.Test", "UnaryCall") .parse::