5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-05 02:40:32 +08:00
wails/v3/internal/assetserver/assethandler_external.go
2023-08-14 08:31:55 +10:00

80 lines
1.7 KiB
Go

//go:build dev
// +build dev
package assetserver
import (
"errors"
"fmt"
"log/slog"
"net/http"
"net/http/httputil"
"net/url"
)
func NewExternalAssetsHandler(logger *slog.Logger, options Options, url *url.URL) http.Handler {
baseHandler := options.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 baseHandler == 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 baseHandler != nil && errors.Is(err, errSkipProxy) {
if logger != nil {
logger.Debug("[ExternalAssetHandler] Loading '%s' failed, using original AssetHandler", r.URL)
}
baseHandler.ServeHTTP(rw, r)
} else {
if logger != nil {
logger.Error("[ExternalAssetHandler] Proxy error: %v", err)
}
rw.WriteHeader(http.StatusBadGateway)
}
}
var result http.Handler = http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodGet {
proxy.ServeHTTP(rw, req)
return
}
if baseHandler != nil {
baseHandler.ServeHTTP(rw, req)
return
}
rw.WriteHeader(http.StatusMethodNotAllowed)
})
if middleware := options.Middleware; middleware != nil {
result = middleware(result)
}
return result
}