基于 Gin 的 HTTP 代理 demo

上次用 TCP 模拟了一个 HTTP 代理之后,感觉那样还是太简陋了,想着是不是可以用框架来做一个有点实际用处的东西。所以,就思索如何用 golang 的 Gin 框架来实现一个?嗯,对的你没有听错,是 gin 框架。你可能会疑惑,它不是 Web 框架吗,怎么可以用来做代理软件呢?哈哈,其实仔细想一想就明白了。我已经说过了,HTTP 代理的本质其实就是一个 HTTP 服务器!所以,我只要想办法让它来处理所有的路由就行了!

经过思考之后,我想到了 404 这个东西,通常对于一个 Web 服务来说,它就是不存在的路由。也就是说:
存在的路由 + 不存在的路由 = 全部的路由
对于一个 Web 服务,我们是有明确的接口(路由)的,所以会定义很多存在的路由。但是对于一个代理服务器来说,它根本不关心你的路由是什么,也就不需要存在的路由(你根本不知道用户会访问哪些路由),所以我们只需要处理不存在的路由即可。这里不存在的路由是指,不被 Web 服务处理的路由。
这样描述可能会有些困惑,那么就直说好了,我的想法是:在 Gin 框架中,不定义路由,这样全部的路由都会被认为是不存在的路由了,然后在专门处理 404 的方法中对所有的路由进行处理。相当于通过一个巧妙的方法,从而达到处理所有路由的目的,这样利用它来做一个 HTTP 代理就没有任何问题了。

代码

package mainimport ("fmt""io""log""net/http""strings""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.NoRoute(routeProxy)  // 路由代理 handlerr.GET("/", routeProxy) // 默认就有一个 / 路由,所以把它也在路由代理中处理r.Run(":8000")         // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}// 这样就可以处理所有的路由情况了
func routeProxy(c *gin.Context) {// 代理接收到请求将其发出,然后再返回对应的响应。req := c.Requestgo resolveReq(req) // 看看这个请求干了什么,注意不能代理自己,否则会有问题的newReq, _ := http.NewRequest(req.Method, req.URL.String(), req.Body)resp, err := http.DefaultClient.Do(newReq)if err != nil {log.Fatal(err)}defer resp.Body.Close()data, err := io.ReadAll(resp.Body)if err != nil {log.Fatal(err)}code := resp.StatusCodec.Status(code) // 响应状态码for k, v := range resp.Header {c.Header(k, strings.Join(v, ","))}c.Header("Server", "CrazyDragonHttpProxy") // 篡改一个响应回复c.Writer.Write(data)                       // 响应数据
}func resolveReq(req *http.Request) {fmt.Printf("Method: %s, Host: %s, URL: %s\n", req.Method, req.Host, req.URL.String())
}

注意:这里似乎也不需要这个默认的 /,因为代理的路由和不代理的路由是有区别的。

代理设置

请添加图片描述

这里 http=127.0.0.1,这样就只会代理 http 协议,不会处理 https 协议。因为我这里只是简单的 demo,我也不想去处理 https,那样太麻烦了,我也不是很了解具体怎么做。使用 Fiddler 进行抓包设置时,如果需要抓包 https 就需要安装它的证书,你就知道很麻烦了。

注意,它现在是一个代理服务器了,所以你不能访问它自己,不然就是代理服务器代理自己了。这里没对这个做处理,所以就会报错。

请添加图片描述

测试

现在想要找一个 http 的网站来测试真的是麻烦了,找了好久才发现一个 http 的网站,毕竟现在还用 http 的网站真的是太稀少了。

请添加图片描述

请添加图片描述

然后就出现问题了,我的电脑风扇开始狂啸,CPU 使用率飙升。然后就是打印上面这些东西了,所以应该就是代理服务器又把请求转发给了自己,然后系统可能就维持了大量的连接导致 CPU 使用率飙升。我开始以为是我的 http.DefaultClient 代码的问题,因为它的默认配置似乎会使用系统的代理。但是我又一想不对呀,因为我并不是在系统之中,我在容器里面呢!我现在把本地开发环境卸载了,所以我是在容器中进行开发的。不过,我又想到虽然我在容器中,但是 docker 还是在系统中的。

在这里插入图片描述

所以这个网络请求可能就是下图这样的:红色是用户请求,蓝色是代理的请求,它循环了,然后导致了问题。

在这里插入图片描述

所以,我又想了想,解决办法就是还是回到 Windows 本机上运行才行。但是因为本地已经没有了开发环境,所以再另辟蹊径,我只需要在 Windows 上执行就行了,并不需要在 Winwos 上面编译。所以让我们来交叉编译一个 Windows 的版本吧。
在这里插入图片描述

不过这玩意在 docker 容器里面呢,我还得拿出去才行,那怎么办才好呢?你听没有听过一个叫 docker cp 的命令!不过根本不需要那么麻烦,因为我这个目录是挂载进来的,我直接去我的挂载目录就行了,哈哈。

在这里插入图片描述
请添加图片描述

演示

终于是演示成功了,不过我发现它还是会因为无法处理 https 而终止(如果错误了,我就简单终止了程序,当然了你可以不处理直接返回就行了)。https 的那个 connect 方法,这玩意真的和乌云一样,正常的 web 开发用不到它,所以遇到了也就没法处理了(我只知道它是代理服务器建立隧道用的,其它的不清楚)。因为我前面那样设置,我以为是可以跳过 https 协议的,而且我的其它 https 页面是可以正常访问的,不过不知道为什么总有几个还是往代理服务器发送,它处理不了这个东西,导致代理崩溃了。

请添加图片描述

请添加图片描述

PS:
我刚开始在寻找那个循环请求的问题时,发现了一个老哥写的相似主题的文章。不过,他这个就早多了,好几年前了。不过,我这里最主要的想法是关于 404 的处理,他做的依然是关于指定路由的处理。不过,他使用那个工具直接发送请求还是值得参考的,但是因为这毕竟只是一个玩具,还是不宜过度深入为好,哈哈。

golang gin 代理和改包

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/139786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 数据结构篇-实现双链表的核心API

🔥博客主页: 小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 双链表的说明 1.1 双链表 - 创建 1.2 双链表 - 根据索引查找节点 1.3 双链表 - 根据索引插入节点 1.4 双链表 - 头插节点 1.5 双链表 - 尾插 1.6 双链表 - 根据索引来…

Dell戴尔灵越Inspiron 7700 AIO一体机电脑原厂预装Windows10系统

链接:https://pan.baidu.com/s/1-slgR9t4Df_eko0Y6xaeyw?pwdmk0p 提取码:mk0p 灵越7700一体机原装出厂系统自带声卡驱动、无线网卡驱动、面部识别等所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 由于时间关系,…

Linux如何修改主机名(hostname)(亲测可用)

文章目录 背景Linux如何修改主机名(hostname)方法方法1. 使用 hostnamectl 命令示例 2. 编辑 /etc/hostname 文件注意事项 背景 我创建虚拟机的时候没设置主机名,现在显示localhost,有点尴尬😅: 需要重新设…

冒泡排序

贵阳这个地方的天气变化好大呀,前两天晒大太阳,今天就冷的脚抖,简直不要太冷,但是不管怎么样,还是要学习的哟! 冬天来了,春天确实还有一点远! 好了,话不多说,…

SpringBoot 缓存之 @Cacheable 详细介绍

一、简介 1、缓存介绍 Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache(JSR-107)注解简化我们的开发。 其…

由浅入深学习统计学 - 常用统计图形学习

学习笔记 第一章- 信息图形化 图形化(可视化) 在一堆数据中,自己发现了这些数据的规律,但是无法表述给其他人知道,图形化就是便于他人理解数据的规律的展示的手段。 或者说我们也可以从统计的数据图形中发现某些没有…

城市内涝积水预防,万宾科技内涝监测仪如何预警?

近几年来城市内涝所引发的安全隐患极为突出,影响着城市道路安全,而且也让市民心中多有惶恐。一旦城市内涝问题出现背后不仅是路面积水问题,更会导致城市无法正常运行,导致市民日常生活和工作受到影响。所以对于排水防涝设施的建设…

Linux之基础开发工具gdb调试器的使用(三)

文章目录 一、Linux调试器-gdb使用1、安装gdb2、背景3、Debug和release4、区分Debug和release 二、Linux调试器-gdb命令演示1、显示指定行之后的代码(自动记录最后一条指令)2、断点1、打印断点2、查看断点3、删除断点4、使能(禁用/开启&#…

智能一体化管网水位监测仪怎么样?

城市排水管网是城市正常运行的关键环节,这是地上和地下通道的连接点,一旦出现问题便会影响城市生命线建设的工程进展。在复杂的地下管道内想要了解水位数据,对于政府部门来讲是一个管理难题。如果可以采取智能产品在其中发挥作用,…

docker.service配置docker镜像加速

加速器配置方法很多,小白我用的是docker.service文件,所以直接在里面配置啊 配置以后,要systemctl daemon-reload下 ,然后docker info 下看下镜像地址是否是自己已配置的 docker run --privilegedtrue --name mytomcat -p 8080…

改进YOLO系列 | YOLOv5/v7 引入反向残差注意力模块 iRMB | 《ICCV 2023 最新论文》

论文地址:https://arxiv.org/abs/2301.01146 代码地址:https://github.com/zhangzjn/EMO 本论文着重于开发现代、高效、轻量级的模型,用于进行密集预测,同时在参数、FLOPs和性能之间进行权衡。倒置残差块(IRB)作为轻量级CNN的基础设施,但在基于注意力的研究中尚未找到对…

电脑版微信收到的图片怎么样自动保存到指定文件夹中?

8-5 在平时的工作中,如果你每天都需要接收并保存很多同事发来的图片,如何实现自动保存在微信上接收到的图片呢?本文的方法也许适合你,它可以自动把微信上收到的图片、视频、文件帮你保存到指定地方,可以大大地提高工作…

Pinia 状态管理器 菠萝:Option Store风格

Pinia介绍: Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。 Pinia 大小只有 1kb 左右,超轻量级,你甚至可能忘记它的存在! 相比 Vuex,Pinia 的优点: 更贴合 Vue 3 的 Composition API 风…

No185.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

STM32 寄存器配置笔记——GPIO配置输出

一、概述 本文主要介绍GPIO 作为输出时的寄存器配置。包括时钟配置,输出模式配置。以STM32F10xxx系列为例,配置PA8、PD2端口作为输出,输出高/低电平。 二、配置流程 1)GPIO外设时钟 通过查找STM32F10xxx中文参考手册得知&#xf…

【Python大数据笔记_day07_hive中的分区表、分桶表以及一些特殊类型】

分区表 分区表的特点/好处:需要产生分区目录,查询的时候使用分区字段筛选数据,避免全表扫描从而提升查询效率 效率上注意:如果分区表在查询的时候呀没有使用分区字段去筛选数据,效率不变 分区字段名注意:分区字段名不能和原有的字段名重复,因为分区字段名要作为字段拼接到表后…

Postman常见报错与解决方法,持续更新~

postman中文文档 基本操作:从控制台查看请求报错 如果 Postman 无法发送你的请求,或者如果它没有收到你发送请求的 API 的响应,你将收到一条错误消息。此消息将包含问题概述和指向控制台的链接,你可以在其中访问有关请求的详细信…

HelloGitHub 社区动态,开启新的篇章!

今天这篇文章是 HelloGitHub 社区动态的第一篇文章,所以我想多说两句,聊聊为啥开启这个系列。 我是 2016 年创建的 HelloGitHub,它从最初的一份分享开源项目的月刊,现如今已经成长为 7w Star 的开源项目、1w 用户的开源社区、全网…

Spring Cloud和Kubernetes + Spring Boot 用哪个?

Spring Cloud和Kubernetes Spring Boot都是用于构建微服务架构的解决方案,它们各有优势和不足,选择哪个更好取决于你的具体需求和上下文。 Spring Cloud是一个基于Spring Boot的微服务开发框架,它提供了一套完整的微服务解决方案&#xff0…