77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
package httpapp
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"gitea.avt.data-center.id/othman.suseno/atlas/internal/errors"
|
|
)
|
|
|
|
// httpsEnforcementMiddleware enforces HTTPS connections
|
|
func (a *App) httpsEnforcementMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Skip HTTPS enforcement for health checks and localhost
|
|
if a.isPublicEndpoint(r.URL.Path, r.Method) || isLocalhost(r) {
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// If TLS is enabled, enforce HTTPS
|
|
if a.tlsConfig != nil && a.tlsConfig.Enabled {
|
|
// Check if request is already over HTTPS
|
|
if r.TLS != nil {
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// Check X-Forwarded-Proto header (for reverse proxies)
|
|
if r.Header.Get("X-Forwarded-Proto") == "https" {
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// Redirect HTTP to HTTPS
|
|
httpsURL := "https://" + r.Host + r.URL.RequestURI()
|
|
http.Redirect(w, r, httpsURL, http.StatusMovedPermanently)
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// isLocalhost checks if the request is from localhost
|
|
func isLocalhost(r *http.Request) bool {
|
|
host := r.Host
|
|
if strings.Contains(host, ":") {
|
|
host = strings.Split(host, ":")[0]
|
|
}
|
|
return host == "localhost" || host == "127.0.0.1" || host == "::1"
|
|
}
|
|
|
|
// requireHTTPSMiddleware requires HTTPS for all requests (strict mode)
|
|
func (a *App) requireHTTPSMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Skip for health checks
|
|
if a.isPublicEndpoint(r.URL.Path, r.Method) {
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// If TLS is enabled, require HTTPS
|
|
if a.tlsConfig != nil && a.tlsConfig.Enabled {
|
|
// Check if request is over HTTPS
|
|
if r.TLS == nil && r.Header.Get("X-Forwarded-Proto") != "https" {
|
|
writeError(w, errors.NewAPIError(
|
|
errors.ErrCodeForbidden,
|
|
"HTTPS required",
|
|
http.StatusForbidden,
|
|
).WithDetails("this endpoint requires HTTPS"))
|
|
return
|
|
}
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|