package httpserver import ( "errors" "fmt" "net/http" "strconv" "strings" "github.com/go-chi/chi/v5" authservice "update_server/internal/auth" "update_server/internal/db" "update_server/internal/slug" ) func (h *handler) basePageData(r *http.Request, title, eyebrow, heading, description string) PageData { return PageData{ Title: title, Eyebrow: eyebrow, Heading: heading, Description: description, BaseURL: strings.TrimRight(h.config.BaseURL, "/"), CSRFToken: h.csrfToken(r), CurrentUser: h.currentUser(r), } } func (h *handler) currentUser(r *http.Request) *db.User { sessionState, ok := authservice.FromContext(r.Context()) if !ok { return nil } user := sessionState.User return &user } func (h *handler) currentUserID(r *http.Request) *int64 { user := h.currentUser(r) if user == nil { return nil } return &user.ID } func routeID(r *http.Request, key string) (int64, error) { raw := strings.TrimSpace(chi.URLParam(r, key)) if raw == "" { return 0, fmt.Errorf("%s is required", key) } value, err := strconv.ParseInt(raw, 10, 64) if err != nil || value <= 0 { return 0, fmt.Errorf("invalid %s", key) } return value, nil } func projectFormInput(name, slugValue, description string) (db.CreateProjectParams, string) { name = strings.TrimSpace(name) slugValue = slug.Make(firstNonEmpty(slugValue, name)) description = strings.TrimSpace(description) switch { case name == "": return db.CreateProjectParams{}, "Project name is required." case slugValue == "": return db.CreateProjectParams{}, "Project slug is required." default: return db.CreateProjectParams{ Name: name, Slug: slugValue, Description: description, }, "" } } func tagFormInput(name, slugValue, description string) (db.CreateTagParams, string) { name = strings.TrimSpace(name) slugValue = slug.Make(firstNonEmpty(slugValue, name)) description = strings.TrimSpace(description) switch { case name == "": return db.CreateTagParams{}, "Tag name is required." case slugValue == "": return db.CreateTagParams{}, "Tag slug is required." default: return db.CreateTagParams{ Name: name, Slug: slugValue, Description: description, }, "" } } func firstNonEmpty(values ...string) string { for _, value := range values { if trimmed := strings.TrimSpace(value); trimmed != "" { return trimmed } } return "" } func maxUploadMegabytes(bytes int64) int64 { if bytes <= 0 { return 0 } const mebibyte = 1024 * 1024 value := bytes / mebibyte if bytes%mebibyte != 0 { value++ } if value == 0 { value = 1 } return value } func maxUploadRequestLimit(fileLimit int64) int64 { const multipartOverhead = 1 << 20 return fileLimit + multipartOverhead } func isMaxBytesError(err error) bool { var maxErr *http.MaxBytesError return errors.As(err, &maxErr) }