From 8522e60af3feac4e92d80dda3ce648a94e1a929f Mon Sep 17 00:00:00 2001 From: hex Date: Sun, 3 Aug 2025 14:22:37 +0200 Subject: [PATCH] feat: basic boxy client --- internal/boxy/boxy.go | 97 +++++++++++++++++++++++++++++++++++++++++ internal/types/types.go | 2 + main.go | 38 +++++----------- 3 files changed, 111 insertions(+), 26 deletions(-) create mode 100644 internal/boxy/boxy.go diff --git a/internal/boxy/boxy.go b/internal/boxy/boxy.go new file mode 100644 index 0000000..4d5ea92 --- /dev/null +++ b/internal/boxy/boxy.go @@ -0,0 +1,97 @@ +package boxy + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "strconv" +) + +type BoxyClient struct { + Name string + Secret string + ApiUrl string + Hostnames []string + + endpointId int +} + +func (b *BoxyClient) Register(address string, port int) error { + rawBody := map[string]any{ + "port": port, + "hostname": b.Hostnames, + } + + if address != "" { + rawBody["address"] = address + } + + jBody, err := json.Marshal(rawBody) + + if err != nil { + return err + } + + req, err := http.NewRequest("POST", b.ApiUrl+"/register", bytes.NewBuffer(jBody)) + + if err != nil { + return err + } + + req.SetBasicAuth(b.Name, b.Secret) + + resp, _ := http.DefaultClient.Do(req) + + if resp.StatusCode != 200 { + log.Fatal("Could not register with Boxy.\nStatus Code: " + strconv.Itoa(req.Response.StatusCode)) + } + + body, err := io.ReadAll(resp.Body) + + if err != nil { + return err + } + + b.endpointId, err = strconv.Atoi(string(body)) + + if err != nil { + return err + } + + return nil +} + +func (b *BoxyClient) Unregister() error { + rawBody := map[string]any{} + + jBody, err := json.Marshal(rawBody) + + if err != nil { + return err + } + + req, err := http.NewRequest("DELETE", b.ApiUrl+"/endpoint/"+strconv.Itoa(b.endpointId), bytes.NewBuffer(jBody)) + + if err != nil { + return err + } + + req.SetBasicAuth(b.Name, b.Secret) + + resp, _ := http.DefaultClient.Do(req) + + body, err := io.ReadAll(resp.Body) + + if err != nil { + return err + } + + if resp.StatusCode != 200 { + return fmt.Errorf("Could not delete endpoint.\nBody: %s", string(body)) + } + + return nil +} diff --git a/internal/types/types.go b/internal/types/types.go index 0395fcb..aef1f95 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -26,6 +26,7 @@ import ( "github.com/minio/minio-go/v7" "gorm.io/gorm" "stereo.cat/backend/internal/auth/client" + "stereo.cat/backend/internal/boxy" ) type Route struct { @@ -45,6 +46,7 @@ type StereoConfig struct { FrontendUri string Domain string Context context.Context + BoxyClient boxy.BoxyClient } type File struct { diff --git a/main.go b/main.go index b0006bc..ec52dc5 100644 --- a/main.go +++ b/main.go @@ -18,13 +18,10 @@ package main import ( - "bytes" "context" - "encoding/json" "errors" "fmt" "log" - "net/http" "os" "strconv" "strings" @@ -39,6 +36,7 @@ import ( "stereo.cat/backend/internal/api" "stereo.cat/backend/internal/auth" "stereo.cat/backend/internal/auth/client" + "stereo.cat/backend/internal/boxy" "stereo.cat/backend/internal/types" ) @@ -137,34 +135,22 @@ func main() { port, err := strconv.Atoi(strings.Split(listenAddr, ":")[1]) - fmt.Printf("Using port %d\n", port) - - rawBody := map[string]any{ - "port": port, - "hostname": c.Domain, - } - if boxyClientAddress != "" { - rawBody["address"] = boxyClientAddress + if err != nil { + panic(err) } - jBody, err := json.Marshal(rawBody) + c.BoxyClient = boxy.BoxyClient{ + Name: boxyClientName, + Secret: boxyClientSecret, + ApiUrl: boxyApiUrl, + Hostnames: []string{c.Domain}, + } + + err = c.BoxyClient.Register(boxyClientAddress, port) if err != nil { - log.Fatal(err) + panic(err) } - - req, err := http.NewRequest("POST", boxyApiUrl+"/register", bytes.NewBuffer(jBody)) - - req.SetBasicAuth(boxyClientName, boxyClientSecret) - - resp, _ := http.DefaultClient.Do(req) - - if resp.StatusCode != 200 { - log.Fatal("Could not register with Boxy.\nStatus Code: " + strconv.Itoa(req.Response.StatusCode)) - return - } - - log.Println("Successfully registered with Boxy.") } api.Register(&c)