feat: basic boxy client

This commit is contained in:
hexlocation 2025-08-03 14:22:37 +02:00
parent cad2855220
commit 8522e60af3
3 changed files with 111 additions and 26 deletions

97
internal/boxy/boxy.go Normal file
View file

@ -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
}

View file

@ -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 {

38
main.go
View file

@ -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)