Golang代理服务器开发实战

最近在学习用Golang开发代理服务器,遇到几个问题想请教:

  1. 如何实现基本的HTTP/HTTPS代理转发功能?
  2. 如何处理高并发连接,有没有推荐的并发模型?
  3. 代理服务器如何实现请求/响应的过滤和修改?
  4. 有没有性能优化的建议,比如连接池或缓存机制?
  5. 如何实现代理认证功能?

希望有实际开发经验的前辈能分享下实战中的注意事项和最佳实践。

2 回复

好的,老哥。搞一个Golang代理服务器,简单又高效。咱们分几步走:

1. 核心思路 代理就是个“中间商”,接收客户端的请求,然后帮你转发给真正的服务器,再把服务器的响应返回给客户端。我们用Go标准库的 net/httpnet/http/httputil 就能轻松搞定。

2. 上代码(极简版)

package main

import (
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    // 1. 指定目标服务器的地址
    target, _ := url.Parse("http://httpbin.org")
    
    // 2. 创建一个反向代理处理器
    proxy := httputil.NewSingleHostReverseProxy(target)
    
    // 3. 启动代理服务器,监听在8080端口
    http.ListenAndServe(":8080", proxy)
}

就这么几行!一个能用的HTTP反向代理服务器就起来了。你访问 http://localhost:8080,它就会把请求转发到 http://httpbin.org

3. 加点料(实战要点)

  • 修改请求:在代理转发前,你可以修改请求头(比如加个X-From-Proxy: golang)。
    proxy.Director = func(req *http.Request) {
        req.Header.Set("X-From-Proxy", "golang-rocks")
    }
    
  • 错误处理:重写 proxy.ErrorHandler 来自定义错误页面。
  • 负载均衡:不用 NewSingleHostReverseProxy,自己写个轮询算法,在多个目标服务器间切换。
  • 中间件:用个Mux(如Gorilla Mux)来加路由、认证、日志等。

总结: Go写代理的优势就是性能强悍、标准库给力。这个例子是反向代理,你要写正向代理(比如科学上网那种)就用 http.Handler 自己解析请求并转发。开搞吧!

更多关于Golang代理服务器开发实战的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang代理服务器开发实战

代理服务器是网络架构中的重要组件,用于转发客户端请求。以下是使用Golang开发代理服务器的核心实现:

1. 基础HTTP代理服务器

package main

import (
    "fmt"
    "io"
    "log"
    "net"
    "net/http"
    "strings"
)

func handleHTTP(w http.ResponseWriter, req *http.Request) {
    // 创建新的HTTP客户端
    client := &http.Client{}
    
    // 修改请求,移除代理相关头部
    req.RequestURI = ""
    req.URL.Scheme = "http"
    req.URL.Host = req.Host
    
    // 发送请求
    resp, err := client.Do(req)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadGateway)
        return
    }
    defer resp.Body.Close()
    
    // 复制响应头
    for k, v := range resp.Header {
        for _, value := range v {
            w.Header().Add(k, value)
        }
    }
    
    w.WriteHeader(resp.StatusCode)
    io.Copy(w, resp.Body)
}

func main() {
    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            if r.Method == http.MethodConnect {
                // HTTPS代理处理
                handleTunneling(w, r)
            } else {
                // HTTP代理处理
                handleHTTP(w, r)
            }
        }),
    }
    
    log.Println("代理服务器启动在 :8080")
    log.Fatal(server.ListenAndServe())
}

2. HTTPS隧道处理

func handleTunneling(w http.ResponseWriter, req *http.Request) {
    // 连接到目标服务器
    destConn, err := net.Dial("tcp", req.Host)
    if err != nil {
        http.Error(w, err.Error(), http.StatusServiceUnavailable)
        return
    }
    defer destConn.Close()
    
    // 通知客户端连接已建立
    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()
    
    // 双向数据转发
    go transfer(destConn, clientConn)
    transfer(clientConn, destConn)
}

func transfer(destination io.WriteCloser, source io.ReadCloser) {
    defer destination.Close()
    defer source.Close()
    io.Copy(destination, source)
}

3. 增强功能:请求过滤

// 简单的URL过滤
func isAllowed(url string) bool {
    blockedSites := []string{"malicious.com", "dangerous.org"}
    for _, site := range blockedSites {
        if strings.Contains(url, site) {
            return false
        }
    }
    return true
}

// 在handleHTTP中添加过滤
func handleHTTPWithFilter(w http.ResponseWriter, req *http.Request) {
    if !isAllowed(req.URL.Host) {
        http.Error(w, "访问被禁止", http.StatusForbidden)
        return
    }
    handleHTTP(w, req)
}

4. 启动和测试

编译并运行:

go build -o proxy-server main.go
./proxy-server

配置浏览器或curl使用代理:

curl -x http://localhost:8080 http://example.com

关键特性

  • 高性能:Golang的并发模型适合处理大量并发连接
  • 内存安全:自动内存管理避免常见的内存错误
  • 标准库支持:net/http包提供了完善的HTTP协议支持
  • 易于扩展:可以轻松添加认证、日志、缓存等功能

这个基础代理服务器可以作为起点,根据需求添加更多功能如认证、负载均衡、缓存等。

回到顶部