The following is a sample code for implementing HTTP tunneling in Go language:
```go
package main
import (
"fmt"
"io"
"net"
"net/http"
)
func handleTunneling(w http.ResponseWriter, r *http.Request) {
destConn, err := net.Dial("tcp", r.Host)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
hijacker, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
return
}
clientConn, _, err := hijacker.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
go transfer(destConn, clientConn)
go transfer(clientConn, destConn)
}
func transfer(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
io.Copy(destination, source)
}
func main() {
http.HandleFunc("/", handleTunneling)
fmt.Println("Listening on :8080...")
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println(err)
}
}
```
This sample code creates an HTTP server listening on port 8080. When receiving an HTTP CONNECT request, it will establish a TCP connection to the target host, and forward the data between the client connection and the target connection.
package main import ( "net/url""net/http""bytes""fmt""io/ioutil" ) const ProxyServer = "http://ip.hahado.cn:39010"type ProxyAuth struct { License string SecretKey string } func (p ProxyAuth) ProxyClient() http.Client { proxyURL, _ := url.Parse("http://" + p.License + ":" + p.SecretKey + "@" + ProxyServer) return http.Client{Transport: &http.Transport{Proxy:http.ProxyURL(proxyURL)}} } func main() { targetURI := "http://ip.hahaod.cn/ip"//targetURI := "http://ip.hahaod.cn/switch-ip"//targetURI := "http://ip.hahaod.cn/current-ip"// Initialize the proxy http client client := ProxyAuth{License: "username", SecretKey: "password"}.ProxyClient() request, _ := http.NewRequest("GET", targetURI, bytes.NewBuffer([] byte(``))) // 切换IP (只支持 HTTP) request.Header.Set("Proxy-Switch-Ip", "yes") response, err := client.Do(request) iferr != nil { panic("failed to connect: " + err.Error()) } else { bodyByte, err := ioutil.ReadAll(response.Body) iferr != nil { fmt.Println("读取 Body 时出错", err) return } response.Body.Close() body := string(bodyByte) fmt.Println("Response Status:", response.Status) fmt.Println("Response Header:", response.Header) fmt.Println("Response Body:\n", body) } }