event-gateway/internal/source/http/payload.go

93 lines
2.3 KiB
Go

// Copyright © 2023 Roberto Hidalgo <event-gateway@un.rob.mx>
// 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
}