当前位置: 首页 > news >正文

基于 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 代理和改包

相关文章:

基于 Gin 的 HTTP 代理 demo

上次用 TCP 模拟了一个 HTTP 代理之后,感觉那样还是太简陋了,想着是不是可以用框架来做一个有点实际用处的东西。所以,就思索如何用 golang 的 Gin 框架来实现一个?嗯,对的你没有听错,是 gin 框架。你可能会…...

【ATTCK】MITRE Caldera - 测试数据泄露技巧

CALDERA是一个由python语言编写的红蓝对抗工具(攻击模拟工具)。它是MITRE公司发起的一个研究项目,该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的,能够较真实地APT攻击行为模式。 通过CALDERA工具,安全…...

【数据结构】树与二叉树(十二):二叉树的递归创建(算法CBT)

文章目录 5.2.1 二叉树二叉树性质引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i≥0。引理5.2:高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点,其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…...

Qt绘制网格和曲线

绘制网格: void Widget::drawGrid(QPainter &p, QRect &windRect) {QRect rect(windRect.left()m_margins.left(),windRect.top()m_margins.top(),windRect.width()-m_margins.left()-m_margins.right(),windRect.height()-m_margins.top()-m_margins.bo…...

2023-11-12

今日比较摆烂, 但是把自写管道的原理搞懂了, 主要是把 exp 完完全全看懂了, 还不错. 然后就没干啥了. 明日计划: 学校的作业. AFL 源码. 我真是服了我自己了, AFL 源码搁多久了, 操操操 然后把 seccomp 重新学习下...

[工业自动化-16]:西门子S7-15xxx编程 - 软件编程 - 西门子仿真软件PLCSIM

目录 前言: 一、PLCSIM仿真软件 1.1 PLCSIM仿真软件基础版(内嵌) 1.2 PLCSIM仿真软件与PLCSIM仿真软件高级版的区别? 1.3 PLCSIM使用 前言: PLC集成开发环境是运行在Host主机上,Host主机与PLC可以通过…...

运行npm install卡住不动的几种解决方案

在前端开发经常会遇到运行npm install 来安装工具包一直卡住不动,为此这里提供几种解决方案,供大家参考学习,不足之处还请指正。 第一种方案、首先检查npm代理,是否已经使用国内镜像 // 执行以下命令查看是否为国内镜像 npm con…...

[Android]_[初级]_[配置gradle的环境变量设置安装位置]

场景 在开发Android项目的时候, gradle是官方指定的构建工具。不同项目通过wrapper指定不同版本的gradle。随着项目越来越多,使用的gradle版本也增多,导致它以来的各种库也增加,系统盘空间不足,怎么解决? 说明 grad…...

docker更改存储目录原因及方案

为什么一定要将docker的存储目录挂载到其他目录 docker在安装时默认存储目录在/var/lib/docker,而该目录是在系统盘下的。docker安装后,会使用各种各样的镜像,动辄几个G,那么如此多的镜像文件,装着装着系统盘就撑爆了…...

HTTPS的工作流程

. HTTPS是什么? https是应用层中的一个协议,是在http协议的基础上引入的一个加密层。 为什么需要HTTPS 由于http协议内容都是按照文本的方式明文传输的,这就导致传输过程中会出现一些被篡改的情况。运营商劫持事件最开始百度,…...

C++语言的广泛应用领域

目录 1. 系统级编程 2. 游戏开发 3. 嵌入式系统 4. 大数据处理 5. 金融和量化分析 6. 人工智能和机器学习 7. 网络和通信 结语 C是一种多范式编程语言,具有高性能、中级抽象能力和面向对象的特性。由Bjarne Stroustrup于1979年首次设计并实现,C在…...

Lambertian模型(完美漫反射)

这里使用相乘的方式组合光照色和纹理色。根据这个模型,面朝光源的区域光照强度高,纹理色也相应增强。面背光源的区域光照弱,纹理色也被抑制。这样通过光照和纹理的结合,可以合成出具有照明效果的面部颜色,而不仅仅是固定的纹理本身的颜色。相乘方式可以近似实现不同光照方向下面…...

MATLAB的编程与应用,匿名函数、嵌套函数、蒙特卡洛法的掌握与使用

目录 1.匿名函数 1.1.匿名函数的定义与分类 1.2.匿名函数在积分和优化中应用 2.嵌套函数 2.1.嵌套函数的定义与分类 2.2.嵌套函数彼此调用关系 2.3.嵌套函数在积分和微分中应用 3.微分和积分 4.蒙特卡洛法 4.1.圆周率的模拟 4.2.计算N重积分(均匀分布&am…...

NFS服务器的搭建

架设一台NFS服务器,并按照以下要求配置 准备阶段:准备两台虚拟机,一台作为服务端,一台作为客户端 服务端(Server):192.168.75.139 客户端(Client):192.168.75.160 两…...

安卓Frida 常用脚本

打印调用堆栈, hook 某个方法,想看下调用堆栈,代码如下: function showStacks() {Java.perform(function () {send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));});} 二,需要hook okhttp3 HttpUrl …...

机器学习数据预处理——Word2Vec的使用

引言: Word2Vec 是一种强大的词向量表示方法,通常通过训练神经网络来学习词汇中的词语嵌入。它可以捕捉词语之间的语义关系,对于许多自然语言处理任务,包括情感分析,都表现出色。 代码: 重点代码&#…...

面试算法常考题之-------逆波兰式合集

逆波兰式背景介绍 逆波兰式是一种特殊的数学表达式表示法,它的诞生背景可以追溯到20世纪30年代。当时,波兰数学家Jan Wjtowicz和Wacław Sierpiński提出了一种新的数学表达式表示法,这种表示法将运算符放在操作数之后,而不是传统…...

独热编码和Word2Vec的区别

独热编码和Word2Vec都是自然语言处理中将词向量化的方式,但它们之间并没有直接的关系或依赖性。它们可以被视为在处理词向量时的两种不同方法或策略。 独热编码是一种简单直观的方法,每个词被表示为一个长向量,其中只有一个元素是1&#xff0…...

RestTemplate.postForEntity 方法进行 HTTP POST 请求

RestTemplate 是 Spring Framework 提供的一个用于处理 HTTP 请求的客户端工具。其中&#xff0c;postForEntity 是 RestTemplate 提供的用于发送 HTTP POST 请求并返回 ResponseEntity 对象的方法。 public <T> ResponseEntity<T> postForEntity(String url, Obj…...

盘点双11!阿里妈妈助这些品牌短视频赢增长!

刚刚&#xff01;一年一度的双11落下帷幕&#xff0c;很多新变化值得回味。 尽管天气在变凉&#xff0c;但市场出现了逐渐回暖的迹象。在此背景下&#xff0c;大量商家特别关心如何在双11打一场漂亮的胜仗。 卖方如何行动&#xff0c;关键在于买方的变化。在阿里妈妈发布的《…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...