Repository navigation
Expand file tree
/
Copy pathhttpclient.go
More file actions
77 lines (63 loc) · 3.82 KB
/
Copy pathhttpclient.go
File metadata and controls
77 lines (63 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
Package httpclient provides a configurable outbound HTTP client with trace
propagation and structured request/response logging.
The [Client] wraps net/http client behavior:
- [New] builds a client from functional options.
- [Client.Do] executes requests with trace/header enrichment and structured
logging around request/response timing.
By default, the client uses a 1-minute timeout, the standard transport, and the
default trace ID header from the traceid package. When a trace ID is missing in
the context, a new UUIDv7-based ID is generated and attached to the context and
request headers. Timeout, logger, component tag, log field prefix, trace ID
header name, transport, dial context, and the redaction function are configurable
through options.
# Logging Behavior
At debug level, request and response dumps are logged (after redaction).
At non-debug levels, summary metadata is logged without payload dumps.
Errors are logged with the same trace context and timing fields.
Query strings are redacted before logging at every level, so secrets carried in
query parameters (for example api_key or token) are not written to logs. This
includes the error field of a failed request, whose embedded URL has its query
and userinfo redacted. Two things are not redacted: the request path (so avoid
placing secrets in the path, e.g. /reset/{token}), and errors produced by a
custom round-tripper that do not wrap a *url.Error (redact those in the
round-tripper).
Debug-level dumps are redacted by the configured function (see [WithRedactFn]),
which by default masks Authorization-style headers, cookie and other sensitive
key/value pairs, and card-like numbers. Arbitrary secret request headers (for
example a custom X-Api-Key) are not covered by the default; supply a stronger
redactor via [WithRedactFn] when such headers are sent.
Debug-level dumps buffer the request and response body in memory, bounded by a
configurable maximum (see [WithMaxDumpSize], default 1 MiB):
- Request bodies larger than the cap, or of unknown length (streaming/chunked),
have their headers dumped but their payload omitted; omitting unknown-length
request bodies also avoids a deadlock that would otherwise occur when dumping
a streaming request body.
- Response bodies larger than the cap are omitted when the length is known; when
the length is unknown (chunked/streaming), the body is truncated to the cap in
the dump and marked as truncated, while the caller still receives the complete
response body.
Because dumping an unknown-length response reads up to the cap before the log
entry is emitted (and before Do returns the body to the caller), debug-level
logging is not suitable for genuinely streaming endpoints (server-sent events,
long polling): enabling it can add up to WithMaxDumpSize worth of buffering
latency. Keep debug logging off for such endpoints, or lower the cap.
# Client Reuse
Each [New] builds a client with its own private transport and connection pool.
Create a client once and reuse it for the lifetime of the caller; constructing a
new client per request defeats connection reuse. Use
[Client.CloseIdleConnections] to release pooled connections on shutdown or
reconfiguration.
The default transport raises MaxIdleConnsPerHost above net/http's default of 2
so that per-host connection reuse is not throttled for the common case of many
concurrent calls to a few downstream hosts. Use [WithTLSClientConfig] for custom
CAs or client certificates, or [WithTransport] to supply a fully tuned transport
(pool sizes, proxy, HTTP/2) when the defaults do not fit.
# When To Use
- Outbound calls should carry the inbound trace ID without threading it
through every call site.
- You want request and response logging that redacts secrets by default.
- You want one client configuration shared across every upstream
dependency.
*/
package httpclient