2016-03-09 03:49:27 +01:00
|
|
|
package respond
|
|
|
|
|
|
|
|
import (
|
2020-01-07 15:27:08 +01:00
|
|
|
"bytes"
|
|
|
|
"compress/flate"
|
|
|
|
"encoding/json"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2016-03-09 03:49:27 +01:00
|
|
|
"net"
|
2020-01-07 15:27:08 +01:00
|
|
|
|
|
|
|
"github.com/bdlm/log"
|
|
|
|
"github.com/tidwall/gjson"
|
|
|
|
|
|
|
|
"github.com/FreifunkBremen/yanic/data"
|
2016-03-09 03:49:27 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2017-12-05 23:17:49 +01:00
|
|
|
// default multicast group used by announced
|
2020-01-07 15:27:08 +01:00
|
|
|
MulticastAddressDefault = "ff05:0:0:0:0:0:2:1001"
|
2017-12-05 23:17:49 +01:00
|
|
|
|
2016-03-09 03:49:27 +01:00
|
|
|
// default udp port used by announced
|
2020-01-07 15:27:08 +01:00
|
|
|
PortDefault = 1001
|
2016-03-09 03:49:27 +01:00
|
|
|
|
|
|
|
// maximum receivable size
|
2020-01-07 15:27:08 +01:00
|
|
|
MaxDataGramSize = 8192
|
2016-03-09 03:49:27 +01:00
|
|
|
)
|
|
|
|
|
2017-10-18 18:22:14 +02:00
|
|
|
// Response of the respond request
|
2016-03-09 03:49:27 +01:00
|
|
|
type Response struct {
|
2017-10-18 18:22:14 +02:00
|
|
|
Address *net.UDPAddr
|
2016-03-09 03:49:27 +01:00
|
|
|
Raw []byte
|
|
|
|
}
|
2020-01-07 15:27:08 +01:00
|
|
|
|
|
|
|
func NewRespone(res *data.ResponseData, addr *net.UDPAddr) (*Response, error) {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
flater, err := flate.NewWriter(buf, flate.BestCompression)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer flater.Close()
|
|
|
|
|
|
|
|
if err = json.NewEncoder(flater).Encode(res); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = flater.Flush()
|
|
|
|
|
|
|
|
return &Response{
|
|
|
|
Raw: buf.Bytes(),
|
|
|
|
Address: addr,
|
|
|
|
}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (res *Response) parse(customFields []CustomFieldConfig) (*data.ResponseData, error) {
|
|
|
|
// Deflate
|
|
|
|
deflater := flate.NewReader(bytes.NewReader(res.Raw))
|
|
|
|
defer deflater.Close()
|
|
|
|
|
|
|
|
jsonData, err := ioutil.ReadAll(deflater)
|
|
|
|
if err != nil && err != io.ErrUnexpectedEOF {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unmarshal
|
|
|
|
rdata := &data.ResponseData{}
|
|
|
|
err = json.Unmarshal(jsonData, rdata)
|
|
|
|
|
|
|
|
rdata.CustomFields = make(map[string]interface{})
|
|
|
|
if !gjson.Valid(string(jsonData)) {
|
|
|
|
log.WithField("jsonData", jsonData).Info("JSON data is invalid")
|
|
|
|
} else {
|
|
|
|
jsonParsed := gjson.Parse(string(jsonData))
|
|
|
|
for _, customField := range customFields {
|
|
|
|
field := jsonParsed.Get(customField.Path)
|
|
|
|
if field.Exists() {
|
|
|
|
rdata.CustomFields[customField.Name] = field.String()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rdata, err
|
|
|
|
}
|