Files
曾志威 5b6cb3e2bf feat: 完善多账号网关、运维监控与配置管理
新增 HTTP/HTTPS 与 SQL Server 支持,完善账号映射、凭据生命周期、角色和 API Token 隔离。实现健康检查、告警、配置导入导出、模板与历史差异,并补充管理界面、回归测试和运维文档。
2026-09-12 22:19:10 +08:00

61 lines
1.4 KiB
Go

package api
import (
"encoding/json"
"io"
"net"
"net/http"
)
func source(r *http.Request) string {
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return r.RemoteAddr
}
return host
}
func decode(w http.ResponseWriter, r *http.Request, v any) bool {
return decodeLimit(w, r, v, 1<<20)
}
func decodeLimit(w http.ResponseWriter, r *http.Request, v any, limit int64) bool {
r.Body = http.MaxBytesReader(w, r.Body, limit)
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(v); err != nil {
fail(w, 400, "invalid JSON body")
return false
}
var extra any
if err := d.Decode(&extra); err != io.EOF {
fail(w, 400, "expected one JSON object")
return false
}
return true
}
func respond(w http.ResponseWriter, status int, v any) {
if _, restricted := w.(tokenResponseWriter); restricted {
raw, err := json.Marshal(v)
if err != nil {
http.Error(w, "response encoding failed", 500)
return
}
var value any
if err = json.Unmarshal(raw, &value); err != nil {
http.Error(w, "response encoding failed", 500)
return
}
redactTokenResponse(value)
v = value
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(status)
_ = json.NewEncoder(w).Encode(v)
}
func fail(w http.ResponseWriter, status int, message string) {
respond(w, status, map[string]string{"error": message})
}