fmt: whole hsp package

This commit is contained in:
2025-04-19 12:38:40 +02:00
parent 58ea1ad890
commit b26eef4307
6 changed files with 63 additions and 44 deletions

View File

@ -6,13 +6,13 @@ import (
) )
type Adddress struct { type Adddress struct {
Host string Host string
Route string Route string
} }
func ParseAddress(address string) (*Adddress, error) { func ParseAddress(address string) (*Adddress, error) {
parts := strings.SplitN(address, "/", 2) parts := strings.SplitN(address, "/", 2)
var route string var route string
if len(parts) == 1 { if len(parts) == 1 {
route = "/" route = "/"
@ -25,7 +25,7 @@ func ParseAddress(address string) (*Adddress, error) {
addr := parts[0] addr := parts[0]
return &Adddress{ return &Adddress{
Host: addr, Host: addr,
Route: route, Route: route,
}, nil }, nil
} }
@ -33,4 +33,3 @@ func ParseAddress(address string) (*Adddress, error) {
func (a *Adddress) String() string { func (a *Adddress) String() string {
return fmt.Sprintf("%s:%s", a.Host, HSP_PORT) return fmt.Sprintf("%s:%s", a.Host, HSP_PORT)
} }

View File

@ -10,15 +10,15 @@ import (
const HSP_PORT = "998" const HSP_PORT = "998"
const ( const (
H_STATUS = "status" H_STATUS = "status"
H_DATA_FORMAT = "data-format" H_DATA_FORMAT = "data-format"
H_ROUTE = "route" H_ROUTE = "route"
) )
const ( const (
DF_BYTES = "bytes" DF_BYTES = "bytes"
DF_TEXT = "text" DF_TEXT = "text"
DF_JSON = "json" DF_JSON = "json"
) )
const ( const (
@ -26,15 +26,15 @@ const (
) )
const ( const (
STATUS_SUCCESS = 0 STATUS_SUCCESS = 0
STATUS_NOTFOUND = 69 STATUS_NOTFOUND = 69
STATUS_INTERNALERR = 129 STATUS_INTERNALERR = 129
) )
var DATA_FORMATS map[string]string = map[string]string{ var DATA_FORMATS map[string]string = map[string]string{
"bytes": DF_BYTES, "bytes": DF_BYTES,
"text": DF_TEXT, "text": DF_TEXT,
"json": DF_JSON, "json": DF_JSON,
} }
var ENCODINGS map[string]string = map[string]string{ var ENCODINGS map[string]string = map[string]string{
@ -42,10 +42,22 @@ var ENCODINGS map[string]string = map[string]string{
} }
type DataFormat struct { type DataFormat struct {
Format string Format string
Encoding string Encoding string
} }
func TextDataFormat() *DataFormat {
return &DataFormat{Format: DF_TEXT, Encoding: E_UTF8}
}
func JsonDataFormat() *DataFormat {
return &DataFormat{Format: DF_JSON, Encoding: E_UTF8}
}
func BytesDataFormat() *DataFormat {
return &DataFormat{Format: DF_BYTES}
}
func ParseDataFormat(format string) (*DataFormat, error) { func ParseDataFormat(format string) (*DataFormat, error) {
parts := strings.Split(format, ":") parts := strings.Split(format, ":")
if len(parts) != 2 { if len(parts) != 2 {
@ -68,7 +80,7 @@ func ParseDataFormat(format string) (*DataFormat, error) {
} }
return &DataFormat{ return &DataFormat{
Format: f, Format: f,
Encoding: encoding, Encoding: encoding,
}, nil }, nil
} }
@ -79,4 +91,3 @@ func (df *DataFormat) String() string {
} }
return fmt.Sprintf("%s:%s", df.Format, df.Encoding) return fmt.Sprintf("%s:%s", df.Format, df.Encoding)
} }

View File

@ -18,18 +18,18 @@ const (
) )
type RawPacket struct { type RawPacket struct {
Magic uint32 Magic uint32
Version uint8 Version uint8
Flags uint8 Flags uint8
HeaderSize uint16 HeaderSize uint16
PayloadSize uint32 PayloadSize uint32
Header []byte Header []byte
Payload []byte Payload []byte
} }
type Packet struct { type Packet struct {
Version int Version int
Flags int Flags int
Headers map[string]string Headers map[string]string
Payload []byte Payload []byte
} }
@ -41,7 +41,7 @@ type PacketDuplex struct {
func BuildPacket(headers map[string]string, payload []byte) *Packet { func BuildPacket(headers map[string]string, payload []byte) *Packet {
return &Packet{ return &Packet{
Version: PacketVersion, Version: PacketVersion,
Flags: 0, // TODO: Flags: 0, // TODO:
Headers: headers, Headers: headers,
Payload: payload, Payload: payload,
} }
@ -76,7 +76,7 @@ func ParseHeaders(rawHeaders []byte, headers *map[string]string) error {
func SerializeHeaders(headers *map[string]string) []byte { func SerializeHeaders(headers *map[string]string) []byte {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
for k, v := range(*headers) { for k, v := range *headers {
fmt.Fprintf(buf, "%s:%s\n", k, v) fmt.Fprintf(buf, "%s:%s\n", k, v)
} }
fmt.Fprintf(buf, "\n") fmt.Fprintf(buf, "\n")
@ -133,7 +133,7 @@ func (r *PacketDuplex) ReadPacket() (*Packet, error) {
pkt := &Packet{ pkt := &Packet{
Version: int(rpkt.Version), Version: int(rpkt.Version),
Flags: int(rpkt.Flags), Flags: int(rpkt.Flags),
Headers: make(map[string]string), Headers: make(map[string]string),
Payload: rpkt.Payload, Payload: rpkt.Payload,
} }
@ -169,7 +169,7 @@ func (r *PacketDuplex) WritePacket(packet *Packet) (int, error) {
if err := binary.Write(buf, binary.BigEndian, uint32(payloadSize)); err != nil { if err := binary.Write(buf, binary.BigEndian, uint32(payloadSize)); err != nil {
return 0, errors.New(fmt.Sprintf("Failed to write payload size into packet: %s", err.Error())) return 0, errors.New(fmt.Sprintf("Failed to write payload size into packet: %s", err.Error()))
} }
if _, err := buf.Write(rawHeaders[:headerSize]); err != nil { if _, err := buf.Write(rawHeaders[:headerSize]); err != nil {
return 0, errors.New(fmt.Sprintf("Failed to write raw headers: %s", err.Error())) return 0, errors.New(fmt.Sprintf("Failed to write raw headers: %s", err.Error()))
} }
@ -185,4 +185,3 @@ func (r *PacketDuplex) WritePacket(packet *Packet) (int, error) {
return n, nil return n, nil
} }

View File

@ -1,6 +1,7 @@
package hsp package hsp
import ( import (
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"net" "net"
@ -8,7 +9,7 @@ import (
) )
type Request struct { type Request struct {
conn net.Conn conn net.Conn
packet *Packet packet *Packet
} }
@ -54,6 +55,19 @@ func (req *Request) ExtractText() (string, error) {
return string(req.packet.Payload), nil 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) { func (req *Request) ExtractBytes() ([]byte, error) {
df, err := req.GetDataFormat() df, err := req.GetDataFormat()
if err != nil { if err != nil {
@ -66,4 +80,3 @@ func (req *Request) ExtractBytes() ([]byte, error) {
return req.packet.Payload, nil return req.packet.Payload, nil
} }

View File

@ -40,9 +40,9 @@ func NewPacketResponse(packet *Packet) *Response {
return &Response{ return &Response{
StatusCode: s, StatusCode: s,
Format: *df, Format: *df,
Headers: packet.Headers, Headers: packet.Headers,
Payload: packet.Payload, Payload: packet.Payload,
} }
} }

View File

@ -9,19 +9,19 @@ import (
) )
type Server struct { type Server struct {
Addr hsp.Adddress Addr hsp.Adddress
routePrefix string // TODO: Support route prefix, e.g listening on localhost/api routePrefix string // TODO: Support route prefix, e.g listening on localhost/api
Running bool Running bool
ConnChan chan net.Conn ConnChan chan net.Conn
listener net.Listener listener net.Listener
mu sync.Mutex mu sync.Mutex
} }
func NewServer(addr hsp.Adddress) *Server { func NewServer(addr hsp.Adddress) *Server {
return &Server{ return &Server{
Addr: addr, Addr: addr,
routePrefix: addr.Route, routePrefix: addr.Route,
Running: false, Running: false,
} }
} }
@ -45,7 +45,7 @@ func (s *Server) Start() error {
conn, err := ln.Accept() conn, err := ln.Accept()
if err != nil { if err != nil {
if !s.IsRunning() { if !s.IsRunning() {
break; break
} }
return err return err
} }
@ -65,7 +65,6 @@ func (s *Server) Start() error {
return nil return nil
} }
func (s *Server) Stop() error { func (s *Server) Stop() error {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
@ -77,7 +76,7 @@ func (s *Server) Stop() error {
if s.ConnChan != nil { if s.ConnChan != nil {
close(s.ConnChan) close(s.ConnChan)
} }
return nil return nil
} }
@ -86,5 +85,3 @@ func (s *Server) IsRunning() bool {
defer s.mu.Unlock() defer s.mu.Unlock()
return s.Running return s.Running
} }