From 62336753c645c6b4237617466cdb8c0dacaffde4 Mon Sep 17 00:00:00 2001 From: William P Date: Sun, 20 Jul 2025 21:22:20 -0400 Subject: [PATCH] refactor --- client/go.mod | 3 +++ client/httputil/helloworld.go | 9 +++++++ client/httputil/response.go | 17 ++++++++++++ client/main.go | 34 ++++++++++++++++++++++++ client/routes/routes.go | 16 ++++++++++++ client/server/server.go | 49 +++++++++++++++++++++++++++++++++++ client/testfunc/testjson.go | 37 ++++++++++++++++++++++++++ 7 files changed, 165 insertions(+) create mode 100644 client/go.mod create mode 100644 client/httputil/helloworld.go create mode 100644 client/httputil/response.go create mode 100644 client/main.go create mode 100644 client/routes/routes.go create mode 100644 client/server/server.go create mode 100644 client/testfunc/testjson.go diff --git a/client/go.mod b/client/go.mod new file mode 100644 index 0000000..60d9961 --- /dev/null +++ b/client/go.mod @@ -0,0 +1,3 @@ +module git.dubyatp.xyz/orphanage/client + +go 1.24.4 diff --git a/client/httputil/helloworld.go b/client/httputil/helloworld.go new file mode 100644 index 0000000..b724ce7 --- /dev/null +++ b/client/httputil/helloworld.go @@ -0,0 +1,9 @@ +package httputil + +import "net/http" + +func HelloWorld(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("hello world")) + }) +} diff --git a/client/httputil/response.go b/client/httputil/response.go new file mode 100644 index 0000000..b8ca28f --- /dev/null +++ b/client/httputil/response.go @@ -0,0 +1,17 @@ +package httputil + +import ( + "encoding/json" + "net/http" +) + +func WriteJSON(w http.ResponseWriter, status int, data interface{}) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + jsonBytes, err := json.Marshal(data) + if err != nil { + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + w.Write(jsonBytes) +} diff --git a/client/main.go b/client/main.go new file mode 100644 index 0000000..a1ac3dd --- /dev/null +++ b/client/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "context" + "fmt" + "io" + "os" + "os/signal" + + "git.dubyatp.xyz/orphanage/client/server" +) + +func run(ctx context.Context, w io.Writer, args []string) error { + ctx, cancel := signal.NotifyContext(ctx, os.Interrupt) + defer cancel() + + config := struct { + Host string + Port string + }{ + Host: "0.0.0.0", + Port: "8080", + } + + return server.StartServer(ctx, config) +} + +func main() { + ctx := context.Background() + if err := run(ctx, os.Stdout, os.Args); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } +} diff --git a/client/routes/routes.go b/client/routes/routes.go new file mode 100644 index 0000000..edc7e96 --- /dev/null +++ b/client/routes/routes.go @@ -0,0 +1,16 @@ +package routes + +import ( + "net/http" + + "git.dubyatp.xyz/orphanage/client/httputil" + "git.dubyatp.xyz/orphanage/client/testfunc" +) + +func AddRoutes( + mux *http.ServeMux, +) { + mux.Handle("/", http.NotFoundHandler()) + mux.Handle("/helloworld", httputil.HelloWorld(nil)) + mux.Handle("/testjson", testfunc.HelloWorldJSON(nil)) +} diff --git a/client/server/server.go b/client/server/server.go new file mode 100644 index 0000000..2337cdc --- /dev/null +++ b/client/server/server.go @@ -0,0 +1,49 @@ +package server + +import ( + "context" + "fmt" + "log" + "net" + "net/http" + "os" + "sync" + "time" + + "git.dubyatp.xyz/orphanage/client/routes" +) + +func NewServer() http.Handler { + mux := http.NewServeMux() + routes.AddRoutes(mux) + var handler http.Handler = mux + return handler +} + +func StartServer(ctx context.Context, config struct{ Host, Port string }) error { + srv := NewServer() + httpServer := &http.Server{ + Addr: net.JoinHostPort(config.Host, config.Port), + Handler: srv, + } + go func() { + log.Printf("orphan listening on %s\n", httpServer.Addr) + if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { + fmt.Fprintf(os.Stderr, "error listening and serving: %s\n", err) + } + }() + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + shutdownCtx := context.Background() + shutdownCtx, cancel := context.WithTimeout(shutdownCtx, 10*time.Second) + defer cancel() + if err := httpServer.Shutdown(shutdownCtx); err != nil { + fmt.Fprintf(os.Stderr, "error shutting down http server: %s\n", err) + } + }() + wg.Wait() + return nil +} diff --git a/client/testfunc/testjson.go b/client/testfunc/testjson.go new file mode 100644 index 0000000..644da68 --- /dev/null +++ b/client/testfunc/testjson.go @@ -0,0 +1,37 @@ +package testfunc + +import ( + "encoding/json" + "net/http" + + "git.dubyatp.xyz/orphanage/client/httputil" +) + +type TestResponse struct { + APIVersion string `json:"apiVersion"` + TestMessage string `json:"testMessage"` +} + +func (m TestResponse) MarshalJSON() ([]byte, error) { + type OrderedTestResponse struct { + APIVersion string `json:"apiVersion"` + TestMessage string `json:"testMessage"` + } + + ordered := OrderedTestResponse{ + APIVersion: m.APIVersion, + TestMessage: m.TestMessage, + } + + return json.Marshal(ordered) +} + +func HelloWorldJSON(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + resp := TestResponse{ + APIVersion: "v1", + TestMessage: "this is a test owo", + } + httputil.WriteJSON(w, http.StatusOK, resp) + }) +}