Documentation
¶
Overview ¶
Package hap provides secure cookie management utilities with sensible defaults.
The cookie functions follow security best practices by default:
- HttpOnly: true (prevents XSS attacks)
- Secure: auto-detected based on request TLS status
- SameSite: Lax (prevents CSRF attacks while allowing normal navigation)
- Path: "/" (cookie available site-wide)
Usage:
// Basic cookie with all secure defaults
hap.SetCookie(w, r, "session_id", "token123")
// Cookie with custom expiration
hap.SetCookie(w, r, "theme", "dark", hap.WithMaxAge(86400))
// Cookie for cross-subdomain sharing
hap.SetCookie(w, r, "user_prefs", "dark", hap.WithDomain(".example.com"))
// Delete a cookie (must match original domain/path)
hap.DelCookie(w, r, "session_id")
hap.DelCookie(w, r, "session_id", hap.WithDomain(".example.com"))
Index ¶
- Constants
- func ApiOnExit(r *http.Request, rep ReplySpec)
- func DebugMode(onoff ...bool) bool
- func DelCookie(w http.ResponseWriter, r *http.Request, key string, opts ...CookieOption)
- func FixedReplyFields(args map[string]any)
- func IsTLS(r *http.Request, checkProxy bool) bool
- func JSONMarshaller() *internal.JSONMarshallerOption
- func LoadLanguage(tag language.Tag, trans map[string]string)
- func NewSubRequest(parent *http.Request, method, url string, body io.Reader) (*http.Request, error)
- func NewSubRequestWithTimeout(parent *http.Request, timeout time.Duration, method, url string, ...) (req *http.Request, cancel context.CancelFunc, err error)
- func Register(a API, mx ...*http.ServeMux)
- func SetCookie(w http.ResponseWriter, r *http.Request, key, val string, opts ...CookieOption)
- func WithGlobalActions(as ...Action)
- func WithLangSpecifier(lang string)
- func WithPanicLogger(f func(mesg string, trace []string))
- func WithPostResponseTrace(f func(*TraceContext))
- func WithServiceInfo(spec ServiceInfo)
- func WithTraceFlagFunc(f TraceFlagFunc)
- type API
- type Action
- type ApiSpec
- type CookieOption
- type NetRange
- type ParamSpec
- type ReplyDesc
- type ReplySpec
- type ServiceInfo
- type TraceContext
- func (tc *TraceContext) Attr(key, val string)
- func (tc *TraceContext) End(fin func(*TraceContext))
- func (tc *TraceContext) GetState(key string) string
- func (tc *TraceContext) Inject(r *http.Request) *http.Request
- func (tc *TraceContext) NewChild(name string) *TraceContext
- func (tc *TraceContext) NewRequest(ctx context.Context, method, url string, body io.Reader) (*http.Request, error)
- func (tc *TraceContext) SetState(key, val string) (err error)
- func (tc *TraceContext) TraceState() string
- func (tc *TraceContext) Traceparent() string
- type TraceFlag
- type TraceFlagFunc
Constants ¶
Variables ¶
This section is empty.
Functions ¶
func ApiOnExit ¶
ApiOnExit is called internally by the framework to end the trace context, and call the registered tracer. If no tracer is registered, nothing happens.
func DelCookie ¶
func DelCookie(w http.ResponseWriter, r *http.Request, key string, opts ...CookieOption)
DelCookie removes a cookie by setting its MaxAge to -1.
IMPORTANT: Cookie deletion requires exact matching of the original cookie's attributes (name, domain, path). If the original cookie was set with custom options like WithDomain(), the same options must be provided to DelCookie() for successful deletion.
Parameters:
w: HTTP response writer r: HTTP request (used for TLS detection) key: cookie name to delete opts: optional configuration functions (must match original cookie)
Examples:
hap.DelCookie(w, r, "session") // Delete basic cookie
hap.DelCookie(w, r, "session", hap.WithDomain(".example.com")) // Delete with domain
func FixedReplyFields ¶
FixedReplyFields adds fixed fields to JSON reply. For example:
FixedReplyFields(map[string]any{
"version": "1.0.0",
"host": "alpha",
})
This will add "version" and "host" fields to all JSON replies, which can be used for debugging. Note that if you specify reserved fields like "code", "data" and "mesg", they will not be actually used when producing API reply.
func JSONMarshaller ¶
func JSONMarshaller() *internal.JSONMarshallerOption
JSONMarshaller returns the JSON Marshaller option object, which is used to customize JSON reply keys in API style replies.
func LoadLanguage ¶
LoadLanguage exposes internal.LoadLanguage
func NewSubRequest ¶
NewSubRequest creates a new HTTP request as a child of the parent request, inheriting its tracing context (if present). If the parent contains a TraceContext, the new request will include the Traceparent header for trace continuity. Otherwise, it creates a plain request.
Use this for nested operations (e.g., service-to-service calls) where trace context propagation is required but no additional timeout is needed.
func NewSubRequestWithTimeout ¶
func NewSubRequestWithTimeout(parent *http.Request, timeout time.Duration, method, url string, body io.Reader) (req *http.Request, cancel context.CancelFunc, err error)
NewSubRequestWithTimeout creates a child HTTP request with a timeout, inheriting the parent's trace context. If the parent context has no deadline, it applies the given timeout.
The returned cancel function must be called by the caller to release resources, even if the request succeeds:
- If the parent had no timeout: cancel() stops the sub-request's timer.
- If the parent had a timeout: cancel() is a no-op but safe to call.
Example:
req, cancel, err := NewSubRequestWithTimeout(parentReq, 5*time.Second, "GET", url, nil)
if err != nil { ... }
defer cancel() // Mandatory to prevent resource leaks
resp, err := http.DefaultClient.Do(req)
func Register ¶
Register registers an API instance. `mx` can be zero or more http.ServeMux instances. If none are provided, the API will be registered with http.DefaultServeMux. In this case, the application only needs to define an http.Server object and call its ListenAndServe method:
svr := http.Server{Addr: ":8080"}
panic(svr.ListenAndServe())
func SetCookie ¶
func SetCookie(w http.ResponseWriter, r *http.Request, key, val string, opts ...CookieOption)
SetCookie creates and sets an HTTP cookie with secure defaults.
The cookie is configured with the following security defaults:
- HttpOnly: true (prevents JavaScript access)
- Secure: auto-detected based on request TLS (HTTPS only)
- SameSite: http.SameSiteLaxMode (CSRF protection)
- Path: "/" (site-wide availability)
Parameters:
w: HTTP response writer r: HTTP request (used for TLS detection) key: cookie name val: cookie value opts: optional configuration functions
Examples:
hap.SetCookie(w, r, "session", "token123") // Basic usage
hap.SetCookie(w, r, "theme", "dark", hap.WithMaxAge(86400))
hap.SetCookie(w, r, "auth", "token", hap.WithDomain(".example.com"), hap.WithMaxAge(3600))
func WithGlobalActions ¶
func WithGlobalActions(as ...Action)
WithGlobalActions defines one or more global actions, which are executed for all HTTP handlers. Global actions are executed before handler specific actions.
func WithLangSpecifier ¶
func WithLangSpecifier(lang string)
WithLangSpecifier exposes internal.WithLangSpecifier
func WithPanicLogger ¶
WithPanicLogger exposes internal.WithPanicLogger
func WithPostResponseTrace ¶
func WithPostResponseTrace(f func(*TraceContext))
WithPostResponseTrace registers a handler function `f` to be executed after the HTTP response is sent to the client.
Key behaviors:
- The handler `f` is **only invoked** if the request has an associated TraceContextm, and is triggered **after response transmission**.
- The provided TraceContext in `f` includes the original http.Request object, accessible via TraceContext.Request.
- The handler runs in the same goroutine as the request, ensure thread safety for shared data. Avoid blocking operations in `f`; use goroutines for long-running tasks.
func WithServiceInfo ¶
func WithServiceInfo(spec ServiceInfo)
WithServiceInfo attaches the given ServiceInfo to the trace context
func WithTraceFlagFunc ¶
func WithTraceFlagFunc(f TraceFlagFunc)
WithTraceFlagFunc registers a decision function to determine the tracing behavior. The provided function should return one of:
- TraceDisabled (-1): Skip generating Traceparent header
- TraceNoSample (0): Generate Traceparent with '00' flag (no sampling)
- TraceSampled (1): Generate Traceparent with '01' flag (sampling enabled)
The registered function will be called during ApiOnEnter phase to evaluate tracing policy for each incoming request.
Types ¶
type API ¶
API defines the interface for an API endpoint. The Endpoint() method returns the endpoint path as a string. The Spec() method provides the API specification, formatted using the provided message.Printer.
It also embeds the http.Handler interface, allowing the API to handle HTTP requests.
type Action ¶
Action represents a function signature used for handling HTTP requests within the hap package. It defines a callback function that takes three parameters:
- *arg.Args: A pointer to the arguments parsed from the request. See the documentation for arg.Args for more details.
- http.ResponseWriter: An interface used to construct the HTTP response.
- *http.Request: A pointer to the HTTP request being handled.
The function returns `any`, which allows it to return various types of responses depending on the logic implemented. This type is typically used to define the logic for processing HTTP requests and generating responses based on the request parameters and other conditions.
A handler can define one or more Actions, which are executed sequentially. The output of the previous Action determines whether the next Action will be executed. Although the output of an Action is defined as `any`, it does not mean any type of value can be returned. The allowed return value types and their handling logic are as follows:
- nil: If an Action returns nil, it indicates that all business logic has been processed and information has been returned to the client. Subsequent Actions will not be executed, and the framework will not return any data to the client.
- hap.ReplySpec: The Action has completed the business logic and returned the final result. The framework will serialize and send the returned data to the client.
- error: If the returned type is error, it will be converted to HTTP/500 information and sent to the client.
- *arg.Args: Indicates that the Action has only processed input parameters or performed part of the business logic. In this case, the next Action will be executed, and the Args parameter passed in will be the result of the previous Action's processing.
type ApiSpec ¶
type ApiSpec struct {
Tags url.Values `json:"tags,omitempty"`
Endpoint string `json:"endpoint"`
Method string `json:"method"`
Help []string `json:"help,omitempty"`
Params []ParamSpec `json:"params,omitempty"`
Output []ReplyDesc `json:"output,omitempty"`
}
ApiSpec describes the API specification used for documentation.
type CookieOption ¶
CookieOption represents a functional option for configuring cookies. It follows the functional options pattern popular in modern Go libraries.
func WithDomain ¶
func WithDomain(domain string) CookieOption
WithDomain sets the cookie's Domain attribute.
The domain determines which hosts can receive the cookie. Use with caution - incorrect domain settings can prevent cookies from being accessible or deleted properly.
Examples:
hap.WithDomain(".example.com") // Available to all subdomains
hap.WithDomain("api.example.com") // Only this specific subdomain
Note: Browsers prevent setting cookies for domains other than the current domain or its parent domains for security reasons.
func WithMaxAge ¶
func WithMaxAge(maxAge int) CookieOption
WithMaxAge sets the cookie's MaxAge attribute in seconds.
Positive values: cookie expires after the specified seconds Zero: session cookie (expires when browser closes) Negative: cookie deleted immediately (used by DelCookie)
Example:
hap.WithMaxAge(86400) // 24 hours hap.WithMaxAge(0) // session cookie
type NetRange ¶
type NetRange struct {
// contains filtered or unexported fields
}
NetRange represents a collection of network ranges stored in a slice of net.IPNet. This structure is used for access control in HTTP requests.
func NetRangeFunc ¶
NetRangeFunc creates a new NetRange object with a dynamic fetcher function. The key difference between this function and NewNetRange is illustrated in the example below:
func init() {
hap.Register(api.New("/api/endpoint").WithHandlers{
handler.GET().WithActions(
hap.AllowRemoteFrom(true, hap.NetRangeFunc(cfg.SafeNets)),
handleEndpoint,
)
})
}
In this example, the HTTP handlers are defined in the init() function to ensure they are automatically executed. At the time when init() is called, the application's configuration has not yet been initialized. By using NetRangeFunc, the actual network ranges are fetched only when the handler is executed for the first time.
func NewNetRange ¶
NewNetRange create a new NetRange object.
func (*NetRange) IsTrustedRequest ¶
IsTrustedRequest checks if an HTTP request `r` comes from an IP address within the NetRange. If `checkForward` is true, the function will check the X-Forwarded-For header (if present); otherwise, it will use r.RemoteAddr. Regardless of the NetRange contents, local loopback addresses (IPv4/IPv6) are always allowed.
In most cases, you should use [WithAccessControl], which internally uses this function.
type ParamSpec ¶
type ParamSpec struct {
Default *string `json:"default,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
Rules [][]string `json:"rules,omitempty"`
Help []string `json:"help,omitempty"`
Required bool `json:"required"`
}
ParamSpec describes the parameter specification used for documentation.
type ReplyDesc ¶
type ReplyDesc struct {
Spec ReplySpec `json:"spec"`
Mime string `json:"mime"`
Raw bool `json:"raw"`
}
ReplyDesc describes the reply specification used for documentation.
type ReplySpec ¶
ReplySpec exposes the private 'reply' struct.
func RawReply ¶
RawReply create a raw reply with an HTTP status code. Unlike the HAP API style Reply, a raw reply allows setting its MIME type using WithMimeType. For example:
func getAvatar(a *arg.Args, w http.ResponseWriter, r *http.Request) any {
uid := arg.Get[int64](a, "user_id")
img := getAvatar(uid)
return hap.RawReply(http.StatusOK).WithData(img).WithMimeType("image/jpeg")
}
func Reply ¶
Reply create a HAP API style reply. The reply will be sent to the client in JSON format, with the following structure:
{
"code": 200, // status code must be an integer
"data": "data", // data can be any type allowed by JSON
"mesg": "help message" // help message
}
Among these properties, only `code` is required, while `data` and `mesg` are optional. Typically, `data` is included in successful responses, and `mesg` is used to explain the failure reason in case of an error. The success or failure of the response is indicated by the `code`. A common convention is to use HTTP status codes for `code`. Example:
func setAvatar(a *arg.Args, w http.ResponseWriter, r *http.Request) any {
uid := arg.Get[int64](a, "user_id")
err := setAvatar(uid, r.Body)
if err != nil {
return hap.Reply(http.StatusInternalServerError).WithHelp(err.Error())
}
return hap.Reply(http.StatusOK)
}
type ServiceInfo ¶
type ServiceInfo struct {
Name string // service.name
Address string // service.instance.id
Version string // service.version
Environ string // deployment.environment.name
}
ServiceInfo describes the HTTP service, providing information like service name, server IP address, service version, and deployment environment (alpha/beta/stable).
type TraceContext ¶
type TraceContext struct {
Service *ServiceInfo
Attrs map[string]string
Request *http.Request
Reply ReplySpec
Args *arg.Args
Route string //handler matching pattern
SpanId string
SpanName string
TraceId string
ParentSpanId string
StartTime int64
EndTime int64
Flags byte
// contains filtered or unexported fields
}
TraceContext maps to the W3C TraceContext specification: https://www.w3.org/TR/trace-context/
func ApiOnEnter ¶
func ApiOnEnter(r *http.Request, entry string) *TraceContext
ApiOnEnter is called internally by the framework to create a trace context
func GetTraceContext ¶
func GetTraceContext(r *http.Request) *TraceContext
GetTraceContext returns the trace context from the request context
func (*TraceContext) Attr ¶
func (tc *TraceContext) Attr(key, val string)
Attr adds attributes to the trace context.
func (*TraceContext) End ¶
func (tc *TraceContext) End(fin func(*TraceContext))
func (*TraceContext) GetState ¶
func (tc *TraceContext) GetState(key string) string
func (*TraceContext) Inject ¶
func (tc *TraceContext) Inject(r *http.Request) *http.Request
Inject adds the Traceparent and Tracestate headers to the given HTTP request to propagate distributed tracing context. The headers follow the W3C Trace Context specification. Note: this method does not perform request cloning internally to avoid unnecessary performance overhead in guaranteed-safe scenarios.
func (*TraceContext) NewChild ¶
func (tc *TraceContext) NewChild(name string) *TraceContext
func (*TraceContext) NewRequest ¶
func (tc *TraceContext) NewRequest(ctx context.Context, method, url string, body io.Reader) (*http.Request, error)
NewRequest creates an HTTP request with the provided context, method, URL, and body, and injects the Traceparent and Tracestate headers from the TraceContext to propagate distributed tracing. These headers follow the W3C Trace Context format.
Key behaviors:
- Traceparent is always injected if the TraceContext is valid.
- Tracestate is injected only if the TraceContext contains non-empty states.
Usage:
- Use this method when creating outbound requests that need to participate in a trace.
- Ensure the context is derived from the parent request's context to maintain cancellation and timeout propagation.
- If the TraceContext contains vendor-specific states, they will be automatically included in the Tracestate header.
func (*TraceContext) SetState ¶
func (tc *TraceContext) SetState(key, val string) (err error)
func (*TraceContext) TraceState ¶
func (tc *TraceContext) TraceState() string
func (*TraceContext) Traceparent ¶
func (tc *TraceContext) Traceparent() string
Traceparent returns the W3C Traceparent header value for the trace context.
Source Files
¶
- actors.go
- cookie.go
- ipnet.go
- json.go
- proxy.go
- register.go
- reply.go
- request.go
- sessions.go
- spec.go
- state.go
- trace.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package api provides HTTP API endpoint management and specification generation.
|
Package api provides HTTP API endpoint management and specification generation. |
|
Package arg provides utilities for managing and processing arguments in a structured way.
|
Package arg provides utilities for managing and processing arguments in a structured way. |
|
Package cors provides configurable handlers for implementing Cross-Origin Resource Sharing (CORS) policies in Go HTTP servers.
|
Package cors provides configurable handlers for implementing Cross-Origin Resource Sharing (CORS) policies in Go HTTP servers. |
|
Package handler provides HTTP endpoint management and request processing for HAP APIs.
|
Package handler provides HTTP endpoint management and request processing for HAP APIs. |
|
Package param provides parameter validation utilities with configurable checkers and character sets.
|
Package param provides parameter validation utilities with configurable checkers and character sets. |
|
Package tag provides functionality for creating and managing Tag objects, which are particularly useful in API documentation.
|
Package tag provides functionality for creating and managing Tag objects, which are particularly useful in API documentation. |