Browse Source

Add EnableFrontendProxy function.

ZRY 1 month ago
parent
commit
6b5e996152
4 changed files with 63 additions and 1 deletions
  1. 50 0
      websubsvc/frontend_proxy.go
  2. 1 0
      websubsvc/go.mod
  3. 2 0
      websubsvc/go.sum
  4. 10 1
      websubsvc/webctx.go

+ 50 - 0
websubsvc/frontend_proxy.go

@@ -0,0 +1,50 @@
+package websubsvc
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/yhat/wsutil"
+	"net/http/httputil"
+	"net/url"
+)
+
+type FrontendProxy struct {
+	debugRedirectNotFoundURLhttp *url.URL
+	debugRedirectNotFoundURLws   *url.URL
+}
+
+func NewFrontendProxy(proxyURL string) (*FrontendProxy, error) {
+	rurl, err := url.Parse(proxyURL)
+	if err != nil {
+		return nil, fmt.Errorf("invalid proxy url: %w", err)
+	}
+	rurl4ws, err := url.Parse(proxyURL)
+	if err != nil {
+		return nil, fmt.Errorf("invalid proxy url: %w", err)
+	}
+	if rurl4ws.Scheme == "https" {
+		rurl4ws.Scheme = "wss"
+	} else {
+		rurl4ws.Scheme = "ws"
+	}
+	return &FrontendProxy{
+		debugRedirectNotFoundURLhttp: rurl,
+		debugRedirectNotFoundURLws:   rurl4ws,
+	}, nil
+}
+
+func (p *FrontendProxy) RedirectNotFoundHandler(context *gin.Context) {
+	if context.IsWebsocket() {
+		if p.debugRedirectNotFoundURLws == nil {
+			return
+		}
+		proxy := wsutil.NewSingleHostReverseProxy(p.debugRedirectNotFoundURLws)
+		proxy.ServeHTTP(context.Writer, context.Request)
+	} else {
+		if p.debugRedirectNotFoundURLhttp == nil {
+			return
+		}
+		proxy := httputil.NewSingleHostReverseProxy(p.debugRedirectNotFoundURLhttp)
+		proxy.ServeHTTP(context.Writer, context.Request)
+	}
+}

+ 1 - 0
websubsvc/go.mod

@@ -5,6 +5,7 @@ go 1.20
 require (
 	git.swzry.com/zry/zry-go-program-framework/core v0.0.0-20230909163811-a6d54dcab998
 	github.com/gin-gonic/gin v1.9.1
+	github.com/yhat/wsutil v0.0.0-20170731153501-1d66fa95c997
 )
 
 require (

+ 2 - 0
websubsvc/go.sum

@@ -61,6 +61,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
 github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/yhat/wsutil v0.0.0-20170731153501-1d66fa95c997 h1:1+FQ4Ns+UZtUiQ4lP0sTCyKSQ0EXoiwAdHZB0Pd5t9Q=
+github.com/yhat/wsutil v0.0.0-20170731153501-1d66fa95c997/go.mod h1:DIGbh/f5XMAessMV/uaIik81gkDVjUeQ9ApdaU7wRKE=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
 golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=

+ 10 - 1
websubsvc/webctx.go

@@ -167,7 +167,7 @@ func (c *WebSubServiceContext) EnableRecovery(recoveryLogPrefix string) {
 				}
 				if brokenPipe {
 					// If the connection is dead, we can't write a status to it.
-					c.Error(err.(error)) //nolint: errcheck
+					_ = c.Error(err.(error)) //nolint: errcheck
 					c.Abort()
 				} else {
 					c.AbortWithStatus(http.StatusInternalServerError)
@@ -187,3 +187,12 @@ func (c *WebSubServiceContext) EnableFrontend(fs IFilesystem, useVueHistoryMode
 	c.s.ginEngine.NoRoute(fu.StaticFilesHandler)
 	return fu
 }
+
+func (c *WebSubServiceContext) EnableFrontendProxy(proxyURL string) error {
+	proxy, err := NewFrontendProxy(proxyURL)
+	if err != nil {
+		return err
+	}
+	c.s.ginEngine.NoRoute(proxy.RedirectNotFoundHandler)
+	return nil
+}