为了账号安全,请及时绑定邮箱和手机立即绑定

初探 ReverseProxy 源码

标签:
Go 面试 源码

如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。[更多系列文章在我博客] coderdao.github.io/

初探 ReverseProxy 源码

Golang 版本 1.16

使用 ReverseProxy 实现反向代理的例子

Talk is cheap, show me the code
图片描述

测试 代理服务器

$ 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 结构体

图片描述

NewSingleHostReverseProxy 函数

图片描述

NewSingleHostReverseProxy 中 URL 拼接方法

图片描述

ReverseProxy 处理请求的方法 ServeHTTP

ServeHTTP() 最终会在请求到达代理服务器, 有监听方法调起。调用链路为:

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. 拷贝上游请求的 context 到下游请求
  2. 使用 指定 director(对请求进行修改的函数)修改请求(例如协议、参数、url 等)
  3. 根据请求 Header[“Connection”] 判断是否需要升级协议(Upgrade)
  4. 删除上游请求中的 hop-by-hop Header, 维持上游持久(相对)连接, 不需要透传到下游
  5. 设置 X-Forward-For Header,追加当前节点 IP
  6. 使用连接池,向下游发起请求
  7. 处理协议升级(httpcode 101):(WebSocket、h2c 等)
  8. 删除请求中的 hop-by-hop Header, 不要返回给上游
  9. 根据结构体 ReverseProxy.ModifyResponse(函数)判断是否修改响应体内容
  10. 拷贝下游响应头部到上游响应请求
  11. 返回 下游请求 HTTP 状态码
  12. 拷贝 下游响应内容 到 上游响应请求
  13. 刷新内容到 response

这些都能在下面的代码实现中一一找到对应:
图片描述

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
154
获赞与收藏
1426

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消