Skip to content

Instantly share code, notes, and snippets.

@KevinWang15
Created June 13, 2024 05:17
Show Gist options
  • Save KevinWang15/54cf1581dceb5d444d25340552a7d0a6 to your computer and use it in GitHub Desktop.
Save KevinWang15/54cf1581dceb5d444d25340552a7d0a6 to your computer and use it in GitHub Desktop.
TCP port forward through HTTP CONNECT PROXY
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
)
func handleConnection(clientConn net.Conn, proxyURL *url.URL, targetAddress string) {
defer clientConn.Close()
proxyConn, err := net.Dial("tcp", proxyURL.Host)
if err != nil {
fmt.Printf("Failed to connect to proxy: %v\n", err)
return
}
defer proxyConn.Close()
connectReq := &http.Request{
Method: http.MethodConnect,
URL: &url.URL{Opaque: targetAddress},
Host: targetAddress,
Header: make(http.Header),
}
err = connectReq.Write(proxyConn)
if err != nil {
fmt.Printf("Failed to write CONNECT request: %v\n", err)
return
}
resp, err := http.ReadResponse(bufio.NewReader(proxyConn), connectReq)
if err != nil {
fmt.Printf("Failed to read CONNECT response: %v\n", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Proxy CONNECT response status: %v\n%s\n", resp.Status, body)
return
}
go io.Copy(proxyConn, clientConn)
io.Copy(clientConn, proxyConn)
}
func main() {
listenAddr := "0.0.0.0:8088"
proxyURL, err := url.Parse("http://squid-host:3128")
if err != nil {
fmt.Printf("Failed to parse proxy URL: %v\n", err)
return
}
targetAddress := "target-mysql-host:3306"
listener, err := net.Listen("tcp", listenAddr)
if err != nil {
fmt.Printf("Failed to start listener: %v\n", err)
return
}
defer listener.Close()
fmt.Printf("Listening on %s\n", listenAddr)
for {
clientConn, err := listener.Accept()
if err != nil {
fmt.Printf("Failed to accept connection: %v\n", err)
continue
}
go handleConnection(clientConn, proxyURL, targetAddress)
}
}
@KevinWang15
Copy link
Author

Or simply

socat TCP-LISTEN:8088,reuseaddr,fork PROXY:squid-host:target-mysql-host:3306,proxyport=3128

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment