/* * Copyright 2026 Oleg Borodin */ package handler import ( "io" "net" "net/http" "strings" "sync" "mproxy/app/router" ) func (hand *Handler) ConnectTo(rctx *router.Context) { hostaddr := rctx.GetHost() hand.logg.Debugf("Hostaddr: [%s]", hostaddr) if strings.Contains(hostaddr, "https://") { hand.logg.Errorf("Wrong request, found schema definition in Host") rctx.SetStatus(http.StatusBadRequest) return } destConn, err := net.Dial("tcp", hostaddr) if err != nil { hand.logg.Errorf("ConnectTo error: %v", err) rctx.SetStatus(http.StatusInternalServerError) return } if err != nil { hand.logg.Errorf("ConnectTo error: %v", err) rctx.SetStatus(http.StatusInternalServerError) return } defer destConn.Close() hijacker, hijackerOk := rctx.Writer.(http.Hijacker) if !hijackerOk { hand.logg.Errorf("Hijacking not OK") rctx.SetStatus(http.StatusInternalServerError) return } rctx.SetStatus(http.StatusOK) clientConn, _, err := hijacker.Hijack() if err != nil { hand.logg.Errorf("Hijacking error: %v", err) rctx.SetStatus(http.StatusInternalServerError) return } var wg sync.WaitGroup copyTo := func() { defer wg.Done() _, err = io.Copy(clientConn, destConn) if err != nil { hand.logg.Errorf("CopyTo error: %v", err) return } } copyFrom := func() { defer wg.Done() _, err = io.Copy(destConn, clientConn) if err != nil { hand.logg.Errorf("CopyFrom error: %v", err) return } } wg.Add(1) go copyTo() wg.Add(1) go copyFrom() wg.Wait() return }