以下是一个使用Golang编写的HTTP加密代理示例:
package main
import (
"crypto/tls"
"fmt"
"io"
"log"
"net"
"net/http"
"os"
)
func handleTunneling(w http.ResponseWriter, r *http.Request) {
// 获取连接目标地址和端口
targetHost := r.URL.Host
log.Printf("Proxying HTTPS request to: %s\n", targetHost)
// 建立与目标地址的TCP连接
conn, err := net.Dial("tcp", targetHost)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer conn.Close()
// 返回客户端HTTP状态码200(成功建立隧道)
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
}
defer clientConn.Close()
io.WriteString(clientConn, "HTTP/1.1 200 Connection established\r\n\r\n")
// 在双方之间进行数据传输
go transfer(conn, clientConn)
transfer(clientConn, conn)
}
func transfer(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
io.Copy(destination, source)
}
func main() {
// 创建TLS配置,允许不安全连接
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}
// 创建代理服务器
proxy := &http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodConnect {
handleTunneling(w, r)
} else {
// 处理普通HTTP请求
proxyHTTPHandler := http.DefaultTransport
resp, err := proxyHTTPHandler.RoundTrip(r)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer resp.Body.Close()
// 将响应返回给客户端
for key, values := range resp.Header {
for _, value := range values {
w.Header().Add(key, value)
}
}
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}
}),
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)), // 禁用HTTP/2
ConnState: func(conn net.Conn, state http.ConnState) {
log.Printf("Connection %s: %s\n", conn.RemoteAddr().String(), state)
},
TLSConfig: tlsConfig,
}
// 启动代理服务器
log.Println("Starting proxy server on :8080")
err := proxy.ListenAndServe()
if err != nil {
fmt.Fprintf(os.Stderr, "Error starting server: %s\n", err)
os.Exit(1)
}
}
这个示例创建了一个HTTP代理服务器,支持不安全的HTTPS连接。它使用net.Dial
建立与目标服务器的TCP连接,并在双方之间进行数据传输。在客户端发起HTTPS请求时,它将返回HTTP状态码200,并直接将客户端和目标服务器之间的TCP连接交换数据。
要测试这个代理服务器,请设置浏览器或应用程序的代理设置,将其指向localhost:8080
。现在,您应该能够通过代理服务器访问任何网站(包括HTTPS网站)。