mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-30 09:38:26 -05:00
* chore: code cleanup services/web * fix: export private member to keep the test external * chore: backport changes --------- Co-authored-by: Florian Schade <f.schade@icloud.com>
99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package assets
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"io/fs"
|
|
"mime"
|
|
"net/http"
|
|
"path"
|
|
"path/filepath"
|
|
|
|
"golang.org/x/net/html"
|
|
)
|
|
|
|
type fileServer struct {
|
|
fsys http.FileSystem
|
|
}
|
|
|
|
// FileServer defines the http handler for the embedded files
|
|
func FileServer(fsys fs.FS) http.Handler {
|
|
return &fileServer{http.FS(fsys)}
|
|
}
|
|
|
|
func (f *fileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
uPath := path.Clean(path.Join("/", r.URL.Path))
|
|
r.URL.Path = uPath
|
|
|
|
tryIndex := func() {
|
|
r.URL.Path = "/index.html"
|
|
|
|
// not every fs contains a file named index.html,
|
|
// therefore, we need to check if the file exists and stop the recursion if it doesn't
|
|
file, err := f.fsys.Open(r.URL.Path)
|
|
if err != nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
f.ServeHTTP(w, r)
|
|
}
|
|
|
|
asset, err := f.fsys.Open(uPath)
|
|
if err != nil {
|
|
tryIndex()
|
|
return
|
|
}
|
|
defer asset.Close()
|
|
|
|
s, _ := asset.Stat()
|
|
if s.IsDir() {
|
|
tryIndex()
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(s.Name())))
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
switch s.Name() {
|
|
case "index.html", "oidc-callback.html", "oidc-silent-redirect.html":
|
|
w.Header().Del("Expires")
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
_ = withBase(buf, asset, "/")
|
|
default:
|
|
_, _ = buf.ReadFrom(asset)
|
|
}
|
|
|
|
_, _ = w.Write(buf.Bytes())
|
|
}
|
|
|
|
func withBase(w io.Writer, r io.Reader, base string) error {
|
|
doc, _ := html.Parse(r)
|
|
var parse func(*html.Node)
|
|
parse = func(n *html.Node) {
|
|
if n.Type == html.ElementNode && n.Data == "head" {
|
|
n.InsertBefore(&html.Node{
|
|
Type: html.ElementNode,
|
|
Data: "base",
|
|
Attr: []html.Attribute{
|
|
{
|
|
Key: "href",
|
|
Val: base,
|
|
},
|
|
},
|
|
}, n.FirstChild)
|
|
|
|
return
|
|
}
|
|
|
|
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
parse(c)
|
|
}
|
|
}
|
|
parse(doc)
|
|
|
|
return html.Render(w, doc)
|
|
}
|