mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
[assetserver] Introduce middleware and extract options (#2016)
* [assetserver] Add support for HTTP Middlewares * [dev] Disable frontend DevServer if no Assets has been defined and inform user * [dev] Consistent WebSocket behaviour in dev and prod mode for assets handler and middleware In prod mode we can't support WebSockets so make sure the assets handler and middleware never see WebSockets in dev mode. * [templates] Migrate to new AssetServer option * [docs] Add assetserver.Options to the reference
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -53,7 +54,10 @@ func (d *DevWebServer) Run(ctx context.Context) error {
|
||||
d.server.GET("/wails/reload", d.handleReload)
|
||||
d.server.GET("/wails/ipc", d.handleIPCWebSocket)
|
||||
|
||||
assetServerConfig := assetserver.BuildAssetServerConfig(d.appoptions)
|
||||
|
||||
var assetHandler http.Handler
|
||||
var wsHandler http.Handler
|
||||
_fronendDevServerURL, _ := ctx.Value("frontenddevserverurl").(string)
|
||||
if _fronendDevServerURL == "" {
|
||||
assetdir, _ := ctx.Value("assetdir").(string)
|
||||
@@ -62,7 +66,7 @@ func (d *DevWebServer) Run(ctx context.Context) error {
|
||||
})
|
||||
|
||||
var err error
|
||||
assetHandler, err = assetserver.NewAssetHandler(ctx, d.appoptions.Assets, d.appoptions.AssetsHandler)
|
||||
assetHandler, err = assetserver.NewAssetHandler(ctx, assetServerConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -81,7 +85,11 @@ func (d *DevWebServer) Run(ctx context.Context) error {
|
||||
d.logger.Error("Timeout waiting for frontend DevServer")
|
||||
}
|
||||
|
||||
assetHandler = newExternalDevServerAssetHandler(d.logger, externalURL, d.appoptions.AssetsHandler)
|
||||
assetHandler = newExternalDevServerAssetHandler(d.logger, externalURL, assetServerConfig)
|
||||
// WebSockets aren't currently supported in prod mode, so a WebSocket connection is the result of the
|
||||
// FrontendDevServer e.g. Vite to support auto reloads.
|
||||
// Therefore we direct WebSockets directly to the FrontendDevServer instead of returning a NotImplementedStatus.
|
||||
wsHandler = httputil.NewSingleHostReverseProxy(externalURL)
|
||||
}
|
||||
|
||||
// Setup internal dev server
|
||||
@@ -90,7 +98,7 @@ func (d *DevWebServer) Run(ctx context.Context) error {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
assetServer, err := assetserver.NewBrowserAssetServer(ctx, assetHandler, bindingsJSON)
|
||||
assetServer, err := assetserver.NewDevAssetServer(ctx, assetHandler, wsHandler, bindingsJSON)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -10,11 +10,21 @@ import (
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
||||
)
|
||||
|
||||
func newExternalDevServerAssetHandler(logger *logger.Logger, url *url.URL, handler http.Handler) http.Handler {
|
||||
func newExternalDevServerAssetHandler(logger *logger.Logger, url *url.URL, options assetserver.Options) http.Handler {
|
||||
handler := newExternalAssetsHandler(logger, url, options.Handler)
|
||||
|
||||
if middleware := options.Middleware; middleware != nil {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
func newExternalAssetsHandler(logger *logger.Logger, url *url.URL, handler http.Handler) http.Handler {
|
||||
errSkipProxy := fmt.Errorf("skip proxying")
|
||||
|
||||
proxy := httputil.NewSingleHostReverseProxy(url)
|
||||
@@ -56,23 +66,18 @@ func newExternalDevServerAssetHandler(logger *logger.Logger, url *url.URL, handl
|
||||
}
|
||||
}
|
||||
|
||||
e := echo.New()
|
||||
e.Any("/*",
|
||||
func(c echo.Context) error {
|
||||
req := c.Request()
|
||||
rw := c.Response()
|
||||
if c.IsWebSocket() || req.Method == http.MethodGet {
|
||||
return http.HandlerFunc(
|
||||
func(rw http.ResponseWriter, req *http.Request) {
|
||||
if req.Method == http.MethodGet {
|
||||
proxy.ServeHTTP(rw, req)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
if handler != nil {
|
||||
handler.ServeHTTP(rw, req)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
return c.NoContent(http.StatusMethodNotAllowed)
|
||||
rw.WriteHeader(http.StatusMethodNotAllowed)
|
||||
})
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user