gohttpc

package module
v0.0.0-...-5af4e00 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

README

gohttpc

gohttpc is a Go HTTP client library that wraps Go's standard http.Client while adding observability, authentication, and configuration management features commonly needed in production HTTP clients:

  • Reusable configurations - HTTP client settings via httpconfig package
  • Semantic telemetry - Built-in OpenTelemetry tracing and metrics support
  • Authentication schemes - Support for basic auth, OAuth2, and other auth methods following OpenAPI 3 spec
  • Request/response wrappers - Enhanced Request and Response types with additional functionality
  • Compression support - Integration with gocompress for request/response compression
  • Retry mechanisms - Built-in retry logic with backoff strategies

Observability

Distributed Tracing

The library provides two tracing modes:

Simple Client Trace (default):
  • Basic span creation and timing
  • Minimal overhead
Enhanced Client Trace (when ClientTraceEnabled=true):
  • Detailed HTTP lifecycle tracking using Go's httptrace package.
  • Captures granular timing for:
    • DNS lookup
    • TCP connection establishment
    • TLS handshake
    • Connection reuse/idle time
    • Time to first response byte
    • Response reading time
Metrics

[!NOTE] Prometheus may replace dots in the metric name with underscores.

Core Metrics (Always Available)
Metric Type Description
dns.lookup.duration Histogram Measures the time taken to perform a DNS lookup
http.client.active_requests Gauge Number of active HTTP requests
http.client.request.duration Histogram Total duration of HTTP requests
http.client.server.duration Histogram Server processing time (time to first byte)
http.client.request.body.size Histogram Size of request bodies in bytes
http.client.response.body.size Histogram Size of response bodies in bytes
Enhanced Metrics (When ClientTraceEnabled=true)
Metric Type Description
http.client.open_connections Gauge Number of active or idle outbound connections
http.client.connection.duration Histogram Duration to establish outbound connections
http.client.idle_connection.duration Histogram How long connections were idle before reuse

Documentation

Index

Constants

View Source
const LogLevelTrace = slog.Level(-8)

LogLevelTrace is the constant enum for the TRACE log level.

Variables

View Source
var (
	// ErrResponseBodyNoContent occurs when the response body has no content.
	ErrResponseBodyNoContent = errors.New("response body has no content")
	// ErrResponseBodyAlreadyRead occurs when the response body was already read.
	ErrResponseBodyAlreadyRead = errors.New("response body was already read")
	// ErrRequestMethodRequired occurs when the request method is null.
	ErrRequestMethodRequired = errors.New("request method is required")
	// ErrRequestAlreadyExecuted occurs when the request was already executed.
	ErrRequestAlreadyExecuted = errors.New("request was already executed")
)

Functions

func DialerFromConfig

func DialerFromConfig(conf *HTTPDialerConfig) *net.Dialer

DialerFromConfig creates a net dialer from the configuration.

func SetHTTPClientMetrics

func SetHTTPClientMetrics(metrics *HTTPClientMetrics)

SetHTTPClientMetrics sets the global HTTPClientMetrics instance.

func TransportFromConfig

func TransportFromConfig(
	ttc *HTTPTransportConfig,
	clientOptions *ClientOptions,
) *http.Transport

TransportFromConfig creates an http transport from the configuration.

Types

type Client

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

Client represents an HTTP client wrapper with extended functionality.

func NewClient

func NewClient(options ...ClientOption) *Client

NewClient creates a new HTTP client wrapper.

func NewClientWithOptions

func NewClientWithOptions(options *ClientOptions) *Client

NewClientWithOptions creates a new HTTP client wrapper with client options.

func (*Client) ClientOptions

func (c *Client) ClientOptions() *ClientOptions

ClientOptions returns a cloned ClientOptions of the current client.

func (*Client) Clone

func (c *Client) Clone(options ...ClientOption) *Client

Clone creates a new client with properties copied.

func (*Client) Close

func (c *Client) Close() error

Close terminates internal processes.

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

Do sends an HTTP request and returns an HTTP response, following policy (such as redirects, cookies, auth) as configured on the client.

func (*Client) HTTPClient

func (c *Client) HTTPClient() (HTTPClient, error)

HTTPClient returns the current or inner HTTP client for load balancing.

func (*Client) NewRequest

func (c *Client) NewRequest(
	ctx context.Context,
	method string,
	url string,
	body io.Reader,
) (*http.Request, error)

NewRequest returns a new http.Request given a method, URL, and optional body.

func (*Client) R

func (c *Client) R(method string, url string) *RequestWithClient

R is the shortcut to create a Request given a method, URL with default request options.

type ClientOption

type ClientOption func(*ClientOptions)

ClientOption abstracts a function to modify client options.

func AllowTraceRequestHeaders

func AllowTraceRequestHeaders(keys []string) ClientOption

AllowTraceRequestHeaders creates an option to set allowed headers for tracing.

func AllowTraceResponseHeaders

func AllowTraceResponseHeaders(keys []string) ClientOption

AllowTraceResponseHeaders creates an option to set allowed headers for tracing.

func EnableClientTrace

func EnableClientTrace(enabled bool) ClientOption

EnableClientTrace creates an option to enable the HTTP client trace.

func WithAuthenticator

func WithAuthenticator(authenticator authscheme.HTTPClientAuthenticator) ClientOption

WithAuthenticator creates an option to set the default authenticator.

func WithCustomAttributesFunc

func WithCustomAttributesFunc(fn CustomAttributesFunc) ClientOption

WithCustomAttributesFunc sets the function to add custom attributes to spans and metrics.

func WithGetEnvFunc

func WithGetEnvFunc(getter goenvconf.GetEnvFunc) ClientOption

WithGetEnvFunc returns a function to set the GetEnvFunc getter to [HTTPClientAuthenticatorOptions].

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) ClientOption

WithHTTPClient create an option to set the HTTP client.

func WithLogger

func WithLogger(logger *slog.Logger) ClientOption

WithLogger create an option to set the logger.

func WithMetricHighCardinalityPath

func WithMetricHighCardinalityPath(enabled bool) ClientOption

WithMetricHighCardinalityPath enables high cardinality path on metrics.

func WithRetry

WithRetry creates an option to set the default retry policy.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout creates an option to set the default timeout.

func WithTraceHighCardinalityPath

func WithTraceHighCardinalityPath(enabled bool) ClientOption

WithTraceHighCardinalityPath enables high cardinality path on traces.

func WithTracer

func WithTracer(tracer trace.Tracer) ClientOption

WithTracer create an option to set the tracer.

func WithUserAgent

func WithUserAgent(userAgent string) ClientOption

WithUserAgent creates an option to set the user agent.

type ClientOptions

type ClientOptions struct {
	RequestOptions
	authscheme.HTTPClientAuthenticatorOptions

	HTTPClient *http.Client
}

ClientOptions defines options for the client.

func NewClientOptions

func NewClientOptions(options ...ClientOption) *ClientOptions

NewClientOptions create a new ClientOptions instance.

func (*ClientOptions) Clone

func (co *ClientOptions) Clone(options ...ClientOption) *ClientOptions

Clone creates a new ClientOptions instance with copied values.

func (*ClientOptions) GetRequestOptions

func (co *ClientOptions) GetRequestOptions() *RequestOptions

GetRequestOptions gets the inner RequestOptions.

type CustomAttributesFunc

type CustomAttributesFunc func(*Request) []attribute.KeyValue

CustomAttributesFunc abstracts a function to add custom attributes to spans and metrics.

type HTTPClient

type HTTPClient interface {
	// NewRequest returns a new http.Request given a method, URL, and optional body.
	NewRequest(
		ctx context.Context,
		method string,
		url string,
		body io.Reader,
	) (*http.Request, error)
	// Do sends an HTTP request and returns an HTTP response, following policy
	// (such as redirects, cookies, auth) as configured on the client.
	Do(req *http.Request) (*http.Response, error)
}

HTTPClient abstracts an HTTP client with methods.

type HTTPClientGetter

type HTTPClientGetter interface {
	// HTTPClient returns the current or inner HTTP client for load balancing.
	HTTPClient() (HTTPClient, error)
}

HTTPClientGetter abstracts an interface to get an HTTP client.

type HTTPClientMetrics

type HTTPClientMetrics struct {
	// Number of outbound HTTP connections that are currently active or idle on the client.
	OpenConnections metric.Int64UpDownCounter
	// The duration of the successfully established outbound HTTP connections.
	ConnectionDuration metric.Float64Histogram
	// The gauge metric to observe the server state.
	ServerState metric.Int64Gauge
	// The duration of how long the connection was previously idle.
	IdleConnectionDuration metric.Float64Histogram
	// The duration of the server for responding to the first byte.
	ServerDuration metric.Float64Histogram
	// Number of active HTTP requests.
	ActiveRequests metric.Int64UpDownCounter
	// Histogram metrics of the request body size.
	RequestBodySize metric.Int64Histogram
	// Histogram metrics of the response body size.
	ResponseBodySize metric.Int64Histogram
	// Duration of HTTP client requests.
	RequestDuration metric.Float64Histogram
	// The duration of DNS lookup operations performed by the HTTP client.
	DNSLookupDuration metric.Float64Histogram
}

HTTPClientMetrics hold semantic metrics of an HTTP client. These metrics are inspired by OpenTelemetry semantic specifications and built-in .NET system metrics.

func GetHTTPClientMetrics

func GetHTTPClientMetrics() *HTTPClientMetrics

GetHTTPClientMetrics gets the global HTTPClientMetrics instance.

func NewHTTPClientMetrics

func NewHTTPClientMetrics(
	meter metric.Meter,
	clientTraceEnabled bool,
) (*HTTPClientMetrics, error)

NewHTTPClientMetrics creates an HTTPClientMetrics instance from the OpenTelemetry meter.

type HTTPClientTracer

type HTTPClientTracer interface {
	trace.Span

	// Context returns the internal context.
	Context() context.Context
	// TotalTime returns the total time.
	TotalTime() time.Duration
	// RemoteAddress gets the remote address if exists.
	RemoteAddress() string
	// SetMetricAttributes sets common attributes for metrics.
	SetMetricAttributes(attrs []attribute.KeyValue)
}

HTTPClientTracer abstracts an interface to collect traces and metrics data of an HTTP request.

type HTTPDialerConfig

type HTTPDialerConfig struct {
	// The maximum amount of time a dial will wait for a connect to complete.
	// If Deadline is also set, it may fail earlier.
	Timeout *goutils.Duration `json:"timeout,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"timeout"`
	// Keep-alive probes are enabled by default.
	KeepAliveEnabled *bool `json:"keepAliveEnabled,omitempty" yaml:"keepAliveEnabled"`
	// KeepAliveInterval is the time between keep-alive probes. If zero, a default value of 15 seconds is used.
	KeepAliveInterval *goutils.Duration `json:"keepAliveInterval,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"keepAliveInterval"`
	// KeepAliveCount is the maximum number of keep-alive probes that can go unanswered before dropping a connection.
	// If zero, a default value of 9 is used.
	KeepAliveCount *int `json:"keepAliveCount,omitempty" jsonschema:"nullable,min=0" yaml:"keepAliveCount"`
	// KeepAliveIdle is the time that the connection must be idle before the first keep-alive probe is sent.
	// If zero, a default value of 15 seconds is used.
	KeepAliveIdle *goutils.Duration `json:"keepAliveIdle,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"keepAliveIdle"`
	// FallbackDelay specifies the length of time to wait before spawning a RFC 6555 Fast Fallback connection.
	// That is, this is the amount of time to wait for IPv6 to succeed before assuming that IPv6 is misconfigured and falling back to IPv4.
	// If zero, a default delay of 300ms is used. A negative value disables Fast Fallback support.
	FallbackDelay *goutils.Duration `json:"fallbackDelay,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"fallbackDelay"`
}

HTTPDialerConfig contains options the http.Dialer to connect to an address.

func (HTTPDialerConfig) Equal

func (c HTTPDialerConfig) Equal(target HTTPDialerConfig) bool

Equal checks if this instance equals the target.

func (*HTTPDialerConfig) IsZero

func (c *HTTPDialerConfig) IsZero() bool

IsZero if the current instance is empty.

type HTTPTransportConfig

type HTTPTransportConfig struct {
	// Options the http.Dialer to connect to an address
	Dialer *HTTPDialerConfig `json:"dialer,omitempty" yaml:"dialer"`
	// Idle connection timeout. The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit.
	IdleConnTimeout *goutils.Duration `json:"idleConnTimeout,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"idleConnTimeout"`
	// Response header timeout, if non-zero, specifies the amount of time to wait for a server's response headers after fully writing the request (including its body, if any).
	// This time does not include the time to read the response body.
	// This timeout is used to cover cases where the tcp connection works but the server never answers.
	ResponseHeaderTimeout *goutils.Duration `json:"responseHeaderTimeout,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"responseHeaderTimeout"`
	// TLS handshake timeout is the maximum amount of time to wait for a TLS handshake. Zero means no timeout.
	TLSHandshakeTimeout *goutils.Duration `json:"tlsHandshakeTimeout,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"tlsHandshakeTimeout"`
	// Expect continue timeout, if non-zero, specifies the amount of time to wait for a server's first response headers after fully writing the request headers if the request has an "Expect: 100-continue" header.
	ExpectContinueTimeout *goutils.Duration `json:"expectContinueTimeout,omitempty" jsonschema:"oneof_ref=#/$defs/Duration,oneof_type=null" yaml:"expectContinueTimeout"`
	// MaxIdleConns controls the maximum number of idle (keep-alive) connections across all hosts. Zero means no limit.
	MaxIdleConns *int `json:"maxIdleConns,omitempty" jsonschema:"nullable,min=0" yaml:"maxIdleConns"`
	// MaxIdleConnsPerHost, if non-zero, controls the maximum idle (keep-alive) connections to keep per-host.
	MaxIdleConnsPerHost *int `json:"maxIdleConnsPerHost,omitempty" jsonschema:"nullable,min=0" yaml:"maxIdleConnsPerHost"`
	// MaxConnsPerHost optionally limits the total number of connections per host, including connections in the dialing, active, and idle states.
	// On limit violation, dials will block. Zero means no limit.
	MaxConnsPerHost *int `json:"maxConnsPerHost,omitempty" jsonschema:"nullable,min=0" yaml:"maxConnsPerHost"`
	// MaxResponseHeaderBytes specifies a limit on how many response bytes are allowed in the server's response header.
	// Zero means to use a default limit.
	MaxResponseHeaderBytes *int64 `json:"maxResponseHeaderBytes,omitempty" jsonschema:"nullable,min=0" yaml:"maxResponseHeaderBytes"`
	// ReadBufferSize specifies the size of the read buffer used when reading from the transport.
	// If zero, a default (currently 4KB) is used.
	ReadBufferSize *int `json:"readBufferSize,omitempty" jsonschema:"nullable,min=0" yaml:"readBufferSize"`
	// WriteBufferSize specifies the size of the write buffer used when writing to the transport.
	// If zero, a default (currently 4KB) is used.
	WriteBufferSize *int `json:"writeBufferSize,omitempty" jsonschema:"nullable,min=0" yaml:"writeBufferSize"`
	// DisableKeepAlives, if true, disables HTTP keep-alives and will only use the connection to the server for a single HTTP request.
	// This is unrelated to the similarly named TCP keep-alives.
	DisableKeepAlives bool `json:"disableKeepAlives,omitempty" yaml:"disableKeepAlives"`
	// ForceAttemptHTTP2 controls whether HTTP/2 is enabled when a non-zero Dial, DialTLS, or DialContext func or TLSClientConfig is provided.
	// Default is true.
	ForceAttemptHTTP2 *bool `json:"forceAttemptHTTP2,omitempty" yaml:"forceAttemptHTTP2"`
}

HTTPTransportConfig stores the http.Transport configuration for the http client.

func (HTTPTransportConfig) Equal

Equal checks if this instance equals the target.

func (*HTTPTransportConfig) IsZero

func (c *HTTPTransportConfig) IsZero() bool

IsZero if the current instance is empty.

type Request

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

Request represents the details and configuration for an individual HTTP(S) request. It encompasses URL, headers, method, body, proxy settings, timeouts, and other configurations necessary for customizing the request and its execution.

func NewRequest

func NewRequest(method string, url string, options *RequestOptions) *Request

NewRequest creates a raw request without client options.

func (*Request) Authenticator

func (r *Request) Authenticator() authscheme.HTTPClientAuthenticator

Authenticator returns the HTTP client authenticator.

func (*Request) Body

func (r *Request) Body() io.Reader

Body returns the request body.

func (*Request) Clone

func (r *Request) Clone() *Request

Clone creates a new request. The body can be nil if it was already read.

func (*Request) Execute

func (r *Request) Execute(
	ctx context.Context,
	client HTTPClientGetter,
) (*http.Response, error)

Execute handles the HTTP request to the remote server.

func (*Request) Header

func (r *Request) Header() http.Header

Header returns the request header fields to be sent by the client.

HTTP defines that header names are case-insensitive. The request parser implements this by using CanonicalHeaderKey, making the first character and any characters following a hyphen uppercase and the rest lowercase.

For client requests, certain headers such as Content-Length and Connection are automatically written when needed and values in Header may be ignored. See the documentation for the Request.Write method.

func (*Request) Method

func (r *Request) Method() string

Method returns the request method.

func (*Request) Retry

Retry returns the retry policy.

func (*Request) SetAuthenticator

func (r *Request) SetAuthenticator(authenticator authscheme.HTTPClientAuthenticator) *Request

SetAuthenticator sets the HTTP authenticator.

func (*Request) SetBody

func (r *Request) SetBody(body io.Reader) *Request

SetBody sets the request body.

func (*Request) SetMethod

func (r *Request) SetMethod(method string) *Request

SetMethod sets the request method.

func (*Request) SetRetry

func (r *Request) SetRetry(retry retrypolicy.RetryPolicy[*http.Response]) *Request

SetRetry sets the retry policy.

func (*Request) SetTimeout

func (r *Request) SetTimeout(timeout time.Duration) *Request

SetTimeout sets the request timeout.

func (*Request) SetURL

func (r *Request) SetURL(value string) *Request

SetURL sets the request URL.

func (*Request) Timeout

func (r *Request) Timeout() time.Duration

Timeout returns the request timeout.

func (*Request) URL

func (r *Request) URL() string

URL returns the request URL.

type RequestOption

type RequestOption func(*RequestOptions)

RequestOption abstracts a function to modify request options.

type RequestOptions

type RequestOptions struct {
	Logger                      *slog.Logger
	Tracer                      trace.Tracer
	TraceHighCardinalityPath    bool
	MetricHighCardinalityPath   bool
	CustomAttributesFunc        CustomAttributesFunc
	Retry                       retrypolicy.RetryPolicy[*http.Response]
	Timeout                     time.Duration
	Authenticator               authscheme.HTTPClientAuthenticator
	ClientTraceEnabled          bool
	UserAgent                   string
	AllowedTraceRequestHeaders  []string
	AllowedTraceResponseHeaders []string
}

RequestOptions defines options for the request.

func (*RequestOptions) GetRequestOptions

func (ro *RequestOptions) GetRequestOptions() *RequestOptions

GetRequestOptions gets the inner RequestOptions.

func (*RequestOptions) IsTraceRequestHeadersEnabled

func (ro *RequestOptions) IsTraceRequestHeadersEnabled() bool

IsTraceRequestHeadersEnabled checks if the trace request headers are enabled.

func (*RequestOptions) IsTraceResponseHeadersEnabled

func (ro *RequestOptions) IsTraceResponseHeadersEnabled() bool

IsTraceResponseHeadersEnabled checks if the trace request headers are enabled.

type RequestOptionsGetter

type RequestOptionsGetter interface {
	GetRequestOptions() *RequestOptions
}

RequestOptionsGetter abstracts an interface to get the RequestOptions.

type RequestWithClient

type RequestWithClient struct {
	*Request
	// contains filtered or unexported fields
}

RequestWithClient embeds the Request with an HTTPClient to make the Execute method shorter.

func NewRequestWithClient

func NewRequestWithClient(req *Request, client HTTPClientGetter) *RequestWithClient

NewRequestWithClient creates a new RequestWithClient instance.

func (*RequestWithClient) Execute

func (rwc *RequestWithClient) Execute(ctx context.Context) (*http.Response, error)

Execute handles the HTTP request to the remote server.

Directories

Path Synopsis
authscheme
Package authscheme defines types and interfaces for security schemes.
Package authscheme defines types and interfaces for security schemes.
basicauth
Package basicauth implements authentication interfaces for the basic security scheme.
Package basicauth implements authentication interfaces for the basic security scheme.
httpauth
Package httpauth implements authentication interfaces for the http security scheme.
Package httpauth implements authentication interfaces for the http security scheme.
oauth2scheme
Package oauth2scheme implements authentication interfaces for OAuth2 security scheme.
Package oauth2scheme implements authentication interfaces for OAuth2 security scheme.

Jump to

Keyboard shortcuts

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