package router import ( "addrss/pkg/config" "encoding/json" "fmt" "mime/multipart" "net/http" "strconv" "strings" ) type Request struct { *http.Request params map[string]any } func (req Request) Param(key string) (any, error) { value, ok := req.params[key] if ok { return value, nil } return nil, fmt.Errorf("param %s not found", key) } func (req Request) ParamInt64(key string) (int64, error) { param, err := req.Param(key) if err != nil { return 0, err } i, err := strconv.Atoi(param.(string)) if err != nil { return 0, err } return int64(i), nil } // Bind Binds the request body to the struct pointer v using the Content-Type header to select a binder. This function panics if v cannot be bound. func (req Request) Bind(v any) error { mime := req.Header.Get("Content-Type") mime = strings.Split(mime, ";")[0] switch mime { case "application/json": err := json.NewDecoder(req.Body).Decode(&v) if err != nil { return fmt.Errorf("error while decoding http request body as json: %w", err) } default: return fmt.Errorf("no binder exists for type %s", mime) } return nil } func (req Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) { maxMegs, err := config.GetInt64("uploads.maxMegabytes") if err != nil { maxMegs = 8000000 } if err := req.ParseMultipartForm(maxMegs << 20); err != nil { return nil, nil, err } file, header, err := req.Request.FormFile(key) if err != nil { return nil, nil, err } return file, header, nil }