Files
hsp.go/hsp/request.go

124 lines
2.4 KiB
Go

package hsp
import (
"encoding/json"
"errors"
"fmt"
"net"
"slices"
"strconv"
"strings"
)
type Request struct {
conn net.Conn
packet *Packet
}
func NewRequest(conn net.Conn, packet *Packet) *Request {
return &Request{
conn, packet,
}
}
func (req *Request) Conn() net.Conn {
return req.conn
}
func (req *Request) GetHeader(key string) (string, bool) {
value, ok := req.packet.Headers[key]
return value, ok
}
func (req *Request) GetRawPacket() *Packet {
return req.packet
}
func (req *Request) GetDataFormat() (*DataFormat, error) {
// TODO: use predefined header names
format, ok := req.packet.Headers["data-format"]
if !ok {
return nil, errors.New("Data format header is not provided in request")
}
return ParseDataFormat(format)
}
func (req *Request) GetRequestKind() string {
_, ok := req.GetHeader(H_XSTREAM)
if ok {
return "stream"
}
return "single-hit"
}
func (req *Request) GetStreamInfo() (*StreamInfo, error) {
stream, ok := req.GetHeader(H_XSTREAM)
if !ok {
return nil, errors.New("No X-STREAM header presented in request")
}
parts := strings.Split(stream, ":")
if len(parts) != 2 {
return nil, fmt.Errorf("Invalid value of X-STREAM header: '%s'", stream)
}
totalS, bufsizeS := parts[0], parts[1]
total, err := strconv.ParseUint(totalS, 10, 64)
if err != nil {
return nil, err
}
bufsize, err := strconv.ParseUint(bufsizeS, 10, 16)
if err != nil {
return nil, err
}
buf := uint16(bufsize)
return &StreamInfo{
TotalBytes: total,
BufferSize: buf,
}, nil
}
func (req *Request) ExtractText() (string, error) {
df, err := req.GetDataFormat()
if err != nil {
return "", err
}
if !slices.Contains([]string{DF_TEXT, DF_JSON}, df.Format) {
return "", errors.New(fmt.Sprintf("Data format '%s' cannot be extracted as text", df.Format))
}
return string(req.packet.Payload), nil
}
func (req *Request) ExtractJson(out any) error {
df, err := req.GetDataFormat()
if err != nil {
return err
}
if !slices.Contains([]string{DF_JSON}, df.Format) {
return errors.New(fmt.Sprintf("Data format '%s' cannot be extracted as json", df.Format))
}
return json.Unmarshal(req.packet.Payload, out)
}
func (req *Request) ExtractBytes() ([]byte, error) {
df, err := req.GetDataFormat()
if err != nil {
return nil, err
}
if df.Format != "bytes" {
return nil, errors.New(fmt.Sprintf("Data format '%s' is invalid for extracting bytes", df.Format))
}
return req.packet.Payload, nil
}