chore: embed build info in the html to reduce requests (#6605)

This will reduce a request on every page load of Coder!
This commit is contained in:
Kyle Carberry 2023-03-21 14:04:54 -05:00 committed by GitHub
parent 74be9c6c55
commit 71eecb3515
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 9 deletions

View File

@ -16,6 +16,7 @@
<meta property="og:type" content="website" />
<meta property="csp-nonce" content="{{ .CSP.Nonce }}" />
<meta property="csrf-token" content="{{ .CSRF.Token }}" />
<meta property="build-info" content="{{ .BuildInfo }}" />
<!-- We need to set data-react-helmet to be able to override it in the workspace page -->
<link
rel="alternate icon"

View File

@ -6,8 +6,10 @@ import (
"crypto/sha1" //#nosec // Not used for cryptography.
_ "embed"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"html"
htmltemplate "html/template"
"io"
"io/fs"
@ -28,6 +30,7 @@ import (
"golang.org/x/sync/singleflight"
"golang.org/x/xerrors"
"github.com/coder/coder/buildinfo"
"github.com/coder/coder/coderd/httpapi"
"github.com/coder/coder/codersdk"
)
@ -102,10 +105,20 @@ func Handler(siteFS fs.FS, binFS http.FileSystem, binHashes map[string]string) h
})))
mux.Handle("/", http.FileServer(http.FS(siteFS))) // All other non-html static files.
buildInfo := codersdk.BuildInfoResponse{
ExternalURL: buildinfo.ExternalURL(),
Version: buildinfo.Version(),
}
buildInfoResponse, err := json.Marshal(buildInfo)
if err != nil {
panic("failed to marshal build info: " + err.Error())
}
return secureHeaders(&handler{
fs: siteFS,
htmlFiles: files,
h: mux,
fs: siteFS,
htmlFiles: files,
h: mux,
buildInfoJSON: html.EscapeString(string(buildInfoResponse)),
})
}
@ -117,8 +130,9 @@ type handler struct {
// scripts, and that nonce is passed through a template.
// We only do this for html files to reduce the amount of in memory caching
// of duplicate files as `fs`.
htmlFiles *htmlTemplates
h http.Handler
htmlFiles *htmlTemplates
h http.Handler
buildInfoJSON string
}
// filePath returns the filepath of the requested file.
@ -138,8 +152,9 @@ func (h *handler) exists(filePath string) bool {
}
type htmlState struct {
CSP cspState
CSRF csrfState
CSP cspState
CSRF csrfState
BuildInfo string
}
type cspState struct {
@ -184,7 +199,8 @@ func (h *handler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
reqFile := filePath(req.URL.Path)
state := htmlState{
// Token is the CSRF token for the given request
CSRF: csrfState{Token: nosurf.Token(req)},
CSRF: csrfState{Token: nosurf.Token(req)},
BuildInfo: h.buildInfoJSON,
}
// First check if it's a file we have in our templates

View File

@ -53,7 +53,20 @@ export const buildInfoMachine = createMachine(
},
{
services: {
getBuildInfo: API.getBuildInfo,
getBuildInfo: async () => {
// Build info is injected by the Coder server into the HTML document.
const buildInfo = document.querySelector("meta[property=build-info]")
if (buildInfo) {
const rawContent = buildInfo.getAttribute("content")
try {
return JSON.parse(rawContent as string)
} catch (ex) {
// Ignore this and fetch as normal!
}
}
return API.getBuildInfo()
},
},
actions: {
assignBuildInfo: assign({