package web import ( "embed" "io" "net/http" "regexp" "strings" ) // The page about llmgw itself: what it is, how to install it, where to get // it. It is the project's website, carried by every gateway so an operator // has it where they already are, and served without a key like the landing // page — it says nothing about this installation, only about the software. // // The same template renders the published website (Site), which differs in // three ways: fonts from Google rather than from this binary, no link back to // a gateway, and features on main marked as coming in the next release. // proxyConfigs are the reverse proxy configurations the page shows. They are // copies of deploy/proxy, which the release attaches; embed cannot reach // outside this package, and TestAboutProxyConfigsMatchDeploy keeps the two // the same. // //go:embed proxy var proxyConfigs embed.FS // AboutData is what the page is rendered with. type AboutData struct { // Version is what this build calls itself; Release is the same when it is // a released version, and empty for a development build, which has no // files to download. Version, Release string // Download is where the release's files are, or for a development build // the proxy configurations on main. Download string // Date is the release date, when it is known. A binary does not know it. Date string Caddy, Nginx string Site bool } // releaseTag is a version the releases page has files for. var releaseTag = regexp.MustCompile(`^v\d+\.\d+\.\d+$`) const repoURL = "https://gitea.mynodes.xyz/ilker/llmgw" // NewAboutData fills the page's data for a version. func NewAboutData(version string) AboutData { d := AboutData{Version: version, Download: repoURL + "/raw/branch/main/deploy/proxy"} if releaseTag.MatchString(version) { d.Release = version d.Download = repoURL + "/releases/download/" + version } d.Caddy = proxyConfig("Caddyfile") d.Nginx = proxyConfig("nginx.conf") return d } func proxyConfig(name string) string { b, err := proxyConfigs.ReadFile("proxy/" + name) if err != nil { panic("web: the proxy configuration " + name + " is missing from the binary: " + err.Error()) } return strings.TrimRight(string(b), "\n") } // RenderAbout writes the page, for the website's build as much as for About. func RenderAbout(w io.Writer, d AboutData) error { return tmpl.ExecuteTemplate(w, "about", d) } // About serves the page at /about. func About(version string) http.HandlerFunc { d := NewAboutData(version) return func(w http.ResponseWriter, r *http.Request) { render(w, "about", d) } }