From e23a633356c97f2527f313d02099f2308fd25b37 Mon Sep 17 00:00:00 2001 From: go-compile <97609133+go-compile@users.noreply.github.com> Date: Sat, 22 Jul 2023 19:31:34 +0100 Subject: [PATCH] refactor: ipc command run relay --- cmd/localrelay/ipcClient.go | 75 +++++++++++-------------------------- cmd/localrelay/ipcServer.go | 64 ++++++++++++++++++++++++++++++- cmd/localrelay/run.go | 2 +- 3 files changed, 86 insertions(+), 55 deletions(-) diff --git a/cmd/localrelay/ipcClient.go b/cmd/localrelay/ipcClient.go index 77554e8..3ae8b7d 100644 --- a/cmd/localrelay/ipcClient.go +++ b/cmd/localrelay/ipcClient.go @@ -1,10 +1,13 @@ package main import ( + "bytes" "encoding/binary" + "encoding/json" "fmt" "io" "net/url" + "strconv" ) // commandDataIPC will send a command with a data section @@ -39,61 +42,27 @@ func commandDataIPC(w io.Writer, id uint8, data []byte) error { // serviceRun takes paths to relay config files and then connects via IPC to // instruct the service to run these relays func serviceRun(relays []string) error { - // conn, err := IPCConnect() - // if err != nil { - // return errors.Wrap(err, "connecting to IPC") - // } + client, conn, err := IPCConnect() + if err != nil { + return err + } - // defer conn.Close() + defer conn.Close() - // for _, relay := range relays { - // buf := bytes.NewBuffer(nil) - // buf.Write([]byte{daemonRun}) - - // lenBuf := make([]byte, 2) - // binary.BigEndian.PutUint16(lenBuf, uint16(len(relay))) - - // buf.Write(lenBuf) - // buf.Write([]byte(relay)) - - // payloadLen := make([]byte, 2) - // binary.BigEndian.PutUint16(payloadLen, uint16(buf.Len())) - - // conn.Write(payloadLen) - // conn.Write(buf.Bytes()) - - // response := make([]byte, 1) - // _, err := conn.Read(response) - // if err != nil { - // return errors.Wrap(err, "reading from ipc conn") - // } - - // switch response[0] { - // case 0: - // fmt.Printf("[Error] Relay %q could not be started.\n", relay) - - // errlenBuf := make([]byte, 2) - // if _, err := conn.Read(errlenBuf); err != nil { - // return err - // } - - // fmt.Println("1") - // msg := make([]byte, binary.BigEndian.Uint16(errlenBuf)) - // if _, err := conn.Read(msg); err != nil { - // return err - // } - - // fmt.Println(string(msg)) - // case 1: - // fmt.Printf("[Info] Relay %q has been started.\n", relay) - // case 2: - // fmt.Printf("[Info] Relay %q is already running.\n", relay) - // case 3: - // fmt.Printf("[Info] Relay %q does not exist.\n", relay) - // case 4: - // fmt.Printf("[Info] Relay %q errored when creating.\n", relay) - // } - // } + for _, relay := range relays { + // make post request to run relay. Use strconv instead of json encoding for performance + resp, err := client.Post("http://lr/run", "application/json", bytes.NewBuffer([]byte("["+strconv.Quote(relay)+"]"))) + if err != nil { + return err + } + + var response msgResponse + if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { + return err + } + + fmt.Println(response.Message) + } return nil } diff --git a/cmd/localrelay/ipcServer.go b/cmd/localrelay/ipcServer.go index 255e053..12110d5 100644 --- a/cmd/localrelay/ipcServer.go +++ b/cmd/localrelay/ipcServer.go @@ -2,15 +2,22 @@ package main import ( "encoding/json" + "os" + "strconv" "strings" "time" "github.com/fasthttp/router" "github.com/go-compile/localrelay" + "github.com/naoina/toml" "github.com/valyala/fasthttp" ) +type msgResponse struct { + Message string `json:"message"` +} + func newIPCServer() *fasthttp.Server { r := router.New() assignIPCRoutes(r) @@ -72,10 +79,65 @@ func ipcRouteStop(ctx *fasthttp.RequestCtx) { func ipcRouteRun(ctx *fasthttp.RequestCtx) { var files []string - if err := json.NewDecoder(ctx.Response.BodyStream()).Decode(&files); err != nil { + + if err := json.Unmarshal(ctx.Request.Body(), &files); err != nil { ctx.SetStatusCode(400) ctx.Write([]byte(`{"message":"Invalid json body."}`)) return } + // TODO: support run multiple files + if len(files) != 1 { + ctx.SetStatusCode(400) + ctx.Write([]byte(`{"message":"Endpoint currently requires at maximum and minimum one relay."}`)) + return + } + + relayFile := files[0] + + exists, err := pathExists(relayFile) + if err != nil { + ctx.SetStatusCode(500) + ctx.Write([]byte(`{"message":"Relay path could not be verified."}`)) + return + } + + if !exists { + ctx.SetStatusCode(404) + ctx.Write([]byte(`{"message":"Relay file does not exist."}`)) + return + } + + f, err := os.Open(relayFile) + if err != nil { + ctx.SetStatusCode(500) + ctx.Write([]byte(`{"message":"Failed to open relay config."}`)) + return + } + + var relay Relay + if err := toml.NewDecoder(f).Decode(&relay); err != nil { + f.Close() + ctx.SetStatusCode(500) + ctx.Write([]byte(`{"message":"Failed to decode relay config."}`)) + return + } + + f.Close() + + if isRunning(relay.Name) { + ctx.SetStatusCode(500) + ctx.Write([]byte(`{"message":"Relay is already running."}`)) + return + } + + if err := launchRelays([]Relay{relay}, false); err != nil { + ctx.SetStatusCode(500) + ctx.Write([]byte(`{"message":` + strconv.Quote("Error launching relay. "+err.Error()) + `}`)) + return + } + + ctx.SetStatusCode(200) + ctx.Write([]byte(`{"message":"Relay successfully launched."}`)) + return } diff --git a/cmd/localrelay/run.go b/cmd/localrelay/run.go index 33fb095..b2962bc 100644 --- a/cmd/localrelay/run.go +++ b/cmd/localrelay/run.go @@ -100,7 +100,7 @@ func runRelays(opt *options, i int, cmd []string) error { fmt.Println("[Info] Service has been started.") - // wait for proccess to launch + // wait for process to launch time.Sleep(time.Millisecond * 50) }