96 lines
2.5 KiB
Go
96 lines
2.5 KiB
Go
// Copyright 2019 Sorint.lab
|
|
//
|
|
// 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 handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"agola.io/agola/webbundle"
|
|
|
|
assetfs "github.com/elazarl/go-bindata-assetfs"
|
|
)
|
|
|
|
// TODO(sgotti) now the test web ui directly calls the run api url, but this is
|
|
// temporary and all requests should pass from the gateway
|
|
|
|
const configTplText = `
|
|
const CONFIG = {
|
|
API_URL: '{{.ApiURL}}',
|
|
API_BASE_PATH: '{{.ApiBasePath}}',
|
|
}
|
|
|
|
window.CONFIG = CONFIG
|
|
`
|
|
|
|
func NewWebBundleHandlerFunc(gatewayURL string) func(w http.ResponseWriter, r *http.Request) {
|
|
var buf bytes.Buffer
|
|
configTpl, err := template.New("config").Parse(configTplText)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
configTplData := struct {
|
|
ApiURL string
|
|
ApiBasePath string
|
|
}{
|
|
gatewayURL,
|
|
"/api/v1alpha",
|
|
}
|
|
configTpl.Execute(&buf, configTplData)
|
|
|
|
config := buf.Bytes()
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
// Setup serving of bundled webapp from the root path, registered after api
|
|
// handlers or it'll match all the requested paths
|
|
fileServerHandler := http.FileServer(&assetfs.AssetFS{
|
|
Asset: webbundle.Asset,
|
|
AssetDir: webbundle.AssetDir,
|
|
AssetInfo: webbundle.AssetInfo,
|
|
})
|
|
|
|
// config.js is the external webapp config file not provided by the
|
|
// asset and not needed when served from the api server
|
|
if r.URL.Path == "/config.js" {
|
|
_, err := w.Write(config)
|
|
if err != nil {
|
|
http.Error(w, "", http.StatusInternalServerError)
|
|
}
|
|
return
|
|
}
|
|
|
|
// check if the required file is available in the webapp asset and serve it
|
|
if _, err := webbundle.Asset(r.URL.Path[1:]); err == nil {
|
|
fileServerHandler.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// skip /api requests
|
|
if strings.HasPrefix(r.URL.Path, "/api/") {
|
|
http.Error(w, "", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
// Fallback to index.html for every other page. Required for the SPA since
|
|
// on browser reload it'll ask the current app url but we have to
|
|
// provide the index.html
|
|
r.URL.Path = "/"
|
|
fileServerHandler.ServeHTTP(w, r)
|
|
}
|
|
}
|