mirror of
https://github.com/danderson/netboot.git
synced 2025-08-11 09:07:12 +02:00
97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
// Copyright 2016 Google Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package pixiecore
|
|
|
|
import (
|
|
"bytes"
|
|
"html/template"
|
|
"io/ioutil"
|
|
"mime"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.universe.tf/netboot/pixiecore/ui"
|
|
)
|
|
|
|
//go:generate go-bindata -o ui/autogen.go -ignore autogen.go -pkg ui -nometadata -nomemcopy -prefix ui/ ui/
|
|
|
|
const assetsPath = "/_/assets/"
|
|
|
|
func (s *Server) serveUI(mux *http.ServeMux) {
|
|
mux.HandleFunc("/", s.handleUI)
|
|
mux.HandleFunc(assetsPath, s.handleUI)
|
|
}
|
|
|
|
func (s *Server) handleUI(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/" {
|
|
r.URL.Path = assetsPath + "index.html"
|
|
}
|
|
if !strings.HasPrefix(r.URL.Path, assetsPath) {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
// Sticking a / in front of the path before cleaning it will strip
|
|
// out any "../" attempts at path traversal. Then we remove the
|
|
// leading /, and we end up with a path we can filepath.Join or
|
|
// fetch from asset data.
|
|
path := filepath.Clean("/" + r.URL.Path[len(assetsPath):])[1:]
|
|
t, err := s.getTemplate(path)
|
|
if err != nil {
|
|
s.log("UI", "Failed to parse template for %q: %s", path, err)
|
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
var b bytes.Buffer
|
|
s.eventsMu.Lock()
|
|
defer s.eventsMu.Unlock()
|
|
if err = t.Execute(&b, s.events); err != nil {
|
|
s.log("UI", "Failed to expand template for %q: %s", path, err)
|
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
mimetype := mime.TypeByExtension(filepath.Ext(path))
|
|
if mimetype != "" {
|
|
w.Header().Set("Content-Type", mimetype)
|
|
}
|
|
|
|
b.WriteTo(w)
|
|
}
|
|
|
|
func (s *Server) getTemplate(name string) (*template.Template, error) {
|
|
var (
|
|
bs []byte
|
|
err error
|
|
)
|
|
if s.UIAssetsDir != "" {
|
|
bs, err = ioutil.ReadFile(filepath.Join(s.UIAssetsDir, name))
|
|
} else {
|
|
bs, err = ui.Asset(name)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
funcs := template.FuncMap{
|
|
"dec": func(i int) int {
|
|
return i - 1
|
|
},
|
|
"timestamp_millis": func(t time.Time) int64 {
|
|
return t.UnixNano() / int64(time.Millisecond)
|
|
},
|
|
}
|
|
return template.New(name).Funcs(funcs).Parse(string(bs))
|
|
}
|