yao/openapi/tai/proxy.go
Max c4dbcdba2b feat(openapi): integrate Tai forward handlers for proxy and VNC operations
- Replaced direct tunnel handling with a dedicated Tai integration for managing proxy and VNC requests.
- Updated routing to streamline the attachment of Tai handlers, enhancing modularity and maintainability.

Made-with: Cursor
2026-03-14 16:23:24 +08:00

60 lines
1.5 KiB
Go

package tai
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
yaoTai "github.com/yaoapp/yao/tai"
)
// handleLocalProxy resolves the container's HTTP address via Docker socket
// and reverse-proxies the request.
func handleLocalProxy(c *gin.Context, taiID string) {
res, ok := yaoTai.GetResources(taiID)
if !ok || res.Proxy == nil {
c.JSON(http.StatusBadGateway, gin.H{"error": "proxy not available for node " + taiID})
return
}
// path format: /{containerID}:{port}/{rest...}
raw := strings.TrimPrefix(c.Param("path"), "/")
colonIdx := strings.Index(raw, ":")
if colonIdx < 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid proxy path, expected /{containerID}:{port}/{path}"})
return
}
containerID := raw[:colonIdx]
rest := raw[colonIdx+1:]
slashIdx := strings.Index(rest, "/")
var portStr, subPath string
if slashIdx >= 0 {
portStr = rest[:slashIdx]
subPath = rest[slashIdx:]
} else {
portStr = rest
subPath = "/"
}
var port int
for _, ch := range portStr {
if ch < '0' || ch > '9' {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid port in proxy path"})
return
}
port = port*10 + int(ch-'0')
}
if port == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "missing port in proxy path"})
return
}
targetURL, err := res.Proxy.URL(c.Request.Context(), containerID, port, subPath)
if err != nil {
c.JSON(http.StatusBadGateway, gin.H{"error": "resolve proxy target: " + err.Error()})
return
}
reverseProxy(c, targetURL)
}