edge/pkg/http/handler.go

131 lines
2.8 KiB
Go
Raw Permalink Normal View History

2023-02-09 12:16:36 +01:00
package http
import (
"context"
"io"
2023-02-09 12:16:36 +01:00
"net/http"
"sync"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bundle"
"forge.cadoles.com/arcad/edge/pkg/bus"
"github.com/go-chi/chi/v5"
"github.com/igm/sockjs-go/v3/sockjs"
"github.com/pkg/errors"
)
const (
sockJSPathPrefix = "/edge/sock"
serverMainScript = "server/main.js"
)
type Handler struct {
bundle bundle.Bundle
public http.Handler
router chi.Router
sockjs http.Handler
bus bus.Bus
sockjsOpts sockjs.Options
uploadMaxFileSize int64
server *app.Server
serverModuleFactories []app.ServerModuleFactory
2023-04-02 17:59:33 +02:00
httpClient *http.Client
2023-02-09 12:16:36 +01:00
mutex sync.RWMutex
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.router.ServeHTTP(w, r)
}
func (h *Handler) Load(ctx context.Context, bdle bundle.Bundle) error {
2023-02-09 12:16:36 +01:00
h.mutex.Lock()
defer h.mutex.Unlock()
file, _, err := bdle.File(serverMainScript)
if err != nil {
return errors.Wrap(err, "could not open server main script")
}
mainScript, err := io.ReadAll(file)
2023-02-09 12:16:36 +01:00
if err != nil {
return errors.Wrap(err, "could not read server main script")
}
server := app.NewServer(h.serverModuleFactories...)
if err := server.Load(serverMainScript, string(mainScript)); err != nil {
return errors.WithStack(err)
}
fs := bundle.NewFileSystem("public", bdle)
public := HTML5Fileserver(fs)
2023-02-09 12:16:36 +01:00
sockjs := sockjs.NewHandler(sockJSPathPrefix, h.sockjsOpts, h.handleSockJSSession)
if h.server != nil {
h.server.Stop()
}
if err := server.Start(ctx); err != nil {
2023-02-09 12:16:36 +01:00
return errors.WithStack(err)
}
h.bundle = bdle
h.server = server
h.public = public
h.sockjs = sockjs
return nil
}
func NewHandler(funcs ...HandlerOptionFunc) *Handler {
opts := defaultHandlerOptions()
for _, fn := range funcs {
fn(opts)
}
router := chi.NewRouter()
handler := &Handler{
uploadMaxFileSize: opts.UploadMaxFileSize,
sockjsOpts: opts.SockJS,
router: router,
serverModuleFactories: opts.ServerModuleFactories,
2023-04-02 17:59:33 +02:00
httpClient: opts.HTTPClient,
2023-02-09 12:16:36 +01:00
bus: opts.Bus,
}
for _, middleware := range opts.HTTPMiddlewares {
router.Use(middleware)
}
2023-02-09 12:16:36 +01:00
router.Route("/edge", func(r chi.Router) {
r.Route("/sdk", func(r chi.Router) {
r.Get("/client.js", handler.handleSDKClient)
r.Get("/client.js.map", handler.handleSDKClientMap)
})
r.Route("/api", func(r chi.Router) {
r.Post("/v1/upload", handler.handleAppUpload)
r.Get("/v1/download/{bucket}/{blobID}", handler.handleAppDownload)
2023-04-02 17:59:33 +02:00
r.Get("/v1/fetch", handler.handleAppFetch)
2023-02-09 12:16:36 +01:00
})
for _, fn := range opts.HTTPMounts {
r.Group(func(r chi.Router) {
fn(r)
})
}
2023-02-09 12:16:36 +01:00
r.HandleFunc("/sock/*", handler.handleSockJS)
})
router.Get("/*", handler.handleAppFiles)
return handler
}