From 99a0eea5d19ac21e5ddec1d6787bab439c621f26 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Fri, 4 Oct 2024 11:43:54 -0400 Subject: [PATCH] both production and development builds now working with vite.js (#221) --- agent/agent.go | 3 +- agent/agentUi/embed.go | 6 ++++ agent/agentUi/middleware.go | 59 ++++++++++++++++++++++++++++++++++++ agent/agentUi/src/App.jsx | 6 +++- agent/agentUi/vite.config.js | 9 ++++++ 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 agent/agentUi/embed.go create mode 100644 agent/agentUi/middleware.go diff --git a/agent/agent.go b/agent/agent.go index eb42ebec..10b111b1 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -4,6 +4,7 @@ import ( "context" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/agent/agentUi" "github.com/openziti/zrok/agent/proctree" "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/sdk/golang/sdk" @@ -99,7 +100,7 @@ func (a *Agent) gateway() { logrus.Fatalf("unable to register gateway: %v", err) } - if err := http.ListenAndServe(":8888", cors(mux)); err != nil { + if err := http.ListenAndServe(":8888", agentUi.Middleware(mux)); err != nil { logrus.Error(err) } } diff --git a/agent/agentUi/embed.go b/agent/agentUi/embed.go new file mode 100644 index 00000000..70b7822f --- /dev/null +++ b/agent/agentUi/embed.go @@ -0,0 +1,6 @@ +package agentUi + +import "embed" + +//go:embed dist +var FS embed.FS diff --git a/agent/agentUi/middleware.go b/agent/agentUi/middleware.go new file mode 100644 index 00000000..4b30efe1 --- /dev/null +++ b/agent/agentUi/middleware.go @@ -0,0 +1,59 @@ +package agentUi + +import ( + "io/fs" + "net/http" + "os" + "path/filepath" + "strings" +) + +func Middleware(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, "/v1") { + handler.ServeHTTP(w, r) + return + } + + staticPath := "dist" + indexPath := "index.html" + + // get the absolute path to prevent directory traversal + path, err := filepath.Abs(r.URL.Path) + if err != nil { + // if we failed to get the absolute path respond with a 400 bad request and stop + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + // prepend the path with the path to the static directory + path = filepath.Join(staticPath, path) + + _, err = FS.Open(path) + if os.IsNotExist(err) { + // file does not exist, serve index.gohtml + index, err := FS.ReadFile(filepath.Join(staticPath, indexPath)) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusAccepted) + _, _ = w.Write(index) + return + + } else if err != nil { + // if we got an error (that wasn't that the file doesn't exist) stating the + // file, return a 500 internal server error and stop + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // get the subdirectory of the static dir + if statics, err := fs.Sub(FS, staticPath); err == nil { + // otherwise, use http.FileServer to serve the static dir + http.FileServer(http.FS(statics)).ServeHTTP(w, r) + } else { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + }) +} diff --git a/agent/agentUi/src/App.jsx b/agent/agentUi/src/App.jsx index 90b90fce..f4639472 100644 --- a/agent/agentUi/src/App.jsx +++ b/agent/agentUi/src/App.jsx @@ -11,10 +11,14 @@ function App() { { name: 'Token', selector: row => row.token + }, + { + name: 'Share Mode', + selector: row => row.shareMode } ]; - let api = new AgentApi(new ApiClient("http://localhost:8888")); + let api = new AgentApi(new ApiClient(window.location.protocol+'//'+window.location.host)); useEffect(() => { let mounted = true; diff --git a/agent/agentUi/vite.config.js b/agent/agentUi/vite.config.js index 5a33944a..b98c79fa 100644 --- a/agent/agentUi/vite.config.js +++ b/agent/agentUi/vite.config.js @@ -4,4 +4,13 @@ import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], + server: { + proxy: { + '/v1': { + target: 'http://localhost:8888', + changeOrigin: true, + } + } + } }) +