transport

package
v1.0.83 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package transport owns how the CLI assembles its outbound HTTP transport: the shared base RoundTripper (Shared/Fallback and the HTTP client constructors), the LARK_CLI_NO_PROXY direct-egress clone, and the ~/.lark-cli/proxy_config.json proxy-plugin mode.

Proxy-plugin mode forces all outbound HTTP(S) requests through a fixed loopback proxy, optionally trusting an extra root CA PEM bundle for TLS-inspection proxies, and fails closed on misconfiguration. Environment variables override matching values from proxy_config.json.

Index

Constants

View Source
const (
	// EnvNoProxy disables automatic proxy support when set to any non-empty value.
	EnvNoProxy = "LARK_CLI_NO_PROXY"

	// EnvNoProxyWarn suppresses the proxy-detected warning when set to any
	// non-empty value, while leaving proxy behavior unchanged. Unlike
	// EnvNoProxy (which both silences the warning AND disables the proxy), this
	// keeps proxy egress active. It exists so agents consuming --format json can
	// keep using the proxy without the human-oriented warning line landing in
	// the output stream and breaking JSON parsing.
	EnvNoProxyWarn = "LARK_CLI_NO_PROXY_WARN"
)

Proxy environment constants control shared transport proxy behavior.

View Source
const (
	ConfigFileName = "proxy_config.json"
)

ConfigFileName is the fixed config file name under core.GetConfigDir().

Variables

This section is empty.

Functions

func ClientForRequestClass added in v1.0.82

func ClientForRequestClass(client *http.Client, class exttransport.RequestClass) *http.Client

ClientForRequestClass clones client and forces all of its requests through a specific policy class. The original client is never mutated.

func CloneHTTPTransportForRequestClass added in v1.0.82

func CloneHTTPTransportForRequestClass(base http.RoundTripper, class exttransport.RequestClass) (rebuilt http.RoundTripper, concrete *http.Transport, ok bool)

CloneHTTPTransportForRequestClass selects one policy branch, clones its innermost *http.Transport, and rebuilds every composable decorator around the clone. Callers can customize concrete before using rebuilt. The original transport graph is never mutated.

func DetectProxyEnv

func DetectProxyEnv() (key, value string)

DetectProxyEnv returns the first proxy-related environment variable that is set, or empty strings if none are configured.

func Fallback

func Fallback() *http.Transport

Fallback returns a shared *http.Transport. It is a thin wrapper over Shared retained so modules already on the leak-free singleton path (internal/auth, internal/cmdutil transport decorators) do not have to migrate. New code should prefer Shared and treat the base as an http.RoundTripper.

Fail-closed invariant: pluginTransport always expresses its blocked transport as a concrete *http.Transport (see failClosedTransport), so the assertion below preserves the block. The noProxyTransport() fallback is therefore only reached when no proxy plugin is configured and some external code replaced http.DefaultTransport with a non-*http.Transport — a case with no fail-closed intent, where a proxy-disabled transport is acceptable.

func InstallSDKTransportBridge added in v1.0.82

func InstallSDKTransportBridge(buildPlatformPolicy func(http.RoundTripper) http.RoundTripper)

InstallSDKTransportBridge wraps larkws's captured HTTP bootstrap client. All requests through that client hit the bridge, but only matched bootstrap traffic uses platform policy. The SDK owns the subsequent WebSocket dial, which does not use this net/http transport.

func NewExternalHTTPClient added in v1.0.82

func NewExternalHTTPClient(timeout time.Duration) *http.Client

NewExternalHTTPClient returns a client for user-provided, pre-signed, CDN, package-registry, and other non-platform URLs. It forces the external policy while preserving the shared proxy configuration and the historical behavior of unscoped transport providers. A zero timeout means no client-level timeout.

func NewHTTPClient

func NewHTTPClient(timeout time.Duration) *http.Client

NewHTTPClient returns a policy-routed client over the shared proxy-aware transport. Known platform endpoints use the platform request class; all other URLs use the external request class. Existing unscoped transport providers continue to apply to both classes.

A zero timeout means no client-level timeout (callers relying on context deadlines pass 0).

func Path

func Path() string

Path returns the absolute path to the proxy plugin config file.

func Shared

func Shared() http.RoundTripper

Shared returns the base http.RoundTripper for all CLI HTTP clients.

Precedence (highest first):

  1. proxy-plugin mode — force traffic through a fixed loopback proxy; FAIL-CLOSED when the plugin config exists but is invalid.
  2. LARK_CLI_NO_PROXY — direct egress, proxy disabled.
  3. http.DefaultTransport — the stdlib process-wide singleton (honors HTTP(S)_PROXY), so every client shares one connection pool / TLS cache.

The returned RoundTripper MUST NOT be mutated. Callers that need a customized transport should assert to *http.Transport and Clone() it. A shared base is required so persistConn read/write goroutines are reused; cloning per call leaks them until IdleConnTimeout (~90s) fires.

func WarnIfProxied

func WarnIfProxied(w io.Writer)

WarnIfProxied prints a one-time warning to w when a proxy environment variable is detected and proxy is not disabled via LARK_CLI_NO_PROXY. Proxy credentials are redacted. Safe to call multiple times; only the first call prints.

func WithRequestClass added in v1.0.82

func WithRequestClass(req *http.Request, class exttransport.RequestClass) *http.Request

WithRequestClass returns a shallow copy of req with explicit routing intent.

func WrapWithExtension added in v1.0.82

func WrapWithExtension(base http.RoundTripper) http.RoundTripper

WrapWithExtension wraps base with the currently registered transport extension. With no registered provider or no resolved interceptor, base is returned unchanged.

func WrapWithExtensionForClass added in v1.0.82

func WrapWithExtensionForClass(base http.RoundTripper, class exttransport.RequestClass) http.RoundTripper

WrapWithExtensionForClass wraps base only when the registered provider supports class. Providers without the optional ScopedProvider interface keep their historical all-request behavior.

Types

type Config

type Config struct {
	// Enable turns on proxy plugin transport handling.
	Enable bool `json:"LARKSUITE_CLI_PROXY_ENABLE"`

	// Proxy is the fixed HTTP proxy address used for all outbound requests.
	Proxy string `json:"LARKSUITE_CLI_PROXY_ADDRESS"`

	// CAPath points to an extra PEM bundle trusted for proxy TLS interception.
	CAPath string `json:"LARKSUITE_CLI_CA_PATH"`
}

Config is the on-disk config format. Keys intentionally mirror env var names.

func Load

func Load() (*Config, error)

Load reads ~/.lark-cli/proxy_config.json once and caches the parsed result. Environment variables (CliProxyEnable/CliProxyAddress/CliCAPath) take precedence over config file values.

Returns (nil, nil) only when:

  • the config file does not exist AND
  • none of the proxy-related env vars are present.

func (*Config) ApplyToTransport

func (c *Config) ApplyToTransport(base *http.Transport) (*http.Transport, error)

ApplyToTransport clones base and applies proxy plugin settings to the clone. Caller owns the returned *http.Transport.

func (*Config) Enabled

func (c *Config) Enabled() bool

Enabled reports whether proxy plugin mode is enabled.

type ExtensionMiddleware added in v1.0.82

type ExtensionMiddleware struct {
	Base    http.RoundTripper
	Ext     exttransport.Interceptor
	ExtName string
}

ExtensionMiddleware wraps the built-in transport chain with extension pre/post hooks. The built-in chain always executes unless an exttransport.AbortableInterceptor rejects the request.

The original request context is restored after the pre hook to prevent an extension from replacing cancellation, deadlines, or built-in values. The request is cloned so URL and header mutations do not alter the caller's request object. The body remains shared; interceptors that consume it must restore it before returning.

func (*ExtensionMiddleware) BaseRoundTripper added in v1.0.82

func (m *ExtensionMiddleware) BaseRoundTripper() http.RoundTripper

BaseRoundTripper returns the wrapped built-in transport chain.

func (*ExtensionMiddleware) RoundTrip added in v1.0.82

func (m *ExtensionMiddleware) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip invokes the extension pre hook, the wrapped transport, and then the optional post hook. Abortable interceptors can stop the request before the wrapped transport is called.

func (*ExtensionMiddleware) WithBaseRoundTripper added in v1.0.82

func (m *ExtensionMiddleware) WithBaseRoundTripper(base http.RoundTripper) http.RoundTripper

WithBaseRoundTripper clones the middleware over base.

type HTTPPolicyRouter added in v1.0.82

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

HTTPPolicyRouter selects an HTTP transport policy from request intent and the endpoint catalog. Explicit request intent takes precedence; otherwise known platform endpoints use the platform policy and all other URLs use the external policy.

func NewHTTPPolicyRouter added in v1.0.82

func NewHTTPPolicyRouter(platform, external http.RoundTripper) *HTTPPolicyRouter

NewHTTPPolicyRouter constructs a router over two policy chains. A nil chain falls back to the shared proxy-aware transport. The currently registered extension provider is resolved once and applied according to its optional ScopedProvider contract.

func (*HTTPPolicyRouter) RoundTrip added in v1.0.82

func (r *HTTPPolicyRouter) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip dispatches the request to its selected policy chain.

type RoundTripperDecorator added in v1.0.82

type RoundTripperDecorator interface {
	BaseRoundTripper() http.RoundTripper
	WithBaseRoundTripper(http.RoundTripper) http.RoundTripper
}

RoundTripperDecorator describes a transport layer that can be rebuilt over a cloned base transport. Connection-policy helpers use this contract to preserve retry, response, and extension layers while safely customizing the innermost *http.Transport.

Jump to

Keyboard shortcuts

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