hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
9.47k stars 974 forks source link

Upgrading to tonic-reflection 0.12 breaks reflection #1786

Open codeitlikemiley opened 2 weeks ago

codeitlikemiley commented 2 weeks ago

Bug

Prior V0.12 using client like grpcurl and evans cli has no problem After upgrading issue , the is an issue on relection

I can still run client code without reflection without issue only reflection has issue.

Version

After upgrading to tonic-reflection 0.12

tonic = { version = "0.11", features = ["tls"] }
├── tonic v0.11.0
├── tonic-reflection v0.11.0
│   └── tonic v0.11.0 (*)
├── tonic-web v0.11.0
│   ├── tonic v0.11.0 (*)
└── tonic-build v0.11.0

once i bumped it to 0.12

├── tonic v0.12.0
├── tonic-reflection v0.12.0
│   └── tonic v0.12.0 (*)
├── tonic-web v0.12.0
│   ├── tonic v0.12.0 (*)
└── tonic-build v0.12.0

Platform

Im running on MacOS , but i also tested this on docker container on debian same issue.

Description

before upgrade . This code works

#[async_trait]
impl Transport for GrpcServer {
    async fn listen(self, port: u16) -> Result<(), Box<dyn std::error::Error>> {
        let address = format!("[::]:{}", port).parse()?;
        let auth_server = AuthServiceServer::new(self);

        info!("Start listening for incoming messages at {}.", address);

        let descriptor = Builder::configure()
            .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET)
            .build()
            .unwrap();

        let cert = std::fs::read_to_string("cert/cert.pem")?;
        let key = std::fs::read_to_string("cert/key.pem")?;
        let identity = Identity::from_pem(cert, key);

        let tlsconfig = ServerTlsConfig::new()
            .identity(identity)
            .client_auth_optional(true)
            .client_ca_root(Certificate::from_pem(std::fs::read_to_string(
                "cert/ca-cert.pem",
            )?));

        Server::builder()
            .tls_config(tlsconfig)?
            .add_service(auth_server)
            .add_service(descriptor)
            .serve(address)
            .await?;

        Ok(())
    }
}

here is the build.rs

use glob::glob;

fn main() {
    println!("Running build.rs");

    // Use a recursive glob pattern to match all .proto files in proto/ and subdirectories
    let proto_files: Vec<_> = glob("src/infrastructure/proto/**/*.proto")
        .expect("Failed to read glob pattern")
        .filter_map(Result::ok)
        .map(|path| {
            let path_str = path.to_string_lossy().into_owned();
            println!("cargo:rerun-if-changed={}", path_str);
            path_str
        })
        .collect();

    tonic_build::configure()
        .out_dir("src/infrastructure/pb/")
        .build_server(true)
        .build_client(true)
        .file_descriptor_set_path("src/infrastructure/pb/reflection_descriptor.bin")
        .compile(&proto_files, &["proto"])
        .unwrap_or_else(|e| panic!("Failed to compile protobuf {:?}", e));

    println!("Finished build.rs");
}

after upgrade all i get is

evans: failed to run REPL mode: failed to instantiate a new spec: failed to instantiate the spec: failed to list packages by gRPC reflection: failed to list services from reflection enabled gRPC server: rpc error: code = Unimplemented desc =
make: *** [rpc] Error 1

I dont know if im missing something but the error clearly says

failed to list services from reflection enabled gRPC server

ttkzhed commented 2 weeks ago

Probably related to: https://github.com/hyperium/tonic/discussions/1784 @ttkjesper has proposed a change to address the issue: https://github.com/hyperium/tonic/pull/1787

shenghui0779 commented 1 week ago

build and run the example(reflection-server), not effect.

image