Files
cli/vendor/connectrpc.com/connect/context.go
Alano Terblanche 0c2d0f700c vendor: github.com/docker/secrets-engine/client v0.2.2
Add the Docker secrets engine client, used to read the Docker Desktop session for Docker Hub. It brings in github.com/docker/secrets-engine/x v0.8.5 and connectrpc.com/connect v1.19.1.

The client module requires go1.26.10, which raises the go directive in vendor.mod from 1.26.0.

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2026-10-22 11:10:40 +02:00

243 lines
7.9 KiB
Go

// Copyright 2021-2025 The Connect Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package connect
import (
"context"
"net/http"
)
// CallInfo represents information relevant to an RPC call.
type CallInfo interface {
// Spec returns a description of this call.
Spec() Spec
// Peer describes the other party for this call.
Peer() Peer
// RequestHeader returns the HTTP headers for this request. Headers beginning with
// "Connect-" and "Grpc-" are reserved for use by the Connect and gRPC
// protocols: applications may read them but shouldn't write them.
RequestHeader() http.Header
// ResponseHeader returns the HTTP headers for this response. Headers beginning with
// "Connect-" and "Grpc-" are reserved for use by the Connect and gRPC
// protocols: applications may read them but shouldn't write them.
// On the client side, this method returns nil before
// the call is actually made. After the call is made, for streaming operations,
// this method will block for the server to actually return response headers.
ResponseHeader() http.Header
// ResponseTrailer returns the trailers for this response. Depending on the underlying
// RPC protocol, trailers may be sent as HTTP trailers or a protocol-specific
// block of in-body metadata.
//
// Trailers beginning with "Connect-" and "Grpc-" are reserved for use by the
// Connect and gRPC protocols: applications may read them but shouldn't write
// them.
//
// On the client side, this method returns nil before the call is actually made.
// After the call is made, for streaming operations, this method will block
// for the server to actually return response trailers.
ResponseTrailer() http.Header
// HTTPMethod returns the HTTP method for this request. This is nearly always
// POST, but side-effect-free unary RPCs could be made via a GET.
//
// On a newly created request, via NewRequest, this will return the empty
// string until the actual request is actually sent and the HTTP method
// determined. This means that client interceptor functions will see the
// empty string until *after* they delegate to the handler they wrapped. It
// is even possible for this to return the empty string after such delegation,
// if the request was never actually sent to the server (and thus no
// determination ever made about the HTTP method).
HTTPMethod() string
internalOnly()
}
// Create a new client (i.e. outgoing) context for use from a client. When the
// returned context is passed to RPCs, the returned call info can be used to set
// request metadata before the RPC is invoked and to inspect response
// metadata after the RPC completes.
//
// The returned context may be re-used across RPCs as long as they are
// not concurrent. Results of all CallInfo methods other than
// RequestHeader() are undefined if the context is used with concurrent RPCs.
func NewClientContext(ctx context.Context) (context.Context, CallInfo) {
info := &clientCallInfo{}
return context.WithValue(ctx, clientCallInfoContextKey{}, info), info
}
// CallInfoForHandlerContext returns the CallInfo for the given handler (i.e. incoming) context, if there is one.
func CallInfoForHandlerContext(ctx context.Context) (CallInfo, bool) {
value, ok := ctx.Value(handlerCallInfoContextKey{}).(CallInfo)
return value, ok
}
// handlerCallInfo is a CallInfo implementation used for unary handlers.
type handlerCallInfo struct {
spec Spec
peer Peer
method string
requestHeader http.Header
responseHeader http.Header
responseTrailer http.Header
}
func (c *handlerCallInfo) Spec() Spec {
return c.spec
}
func (c *handlerCallInfo) Peer() Peer {
return c.peer
}
func (c *handlerCallInfo) RequestHeader() http.Header {
if c.requestHeader == nil {
c.requestHeader = make(http.Header)
}
return c.requestHeader
}
func (c *handlerCallInfo) ResponseHeader() http.Header {
if c.responseHeader == nil {
c.responseHeader = make(http.Header)
}
return c.responseHeader
}
func (c *handlerCallInfo) ResponseTrailer() http.Header {
if c.responseTrailer == nil {
c.responseTrailer = make(http.Header)
}
return c.responseTrailer
}
func (c *handlerCallInfo) HTTPMethod() string {
return c.method
}
// internalOnly implements CallInfo.
func (c *handlerCallInfo) internalOnly() {}
// streamingHandlerCallInfo is a CallInfo implementation used for streaming RPC handlers.
type streamingHandlerCallInfo struct {
conn StreamingHandlerConn
}
func (c *streamingHandlerCallInfo) Spec() Spec {
return c.conn.Spec()
}
func (c *streamingHandlerCallInfo) Peer() Peer {
return c.conn.Peer()
}
func (c *streamingHandlerCallInfo) RequestHeader() http.Header {
return c.conn.RequestHeader()
}
func (c *streamingHandlerCallInfo) ResponseHeader() http.Header {
return c.conn.ResponseHeader()
}
func (c *streamingHandlerCallInfo) ResponseTrailer() http.Header {
return c.conn.ResponseTrailer()
}
func (c *streamingHandlerCallInfo) HTTPMethod() string {
// All stream calls are POSTs
return http.MethodPost
}
// internalOnly implements CallInfo.
func (c *streamingHandlerCallInfo) internalOnly() {}
// clientCallInfo is a CallInfo implementation used for clients.
type clientCallInfo struct {
responseSource
spec Spec
peer Peer
method string
requestHeader http.Header
}
func (c *clientCallInfo) Spec() Spec {
return c.spec
}
func (c *clientCallInfo) Peer() Peer {
return c.peer
}
func (c *clientCallInfo) RequestHeader() http.Header {
if c.requestHeader == nil {
c.requestHeader = make(http.Header)
}
return c.requestHeader
}
func (c *clientCallInfo) ResponseHeader() http.Header {
if c.responseSource == nil {
return nil
}
return c.responseSource.ResponseHeader()
}
func (c *clientCallInfo) ResponseTrailer() http.Header {
if c.responseSource == nil {
return nil
}
return c.responseSource.ResponseTrailer()
}
func (c *clientCallInfo) HTTPMethod() string {
return c.method
}
// internalOnly implements CallInfo.
func (c *clientCallInfo) internalOnly() {}
// clientCallInfoContextKey is the key used to store client call info in context.
type clientCallInfoContextKey struct{}
// sentinelContextKey is the key used to store a copy of client call info in context
// when a request is made.
// Each step in an interceptor chain compares the actual call info with the
// sentinel call info. If the two values are different, the request will
// return an error in the interceptor.
// This protects against changing the call info in interceptors, which is prohibited
// as it would allow users to modify call info mid-flight independent of the actual
// request or response.
// Users who wish to modify call info data such as headers and trailers should instead
// use Connect [Request] and [Response] wrapper types.
type sentinelContextKey struct{}
// handlerCallInfoContextKey is the key used to store handler call info in context.
type handlerCallInfoContextKey struct{}
// responseSource indicates a type that manages response headers and trailers.
type responseSource interface {
ResponseHeader() http.Header
ResponseTrailer() http.Header
}
// clientCallInfoForContext gets the call info from a client/outgoing context.
func clientCallInfoForContext(ctx context.Context) (*clientCallInfo, bool) {
info, ok := ctx.Value(clientCallInfoContextKey{}).(*clientCallInfo)
return info, ok
}
// newHandlerContext creates a new handler/incoming context.
func newHandlerContext(ctx context.Context, info CallInfo) context.Context {
return context.WithValue(ctx, handlerCallInfoContextKey{}, info)
}