Documentation
¶
Overview ¶
Package network provides centralized HTTP client management with proxy support. It allows runtime proxy configuration updates that propagate to all HTTP clients.
Index ¶
- Variables
- func IsLinkLocal(ip net.IP) bool
- func IsLocalhost(hostname string) bool
- func IsPrivateIP(ip net.IP) bool
- func IsPublicIP(ip net.IP) bool
- func ParseMultipartFormFields(contentType string, body []byte) (map[string]any, error)
- func ReconstructMultipartBody(origContentType string, origBody []byte, payload map[string]any) ([]byte, string, error)
- func SSRFSafeDialContext(dialTimeout time.Duration) func(ctx context.Context, netw, addr string) (net.Conn, error)
- func SerializePayloadToRequest(req *schemas.HTTPRequest, payload map[string]any, isMultipart bool, ...) error
- func StaleConnectionRetryIfErr(_ *fasthttp.Request, attempts int, err error) (resetTimeout bool, retry bool)
- func WriteMultipartField(writer *multipart.Writer, name string, val any) error
- type ClientPurpose
- type GlobalProxyConfig
- type GlobalProxyType
- type HTTPClientFactory
- func (f *HTTPClientFactory) GetFasthttpClient(purpose ClientPurpose) *fasthttp.Client
- func (f *HTTPClientFactory) GetHTTPClient(purpose ClientPurpose) *http.Client
- func (f *HTTPClientFactory) GetProxyConfig() *GlobalProxyConfig
- func (f *HTTPClientFactory) UpdateProxyConfig(config *GlobalProxyConfig)
Constants ¶
This section is empty.
Variables ¶
var DefaultClientConfig = struct { ReadTimeout time.Duration WriteTimeout time.Duration MaxIdleConnDuration time.Duration MaxConnDuration time.Duration MaxConnsPerHost int }{ ReadTimeout: 60 * time.Second, WriteTimeout: 60 * time.Second, MaxIdleConnDuration: 30 * time.Second, MaxConnDuration: 300 * time.Second, MaxConnsPerHost: 200, }
DefaultClientConfig holds default timeout values for HTTP clients
Functions ¶
func IsLinkLocal ¶ added in v1.5.17
IsLinkLocal reports whether ip is a link-local address. These are always blocked regardless of AllowPrivateNetwork — they include cloud instance metadata endpoints (169.254.169.254, fe80::) that must never be reachable even in private-network deployments.
func IsLocalhost ¶ added in v1.5.17
IsLocalhost reports whether hostname is localhost or a loopback literal.
func IsPrivateIP ¶ added in v1.5.17
IsPrivateIP reports whether ip falls in a private, loopback, or link-local range.
func IsPublicIP ¶ added in v1.7.3
IsPublicIP reports whether ip is safe to dial from server-side code that fetches user-controlled URLs: not loopback, private, CGNAT, link-local, unique-local, site-local, multicast, broadcast, or unspecified. IPv6 forms that embed an IPv4 address (IPv4-mapped, 6to4, NAT64) are reduced to that IPv4 and re-checked, so an internal IPv4 such as the 169.254.169.254 metadata endpoint cannot be reached by wrapping it in an IPv6 transition representation.
This is stricter than the complement of IsPrivateIP: IsPrivateIP is a coarse range check for save-time URL validation (where private targets may be deliberately allowed), while IsPublicIP is the dial-time gate.
func ParseMultipartFormFields ¶ added in v1.4.4
ParseMultipartFormFields extracts text form fields from a multipart/form-data body, skipping file parts to avoid loading binary data into memory.
func ReconstructMultipartBody ¶ added in v1.4.4
func ReconstructMultipartBody(origContentType string, origBody []byte, payload map[string]any) ([]byte, string, error)
ReconstructMultipartBody rebuilds a multipart/form-data body from the original, replacing text field values with those from payload (e.g. updated "model") and copying file parts byte-for-byte.
func SSRFSafeDialContext ¶ added in v1.7.3
func SSRFSafeDialContext(dialTimeout time.Duration) func(ctx context.Context, netw, addr string) (net.Conn, error)
SSRFSafeDialContext returns a DialContext for outbound requests to user-controlled URLs. On every dial it resolves the host, rejects the connection if any resolved address fails IsPublicIP, and then dials the first validated IP directly — so a second DNS resolution cannot swap in a private address after validation (DNS rebinding TOCTOU). Because the check runs per dial, it also holds across redirects and connection-pool re-dials.
func SerializePayloadToRequest ¶ added in v1.4.4
func SerializePayloadToRequest(req *schemas.HTTPRequest, payload map[string]any, isMultipart bool, origContentType string) error
SerializePayloadToRequest writes the modified payload back to req.Body, using multipart reconstruction for multipart/form-data or JSON for everything else.
func StaleConnectionRetryIfErr ¶ added in v1.4.3
Types ¶
type ClientPurpose ¶
type ClientPurpose string
ClientPurpose defines the intended use of an HTTP client for proxy filtering
const ( // ClientPurposeSCIM is used for SCIM/OAuth provider requests ClientPurposeSCIM ClientPurpose = "scim" // ClientPurposeInference is used for LLM inference requests ClientPurposeInference ClientPurpose = "inference" // ClientPurposeAPI is used for general API requests (guardrails, etc.) ClientPurposeAPI ClientPurpose = "api" )
type GlobalProxyConfig ¶
type GlobalProxyConfig struct {
Enabled bool `json:"enabled"`
Type GlobalProxyType `json:"type"` // "http", "socks5", "tcp"
URL string `json:"url"` // Proxy URL (e.g., http://proxy.example.com:8080)
Username string `json:"username,omitempty"` // Optional authentication username
Password string `json:"password,omitempty"` // Optional authentication password
NoProxy string `json:"no_proxy,omitempty"` // Comma-separated list of hosts to bypass proxy
Timeout int `json:"timeout,omitempty"` // Connection timeout in seconds
SkipTLSVerify bool `json:"skip_tls_verify,omitempty"` // Skip TLS certificate verification
// Entity enablement flags
EnableForSCIM bool `json:"enable_for_scim"` // Enable proxy for SCIM requests (enterprise only)
EnableForInference bool `json:"enable_for_inference"` // Enable proxy for inference requests
EnableForAPI bool `json:"enable_for_api"` // Enable proxy for API requests
}
GlobalProxyConfig represents the global proxy configuration
type GlobalProxyType ¶
type GlobalProxyType string
GlobalProxyType represents the type of global proxy
const ( GlobalProxyTypeHTTP GlobalProxyType = "http" GlobalProxyTypeSOCKS5 GlobalProxyType = "socks5" GlobalProxyTypeTCP GlobalProxyType = "tcp" )
type HTTPClientFactory ¶
type HTTPClientFactory struct {
// contains filtered or unexported fields
}
HTTPClientFactory manages HTTP clients with centralized proxy configuration. It supports both fasthttp and standard net/http clients with purpose-based proxy enablement (SCIM, Inference, API).
func NewHTTPClientFactory ¶
func NewHTTPClientFactory(proxyConfig *GlobalProxyConfig, logger schemas.Logger) *HTTPClientFactory
NewHTTPClientFactory creates a new HTTP client factory with the given proxy configuration. Pass nil for proxyConfig if proxy is not yet configured.
func (*HTTPClientFactory) GetFasthttpClient ¶
func (f *HTTPClientFactory) GetFasthttpClient(purpose ClientPurpose) *fasthttp.Client
GetFasthttpClient returns a fasthttp client configured for the given purpose. If proxy is enabled for this purpose, the client will be configured with proxy settings. Clients are cached and reused until proxy config changes.
func (*HTTPClientFactory) GetHTTPClient ¶
func (f *HTTPClientFactory) GetHTTPClient(purpose ClientPurpose) *http.Client
GetHTTPClient returns a standard net/http client configured for the given purpose. If proxy is enabled for this purpose, the client will be configured with proxy settings. Clients are cached and reused until proxy config changes.
func (*HTTPClientFactory) GetProxyConfig ¶
func (f *HTTPClientFactory) GetProxyConfig() *GlobalProxyConfig
GetProxyConfig returns the current proxy configuration (thread-safe read)
func (*HTTPClientFactory) UpdateProxyConfig ¶
func (f *HTTPClientFactory) UpdateProxyConfig(config *GlobalProxyConfig)
UpdateProxyConfig updates the proxy configuration and recreates all cached clients. This is thread-safe and can be called at runtime.