modify proxy handler

This commit is contained in:
2025-11-17 12:21:35 +08:00
parent 760e4a9b03
commit abfa51f12e
19 changed files with 755 additions and 52 deletions

View File

@@ -1,46 +1,84 @@
package proxy
import (
"fmt"
"strings"
"sync"
"github.com/gofiber/fiber/v3"
"github.com/sirupsen/logrus"
"github.com/any-hub/any-hub/internal/logging"
"github.com/any-hub/any-hub/internal/server"
)
// Forwarder 根据 HubRoute 的 module_key 选择对应的 ProxyHandler默认回退到构造时注入的 handler。
type Forwarder struct {
defaultHandler server.ProxyHandler
logger *logrus.Logger
}
// NewForwarder 创建 ForwarderdefaultHandler 不能为空。
func NewForwarder(defaultHandler server.ProxyHandler) *Forwarder {
return &Forwarder{defaultHandler: defaultHandler}
func NewForwarder(defaultHandler server.ProxyHandler, logger *logrus.Logger) *Forwarder {
return &Forwarder{
defaultHandler: defaultHandler,
logger: logger,
}
}
var (
moduleHandlers sync.Map
)
// RegisterModuleHandler 将特定 module_key 映射到 ProxyHandler重复注册会覆盖旧值。
// RegisterModuleHandler is kept for backward compatibility; it panics on invalid input.
func RegisterModuleHandler(key string, handler server.ProxyHandler) {
normalized := normalizeModuleKey(key)
if normalized == "" || handler == nil {
return
}
moduleHandlers.Store(normalized, handler)
MustRegisterModule(ModuleRegistration{Key: key, Handler: handler})
}
// Handle 实现 server.ProxyHandler根据 route.ModuleKey 选择 handler。
func (f *Forwarder) Handle(c fiber.Ctx, route *server.HubRoute) error {
handler := f.lookup(route)
if handler == nil {
return fiber.NewError(fiber.StatusInternalServerError, "proxy handler unavailable")
return f.respondMissingHandler(c, route)
}
return f.invokeHandler(c, route, handler)
}
func (f *Forwarder) respondMissingHandler(c fiber.Ctx, route *server.HubRoute) error {
f.logModuleError(route, "module_handler_missing", nil)
return c.Status(fiber.StatusInternalServerError).
JSON(fiber.Map{"error": "module_handler_missing"})
}
func (f *Forwarder) invokeHandler(c fiber.Ctx, route *server.HubRoute, handler server.ProxyHandler) (err error) {
defer func() {
if r := recover(); r != nil {
err = f.respondHandlerPanic(c, route, r)
}
}()
return handler.Handle(c, route)
}
func (f *Forwarder) respondHandlerPanic(c fiber.Ctx, route *server.HubRoute, recovered interface{}) error {
f.logModuleError(route, "module_handler_panic", fmt.Errorf("panic: %v", recovered))
return c.Status(fiber.StatusInternalServerError).
JSON(fiber.Map{"error": "module_handler_panic"})
}
func (f *Forwarder) logModuleError(route *server.HubRoute, code string, err error) {
if f.logger == nil {
return
}
fields := f.routeFields(route)
fields["action"] = "proxy"
fields["error"] = code
if err != nil {
f.logger.WithFields(fields).Error(err.Error())
return
}
f.logger.WithFields(fields).Error("module handler unavailable")
}
func (f *Forwarder) lookup(route *server.HubRoute) server.ProxyHandler {
if route != nil {
if handler := lookupModuleHandler(route.ModuleKey); handler != nil {
@@ -66,3 +104,26 @@ func lookupModuleHandler(key string) server.ProxyHandler {
func normalizeModuleKey(key string) string {
return strings.ToLower(strings.TrimSpace(key))
}
func (f *Forwarder) routeFields(route *server.HubRoute) logrus.Fields {
if route == nil {
return logrus.Fields{
"hub": "",
"domain": "",
"hub_type": "",
"auth_mode": "",
"cache_hit": false,
"module_key": "",
}
}
return logging.RequestFields(
route.Config.Name,
route.Config.Domain,
route.Config.Type,
route.Config.AuthMode(),
route.ModuleKey,
string(route.RolloutFlag),
false,
)
}