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
- func ClientForRequestClass(client *http.Client, class exttransport.RequestClass) *http.Client
- func CloneHTTPTransportForRequestClass(base http.RoundTripper, class exttransport.RequestClass) (rebuilt http.RoundTripper, concrete *http.Transport, ok bool)
- func DetectProxyEnv() (key, value string)
- func Fallback() *http.Transport
- func InstallSDKTransportBridge(buildPlatformPolicy func(http.RoundTripper) http.RoundTripper)
- func NewExternalHTTPClient(timeout time.Duration) *http.Client
- func NewHTTPClient(timeout time.Duration) *http.Client
- func Path() string
- func Shared() http.RoundTripper
- func WarnIfProxied(w io.Writer)
- func WithRequestClass(req *http.Request, class exttransport.RequestClass) *http.Request
- func WrapWithExtension(base http.RoundTripper) http.RoundTripper
- func WrapWithExtensionForClass(base http.RoundTripper, class exttransport.RequestClass) http.RoundTripper
- type Config
- type ExtensionMiddleware
- type HTTPPolicyRouter
- type RoundTripperDecorator
Constants ¶
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.
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 ¶
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
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 ¶
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 Shared ¶
func Shared() http.RoundTripper
Shared returns the base http.RoundTripper for all CLI HTTP clients.
Precedence (highest first):
- proxy-plugin mode — force traffic through a fixed loopback proxy; FAIL-CLOSED when the plugin config exists but is invalid.
- LARK_CLI_NO_PROXY — direct egress, proxy disabled.
- 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 ¶
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 ¶
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 ¶
ApplyToTransport clones base and applies proxy plugin settings to the clone. Caller owns the returned *http.Transport.
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
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.
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.