rpc

package
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package rpc holds the gRPC stream plumbing the proxy's forwarding paths share.

ServiceMethod, Service, and Method split a gRPC full method name into the halves an allowlist check or a descriptor lookup needs. Pump.Forward forwards one call between an inbound server stream and an outbound client stream, and StatusError maps a failure along the way to the status the caller sees.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FullMethod

func FullMethod(ctx context.Context) (string, error)

FullMethod returns the full method name of the call ctx belongs to, in the "/pkg.Service/Method" form the other helpers here parse. It fails when ctx carries no server transport stream, which means it is not a server call's context and there is no method to name.

func Method

func Method(fullMethod string) string

Method returns the method half of a gRPC full method, or "" when fullMethod carries no method to strip.

func Reject

func Reject(code codes.Code, clientMsg, detail string) error

Reject builds a rejection carrying a client-safe code+message and a server-side detail for logging.

Return the result unwrapped. gRPC reads GRPCStatus verbatim only for an error it can type-assert directly; for a wrapped one it keeps the code but replaces the message with err.Error(), which is the detail. Adding context with %w therefore sends the caller exactly what this type withholds, so put the context in the detail instead.

func Service

func Service(fullMethod string) string

Service returns the service half of a gRPC full method, or "" when fullMethod carries no method to strip. Callers must treat "" as "no service" rather than as a name to match on.

func ServiceMethod

func ServiceMethod(fullMethod string) (service, method string, ok bool)

ServiceMethod splits a gRPC full method ("/pkg.Service/Method", with or without the leading slash gRPC supplies) into its service and method halves. It reports false when fullMethod carries no method to split off, in which case both halves are empty.

func StatusError

func StatusError(what string, err error) error

StatusError maps a forwarding error to the gRPC status returned to the caller, naming the step that failed as what. It forwards an error already carrying a status verbatim, maps a raw context error to its status, and otherwise reports Internal. Callers own the whole message, so what carries their own package prefix.

func WithOutgoing

func WithOutgoing(ctx context.Context, fn func(metadata.MD)) context.Context

WithOutgoing returns ctx with fn applied to its outgoing gRPC metadata. fn receives a copy, never the metadata already on ctx: that copy is the whole point, because outgoing metadata is shared with whatever else holds the context and mutating it in place corrupts calls in flight. fn is handed empty metadata when ctx carries none, so a caller that only adds keys needs no special case.

Types

type Frame

type Frame func() any

Frame allocates the value one direction receives into, and is called once per message. What that value is decides what the streams' codec does with it: a typed proto message is one client interceptors can read, while an opaque byte frame passes through unparsed. Returning the same value every call reuses one buffer for the direction, which is safe because the direction is sequential.

type Pump

type Pump struct {
	// contains filtered or unexported fields
}

Pump copies messages between the inbound server stream and the outbound client stream of one forwarded call, one goroutine per direction.

func NewPump

func NewPump(cs grpc.ClientStream, ss grpc.ServerStream) *Pump

NewPump returns a Pump that reads requests from ss and writes them to cs, and reads responses from cs and writes them to ss.

func (*Pump) Forward

func (p *Pump) Forward(in, out Frame) error

Forward forwards the whole call, relaying the upstream's header, trailer, and status to the caller. A half-close from the caller closes the upstream's send side and the call continues, so the loop runs at most twice: the request direction ending is not the call ending, and only the response direction finishing is. Both directions are started once, up front, because starting them inside the select would spawn a fresh pair per iteration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL