0

    基于golang的http(s)与socks5代理服务器的代码实现

    2023.05.24 | admin | 129次围观

    Golang可以轻松实现一个https代理,你需要执行以下步骤:

    获取客户端请求: 使用Golang的net包接收客户端请求。转发请求: 使用Golang的http包将请求转发到服务端。获取服务端响应: 从服务端接收响应并将其返回给客户端。

    以下是一个示例代码,实现了一个https代理:

    package main
    import (
    	"bufio"
    	"io"
    	"net"
    	"net/http"
    	"net/http/httputil"
    )
    func handleHttps(w http.ResponseWriter, r *http.Request) {
    	dest_conn, err := net.DialTimeout("tcp", r.Host, 10*time.Second)
    	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
    	}
    	client_conn, _, err := hijacker.Hijack()
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusServiceUnavailable)
    	}
    	go transfer(dest_conn, client_conn)
    	go transfer(client_conn, dest_conn)
    }
    func transfer(destination io.WriteCloser, source io.ReadCloser) {
    	defer destination.Close()
    	defer source.Close()
    	io.Copy(destination, source)
    }
    func handleHTTP(w http.ResponseWriter, req *http.Request) {
    	resp, err := http.DefaultTransport.RoundTrip(req)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusServiceUnavailable)
    		return
    	}
    	defer resp.Body.Close()
    	copyHeader(w.Header(), resp.Header)
    	w.WriteHeader(resp.StatusCode)
    	io.Copy(w, resp.Body)
    }
    func copyHeader(dst, src http.Header) {
    	for k, vv := range src {
    		for _, v := range vv {
    			dst.Add(k, v)
    		}
    	}
    }

    SOCKS代理

    Socks5协议是一种灵活的代理协议,主要用于实现代理服务器的功能,允许客户端通过代理服务器与其他网络资源进行通信。Socks5协议比Socks4协议更先进,具有更多的特性,如它支持用户名/密码验证寻求web网页代理速度要快寻求web网页代理速度要快,还支持TCP和UDP协议.下面实现的是Socks5代理协议

    package main
    import (
        "bufio"
        "fmt"
        "net"
        "os"
    )
    func main() {
        l, err := net.Listen("tcp", ":1080")
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
        defer l.Close()
        for {
            client, err := l.Accept()
            if err != nil {
                fmt.Println(err)
                continue
            }
            go handleClientRequest(client)
        }
    }
    func handleClientRequest(client net.Conn) {
        if client == nil {
            return
        }
        defer client.Close()
        var b [1024]byte
        n, err := client.Read(b[:])
        if err != nil {
            fmt.Println(err)
            return
        }
        var host, port string
        switch b[3] {
        case 0x01: // IPv4
            host = net.IPv4(b[4], b[5], b[6], b[7]).String()
            port = fmt.Sprintf("%d", b[8]<<8|b[9])
        case 0x03: // Domain name
            host = string(b[5 : n-2])
            port = fmt.Sprintf("%d", b[n-2]<<8|b[n-1])
        case 0x04: // IPv6
            host = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String()
            port = fmt.Sprintf("%d", b[20]<<8|b[21])
        }
        server, err := net.Dial("tcp", host+":"+port)
        if err != nil {
            fmt.Println(err)
            return
        }
        defer server.Close()
        client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43})
        go func() {
            _, err := io.Copy(server, client)
            if err != nil {
                fmt.Println("io.Copy error:", err)
            }
        }()
        _, err = io.Copy(client, server)
        if err != nil {
            fmt.Println("io.Copy error:", err)
        }
    }
    

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论