// Copyright © 2023 Roberto Hidalgo // SPDX-License-Identifier: Apache-2.0 package http import ( "encoding/json" "fmt" "io" "net/http" "strings" "git.rob.mx/nidito/event-gateway/internal/payload" ) type Payload struct { Req *http.Request resolved *payload.Payload } func (p *Payload) Parse() (*payload.Payload, error) { if p.resolved == nil { contentType := p.Req.Header.Get("Content-Type") if contentType == "" { contentType = "text/plain" } else { contentType = strings.SplitN(contentType, ";", 2)[0] } p.resolved = &payload.Payload{} switch contentType { case "text/plain": body, err := io.ReadAll(p.Req.Body) if err != nil { return p.resolved, fmt.Errorf("could not decode text/plain payload: %s", err) } if len(body) == 0 { return nil, nil } p.resolved.Kind = "text" p.resolved.Value = string(body) case "application/json": body, err := io.ReadAll(p.Req.Body) if err != nil { return p.resolved, fmt.Errorf("could not read json body: %s", err) } var data any if err := json.Unmarshal(body, &data); err != nil { return p.resolved, fmt.Errorf("could not decode json payload: %s", err) } p.resolved.Kind = "json" p.resolved.Value = data case "application/x-www-form-urlencoded": if err := p.Req.ParseForm(); err != nil { return p.resolved, fmt.Errorf("could not decode %s payload: %s", contentType, err) } log.Debugf("parsed form: %+v", p.Req.Form) form := map[string]any{} for key, values := range p.Req.PostForm { log.Debugf("parsing form: %s", key) if len(values) > 1 { form[key] = values } else { form[key] = p.Req.FormValue(key) } } p.resolved.Kind = "form" p.resolved.Value = form case "multipart/form-data": if err := p.Req.ParseMultipartForm(100); err != nil { if body, err := io.ReadAll(p.Req.Body); err == nil { log.Errorf("request %s body: %s", p.Req.Header["Content-Type"], body) } return p.resolved, fmt.Errorf("could not decode %s payload: %s", contentType, err) } form := map[string]any{} for key, values := range p.Req.MultipartForm.Value { if len(values) > 1 { form[key] = values } else { form[key] = p.Req.FormValue(key) } } p.resolved.Kind = "form" p.resolved.Value = form } } return p.resolved, nil }