chore: update golangci-lint to v2.12.2 with canonical config
All checks were successful
check / check (push) Successful in 2m3s
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.
This commit is contained in:
@@ -35,7 +35,8 @@ func (s *Handlers) HandleRoot() http.HandlerFunc {
|
||||
|
||||
// handleLoginPost handles login form submission.
|
||||
func (s *Handlers) handleLoginPost(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
s.renderLogin(w, "Invalid form data")
|
||||
|
||||
return
|
||||
@@ -52,7 +53,8 @@ func (s *Handlers) handleLoginPost(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Create session
|
||||
if err := s.sessMgr.CreateSession(w); err != nil {
|
||||
err = s.sessMgr.CreateSession(w)
|
||||
if err != nil {
|
||||
s.log.Error("failed to create session", "error", err)
|
||||
s.renderLogin(w, "Failed to create session")
|
||||
|
||||
@@ -83,20 +85,14 @@ func (s *Handlers) HandleGenerateURL() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
s.renderGenerator(w, &generatorData{Error: "Invalid form data"})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Parse form values
|
||||
sourceURL := r.FormValue("url")
|
||||
widthStr := r.FormValue("width")
|
||||
heightStr := r.FormValue("height")
|
||||
format := r.FormValue("format")
|
||||
qualityStr := r.FormValue("quality")
|
||||
fit := r.FormValue("fit")
|
||||
ttlStr := r.FormValue("ttl")
|
||||
|
||||
// Validate source URL
|
||||
parsed, err := url.Parse(sourceURL)
|
||||
@@ -106,38 +102,7 @@ func (s *Handlers) HandleGenerateURL() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
// Parse dimensions
|
||||
width, _ := strconv.Atoi(widthStr)
|
||||
height, _ := strconv.Atoi(heightStr)
|
||||
quality, _ := strconv.Atoi(qualityStr)
|
||||
ttl, _ := strconv.Atoi(ttlStr)
|
||||
|
||||
if quality <= 0 {
|
||||
quality = 85
|
||||
}
|
||||
|
||||
// Create payload
|
||||
// ttl=0 means never expires
|
||||
var expiresAt time.Time
|
||||
var expiresAtUnix int64
|
||||
|
||||
if ttl > 0 {
|
||||
expiresAt = time.Now().Add(time.Duration(ttl) * time.Second)
|
||||
expiresAtUnix = expiresAt.Unix()
|
||||
}
|
||||
// else expiresAtUnix stays 0 (never expires)
|
||||
|
||||
payload := &encurl.Payload{
|
||||
SourceHost: parsed.Host,
|
||||
SourcePath: parsed.Path,
|
||||
SourceQuery: parsed.RawQuery,
|
||||
Width: width,
|
||||
Height: height,
|
||||
Format: imgcache.ImageFormat(format),
|
||||
Quality: quality,
|
||||
FitMode: imgcache.FitMode(fit),
|
||||
ExpiresAt: expiresAtUnix,
|
||||
}
|
||||
payload, expiresAt, ttl := buildGeneratePayload(parsed, r.Form)
|
||||
|
||||
// Generate encrypted token
|
||||
token, err := s.encGen.Generate(payload)
|
||||
@@ -148,20 +113,7 @@ func (s *Handlers) HandleGenerateURL() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
// Build full URL (URL-encode the token for safety)
|
||||
scheme := "https"
|
||||
if s.config.Debug {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
// Determine file extension for the trailing filename
|
||||
ext := format
|
||||
if ext == "" || ext == "orig" {
|
||||
ext = "jpg" // Default extension
|
||||
}
|
||||
|
||||
host := r.Host
|
||||
generatedURL := scheme + "://" + host + "/v1/e/" + url.PathEscape(token) + "/img." + ext
|
||||
generatedURL := s.buildGeneratedURL(r, token, r.FormValue("format"))
|
||||
|
||||
// Format expiry for display
|
||||
expiresAtStr := "Never"
|
||||
@@ -173,16 +125,55 @@ func (s *Handlers) HandleGenerateURL() http.HandlerFunc {
|
||||
GeneratedURL: generatedURL,
|
||||
ExpiresAt: expiresAtStr,
|
||||
FormURL: sourceURL,
|
||||
FormWidth: widthStr,
|
||||
FormHeight: heightStr,
|
||||
FormFormat: format,
|
||||
FormQuality: qualityStr,
|
||||
FormFit: fit,
|
||||
FormTTL: ttlStr,
|
||||
FormWidth: r.FormValue("width"),
|
||||
FormHeight: r.FormValue("height"),
|
||||
FormFormat: r.FormValue("format"),
|
||||
FormQuality: r.FormValue("quality"),
|
||||
FormFit: r.FormValue("fit"),
|
||||
FormTTL: r.FormValue("ttl"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// buildGeneratePayload parses the numeric form fields and assembles the
|
||||
// encrypted URL payload. ttl=0 means never expires (ExpiresAt stays 0).
|
||||
func buildGeneratePayload(
|
||||
parsed *url.URL, form url.Values,
|
||||
) (*encurl.Payload, time.Time, int) {
|
||||
width, _ := strconv.Atoi(form.Get("width"))
|
||||
height, _ := strconv.Atoi(form.Get("height"))
|
||||
quality, _ := strconv.Atoi(form.Get("quality"))
|
||||
ttl, _ := strconv.Atoi(form.Get("ttl"))
|
||||
|
||||
if quality <= 0 {
|
||||
quality = 85
|
||||
}
|
||||
|
||||
var (
|
||||
expiresAt time.Time
|
||||
expiresAtUnix int64
|
||||
)
|
||||
|
||||
if ttl > 0 {
|
||||
expiresAt = time.Now().Add(time.Duration(ttl) * time.Second)
|
||||
expiresAtUnix = expiresAt.Unix()
|
||||
}
|
||||
|
||||
payload := &encurl.Payload{
|
||||
SourceHost: parsed.Host,
|
||||
SourcePath: parsed.Path,
|
||||
SourceQuery: parsed.RawQuery,
|
||||
Width: width,
|
||||
Height: height,
|
||||
Format: imgcache.ImageFormat(form.Get("format")),
|
||||
Quality: quality,
|
||||
FitMode: imgcache.FitMode(form.Get("fit")),
|
||||
ExpiresAt: expiresAtUnix,
|
||||
}
|
||||
|
||||
return payload, expiresAt, ttl
|
||||
}
|
||||
|
||||
// generatorData holds template data for the generator page.
|
||||
type generatorData struct {
|
||||
GeneratedURL string
|
||||
@@ -206,7 +197,8 @@ func (s *Handlers) renderLogin(w http.ResponseWriter, errorMsg string) {
|
||||
Error: errorMsg,
|
||||
}
|
||||
|
||||
if err := templates.Render(w, "login.html", data); err != nil {
|
||||
err := templates.Render(w, "login.html", data)
|
||||
if err != nil {
|
||||
s.log.Error("failed to render login template", "error", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
@@ -219,13 +211,16 @@ func (s *Handlers) renderGenerator(w http.ResponseWriter, data *generatorData) {
|
||||
data = &generatorData{}
|
||||
}
|
||||
|
||||
if err := templates.Render(w, "generator.html", data); err != nil {
|
||||
err := templates.Render(w, "generator.html", data)
|
||||
if err != nil {
|
||||
s.log.Error("failed to render generator template", "error", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Handlers) renderGeneratorWithForm(w http.ResponseWriter, errorMsg string, form url.Values) {
|
||||
func (s *Handlers) renderGeneratorWithForm(
|
||||
w http.ResponseWriter, errorMsg string, form url.Values,
|
||||
) {
|
||||
s.renderGenerator(w, &generatorData{
|
||||
Error: errorMsg,
|
||||
FormURL: form.Get("url"),
|
||||
@@ -237,3 +232,19 @@ func (s *Handlers) renderGeneratorWithForm(w http.ResponseWriter, errorMsg strin
|
||||
FormTTL: form.Get("ttl"),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Handlers) buildGeneratedURL(r *http.Request, token, format string) string {
|
||||
// Build full URL (URL-encode the token for safety)
|
||||
scheme := "https"
|
||||
if s.config.Debug {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
// Determine file extension for the trailing filename
|
||||
ext := format
|
||||
if ext == "" || ext == "orig" {
|
||||
ext = "jpg" // Default extension
|
||||
}
|
||||
|
||||
return scheme + "://" + r.Host + "/v1/e/" + url.PathEscape(token) + "/img." + ext
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user