From ba200efc46a26772829b8e7153c04740700584b7 Mon Sep 17 00:00:00 2001 From: metalblueberry Date: Wed, 21 Aug 2024 19:04:41 +0200 Subject: [PATCH] Encode static files to avoid problems with special characters Serve figures in server mode for the same reason. It is also a good reference example if people want to build on top --- examples/bar.html | 2 +- pkg/offline/plot.go | 68 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/examples/bar.html b/examples/bar.html index c55e846..74a5790 100755 --- a/examples/bar.html +++ b/examples/bar.html @@ -5,7 +5,7 @@
diff --git a/pkg/offline/plot.go b/pkg/offline/plot.go index 4b15beb..50aac1a 100644 --- a/pkg/offline/plot.go +++ b/pkg/offline/plot.go @@ -2,6 +2,7 @@ package offline import ( "bytes" + "encoding/base64" "encoding/json" "log" "net/http" @@ -34,17 +35,18 @@ func figToBuffer(fig types.Fig) *bytes.Buffer { if err != nil { panic(err) } - tmpl, err := template.New("plotly").Parse(baseHtml) + tmpl, err := template.New("plotly").Parse(singleFileHTML) if err != nil { panic(err) } buf := &bytes.Buffer{} data := struct { - Version types.Version - Content string + Version types.Version + B64Content string }{ Version: fig.Info(), - Content: string(figBytes), + // Encode to avoid problems with special characters + B64Content: base64.StdEncoding.EncodeToString(figBytes), } err = tmpl.Execute(buf, data) @@ -66,12 +68,18 @@ func Serve(fig types.Fig, opt ...Options) { Handler: mux, Addr: opts.Addr, } - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - buf := figToBuffer(fig) - buf.WriteTo(w) + + mux.HandleFunc("/content", func(w http.ResponseWriter, r *http.Request) { + err := json.NewEncoder(w).Encode(fig) + if err != nil { + log.Printf("Error rendering template, %s", err) + w.WriteHeader(http.StatusInternalServerError) + } }) - log.Print("Starting server") + mux.HandleFunc("/", webPage(fig, "/content")) + + log.Printf("Starting server at %s", srv.Addr) if err := srv.ListenAndServe(); err != nil { log.Print(err) } @@ -88,15 +96,55 @@ func computeOptions(def Options, opt ...Options) Options { return def } -var baseHtml = ` +var singleFileHTML = `
` + +type serverHTMLdata struct { + Version types.Version + ContentURL string +} + +func webPage(fig types.Fig, contentURL string) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + tmpl := template.Must(template.New("server").Parse(serverHTML)) + data := serverHTMLdata{ + Version: fig.Info(), + ContentURL: contentURL, + } + err := tmpl.Execute(w, data) + if err != nil { + log.Printf("Error rendering template, %s", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + } +} + +var serverHTML = ` + + + + +
+ + + `