mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 06:01:52 +08:00

* [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
84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
//go:build dev
|
|
// +build dev
|
|
|
|
package devserver
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
|
|
"github.com/wailsapp/wails/v2/internal/logger"
|
|
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
|
)
|
|
|
|
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)
|
|
baseDirector := proxy.Director
|
|
proxy.Director = func(r *http.Request) {
|
|
baseDirector(r)
|
|
if logger != nil {
|
|
logger.Debug("[ExternalAssetHandler] Loading '%s'", r.URL)
|
|
}
|
|
}
|
|
|
|
proxy.ModifyResponse = func(res *http.Response) error {
|
|
if handler == nil {
|
|
return nil
|
|
}
|
|
|
|
if res.StatusCode == http.StatusSwitchingProtocols {
|
|
return nil
|
|
}
|
|
|
|
if res.StatusCode == http.StatusNotFound || res.StatusCode == http.StatusMethodNotAllowed {
|
|
return errSkipProxy
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
proxy.ErrorHandler = func(rw http.ResponseWriter, r *http.Request, err error) {
|
|
if handler != nil && errors.Is(err, errSkipProxy) {
|
|
if logger != nil {
|
|
logger.Debug("[ExternalAssetHandler] Loading '%s' failed, using AssetHandler", r.URL)
|
|
}
|
|
handler.ServeHTTP(rw, r)
|
|
} else {
|
|
if logger != nil {
|
|
logger.Error("[ExternalAssetHandler] Proxy error: %v", err)
|
|
}
|
|
rw.WriteHeader(http.StatusBadGateway)
|
|
}
|
|
}
|
|
|
|
return http.HandlerFunc(
|
|
func(rw http.ResponseWriter, req *http.Request) {
|
|
if req.Method == http.MethodGet {
|
|
proxy.ServeHTTP(rw, req)
|
|
return
|
|
}
|
|
|
|
if handler != nil {
|
|
handler.ServeHTTP(rw, req)
|
|
return
|
|
}
|
|
|
|
rw.WriteHeader(http.StatusMethodNotAllowed)
|
|
})
|
|
}
|