### Benchmarks Middleware Setup and Usage Source: https://github.com/go-pkgz/rest/blob/master/README.md This example demonstrates how to set up the Benchmarks middleware with a chi router and retrieve benchmark statistics for different time windows. ```go router := chi.NewRouter() bench = rest.NewBenchmarks() router.Use(bench.Middleware) ... router.Get("/bench", func(w http.ResponseWriter, r *http.Request) { resp := struct { OneMin rest.BenchmarkStats `json:"1min"` FiveMin rest.BenchmarkStats `json:"5min"` FifteenMin rest.BenchmarkStats `json:"15min"` }{ bench.Stats(time.Minute), bench.Stats(time.Minute * 5), bench.Stats(time.Minute * 15), } render.JSON(w, r, resp) }) ``` -------------------------------- ### Complete Logger Configuration Example Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/logger.md Example demonstrating a full logger configuration with various options including prefix, body logging, size limits, IP anonymization, and custom user/subject functions. ```go package main import ( "net/http" "github.com/go-chi/chi" "github.com/go-pkgz/rest/logger" ) func main() { router := chi.NewRouter() // Logger with full configuration l := logger.New( logger.Prefix("MYAPP"), logger.WithBody, logger.MaxBodySize(2048), logger.IPfn(logger.AnonymizeIP), logger.UserFn(func(r *http.Request) (string, error) { return r.Header.Get("X-User-ID"), nil }), logger.SubjFn(func(r *http.Request) (string, error) { return r.Method + " " + r.URL.Path, nil }), ) router.Use(l.Handler) router.Get("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Hello")) }) http.ListenAndServe(":8080", router) } ``` -------------------------------- ### Install go-pkgz/rest Source: https://github.com/go-pkgz/rest/blob/master/README.md Use this command to install or update the library. ```bash go get -u github.com/go-pkgz/rest ``` -------------------------------- ### Custom Backend Implementation Example Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/logger.md Example of implementing a custom file logger by embedding os.File and implementing the Logf method. ```go type FileLogger struct { file *os.File } func (fl *FileLogger) Logf(format string, args ...any) { fmt.Fprintf(fl.file, format, args...) } l := logger.New(logger.Log(&FileLogger{file: logFile})) ``` -------------------------------- ### Complete Advanced Go REST API Example Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md A comprehensive example demonstrating the integration of various advanced features including benchmarking, metrics, profiling, compression, static file serving with SPA support, and deprecation middleware. ```go package main import ( "log" "net/http" "time" "github.com/go-chi/chi" "github.com/go-pkgz/rest" ) func main() { router := chi.NewRouter() // Benchmarking bench := rest.NewBenchmarks().WithTimeRange(30 * time.Minute) router.Use(bench.Middleware) // Metrics and profiling router.Use(rest.Metrics("127.0.0.1")) router.Mount("/debug", rest.Profiler("127.0.0.1")) // Compression router.Use(rest.Gzip()) // Benchmark metrics endpoint router.Get("/metrics/bench", func(w http.ResponseWriter, r *http.Request) { resp := struct { OneMin rest.BenchmarkStats `json:"1min"` FiveMin rest.BenchmarkStats `json:"5min"` }{ OneMin: bench.Stats(time.Minute), FiveMin: bench.Stats(5 * time.Minute), } rest.EncodeJSON(w, http.StatusOK, resp) }) // Static files with SPA support fs, err := rest.NewFileServer("/", "./dist", rest.FsOptSPA) if err != nil { log.Fatal(err) } router.Handle("/*", fs) // Deprecated API endpoint v1 := chi.NewRouter() v1.Use(rest.Deprecation("1.0", time.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC))) v1.Get("/users", handleV1Users) router.Mount("/api/v1", v1) log.Fatal(http.ListenAndServe(":8080", router)) } func handleV1Users(w http.ResponseWriter, r *http.Request) { rest.EncodeJSON(w, http.StatusOK, []map[string]string{ {"id": "1", "name": "John"}, }) } ``` -------------------------------- ### Ping-Pong Middleware Example Source: https://github.com/go-pkgz/rest/blob/master/README.md Demonstrates the Ping-Pong middleware's response to a GET request on /ping or any path with a /ping suffix. Includes example response headers. ```http > http GET https://remark42.radio-t.com/ping HTTP/1.1 200 OK Date: Sun, 15 Jul 2018 19:40:31 GMT Content-Type: text/plain Content-Length: 4 Connection: keep-alive App-Name: remark42 App-Version: master-ed92a0b-20180630-15:59:56 Org: Umputun pong ``` -------------------------------- ### Custom Logger Implementation Example Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md An example implementation of the logger.Backend interface. This demonstrates how to create a custom logger that satisfies the Logf method signature. ```go type CustomLogger struct{} func (c *CustomLogger) Logf(format string, args ...any) { // Custom logging logic } ``` -------------------------------- ### Benchmarks Middleware Setup Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Creates a benchmarking middleware for collecting performance metrics like request rate and response times. The middleware is then applied to the router. ```go router := chi.NewRouter() bench := rest.NewBenchmarks() router.Use(bench.Middleware) // In a metrics endpoint router.Get("/metrics/bench", func(w http.ResponseWriter, r *http.Request) { resp := struct { OneMin rest.BenchmarkStats `json:"1min"` FiveMin rest.BenchmarkStats `json:"5min"` FifteenMin rest.BenchmarkStats `json:"15min"` }{ OneMin: bench.Stats(time.Minute), FiveMin: bench.Stats(time.Minute * 5), FifteenMin: bench.Stats(time.Minute * 15), } rest.EncodeJSON(w, http.StatusOK, resp) }) ``` -------------------------------- ### Complete REST API Example with Helpers Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/helpers.md Demonstrates the usage of various go-pkgz/rest helpers including JSON encoding/decoding, date range parsing, and error logging within a simple HTTP server. ```go package main import ( "log" "net/http" "github.com/go-pkgz/rest" "github.com/go-pkgz/rest/logger" ) type User struct { ID int `json:"id"` Name string `json:"name"` } func main() { logBackend := &logger.Middleware{} errLogger := rest.NewErrorLogger(logBackend) http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": // GET /users?from=2023-01-01&to=2023-12-31 from, to, err := rest.ParseFromTo(r) if err != nil { errLogger.Log(w, r, http.StatusBadRequest, err, "Invalid date range") return } users := []User{{ID: 1, Name: "John"}} rest.EncodeJSON(w, http.StatusOK, users) case "POST": var req User if err := rest.DecodeJSON(r, &req); err != nil { errLogger.Log(w, r, http.StatusBadRequest, err, "Invalid request") return } resp := rest.JSON{ "id": 1, "name": req.Name, } rest.RenderJSON(w, resp) } }) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` -------------------------------- ### Profiler Middleware Mounting Source: https://github.com/go-pkgz/rest/blob/master/README.md This example shows how to mount the Profiler middleware as a sub-router to expose net/http/pprof endpoints. ```go func MyService() http.Handler { r := chi.NewRouter() // ..middlewares r.Mount("/debug", middleware.Profiler()) // ..routes return r } ``` -------------------------------- ### CORS Middleware Configuration Examples Source: https://github.com/go-pkgz/rest/blob/master/README.md Configure Cross-Origin Resource Sharing with various options. Supports default settings, specific origins with credentials, and full configuration. ```go // allow all origins (default) router.Use(rest.CORS()) ``` ```go // specific origins with credentials router.Use(rest.CORS( rest.CorsAllowedOrigins("https://app.example.com", "https://admin.example.com"), rest.CorsAllowCredentials(true), rest.CorsMaxAge(86400), )) ``` ```go // full configuration router.Use(rest.CORS( rest.CorsAllowedOrigins("https://app.example.com"), rest.CorsAllowedMethods("GET", "POST", "PUT", "DELETE"), rest.CorsAllowedHeaders("Authorization", "Content-Type", "X-Custom-Header"), rest.CorsExposedHeaders("X-Request-Id", "X-Total-Count"), rest.CorsAllowCredentials(true), rest.CorsMaxAge(3600), )) ``` -------------------------------- ### Create JSON Response Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md Example of creating a JSON response object and rendering it using rest.RenderJSON. ```go resp := rest.JSON{ "status": "ok", "data": data, "count": 42, } rest.RenderJSON(w, resp) ``` -------------------------------- ### Metrics Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Responds to GET /metrics with expvar metrics in JSON, allowing access control via IP addresses. Useful for monitoring and observability. ```go router := chi.NewRouter() // Allow all router.Use(rest.Metrics()) // Restrict to localhost router.Use(rest.Metrics("127.0.0.1")) // Restrict to internal network router.Use(rest.Metrics("192.168.0.0/24", "10.0.0.0/8")) // Access at: GET /metrics ``` -------------------------------- ### Configure CSRF Protection Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/cors-csrf.md Demonstrates different ways to configure the CSRF protection middleware, including basic setup, adding trusted origins, and bypassing patterns. ```go router := chi.NewRouter() // Basic protection protection := rest.NewCrossOriginProtection() router.Use(protection.Handler) // With trusted origins for cross-origin requests protection := rest.NewCrossOriginProtection() protection.AddTrustedOrigin("https://mobile.example.com") protection.AddTrustedOrigin("https://api.example.com") router.Use(protection.Handler) // With bypass patterns for webhooks protection := rest.NewCrossOriginProtection() protection.AddBypassPattern("/api/webhook") protection.AddBypassPattern("/oauth/") router.Use(protection.Handler) // Custom deny handler protection := rest.NewCrossOriginProtection() protection.SetDenyHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "CSRF validation failed", http.StatusForbidden) })) router.Use(protection.Handler) ``` -------------------------------- ### Health Middleware Setup Source: https://github.com/go-pkgz/rest/blob/master/README.md Configures the Health middleware with custom check functions. The middleware responds with 200 if all checks pass, and 503 otherwise. For production, consider using with a throttler/limiter and auth middleware. ```go check1 := func(ctx context.Context) (name string, err error) { // do some check, for example check DB connection return "check1", nil // all good, passed } check2 := func(ctx context.Context) (name string, err error) { // do some other check, for example ping an external service return "check2", errors.New("some error") // check failed } router := chi.NewRouter() outer.Use(rest.Health("/health", check1, check2)) ``` -------------------------------- ### Logger Middleware Log Format Example Source: https://github.com/go-pkgz/rest/blob/master/README.md Illustrates the format of log entries produced by the Logger middleware, including method, URL, IP, status code, body size, handling time, and optional user info, subject, request ID, and body. ```log 019/03/05 17:26:12.976 [INFO] GET - /api/v1/find?site=remark - 8e228e9cfece - 200 (115) - 4.47784618s ``` -------------------------------- ### Metrics Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Provides a middleware that responds to GET /metrics requests with expvar metrics in JSON format. This is useful for monitoring and observability. You can optionally restrict access to specific IP addresses. ```APIDOC ## Metrics Middleware ### Description Responds to GET /metrics with expvar metrics in JSON. Useful for monitoring and observability. ### Function Signature ```go func Metrics(onlyIps ...string) func(http.Handler) http.Handler ``` ### Parameters #### Variadic Parameters - **onlyIps** (...string) - Optional - IPs allowed to access metrics. ### Returns - Middleware function that exposes metrics. ### Response - JSON with all registered expvar metrics. ### Status Codes - `200` - Metrics returned successfully. - `403` - IP address not allowed to access metrics. ### Example Usage ```go router := chi.NewRouter() // Allow all IPs to access metrics router.Use(rest.Metrics()) // Restrict access to localhost router.Use(rest.Metrics("127.0.0.1")) // Restrict access to internal network ranges router.Use(rest.Metrics("192.168.0.0/24", "10.0.0.0/8")) // Metrics will be available at: GET /metrics ``` ### Example Response (JSON) ```json { "cmdline": ["/app"], "memstats": {...}, "custom_metric": 42 } ``` ``` -------------------------------- ### Configure File Server with Options Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Set up a file server with options for Single Page Application (SPA) mode, directory listing, and custom 404 responses. ```go fs, err := rest.NewFileServer( "/static", // public URL path "./public", // local directory rest.FsOptSPA, rest.FsOptListing, rest.FsOptCustom404(custom404Reader), ) ``` -------------------------------- ### Enable Directory Listing Option Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Use FsOptListing to enable directory listing for the file server. By default, accessing directories results in a 404 error. ```go fs, err := rest.NewFileServer("/files", "./uploads", rest.FsOptListing) ``` -------------------------------- ### realip Get Function Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md The realip.Get function is a utility function for extracting the real client IP address from an HTTP request. ```APIDOC ## realip Get Function ### Description Utility function for IP extraction. Provides a way to get the real client IP address from an HTTP request. ### Signature `func Get(r *http.Request) (string, error)` ``` -------------------------------- ### Create Basic File Server Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Creates a file server for static assets. By default, directory listing is disabled and path traversal is prevented. ```go fs, err := rest.NewFileServer("/static", "./public") if err != nil { log.Fatal(err) } router.Handle("/static/*", fs) ``` -------------------------------- ### Create File Server with Directory Listing and Custom 404 Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Creates a file server with directory listing enabled and a custom 404 error page. Ensure the custom 404 file reader is properly handled. ```go custom404, err := os.Open("./public/404.html") if err != nil { log.Fatal(err) } fs, err := rest.NewFileServer("/static", "./public", rest.FsOptListing, rest.FsOptCustom404(custom404), ) ``` -------------------------------- ### RealIP Get Function Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md Provides a utility function for extracting the real IP address from an HTTP request. This function is part of the realip package. ```go package realip func Get(r *http.Request) (string, error) ``` -------------------------------- ### Ping Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/middleware.md Responds with 'pong' to requests ending in '/ping' for GET and HEAD methods. This middleware stops the chain if a ping request is detected. ```go func Ping(next http.Handler) http.Handler ``` ```go router := chi.NewRouter() router.Use(rest.Ping) // GET /ping -> 200 OK with "pong" // GET /api/v1/ping -> 200 OK with "pong" ``` -------------------------------- ### FsOptListing Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Enables directory listing. By default, accessing directories returns 404. ```APIDOC ## FsOptListing ### Description Enables directory listing. By default, accessing directories returns 404. ### Method Signature ```go func FsOptListing(fs *FS) error ``` ### Example Usage ```go fs, err := rest.NewFileServer("/files", "./uploads", rest.FsOptListing) ``` ``` -------------------------------- ### Configure Benchmarks with Time Range Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Initialize a benchmarks instance and configure the maximum data retention period using method chaining. ```go bench := rest.NewBenchmarks().WithTimeRange(30 * time.Minute) ``` -------------------------------- ### Configure Gzip Compression (Default) Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Enables Gzip compression with default content types. ```go rest.Gzip() // Default types ``` -------------------------------- ### Complete Go REST Configuration Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md This snippet shows a full configuration of the go-pkgz/rest library, including setting up Chi router, various middleware for logging, security, rate limiting, and API versioning. It's useful for setting up a robust API server. ```go package main import ( "net/http" "time" "github.com/go-chi/chi" "github.com/go-pkgz/rest" "github.com/go-pkgz/rest/logger" ) func main() { router := chi.NewRouter() // Logger with full config l := logger.New( logger.Prefix("API"), logger.WithBody, logger.MaxBodySize(2048), logger.IPfn(logger.AnonymizeIP), ) router.Use(l.Handler) // CORS router.Use(rest.CORS( rest.CorsAllowedOrigins("https://app.example.com"), rest.CorsAllowCredentials(true), rest.CorsMaxAge(86400), )) // Security router.Use(rest.Secure(rest.SecAllHeaders())) // Rate limiting router.Use(rest.Throttle(100)) // Request size router.Use(rest.SizeLimit(1024 * 1024)) // Compression router.Use(rest.Gzip()) // Benchmarks bench := rest.NewBenchmarks().WithTimeRange(30 * time.Minute) router.Use(bench.Middleware) // IP restrictions router.Use(rest.OnlyFrom("192.168.0.0/16", "10.0.0.0/8")) // Authentication (v1 API only) v1 := chi.NewRouter() v1.Use(rest.BasicAuthWithUserPasswd("admin", "secret")) v1.Use(rest.Deprecation("1.0", time.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC))) v1.Get("/users", handleV1Users) router.Mount("/api/v1", v1) // Profiling (localhost only) router.Mount("/debug", rest.Profiler("127.0.0.1")) http.ListenAndServe(":8080", router) } func handleV1Users(w http.ResponseWriter, r *http.Request) { rest.EncodeJSON(w, http.StatusOK, []map[string]string{ {"id": "1", "name": "John"}, }) } ``` -------------------------------- ### StripSlashes Middleware for Trailing Slash Removal Source: https://github.com/go-pkgz/rest/blob/master/README.md This middleware removes trailing slashes from URL paths, except for the root path. For example, '/users/' becomes '/users'. ```go router.Use(rest.StripSlashes) ``` -------------------------------- ### Health Middleware Response Example Source: https://github.com/go-pkgz/rest/blob/master/README.md Shows the typical HTTP response from the Health middleware when some checks fail. The response body is a JSON array detailing the status of each check. ```http > http GET https://example.com/health HTTP/1.1 503 Service Unavailable Date: Sun, 15 Jul 2018 19:40:31 GMT Content-Type: application/json; charset=utf-8 Content-Length: 36 [ {"name":"check1","status":"ok"}, {"name":"check2","status":"failed","error":"some error"} ] ``` -------------------------------- ### Basic Middleware Stack in Go Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/README.md Demonstrates how to compose common middleware for a REST API using chi router. Includes logging, security, performance, and API-specific middleware. ```go router := chi.NewRouter() // Logging router.Use(logger.Logger) // Security router.Use(rest.Secure()) router.Use(rest.CSRF()) // Performance router.Use(rest.Gzip()) router.Use(rest.Throttle(100)) // API router.Get("/users", handleUsers) ``` -------------------------------- ### NewFileServer Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Creates a file server for static assets with optional SPA support and directory listing control. ```APIDOC ## NewFileServer ### Description Creates a file server for static assets with optional SPA support and directory listing control. ### Method Signature ```go func NewFileServer(public, local string, options ...FsOpt) (*FS, error) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | public | string | yes | Public URL path (e.g., "/static") | | local | string | yes | Local directory path | | options | ...FsOpt | no | Configuration options | ### Returns `(*FS, error)` - File server or error ### Behavior - Disables directory listing by default - Supports SPA mode (404 → /index.html) - Prevents path traversal attacks - Validates local path exists ### Example Usage ```go // Basic file server fs, err := rest.NewFileServer("/static", "./public") if err != nil { log.Fatal(err) } router.Handle("/static/*", fs) // SPA support (React, Vue, etc.) fs, err := rest.NewFileServer("/", "./dist", rest.FsOptSPA) if err != nil { log.Fatal(err) } router.Handle("/*", fs) // With directory listing and custom 404 custom404, err := os.Open("./public/404.html") if err != nil { log.Fatal(err) } fs, err := rest.NewFileServer("/static", "./public", rest.FsOptListing, rest.FsOptCustom404(custom404), ) ``` ``` -------------------------------- ### Get Client Real IP Address Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Extracts the client's real IP address from request headers with intelligent fallback. Prioritizes X-Real-IP, CF-Connecting-IP, X-Forwarded-For, and RemoteAddr. Only accepts public IPs and validates IP format. ```go package realip func Get(r *http.Request) (string, error) ``` ```go http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ip, err := realip.Get(r) if err != nil { ip = "unknown" } log.Printf("Client IP: %s", ip) }) ``` -------------------------------- ### Basic Authentication with Username and Password Source: https://github.com/go-pkgz/rest/blob/master/README.md Use this middleware for simple username and password authentication. It directly compares the provided credentials. ```go router.Use(rest.BasicAuthWithUserPasswd("admin", "secret")) ``` -------------------------------- ### Ping Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/middleware.md Responds with "pong" to requests ending in "/ping". Supports both GET and HEAD methods. HEAD requests return headers only without body. This middleware stops the chain if a ping request is detected. ```APIDOC ## Ping ### Description Responds with "pong" to requests ending in "/ping". Supports both GET and HEAD methods. HEAD requests return headers only without body. This middleware stops the chain if a ping request is detected. ### Function Signature ```go func Ping(next http.Handler) http.Handler ``` ### Parameters #### Next Handler - **next** (http.Handler) - Required - The next handler in the chain ### Returns - **http.Handler** - Middleware handler ### Response - **Status**: `200 OK` - **Body**: "pong" (GET only, not for HEAD) - **Content-Type**: `text/plain` ### Behavior - Matches requests to paths ending with "/ping" (e.g., `/ping`, `/api/v2/ping`) - Supports both GET and HEAD methods - Case-insensitive path matching - Terminates middleware chain for matched requests ### Example ```go router := chi.NewRouter() router.Use(rest.Ping) // GET /ping -> 200 OK with "pong" // GET /api/v1/ping -> 200 OK with "pong" ``` ``` -------------------------------- ### Configure AppInfo Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Initializes the AppInfo middleware with application name, company, and version. It uses the MHOST environment variable to set the Host header. ```go rest.AppInfo("myapp", "acme", "1.0.0") // Sets Host header to "server-prod-01" ``` -------------------------------- ### Configure All Security Headers Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Enable a comprehensive set of security headers suitable for most web applications, including CSP and Permissions-Policy. ```go rest.Secure(rest.SecAllHeaders()) ``` -------------------------------- ### Create File Server with SPA Support Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Creates a file server with Single Page Application (SPA) mode enabled. Requests for missing files will serve /index.html, suitable for client-side routers. ```go fs, err := rest.NewFileServer("/", "./dist", rest.FsOptSPA) if err != nil { log.Fatal(err) } router.Handle("/*", fs) ``` -------------------------------- ### NewCrossOriginProtection Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/cors-csrf.md Creates a new CSRF protection middleware instance. This middleware uses modern browser Fetch metadata headers (Sec-Fetch-Site, Origin) to protect against cross-origin attacks. Safe methods like GET, HEAD, and OPTIONS are always permitted. By default, it returns a 403 Forbidden status for blocked requests. ```APIDOC ## NewCrossOriginProtection ### Description Creates a new CSRF protection middleware using modern browser Fetch metadata headers (Sec-Fetch-Site, Origin). Safe methods (GET, HEAD, OPTIONS) are always allowed. Returns 403 Forbidden for blocked requests. ### Returns `*CrossOriginProtection` - CSRF protection handler ### How It Works: 1. Safe methods (GET, HEAD, OPTIONS) always allowed 2. Checks `Sec-Fetch-Site` header: "same-origin" or "none" allowed 3. Falls back to comparing `Origin` header with request `Host` 4. Requests without headers assumed same-origin (non-browser clients) ### Supported Requests: - Sec-Fetch-Site: "same-origin" or "none" - Sec-Fetch-Site: "cross-site" if origin is trusted - Requests from same origin - Requests without browser headers (non-browser clients) ### Blocked Requests: - Cross-origin requests (Sec-Fetch-Site: "cross-site") - Requests from untrusted origins ### Example: ```go router := chi.NewRouter() // Basic protection protection := rest.NewCrossOriginProtection() router.Use(protection.Handler) // With trusted origins for cross-origin requests protection := rest.NewCrossOriginProtection() protection.AddTrustedOrigin("https://mobile.example.com") protection.AddTrustedOrigin("https://api.example.com") router.Use(protection.Handler) // With bypass patterns for webhooks protection := rest.NewCrossOriginProtection() protection.AddBypassPattern("/api/webhook") protection.AddBypassPattern("/oauth/") router.Use(protection.Handler) // Custom deny handler protection := rest.NewCrossOriginProtection() protection.SetDenyHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "CSRF validation failed", http.StatusForbidden) })) router.Use(protection.Handler) ``` ``` -------------------------------- ### Configure Gzip Compression (Custom) Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Enables Gzip compression for specified content types. ```go rest.Gzip("application/json", "text/html", "application/xml") ``` -------------------------------- ### Configure Default Security Headers Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Apply a baseline set of security headers for general web applications. ```go rest.Secure() ``` -------------------------------- ### Apply Secure Middleware with Defaults Source: https://github.com/go-pkgz/rest/blob/master/README.md Applies security headers with sensible defaults. This is a quick way to add common security headers to your responses. ```go router.Use(rest.Secure()) ``` -------------------------------- ### File Server Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/README.md Shows how to configure a file server for serving static assets, including Single Page Application (SPA) support and custom 404 pages. ```APIDOC ## File Server ### Description Configures a file server to serve static assets, with options for Single Page Application (SPA) routing and custom 404 error pages. ### Usage ```go // SPA support (React, Vue, etc.) fs, _ := rest.NewFileServer("/", "./dist", rest.FsOptSPA) router.Handle("/*", fs) // Static files with custom 404 fs, _ := rest.NewFileServer("/static", "./public", rest.FsOptCustom404(os.Open("404.html")), ) router.Handle("/static/*", fs) ``` ``` -------------------------------- ### Configure Security Headers with Options Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Customize security headers like X-Frame-Options, Content-Security-Policy, and HSTS. This helps protect your application from common web vulnerabilities. ```go rest.Secure( rest.SecFrameOptions("SAMEORIGIN"), rest.SecContentTypeNosniff(true), rest.SecReferrerPolicy("no-referrer"), rest.SecContentSecurityPolicy("default-src 'self'"), rest.SecPermissionsPolicy("geolocation=(), camera=()"), rest.SecHSTS(31536000, true, false), rest.SecXSSProtection("1; mode=block"), ) ``` -------------------------------- ### File Server with SPA Support Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/README.md Serves static files and enables Single Page Application (SPA) routing by falling back to index.html for unknown paths. Use this for React, Vue, etc. applications. ```go // SPA support (React, Vue, etc.) fs, _ := rest.NewFileServer("/", "./dist", rest.FsOptSPA) router.Handle("/*", fs) ``` -------------------------------- ### Bcrypt Password Authentication Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/README.md Sets up basic authentication using Bcrypt hashed passwords. Ensure the password is kept secret. ```go // Bcrypt password hash, _ := rest.GenerateBcryptHash("password") router.Use(rest.BasicAuthWithBcryptHash("admin", hash)) ``` -------------------------------- ### Set Custom Logging Backend Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/logger.md Use this option to set a custom logging backend. The default uses the standard Go logger. The custom backend must implement the Backend interface. ```go func Log(log Backend) Option ``` ```go type Backend interface { Logf(format string, args ...any) } ``` ```go type CustomLogger struct{} func (c *CustomLogger) Logf(format string, args ...any) { // Custom logging } logger.New(logger.Log(&CustomLogger{})) ``` -------------------------------- ### Apply Secure Middleware with All Headers Source: https://github.com/go-pkgz/rest/blob/master/README.md Applies all security headers, including Content Security Policy (CSP) and Permissions-Policy, with restrictive defaults suitable for web applications. ```go router.Use(rest.Secure(rest.SecAllHeaders())) ``` -------------------------------- ### Benchmarks Struct Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md Defines the structure for performance metrics middleware. Use NewBenchmarks() to create an instance and Handler() to apply it as middleware. ```go type Benchmarks struct { // Fields are private } ``` -------------------------------- ### Basic Authentication with Checker Function Source: https://github.com/go-pkgz/rest/blob/master/README.md Implements Basic Authentication by matching provided username and password against a checker function. Use this for simple authentication scenarios where you can define credentials programmatically. ```go checkFn := func(user, passwd string) bool { return user == "admin" && passwd == "secret" } router.Use(rest.BasicAuth(checkFn)) ``` -------------------------------- ### File Server with Custom 404 Page Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/README.md Serves static files from a specified directory and uses a custom 404.html file when a requested resource is not found. Ensure the 404.html file exists. ```go // Static files with custom 404 fs, _ := rest.NewFileServer("/static", "./public", rest.FsOptCustom404(os.Open("404.html")), ) router.Handle("/static/*", fs) ``` -------------------------------- ### Apply Secure Middleware with Custom Options Source: https://github.com/go-pkgz/rest/blob/master/README.md Configures specific security headers with custom values. Use this to tailor security headers like X-Frame-Options, Referrer-Policy, HSTS, CSP, and Permissions-Policy to your application's needs. ```go router.Use(rest.Secure( rest.SecFrameOptions("SAMEORIGIN"), rest.SecReferrerPolicy("no-referrer"), rest.SecHSTS(86400, true, true), rest.SecContentSecurityPolicy("default-src 'self'"), rest.SecPermissionsPolicy("geolocation=(), camera=()"), )) ``` -------------------------------- ### CORS Middleware Usage Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/cors-csrf.md Demonstrates how to apply the CORS middleware to a router. It shows both default configuration and specific origin settings with credentials enabled. ```go router := chi.NewRouter() // Allow all origins with default settings router.Use(rest.CORS()) // Specific origins with credentials router.Use( rest.CORS( rest.CorsAllowedOrigins("https://app.example.com", "https://admin.example.com"), rest.CorsAllowCredentials(true), rest.CorsMaxAge(86400), ), ) ``` -------------------------------- ### Default Logger Configuration Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Initialize the default logger with a "REST" prefix using the standard Go logger. ```go logger.Logger ``` -------------------------------- ### Configure X-Frame-Options Header Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/security-middleware.md Sets the X-Frame-Options header to control clickjacking. Common values include 'DENY' and 'SAMEORIGIN'. ```go rest.SecFrameOptions("SAMEORIGIN") ``` -------------------------------- ### Basic Authentication with Browser Prompt Source: https://github.com/go-pkgz/rest/blob/master/README.md This middleware is similar to BasicAuthWithUserPasswd but also triggers the browser's authentication prompt by setting the WWW-Authenticate header. ```go router.Use(rest.BasicAuthWithPrompt("admin", "secret")) ``` -------------------------------- ### Authentication Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/README.md Demonstrates how to use BasicAuth middleware with Bcrypt and Argon2 password hashing for securing API endpoints. ```APIDOC ## Authentication Middleware ### Description Provides middleware for basic HTTP authentication using Bcrypt or Argon2 password hashing. ### Usage ```go // Bcrypt password hash, _ := rest.GenerateBcryptHash("password") router.Use(rest.BasicAuthWithBcryptHash("admin", hash)) // Argon2 password hash, salt, _ := rest.GenerateArgon2Hash("password") router.Use(rest.BasicAuthWithArgon2Hash("admin", hash, salt)) ``` ``` -------------------------------- ### Enable SPA Mode Option Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Use FsOptSPA to enable Single Page Application mode for the file server. This redirects 404 errors to index.html. ```go fs, err := rest.NewFileServer("/", "./dist", rest.FsOptSPA) // GET /any-route → returns /dist/index.html for client-side routing ``` -------------------------------- ### Configure Permissions-Policy Header Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/security-middleware.md Sets the Permissions-Policy header to control access to browser features. Provide a valid policy string. ```go rest.SecPermissionsPolicy("geolocation=(), microphone=()") ``` -------------------------------- ### Create ErrorLogger Instance Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/helpers.md Creates a new ErrorLogger instance from a provided logger backend. This logger is used for convenient error logging. ```go type ErrorLogger struct { l logger.Backend } ``` ```go func NewErrorLogger(l logger.Backend) *ErrorLogger ``` ```go errorLogger := rest.NewErrorLogger(myLogger) ``` -------------------------------- ### Secure Middleware with Custom Options Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/security-middleware.md Applies security headers with fully customized options. Use this to fine-tune specific security headers according to your application's needs. ```go router.Use(rest.Secure( rest.SecFrameOptions("SAMEORIGIN"), rest.SecReferrerPolicy("no-referrer"), rest.SecHSTS(86400, true, true), rest.SecContentSecurityPolicy("default-src 'self'ப்பில்"), rest.SecPermissionsPolicy("geolocation=(), camera=()"), )) ``` -------------------------------- ### FsOptSPA Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Enables SPA (Single Page Application) mode. Missing files (404) return /index.html instead. ```APIDOC ## FsOptSPA ### Description Enables SPA (Single Page Application) mode. Missing files (404) return /index.html instead. ### Method Signature ```go func FsOptSPA(fs *FS) error ``` ### Use Case React, Vue, Angular, and other client-side routers ### Example Usage ```go fs, err := rest.NewFileServer("/", "./dist", rest.FsOptSPA) // GET /any-route → returns /dist/index.html for client-side routing ``` ``` -------------------------------- ### File Server Structure Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md Represents an HTTP file server with optional SPA support and directory listing. Its fields are private; use NewFileServer. ```go type FS struct { // Fields are private, use NewFileServer } ``` -------------------------------- ### Create Custom Logger Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/logger.md Create a logger middleware with custom configurations using functional options. This allows for setting prefixes, enabling body logging, defining max body size, and adding custom user or subject identification functions. ```go l := logger.New( logger.Prefix("API"), logger.WithBody, logger.MaxBodySize(2048), logger.UserFn(func(r *http.Request) (string, error) { return r.Header.Get("X-User-ID"), nil }), ) router.Use(l.Handler) ``` -------------------------------- ### Enable Request Body Logging Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/logger.md Enable logging of the request body using the `WithBody` option. This is often used in conjunction with `MaxBodySize` to control the amount of data logged. ```go logger.New(logger.WithBody, logger.MaxBodySize(1024)) ``` -------------------------------- ### Configure Logger with Options Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Customize logger behavior by setting prefixes, logging request bodies, defining IP masking, and specifying user or subject identification functions. Supports Apache Combined Log format and custom backends. ```go logger.New( logger.Prefix("API"), logger.WithBody, logger.MaxBodySize(2048), logger.IPfn(logger.AnonymizeIP), logger.UserFn(func(r *http.Request) (string, error) { return r.Header.Get("X-User-ID"), nil }), logger.SubjFn(func(r *http.Request) (string, error) { return r.Method + " " + r.URL.Path, nil }), logger.ApacheCombined, logger.Log(customBackend), ) ``` -------------------------------- ### Security Headers Configuration Structure Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md Holds configuration for security headers like X-Frame-Options, Content-Security-Policy, and HSTS. ```go type SecureConfig struct { XFrameOptions string // X-Frame-Options value XContentTypeOptions string // X-Content-Type-Options value ReferrerPolicy string // Referrer-Policy value ContentSecurityPolicy string // Content-Security-Policy value PermissionsPolicy string // Permissions-Policy value STSSeconds int // HSTS max-age in seconds STSIncludeSubdomains bool // Add includeSubDomains flag STSPreload bool // Add preload flag XSSProtection string // X-XSS-Protection value } ``` -------------------------------- ### Add App Info Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/middleware.md Adds application information (name, version, author, host) to response headers. Useful for identifying your application in logs and network traffic. ```go func AppInfo(app, author, version string) func(http.Handler) http.Handler ``` ```go router := chi.NewRouter() router.Use(rest.AppInfo("myapp", "acme-corp", "1.2.3")) ``` -------------------------------- ### BasicAuth with Username and Password Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/authentication.md A simplified BasicAuth middleware for direct username and password comparison. It uses constant-time comparison to prevent timing attacks. ```go func BasicAuthWithUserPasswd(user, passwd string) func(http.Handler) http.Handler ``` ```go router := chi.NewRouter() router.Use(rest.BasicAuthWithUserPasswd("admin", "mysecret")) ``` -------------------------------- ### Logger Handler with Custom Prefix Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/logger.md Instantiate a logger middleware with a specific prefix and attach it to the router. This handler captures request details and logs them with the defined prefix. ```go l := logger.New(logger.Prefix("REST")) router.Use(l.Handler) ``` -------------------------------- ### BasicAuth with Bcrypt Hash and Browser Prompt Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/authentication.md Combines the security of bcrypt-hashed passwords with the user experience of a browser authentication prompt. This is useful for web applications requiring secure, yet user-friendly, authentication. ```go func BasicAuthWithBcryptHashAndPrompt(user, hashedPassword string) func(http.Handler) http.Handler ``` ```go hash, err := rest.GenerateBcryptHash("secret") if err != nil { log.Fatal(err) } router := chi.NewRouter() router.Use(rest.BasicAuthWithBcryptHashAndPrompt("admin", hash)) ``` -------------------------------- ### Configure Content-Security-Policy Header Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/security-middleware.md Sets the Content-Security-Policy header to mitigate cross-site scripting (XSS) and data injection attacks. Provide a valid policy string. ```go rest.SecContentSecurityPolicy("default-src 'self'ப்பில்") ``` -------------------------------- ### Convenience Option for All Headers Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/security-middleware.md A convenience option that sets both Content-Security-Policy and Permissions-Policy with restrictive defaults suitable for secure web applications. ```go rest.SecAllHeaders() ``` -------------------------------- ### BasicAuthWithBcryptHashAndPrompt Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/authentication.md Combines bcrypt-hashed password verification with browser authentication prompt. ```APIDOC ## BasicAuthWithBcryptHashAndPrompt ### Description Combines bcrypt-hashed password verification with browser authentication prompt. ### Method Signature ```go func BasicAuthWithBcryptHashAndPrompt(user, hashedPassword string) func(http.Handler) http.Handler ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | user | string | yes | Expected username | | hashedPassword | string | yes | Bcrypt hash of password | ### Returns Middleware function ### Example ```go hash, err := rest.GenerateBcryptHash("secret") if err != nil { log.Fatal(err) } router := chi.NewRouter() router.Use(rest.BasicAuthWithBcryptHashAndPrompt("admin", hash)) ``` ``` -------------------------------- ### Configure Static Cache Control Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Sets the cache expiration duration and a static version string for ETag generation. ```go rest.CacheControl(24*time.Hour, "v1.0.0") ``` -------------------------------- ### BasicAuthWithPrompt Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/authentication.md BasicAuth that adds a WWW-Authenticate header to prompt for credentials in the browser. Useful for protecting web applications. ```APIDOC ## BasicAuthWithPrompt ### Description BasicAuth that adds a WWW-Authenticate header to prompt for credentials in the browser. Useful for protecting web applications. ### Method Signature ```go func BasicAuthWithPrompt(user, passwd string) func(http.Handler) http.Handler ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | user | string | yes | Expected username | | passwd | string | yes | Expected password | ### Returns Middleware function ### Behavior - If valid credentials provided, continues to handler - If missing or invalid credentials, returns 401 with WWW-Authenticate header - Triggers browser login dialog ### Example ```go router := chi.NewRouter() router.Use(rest.BasicAuthWithPrompt("admin", "secret")) ``` ``` -------------------------------- ### AppInfo Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/middleware.md Adds application information to response headers. Sets App-Name, App-Version, Author, and optionally Host headers. ```APIDOC ## AppInfo ### Description Adds application information to response headers. Sets App-Name, App-Version, Author, and optionally Host headers. The Host header is populated from the `MHOST` environment variable if present. ### Function Signature ```go func AppInfo(app, author, version string) func(http.Handler) http.Handler ``` ### Parameters #### App - **app** (string) - Required - Application name to set in App-Name header #### Author - **author** (string) - Required - Author/organization name to set in Author header #### Version - **version** (string) - Required - Version string to set in App-Version header ### Returns - Middleware function ### Headers Set - `App-Name: {app}` - `App-Version: {version}` - `Author: {author}` - `Host: {MHOST}` (only if MHOST env var is set) ### Example ```go router := chi.NewRouter() router.Use(rest.AppInfo("myapp", "acme-corp", "1.2.3")) ``` ``` -------------------------------- ### FS Type Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Implements http.Handler for static file serving. ```APIDOC ## FS Type ### Description Implements http.Handler for static file serving. ### Method Signature ```go type FS struct { // Fields are private, use NewFileServer and options } func (fs *FS) ServeHTTP(w http.ResponseWriter, r *http.Request) ``` ``` -------------------------------- ### File Server Functional Options Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/types.md Functional options for configuring the file server. ```APIDOC ## File Server Functional Options ### Description Functional option type for file server configuration. ### Type Definition ```go type FsOpt func(*FS) error ``` ### Available Options - `FsOptSPA` - Enable SPA mode - `FsOptListing` - Enable directory listing - `FsOptCustom404(io.Reader)` - Custom 404 response ``` -------------------------------- ### Configure CORS with Options Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/configuration.md Set CORS policies by providing specific origins, methods, headers, and credential settings. Use this to control cross-origin access to your API. ```go rest.CORS( rest.CorsAllowedOrigins("https://app.example.com", "https://admin.example.com"), rest.CorsAllowedMethods("GET", "POST", "PUT"), rest.CorsAllowedHeaders("Content-Type", "Authorization"), rest.CorsExposedHeaders("X-Total-Count", "X-Page"), rest.CorsAllowCredentials(true), rest.CorsMaxAge(86400), ) ``` -------------------------------- ### Configure Referrer-Policy Header Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/security-middleware.md Sets the Referrer-Policy header to control the amount of referrer information sent. Common policies include 'no-referrer' and 'strict-origin-when-cross-origin'. ```go rest.SecReferrerPolicy("no-referrer") ``` -------------------------------- ### Mount Profiler Handler Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Mounts a sub-router for pprof profiling endpoints and runtime metrics. Restrict access by IP for production environments. ```go func Profiler(onlyIps ...string) http.Handler ``` -------------------------------- ### Gzip Compression Middleware Source: https://github.com/go-pkgz/rest/blob/master/_autodocs/api-reference/advanced-features.md Compresses responses with gzip if the client supports it and the content type matches. Default content types are provided, or custom ones can be specified. ```go router := chi.NewRouter() // Default compression router.Use(rest.Gzip()) // Custom content types router.Use(rest.Gzip( "application/json", "text/html", "application/xml", "text/csv", )) ```