Documentation
¶
Overview ¶
Package httpx provides building blocks for net/http servers and clients: request/response dumping and structured request/response info for logging, client IP extraction, protocol upgrade detection, MIME type matching, and a response writer wrapper that records status code and bytes written.
Subpackages build on it:
- middleware: func(http.Handler) http.Handler decorators for servers;
- roundtrip: func(http.RoundTripper) http.RoundTripper decorators for clients;
- rest: request binding and response rendering helpers (JSON, XML, HTML).
Index ¶
- func DumpRequest(req *http.Request, maxBodySize int) ([]byte, error)
- func DumpResponse(resp *http.Response, maxBodySize int) ([]byte, error)
- func ExtractRealIP(req *http.Request, headers ...string) string
- func IsUpgradeRequest(req *http.Request) bool
- type MIMEMatcher
- type RequestInfo
- type ResponseInfo
- type WrapResponseWriter
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DumpRequest ¶
DumpRequest dumps req in its HTTP/1.x wire representation. Headers are always dumped; maxBodySize controls only the body: 0 omits it, -1 dumps it in full, a positive value truncates the dumped body to maxBodySize bytes, and any other negative value behaves like 0. At most maxBodySize+1 bytes of the body are read into memory (all of it for -1) and req.Body is replaced with a reader that still yields the original data.
func DumpResponse ¶
DumpResponse dumps resp in its HTTP/1.x wire representation. Headers are always dumped; maxBodySize controls only the body: 0 omits it, -1 dumps it in full, a positive value truncates the dumped body to maxBodySize bytes, and any other negative value behaves like 0. At most maxBodySize+1 bytes of the body are read into memory (all of it for -1) and resp.Body is replaced with a reader that still yields the original data.
func ExtractRealIP ¶
ExtractRealIP returns the client IP address extracted from the request headers, in priority order. With no explicit headers the default order is CF-Connecting-IP, True-Client-IP, X-Real-IP, X-Forwarded-For (first entry). A header whose value is not a valid IP is skipped in favor of the next one; an empty string is returned when no header carries a valid IP.
These headers are set by the client unless a trusted proxy overwrites them, so the result is only trustworthy behind such a proxy — and only for the headers that proxy actually manages: with the default list a spoofed higher-priority header (e.g. CF-Connecting-IP when you are not behind Cloudflare) wins over the genuine one. Pass exactly the headers your infrastructure sets.
func IsUpgradeRequest ¶
IsUpgradeRequest determines if an HTTP request is requesting a protocol upgrade. It checks for presence of both "Connection: Upgrade" and a valid "Upgrade" header according to the HTTP/1.1 specification (RFC 7230, Section 6.7).
Types ¶
type MIMEMatcher ¶
type MIMEMatcher struct {
// contains filtered or unexported fields
}
MIMEMatcher contains pre-parsed patterns
func NewMIMEMatcher ¶
func NewMIMEMatcher(patterns []string) *MIMEMatcher
NewMIMEMatcher creates a new matcher from an array of patterns
func (*MIMEMatcher) Matches ¶
func (m *MIMEMatcher) Matches(mimeType string) bool
Matches checks if the MIME type matches at least one pattern
type RequestInfo ¶
type RequestInfo struct {
RemoteAddr string `json:"remote_addr"`
Host string `json:"host"`
Proto string `json:"proto"`
Method string `json:"method"`
URL string `json:"url"`
Path string `json:"path"`
Query map[string]string `json:"query"`
Header map[string]string `json:"header"`
// Body is a human-readable capture of the request body, serialized as a
// JSON string. Invalid UTF-8 (binary bodies) is replaced with U+FFFD
// during marshalling, so the round-trip is lossy for binary payloads —
// readability of the logs is chosen over fidelity here.
Body []byte `json:"body"`
}
RequestInfo contains metadata about a http.Request including query parameters, headers, and part of the body.
func ExtractRequestInfo ¶
func ExtractRequestInfo(req *http.Request, maxBodySize int) (RequestInfo, error)
ExtractRequestInfo extracts RequestInfo from req. Headers are always included; maxBodySize controls only the body: 0 omits it, -1 captures it in full, a positive value truncates the captured body to maxBodySize bytes, and any other negative value behaves like 0. The body is taken from req.GetBody when available, leaving req.Body untouched; otherwise at most maxBodySize+1 bytes are read from req.Body (all of it for -1) and req.Body is replaced with a reader that still yields the original data.
func (RequestInfo) LogValue ¶
func (ri RequestInfo) LogValue() slog.Value
LogValue implements slog.LogValuer.
func (RequestInfo) MarshalJSON ¶
func (ri RequestInfo) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler; the body is encoded as a string.
func (*RequestInfo) UnmarshalJSON ¶
func (ri *RequestInfo) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler; the body is decoded from a string.
type ResponseInfo ¶
type ResponseInfo struct {
Proto string `json:"proto"`
StatusCode int `json:"status_code"`
Header map[string]string `json:"header"`
// Body is a human-readable capture of the response body, serialized as a
// JSON string. Invalid UTF-8 (binary bodies) is replaced with U+FFFD
// during marshalling, so the round-trip is lossy for binary payloads —
// readability of the logs is chosen over fidelity here.
Body []byte `json:"body"`
}
ResponseInfo contains metadata about a http.Response including headers and part of the body.
func ExtractResponseInfo ¶
func ExtractResponseInfo(resp *http.Response, maxBodySize int) (ResponseInfo, error)
ExtractResponseInfo extracts ResponseInfo from resp. Headers are always included; maxBodySize controls only the body: 0 omits it, -1 captures it in full, a positive value truncates the captured body to maxBodySize bytes, and any other negative value behaves like 0. At most maxBodySize+1 bytes are read from resp.Body (all of it for -1) and resp.Body is replaced with a reader that still yields the original data.
func (ResponseInfo) LogValue ¶
func (ri ResponseInfo) LogValue() slog.Value
LogValue implements slog.LogValuer.
func (ResponseInfo) MarshalJSON ¶
func (ri ResponseInfo) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler; the body is encoded as a string.
func (*ResponseInfo) UnmarshalJSON ¶
func (ri *ResponseInfo) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler; the body is decoded from a string.
type WrapResponseWriter ¶
type WrapResponseWriter interface {
http.ResponseWriter
// Status returns the HTTP status of the response. It defaults to
// http.StatusOK when the handler has not set one explicitly; use Written
// to check whether the response header has actually been sent.
Status() int
// Written reports whether the response header has been written.
Written() bool
// BytesWritten returns the total number of bytes sent to the client.
BytesWritten() int
// Tee causes the response body to be written to the given io.Writer in
// addition to proxying the writes through. Only one io.Writer can be
// tee'd to at once: setting a second one will overwrite the first.
// Writes will be sent to the proxy before being written to this
// io.Writer. It is illegal for the tee'd writer to be modified
// concurrently with writes.
Tee(io.Writer)
// Unwrap returns the original proxied target.
Unwrap() http.ResponseWriter
// Error returns the first error recorded while writing the body
// (via Write or ReadFrom).
Error() error
}
WrapResponseWriter is a proxy around a http.ResponseWriter that allows you to hook into various parts of the response process. It can't catch a hijack writer, because it is not possible to wrap it.
func NewWrapResponseWriter ¶
func NewWrapResponseWriter(w http.ResponseWriter, protoMajor int) WrapResponseWriter
NewWrapResponseWriter wraps an http.ResponseWriter, returning a proxy that allows you to hook into various parts of the response process.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
semconv
Package semconv maps HTTP requests and responses onto OpenTelemetry attributes and span statuses, following the stable HTTP semantic conventions (semconv v1.41.0).
|
Package semconv maps HTTP requests and responses onto OpenTelemetry attributes and span statuses, following the stable HTTP semantic conventions (semconv v1.41.0). |
|
Package middleware provides composable net/http middleware for common server concerns: structured request/response logging, OpenTelemetry tracing and metrics, panic recovery, body size limits, throttling, timeouts, and more.
|
Package middleware provides composable net/http middleware for common server concerns: structured request/response logging, OpenTelemetry tracing and metrics, panic recovery, body size limits, throttling, timeouts, and more. |
|
Package rest provides helpers for HTTP request binding and response rendering: decoding JSON or XML request bodies with optional validation, and rendering JSON, XML, or HTML responses with the correct headers and status codes.
|
Package rest provides helpers for HTTP request binding and response rendering: decoding JSON or XML request bodies with optional validation, and rendering JSON, XML, or HTML responses with the correct headers and status codes. |
|
Package roundtrip provides composable http.RoundTripper middleware for common HTTP client concerns: retries with backoff, structured request/response logging, OpenTelemetry tracing, rate limiting, throttling, timeouts, and response body size limits.
|
Package roundtrip provides composable http.RoundTripper middleware for common HTTP client concerns: retries with backoff, structured request/response logging, OpenTelemetry tracing, rate limiting, throttling, timeouts, and response body size limits. |