Skip to content

Commit 468fce1

Browse files
Add files via upload
1 parent 9d80b3b commit 468fce1

1 file changed

Lines changed: 32 additions & 34 deletions

File tree

core_engine/main.go

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,48 @@
1-
// core_engine/main.go
2-
31
package main
42

53
import (
4+
"bytes"
65
"context"
76
"encoding/json"
87
"fmt"
98
"io"
109
"net"
1110
"net/http"
1211
"os"
12+
"os/exec"
1313
"sync"
1414
"time"
15-
"os/exec"
15+
1616
"golang.org/x/net/proxy"
1717
)
1818

19-
// note: This struct defines the input format we expect from Python.
2019
type TestConfig struct {
2120
Tag string `json:"tag"`
22-
Config json.RawMessage `json:"config"` // * We use RawMessage to keep the outbound config as-is.
21+
Config json.RawMessage `json:"config"`
2322
TestPort int `json:"test_port"`
24-
XrayPath string `json:"xray_path"`
23+
XrayPath string `json:"xray_path"`
2524
}
2625

27-
// note: This struct defines the output format we send back to Python.
2826
type TestResult struct {
2927
Tag string `json:"tag"`
30-
Ping int64 `json:"ping_ms"` // * Ping in milliseconds
28+
Ping int64 `json:"ping_ms"`
3129
Status string `json:"status"`
3230
}
3331

3432
func main() {
3533
inputData, err := io.ReadAll(os.Stdin)
3634
if err != nil {
37-
fmt.Fprintf(os.Stderr, "Error reading stdin: %v\n", err)
3835
os.Exit(1)
3936
}
4037

4138
var configs []TestConfig
4239
if err := json.Unmarshal(inputData, &configs); err != nil {
43-
fmt.Fprintf(os.Stderr, "Error unmarshaling json: %v\n", err)
4440
os.Exit(1)
4541
}
4642

47-
results := make(chan TestResult, len(configs)) // * Use a buffered channel for collecting results.
43+
results := make(chan TestResult, len(configs))
4844
var wg sync.WaitGroup
4945

50-
// * All tests will run concurrently!
5146
for _, conf := range configs {
5247
wg.Add(1)
5348
go func(c TestConfig) {
@@ -58,48 +53,52 @@ func main() {
5853
results <- TestResult{Tag: c.Tag, Ping: -1, Status: "tempfile_error"}
5954
return
6055
}
61-
// * Ensure the temp file is cleaned up even if something panics.
6256
defer os.Remove(tmpFile.Name())
6357

6458
fullConfig := map[string]interface{}{
59+
"log": map[string]string{
60+
"loglevel": "debug", // ! Enable debug logging
61+
},
6562
"inbounds": []map[string]interface{}{
66-
{
67-
"protocol": "socks",
68-
"port": c.TestPort,
69-
"listen": "127.0.0.1",
70-
"settings": map[string]interface{}{
71-
"auth": "noauth",
72-
"udp": true,
73-
},
74-
},
63+
{"protocol": "socks", "port": c.TestPort, "listen": "127.0.0.1", "settings": map[string]interface{}{"auth": "noauth", "udp": true}},
7564
},
7665
"outbounds": []json.RawMessage{c.Config},
7766
}
7867

7968
configBytes, _ := json.Marshal(fullConfig)
80-
if _, err := tmpFile.Write(configBytes); err != nil {
81-
results <- TestResult{Tag: c.Tag, Ping: -1, Status: "tempfile_write_error"}
82-
tmpFile.Close()
83-
return
84-
}
69+
tmpFile.Write(configBytes)
8570
tmpFile.Close()
8671

87-
// * We set a context with a timeout for the entire Xray process.
8872
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
8973
defer cancel()
9074

9175
cmd := exec.CommandContext(ctx, c.XrayPath, "-c", tmpFile.Name())
9276

77+
// ! Capture Xray's output
78+
var xrayOutput bytes.Buffer
79+
cmd.Stdout = &xrayOutput
80+
cmd.Stderr = &xrayOutput
81+
9382
if err := cmd.Start(); err != nil {
9483
results <- TestResult{Tag: c.Tag, Ping: -1, Status: "xray_start_failed"}
9584
return
9685
}
9786

98-
time.Sleep(700 * time.Millisecond)
87+
time.Sleep(800 * time.Millisecond) // Increased sleep time slightly for debug logs
9988

10089
ping, status := testProxy(c.TestPort)
10190

102-
// * Killing the process is more reliable than waiting for it to exit.
91+
// ! If test fails, append Xray's log to the status
92+
if status != "success" {
93+
// Sanitize and shorten the log for cleaner output
94+
logStr := string(xrayOutput.Bytes())
95+
logStr = re.SubexpNames(logStr, -1)
96+
if len(logStr) > 200 {
97+
logStr = logStr[:200]
98+
}
99+
status = fmt.Sprintf("%s | xray_log: %s", status, logStr)
100+
}
101+
103102
cmd.Process.Kill()
104103
cmd.Wait()
105104

@@ -120,7 +119,6 @@ func main() {
120119
}
121120

122121
func testProxy(port int) (int64, string) {
123-
// * This function tests the SOCKS5 proxy that the Xray core creates.
124122
targetURL := "http://cp.cloudflare.com/generate_204"
125123
timeout := 8 * time.Second
126124

@@ -138,14 +136,14 @@ func testProxy(port int) (int64, string) {
138136
start := time.Now()
139137
resp, err := httpClient.Get(targetURL)
140138
if err != nil {
141-
return -1, "failed_http"
139+
return -1, fmt.Sprintf("failed_http: %v", err)
142140
}
143141
defer resp.Body.Close()
144142

145-
if resp.StatusCode != http.StatusOK {
143+
if resp.StatusCode != http.StatusNoContent {
146144
return -1, fmt.Sprintf("bad_status_%d", resp.StatusCode)
147145
}
148146

149147
latency := time.Since(start).Milliseconds()
150148
return latency, "success"
151-
}
149+
}

0 commit comments

Comments
 (0)