实现手动 proxy 同步接口
This commit is contained in:
107
web/globals/gost_test.go
Normal file
107
web/globals/gost_test.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package globals
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGostClientChainOperations(t *testing.T) {
|
||||
var (
|
||||
created *GostChainConfig
|
||||
deleted []string
|
||||
saved bool
|
||||
)
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
username, password, ok := r.BasicAuth()
|
||||
if !ok || username != "user" || password != "pass" {
|
||||
t.Errorf("unexpected auth: ok=%v username=%q password=%q", ok, username, password)
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
switch {
|
||||
case r.Method == http.MethodGet && r.URL.Path == "/api/config/chains":
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"count": 2,
|
||||
"list": []map[string]any{
|
||||
{"name": "old-a"},
|
||||
{"name": "old-b"},
|
||||
},
|
||||
})
|
||||
case r.Method == http.MethodPost && r.URL.Path == "/api/config/chains":
|
||||
if err := json.NewDecoder(r.Body).Decode(&created); err != nil {
|
||||
t.Errorf("Decode chain failed: %v", err)
|
||||
http.Error(w, "bad request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
_, _ = w.Write([]byte(`{}`))
|
||||
case r.Method == http.MethodDelete && r.URL.Path == "/api/config/chains/old-a":
|
||||
deleted = append(deleted, "old-a")
|
||||
_, _ = w.Write([]byte(`{}`))
|
||||
case r.Method == http.MethodDelete && r.URL.Path == "/api/config/chains/old-b":
|
||||
deleted = append(deleted, "old-b")
|
||||
_, _ = w.Write([]byte(`{}`))
|
||||
case r.Method == http.MethodPost && r.URL.Path == "/api/config":
|
||||
saved = true
|
||||
_, _ = w.Write([]byte(`{}`))
|
||||
default:
|
||||
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewGost(server.URL, 9700, "/api", "user", "pass")
|
||||
|
||||
chains, err := client.ListChains()
|
||||
if err != nil {
|
||||
t.Fatalf("ListChains returned error: %v", err)
|
||||
}
|
||||
if len(chains) != 2 || chains[0].Name != "old-a" || chains[1].Name != "old-b" {
|
||||
t.Fatalf("unexpected chains: %#v", chains)
|
||||
}
|
||||
|
||||
if err := client.DeleteChain(chains[0].Name); err != nil {
|
||||
t.Fatalf("DeleteChain old-a returned error: %v", err)
|
||||
}
|
||||
if err := client.DeleteChain(chains[1].Name); err != nil {
|
||||
t.Fatalf("DeleteChain old-b returned error: %v", err)
|
||||
}
|
||||
if len(deleted) != 2 {
|
||||
t.Fatalf("unexpected deleted chains: %#v", deleted)
|
||||
}
|
||||
|
||||
err = client.CreateChain(&GostChainConfig{
|
||||
Name: "edge-a",
|
||||
Hops: []GostHopConfig{{
|
||||
Nodes: []GostNodeConfig{{
|
||||
Addr: "192.0.2.1:1080",
|
||||
Connector: GostConnectorConfig{Type: "socks5"},
|
||||
Dialer: GostDialerConfig{Type: "tcp"},
|
||||
}},
|
||||
}},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CreateChain returned error: %v", err)
|
||||
}
|
||||
if created == nil || created.Name != "edge-a" {
|
||||
t.Fatalf("unexpected created chain: %#v", created)
|
||||
}
|
||||
if len(created.Hops) != 1 || len(created.Hops[0].Nodes) != 1 {
|
||||
t.Fatalf("unexpected created chain hops: %#v", created.Hops)
|
||||
}
|
||||
node := created.Hops[0].Nodes[0]
|
||||
if node.Addr != "192.0.2.1:1080" || node.Connector.Type != "socks5" || node.Dialer.Type != "tcp" {
|
||||
t.Fatalf("unexpected created node: %#v", node)
|
||||
}
|
||||
|
||||
if err := client.SaveConfig(); err != nil {
|
||||
t.Fatalf("SaveConfig returned error: %v", err)
|
||||
}
|
||||
if !saved {
|
||||
t.Fatal("expected SaveConfig request")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user