Documentation
¶
Overview ¶
Package httpx includes various HTTP utilities.
Index ¶
- func Copy(w http.ResponseWriter, res *http.Response) error
- func DecodeDeepObject(values url.Values, obj any) error
- func EncodeDeepObject(obj any) (url.Values, error)
- func FillPathArguments(u string) (resolved string, err error)
- func IsLocalhostAddress(r *http.Request) bool
- func IsPrivateIPAddress(r *http.Request) bool
- func JoinHostAndPath(host string, route string) string
- func MethodWithBody(method string) bool
- func MustNewRequest(method string, url string, body any) *http.Request
- func MustNewRequestWithContext(ctx context.Context, method string, url string, body any) *http.Request
- func NewRequest(method string, url string, body any) (*http.Request, error)
- func NewRequestWithContext(ctx context.Context, method string, url string, body any) (*http.Request, error)
- func ParseRequestBody(r *http.Request, data any) error
- func ParseURL(rawURL string) (canonical *url.URL, err error)
- func PathValues(r *http.Request, routePath string) (result url.Values, err error)
- func ReadInputPayload(r *http.Request, route string, in any) (err error)
- func ReadOutputPayload(res *http.Response, out any) (err error)
- func ResolveURL(base string, relative string) (resolved string, err error)
- func SetPathValues(r *http.Request, routePath string) error
- func SetRequestBody(r *http.Request, body any) error
- func ValidateHostname(hostname string) error
- func WriteInputPayload(method string, in any) (query url.Values, body any, err error)
- func WriteOutputPayload(w http.ResponseWriter, out any) (err error)
- type BodyReader
- type CertLogger
- type CertStore
- func (cs *CertStore) Get(port int, serverName string) (*tls.Certificate, error)
- func (cs *CertStore) GetCertificate(listenPort int) func(*tls.ClientHelloInfo) (*tls.Certificate, error)
- func (cs *CertStore) Load(ctx context.Context)
- func (cs *CertStore) ReloadIfChanged(ctx context.Context) bool
- func (cs *CertStore) Watch(ctx context.Context) (err error)
- type DefragRequest
- type DefragResponse
- type FragRequest
- type FragResponse
- type QArgs
- type ResponseRecorder
- func (rr *ResponseRecorder) Clear()
- func (rr *ResponseRecorder) ClearBody()
- func (rr *ResponseRecorder) ClearHeader()
- func (rr *ResponseRecorder) ContentLength() int
- func (rr *ResponseRecorder) Header() http.Header
- func (rr *ResponseRecorder) Result() *http.Response
- func (rr *ResponseRecorder) StatusCode() int
- func (rr *ResponseRecorder) Write(b []byte) (int, error)
- func (rr *ResponseRecorder) WriteHeader(statusCode int)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Copy ¶
func Copy(w http.ResponseWriter, res *http.Response) error
Copy writes the http.Response to the http.ResponseWriter. Headers are added, the body is appended, and the status code is overwritten. It is possible for this function to take ownership of the bytes of the body of the http.Response so do not modify them.
func DecodeDeepObject ¶
DecodeDeepObject decodes an object from a string representation with bracketed or dot-notation nested field names. For example, color[R]=100&color[G]=200&color[B]=150 or color.R=100&color.G=200. Maps whose keys are sequential integers starting from 0 are decoded as arrays. For example, x[0]=a&x[1]=b&x[2]=c is decoded as {"x":["a","b","c"]}. It builds a single JSON object from all values and unmarshals it in one pass.
func EncodeDeepObject ¶
EncodeDeepObject encodes an object into string representation with bracketed nested fields names. For example, color[R]=100&color[G]=200&color[B]=150 .
func FillPathArguments ¶
FillPathArguments transfers query arguments into path arguments, if present.
func IsLocalhostAddress ¶
IsLocalhostAddress checks if the request's remote address is the local host.
func IsPrivateIPAddress ¶
IsPrivateIPAddress checks if the request's remote address is on the local subnets, e.g. 192.168.X.X or 10.X.X.X.
func JoinHostAndPath ¶
JoinHostAndPath combines the route with a hostname.
func MethodWithBody ¶ added in v1.22.0
MethodWithBody returns true if the HTTP method typically accepts a request body.
func MustNewRequest ¶
MustNewRequest wraps NewRequestWithContext with the background context. It panics on error.
func MustNewRequestWithContext ¶
func MustNewRequestWithContext(ctx context.Context, method string, url string, body any) *http.Request
MustNewRequestWithContext returns a new http.Request given a method, URL, and optional body. It panics on error. Arguments of type io.Reader, io.ReadCloser, []byte and string are serialized in binary form. url.Values and QArgs are serialized as form data. All other types are serialized as JSON. The Content-Type Content-Length headers will be set to match the body if they can be determined and unless already set.
func NewRequest ¶
NewRequest wraps NewRequestWithContext with the background context.
func NewRequestWithContext ¶
func NewRequestWithContext(ctx context.Context, method string, url string, body any) (*http.Request, error)
NewRequestWithContext returns a new http.Request given a method, URL, and optional body. Arguments of type io.Reader, io.ReadCloser, []byte and string are serialized in binary form. url.Values and QArgs are serialized as form data. All other types are serialized as JSON. The Content-Type Content-Length headers will be set to match the body if they can be determined and unless already set.
func ParseRequestBody ¶
ParseRequestBody parses the body of an incoming request and populates the fields of a data object. It supports JSON and URL-encoded form data content types. Use json tags to designate the name of the argument to map to each field.
func ParseURL ¶
ParseURL returns a canonical version of the parsed URL with the scheme and port filled in if omitted. It performs syntactic checks only - rejecting backticks, malformed URL strings, and URLs that lack a hostname - but does not enforce the Microbus identity rules. Callers that need an identity check must call ValidateHostname (or the route equivalent) explicitly.
func PathValues ¶ added in v1.19.0
PathValues pulls the path values from the request given a parameterized route path such as /obj/{id}/{}. The path values should have been previously set on the request with SetPathValue.
func ReadInputPayload ¶ added in v1.22.0
ReadInputPayload parses the body, path arguments, and query arguments of an incoming request and populates them into an object. The body can contain a JSON payload or URL-encoded form data. Use JSON tags to designate the name of the argument to map to each field. An argument name can be hierarchical using either notation "a[b][c]" or "a.b.c", in which case it is read into the corresponding nested field.
func ReadOutputPayload ¶ added in v1.22.0
ReadOutputPayload reads the HTTP response into the output payload. It enables the HTTPResponseBody and HTTPStatusCode magic arguments.
func ResolveURL ¶
ResolveURL resolves a URL in relation to the endpoint's base path.
func SetPathValues ¶ added in v1.19.0
SetPathValues compares the request's actual path against a parameterized route path such as /obj/{id}/{}, and sets the path values of the request appropriately.
func SetRequestBody ¶
SetRequestBody sets the body of the request. Arguments of type io.Reader, io.ReadCloser, []byte and string are serialized in binary form. url.Values and QArgs are serialized as form data. All other types are serialized as JSON. The Content-Type Content-Length headers will be set to match the body if they can be determined and unless already set.
func ValidateHostname ¶ added in v1.21.0
ValidateHostname checks that the string is a canonical Microbus service identity. Rules:
- Length up to 252 characters.
- Only lowercase letters, digits, dot separators, and hyphens. No underscores. No uppercase.
- Segments are separated by single dots; no leading, trailing, or consecutive dots.
- The first segment may not start with the reserved prefixes "id-" or "loc-".
- The hostname is not "all" and does not end in ".all".
The caller is responsible for normalization (trim, lowercase). Non-canonical input produces an error rather than being silently coerced.
func WriteInputPayload ¶ added in v1.22.0
WriteInputPayload determines how to deliver the input payload, via query arguments or the body of the request. It enables the HTTPRequestBody magic argument.
func WriteOutputPayload ¶ added in v1.22.0
func WriteOutputPayload(w http.ResponseWriter, out any) (err error)
WriteOutputPayload writes the output payload to the HTTP response as JSON. It enables the HTTPStatusCode and HTTPResponseBody magic arguments.
Types ¶
type BodyReader ¶
type BodyReader struct {
// contains filtered or unexported fields
}
BodyReader is used to wrap bytes in a closer+reader while allowing access to the underlying bytes.
func NewBodyReader ¶
func NewBodyReader(b []byte) *BodyReader
NewBodyReader creates a new closer+reader for the request body while allowing access to the underlying bytes.
func (*BodyReader) Bytes ¶
func (br *BodyReader) Bytes() []byte
Bytes gives access to the underlying bytes.
func (*BodyReader) Close ¶
func (br *BodyReader) Close() error
Read implements the io.Closer interface.
func (*BodyReader) Len ¶ added in v1.14.0
func (br *BodyReader) Len() int
Len is the length of the underlying bytes.
func (*BodyReader) Read ¶
func (br *BodyReader) Read(p []byte) (n int, err error)
Read implements the io.Reader interface.
func (*BodyReader) Reset ¶
func (br *BodyReader) Reset()
Reset resets the underlying reader to the beginning.
type CertLogger ¶ added in v1.34.0
type CertLogger interface {
LogInfo(ctx context.Context, msg string, args ...any)
LogWarn(ctx context.Context, msg string, args ...any)
}
CertLogger is the minimal logger CertStore needs. It matches the Microbus connector's LogInfo and LogWarn so a microservice can be passed directly. A nil logger is silent.
type CertStore ¶ added in v1.34.0
type CertStore struct {
// contains filtered or unexported fields
}
CertStore discovers TLS cert/key file pairs in a directory and serves them by SNI. The file-naming convention (see the package-level constants) ties a cert to its key by a shared filename prefix and optionally marks a per-port default or the server-wide default. Certificate matching is on the parsed SAN DNS names of each certificate, not on the file name, so a misnamed file cannot cause a wrong-certificate mis-serve.
Resolution order on every TLS handshake:
- Exact SAN match against the SNI.
- Wildcard SAN match.
- The listener's port-named default (a cert whose token parses as the listener's port).
- The server-wide default (cert.pem / key.pem).
- With no match, the handshake fails rather than serve an arbitrary default.
The active index is swapped atomically so resolution stays lock-free on the handshake path. Reload is driven by fsnotify on the directory (not individual files) so atomic-rename and symlink-swap rotations - Kubernetes secret mounts, certbot - are detected.
func NewCertStore ¶ added in v1.34.0
func NewCertStore(dir string, log CertLogger) *CertStore
NewCertStore creates a store scanning dir (empty means the working directory). A nil log is treated as silent.
func (*CertStore) Get ¶ added in v1.34.0
Get resolves a certificate for the given SNI name on the given listener port, in the order documented on CertStore. It returns an error rather than serving a wrong certificate.
func (*CertStore) GetCertificate ¶ added in v1.34.0
func (cs *CertStore) GetCertificate(listenPort int) func(*tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificate returns a callback bound to a listener port, suitable for tls.Config.GetCertificate. It saves the caller from writing the closure manually.
func (*CertStore) Load ¶ added in v1.34.0
Load builds the index and stores it atomically. Call once before the first handshake.
func (*CertStore) ReloadIfChanged ¶ added in v1.34.0
ReloadIfChanged rebuilds and atomically swaps the index when the source files have changed since the last load, logging an info record when it does. It returns true if a reload occurred.
func (*CertStore) Watch ¶ added in v1.34.0
Watch observes the certificate directory and reloads the index when the cert/key files change. It watches the directory rather than the individual files so that atomic-rename and symlink-swap rotations are detected. Events are debounced to coalesce the multi-file burst of a single rotation and to avoid reading a half-written pair. Watch runs until ctx is cancelled.
type DefragRequest ¶
type DefragRequest struct {
// contains filtered or unexported fields
}
DefragRequest merges together multiple fragments back into a single HTTP request
func NewDefragRequest ¶
func NewDefragRequest() *DefragRequest
NewDefragRequest creates a new request integrator.
func (*DefragRequest) Add ¶
func (st *DefragRequest) Add(r *http.Request) (final bool, err error)
Add a fragment to be integrated. The integrated request is returned if this was the last fragment.
func (*DefragRequest) Integrated ¶
func (st *DefragRequest) Integrated() (integrated *http.Request, err error)
Integrated returns all the fragments have been collected as a single HTTP request.
func (*DefragRequest) LastActivity ¶
func (st *DefragRequest) LastActivity() time.Duration
LastActivity indicates how long ago was the last fragment added.
type DefragResponse ¶
type DefragResponse struct {
// contains filtered or unexported fields
}
DefragResponse merges together multiple fragments back into a single HTTP response
func NewDefragResponse ¶
func NewDefragResponse() *DefragResponse
NewDefragResponse creates a new response integrator.
func (*DefragResponse) Add ¶
func (st *DefragResponse) Add(r *http.Response) (final bool, err error)
Add a fragment to be integrated. The integrated response is returned if this was the last fragment.
func (*DefragResponse) Integrated ¶
func (st *DefragResponse) Integrated() (integrated *http.Response, err error)
Integrated returns all the fragments have been collected as a single HTTP response.
func (*DefragResponse) LastActivity ¶
func (st *DefragResponse) LastActivity() time.Duration
LastActivity indicates how long ago was the last fragment added.
type FragRequest ¶
type FragRequest struct {
// contains filtered or unexported fields
}
FragRequest transforms an HTTP request into one or more fragments that do not exceed a given size. Fragmenting is needed because NATS imposes a maximum size for messages
func NewFragRequest ¶
func NewFragRequest(r *http.Request, fragmentSize int64) (*FragRequest, error)
NewFragRequest creates a new request fragmentor
type FragResponse ¶
type FragResponse struct {
// contains filtered or unexported fields
}
FragResponse transforms an HTTP response into one or more fragments that do not exceed a given size. Fragmenting is needed because NATS imposes a maximum size for messages
func NewFragResponse ¶
func NewFragResponse(r *http.Response, fragmentSize int64) (*FragResponse, error)
NewFragResponse creates a new response fragmentor
type QArgs ¶
QArgs facilitates the creation of URL query arguments for the common case where there is only one value per key. Values of any type are converted to a string. Keys are case-sensitive.
Usage:
u := "https://example.com/path?"+QArgs{
"hello": "World",
"number": 6,
"id", key
}.Encode()
func (QArgs) Encode ¶
Encode encodes the values into “URL encoded” form ("bar=baz&foo=quux") sorted by key.
type ResponseRecorder ¶
type ResponseRecorder struct {
// contains filtered or unexported fields
}
ResponseRecorder is used to record HTTP responses.
func NewResponseRecorder ¶
func NewResponseRecorder() *ResponseRecorder
NewResponseRecorder creates a new response recorder. The recorder is modifiable even after the body was written because it keeps the entire response in memory.
func (*ResponseRecorder) Clear ¶
func (rr *ResponseRecorder) Clear()
Clear resets all headers, body and status code.
func (*ResponseRecorder) ClearBody ¶ added in v1.13.1
func (rr *ResponseRecorder) ClearBody()
ClearBody resets the body's content.
func (*ResponseRecorder) ClearHeader ¶ added in v1.13.1
func (rr *ResponseRecorder) ClearHeader()
ClearHeader resets the headers.
func (*ResponseRecorder) ContentLength ¶
func (rr *ResponseRecorder) ContentLength() int
ContentLength returns the total number of bytes written to the body of the response.
func (*ResponseRecorder) Header ¶
func (rr *ResponseRecorder) Header() http.Header
Header enables setting headers. It implements the http.ResponseWriter interface.
func (*ResponseRecorder) Result ¶
func (rr *ResponseRecorder) Result() *http.Response
Result returns the response generated by the recorder.
func (*ResponseRecorder) StatusCode ¶
func (rr *ResponseRecorder) StatusCode() int
StatusCode returns the status code set for the response. If unset, the default is http.StatusOK 200.
func (*ResponseRecorder) Write ¶
func (rr *ResponseRecorder) Write(b []byte) (int, error)
Write writes bytes to the body of the response. It implements the http.ResponseWriter interface.
func (*ResponseRecorder) WriteHeader ¶
func (rr *ResponseRecorder) WriteHeader(statusCode int)
WriteHeader writes the header to the response. It implements the http.ResponseWriter interface.