module Methods
Provides utility methods for building and parsing gRPC-compatible HTTP requests.
Definitions
def self.build_path(service, method)
Build gRPC path from service and method.
Signature
-
parameter
serviceString e.g., "my_service.Greeter"
-
parameter
methodString e.g., "SayHello"
-
returns
String e.g., "/my_service.Greeter/SayHello"
Implementation
def self.build_path(service, method)
"/#{service}/#{method}"
end
def self.parse_path(path)
Parse service and method from gRPC path.
Signature
-
parameter
pathString e.g., "/my_service.Greeter/SayHello"
-
returns
Array(String, String) [service, method]
Implementation
def self.parse_path(path)
parts = path.split("/")
[parts[1], parts[2]]
end
def self.build_headers(metadata: {}, timeout: nil, content_type: "application/grpc+proto")
Build gRPC request headers.
Signature
-
parameter
metadataHash Custom metadata key-value pairs
-
parameter
timeoutNumeric | Nil Optional timeout in seconds
-
parameter
content_typeString Content type (default: "application/grpc+proto")
-
returns
Protocol::HTTP::Headers
Implementation
def self.build_headers(metadata: {}, timeout: nil, content_type: "application/grpc+proto")
headers = Protocol::HTTP::Headers.new
headers["content-type"] = content_type
headers["te"] = "trailers"
headers["grpc-timeout"] = format_timeout(timeout) if timeout
metadata.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
def self.extract_metadata(headers)
Extract metadata from gRPC headers.
Signature
-
parameter
headersProtocol::HTTP::Headers -
returns
Hash Metadata key-value pairs
Implementation
def self.extract_metadata(headers)
metadata = {}
headers.each do |key, value|
# Skip reserved headers:
next if key.start_with?("grpc-") || key == "content-type" || key == "te"
# Decode binary headers:
metadata[key] = if key.end_with?("-bin")
Base64.strict_decode64(value)
else
value
end
end
metadata
end
def self.format_timeout(timeout)
Format timeout for grpc-timeout header.
Signature
-
parameter
timeoutNumeric Timeout in seconds
-
returns
String e.g., "1000m" for 1 second
Implementation
def self.format_timeout(timeout)
# gRPC timeout format: value + unit (H=hours, M=minutes, S=seconds, m=milliseconds, u=microseconds, n=nanoseconds)
if timeout >= 3600
"#{(timeout / 3600).to_i}H"
elsif timeout >= 60
"#{(timeout / 60).to_i}M"
elsif timeout >= 1
"#{timeout.to_i}S"
elsif timeout >= 0.001
"#{(timeout * 1000).to_i}m"
elsif timeout >= 0.000001
"#{(timeout * 1_000_000).to_i}u"
else
"#{(timeout * 1_000_000_000).to_i}n"
end
end
def self.parse_timeout(value)
Parse grpc-timeout header value.
Signature
-
parameter
valueString e.g., "1000m"
-
returns
Numeric | Nil Timeout in seconds, or
Nilif value is invalid
Implementation
def self.parse_timeout(value)
return nil unless value
amount = value[0...-1].to_i
unit = value[-1]
case unit
when "H" then amount * 3600
when "M" then amount * 60
when "S" then amount
when "m" then amount / 1000.0
when "u" then amount / 1_000_000.0
when "n" then amount / 1_000_000_000.0
end
end