From df0dd98c727d271a74d2e0d814274188705777da Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Tue, 21 Oct 2025 16:41:49 +0000 Subject: [PATCH] fix(lib): show error message detail when hitting some common flows Instead of giving the user nothing to go off of, this patch gives them an opaque blob of ROT-13 encoded base64. The logic is that if you are smart enough to figure out how to decode this, you're probably smart enough to either fix your broken client or give it to the adminstrator. Signed-off-by: Xe Iaso --- lib/anubis.go | 36 +++---- lib/http.go | 69 ++++++++++-- web/index.go | 4 +- web/index.templ | 5 +- web/index_templ.go | 257 ++++++++++++++++++++++++--------------------- 5 files changed, 220 insertions(+), 151 deletions(-) diff --git a/lib/anubis.go b/lib/anubis.go index 6a44e1fc..da5727cb 100644 --- a/lib/anubis.go +++ b/lib/anubis.go @@ -164,7 +164,7 @@ func (s *Server) maybeReverseProxy(w http.ResponseWriter, r *http.Request, httpS if err != nil { lg.Error("check failed", "err", err) localizer := localization.GetLocalizer(r) - s.respondWithError(w, r, fmt.Sprintf("%s \"maybeReverseProxy\"", localizer.T("internal_server_error"))) + s.respondWithError(w, r, fmt.Sprintf("%s \"maybeReverseProxy\"", localizer.T("internal_server_error")), makeCode(err)) return } @@ -267,13 +267,13 @@ func (s *Server) checkRules(w http.ResponseWriter, r *http.Request, cr policy.Ch lg.Info("explicit deny") if rule == nil { lg.Error("rule is nil, cannot calculate checksum") - s.respondWithError(w, r, fmt.Sprintf("%s \"maybeReverseProxy.RuleDeny\"", localizer.T("internal_server_error"))) + s.respondWithError(w, r, fmt.Sprintf("%s \"maybeReverseProxy.RuleDeny\"", localizer.T("internal_server_error")), makeCode(ErrActualAnubisBug)) return true } hash := rule.Hash() lg.Debug("rule hash", "hash", hash) - s.respondWithStatus(w, r, fmt.Sprintf("%s %s", localizer.T("access_denied"), hash), s.policy.StatusCodes.Deny) + s.respondWithStatus(w, r, fmt.Sprintf("%s %s", localizer.T("access_denied"), hash), "", s.policy.StatusCodes.Deny) return true case config.RuleChallenge: lg.Debug("challenge requested") @@ -284,7 +284,7 @@ func (s *Server) checkRules(w http.ResponseWriter, r *http.Request, cr policy.Ch default: s.ClearCookie(w, CookieOpts{Path: cookiePath, Host: r.Host}) lg.Error("CONFIG ERROR: unknown rule", "rule", cr.Rule) - s.respondWithError(w, r, fmt.Sprintf("%s \"maybeReverseProxy.Rules\"", localizer.T("internal_server_error"))) + s.respondWithError(w, r, fmt.Sprintf("%s \"maybeReverseProxy.Rules\"", localizer.T("internal_server_error")), makeCode(ErrActualAnubisBug)) return true } return false @@ -311,7 +311,7 @@ func (s *Server) handleDNSBL(w http.ResponseWriter, r *http.Request, ip string, localizer.T("dronebl_entry"), resp.String(), localizer.T("see_dronebl_lookup"), - ip), s.policy.StatusCodes.Deny) + ip), "", s.policy.StatusCodes.Deny) return true } } @@ -399,7 +399,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { redirURL, err := url.ParseRequestURI(redir) if err != nil { lg.Error("invalid redirect", "err", err) - s.respondWithStatus(w, r, localizer.T("invalid_redirect"), http.StatusBadRequest) + s.respondWithStatus(w, r, localizer.T("invalid_redirect"), makeCode(err), http.StatusBadRequest) return } @@ -408,7 +408,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { // allowed default: lg.Error("XSS attempt blocked, invalid redirect scheme", "scheme", redirURL.Scheme) - s.respondWithStatus(w, r, localizer.T("invalid_redirect"), http.StatusBadRequest) + s.respondWithStatus(w, r, localizer.T("invalid_redirect"), "", http.StatusBadRequest) return } @@ -422,7 +422,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { s.ClearCookie(w, CookieOpts{Path: cookiePath, Host: r.Host}) s.ClearCookie(w, CookieOpts{Name: anubis.TestCookieName, Host: r.Host}) lg.Warn("user has cookies disabled, this is not an anubis bug") - s.respondWithError(w, r, localizer.T("cookies_disabled")) + s.respondWithError(w, r, localizer.T("cookies_disabled"), "") return } @@ -431,19 +431,19 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { urlParsed, err := r.URL.Parse(redir) if err != nil { - s.respondWithError(w, r, localizer.T("redirect_not_parseable")) + s.respondWithError(w, r, localizer.T("redirect_not_parseable"), makeCode(err)) return } if (len(urlParsed.Host) > 0 && len(s.opts.RedirectDomains) != 0 && !matchRedirectDomain(s.opts.RedirectDomains, urlParsed.Host)) || urlParsed.Host != r.URL.Host { lg.Debug("domain not allowed", "domain", urlParsed.Host) - s.respondWithError(w, r, localizer.T("redirect_domain_not_allowed")) + s.respondWithError(w, r, localizer.T("redirect_domain_not_allowed"), "") return } cr, rule, err := s.check(r, lg) if err != nil { lg.Error("check failed", "err", err) - s.respondWithError(w, r, fmt.Sprintf("%s \"passChallenge\"", localizer.T("internal_server_error"))) + s.respondWithError(w, r, fmt.Sprintf("%s \"passChallenge\"", localizer.T("internal_server_error")), makeCode(err)) return } lg = lg.With("check_result", cr) @@ -451,20 +451,20 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { chall, err := s.getChallenge(r) if err != nil { lg.Error("getChallenge failed", "err", err) - s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm)) + s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm), makeCode(err)) return } if chall.Spent { lg.Error("double spend prevented", "reason", "double_spend") - s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), "double_spend")) + s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), "double_spend"), "") return } impl, ok := challenge.Get(chall.Method) if !ok { lg.Error("check failed", "err", err) - s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm)) + s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm), makeCode(ErrActualAnubisBug)) return } @@ -487,11 +487,11 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { switch { case errors.Is(err, challenge.ErrFailed): lg.Error("challenge failed", "err", err) - s.respondWithStatus(w, r, cerr.PublicReason, cerr.StatusCode) + s.respondWithStatus(w, r, cerr.PublicReason, makeCode(err), cerr.StatusCode) return case errors.Is(err, challenge.ErrInvalidFormat), errors.Is(err, challenge.ErrMissingField): lg.Error("invalid challenge format", "err", err) - s.respondWithError(w, r, cerr.PublicReason) + s.respondWithError(w, r, cerr.PublicReason, makeCode(err)) return } } @@ -511,7 +511,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { if r.Header.Get(s.opts.JWTRestrictionHeader) == "" { lg.Error("JWTRestrictionHeader is set in config but not found in request, please check your reverse proxy config.") s.ClearCookie(w, CookieOpts{Path: cookiePath, Host: r.Host}) - s.respondWithError(w, r, "failed to sign JWT") + s.respondWithError(w, r, "failed to sign JWT", makeCode(err)) return } else { claims["restriction"] = internal.SHA256sum(r.Header.Get(s.opts.JWTRestrictionHeader)) @@ -525,7 +525,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { if err != nil { lg.Error("failed to sign JWT", "err", err) s.ClearCookie(w, CookieOpts{Path: cookiePath, Host: r.Host}) - s.respondWithError(w, r, localizer.T("failed_to_sign_jwt")) + s.respondWithError(w, r, localizer.T("failed_to_sign_jwt"), makeCode(err)) return } diff --git a/lib/http.go b/lib/http.go index 0f63ba74..65f96400 100644 --- a/lib/http.go +++ b/lib/http.go @@ -1,6 +1,9 @@ package lib import ( + "bytes" + "compress/gzip" + "encoding/base64" "errors" "fmt" "math/rand" @@ -25,6 +28,10 @@ import ( var domainMatchRegexp = regexp.MustCompile(`^((xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$`) +var ( + ErrActualAnubisBug = errors.New("this is an actual bug in Anubis, please file an issue with the magic string 'taco bell'") +) + // matchRedirectDomain returns true if host matches any of the allowed redirect // domain patterns. Patterns may contain '*' which are matched using the // internal glob matcher. Matching is case-insensitive on hostnames. @@ -145,6 +152,46 @@ func randomChance(n int) bool { return rand.Intn(n) == 0 } +// XXX(Xe): generated by ChatGPT +func rot13(s string) string { + rotated := make([]rune, len(s)) + for i, c := range s { + switch { + case c >= 'A' && c <= 'Z': + rotated[i] = 'A' + ((c - 'A' + 13) % 26) + case c >= 'a' && c <= 'z': + rotated[i] = 'a' + ((c - 'a' + 13) % 26) + default: + rotated[i] = c + } + } + return string(rotated) +} + +func makeCode(err error) string { + var buf bytes.Buffer + gzw := gzip.NewWriter(&buf) + errStr := fmt.Sprintf("internal error: %v", err) + + fmt.Fprintln(gzw, rot13(errStr)) + if err := gzw.Close(); err != nil { + panic("can't write to gzip in ram buffer") + } + const width = 16 + + enc := base64.StdEncoding.EncodeToString(buf.Bytes()) + var builder strings.Builder + for i := 0; i < len(enc); i += width { + end := i + width + if end > len(enc) { + end = len(enc) + } + builder.WriteString(enc[i:end]) + builder.WriteByte('\n') + } + return builder.String() +} + func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.CheckResult, rule *policy.Bot, returnHTTPStatusOnly bool) { localizer := localization.GetLocalizer(r) @@ -155,7 +202,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.C } else { redirectURL, err := s.constructRedirectURL(r) if err != nil { - s.respondWithStatus(w, r, err.Error(), http.StatusBadRequest) + s.respondWithStatus(w, r, err.Error(), "", http.StatusBadRequest) return } http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect) @@ -167,7 +214,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.C if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") && randomChance(64) { lg.Error("client was given a challenge but does not in fact support gzip compression") - s.respondWithError(w, r, localizer.T("client_error_browser")) + s.respondWithError(w, r, localizer.T("client_error_browser"), "") return } @@ -176,7 +223,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.C if err != nil { lg.Error("can't get challenge", "err", err) s.ClearCookie(w, CookieOpts{Name: anubis.TestCookieName, Host: r.Host}) - s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm)) + s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm), makeCode(err)) return } @@ -203,7 +250,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.C if !ok { lg.Error("check failed", "err", "can't get algorithm", "algorithm", rule.Challenge.Algorithm) s.ClearCookie(w, CookieOpts{Name: anubis.TestCookieName, Host: r.Host}) - s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm)) + s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm), makeCode(err)) return } @@ -218,7 +265,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.C component, err := impl.Issue(w, r, lg, in) if err != nil { lg.Error("[unexpected] challenge component render failed, please open an issue", "err", err) // This is likely a bug in the template. Should never be triggered as CI tests for this. - s.respondWithError(w, r, fmt.Sprintf("%s \"RenderIndex\"", localizer.T("internal_server_error"))) + s.respondWithError(w, r, fmt.Sprintf("%s \"RenderIndex\"", localizer.T("internal_server_error")), makeCode(err)) return } @@ -269,14 +316,14 @@ func (s *Server) RenderBench(w http.ResponseWriter, r *http.Request) { ).ServeHTTP(w, r) } -func (s *Server) respondWithError(w http.ResponseWriter, r *http.Request, message string) { - s.respondWithStatus(w, r, message, http.StatusInternalServerError) +func (s *Server) respondWithError(w http.ResponseWriter, r *http.Request, message, code string) { + s.respondWithStatus(w, r, message, code, http.StatusInternalServerError) } -func (s *Server) respondWithStatus(w http.ResponseWriter, r *http.Request, msg string, status int) { +func (s *Server) respondWithStatus(w http.ResponseWriter, r *http.Request, msg, code string, status int) { localizer := localization.GetLocalizer(r) - templ.Handler(web.Base(localizer.T("oh_noes"), web.ErrorPage(msg, s.opts.WebmasterEmail, localizer), s.policy.Impressum, localizer), templ.WithStatus(status)).ServeHTTP(w, r) + templ.Handler(web.Base(localizer.T("oh_noes"), web.ErrorPage(msg, s.opts.WebmasterEmail, code, localizer), s.policy.Impressum, localizer), templ.WithStatus(status)).ServeHTTP(w, r) } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -324,7 +371,7 @@ func (s *Server) ServeHTTPNext(w http.ResponseWriter, r *http.Request) { redir := r.FormValue("redir") urlParsed, err := r.URL.Parse(redir) if err != nil { - s.respondWithStatus(w, r, localizer.T("redirect_not_parseable"), http.StatusBadRequest) + s.respondWithStatus(w, r, localizer.T("redirect_not_parseable"), makeCode(err), http.StatusBadRequest) return } @@ -336,7 +383,7 @@ func (s *Server) ServeHTTPNext(w http.ResponseWriter, r *http.Request) { if hostNotAllowed || hostMismatch { lg := internal.GetRequestLogger(s.logger, r) lg.Debug("domain not allowed", "domain", urlParsed.Host) - s.respondWithStatus(w, r, localizer.T("redirect_domain_not_allowed"), http.StatusBadRequest) + s.respondWithStatus(w, r, localizer.T("redirect_domain_not_allowed"), makeCode(err), http.StatusBadRequest) return } diff --git a/web/index.go b/web/index.go index c3ba03d0..7b171ea1 100644 --- a/web/index.go +++ b/web/index.go @@ -22,8 +22,8 @@ func BaseWithChallengeAndOGTags(title string, body templ.Component, impressum *c }, ogTags, localizer) } -func ErrorPage(msg, mail string, localizer *localization.SimpleLocalizer) templ.Component { - return errorPage(msg, mail, localizer) +func ErrorPage(msg, mail, code string, localizer *localization.SimpleLocalizer) templ.Component { + return errorPage(msg, mail, code, localizer) } func Bench(localizer *localization.SimpleLocalizer) templ.Component { diff --git a/web/index.templ b/web/index.templ index 54b368cc..8e34ea4b 100644 --- a/web/index.templ +++ b/web/index.templ @@ -88,10 +88,13 @@ templ base(title string, body templ.Component, impressum *config.Impressum, chal } -templ errorPage(message, mail string, localizer *localization.SimpleLocalizer) { +templ errorPage(message, mail, code string, localizer *localization.SimpleLocalizer) {
Sad Anubis
{ code }
+ } if mail != "" {

{ localizer.T("go_home") } { localizer.T("contact_webmaster") } diff --git a/web/index_templ.go b/web/index_templ.go index 13f17e42..b672b301 100644 --- a/web/index_templ.go +++ b/web/index_templ.go @@ -283,7 +283,7 @@ func base(title string, body templ.Component, impressum *config.Impressum, chall }) } -func errorPage(message, mail string, localizer *localization.SimpleLocalizer) templ.Component { +func errorPage(message, mail, code string, localizer *localization.SimpleLocalizer) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -334,72 +334,73 @@ func errorPage(message, mail string, localizer *localization.SimpleLocalizer) te if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if mail != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "

") + if code != "" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "

")
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}
 			var templ_7745c5c3_Var19 string
-			templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("go_home"))
+			templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(code)
 			if templ_7745c5c3_Err != nil {
-				return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 97, Col: 40}
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 96, Col: 20}
 			}
 			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}
-			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, " ")
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if mail != "" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("contact_webmaster")) + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("go_home")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 97, Col: 81} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 100, Col: 40} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var21 templ.SafeURL - templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinURLErrs("mailto:" + templ.SafeURL(mail)) + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("contact_webmaster")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 98, Col: 45} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 100, Col: 81} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var23 string - templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("go_home")) + templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(mail) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 103, Col: 42} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 102, Col: 11} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) if templ_7745c5c3_Err != nil { @@ -409,8 +410,26 @@ func errorPage(message, mail string, localizer *localization.SimpleLocalizer) te if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var24 string + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("go_home")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 106, Col: 42} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -434,39 +453,39 @@ func StaticHappy(localizer *localization.SimpleLocalizer) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var24 := templ.GetChildren(ctx) - if templ_7745c5c3_Var24 == nil { - templ_7745c5c3_Var24 = templ.NopComponent + templ_7745c5c3_Var25 := templ.GetChildren(ctx) + if templ_7745c5c3_Var25 == nil { + templ_7745c5c3_Var25 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\">

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var27 string + templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("static_check_endpoint")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 119, Col: 43} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -490,181 +509,181 @@ func bench(localizer *localization.SimpleLocalizer) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var27 := templ.GetChildren(ctx) - if templ_7745c5c3_Var27 == nil { - templ_7745c5c3_Var27 = templ.NopComponent + templ_7745c5c3_Var28 := templ.GetChildren(ctx) + if templ_7745c5c3_Var28 == nil { + templ_7745c5c3_Var28 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var28 string - templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 127, Col: 51} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var29 string - templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters")) + templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 128, Col: 50} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 130, Col: 51} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var30 string - templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time_a")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 131, Col: 53} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var31 string - templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters_a")) + var templ_7745c5c3_Var30 string + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 132, Col: 52} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 131, Col: 50} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var31 string + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time_a")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 134, Col: 53} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var32 string - templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time_b")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 133, Col: 53} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var33 string - templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters_b")) + var templ_7745c5c3_Var32 string + templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters_a")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 134, Col: 52} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 135, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var33 string + templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time_b")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 136, Col: 53} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var34 string - templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version) + templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters_b")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 143, Col: 166} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 137, Col: 52} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "\">

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err }