onesvm-browser-server/server/internal/gateway/v1handlers.go
chii eb972dfa93 feat: 落地 browser-server 控制面并打通 mgr1 海外订阅
单二进制三角色 + Dock 适配器 + Swarm stack 达到可部署态;mgr1 实测订阅经 central-proxy bootstrap,探活 alive=41/52。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 15:05:12 +08:00

62 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// v1handlers.go:HTTP 兜底面 /v1/search /v1/read(与 MCP tools/call 共用同一内核)。
package gateway
import (
"net/http"
"onesvm.com/onesvm/browser-server/internal/contract"
)
// handleV1Search POST /v1/search。
func (s *Server) handleV1Search(w http.ResponseWriter, r *http.Request, a *consumerAuth) {
var in contract.SearchInput
if err := jsonDecode(r, &in); err != nil {
s.writeErr(w, r, contract.CodeUnavailable, "请求体非法 JSON: "+err.Error(), http.StatusBadRequest, "", nil)
return
}
s.runAndRespond(w, r, a, runCtx{Intent: "search", Search: &in})
}
// handleV1Read POST /v1/read。
func (s *Server) handleV1Read(w http.ResponseWriter, r *http.Request, a *consumerAuth) {
var in contract.ReadInput
if err := jsonDecode(r, &in); err != nil {
s.writeErr(w, r, contract.CodeUnavailable, "请求体非法 JSON: "+err.Error(), http.StatusBadRequest, "", nil)
return
}
s.runAndRespond(w, r, a, runCtx{Intent: "read", Read: &in})
}
// runAndRespond 共用响应路径:管线 → 信封/错误输出。
func (s *Server) runAndRespond(w http.ResponseWriter, r *http.Request, a *consumerAuth, rc runCtx) {
rc.Auth = a
rc.W = w
rc.R = r
res := s.pipeline(rc)
switch {
case res.HTTPStatus != http.StatusOK && res.Body == nil:
// 前置错误(401/402/403/429/503)
w.Header().Set("Content-Type", "application/json")
if res.RetryAfterS != nil {
setRetryAfter(w, *res.RetryAfterS)
}
for k, v := range res.Headers {
w.Header().Set(k, v)
}
w.WriteHeader(res.HTTPStatus)
_, _ = w.Write(res.Body2)
case res.Body != nil:
// 完整信封(成功或 200 信封错误)
for k, v := range res.Headers {
w.Header().Set(k, v)
}
s.writeEnvelope(w, r, a, res.Body)
default:
s.writeErr(w, r, contract.CodeUpstream, "空管线结果", http.StatusInternalServerError, "", nil)
}
}
// setRetryAfter Retry-After 头。
func setRetryAfter(w http.ResponseWriter, secs int) {
w.Header().Set("Retry-After", itoa(secs))
}