All checks were successful
check / check (push) Successful in 2m3s
Replace .golangci.yml with the canonical v2-schema config (default: all minus six disabled linters, lll 88, tests included) and bump every golangci-lint pin to v2.12.2: - Dockerfile: golangci/golangci-lint:v2.12.2-alpine (hash-pinned) - script/bootstrap: GOLANGCI_LINT_VERSION 2.12.2 with new linux-amd64/arm64 release-archive sha256 pins Fix all 747 findings the stricter config surfaces, with no behavior changes: t.Parallel() throughout the test suite, static sentinel errors and errors.Is comparisons, checked error returns, context propagation (contextcheck/noctx), 88-column wrapping, extracted constants and helpers for goconst/dupl/funlen/cyclop, exhaustive switch cases replicating existing defaults, and white-box test files renamed to *_internal_test.go for testpackage. Three nolint:tagliatelle directives preserve the existing snake_case JSON wire and on-disk metadata formats.
71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
sentryhttp "github.com/getsentry/sentry-go/http"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
|
|
"sneak.berlin/go/pixa/internal/static"
|
|
)
|
|
|
|
// SetupRoutes configures all HTTP routes.
|
|
func (s *Server) SetupRoutes() {
|
|
s.router = chi.NewRouter()
|
|
|
|
s.router.Use(middleware.Recoverer)
|
|
s.router.Use(middleware.RequestID)
|
|
s.router.Use(s.mw.SecurityHeaders())
|
|
s.router.Use(s.mw.Logging())
|
|
|
|
// Add metrics middleware only if credentials are configured
|
|
if s.config.MetricsUsername != "" {
|
|
s.router.Use(s.mw.Metrics())
|
|
}
|
|
|
|
s.router.Use(s.mw.CORS())
|
|
s.router.Use(middleware.Timeout(HTTPWriteTimeout))
|
|
|
|
if s.sentryEnabled {
|
|
sentryHandler := sentryhttp.New(sentryhttp.Options{
|
|
Repanic: true,
|
|
})
|
|
s.router.Use(sentryHandler.Handle)
|
|
}
|
|
|
|
// Health check endpoint
|
|
s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck())
|
|
|
|
// Robots.txt
|
|
s.router.Get("/robots.txt", s.h.HandleRobotsTxt())
|
|
|
|
// Static files (Tailwind CSS, etc.)
|
|
s.router.Handle("/static/*", http.StripPrefix("/static/", static.Handler()))
|
|
|
|
// Login/generator UI
|
|
s.router.Get("/", s.h.HandleRoot())
|
|
s.router.Post("/", s.h.HandleRoot())
|
|
s.router.Get("/logout", s.h.HandleLogout())
|
|
s.router.Post("/generate", s.h.HandleGenerateURL())
|
|
|
|
// Main image proxy route
|
|
// /v1/image/<host>/<path>/<width>x<height>.<format>
|
|
s.router.Get("/v1/image/*", s.h.HandleImage())
|
|
s.router.Head("/v1/image/*", s.h.HandleImage())
|
|
|
|
// Encrypted image URL route
|
|
// The trailing filename (e.g., /img.jpg) is ignored but helps
|
|
// browsers with content type
|
|
s.router.Get("/v1/e/{token}/*", s.h.HandleImageEnc())
|
|
|
|
// Metrics endpoint with auth
|
|
if s.config.MetricsUsername != "" {
|
|
s.router.Group(func(r chi.Router) {
|
|
r.Use(s.mw.MetricsAuth())
|
|
r.Get("/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP))
|
|
})
|
|
}
|
|
}
|