Golang ReverseProxy 如何实现反向代理?
温馨提示:这篇文章已超过493天没有更新,请注意相关的内容是否还可用!
如果❤️我的文章对您有帮助,请点赞关注。 这是对我继续技术创作最大的鼓励。 更多系列文章在我的博客[1]
Golang ReverseProxy源码初探
高朗版本 1.16
使用ReverseProxy实现反向代理的例子
♀️废话不多说,直接举例
测试代理服务器
$ curl 'http://127.0.0.1:2002/sda?sda=111'
# 2003 设置了 打印请求地址代码: upath := fmt.Sprintf("http://%s%s\n", r.Addr, req.URL.Path)
http://127.0.0.1:2003/base/sda
RemoteAddr=127.0.0.1:51738,X-Forwarded-For=127.0.0.1,X-Real-Ip=
headers =map[Accept:[*/*] Accept-Encoding:[gzip] User-Agent:[curl/7.69.1] X-Forwarded-For:[127.0.0.1]]
查看httputil.NewSingleHostReverseProxy()函数,可以找到ReverseProxy的源码。 文件 go/src/net/http/httputil/reverseproxy.go 位于此路径
核心源码ReverseProxy结构
用于处理请求的 ReverseProxy 方法 ServeHTTP()
ReverseProxy 实现了 ServeHTTP() 方法,当请求到达代理服务器时代理服务器,最终会被监听方法 ListenAndServe() 调用。 调用链接是:
http.ListenAndServe(addr string, handler Handler)
-> Server.ListenAndServeTLS(certFile, keyFile)
-> Server.ServeTLS(ln, certFile, keyFile)
-> Server.Serve(l net.Listener)
-> go c.serve(connCtx)
-> serverHandler{c.server}.ServeHTTP(w, w.req)
所以ReverseProxy结构体也实现了ServeHTTP方法,该方法的作用是:
1.将上游请求的上下文复制到下游请求 2.使用指定的director(修改请求的函数)修改请求(如协议、参数、url等) 3.根据请求Header[ "Connection"]判断是否升级协议(Upgrade) 4.删除上游请求中的hop-by-hop Header,保持上游持久(相对)连接,不需要透传给下游 5.设置X-Forward-For Header,添加当前节点IP6。 使用连接池发送 Downstream 发起请求 7. 处理httpcode 101 协议升级:(WebSocket, h2c等) 8. 删除请求中的hop-by-hop Header代理服务器,不返回upstream 9. 判断是否根据结构ReverseProxy.ModifyResponse(function)修改响应体内容 10.复制下游响应头到上游响应请求 11.返回下游请求的HTTP状态码 12.复制下游响应内容到上游响应request 13.刷新内容到response
其他源码NewSingleHostReverseProxy函数
NewSingleHostReverseProxy中的URL拼接方法
参考
[1] 更多系列文章在我的博客: