Module: Protocol::GRPC::Metadata
- Defined in:
- lib/protocol/grpc/metadata.rb
Overview
Provides operations for building and extracting gRPC metadata.
Class Method Summary collapse
-
.assign_status!(headers, status: Status::OK, message: nil, error: nil) ⇒ Object
(also: add_status!)
Assign gRPC status, message, and optional backtrace to headers.
-
.build(metadata: {}, timeout: nil, content_type: "application/grpc+proto") ⇒ Object
Build gRPC request headers containing the given metadata.
-
.extract(headers) ⇒ Object
Extract application metadata from gRPC headers.
-
.extract_message(headers) ⇒ Object
Extract gRPC status message from headers.
-
.extract_status(headers) ⇒ Object
Extract gRPC status from headers.
Class Method Details
.assign_status!(headers, status: Status::OK, message: nil, error: nil) ⇒ Object Also known as: add_status!
Assign gRPC status, message, and optional backtrace to headers.
Whether these become headers or trailers is controlled by the protocol layer.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/protocol/grpc/metadata.rb', line 111 def self.assign_status!(headers, status: Status::OK, message: nil, error: nil) headers["grpc-status"] = status if error && .nil? # If message is not provided but error is, use error message = error. end if headers["grpc-message"] = end # Add backtrace from error if available if error && error.backtrace && !error.backtrace.empty? # Assign backtrace array directly - Split header will handle it headers["backtrace"] = error.backtrace end return headers end |
.build(metadata: {}, timeout: nil, content_type: "application/grpc+proto") ⇒ Object
Build gRPC request headers containing the given metadata.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/protocol/grpc/metadata.rb', line 20 def self.build(metadata: {}, timeout: nil, content_type: "application/grpc+proto") headers = Protocol::HTTP::Headers.new(policy: Protocol::GRPC::HEADER_POLICY) headers["content-type"] = content_type headers["te"] = "trailers" if timeout # Coerced to proper format by header policy: headers["grpc-timeout"] = timeout end .each do |key, value| # Binary headers end with -bin and are base64 encoded: headers[key] = if key.end_with?("-bin") Base64.strict_encode64(value) else value.to_s end end headers end |
.extract(headers) ⇒ Object
Extract application metadata from gRPC headers.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/protocol/grpc/metadata.rb', line 45 def self.extract(headers) = {} headers.to_h.each do |key, value| # Skip reserved headers: next if key.start_with?("grpc-") || key == "content-type" || key == "te" # Decode binary headers: if key.end_with?("-bin") if value.is_a?(String) value = Base64.strict_decode64(value) elsif value.is_a?(Array) value = value.map{|item| Base64.strict_decode64(item)} end end [key] = value end end |
.extract_message(headers) ⇒ Object
Extract gRPC status message from headers.
Returns Nil if message is not present.
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/protocol/grpc/metadata.rb', line 92 def self.(headers) # Ensure policy is set - setting policy clears the index (@indexed = nil) # The index will be rebuilt automatically on next access via to_h headers.policy = Protocol::GRPC::HEADER_POLICY unless headers.policy == Protocol::GRPC::HEADER_POLICY = headers["grpc-message"] return nil unless return .decode end |
.extract_status(headers) ⇒ Object
Extract gRPC status from headers. Returns Status::UNKNOWN if status is not present.
Note: In Protocol::HTTP::Headers, trailers are merged into the headers so users just access headers regardless of whether it was sent as an initial header or trailer.
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/protocol/grpc/metadata.rb', line 76 def self.extract_status(headers) # Ensure policy is set - setting policy clears the index (@indexed = nil) # The index will be rebuilt automatically on next access via to_h headers.policy = Protocol::GRPC::HEADER_POLICY unless headers.policy == Protocol::GRPC::HEADER_POLICY status = headers["grpc-status"] return Status::UNKNOWN unless status return status.to_i end |