Documentation
¶
Overview ¶
Package web provides a configurable HTTP web server with built-in support for common middleware patterns, file serving, and WebSocket handling.
This package offers a singleton Server instance that can be customized through fluent-style methods for setting host, port, headers, middleware, handlers, and WebSocket routes.
Features include:
- Serving static files from embedded file systems
- Middleware support including security headers, CORS, gzip compression, and request logging
- Easy registration of HTTP handlers and handler functions
- WebSocket support with connection management and custom handlers
- Graceful shutdown and restart capabilities
Example usage:
package main
import (
"net/http" "github.com/valentin-kaiser/go-core/web"
)
func main() {
done := make(chan error)
web.Instance().
WithHost("localhost").
WithPort(8088).
WithCacheControl("max-age=3600, s-maxage=7200").
WithSecurityHeaders().
WithCORSHeaders().
WithGzip().
WithLog().
WithHandlerFunc("/", handler).
StartAsync(done)
if err := <-done; err != nil {
panic(err)
}
err := web.Instance().Stop()
if err != nil {
panic(err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("Hello, World!"))
}
Index ¶
- Variables
- type Middleware
- type MiddlewareOrder
- type ResponseWriter
- func (rw *ResponseWriter) Header() http.Header
- func (rw *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
- func (rw *ResponseWriter) History() [][]byte
- func (rw *ResponseWriter) Status() int
- func (rw *ResponseWriter) Write(b []byte) (int, error)
- func (rw *ResponseWriter) WriteHeader(status int)
- type Router
- func (router *Router) GetRegisteredRoutes() []string
- func (router *Router) Handle(pattern string, handler http.Handler)
- func (router *Router) HandleFunc(pattern string, handlerFunc http.HandlerFunc)
- func (router *Router) OnStatus(pattern string, status int, fn func(http.ResponseWriter, *http.Request))
- func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (router *Router) UnregisterAllHandler()
- func (router *Router) UnregisterHandler(patterns []string)
- func (router *Router) Use(order MiddlewareOrder, middleware func(http.Handler) http.Handler)
- type Server
- func (s *Server) GetRegisteredRoutes() []string
- func (s *Server) Restart() error
- func (s *Server) RestartAsync(done chan error)
- func (s *Server) SetBlacklist(list []string) *Server
- func (s *Server) SetWhitelist(list []string) *Server
- func (s *Server) Shutdown() error
- func (s *Server) Start() *Server
- func (s *Server) StartAsync(done chan error)
- func (s *Server) Stop() error
- func (s *Server) UnregisterAllHandler() *Server
- func (s *Server) UnregisterHandler(paths []string) *Server
- func (s *Server) WithCORSHeaders() *Server
- func (s *Server) WithCacheControl(cacheControl string) *Server
- func (s *Server) WithCanonicalRedirect(domain string) *Server
- func (s *Server) WithCustomErrorLog(logger *l.Logger) *Server
- func (s *Server) WithCustomMiddleware(middleware Middleware) *Server
- func (s *Server) WithCustomMiddlewareOrder(order MiddlewareOrder, middleware Middleware) *Server
- func (s *Server) WithErrorLog() *Server
- func (s *Server) WithFS(entrypoints []string, filesystem fs.FS) *Server
- func (s *Server) WithFileServer(entrypoints []string, path string) *Server
- func (s *Server) WithGzip() *Server
- func (s *Server) WithGzipLevel(level int) *Server
- func (s *Server) WithHandler(path string, handler http.Handler) *Server
- func (s *Server) WithHandlerFunc(path string, handler http.HandlerFunc) *Server
- func (s *Server) WithHeader(key, value string) *Server
- func (s *Server) WithHeaders(headers map[string]string) *Server
- func (s *Server) WithHoneypot(pattern string) *Server
- func (s *Server) WithHost(address string) *Server
- func (s *Server) WithIdleTimeout(timeout time.Duration) *Server
- func (s *Server) WithJRPC(path string, service *jrpc.Service) *Server
- func (s *Server) WithLog() *Server
- func (s *Server) WithOnHTTPCode(code int, pattern []string, handler func(http.ResponseWriter, *http.Request)) *Server
- func (s *Server) WithOnHoneypot(callback func(map[string]*net.IPNet)) *Server
- func (s *Server) WithPort(port uint16) *Server
- func (s *Server) WithRateLimit(pattern string, count int, period time.Duration) *Server
- func (s *Server) WithReadHeaderTimeout(timeout time.Duration) *Server
- func (s *Server) WithReadTimeout(timeout time.Duration) *Server
- func (s *Server) WithRedirectToHTTPS(port uint16) *Server
- func (s *Server) WithSecurityHeaders() *Server
- func (s *Server) WithSelfSignedTLS() *Server
- func (s *Server) WithTLS(config *tls.Config) *Server
- func (s *Server) WithVaryHeader(header string) *Server
- func (s *Server) WithVaryHeaders(headers []string) *Server
- func (s *Server) WithWebsocket(path string, handler func(http.ResponseWriter, *http.Request, *websocket.Conn)) *Server
- func (s *Server) WithWriteTimeout(timeout time.Duration) *Server
Constants ¶
This section is empty.
Variables ¶
var ErrorCodes = []int{ http.StatusBadRequest, http.StatusUnauthorized, http.StatusPaymentRequired, http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed, http.StatusNotAcceptable, http.StatusProxyAuthRequired, http.StatusRequestTimeout, http.StatusConflict, http.StatusGone, http.StatusLengthRequired, http.StatusPreconditionFailed, http.StatusRequestEntityTooLarge, http.StatusRequestURITooLong, http.StatusUnsupportedMediaType, http.StatusRequestedRangeNotSatisfiable, http.StatusExpectationFailed, http.StatusTeapot, http.StatusMisdirectedRequest, http.StatusUnprocessableEntity, http.StatusLocked, http.StatusFailedDependency, http.StatusTooEarly, http.StatusUpgradeRequired, http.StatusPreconditionRequired, http.StatusTooManyRequests, http.StatusRequestHeaderFieldsTooLarge, http.StatusUnavailableForLegalReasons, http.StatusInternalServerError, http.StatusNotImplemented, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout, http.StatusHTTPVersionNotSupported, http.StatusVariantAlsoNegotiates, http.StatusInsufficientStorage, http.StatusLoopDetected, http.StatusNotExtended, http.StatusNetworkAuthenticationRequired, }
ErrorCodes contains a list of HTTP status codes that are considered errors.
Functions ¶
This section is empty.
Types ¶
type Middleware ¶
Middleware is a function that takes an http.Handler and returns an http.Handler.
type MiddlewareOrder ¶
type MiddlewareOrder int8
MiddlewareOrder defines the order in which middlewares are executed.
const ( // MiddlewareOrderDefault is the default execution order for middlewares. // It is invoked at the same level as the original handler. MiddlewareOrderDefault MiddlewareOrder = 0 // MiddlewareOrderLow represents the lowest execution order. // Middlewares with negative values (-128 to -1) are called before the original handler. MiddlewareOrderLow MiddlewareOrder = -128 // MiddlewareOrderHigh represents the highest execution order. // Middlewares with positive values (1 to 127) are called after the original handler. MiddlewareOrderHigh MiddlewareOrder = 127 // MiddlewareOrderSecurity is a specific order typically used for security-related middlewares. // It is called before the handler. MiddlewareOrderSecurity MiddlewareOrder = -127 // MiddlewareOrderCors is a specific order typically used for CORS-related middlewares. // It is called before the handler. MiddlewareOrderCors MiddlewareOrder = -126 // MiddlewareOrderLog is a specific order typically used for logging middlewares. // It is called after the handler. MiddlewareOrderLog MiddlewareOrder = 126 // MiddlewareOrderGzip is a specific order typically used for gzip compression middlewares. MiddlewareOrderGzip MiddlewareOrder = 127 )
type ResponseWriter ¶
type ResponseWriter struct {
// contains filtered or unexported fields
}
ResponseWriter is a wrapper around http.ResponseWriter that captures the status code
func (*ResponseWriter) Header ¶
func (rw *ResponseWriter) Header() http.Header
Header returns the custom header map
func (*ResponseWriter) Hijack ¶
func (rw *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
Hijack is a wrapper around the http.Hijacker interface
func (*ResponseWriter) History ¶
func (rw *ResponseWriter) History() [][]byte
History returns the history of response bodies written
func (*ResponseWriter) Status ¶
func (rw *ResponseWriter) Status() int
Status returns the status code of the response
func (*ResponseWriter) Write ¶
func (rw *ResponseWriter) Write(b []byte) (int, error)
Write buffers the response body
func (*ResponseWriter) WriteHeader ¶
func (rw *ResponseWriter) WriteHeader(status int)
WriteHeader captures the status code but does not send it immediately It is send when Flush is called
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is a custom HTTP router that supports middlewares and status callbacks It implements the http.Handler interface and allows for flexible request handling
func NewRouter ¶
func NewRouter() *Router
NewRouter creates a new Router instance It initializes the ServeMux and the middlewares map
func (*Router) GetRegisteredRoutes ¶
GetRegisteredRoutes returns a slice of all currently registered route patterns
func (*Router) HandleFunc ¶
func (router *Router) HandleFunc(pattern string, handlerFunc http.HandlerFunc)
HandleFunc registers a handler function for the given pattern
func (*Router) OnStatus ¶
func (router *Router) OnStatus(pattern string, status int, fn func(http.ResponseWriter, *http.Request))
OnStatus registers a callback function for a specific HTTP status code This function will be called after the response is written if the status and pattern match It allows you to handle specific status codes, such as logging or a custom response
func (*Router) ServeHTTP ¶
func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements the http.Handler interface for the Router It wraps the request with middlewares and handles the response
func (*Router) UnregisterAllHandler ¶
func (router *Router) UnregisterAllHandler()
UnregisterAllHandler removes all routes from the router It clears all route-related maps and creates a new empty ServeMux
func (*Router) UnregisterHandler ¶
UnregisterHandler removes routes from the router It removes the route pattern from all relevant internal maps and recreates the ServeMux
type Server ¶
type Server struct {
// Error is the error that occurred during the server's operation
// It will be nil if no error occurred
Error error
// contains filtered or unexported fields
}
Server represents a web server with a set of middlewares and handlers
func (*Server) GetRegisteredRoutes ¶
GetRegisteredRoutes returns a slice of all currently registered route patterns
func (*Server) Restart ¶
Restart gracefully shuts down the web server and starts it again It will wait for all active connections to finish before shutting down
func (*Server) RestartAsync ¶
RestartAsync gracefully shuts down the web server and starts it again asynchronously It will wait for all active connections to finish before shutting down
func (*Server) SetBlacklist ¶
SetBlacklist registers a blacklist for the server Addresses in the blacklist will be blocked from accessing the server This is useful for blocking known malicious IPs or ranges
func (*Server) SetWhitelist ¶
SetWhitelist registers a whitelist for the server Addresses in the whitelist will be ignored by the rate limit and honey pot
func (*Server) Shutdown ¶
Shutdown gracefully shuts down the web server It will wait for all active connections to finish before shutting down Make sure the program doesn't exit and waits instead for Shutdown to return
func (*Server) Start ¶
Start starts the web server All middlewares and handlers that should be registered must be registered before calling this function
func (*Server) StartAsync ¶
StartAsync starts the web server asynchronously It will return immediately and the server will run in the background
func (*Server) Stop ¶
Stop stops the web server Close does not attempt to close any hijacked connections, such as WebSockets.
func (*Server) UnregisterAllHandler ¶
UnregisterAllHandler removes all handlers from the server
func (*Server) UnregisterHandler ¶
UnregisterHandler removes multiple handlers from the server
func (*Server) WithCORSHeaders ¶
WithCORSHeaders adds CORS headers to the server
func (*Server) WithCacheControl ¶
WithCacheControl sets a custom Cache-Control header value that will override the default cache control setting in security headers
func (*Server) WithCanonicalRedirect ¶
WithCanonicalRedirect sets a canonical redirect domain for the server If a request is made to the server with a different domain, it will be redirected to the canonical domain This is useful for SEO purposes and to avoid duplicate content issues
func (*Server) WithCustomErrorLog ¶
WithCustomErrorLog sets the error log for the server
func (*Server) WithCustomMiddleware ¶
func (s *Server) WithCustomMiddleware(middleware Middleware) *Server
WithCustomMiddleware adds a custom middleware to the server
func (*Server) WithCustomMiddlewareOrder ¶
func (s *Server) WithCustomMiddlewareOrder(order MiddlewareOrder, middleware Middleware) *Server
WithCustomMiddlewareOrder adds a custom middleware to the server with a specific order The order is a int8 value that determines the order of the middleware 0 is the original handler, -128 is the beginning of the chain, and 127 is the end of the chain
func (*Server) WithErrorLog ¶
WithErrorLog sets the default error log for the server It will log errors at the Error level using the zerolog logger
func (*Server) WithFS ¶
WithFS serves files from the specified filesystem It will return an error in the Error field if the entrypoint is already registered as a handler or a websocket
func (*Server) WithFileServer ¶
WithFileServer serves files from the specified directory It will fail if the directory does not exist
func (*Server) WithGzipLevel ¶
WithGzipLevel enables gzip compression with a specific level for the server
func (*Server) WithHandler ¶
WithHandler adds a custom handler to the server It will return an error in the Error field if the path is already registered as a handler or a websocket
func (*Server) WithHandlerFunc ¶
func (s *Server) WithHandlerFunc(path string, handler http.HandlerFunc) *Server
WithHandlerFunc adds a custom handler function to the server It will return an error in the Error field if the path is already registered as a handler or a websocket
func (*Server) WithHeader ¶
WithHeader adds a custom header to the server
func (*Server) WithHeaders ¶
WithHeaders adds multiple custom headers to the server
func (*Server) WithHoneypot ¶
WithHoneypot registers a handler for the given pattern Clients that access this pattern will be blocked This is useful for detecting and blocking malicious bots or crawlers
func (*Server) WithIdleTimeout ¶
WithIdleTimeout sets the idle timeout for the server It will be used for all requests and connections
func (*Server) WithOnHTTPCode ¶
func (s *Server) WithOnHTTPCode(code int, pattern []string, handler func(http.ResponseWriter, *http.Request)) *Server
WithOnHTTPCode adds a custom handler for a specific HTTP status code and pattern. It will be called after the request is handled and before the response is sent, and is called with the http.ResponseWriter and the http.Request
func (*Server) WithOnHoneypot ¶
WithOnHoneypot registers a callback function that will be called when a honeypot is triggered The callback will receives the blocklist used. Useful for persisting the blocklist
func (*Server) WithRateLimit ¶
WithRateLimit applies a rate limit to the given pattern The limiter allows `count` events per `period` duration Example: WithRateLimit("/api", 10, time.Minute) allows 10 requests per minute
func (*Server) WithReadHeaderTimeout ¶
WithReadHeaderTimeout sets the read header timeout for the server It will be used for all requests and connections
func (*Server) WithReadTimeout ¶
WithReadTimeout sets the read timeout for the server It will be used for all requests and connections
func (*Server) WithRedirectToHTTPS ¶
WithRedirectToHTTPS sets up a redirect server that redirects HTTP requests to HTTPS It must be called after WithPort and WithTLS or else it will return an error
func (*Server) WithSecurityHeaders ¶
WithSecurityHeaders adds security headers to the server
func (*Server) WithSelfSignedTLS ¶
WithSelfSignedTLS generates a self-signed TLS certificate for the web server It will use the host set by WithHost as the common name for the certificate
func (*Server) WithVaryHeader ¶
WithVaryHeader adds a Vary header to the server The Vary header indicates which request headers a server uses when selecting the representation of a resource This is important for caching behavior and content negotiation
func (*Server) WithVaryHeaders ¶
WithVaryHeaders adds multiple Vary headers to the server The headers will be properly combined with any existing Vary headers
func (*Server) WithWebsocket ¶
func (s *Server) WithWebsocket(path string, handler func(http.ResponseWriter, *http.Request, *websocket.Conn)) *Server
WithWebsocket adds a websocket handler to the server It will return an error in the Error field if the path is already registered as a handler or a websocket The handler function will be called with the http.ResponseWriter, http.Request and *websocket.Conn and will be responsible for handling and closing the connection