12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- package internal
- import (
- "log/slog"
- "net"
- "net/http"
- "strings"
- "github.com/TecharoHQ/anubis"
- "github.com/sebest/xff"
- )
- // UnchangingCache sets the Cache-Control header to cache a response for 1 year if
- // and only if the application is compiled in "release" mode by Docker.
- func UnchangingCache(next http.Handler) http.Handler {
- //goland:noinspection GoBoolExpressions
- if anubis.Version == "devel" {
- return next
- }
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Cache-Control", "public, max-age=31536000")
- next.ServeHTTP(w, r)
- })
- }
- // RemoteXRealIP sets the X-Real-Ip header to the request's real IP if
- // the setting is enabled by the user.
- func RemoteXRealIP(useRemoteAddress bool, bindNetwork string, next http.Handler) http.Handler {
- if !useRemoteAddress {
- slog.Debug("skipping middleware, useRemoteAddress is empty")
- return next
- }
- if bindNetwork == "unix" {
- // For local sockets there is no real remote address but the localhost
- // address should be sensible.
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- r.Header.Set("X-Real-Ip", "127.0.0.1")
- next.ServeHTTP(w, r)
- })
- }
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- host, _, err := net.SplitHostPort(r.RemoteAddr)
- if err != nil {
- panic(err) // this should never happen
- }
- r.Header.Set("X-Real-Ip", host)
- next.ServeHTTP(w, r)
- })
- }
- // XForwardedForToXRealIP sets the X-Real-Ip header based on the contents
- // of the X-Forwarded-For header.
- func XForwardedForToXRealIP(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if xffHeader := r.Header.Get("X-Forwarded-For"); r.Header.Get("X-Real-Ip") == "" && xffHeader != "" {
- ip := xff.Parse(xffHeader)
- slog.Debug("setting x-real-ip", "val", ip)
- r.Header.Set("X-Real-Ip", ip)
- }
- next.ServeHTTP(w, r)
- })
- }
- // NoStoreCache sets the Cache-Control header to no-store for the response.
- func NoStoreCache(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Cache-Control", "no-store")
- next.ServeHTTP(w, r)
- })
- }
- // NoBrowsing prevents directory browsing by returning a 404 for any request that ends with a "/".
- func NoBrowsing(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if strings.HasSuffix(r.URL.Path, "/") {
- http.NotFound(w, r)
- return
- }
- next.ServeHTTP(w, r)
- })
- }
|