Add ability to enable static file serving
This commit is contained in:
parent
2f631f055a
commit
b48010730b
@ -2,12 +2,14 @@ package monolith
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/webapp"
|
||||
"github.com/go-chi/chi"
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/compose"
|
||||
"github.com/cortezaproject/corteza-server/corteza"
|
||||
@ -20,6 +22,7 @@ import (
|
||||
|
||||
type (
|
||||
App struct {
|
||||
Opts *app.Options
|
||||
Core *corteza.App
|
||||
System *system.App
|
||||
Compose *compose.App
|
||||
@ -28,12 +31,16 @@ type (
|
||||
)
|
||||
|
||||
func (monolith *App) Setup(log *zap.Logger, opts *app.Options) (err error) {
|
||||
|
||||
monolith.Opts = opts
|
||||
// Make sure system behaves properly
|
||||
//
|
||||
// This will alter the auth settings provision procedure
|
||||
system.IsMonolith = true
|
||||
|
||||
if err = monolith.CheckOptions(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = app.RunSetup(
|
||||
log,
|
||||
opts,
|
||||
@ -49,6 +56,15 @@ func (monolith *App) Setup(log *zap.Logger, opts *app.Options) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (monolith *App) CheckOptions() error {
|
||||
o := monolith.Opts.HTTPServer
|
||||
if o.ApiEnabled && o.WebappEnabled && o.ApiBaseUrl == o.WebappBaseUrl {
|
||||
return errors.Errorf("cannot serve api and web apps form the same base url (%v)", o.ApiBaseUrl)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (monolith *App) Upgrade(ctx context.Context) (err error) {
|
||||
return app.RunUpgrade(
|
||||
ctx,
|
||||
@ -101,17 +117,33 @@ func (monolith *App) Provision(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
func (monolith *App) MountApiRoutes(r chi.Router) {
|
||||
r.Route("/system", func(r chi.Router) {
|
||||
monolith.System.MountApiRoutes(r)
|
||||
})
|
||||
var (
|
||||
apiEnabled = monolith.Opts.HTTPServer.ApiEnabled
|
||||
apiBaseUrl = strings.Trim(monolith.Opts.HTTPServer.ApiBaseUrl, "/")
|
||||
|
||||
r.Route("/compose", func(r chi.Router) {
|
||||
monolith.Compose.MountApiRoutes(r)
|
||||
})
|
||||
webappEnabled = monolith.Opts.HTTPServer.WebappEnabled
|
||||
webappBaseUrl = strings.Trim(monolith.Opts.HTTPServer.WebappBaseUrl, "/")
|
||||
)
|
||||
|
||||
r.Route("/messaging", func(r chi.Router) {
|
||||
monolith.Messaging.MountApiRoutes(r)
|
||||
})
|
||||
if apiEnabled {
|
||||
r.Route("/"+apiBaseUrl, func(r chi.Router) {
|
||||
r.Route("/system", func(r chi.Router) {
|
||||
monolith.System.MountApiRoutes(r)
|
||||
})
|
||||
|
||||
r.Route("/compose", func(r chi.Router) {
|
||||
monolith.Compose.MountApiRoutes(r)
|
||||
})
|
||||
|
||||
r.Route("/messaging", func(r chi.Router) {
|
||||
monolith.Messaging.MountApiRoutes(r)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if webappEnabled {
|
||||
r.Route("/"+webappBaseUrl, webapp.MakeWebappServer(monolith.Opts.HTTPServer))
|
||||
}
|
||||
}
|
||||
|
||||
func (monolith *App) RegisterGrpcServices(srv *grpc.Server) {
|
||||
|
||||
@ -20,6 +20,14 @@ type (
|
||||
MetricsPassword string `env:"HTTP_METRICS_PASSWORD"`
|
||||
|
||||
EnablePanicReporting bool `env:"HTTP_REPORT_PANIC"`
|
||||
|
||||
ApiEnabled bool `env:"HTTP_API_ENABLED"`
|
||||
ApiBaseUrl string `env:"HTTP_API_BASE_URL"`
|
||||
|
||||
WebappEnabled bool `env:"HTTP_WEBAPP_ENABLED"`
|
||||
WebappBaseUrl string `env:"HTTP_WEBAPP_BASE_URL"`
|
||||
WebappBaseDir string `env:"HTTP_WEBAPP_BASE_DIR"`
|
||||
WebappList string `env:"HTTP_WEBAPP_LIST"`
|
||||
}
|
||||
)
|
||||
|
||||
@ -35,11 +43,19 @@ func HTTP(pfix string) (o *HTTPServerOpt) {
|
||||
MetricsServiceLabel: "corteza",
|
||||
MetricsUsername: "metrics",
|
||||
|
||||
// Reports panics to Sentry throught HTTP middleware
|
||||
// Reports panics to Sentry through HTTP middleware
|
||||
EnablePanicReporting: true,
|
||||
|
||||
// Setting metrics password to random string to prevent security accidents...
|
||||
MetricsPassword: string(rand.Bytes(5)),
|
||||
|
||||
ApiEnabled: true,
|
||||
ApiBaseUrl: "",
|
||||
|
||||
WebappEnabled: false,
|
||||
WebappBaseUrl: "/",
|
||||
WebappBaseDir: "/webapp",
|
||||
WebappList: "admin,auth,messaging,compose",
|
||||
}
|
||||
|
||||
fill(o, pfix)
|
||||
|
||||
@ -235,6 +235,7 @@ func (r *runner) serve(ctx context.Context) (err error) {
|
||||
if err = r.Provision(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.setupHttpApi()
|
||||
r.setupGRPCServices()
|
||||
|
||||
|
||||
51
pkg/webapp/serve.go
Normal file
51
pkg/webapp/serve.go
Normal file
@ -0,0 +1,51 @@
|
||||
package webapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/app/options"
|
||||
"github.com/go-chi/chi"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func MakeWebappServer(opt options.HTTPServerOpt) func(r chi.Router) {
|
||||
// Serves static files directly from FS
|
||||
return func(r chi.Router) {
|
||||
fileserver := http.FileServer(http.Dir(opt.WebappBaseDir))
|
||||
|
||||
for _, app := range strings.Split(opt.WebappList, ",") {
|
||||
basedir := path.Join(opt.WebappBaseUrl, app)
|
||||
serveConfig(r, basedir, opt.ApiBaseUrl)
|
||||
r.Get(basedir+"*", serveIndex(opt.WebappBaseDir, basedir+"/index.html", fileserver))
|
||||
}
|
||||
|
||||
serveConfig(r, opt.WebappBaseUrl, opt.ApiBaseUrl)
|
||||
r.Get(opt.WebappBaseUrl+"*", serveIndex(opt.WebappBaseDir, opt.WebappBaseUrl+"/index.html", fileserver))
|
||||
}
|
||||
}
|
||||
|
||||
// Serves index.html in case the requested file isn't found (or some other os.Stat error)
|
||||
func serveIndex(assetPath string, indexPath string, serve http.Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
indexPage := path.Join(assetPath, indexPath)
|
||||
requestedPage := path.Join(assetPath, r.URL.Path)
|
||||
_, err := os.Stat(requestedPage)
|
||||
|
||||
if err != nil {
|
||||
http.ServeFile(w, r, indexPage)
|
||||
return
|
||||
}
|
||||
serve.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func serveConfig(r chi.Router, appUrl, apiBaseUrl string) {
|
||||
r.Get(strings.TrimRight(appUrl, "/")+"/config.js", func(w http.ResponseWriter, r *http.Request) {
|
||||
const line = "window.%sAPI = '%s/%s';\n"
|
||||
_, _ = fmt.Fprintf(w, line, "System", apiBaseUrl, "system")
|
||||
_, _ = fmt.Fprintf(w, line, "Messaging", apiBaseUrl, "messaging")
|
||||
_, _ = fmt.Fprintf(w, line, "Compose", apiBaseUrl, "compose")
|
||||
})
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user