85 lines
1.6 KiB
Go
85 lines
1.6 KiB
Go
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
|
|
}
|