Documentation
¶
Overview ¶
Package client is an HTTP client wrapping net/http.Client, with a testing surface built in: stub callbacks (Fake), response sequences, request recording, and assertions on what was sent. A PendingRequest is the fluent builder -- Get, Post, WithToken, WithHeaders, Timeout, Retry -- that materialises into an *http.Request and sends it.
The Factory holds the global configuration (middleware, options, stubs) and issues PendingRequest instances. It is the entry point for both the application and the test: a test calls Factory.Fake to intercept requests and Factory.AssertSent to verify them.
Why not a third-party HTTP client library ¶
Go's net/http is the standard, and the testing surface -- Fake, Sequence, Record, AssertSent -- is the value this package adds. A wrapper around a third-party HTTP client would be a dependency for a dependency.
Index ¶
- Constants
- func DontTruncate()
- func Truncate()
- func TruncateAt(length int)
- type AssertionError
- type Batch
- func (b *Batch) As(key string) *PendingRequest
- func (b *Batch) Before(callback func()) *Batch
- func (b *Batch) Catch(callback func(error, int)) *Batch
- func (b *Batch) Concurrency(limit int) *Batch
- func (b *Batch) Defer() *deferpkg.DeferredCallback
- func (b *Batch) Finally(callback func()) *Batch
- func (b *Batch) Finished() bool
- func (b *Batch) GetRequests() []batchRequest
- func (b *Batch) HasFailures() bool
- func (b *Batch) NewRequest() *PendingRequest
- func (b *Batch) ProcessedRequests() int
- func (b *Batch) Progress(callback func(*Response, int)) *Batch
- func (b *Batch) Send() (map[string]*Response, error)
- func (b *Batch) Then(callback func(map[string]*Response)) *Batch
- type BatchInProgressError
- type ConnectionException
- type Dispatcher
- type Factory
- func (f *Factory) AllowStrayRequests(only ...string) *Factory
- func (f *Factory) AssertNotSent(callback func(*http.Request) bool) error
- func (f *Factory) AssertNothingSent() error
- func (f *Factory) AssertSent(callback func(*http.Request) bool) error
- func (f *Factory) AssertSentCount(count int) error
- func (f *Factory) AssertSentInOrder(callbacks ...func(*http.Request) bool) error
- func (f *Factory) AssertSequencesAreEmpty() error
- func (f *Factory) Client() *http.Client
- func (f *Factory) CreatePendingRequest() *PendingRequest
- func (f *Factory) FailedConnection(message string) StubCallback
- func (f *Factory) FailedRequest(body any, status int, headers http.Header) *RequestException
- func (f *Factory) Fake(callbacks ...StubCallback) *Factory
- func (f *Factory) FakeSequence(urlPattern string) *ResponseSequence
- func (f *Factory) GetDispatcher() Dispatcher
- func (f *Factory) GetGlobalMiddleware() []func(*http.Request, http.RoundTripper) http.RoundTripper
- func (f *Factory) GlobalMiddleware(middleware ...func(*http.Request, http.RoundTripper) http.RoundTripper) *Factory
- func (f *Factory) GlobalOptions(fn func(*http.Client)) *Factory
- func (f *Factory) GlobalRequestMiddleware(middleware ...func(*http.Request) error) *Factory
- func (f *Factory) GlobalResponseMiddleware(middleware ...func(*http.Response) error) *Factory
- func (f *Factory) Pool() *Pool
- func (f *Factory) PreventStrayRequests(prevent bool) *Factory
- func (f *Factory) PreventingStrayRequests() bool
- func (f *Factory) Record() *Factory
- func (f *Factory) RecordRequestResponsePair(req *http.Request, resp *http.Response, err error)
- func (f *Factory) Recorded(callback func(RecordedPair) bool) []RecordedPair
- func (f *Factory) Response(body any, status int, headers http.Header) *http.Response
- func (f *Factory) Sequence() *ResponseSequence
- func (f *Factory) SetDispatcher(dispatcher Dispatcher) *Factory
- func (f *Factory) Stub(callback StubCallback) *Factorydeprecated
- func (f *Factory) StubUrl(urlPattern string, callback StubCallback) *Factory
- type HttpClientException
- type PendingRequest
- func (p *PendingRequest) Accept(ct string) *PendingRequest
- func (p *PendingRequest) AcceptJSON() *PendingRequest
- func (p *PendingRequest) AfterResponse(callback func(*Response) error) *PendingRequest
- func (p *PendingRequest) AllowStrayRequests(only []string) *PendingRequest
- func (p *PendingRequest) AsForm() *PendingRequest
- func (p *PendingRequest) AsJSON() *PendingRequest
- func (p *PendingRequest) AsMultipart() *PendingRequest
- func (p *PendingRequest) Async(async bool) *PendingRequest
- func (p *PendingRequest) Attach(name, contents, filename string, headers map[string]string) *PendingRequest
- func (p *PendingRequest) BaseURL(u string) *PendingRequest
- func (p *PendingRequest) Batch(callback func(*Batch)) *Batch
- func (p *PendingRequest) BeforeSending(callback func(*http.Request) error) *PendingRequest
- func (p *PendingRequest) BodyFormat(format string) *PendingRequest
- func (p *PendingRequest) BuildClient() *http.Client
- func (p *PendingRequest) ConnectTimeout(d time.Duration) *PendingRequest
- func (p *PendingRequest) ContentType(ct string) *PendingRequest
- func (p *PendingRequest) CreateClient(handler http.RoundTripper) *http.Client
- func (p *PendingRequest) Dd() *PendingRequest
- func (p *PendingRequest) Delete(urlStr string, data any) (*Response, error)
- func (p *PendingRequest) DontTruncateExceptions() *PendingRequest
- func (p *PendingRequest) Dump() *PendingRequest
- func (p *PendingRequest) Get(urlStr string, query map[string]string) (*Response, error)
- func (p *PendingRequest) GetOptions() map[string]any
- func (p *PendingRequest) GetPromise() promises.Promise
- func (p *PendingRequest) Head(urlStr string, query map[string]string) (*Response, error)
- func (p *PendingRequest) IsAllowedRequestUrl(url string) bool
- func (p *PendingRequest) MaxRedirects(max int) *PendingRequest
- func (p *PendingRequest) MergeOptions(options ...map[string]any) map[string]any
- func (p *PendingRequest) Patch(urlStr string, data any) (*Response, error)
- func (p *PendingRequest) Pool(callback func(*Pool), concurrency int) (map[string]*Response, error)
- func (p *PendingRequest) Post(urlStr string, data any) (*Response, error)
- func (p *PendingRequest) PreventStrayRequests(prevent bool) *PendingRequest
- func (p *PendingRequest) Put(urlStr string, data any) (*Response, error)
- func (p *PendingRequest) ReplaceHeaders(headers map[string]string) *PendingRequest
- func (p *PendingRequest) Retry(times int, delay time.Duration, when func(*http.Response, error) bool, ...) *PendingRequest
- func (p *PendingRequest) RunBeforeSendingCallbacks(req *http.Request) error
- func (p *PendingRequest) Send(method, urlStr string, query map[string]string, data any) (*Response, error)
- func (p *PendingRequest) SetClient(client *http.Client) *PendingRequest
- func (p *PendingRequest) SetHandler(handler http.RoundTripper) *PendingRequest
- func (p *PendingRequest) Sink(w io.Writer) *PendingRequest
- func (p *PendingRequest) Stub(callback StubCallback) *PendingRequest
- func (p *PendingRequest) Throw(callback func(*Response, *RequestException)) *PendingRequest
- func (p *PendingRequest) ThrowIf(condition bool) *PendingRequest
- func (p *PendingRequest) ThrowUnless(condition bool) *PendingRequest
- func (p *PendingRequest) Timeout(d time.Duration) *PendingRequest
- func (p *PendingRequest) TruncateExceptionsAt(length int) *PendingRequest
- func (p *PendingRequest) WithAttributes(attrs map[string]any) *PendingRequest
- func (p *PendingRequest) WithBasicAuth(username, password string) *PendingRequest
- func (p *PendingRequest) WithBody(content io.Reader, contentType string) *PendingRequest
- func (p *PendingRequest) WithCookies(cookies []*http.Cookie, domain string) *PendingRequest
- func (p *PendingRequest) WithDigestAuth(username, password string) *PendingRequest
- func (p *PendingRequest) WithHeader(name, value string) *PendingRequest
- func (p *PendingRequest) WithHeaders(headers map[string]string) *PendingRequest
- func (p *PendingRequest) WithMiddleware(mw ...func(*http.Request, http.RoundTripper) http.RoundTripper) *PendingRequest
- func (p *PendingRequest) WithOptions(fn func(*http.Client)) *PendingRequest
- func (p *PendingRequest) WithQueryParameters(params map[string]string) *PendingRequest
- func (p *PendingRequest) WithRequestMiddleware(mw ...func(*http.Request) error) *PendingRequest
- func (p *PendingRequest) WithResponseMiddleware(mw ...func(*http.Response) error) *PendingRequest
- func (p *PendingRequest) WithToken(token string, tokenType string) *PendingRequest
- func (p *PendingRequest) WithURLParameters(params map[string]string) *PendingRequest
- func (p *PendingRequest) WithUserAgent(ua string) *PendingRequest
- func (p *PendingRequest) WithoutRedirecting() *PendingRequest
- func (p *PendingRequest) WithoutVerifying() *PendingRequest
- type Pool
- type RecordedPair
- type Request
- func (r *Request) Attributes() map[string]any
- func (r *Request) Body() string
- func (r *Request) Data() map[string]any
- func (r *Request) HTTPRequest() *http.Request
- func (r *Request) HasFile(name, value, filename string) bool
- func (r *Request) HasHeader(key string, value string) bool
- func (r *Request) HasHeaders(headers map[string]string) bool
- func (r *Request) Header(key string) []string
- func (r *Request) Headers() http.Header
- func (r *Request) IsForm() bool
- func (r *Request) IsJSON() bool
- func (r *Request) IsMultipart() bool
- func (r *Request) Method() string
- func (r *Request) SetRequestAttributes(attrs map[string]any) *Request
- func (r *Request) String() string
- func (r *Request) URL() string
- func (r *Request) WithData(data map[string]any) *Request
- type RequestException
- type Response
- func (r *Response) Accepted() bool
- func (r *Response) BadRequest() bool
- func (r *Response) Body() string
- func (r *Response) ClientError() bool
- func (r *Response) Close() error
- func (r *Response) Collect(key string) ([]map[string]any, error)
- func (r *Response) Conflict() bool
- func (r *Response) Cookies() []*http.Cookie
- func (r *Response) Created() bool
- func (r *Response) DdHeaders()
- func (r *Response) DontTruncateExceptions() *Response
- func (r *Response) DumpHeaders() *Response
- func (r *Response) EffectiveURI() string
- func (r *Response) Failed() bool
- func (r *Response) Forbidden() bool
- func (r *Response) Found() bool
- func (r *Response) HTTPResponse() *http.Response
- func (r *Response) HandlerStats() map[string]any
- func (r *Response) Header(name string) string
- func (r *Response) Headers() http.Header
- func (r *Response) JSON(key string, defaultValue any) (any, error)
- func (r *Response) MovedPermanently() bool
- func (r *Response) NoContent() bool
- func (r *Response) NotFound() bool
- func (r *Response) NotModified() bool
- func (r *Response) OK() bool
- func (r *Response) Object(v any) error
- func (r *Response) OnError(callback func(*Response) error) error
- func (r *Response) PaymentRequired() bool
- func (r *Response) Reason() string
- func (r *Response) Redirect() bool
- func (r *Response) RequestTimeout() bool
- func (r *Response) Resource() []byte
- func (r *Response) ServerError() bool
- func (r *Response) Status() int
- func (r *Response) StatusText() string
- func (r *Response) Successful() bool
- func (r *Response) Throw(callback func(*Response, *RequestException)) error
- func (r *Response) ThrowIf(condition bool, callback func(*Response, *RequestException)) error
- func (r *Response) ThrowIfClientError() error
- func (r *Response) ThrowIfServerError() error
- func (r *Response) ThrowIfStatus(statusCode int) error
- func (r *Response) ThrowUnless(condition bool) error
- func (r *Response) ThrowUnlessStatus(statusCode int) error
- func (r *Response) ToException() *RequestException
- func (r *Response) TooManyRequests() bool
- func (r *Response) TruncateExceptionsAt(length int) *Response
- func (r *Response) Unauthorized() bool
- func (r *Response) UnprocessableContent() bool
- func (r *Response) UnprocessableEntity() bool
- type ResponseSequence
- func (s *ResponseSequence) AsStub(urlPattern string) StubCallback
- func (s *ResponseSequence) DontFailWhenEmpty() *ResponseSequence
- func (s *ResponseSequence) IsEmpty() bool
- func (s *ResponseSequence) Push(status int, body string, headers http.Header) *ResponseSequence
- func (s *ResponseSequence) PushFailedConnection(message string) *ResponseSequence
- func (s *ResponseSequence) PushFile(filePath string, status int, headers http.Header) *ResponseSequence
- func (s *ResponseSequence) PushResponse(resp *http.Response) *ResponseSequence
- func (s *ResponseSequence) PushStatus(status int, headers http.Header) *ResponseSequence
- func (s *ResponseSequence) WhenEmpty(status int, body string, headers http.Header) *ResponseSequence
- type StrayRequestError
- type StubCallback
Constants ¶
const DefaultRequestExceptionTruncateAt = 120
DefaultRequestExceptionTruncateAt is how many characters of body summary go in the message, by default.
Variables ¶
This section is empty.
Functions ¶
func DontTruncate ¶
func DontTruncate()
DontTruncate lets the whole body into the message of every request exception built from here on.
func Truncate ¶
func Truncate()
Truncate restores the default truncation length for every request exception built from here on.
func TruncateAt ¶
func TruncateAt(length int)
TruncateAt sets the truncation length for every request exception built from here on.
Types ¶
type AssertionError ¶
type AssertionError struct {
Message string
}
AssertionError is returned by assertion methods when the assertion fails.
func (*AssertionError) Error ¶
func (e *AssertionError) Error() string
type Batch ¶
type Batch struct {
// contains filtered or unexported fields
}
Batch collects requests to send concurrently, with callbacks for progress, error handling, and completion. It uses goroutines to send them.
func (*Batch) As ¶
func (b *Batch) As(key string) *PendingRequest
As adds a named request to the batch.
func (*Batch) Concurrency ¶
Concurrency sets the maximum number of concurrent requests.
func (*Batch) Defer ¶
func (b *Batch) Defer() *deferpkg.DeferredCallback
Defer sends the batch after the response has gone back to the browser, rather than while it is waiting.
The callback it hands back is the one the deferred-callback collection invokes; nothing here runs it, which is what makes it deferred.
func (*Batch) Finally ¶
Finally registers a callback that runs after all requests complete, regardless of success or failure.
func (*Batch) GetRequests ¶
func (b *Batch) GetRequests() []batchRequest
GetRequests returns all requests in the batch.
func (*Batch) HasFailures ¶
HasFailures reports whether any request in the batch failed.
func (*Batch) NewRequest ¶
func (b *Batch) NewRequest() *PendingRequest
NewRequest adds an unnamed request to the batch.
func (*Batch) ProcessedRequests ¶
ProcessedRequests returns the number of requests that have been processed.
func (*Batch) Progress ¶
Progress registers a callback that runs after each successful request. It receives the Response and the index of the completed request.
type BatchInProgressError ¶
type BatchInProgressError struct {
HttpClientException
}
BatchInProgressError is returned by Batch.Send when that batch has already been sent. A batch collects its requests once and dispatches them once, so the second call is a mistake in the calling code rather than a transient failure -- going ahead with it would put every request in the batch on the wire a second time.
func NewBatchInProgressError ¶
func NewBatchInProgressError() *BatchInProgressError
NewBatchInProgressError creates a BatchInProgressError.
type ConnectionException ¶
type ConnectionException struct {
HttpClientException
}
ConnectionException is returned when the request never reached the server: the host did not resolve, the connection was refused, or the transport gave up before a status line came back. There is no Response to inspect, because none arrived.
It is not the same failure as a response that arrived carrying a failing status -- that one is a RequestException. The retry callback is handed this error when the transport failed and the other one when the server answered badly, so a caller that treats them alike is retrying two different problems with one policy.
func NewConnectionException ¶
func NewConnectionException(message string) *ConnectionException
NewConnectionException creates a ConnectionException.
type Dispatcher ¶
type Dispatcher interface {
// Dispatch delivers one event to whoever is listening.
Dispatch(event any)
}
Dispatcher is the event sink the client uses: it fires RequestSending, ResponseReceived and ConnectionFailed.
It runs on the calling goroutine, so a listener that blocks blocks the request. Anything slow belongs on a queue.
type Factory ¶
type Factory struct {
// contains filtered or unexported fields
}
Factory is the entry point for the HTTP client layer. It holds global configuration — middleware, base options, stub callbacks — and issues PendingRequest instances through CreatePendingRequest. In a test, Fake installs a stub that intercepts every outgoing request; AssertSent verifies what was sent.
The zero value is usable: it creates a PendingRequest backed by http.DefaultClient with no stubs and no middleware.
func NewFactory ¶
NewFactory creates a Factory with the given HTTP client. If client is nil, http.DefaultClient is used.
func (*Factory) AllowStrayRequests ¶
AllowStrayRequests allows stray requests, optionally limited to specific URLs. When only is empty, all stray requests are allowed.
func (*Factory) AssertNotSent ¶
AssertNotSent asserts that no request matching the callback was sent.
func (*Factory) AssertNothingSent ¶
AssertNothingSent asserts that no requests were sent at all.
func (*Factory) AssertSent ¶
AssertSent asserts that a request matching the callback was sent. The callback receives the sent *http.Request and returns true if it matches.
func (*Factory) AssertSentCount ¶
AssertSentCount asserts that exactly count requests were sent.
func (*Factory) AssertSentInOrder ¶
AssertSentInOrder asserts that requests matching the given callbacks were sent in the specified order.
func (*Factory) AssertSequencesAreEmpty ¶
AssertSequencesAreEmpty asserts that all registered ResponseSequences have been fully consumed.
func (*Factory) CreatePendingRequest ¶
func (f *Factory) CreatePendingRequest() *PendingRequest
CreatePendingRequest creates a new PendingRequest backed by this Factory.
func (*Factory) FailedConnection ¶
func (f *Factory) FailedConnection(message string) StubCallback
FailedConnection is a stub that fails to connect.
When no message is given, the error names the host instead, because a test that asserts on the text is asserting on the host.
func (*Factory) FailedRequest ¶
FailedRequest is the RequestException a stub hands back when it wants the caller to see a failure it can inspect.
func (*Factory) Fake ¶
func (f *Factory) Fake(callbacks ...StubCallback) *Factory
Fake installs stub callbacks that intercept outgoing requests. When stubs are installed, requests are routed through them instead of the wire. Each callback receives the *http.Request; return a (*http.Response, nil) to simulate a successful response, or (nil, error) for a connection failure.
factory.Fake(func(r *http.Request) (*http.Response, error) {
return client.NewResponse(200, `{"ok":true}`), nil
})
func (*Factory) FakeSequence ¶
func (f *Factory) FakeSequence(urlPattern string) *ResponseSequence
FakeSequence registers a ResponseSequence for the given URL pattern. Each call to a matching URL consumes the next response in the sequence.
func (*Factory) GetDispatcher ¶
func (f *Factory) GetDispatcher() Dispatcher
GetDispatcher is the dispatcher the client fires into, or nil when nobody is listening.
func (*Factory) GetGlobalMiddleware ¶
func (f *Factory) GetGlobalMiddleware() []func(*http.Request, http.RoundTripper) http.RoundTripper
GetGlobalMiddleware is the middleware Factory.GlobalMiddleware added.
func (*Factory) GlobalMiddleware ¶
func (f *Factory) GlobalMiddleware(middleware ...func(*http.Request, http.RoundTripper) http.RoundTripper) *Factory
GlobalMiddleware adds middleware applied to every request-response cycle.
func (*Factory) GlobalOptions ¶
GlobalOptions sets global options on the underlying HTTP client.
func (*Factory) GlobalRequestMiddleware ¶
GlobalRequestMiddleware adds middleware applied before every request is sent.
func (*Factory) GlobalResponseMiddleware ¶
GlobalResponseMiddleware adds middleware applied after every response is received.
func (*Factory) PreventStrayRequests ¶
PreventStrayRequests enables prevention of requests that do not match any stub. When enabled, an unmatched request fails with StrayRequestError.
func (*Factory) PreventingStrayRequests ¶
PreventingStrayRequests reports whether stray request prevention is active.
func (*Factory) Record ¶
Record enables request-response recording. Every sent request and its response (or error) is stored for later assertion.
func (*Factory) RecordRequestResponsePair ¶
RecordRequestResponsePair stores a request-response pair.
func (*Factory) Recorded ¶
func (f *Factory) Recorded(callback func(RecordedPair) bool) []RecordedPair
Recorded returns the recorded request-response pairs, optionally filtered by the callback. If callback is nil, all pairs are returned.
func (*Factory) Response ¶
Response is a stub response for a fake to hand back.
A nil body produces an empty body; anything that is not a string or a []byte is JSON-encoded and the Content-Type header is set.
It is a method and not a package function because the package already has a type named Response.
func (*Factory) Sequence ¶
func (f *Factory) Sequence() *ResponseSequence
Sequence is a ResponseSequence the caller installs itself.
Factory.FakeSequence is the same sequence already wired to a URL pattern. This one is registered for AssertSequencesAreEmpty and handed back bare, for a caller that builds its own stub around it.
func (*Factory) SetDispatcher ¶
func (f *Factory) SetDispatcher(dispatcher Dispatcher) *Factory
SetDispatcher sets the dispatcher the client fires its events into. It is a setter rather than a constructor argument, since most callers never need one.
func (*Factory) Stub
deprecated
func (f *Factory) Stub(callback StubCallback) *Factory
Stub registers a stub callback for requests matching the given URL.
Deprecated: use Fake instead, which covers the same use case without the URL-matching layer that duplicates what callers already do in the callback.
func (*Factory) StubUrl ¶
func (f *Factory) StubUrl(urlPattern string, callback StubCallback) *Factory
StubUrl fakes one URL pattern with one canned response.
It accepts the StubCallback that a status, a body, a closure or a sequence would all collapse into, and Factory.Response builds the canned one.
type HttpClientException ¶
type HttpClientException struct {
Message string
}
HttpClientException is the base exception type for HTTP client errors.
func (*HttpClientException) Error ¶
func (e *HttpClientException) Error() string
type PendingRequest ¶
type PendingRequest struct {
// contains filtered or unexported fields
}
PendingRequest is the fluent builder for an outgoing HTTP request. Every method returns the PendingRequest itself so that callers chain: WithToken, WithHeader, Timeout, Retry, and finally Get, Post, Put, Patch, Delete, Head, or Send.
The zero value is not usable; create one with Factory.CreatePendingRequest.
func (*PendingRequest) Accept ¶
func (p *PendingRequest) Accept(ct string) *PendingRequest
Accept sets the Accept header.
func (*PendingRequest) AcceptJSON ¶
func (p *PendingRequest) AcceptJSON() *PendingRequest
AcceptJSON sets the Accept header to application/json.
func (*PendingRequest) AfterResponse ¶
func (p *PendingRequest) AfterResponse(callback func(*Response) error) *PendingRequest
AfterResponse registers a callback that runs after the Response is built.
func (*PendingRequest) AllowStrayRequests ¶
func (p *PendingRequest) AllowStrayRequests(only []string) *PendingRequest
AllowStrayRequests allows stray requests for specific URLs.
func (*PendingRequest) AsForm ¶
func (p *PendingRequest) AsForm() *PendingRequest
AsForm sets the body format to application/x-www-form-urlencoded.
func (*PendingRequest) AsJSON ¶
func (p *PendingRequest) AsJSON() *PendingRequest
AsJSON sets the body format to JSON (the default).
func (*PendingRequest) AsMultipart ¶
func (p *PendingRequest) AsMultipart() *PendingRequest
AsMultipart sets the body format to multipart/form-data.
func (*PendingRequest) Async ¶
func (p *PendingRequest) Async(async bool) *PendingRequest
Async sets whether to send without waiting.
A verb called on an asynchronous request returns (nil, nil) and leaves a promise on PendingRequest.GetPromise; waiting on that promise is what makes the request go out, and what hands back the response.
func (*PendingRequest) Attach ¶
func (p *PendingRequest) Attach(name, contents, filename string, headers map[string]string) *PendingRequest
Attach adds a file to the multipart form data.
func (*PendingRequest) BaseURL ¶
func (p *PendingRequest) BaseURL(u string) *PendingRequest
BaseURL sets the base URL. Paths in Get/Post/etc. are resolved against it.
func (*PendingRequest) Batch ¶
func (p *PendingRequest) Batch(callback func(*Batch)) *Batch
Batch executes a callback that adds requests to a Batch and sends them concurrently with progress and error callbacks.
func (*PendingRequest) BeforeSending ¶
func (p *PendingRequest) BeforeSending(callback func(*http.Request) error) *PendingRequest
BeforeSending registers a callback that runs just before the request is sent.
func (*PendingRequest) BodyFormat ¶
func (p *PendingRequest) BodyFormat(format string) *PendingRequest
BodyFormat sets the body format explicitly.
func (*PendingRequest) BuildClient ¶
func (p *PendingRequest) BuildClient() *http.Client
BuildClient is the client this request will go out on.
func (*PendingRequest) ConnectTimeout ¶
func (p *PendingRequest) ConnectTimeout(d time.Duration) *PendingRequest
ConnectTimeout sets the connection timeout.
func (*PendingRequest) ContentType ¶
func (p *PendingRequest) ContentType(ct string) *PendingRequest
ContentType sets the Content-Type header.
func (*PendingRequest) CreateClient ¶
func (p *PendingRequest) CreateClient(handler http.RoundTripper) *http.Client
CreateClient is a client configured the way this request needs it, without touching the shared one.
It takes the transport for the reason PendingRequest.SetHandler gives. A nil transport keeps whatever the client already had.
func (*PendingRequest) Dd ¶
func (p *PendingRequest) Dd() *PendingRequest
Dd enables request/response dumping and then exits.
func (*PendingRequest) Delete ¶
func (p *PendingRequest) Delete(urlStr string, data any) (*Response, error)
Delete sends a DELETE request.
func (*PendingRequest) DontTruncateExceptions ¶
func (p *PendingRequest) DontTruncateExceptions() *PendingRequest
DontTruncateExceptions lets the whole body into this request's exception messages.
func (*PendingRequest) Dump ¶
func (p *PendingRequest) Dump() *PendingRequest
Dump enables request/response dumping.
func (*PendingRequest) GetOptions ¶
func (p *PendingRequest) GetOptions() map[string]any
GetOptions returns the current option configuration.
func (*PendingRequest) GetPromise ¶
func (p *PendingRequest) GetPromise() promises.Promise
GetPromise is the promise this request left behind, or nil when it was not sent asynchronously.
Wait on it for a (*Response, error): the value is the *Response.
func (*PendingRequest) IsAllowedRequestUrl ¶
func (p *PendingRequest) IsAllowedRequestUrl(url string) bool
IsAllowedRequestUrl reports whether a request to this URL may leave the process when no stub matched it.
Every URL is allowed until stray request prevention is on. After that only the patterns given to PendingRequest.AllowStrayRequests or Factory.AllowStrayRequests are, matched the way str.Is matches: a literal string, or one with * standing for any run of characters.
func (*PendingRequest) MaxRedirects ¶
func (p *PendingRequest) MaxRedirects(max int) *PendingRequest
MaxRedirects sets how many redirects the request follows before it gives up.
func (*PendingRequest) MergeOptions ¶
func (p *PendingRequest) MergeOptions(options ...map[string]any) map[string]any
MergeOptions is this request's options with the given ones laid over them, later maps winning.
Nothing in PendingRequest.GetOptions nests, so this is a flat merge.
func (*PendingRequest) Patch ¶
func (p *PendingRequest) Patch(urlStr string, data any) (*Response, error)
Patch sends a PATCH request.
func (*PendingRequest) Pool ¶
Pool executes a callback that adds requests to a Pool and sends them concurrently.
func (*PendingRequest) Post ¶
func (p *PendingRequest) Post(urlStr string, data any) (*Response, error)
Post sends a POST request.
func (*PendingRequest) PreventStrayRequests ¶
func (p *PendingRequest) PreventStrayRequests(prevent bool) *PendingRequest
PreventStrayRequests enables stray request prevention for this request.
func (*PendingRequest) Put ¶
func (p *PendingRequest) Put(urlStr string, data any) (*Response, error)
Put sends a PUT request.
func (*PendingRequest) ReplaceHeaders ¶
func (p *PendingRequest) ReplaceHeaders(headers map[string]string) *PendingRequest
ReplaceHeaders replaces all headers.
func (*PendingRequest) Retry ¶
func (p *PendingRequest) Retry(times int, delay time.Duration, when func(*http.Response, error) bool, throw bool) *PendingRequest
Retry sets how many times the request may be attempted.
times is a total and includes the first send: Retry(3) makes at most three requests, not four. delay is what is waited between them.
when decides whether a failure is worth repeating and is handed the raw response, if one arrived, and the failure itself -- a *RequestException when the response failed, or the transport's error when the connection did. A nil when repeats every failure, which is the ordinary way to call this.
throw: when more than one attempt was asked for and the last one still failed, the failure comes back as an error rather than as a response. It is on by default.
func (*PendingRequest) RunBeforeSendingCallbacks ¶
func (p *PendingRequest) RunBeforeSendingCallbacks(req *http.Request) error
RunBeforeSendingCallbacks runs what PendingRequest.BeforeSending registered, in the order it was registered, mutating req in place. It returns only what went wrong.
func (*PendingRequest) Send ¶
func (p *PendingRequest) Send(method, urlStr string, query map[string]string, data any) (*Response, error)
Send sends the request. It is the central method that all HTTP verb methods delegate to.
func (*PendingRequest) SetClient ¶
func (p *PendingRequest) SetClient(client *http.Client) *PendingRequest
SetClient sets the underlying HTTP client.
func (*PendingRequest) SetHandler ¶
func (p *PendingRequest) SetHandler(handler http.RoundTripper) *PendingRequest
SetHandler sets the transport the request goes out on: the http.RoundTripper on the client, which is where a caller puts a recording or an offline transport.
func (*PendingRequest) Sink ¶
func (p *PendingRequest) Sink(w io.Writer) *PendingRequest
Sink directs the response body to the given writer instead of reading it into memory.
func (*PendingRequest) Stub ¶
func (p *PendingRequest) Stub(callback StubCallback) *PendingRequest
StubCallback registers a stub callback for this specific request.
func (*PendingRequest) Throw ¶
func (p *PendingRequest) Throw(callback func(*Response, *RequestException)) *PendingRequest
Throw turns a failed response into an error.
The callback is a side effect only, never a substitute for building the exception: it used to run in place of returning it, so a callback that only logged made the failure vanish instead of surfacing as an error.
func (*PendingRequest) ThrowIf ¶
func (p *PendingRequest) ThrowIf(condition bool) *PendingRequest
ThrowIf enables conditional throwing on failed responses.
func (*PendingRequest) ThrowUnless ¶
func (p *PendingRequest) ThrowUnless(condition bool) *PendingRequest
ThrowUnless enables throwing unless the condition is true.
func (*PendingRequest) Timeout ¶
func (p *PendingRequest) Timeout(d time.Duration) *PendingRequest
Timeout sets the request timeout.
func (*PendingRequest) TruncateExceptionsAt ¶
func (p *PendingRequest) TruncateExceptionsAt(length int) *PendingRequest
TruncateExceptionsAt cuts the body summary of this request's exceptions at the given length.
func (*PendingRequest) WithAttributes ¶
func (p *PendingRequest) WithAttributes(attrs map[string]any) *PendingRequest
WithAttributes attaches arbitrary attributes to the request.
func (*PendingRequest) WithBasicAuth ¶
func (p *PendingRequest) WithBasicAuth(username, password string) *PendingRequest
WithBasicAuth sets HTTP Basic authentication.
func (*PendingRequest) WithBody ¶
func (p *PendingRequest) WithBody(content io.Reader, contentType string) *PendingRequest
WithBody sets the raw request body with a given Content-Type.
func (*PendingRequest) WithCookies ¶
func (p *PendingRequest) WithCookies(cookies []*http.Cookie, domain string) *PendingRequest
WithCookies sets cookies for the request domain.
func (*PendingRequest) WithDigestAuth ¶
func (p *PendingRequest) WithDigestAuth(username, password string) *PendingRequest
WithDigestAuth sets HTTP Digest authentication.
func (*PendingRequest) WithHeader ¶
func (p *PendingRequest) WithHeader(name, value string) *PendingRequest
WithHeader sets a single header.
func (*PendingRequest) WithHeaders ¶
func (p *PendingRequest) WithHeaders(headers map[string]string) *PendingRequest
WithHeaders merges the given headers into the request headers.
func (*PendingRequest) WithMiddleware ¶
func (p *PendingRequest) WithMiddleware(mw ...func(*http.Request, http.RoundTripper) http.RoundTripper) *PendingRequest
WithMiddleware adds transport-level middleware.
func (*PendingRequest) WithOptions ¶
func (p *PendingRequest) WithOptions(fn func(*http.Client)) *PendingRequest
WithOptions sets arbitrary options on the underlying HTTP client.
func (*PendingRequest) WithQueryParameters ¶
func (p *PendingRequest) WithQueryParameters(params map[string]string) *PendingRequest
WithQueryParameters adds query parameters to the request URL.
func (*PendingRequest) WithRequestMiddleware ¶
func (p *PendingRequest) WithRequestMiddleware(mw ...func(*http.Request) error) *PendingRequest
WithRequestMiddleware adds request-level middleware (runs before send).
func (*PendingRequest) WithResponseMiddleware ¶
func (p *PendingRequest) WithResponseMiddleware(mw ...func(*http.Response) error) *PendingRequest
WithResponseMiddleware adds response-level middleware (runs after receive).
func (*PendingRequest) WithToken ¶
func (p *PendingRequest) WithToken(token string, tokenType string) *PendingRequest
WithToken sets a Bearer token (or custom token type).
func (*PendingRequest) WithURLParameters ¶
func (p *PendingRequest) WithURLParameters(params map[string]string) *PendingRequest
WithURLParameters sets URL template parameters.
func (*PendingRequest) WithUserAgent ¶
func (p *PendingRequest) WithUserAgent(ua string) *PendingRequest
WithUserAgent sets the User-Agent header.
func (*PendingRequest) WithoutRedirecting ¶
func (p *PendingRequest) WithoutRedirecting() *PendingRequest
WithoutRedirecting disables automatic redirect following.
func (*PendingRequest) WithoutVerifying ¶
func (p *PendingRequest) WithoutVerifying() *PendingRequest
WithoutVerifying disables TLS certificate verification.
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool collects concurrent HTTP requests and sends them as a batch. Each request is keyed either by a numeric index (NewRequest) or by a string key (As).
func (*Pool) GetRequests ¶
func (p *Pool) GetRequests() []poolRequest
GetRequests returns all pending requests in the pool.
func (*Pool) NewRequest ¶
func (p *Pool) NewRequest() *PendingRequest
NewRequest adds a request with a numeric key.
The key counts only the unnamed requests: a pool of As("a"), NewRequest(), As("b"), NewRequest() answers under "a", "0", "b" and "1".
type RecordedPair ¶
RecordedPair is a request-response pair stored during recording.
type Request ¶
type Request struct {
// contains filtered or unexported fields
}
Request wraps *http.Request and adds inspection methods for method, URL, headers, body, and content-type detection, for inspecting outgoing HTTP client requests in stubs and assertions.
func NewRequest ¶
NewRequest creates a Request from an *http.Request. The body is read eagerly so that it can be inspected multiple times.
func (*Request) Attributes ¶
Attributes returns the request attributes.
func (*Request) HTTPRequest ¶
HTTPRequest returns the underlying *http.Request.
func (*Request) HasFile ¶
HasFile reports whether the request has a file with the given name in its multipart body.
func (*Request) HasHeader ¶
HasHeader reports whether the request has the given header, and optionally whether it has the given value.
func (*Request) HasHeaders ¶
HasHeaders reports whether the request has all the given headers.
func (*Request) IsForm ¶
IsForm reports whether the Content-Type is application/x-www-form-urlencoded.
func (*Request) IsMultipart ¶
IsMultipart reports whether the Content-Type is multipart/form-data.
func (*Request) SetRequestAttributes ¶
SetRequestAttributes sets the request attributes.
type RequestException ¶
type RequestException struct {
HttpClientException
Response *Response
// TruncateExceptionsAt is the per-instance override of the
// package-level truncation length. Nil means the package-level
// [TruncateAt] decides; a pointer to zero lets the whole body through.
TruncateExceptionsAt *int
// HasBeenSummarized is whether Report has already rebuilt the message
// once.
HasBeenSummarized bool
}
RequestException is returned when a response did come back and the caller asked for a failing one to be treated as an error: Response.Throw, Response.ThrowIfStatus and the retry loop that ran out of attempts all build one. The response stays on the value, so whatever handles the error can still read the status, the headers and the body.
Its message is the status code followed by a summary of the body, cut at the truncation length so that one log line does not swallow a whole HTML error page. TruncateExceptionsAt decides that length when it is set on the instance; otherwise the package-level TruncateAt does.
func NewRequestException ¶
func NewRequestException(resp *Response, truncateExceptionsAt *int) *RequestException
NewRequestException creates a RequestException from a failed Response.
truncateExceptionsAt: nil defers to TruncateAt, a pointer to zero lets the whole body through, and a pointer to a positive length cuts the body summary there.
func (*RequestException) Report ¶
func (e *RequestException) Report() bool
Report rebuilds the message from the response once, and returns false so that a caller's own exception handler carries on with its own reporting.
type Response ¶
type Response struct {
// contains filtered or unexported fields
}
Response wraps *http.Response and adds inspection, JSON decoding, and error-throwing methods. The body is read eagerly so that the caller can call Body, JSON, and Collect repeatedly without draining the stream.
func NewResponse ¶
NewResponse creates a Response from an *http.Response. The body is read eagerly.
func NewResponseFromBytes ¶
NewResponseFromBytes creates a Response from raw bytes and a status code. This is useful in stubs and tests.
func (*Response) BadRequest ¶
BadRequest reports whether the status is 400.
func (*Response) ClientError ¶
ClientError reports whether the status code is 4xx.
func (*Response) DdHeaders ¶
func (r *Response) DdHeaders()
DdHeaders dumps the headers and ends the process.
func (*Response) DontTruncateExceptions ¶
DontTruncateExceptions lets the whole body into this response's exception message.
func (*Response) DumpHeaders ¶
DumpHeaders writes the response headers out where the process can see them.
func (*Response) EffectiveURI ¶
EffectiveURI returns the effective request URI (after redirects).
func (*Response) Failed ¶
Failed reports whether the response is a client or server error (4xx or 5xx).
func (*Response) HTTPResponse ¶
HTTPResponse returns the underlying *http.Response.
func (*Response) HandlerStats ¶
HandlerStats returns basic timing information about the request.
func (*Response) JSON ¶
JSON decodes the response body as JSON. If key is non-empty, it extracts a nested value using dot notation (e.g., "data.user.name").
func (*Response) MovedPermanently ¶
MovedPermanently reports whether the status is 301.
func (*Response) NotModified ¶
NotModified reports whether the status is 304.
func (*Response) PaymentRequired ¶
PaymentRequired reports whether the status is 402.
func (*Response) Reason ¶
Reason is the reason phrase the server sent.
net/http keeps the whole status line, so the code is trimmed off the front of it. When there is no status line -- a stubbed response -- the registered text for the code stands in, which is what the server would have sent.
func (*Response) RequestTimeout ¶
RequestTimeout reports whether the status is 408.
func (*Response) ServerError ¶
ServerError reports whether the status code is >= 500.
func (*Response) StatusText ¶
StatusText returns the HTTP status text.
func (*Response) Successful ¶
Successful reports whether the status code is 2xx.
func (*Response) Throw ¶
func (r *Response) Throw(callback func(*Response, *RequestException)) error
Throw is the RequestException a failed response carries, or nil when it did not fail.
The callback is a side effect and never a substitute for the exception: it used to return the callback's own error instead, so a callback that only logged and returned nil made a 500 disappear. It also used to hand the callback one argument instead of two -- the response and the exception.
func (*Response) ThrowIf ¶
func (r *Response) ThrowIf(condition bool, callback func(*Response, *RequestException)) error
ThrowIf throws when the condition holds and the response failed. The callback is the side effect Response.Throw describes.
func (*Response) ThrowIfClientError ¶
ThrowIfClientError throws when the response is a 4xx.
func (*Response) ThrowIfServerError ¶
ThrowIfServerError throws when the response is a 5xx.
func (*Response) ThrowIfStatus ¶
ThrowIfStatus throws when the response carries the given status code.
It does not consult Failed: a RequestException is returned the moment the status matches, whatever the status is, which is what makes ThrowIfStatus(201) a usable assertion. This used to go through Throw, which returns nil for anything below 400, so every status a caller could name under 400 was silently accepted -- the mirror image of ThrowUnlessStatus, which was already right.
func (*Response) ThrowUnless ¶
ThrowUnless calls throw unless the condition is true.
func (*Response) ThrowUnlessStatus ¶
ThrowUnlessStatus throws unless the response carries the given status code.
func (*Response) ToException ¶
func (r *Response) ToException() *RequestException
ToException is the RequestException this response would throw, or nil when it did not fail.
Callers that assign it to an error must check for nil before returning it, because a nil pointer in a non-nil interface is not a nil error.
func (*Response) TooManyRequests ¶
TooManyRequests reports whether the status is 429.
func (*Response) TruncateExceptionsAt ¶
TruncateExceptionsAt cuts the body summary of this response's exception at the given length.
func (*Response) Unauthorized ¶
Unauthorized reports whether the status is 401.
func (*Response) UnprocessableContent ¶
UnprocessableContent is the 422 check under the name the current RFC gives it. Response.UnprocessableEntity is the same check under the name the older RFC gave it; both are kept for callers who know the status by either name.
func (*Response) UnprocessableEntity ¶
UnprocessableEntity reports whether the status is 422.
type ResponseSequence ¶
type ResponseSequence struct {
// contains filtered or unexported fields
}
ResponseSequence provides an ordered sequence of stub responses that are returned one at a time as requests are made. When the sequence is exhausted, the next request returns an error (or a default if one is configured).
func NewResponseSequence ¶
func NewResponseSequence() *ResponseSequence
NewResponseSequence creates an empty ResponseSequence.
func (*ResponseSequence) AsStub ¶
func (s *ResponseSequence) AsStub(urlPattern string) StubCallback
AsStub returns a StubCallback that consumes responses from this sequence.
func (*ResponseSequence) DontFailWhenEmpty ¶
func (s *ResponseSequence) DontFailWhenEmpty() *ResponseSequence
DontFailWhenEmpty prevents the sequence from returning an error when exhausted.
func (*ResponseSequence) IsEmpty ¶
func (s *ResponseSequence) IsEmpty() bool
IsEmpty reports whether the sequence has any remaining responses.
func (*ResponseSequence) Push ¶
func (s *ResponseSequence) Push(status int, body string, headers http.Header) *ResponseSequence
Push adds a response to the sequence.
func (*ResponseSequence) PushFailedConnection ¶
func (s *ResponseSequence) PushFailedConnection(message string) *ResponseSequence
PushFailedConnection adds a connection failure to the sequence.
func (*ResponseSequence) PushFile ¶
func (s *ResponseSequence) PushFile(filePath string, status int, headers http.Header) *ResponseSequence
PushFile adds a response whose body is read from the given file path.
func (*ResponseSequence) PushResponse ¶
func (s *ResponseSequence) PushResponse(resp *http.Response) *ResponseSequence
PushResponse adds a raw *http.Response to the sequence.
func (*ResponseSequence) PushStatus ¶
func (s *ResponseSequence) PushStatus(status int, headers http.Header) *ResponseSequence
PushStatus adds a response with only a status code (no body).
func (*ResponseSequence) WhenEmpty ¶
func (s *ResponseSequence) WhenEmpty(status int, body string, headers http.Header) *ResponseSequence
WhenEmpty configures the default response returned when the sequence is exhausted. When set, the sequence does not fail when empty.
type StrayRequestError ¶
type StrayRequestError struct {
URI string
}
StrayRequestError is returned when a request is made that does not match any stub and stray request prevention is enabled.
func NewStrayRequestError ¶
func NewStrayRequestError(uri string) *StrayRequestError
NewStrayRequestError creates a StrayRequestError.
func (*StrayRequestError) Error ¶
func (e *StrayRequestError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package concerns is intentionally empty.
|
Package concerns is intentionally empty. |
|
Package events holds the events dispatched during an HTTP client request lifecycle: RequestSending, ResponseReceived and ConnectionFailed.
|
Package events holds the events dispatched during an HTTP client request lifecycle: RequestSending, ResponseReceived and ConnectionFailed. |
|
Package promises provides the two promise-like types the HTTP client returns from an asynchronous request: FluentPromise and LazyPromise.
|
Package promises provides the two promise-like types the HTTP client returns from an asynchronous request: FluentPromise and LazyPromise. |