Protocol::GRPCSourceProtocolGRPCMethods

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 service String

e.g., "my_service.Greeter"

parameter method String

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 path String

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 metadata Hash

Custom metadata key-value pairs

parameter timeout Numeric | Nil

Optional timeout in seconds

parameter content_type String

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(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
	
	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 headers Protocol::HTTP::Headers
returns Hash

Metadata key-value pairs

Implementation

def self.extract_metadata(headers)
	metadata = {}
	
	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
		else
			value
		end
		
		metadata[key] = value
	end
	
	metadata
end

def self.format_timeout(timeout)

  • deprecated

Format timeout for grpc-timeout header.

Signature

parameter timeout Numeric

Timeout in seconds

returns String

e.g., "1000m" for 1 second

deprecated

Use Protocol::GRPC::Header::Timeout.format instead.

Implementation

def self.format_timeout(timeout)
	Kernel.warn("`Protocol::GRPC::Methods.format_timeout` is deprecated; use `Protocol::GRPC::Header::Timeout.format` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
	
	Header::Timeout.format(timeout)
end

def self.parse_timeout(value)

  • deprecated

Parse grpc-timeout header value.

Signature

parameter value String

e.g., "1000m"

returns Numeric | Nil

Timeout in seconds, or Nil if value is invalid

deprecated

Use Protocol::GRPC::Header::Timeout#to_seconds instead.

Implementation

def self.parse_timeout(value)
	Kernel.warn("`Protocol::GRPC::Methods.parse_timeout` is deprecated; use `Protocol::GRPC::Header::Timeout#to_seconds` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
	
	return nil unless value
	
	Header::Timeout.parse(value).to_seconds
rescue ArgumentError
	return nil
end