93 lines
2.3 KiB
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
|
|
}
|