Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: hyperium/tonic
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.7.1
Choose a base ref
...
head repository: hyperium/tonic
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.7.2
Choose a head ref
  • 13 commits
  • 23 files changed
  • 9 contributors

Commits on Apr 4, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9e0d21f View commit details

Commits on Apr 7, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    03fb09c View commit details

Commits on Apr 13, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b4f9634 View commit details

Commits on Apr 20, 2022

  1. fix(build): Reduce Default bound requirement (#974)

    Co-authored-by: David Pedersen <david.pdrsn@gmail.com>
    conradludgate and davidpdrsn authored Apr 20, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4533a6e View commit details

Commits on Apr 26, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fd596a8 View commit details

Commits on Apr 27, 2022

  1. chore: update tower-http (#985)

    * Update tower-http
    
    * one more update
    davidpdrsn authored Apr 27, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    13b55df View commit details
  2. chore: fix some typos (#984)

    Signed-off-by: cuishuang <imcusg@gmail.com>
    cuishuang authored Apr 27, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6d95473 View commit details

Commits on Apr 28, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2112ecc View commit details

Commits on May 2, 2022

  1. feat: Add TryFrom implementations for MetadataValue (#990)

    Co-authored-by: Adam Chalmers <adamschalmers@gmail.com>
    adamchalmers and Adam Chalmers authored May 2, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    edc5a0d View commit details

Commits on May 3, 2022

  1. tonic: Document Ascii and Binary (#993)

    This fixes the problem where MetadataValue::from<i16> (and other numeric types) aren't shown in Rustdoc, because they're implemented for Metadata<Ascii>, and Ascii is hidden.
    
    Co-authored-by: Adam Chalmers <adamschalmers@gmail.com>
    adamchalmers and Adam Chalmers authored May 3, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2e19b66 View commit details

Commits on May 4, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1dd5ad2 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6857c83 View commit details

Commits on May 5, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1b0b525 View commit details
3 changes: 3 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ jobs:
run: rustup component add rustfmt
- name: Install cargo-hack
run: cargo install cargo-hack
- uses: Swatinem/rust-cache@v1
- name: Check fmt
run: cargo fmt -- --check
- name: Check features
@@ -58,6 +59,7 @@ jobs:
rust-version: ${{ matrix.rust }}
- name: Install rustfmt
run: rustup component add rustfmt
- uses: Swatinem/rust-cache@v1
- uses: actions/checkout@master
- name: Run tests
run: cargo test --all --all-features
@@ -80,6 +82,7 @@ jobs:
- name: Install rustfmt
run: rustup component add rustfmt
- uses: actions/checkout@master
- uses: Swatinem/rust-cache@v1
- name: Run interop tests
run: ./interop/test.sh
shell: bash
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# [v0.7.2](https://github.com/hyperium/tonic/compare/v0.7.1...v0.7.2) (2022-05-04)


### Bug Fixes

* **build:** Reduce `Default` bound requirement ([#974](https://github.com/hyperium/tonic/issues/974)) ([4533a6e](https://github.com/hyperium/tonic/commit/4533a6e20eb889f8f13446c0edf39613fa4fe9f6))
* don't enable default features in tower ([#972](https://github.com/hyperium/tonic/issues/972)) ([b4f9634](https://github.com/hyperium/tonic/commit/b4f96343afe6106db80f41f49e576a687bfcd633))
* **transport:** Emit `HttpsUriWithoutTlsSupport` only with tls feature enabled ([#996](https://github.com/hyperium/tonic/issues/996)) ([1dd5ad2](https://github.com/hyperium/tonic/commit/1dd5ad2b07810fc6eb5015c152ec737b5f0ca39c))


### Features

* Add TryFrom implementations for MetadataValue ([#990](https://github.com/hyperium/tonic/issues/990)) ([edc5a0d](https://github.com/hyperium/tonic/commit/edc5a0d88d4a392effe065dfcc1c005b6bb55b5d))



# [0.7.1](https://github.com/hyperium/tonic/compare/v0.7.0...v0.7.1) (2022-04-04)

### Features
@@ -72,7 +88,7 @@

* **build:** Correctly convert `Empty` to `()` ([#734](https://github.com/hyperium/tonic/issues/734)) ([ff6a690](https://github.com/hyperium/tonic/commit/ff6a690cec9daca33984cabea66f9d370ac63462))
* **tonic:** fix extensions disappearing during streaming requests ([5c1bb90](https://github.com/hyperium/tonic/commit/5c1bb90ce82ecf90843a7c959edd7ef8fc280f62)), closes [#770](https://github.com/hyperium/tonic/issues/770)
* **tonic:** Status code to set correct source on unkown error ([#799](https://github.com/hyperium/tonic/issues/799)) ([4054d61](https://github.com/hyperium/tonic/commit/4054d61e14b9794a72b48de1a051c26129ec36b1))
* **tonic:** Status code to set correct source on unknown error ([#799](https://github.com/hyperium/tonic/issues/799)) ([4054d61](https://github.com/hyperium/tonic/commit/4054d61e14b9794a72b48de1a051c26129ec36b1))
* **transport:** AddOrigin panic on invalid uri ([#801](https://github.com/hyperium/tonic/issues/801)) ([3ab00f3](https://github.com/hyperium/tonic/commit/3ab00f304dd204fccf00d1995e635fa6b2f8503b))
* **transport:** Correctly map hyper errors ([#629](https://github.com/hyperium/tonic/issues/629)) ([4947b07](https://github.com/hyperium/tonic/commit/4947b076f5b0b5149ee7f6144515535b85f65db5))
* **tonic:** compression: handle compression flag but no header (#763)
13 changes: 13 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -54,10 +54,18 @@ path = "src/dynamic_load_balance/server.rs"
name = "tls-client"
path = "src/tls/client.rs"

[[bin]]
name = "tls-client-rustls"
path = "src/tls/client_rustls.rs"

[[bin]]
name = "tls-server"
path = "src/tls/server.rs"

[[bin]]
name = "tls-server-rustls"
path = "src/tls/server_rustls.rs"

[[bin]]
name = "tls-client-auth-server"
path = "src/tls_client_auth/server.rs"
@@ -214,6 +222,11 @@ tonic-web = { path = "../tonic-web" }
# streaming example
h2 = "0.3"

tokio-rustls = "*"
hyper-rustls = { version = "0.23", features = ["http2"] }
rustls-pemfile = "*"
tower-http = { version = "0.3", features = ["add-extension", "util"] }


[build-dependencies]
tonic-build = { path = "../tonic-build", features = ["prost", "compression"] }
2 changes: 1 addition & 1 deletion examples/src/authentication/client.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use tonic::{metadata::MetadataValue, transport::Channel, Request};
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let channel = Channel::from_static("http://[::1]:50051").connect().await?;

let token = MetadataValue::from_str("Bearer some-auth-token")?;
let token: MetadataValue<_> = "Bearer some-auth-token".parse()?;

let mut client = EchoClient::with_interceptor(channel, move |mut req: Request<()>| {
req.metadata_mut().insert("authorization", token.clone());
2 changes: 1 addition & 1 deletion examples/src/authentication/server.rs
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}

fn check_auth(req: Request<()>) -> Result<Request<()>, Status> {
let token = MetadataValue::from_str("Bearer some-secret-token").unwrap();
let token: MetadataValue<_> = "Bearer some-secret-token".parse().unwrap();

match req.metadata().get("authorization") {
Some(t) if token == t => Ok(req),
2 changes: 1 addition & 1 deletion examples/src/gcp/client.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.ok_or_else(|| "Expected a project name as the first argument.".to_string())?;

let bearer_token = format!("Bearer {}", token);
let header_value = MetadataValue::from_str(&bearer_token)?;
let header_value: MetadataValue<_> = bearer_token.parse()?;

let certs = tokio::fs::read("examples/data/gcp/roots.pem").await?;

20 changes: 10 additions & 10 deletions examples/src/streaming/client.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ async fn streaming_echo(client: &mut EchoClient<Channel>, num: usize) {
// stream is infinite - take just 5 elements and then disconnect
let mut stream = stream.take(num);
while let Some(item) = stream.next().await {
println!("\trecived: {}", item.unwrap().message);
println!("\treceived: {}", item.unwrap().message);
}
// stream is droped here and the disconnect info is send to server
}
@@ -42,9 +42,9 @@ async fn bidirectional_streaming_echo(client: &mut EchoClient<Channel>, num: usi

let mut resp_stream = response.into_inner();

while let Some(recived) = resp_stream.next().await {
let recived = recived.unwrap();
println!("\trecived message: `{}`", recived.message);
while let Some(received) = resp_stream.next().await {
let received = received.unwrap();
println!("\treceived message: `{}`", received.message);
}
}

@@ -58,9 +58,9 @@ async fn bidirectional_streaming_echo_throttle(client: &mut EchoClient<Channel>,

let mut resp_stream = response.into_inner();

while let Some(recived) = resp_stream.next().await {
let recived = recived.unwrap();
println!("\trecived message: `{}`", recived.message);
while let Some(received) = resp_stream.next().await {
let received = received.unwrap();
println!("\treceived message: `{}`", received.message);
}
}

@@ -72,13 +72,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
streaming_echo(&mut client, 5).await;
tokio::time::sleep(Duration::from_secs(1)).await; //do not mess server println functions

// Echo stream that sends 17 requests then gracefull end that conection
// Echo stream that sends 17 requests then graceful end that connection
println!("\r\nBidirectional stream echo:");
bidirectional_streaming_echo(&mut client, 17).await;

// Echo stream that sends up to `usize::MAX` requets. One request each 2s.
// Exiting client with CTRL+C demostrate how to distinguise broken pipe from
//gracefull client disconnection (above example) on the server side.
// Exiting client with CTRL+C demonstrate how to distinguish broken pipe from
//graceful client disconnection (above example) on the server side.
println!("\r\nBidirectional stream echo (kill client with CTLR+C):");
bidirectional_streaming_echo_throttle(&mut client, Duration::from_secs(2)).await;

85 changes: 85 additions & 0 deletions examples/src/tls/client_rustls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//! This examples shows how you can combine `hyper-rustls` and `tonic` to
//! provide a custom `ClientConfig` for the tls configuration.
pub mod pb {
tonic::include_proto!("/grpc.examples.echo");
}

use hyper::{client::HttpConnector, Uri};
use pb::{echo_client::EchoClient, EchoRequest};
use tokio_rustls::rustls::{ClientConfig, RootCertStore};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let fd = std::fs::File::open("examples/data/tls/ca.pem")?;

let mut roots = RootCertStore::empty();

let mut buf = std::io::BufReader::new(&fd);
let certs = rustls_pemfile::certs(&mut buf)?;
roots.add_parsable_certificates(&certs);

let tls = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(roots)
.with_no_client_auth();

let mut http = HttpConnector::new();
http.enforce_http(false);

// We have to do some wrapping here to map the request type from
// `https://example.com` -> `https://[::1]:50051` because `rustls`
// doesn't accept ip's as `ServerName`.
let connector = tower::ServiceBuilder::new()
.layer_fn(move |s| {
let tls = tls.clone();

hyper_rustls::HttpsConnectorBuilder::new()
.with_tls_config(tls)
.https_or_http()
.enable_http2()
.wrap_connector(s)
})
// Since our cert is signed with `example.com` but we actually want to connect
// to a local server we will override the Uri passed from the `HttpsConnector`
// and map it to the correct `Uri` that will connect us directly to the local server.
.map_request(|_| Uri::from_static("https://[::1]:50051"))
.service(http);

let client = hyper::Client::builder().build(connector);

// Hyper expects an absolute `Uri` to allow it to know which server to connect too.
// Currently, tonic's generated code only sets the `path_and_query` section so we
// are going to write a custom tower layer in front of the hyper client to add the
// scheme and authority.
//
// Again, this Uri is `example.com` because our tls certs is signed with this SNI but above
// we actually map this back to `[::1]:50051` before the `Uri` is passed to hyper's `HttpConnector`
// to allow it to correctly establish the tcp connection to the local `tls-server`.
let uri = Uri::from_static("https://example.com");
let svc = tower::ServiceBuilder::new()
.map_request(move |mut req: http::Request<tonic::body::BoxBody>| {
let uri = Uri::builder()
.scheme(uri.scheme().unwrap().clone())
.authority(uri.authority().unwrap().clone())
.path_and_query(req.uri().path_and_query().unwrap().clone())
.build()
.unwrap();

*req.uri_mut() = uri;
req
})
.service(client);

let mut client = EchoClient::new(svc);

let request = tonic::Request::new(EchoRequest {
message: "hello".into(),
});

let response = client.unary_echo(request).await?;

println!("RESPONSE={:?}", response);

Ok(())
}
143 changes: 143 additions & 0 deletions examples/src/tls/server_rustls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
pub mod pb {
tonic::include_proto!("/grpc.examples.echo");
}

use futures::Stream;
use hyper::server::conn::Http;
use pb::{EchoRequest, EchoResponse};
use std::{pin::Pin, sync::Arc};
use tokio::net::TcpListener;
use tokio_rustls::{
rustls::{Certificate, PrivateKey, ServerConfig},
TlsAcceptor,
};
use tonic::{transport::Server, Request, Response, Status, Streaming};
use tower_http::ServiceBuilderExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let certs = {
let fd = std::fs::File::open("examples/data/tls/server.pem")?;
let mut buf = std::io::BufReader::new(&fd);
rustls_pemfile::certs(&mut buf)?
.into_iter()
.map(Certificate)
.collect()
};
let key = {
let fd = std::fs::File::open("examples/data/tls/server.key")?;
let mut buf = std::io::BufReader::new(&fd);
rustls_pemfile::pkcs8_private_keys(&mut buf)?
.into_iter()
.map(PrivateKey)
.next()
.unwrap()

// let key = std::fs::read("examples/data/tls/server.key")?;
// PrivateKey(key)
};

let mut tls = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs, key)?;
tls.alpn_protocols = vec![b"h2".to_vec()];

let server = EchoServer::default();

let svc = Server::builder()
.add_service(pb::echo_server::EchoServer::new(server))
.into_service();

let mut http = Http::new();
http.http2_only(true);

let listener = TcpListener::bind("[::1]:50051").await?;
let tls_acceptor = TlsAcceptor::from(Arc::new(tls));

loop {
let (conn, addr) = match listener.accept().await {
Ok(incoming) => incoming,
Err(e) => {
eprintln!("Error accepting connection: {}", e);
continue;
}
};

let http = http.clone();
let tls_acceptor = tls_acceptor.clone();
let svc = svc.clone();

tokio::spawn(async move {
let mut certificates = Vec::new();

let conn = tls_acceptor
.accept_with(conn, |info| {
if let Some(certs) = info.peer_certificates() {
for cert in certs {
certificates.push(cert.clone());
}
}
})
.await
.unwrap();

let svc = tower::ServiceBuilder::new()
.add_extension(Arc::new(ConnInfo { addr, certificates }))
.service(svc);

http.serve_connection(conn, svc).await.unwrap();
});
}
}

#[derive(Debug)]
struct ConnInfo {
addr: std::net::SocketAddr,
certificates: Vec<Certificate>,
}

type EchoResult<T> = Result<Response<T>, Status>;
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;

#[derive(Default)]
pub struct EchoServer;

#[tonic::async_trait]
impl pb::echo_server::Echo for EchoServer {
async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> {
let conn_info = request.extensions().get::<Arc<ConnInfo>>().unwrap();
println!(
"Got a request from: {:?} with certs: {:?}",
conn_info.addr, conn_info.certificates
);

let message = request.into_inner().message;
Ok(Response::new(EchoResponse { message }))
}

type ServerStreamingEchoStream = ResponseStream;

async fn server_streaming_echo(
&self,
_: Request<EchoRequest>,
) -> EchoResult<Self::ServerStreamingEchoStream> {
Err(Status::unimplemented("not implemented"))
}

async fn client_streaming_echo(
&self,
_: Request<Streaming<EchoRequest>>,
) -> EchoResult<EchoResponse> {
Err(Status::unimplemented("not implemented"))
}

type BidirectionalStreamingEchoStream = ResponseStream;

async fn bidirectional_streaming_echo(
&self,
_: Request<Streaming<EchoRequest>>,
) -> EchoResult<Self::BidirectionalStreamingEchoStream> {
Err(Status::unimplemented("not implemented"))
}
}
Loading