| package main |
|
|
| import ( |
| "bufio" |
| "fmt" |
| "io" |
| "log" |
| "net" |
| "net/http" |
| "net/http/httputil" |
| "net/url" |
| "os" |
| "strings" |
| "sync" |
|
|
| "github.com/gorilla/websocket" |
| ) |
|
|
| var bufPool = sync.Pool{ |
| New: func() interface{} { return make([]byte, 32768) }, |
| } |
|
|
| var upgrader = websocket.Upgrader{ |
| CheckOrigin: func(r *http.Request) bool { return true }, |
| ReadBufferSize: 32768, |
| WriteBufferSize: 32768, |
| } |
|
|
| var indexHTML []byte |
|
|
| func init() { |
| var err error |
| indexHTML, err = os.ReadFile("/app/index.html") |
| if err != nil { |
| indexHTML = []byte("Cloud Node Active") |
| } |
| } |
|
|
| func main() { |
| port := os.Getenv("PORT") |
| if port == "" { |
| port = "7860" |
| } |
|
|
| targetURL, _ := url.Parse("http://127.0.0.1:8080") |
| proxy := httputil.NewSingleHostReverseProxy(targetURL) |
|
|
| http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { |
| if strings.HasPrefix(r.URL.Path, "/moz") { |
| if r.Header.Get("Sec-WebSocket-Key") != "" { |
| handleWS(w, r) |
| return |
| } |
| proxy.ServeHTTP(w, r) |
| return |
| } |
|
|
| if r.URL.Path == "/sub" { |
| host := r.Host |
| w.Header().Set("Content-Type", "text/plain; charset=utf-8") |
| fmt.Fprintf(w, "trojan://1q2w3e4r5t@%s:443?type=ws&security=tls&path=%%2Fmoz#NyxServer-Trojan-WS\n", host) |
| fmt.Fprintf(w, "trojan://1q2w3e4r5t@%s:443?type=httpupgrade&security=tls&path=%%2Fmoz#NyxServer-Trojan-HTTPUpgrade\n", host) |
| return |
| } |
|
|
| w.Header().Set("Content-Type", "text/html; charset=utf-8") |
| w.WriteHeader(http.StatusOK) |
| w.Write(indexHTML) |
| }) |
|
|
| log.Printf("Gateway starting on port %s...", port) |
| if err := http.ListenAndServe(":"+port, nil); err != nil { |
| log.Fatal(err) |
| } |
| } |
|
|
| func handleWS(w http.ResponseWriter, r *http.Request) { |
| clientConn, err := upgrader.Upgrade(w, r, nil) |
| if err != nil { |
| return |
| } |
| defer clientConn.Close() |
|
|
| sbConn, err := net.Dial("tcp", "127.0.0.1:8080") |
| if err != nil { |
| return |
| } |
| defer sbConn.Close() |
|
|
| handshake := "GET /moz HTTP/1.1\r\n" + |
| "Host: 127.0.0.1:8080\r\n" + |
| "Connection: Upgrade\r\n" + |
| "Upgrade: websocket\r\n\r\n" |
| if _, err = sbConn.Write([]byte(handshake)); err != nil { |
| return |
| } |
|
|
| reader := bufio.NewReader(sbConn) |
| for { |
| line, _, err := reader.ReadLine() |
| if err != nil { |
| return |
| } |
| if len(line) == 0 { |
| break |
| } |
| } |
|
|
| errChan := make(chan error, 2) |
|
|
| go func() { |
| for { |
| messageType, r, err := clientConn.NextReader() |
| if err != nil { |
| errChan <- err |
| return |
| } |
| if messageType == websocket.BinaryMessage || messageType == websocket.TextMessage { |
| buf := bufPool.Get().([]byte) |
| _, err = io.CopyBuffer(sbConn, r, buf) |
| bufPool.Put(buf) |
| if err != nil { |
| errChan <- err |
| return |
| } |
| } |
| } |
| }() |
|
|
| go func() { |
| buf := bufPool.Get().([]byte) |
| defer bufPool.Put(buf) |
| for { |
| n, err := reader.Read(buf) |
| if err != nil { |
| errChan <- err |
| return |
| } |
| if n > 0 { |
| if err = clientConn.WriteMessage(websocket.BinaryMessage, buf[:n]); err != nil { |
| errChan <- err |
| return |
| } |
| } |
| } |
| }() |
|
|
| <-errChan |
| } |