fix various endpoints

This commit is contained in:
yusing 2025-02-13 15:05:16 +08:00
parent 02d1c9ce98
commit decd2c2ded
9 changed files with 39 additions and 51 deletions

View file

@ -50,6 +50,7 @@ const (
) )
var ( var (
AgentURL = types.MustParseURL(APIBaseURL)
HTTPProxyURL = types.MustParseURL(APIBaseURL + EndpointProxyHTTP) HTTPProxyURL = types.MustParseURL(APIBaseURL + EndpointProxyHTTP)
HTTPProxyURLPrefixLen = len(APIEndpointBase + EndpointProxyHTTP) HTTPProxyURLPrefixLen = len(APIEndpointBase + EndpointProxyHTTP)
) )

View file

@ -21,6 +21,7 @@ func (cfg *AgentConfig) Forward(req *http.Request, endpoint string) ([]byte, int
req.URL.Host = AgentHost req.URL.Host = AgentHost
req.URL.Scheme = "https" req.URL.Scheme = "https"
req.URL.Path = APIEndpointBase + endpoint req.URL.Path = APIEndpointBase + endpoint
req.RequestURI = ""
resp, err := cfg.httpClient.Do(req) resp, err := cfg.httpClient.Do(req)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err

View file

@ -3,27 +3,27 @@ package v1
import ( import (
"net/http" "net/http"
"github.com/coder/websocket/wsjson"
agentPkg "github.com/yusing/go-proxy/agent/pkg/agent" agentPkg "github.com/yusing/go-proxy/agent/pkg/agent"
U "github.com/yusing/go-proxy/internal/api/v1/utils" U "github.com/yusing/go-proxy/internal/api/v1/utils"
config "github.com/yusing/go-proxy/internal/config/types" config "github.com/yusing/go-proxy/internal/config/types"
E "github.com/yusing/go-proxy/internal/error" E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/metrics/systeminfo" "github.com/yusing/go-proxy/internal/metrics/systeminfo"
"github.com/yusing/go-proxy/internal/net/http/httpheaders" "github.com/yusing/go-proxy/internal/net/http/httpheaders"
"github.com/yusing/go-proxy/internal/net/http/reverseproxy"
) )
func SystemInfo(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) { func SystemInfo(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
query := r.URL.Query() query := r.URL.Query()
agentName := query.Get("agent_name") agentAddr := query.Get("agent_addr")
query.Del("agent_name") query.Del("agent_addr")
if agentName == "" { if agentAddr == "" {
systeminfo.Poller.ServeHTTP(w, r) systeminfo.Poller.ServeHTTP(w, r)
return return
} }
agent, ok := cfg.GetAgent(agentName) agent, ok := cfg.GetAgent(agentAddr)
if !ok { if !ok {
U.HandleErr(w, r, U.ErrInvalidKey("agent_name"), http.StatusNotFound) U.HandleErr(w, r, U.ErrInvalidKey("agent_addr"), http.StatusNotFound)
return return
} }
@ -40,35 +40,14 @@ func SystemInfo(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Reques
} }
U.WriteBody(w, respData) U.WriteBody(w, respData)
} else { } else {
r = r.WithContext(r.Context()) rp := reverseproxy.NewReverseProxy("agent", agentPkg.AgentURL, agent.Transport())
clientConn, err := U.InitiateWS(w, r) header := r.Header.Clone()
r, err := http.NewRequestWithContext(r.Context(), r.Method, agentPkg.EndpointSystemInfo+"?"+query.Encode(), nil)
if err != nil { if err != nil {
U.HandleErr(w, r, E.Wrap(err, "failed to initiate websocket")) U.HandleErr(w, r, E.Wrap(err, "failed to create request"))
return return
} }
defer clientConn.CloseNow() r.Header = header
agentConn, _, err := agent.Websocket(r.Context(), agentPkg.EndpointSystemInfo+"?"+query.Encode()) rp.ServeHTTP(w, r)
if err != nil {
U.HandleErr(w, r, E.Wrap(err, "failed to connect to agent with websocket"))
return
}
//nolint:errcheck
defer agentConn.CloseNow()
var data []byte
for {
select {
case <-r.Context().Done():
return
default:
err := wsjson.Read(r.Context(), agentConn, &data)
if err == nil {
err = wsjson.Write(r.Context(), clientConn, data)
}
if err != nil {
U.HandleErr(w, r, E.Wrap(err, "failed to write data to client"))
return
}
}
}
} }
} }

View file

@ -8,6 +8,7 @@ import (
"syscall" "syscall"
E "github.com/yusing/go-proxy/internal/error" E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/net/http/httpheaders"
"github.com/yusing/go-proxy/internal/utils/strutils/ansi" "github.com/yusing/go-proxy/internal/utils/strutils/ansi"
) )
@ -25,7 +26,7 @@ func HandleErr(w http.ResponseWriter, r *http.Request, err error, code ...int) {
return return
} }
LogError(r).Msg(err.Error()) LogError(r).Msg(err.Error())
if r.Header.Get("Upgrade") == "websocket" { if httpheaders.IsWebsocket(r.Header) {
return return
} }
if len(code) == 0 { if len(code) == 0 {

View file

@ -1,8 +1,6 @@
package config package config
import ( import (
"errors"
"github.com/yusing/go-proxy/agent/pkg/agent" "github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal/utils/functional" "github.com/yusing/go-proxy/internal/utils/functional"
) )
@ -22,11 +20,11 @@ func GetAgent(addr string) (agent *agent.AgentConfig, ok bool) {
return return
} }
func (cfg *Config) GetAgent(agentDockerHost string) (*agent.AgentConfig, bool) { func (cfg *Config) GetAgent(agentAddrOrDockerHost string) (*agent.AgentConfig, bool) {
if !agent.IsDockerHostAgent(agentDockerHost) { if !agent.IsDockerHostAgent(agentAddrOrDockerHost) {
panic(errors.New("invalid use of GetAgent with docker host: " + agentDockerHost)) return GetAgent(agentAddrOrDockerHost)
} }
return GetAgent(agent.GetAgentAddrFromDockerHost(agentDockerHost)) return GetAgent(agent.GetAgentAddrFromDockerHost(agentAddrOrDockerHost))
} }
func (cfg *Config) ListAgents() []*agent.AgentConfig { func (cfg *Config) ListAgents() []*agent.AgentConfig {

View file

@ -41,7 +41,7 @@ type (
Statistics() map[string]any Statistics() map[string]any
RouteProviderList() []string RouteProviderList() []string
Context() context.Context Context() context.Context
GetAgent(agentDockerHost string) (*agent.AgentConfig, bool) GetAgent(agentAddrOrDockerHost string) (*agent.AgentConfig, bool)
ListAgents() []*agent.AgentConfig ListAgents() []*agent.AgentConfig
} }
) )

View file

@ -25,6 +25,8 @@ import (
// If the request is a websocket request, it serves the data for the given period for every interval. // If the request is a websocket request, it serves the data for the given period for every interval.
func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query() query := r.URL.Query()
if httpheaders.IsWebsocket(r.Header) {
interval := metricsutils.QueryDuration(query, "interval", 0) interval := metricsutils.QueryDuration(query, "interval", 0)
minInterval := 1 * time.Second minInterval := 1 * time.Second
@ -34,8 +36,6 @@ func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request
if interval < minInterval { if interval < minInterval {
interval = minInterval interval = minInterval
} }
if httpheaders.IsWebsocket(r.Header) {
utils.PeriodicWS(w, r, interval, func(conn *websocket.Conn) error { utils.PeriodicWS(w, r, interval, func(conn *websocket.Conn) error {
data, err := p.getRespData(r) data, err := p.getRespData(r)
if err != nil { if err != nil {

View file

@ -0,0 +1,7 @@
package httpheaders
import "net/http"
func IsSSE(h http.Header) bool {
return h.Get("Content-Type") == "text/event-stream"
}

View file

@ -45,12 +45,13 @@ func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, E.Error) {
httpConfig := base.HTTPConfig httpConfig := base.HTTPConfig
proxyURL := base.ProxyURL proxyURL := base.ProxyURL
trans := gphttp.NewTransport() var trans *http.Transport
a := base.Agent() a := base.Agent()
if a != nil { if a != nil {
trans = a.Transport() trans = a.Transport()
proxyURL = agent.HTTPProxyURL proxyURL = agent.HTTPProxyURL
} else { } else {
trans = gphttp.NewTransport()
if httpConfig.NoTLSVerify { if httpConfig.NoTLSVerify {
trans.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} trans.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
} }