Define base for assets and support for sub path (#1247)

* Added correct mime type to files

* Define Base for Assets

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* lint

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Make things relative

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* hop styling

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Daniel Valdivia
2021-11-22 21:02:16 -08:00
committed by GitHub
parent 820fa61b43
commit 53d278a91e
11 changed files with 171 additions and 126 deletions

View File

@@ -21,14 +21,16 @@ package restapi
import (
"bytes"
"crypto/tls"
"fmt"
"io"
"io/fs"
"log"
"net"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"
"github.com/klauspost/compress/gzhttp"
@@ -50,6 +52,9 @@ var additionalServerFlags = struct {
CertsDir string `long:"certs-dir" description:"path to certs directory" env:"CONSOLE_CERTS_DIR"`
}{}
var subPath = "/"
var subPathOnce sync.Once
func configureFlags(api *operations.ConsoleAPI) {
api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{
{
@@ -251,8 +256,6 @@ func FileServerMiddleware(next http.Handler) http.Handler {
})
}
var reHrefIndex = regexp.MustCompile(`(?m)((href|src)="(.\/).*?")`)
type notFoundRedirectRespWr struct {
http.ResponseWriter // We embed http.ResponseWriter
status int
@@ -274,9 +277,15 @@ func (w *notFoundRedirectRespWr) Write(p []byte) (int, error) {
func handleSPA(w http.ResponseWriter, r *http.Request) {
basePath := "/"
// For SPA mode we will replace relative paths with absolute unless we receive query param cp=y
// For SPA mode we will replace root base with a sub path if configured unless we received cp=y and cpb=/NEW/BASE
if v := r.URL.Query().Get("cp"); v == "y" {
basePath = "./"
if base := r.URL.Query().Get("cpb"); base != "" {
// make sure the subpath has a trailing slash
if !strings.HasSuffix(base, "/") {
base = fmt.Sprintf("%s/", base)
}
basePath = base
}
}
indexPage, err := portal_ui.GetStaticAssets().Open("build/index.html")
@@ -291,16 +300,21 @@ func handleSPA(w http.ResponseWriter, r *http.Request) {
return
}
if basePath != "./" {
indexPageStr := string(indexPageBytes)
for _, match := range reHrefIndex.FindAllStringSubmatch(indexPageStr, -1) {
toReplace := strings.Replace(match[1], match[3], basePath, 1)
indexPageStr = strings.Replace(indexPageStr, match[1], toReplace, 1)
}
indexPageBytes = []byte(indexPageStr)
// if we have a seeded basePath. This should override CONSOLE_SUBPATH every time, thus the `if else`
if basePath != "/" {
indexPageBytes = replaceBaseInIndex(indexPageBytes, basePath)
// if we have a custom subpath replace it in
} else if getSubPath() != "/" {
indexPageBytes = replaceBaseInIndex(indexPageBytes, getSubPath())
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
mimeType := mimedb.TypeByExtension(filepath.Ext(r.URL.Path))
if mimeType == "application/octet-stream" {
mimeType = "text/html"
}
w.Header().Set("Content-Type", mimeType)
http.ServeContent(w, r, "index.html", time.Now(), bytes.NewReader(indexPageBytes))
}
@@ -335,3 +349,24 @@ func configureServer(s *http.Server, _, _ string) {
// Turn-off random logging by Go net/http
s.ErrorLog = log.New(&nullWriter{}, "", 0)
}
func getSubPath() string {
subPathOnce.Do(func() {
if v := os.Getenv("CONSOLE_SUBPATH"); v != "" {
// make sure the subpath has a trailing slash
if !strings.HasSuffix(v, "/") {
v = fmt.Sprintf("%s/", v)
}
subPath = v
}
})
return subPath
}
func replaceBaseInIndex(indexPageBytes []byte, basePath string) []byte {
indexPageStr := string(indexPageBytes)
newBase := fmt.Sprintf("<base href=\"%s\"/>", basePath)
indexPageStr = strings.Replace(indexPageStr, "<base href=\"/\"/>", newBase, 1)
indexPageBytes = []byte(indexPageStr)
return indexPageBytes
}