httpx

package
v1.40.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package httpx includes various HTTP utilities.

Index

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

func DecodeDeepObject(values url.Values, obj any) error

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

func EncodeDeepObject(obj any) (url.Values, error)

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

func FillPathArguments(u string) (resolved string, err error)

FillPathArguments transfers query arguments into path arguments, if present.

func IsLocalhostAddress

func IsLocalhostAddress(r *http.Request) bool

IsLocalhostAddress checks if the request's remote address is the local host.

func IsPrivateIPAddress

func IsPrivateIPAddress(r *http.Request) bool

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

func JoinHostAndPath(host string, route string) string

JoinHostAndPath combines the route with a hostname.

func MethodWithBody added in v1.22.0

func MethodWithBody(method string) bool

MethodWithBody returns true if the HTTP method typically accepts a request body.

func MustNewRequest

func MustNewRequest(method string, url string, body any) *http.Request

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

func NewRequest(method string, url string, body any) (*http.Request, error)

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

func ParseRequestBody(r *http.Request, data any) error

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

func ParseURL(rawURL string) (canonical *url.URL, err error)

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

func PathValues(r *http.Request, routePath string) (result url.Values, err error)

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

func ReadInputPayload(r *http.Request, route string, in any) (err error)

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

func ReadOutputPayload(res *http.Response, out any) (err error)

ReadOutputPayload reads the HTTP response into the output payload. It enables the HTTPResponseBody and HTTPStatusCode magic arguments.

func ResolveURL

func ResolveURL(base string, relative string) (resolved string, err error)

ResolveURL resolves a URL in relation to the endpoint's base path.

func SetPathValues added in v1.19.0

func SetPathValues(r *http.Request, routePath string) error

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

func SetRequestBody(r *http.Request, body any) error

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

func ValidateHostname(hostname string) error

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

func WriteInputPayload(method string, in any) (query url.Values, body any, err error)

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:

  1. Exact SAN match against the SNI.
  2. Wildcard SAN match.
  3. The listener's port-named default (a cert whose token parses as the listener's port).
  4. The server-wide default (cert.pem / key.pem).
  5. 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

func (cs *CertStore) Get(port int, serverName string) (*tls.Certificate, error)

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

func (cs *CertStore) Load(ctx context.Context)

Load builds the index and stores it atomically. Call once before the first handshake.

func (*CertStore) ReloadIfChanged added in v1.34.0

func (cs *CertStore) ReloadIfChanged(ctx context.Context) bool

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

func (cs *CertStore) Watch(ctx context.Context) (err error)

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

func (*FragRequest) Fragment

func (fr *FragRequest) Fragment(index int) (f *http.Request, err error)

Fragment returns the 1-indexed fragment

func (*FragRequest) N

func (fr *FragRequest) N() int

N is the number of fragments

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

func (*FragResponse) Fragment

func (fr *FragResponse) Fragment(index int) (f *http.Response, err error)

Fragment returns the 1-indexed fragment

func (*FragResponse) N

func (fr *FragResponse) N() int

N is the number of fragments

type QArgs

type QArgs map[string]any

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

func (q QArgs) Encode() string

Encode encodes the values into “URL encoded” form ("bar=baz&foo=quux") sorted by key.

func (QArgs) String

func (q QArgs) String() string

String encodes the values into “URL encoded” form ("bar=baz&foo=quux") sorted by key.

func (QArgs) URLValues

func (q QArgs) URLValues() url.Values

URLValues generates a standard URL values map.

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.

Jump to

Keyboard shortcuts

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