grpc.rs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. //! gRPC version checking utilities
  2. use tonic::{Request, Status};
  3. /// Header name for protocol version
  4. pub const VERSION_HEADER: &str = "x-cdk-protocol-version";
  5. /// Creates a client-side interceptor that injects a specific protocol version into outgoing requests
  6. ///
  7. /// # Panics
  8. /// Panics if the version string is not a valid gRPC metadata ASCII value
  9. pub fn create_version_inject_interceptor(
  10. version: &'static str,
  11. ) -> impl Fn(Request<()>) -> Result<Request<()>, Status> + Clone {
  12. move |mut request: Request<()>| {
  13. request.metadata_mut().insert(
  14. VERSION_HEADER,
  15. version.parse().expect("Invalid protocol version"),
  16. );
  17. Ok(request)
  18. }
  19. }
  20. /// Creates a server-side interceptor that validates a specific protocol version on incoming requests
  21. pub fn create_version_check_interceptor(
  22. expected_version: &'static str,
  23. ) -> impl Fn(Request<()>) -> Result<Request<()>, Status> + Clone {
  24. move |request: Request<()>| match request.metadata().get(VERSION_HEADER) {
  25. Some(version) => {
  26. let version = version
  27. .to_str()
  28. .map_err(|_| Status::invalid_argument("Invalid protocol version header"))?;
  29. if version != expected_version {
  30. return Err(Status::failed_precondition(format!(
  31. "Protocol version mismatch: server={}, client={}",
  32. expected_version, version
  33. )));
  34. }
  35. Ok(request)
  36. }
  37. None => Err(Status::failed_precondition(
  38. "Missing x-cdk-protocol-version header",
  39. )),
  40. }
  41. }