依据 coord-final-decisions §3.8 W1-W8 裁决与 president-final-rulings §2.15/§2.16/§2.19 完整实现网关硬化: - W1/W2: 错误码 GW_ 前缀 + ActionState 信封响应体 - W3: 全量替换为 log/slog 结构化日志 - W4: /readyz 并行 ping 9 下游 + 软失败规则 - W5: 7 个业务 Prometheus 指标 + /metrics 端点 - W6: tracer 资源属性补全(name/version/env/host) - W7: DevMode=true && ENV=production panic 防护 - W8: 保持共享 downstream 熔断 P2 RS256 升级:接入 shared-go/jwks.Fetcher(TTL 5min)。 P2.7+P3-P5 路由扩展:student/parent/messages/dashboard。 文档同步:README/01/02/known-issues,arch.db 已更新。 质量校验:go vet + build + test 均通过。
35 lines
824 B
Go
35 lines
824 B
Go
package proxy
|
||
|
||
import (
|
||
"net/http"
|
||
"net/http/httputil"
|
||
"net/url"
|
||
"strings"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// NewProxy 创建反向代理
|
||
func NewProxy(targetURL string) (*httputil.ReverseProxy, error) {
|
||
target, err := url.Parse(targetURL)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
proxy := httputil.NewSingleHostReverseProxy(target)
|
||
originalDirector := proxy.Director
|
||
proxy.Director = func(req *http.Request) {
|
||
originalDirector(req)
|
||
// 去除 /api/v1 前缀(Gateway 不改路径,直接透传给下游服务根路径)
|
||
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/api/v1")
|
||
req.Host = target.Host
|
||
}
|
||
return proxy, nil
|
||
}
|
||
|
||
// ProxyHandler 返回 Gin 处理函数
|
||
func ProxyHandler(proxy *httputil.ReverseProxy) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
proxy.ServeHTTP(c.Writer, c.Request)
|
||
}
|
||
}
|