Configuration Reference
All configuration is done by setting fields on *Mux after calling muxmaster.New(). Every field has a sensible default suitable for production use.
Table of Contents
Router Behaviour
RedirectTrailingSlash
mux.RedirectTrailingSlash = true // default
Automatically redirects requests with a trailing slash mismatch:
GET /users/→ 301 redirect to/users(when/usersis registered but not/users/)GET /users→ 301 redirect to/users/(when/users/is registered but not/users)
The redirect code is controlled by RedirectCode.
Set to false to return 404 in both cases instead of redirecting.
RedirectFixedPath
mux.RedirectFixedPath = true // default
Cleans the request path and issues a redirect if a match is found after cleaning:
- Removes extra slashes:
GET //users→ 301 to/users - Resolves dots:
GET /a/../users→ 301 to/users
This prevents duplicate-content issues where /users and //users serve identical content under different URLs.
Set to false to return 404 for malformed paths instead of redirecting.
HandleMethodNotAllowed
mux.HandleMethodNotAllowed = true // default
When true, and the URL matches a registered route but not for the requested method, MuxMaster responds with 405 Method Not Allowed and sets the Allow header to the list of allowed methods.
When false, such requests receive a 404 Not Found instead.
The response handler can be customized via mux.MethodNotAllowed.
HandleOPTIONS
mux.HandleOPTIONS = true // default
Automatically responds to OPTIONS requests with the list of allowed HTTP methods in the Allow header. The default response body is empty with status 200.
To customize the OPTIONS response globally:
mux.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Methods", w.Header().Get("Allow"))
w.WriteHeader(http.StatusNoContent)
})
Set to false if you handle OPTIONS manually (e.g. through the CORS middleware).
RedirectCode
mux.RedirectCode = http.StatusMovedPermanently // default: 301
The HTTP status code used for redirects triggered by RedirectTrailingSlash and RedirectFixedPath. Common values:
| Code | Constant | Semantics |
|---|---|---|
| 301 | http.StatusMovedPermanently |
Permanent redirect (cached) |
| 302 | http.StatusFound |
Temporary redirect (not cached) |
| 307 | http.StatusTemporaryRedirect |
Temporary, preserves method |
| 308 | http.StatusPermanentRedirect |
Permanent, preserves method |
Use 307 or 308 if you need POST requests to be redirected without the browser changing the method to GET.
Path Matching
CaseInsensitive
mux.CaseInsensitive = false // default
When true, route matching ignores case in path segments. A request for /Users/42 matches a route registered as /users/:id.
Note: this does not issue a redirect; the original URL is preserved in the response.
UseRawPath
mux.UseRawPath = false // default
When true, MuxMaster uses r.URL.RawPath for route matching instead of r.URL.Path. This matters when path values contain percent-encoded slashes (%2F):
r.URL.Path:/files/a%2Fbis decoded to/files/a/band would match/files/*filepathwithfilepath = "/a/b"(two separate segments)r.URL.RawPath:/files/a%2Fbis kept as-is and matches/files/*filepathwithfilepath = "/a%2Fb"(treated as a single segment)
Enable this only if your application legitimately uses encoded slashes in URL paths.
UnescapePathValues
mux.UnescapePathValues = false // default
When true, path parameter values are percent-decoded before being returned by PathParam and ParamsFromContext.
For example, with the route /search/:query and the URL /search/hello%20world:
false:PathParam(r, "query")returns"hello%20world"true:PathParam(r, "query")returns"hello world"
Performance Opt-ins (v1.1.0)
Two flags introduced in v1.1.0 recycle the per-request bundle through sync.Pools and bring the parameterised hot path down to zero allocations. Both flags default to false; both impose a strict handler-lifetime contract. The full contract, the failure modes, and an audit checklist for an existing codebase are at Maximum performance.
PoolRequestBundle
mux.PoolRequestBundle = false // default
When true, MuxMaster recycles the fused requestCtx + *http.Request bundle through three tier-matched sync.Pools (1 / 2 / 3+ parameters). The bundle is fully zeroed on Put so the next request cannot observe stale state.
Contract: handlers must not retain *http.Request past return — never capture r in a goroutine that outlives the handler. See the audit checklist before enabling on an existing codebase.
Forward compatibility: MuxMaster detects the unexported ctx field of http.Request at init via reflection (hasReqCtxField). On a future Go release that renames or removes the field, PoolRequestBundle = true is silently ignored and the router falls back to r.WithContext(...), preserving correctness over speed.
PoolFastParams
mux.PoolFastParams = false // default
When true, MuxMaster recycles the Params slice handed to FastHandler routes through three tier-matched sync.Pools (1 / 2 / 3 parameters). The pool stores *[N]Param so Put is itself zero-allocation.
Contract: FastHandler callbacks must not retain the Params slice or any Param element past return.
The two flags are independent — enable either, both, or neither.
Custom Handlers
NotFound
mux.NotFound = myNotFoundHandler
Called when no route matches the request path. Defaults to http.NotFound (plain-text 404).
mux.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
muxmaster.JSON(w, http.StatusNotFound, map[string]string{
"error": "not found",
"path": r.URL.Path,
})
})
MethodNotAllowed
mux.MethodNotAllowed = myMethodNotAllowedHandler
Called when the path matches a route but not for the requested HTTP method. The Allow header is set to the list of allowed methods before this handler is called.
mux.MethodNotAllowed = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
muxmaster.JSON(w, http.StatusMethodNotAllowed, map[string]string{
"error": "method not allowed",
"allowed": w.Header().Get("Allow"),
})
})
Only active when HandleMethodNotAllowed is true.
GlobalOPTIONS
mux.GlobalOPTIONS = myOptionsHandler
Called for every auto-handled OPTIONS request. The Allow header is already set when this handler runs.
Only active when HandleOPTIONS is true.
PanicHandler
mux.PanicHandler = func(w http.ResponseWriter, r *http.Request, rcv any) { ... }
If set, catches panics in downstream handlers and calls this function instead of letting the panic propagate. Receives the value passed to panic() as rcv.
mux.PanicHandler = func(w http.ResponseWriter, r *http.Request, rcv any) {
log.Printf("panic: %v", rcv)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
ErrorHandler
mux.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { ... }
Called for every HandlerFuncE that returns a non-nil error. See Error Handling for details.
Complete Example
mux := muxmaster.New()
// Routing behaviour
mux.RedirectTrailingSlash = true
mux.RedirectFixedPath = true
mux.HandleMethodNotAllowed = true
mux.HandleOPTIONS = true
mux.RedirectCode = http.StatusMovedPermanently
// Path matching
mux.CaseInsensitive = false
mux.UseRawPath = false
mux.UnescapePathValues = false
// Custom error responses (JSON)
mux.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
muxmaster.JSON(w, http.StatusNotFound, map[string]string{"error": "not found"})
})
mux.MethodNotAllowed = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
muxmaster.JSON(w, http.StatusMethodNotAllowed, map[string]string{
"error": "method not allowed",
"allowed": w.Header().Get("Allow"),
})
})
mux.PanicHandler = func(w http.ResponseWriter, r *http.Request, rcv any) {
log.Printf("panic: %v\n%s", rcv, debug.Stack())
muxmaster.JSON(w, http.StatusInternalServerError, map[string]string{
"error": "internal server error",
})
}
mux.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
code := http.StatusInternalServerError
var he muxmaster.HTTPError
if errors.As(err, &he) {
code = he.StatusCode()
} else {
log.Printf("unhandled error: %v", err)
}
muxmaster.JSON(w, code, map[string]string{"error": err.Error()})
}
See Also
- Routing — trailing slash and path normalization in more detail
- Error Handling — custom error handler patterns
- Middleware — CleanPath and StripSlashes as alternatives to redirect-based normalization
Upstream source
The Mux struct, its option functions, and the trailing-slash and path-cleaning semantics referenced above are implemented in mux.go in the upstream repository.
Common questions
How do I configure MuxMaster's trailing-slash policy?
Pass mux.WithStrictSlash(false) (or set Config.StrictSlash to false) so the router treats /foo and /foo/ as the same route. The default is true, which serves a 301 redirect from one form to the other to keep search-engine signals concentrated on a single canonical URL.
How do I customise the not-found response?
Set mux.Config.NotFoundHandler to any http.Handler (or pass mux.WithNotFoundHandler at construction). The handler runs when no registered pattern matches the request URL; it sees the original request unchanged and is responsible for writing both the status code and the body.
How do I enforce a maximum request size at the router level?
There is no router-level body limit — the runtime exposes http.MaxBytesReader for that purpose. Wrap the handler chain (or attach a middleware that wraps r.Body in http.MaxBytesReader) to enforce a per-route or per-method cap before any business logic runs.