package router import ( "addrss/pkg/config" "encoding/json" "fmt" "mime/multipart" "net/http" "net/url" "strings" ) type Request struct { *http.Request params map[string]any } func (req Request) Param(key string) (any, error) { if value, ok := req.params[key]; ok { return value, nil } return nil, fmt.Errorf("param %s not found", key) } func (req Request) Query(key string) (any, error) { values, err := url.ParseQuery(req.Request.URL.RawQuery) if err != nil { return nil, err } value, ok := values[key] if !ok { return nil, fmt.Errorf("query string parameter %s not found", key) } if len(value) > 1 { return value, nil } return value[0], nil } // Bind Binds the request body to the struct pointer v using the Content-Type header to select a binder. func (req Request) Bind(v any) error { body, err := req.Request.GetBody() if err != nil { return err } mime := req.Header.Get("Content-Type") mime = strings.Split(mime, ";")[0] switch mime { case "application/json": err := json.NewDecoder(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) File(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 }