//go:build development package hub import ( "fmt" "io" "log/slog" "net/http" "net/http/httputil" "net/url" "strings" "github.com/henrygd/beszel" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/osutils" ) // Wraps http.RoundTripper to modify dev proxy HTML responses type responseModifier struct { transport http.RoundTripper hub *Hub } func (rm *responseModifier) RoundTrip(req *http.Request) (*http.Response, error) { resp, err := rm.transport.RoundTrip(req) if err != nil { return resp, err } // Only modify HTML responses contentType := resp.Header.Get("Content-Type") if !strings.Contains(contentType, "text/html") { return resp, nil } body, err := io.ReadAll(resp.Body) if err != nil { return resp, err } resp.Body.Close() // Create a new response with the modified body modifiedBody := rm.modifyHTML(string(body)) resp.Body = io.NopCloser(strings.NewReader(modifiedBody)) resp.ContentLength = int64(len(modifiedBody)) resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(modifiedBody))) return resp, nil } func (rm *responseModifier) modifyHTML(html string) string { parsedURL, err := url.Parse(rm.hub.appURL) if err != nil { return html } // fix base paths in html if using subpath basePath := strings.TrimSuffix(parsedURL.Path, "/") + "/" html = strings.ReplaceAll(html, "./", basePath) html = strings.Replace(html, "{{V}}", beszel.Version, 1) html = strings.Replace(html, "{{HUB_URL}}", rm.hub.appURL, 1) return html } // startServer sets up the development server for Beszel func (h *Hub) startServer(se *core.ServeEvent) error { slog.Info("starting server", "appURL", h.appURL) proxy := httputil.NewSingleHostReverseProxy(&url.URL{ Scheme: "http", Host: "localhost:5173", }) proxy.Transport = &responseModifier{ transport: http.DefaultTransport, hub: h, } se.Router.GET("/{path...}", func(e *core.RequestEvent) error { proxy.ServeHTTP(e.Response, e.Request) return nil }) _ = osutils.LaunchURL(h.appURL) return nil }