httpclient

package
v1.19.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithBasicAuth

func WithBasicAuth(username string, password string) httpclientcontract.RequestOption

func WithBearerToken

func WithBearerToken(token string) httpclientcontract.RequestOption

func WithBody

func WithBody(body any) httpclientcontract.RequestOption

func WithHeader

func WithHeader(key string, value string) httpclientcontract.RequestOption

func WithHeaders

func WithHeaders(headers map[string]string) httpclientcontract.RequestOption

func WithJson

func WithJson(data any) httpclientcontract.RequestOption

func WithMaxResponseBodyBytes

func WithMaxResponseBodyBytes(maxResponseBodyBytes int) httpclientcontract.RequestOption

func WithQuery

func WithQuery(key string, value string) httpclientcontract.RequestOption

func WithQueryParams

func WithQueryParams(parameters map[string]string) httpclientcontract.RequestOption

func WithTimeout

func WithTimeout(timeout time.Duration) httpclientcontract.RequestOption

Types

type AuthorizationOptions

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

func NewAuthorizationOptions

func NewAuthorizationOptions() *AuthorizationOptions

func (*AuthorizationOptions) Basic

func (*AuthorizationOptions) Bearer

func (instance *AuthorizationOptions) Bearer() string

func (*AuthorizationOptions) SetBasic

func (*AuthorizationOptions) SetBearer

func (instance *AuthorizationOptions) SetBearer(bearer string)

type BasicAuthorizationOptions

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

func (*BasicAuthorizationOptions) Password

func (instance *BasicAuthorizationOptions) Password() string

func (*BasicAuthorizationOptions) SetPassword

func (instance *BasicAuthorizationOptions) SetPassword(password string)

func (*BasicAuthorizationOptions) SetUsername

func (instance *BasicAuthorizationOptions) SetUsername(username string)

func (*BasicAuthorizationOptions) Username

func (instance *BasicAuthorizationOptions) Username() string

type HttpClient

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

func NewDefaultHttpClient

func NewDefaultHttpClient() *HttpClient

func NewHttpClient

func NewHttpClient(config *HttpClientConfig) *HttpClient

NewHttpClient builds a client over its own net/http transport, which owns an idle connection pool: hold the client for as long as the application calls the service it points at, and close it when it is done, rather than building one per call. A nil configuration panics at the point the wiring mistake is made — NewDefaultHttpClient is the constructor that asks for the defaults.

func (*HttpClient) Close added in v1.19.0

func (instance *HttpClient) Close() error

Close releases the idle connections the client's own transport is holding. Every client builds its own pool — a hundred connections per host by default, kept for ninety seconds — and dropping the last reference to the client releases none of them, because each parked connection has a read loop of its own keeping the transport reachable. Close does not abort requests in flight, and the client stays usable afterwards: it dials again.

func (*HttpClient) Delete

func (instance *HttpClient) Delete(urlString string, options ...httpclientcontract.RequestOption) (httpclientcontract.Response, error)

func (*HttpClient) Get

func (instance *HttpClient) Get(urlString string, options ...httpclientcontract.RequestOption) (httpclientcontract.Response, error)

func (*HttpClient) Patch

func (instance *HttpClient) Patch(urlString string, body any, options ...httpclientcontract.RequestOption) (httpclientcontract.Response, error)

func (*HttpClient) Post

func (instance *HttpClient) Post(urlString string, body any, options ...httpclientcontract.RequestOption) (httpclientcontract.Response, error)

func (*HttpClient) Put

func (instance *HttpClient) Put(urlString string, body any, options ...httpclientcontract.RequestOption) (httpclientcontract.Response, error)

func (*HttpClient) Request

func (instance *HttpClient) Request(method string, urlString string, options ...httpclientcontract.RequestOption) (httpclientcontract.Response, error)

func (*HttpClient) RequestStream

func (instance *HttpClient) RequestStream(
	method string,
	urlString string,
	options ...httpclientcontract.RequestOption,
) (httpclientcontract.StreamResponse, error)

RequestStream hands the caller a response whose body is still on the wire. The caller OWNS it and must Close it on every path, including the ones that never read it — a status it does not like, an error it returns instead — because the streaming client carries no whole-request deadline: an unclosed stream pins its connection and its descriptor for as long as the process lives. RequestStreamWithContext is the variant that can bound one from the outside. The response body cap applies only when the caller asked for one; the default belongs to Request, which holds the whole body in memory.

func (*HttpClient) RequestStreamWithContext added in v1.19.0

func (instance *HttpClient) RequestStreamWithContext(
	contextInstance context.Context,
	method string,
	urlString string,
	options ...httpclientcontract.RequestOption,
) (httpclientcontract.StreamResponse, error)

RequestStreamWithContext is RequestStream bound to a context: cancelling it ends the request and the body read, which is the only remedy for a stream a server never ends. The close obligation described on RequestStream is unchanged — cancelling releases the connection, it does not close the StreamResponse for the caller.

func (*HttpClient) SetBaseUrl

func (instance *HttpClient) SetBaseUrl(baseUrl string)

func (*HttpClient) SetHeader

func (instance *HttpClient) SetHeader(key string, value string)

SetHeader stores the header under its canonical spelling, the one the constructor stores under: the map is applied to every request with Set, which canonicalizes, so rotating a credential under a different spelling than the one it was configured with used to leave two live entries whose survivor was chosen by map iteration order — a different credential per request. Canonicalizing here makes the collision structurally impossible, and a rotation overwrites the entry it means to.

func (*HttpClient) SetTimeout

func (instance *HttpClient) SetTimeout(timeout time.Duration)

type HttpClientConfig

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

func NewHttpClientConfig

func NewHttpClientConfig(
	baseUrl string,
	timeout time.Duration,
	headers map[string]string,
) *HttpClientConfig

func (*HttpClientConfig) BaseUrl

func (instance *HttpClientConfig) BaseUrl() string

func (*HttpClientConfig) Headers

func (instance *HttpClientConfig) Headers() map[string]string

func (*HttpClientConfig) Timeout

func (instance *HttpClientConfig) Timeout() time.Duration

func (*HttpClientConfig) Transport added in v1.14.0

func (instance *HttpClientConfig) Transport() *TransportConfig

func (*HttpClientConfig) WithTransport added in v1.14.0

func (instance *HttpClientConfig) WithTransport(transport *TransportConfig) *HttpClientConfig

type RequestOptions

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

func NewRequestOptions

func NewRequestOptions() *RequestOptions

func (*RequestOptions) Authorization

func (instance *RequestOptions) Authorization() httpclientcontract.AuthorizationOptions

func (*RequestOptions) Body

func (instance *RequestOptions) Body() any

func (*RequestOptions) ContentType

func (instance *RequestOptions) ContentType() string

func (*RequestOptions) Headers

func (instance *RequestOptions) Headers() map[string]string

Headers hands out a copy: the live map invited writes that bypass the canonicalization SetHeader exists to enforce, and a non-canonical spelling planted through the getter next to the canonical one made the request-time winner a map-iteration choice — in what is often a credential header, the exact nondeterminism the setters refuse. The setters remain the one door that writes.

func (*RequestOptions) MaxResponseBodyBytes

func (instance *RequestOptions) MaxResponseBodyBytes() int

func (*RequestOptions) Query

func (instance *RequestOptions) Query() map[string]string

Query hands out a copy under the same single-door rule as Headers.

func (*RequestOptions) SetBasicAuth

func (instance *RequestOptions) SetBasicAuth(username string, password string)

func (*RequestOptions) SetBearerToken

func (instance *RequestOptions) SetBearerToken(token string)

func (*RequestOptions) SetBody

func (instance *RequestOptions) SetBody(body any)

func (*RequestOptions) SetHeader

func (instance *RequestOptions) SetHeader(key string, value string)

SetHeader stores the key canonicalized, so two spellings of one header land on one entry deterministically — the last sequential write wins — instead of surviving as two map entries whose request-time winner map iteration chose.

func (*RequestOptions) SetHeaders

func (instance *RequestOptions) SetHeaders(headers map[string]string)

SetHeaders refuses a map carrying two spellings that collapse onto one header, the way the client config constructor does: inside one map there is no sequential order to make the survivor deterministic.

func (*RequestOptions) SetJson

func (instance *RequestOptions) SetJson(data any)

func (*RequestOptions) SetMaxResponseBodyBytes

func (instance *RequestOptions) SetMaxResponseBodyBytes(maxResponseBodyBytes int)

func (*RequestOptions) SetQuery

func (instance *RequestOptions) SetQuery(key string, value string)

func (*RequestOptions) SetQueryParams

func (instance *RequestOptions) SetQueryParams(parameters map[string]string)

func (*RequestOptions) SetTimeout

func (instance *RequestOptions) SetTimeout(timeout time.Duration)

func (*RequestOptions) Timeout

func (instance *RequestOptions) Timeout() time.Duration

type Response

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

func NewResponse

func NewResponse(
	statusCode int,
	status string,
	headers nethttp.Header,
	body []byte,
	request *nethttp.Request,
) *Response

func (*Response) Body

func (instance *Response) Body() []byte

Body hands out the live slice under the same single-owner reading as Headers.

func (*Response) Headers

func (instance *Response) Headers() nethttp.Header

Headers hands out the live map, not a copy: the response is the caller's own result object with a single owner, so a mutation only changes what that owner later reads — including String and Json. Callers that fan a response out across goroutines copy first.

func (*Response) IsClientError

func (instance *Response) IsClientError() bool

func (*Response) IsServerError

func (instance *Response) IsServerError() bool

func (*Response) IsSuccess

func (instance *Response) IsSuccess() bool

func (*Response) Json

func (instance *Response) Json(target any) error

func (*Response) Request

func (instance *Response) Request() *nethttp.Request

func (*Response) Status

func (instance *Response) Status() string

func (*Response) StatusCode

func (instance *Response) StatusCode() int

func (*Response) String

func (instance *Response) String() string

type StreamResponse

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

func NewStreamResponse

func NewStreamResponse(statusCode int, headers nethttp.Header, body io.ReadCloser) *StreamResponse

func (*StreamResponse) Body

func (instance *StreamResponse) Body() io.ReadCloser

Body hands back the live body. After Close it answers with a reader that fails on the first read instead of a nil one: the whole point of Close on a stream is that another goroutine — a watchdog bounding a stream nothing else can end — may call it while the consumer is deciding to read, and a consumer written the ordinary way, io.Copy(destination, streamResponse.Body()), would dereference that nil and take the process down.

func (*StreamResponse) Close

func (instance *StreamResponse) Close() error

func (*StreamResponse) Headers

func (instance *StreamResponse) Headers() nethttp.Header

func (*StreamResponse) StatusCode

func (instance *StreamResponse) StatusCode() int

type TransportConfig added in v1.14.0

type TransportConfig struct {
	DialTimeout time.Duration
	KeepAlive   time.Duration

	MaxIdleConns int

	/* MaxIdleConnsPerHost bounds the idle pool of a single host. net/http defaults it to two, which caps the whole pool for a client bound to one BaseUrl: every connection past the second is closed as soon as it goes idle, so a burst dials as many sockets as it has requests and leaves almost all of them in TIME_WAIT for the MSL, until the ephemeral port range runs out and every request fails to connect. It defaults to MaxIdleConns and follows an override of it. */
	MaxIdleConnsPerHost int

	IdleConnTimeout       time.Duration
	TlsHandshakeTimeout   time.Duration
	ExpectContinueTimeout time.Duration
	ResponseHeaderTimeout time.Duration
}

TransportConfig overrides the transport melody builds for a client. Every field reads a non-positive value as "not set" and falls back to the default beside it, so the meanings net/http gives to zero — MaxIdleConns zero for an unbounded pool, IdleConnTimeout or ResponseHeaderTimeout zero for no deadline — and the meaning net.Dialer gives to a negative KeepAlive cannot be reached through this type. A deployment that needs one of them asks for a duration large enough to be the same thing in practice.

func DefaultTransportConfig added in v1.14.0

func DefaultTransportConfig() *TransportConfig

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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