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

从零实现支持缓存+上游代理的HTTP/HTTPS中间人代理

一、项目背景

在日常开发和运维中,我们经常需要访问各类开源软件包、镜像文件,反复下载相同资源会浪费大量带宽和时间。本文将手把手教你用Go语言实现一个支持缓存的HTTP/HTTPS中间人代理服务器,核心功能包括:

  • 支持HTTP/HTTPS全量代理(中间人模式)
  • 自动缓存可复用资源(压缩包、二进制文件、静态资源等)
  • 配置上游HTTP代理转发请求
  • 高性能日志输出(基于Zap框架)
  • 解决Go net/http库默认重定向导致的CONNECT请求301错误

项目完整代码:https://gitee.com/impl/myproxy

二、核心技术点

  • Go net/http Hijack:劫持CONNECT请求,建立HTTPS隧道
  • TLS中间人代理:自签CA证书,动态生成目标域名证书
  • 文件缓存:基于文件扩展名的缓存策略,减少重复下载
  • 上游代理集成:所有对外请求通过指定代理转发
  • Zap日志框架:结构化日志输出,替代原生fmt.Printf

三、实现步骤

3.1 项目初始化

# 初始化Go模块go mod init myproxy# 安装依赖(Zap日志框架)go get go.uber.org/zap

3.2 核心问题解决:CONNECT请求301重定向

问题现象

使用Go原生ServeMux处理CONNECT请求时,会触发net/http库的路径规范化逻辑,返回301 Moved Permanently重定向,导致HTTPS隧道建立失败。

解决方案:自定义Handler完全接管请求

绕过默认ServeMux,实现自定义http.Handler接口,在最顶层处理CONNECT请求:

// 自定义Handler,完全接管所有请求typeProxyHandlerstruct{cm*CacheManager tm*TLSManager}func(ph*ProxyHandler)ServeHTTP(w http.ResponseWriter,r*http.Request){logger.Debug("收到请求",zap.String("method",r.Method),zap.String("url",r.URL.String()),zap.String("remoteAddr",r.RemoteAddr))// 最顶层判断CONNECT,直接处理ifr.Method==http.MethodConnect{handleConnect(w,r,ph.cm,ph.tm)return}// 其他请求走HTTP代理逻辑httpProxyHandler(ph.cm)(w,r)}
CONNECT请求处理(关键修复)

立即劫持连接,发送标准200响应,避免默认逻辑干扰:

// 独立的CONNECT处理函数funchandleConnect(w http.ResponseWriter,r*http.Request,cm*CacheManager,tm*TLSManager){logger.Info("处理CONNECT请求",zap.String("host",r.URL.Host),zap.String("remoteAddr",r.RemoteAddr))// 立即劫持连接,绕过所有默认逻辑hj,ok:=w.(http.Hijacker)if!ok{logger.Error("服务器不支持Hijack",zap.String("remoteAddr",r.RemoteAddr))http.Error(w,"服务器不支持Hijack",http.StatusInternalServerError)return}conn,bufrw,err:=hj.Hijack()iferr!=nil{logger.Error("Hijack失败",zap.Error(err),zap.String("remoteAddr",r.RemoteAddr))http.Error(w,err.Error(),http.StatusInternalServerError)return}// 发送标准的200响应,建立隧道_,err=bufrw.WriteString("HTTP/1.1 200 Connection established\r\n\r\n")iferr!=nil{logger.Error("发送200响应失败",zap.Error(err),zap.String("remoteAddr",r.RemoteAddr))conn.Close()return}err=bufrw.Flush()iferr!=nil{logger.Error("刷新缓冲区失败",zap.Error(err),zap.String("remoteAddr",r.RemoteAddr))conn.Close()return}// 启动中间人代理,连接的关闭由handleHTTPSMitm负责gohandleHTTPSMitm(cm,tm,conn)}

3.3 集成上游代理

添加上游代理配置,所有对外请求通过指定代理转发:

// 全局上游代理配置varupstreamProxyURL*url.URL// 创建带上游代理的HTTP客户端funccreateProxyClient()*http.Client{transport:=&http.Transport{TLSClientConfig:&tls.Config{InsecureSkipVerify:true},Proxy:http.ProxyURL(upstreamProxyURL),// 使用上游代理}return&http.Client{Timeout:10*time.Minute,Transport:transport,}}

3.4 缓存功能实现

基于文件扩展名的缓存策略,自动缓存常用资源:

// 判断URL是否可缓存func(cm*CacheManager)isCacheableURL(urlStrstring)bool{ext:=filepath.Ext(urlStr)returncm.cacheableExt[strings.ToLower(ext)]}// 缓存命中逻辑ifreq.Method==http.MethodGet&&cm.hasCache(fullURL){logger.Info("缓存命中",zap.String("url",fullURL))data,err:=cm.readCache(fullURL)iferr!=nil{http.Error(rw,fmt.Sprintf("读取缓存失败: %v",err),http.StatusInternalServerError)req.Body.Close()continue}rw.Header().Set("X-Cache","HIT")rw.WriteHeader(http.StatusOK)rw.Write(data)req.Body.Close()continue}

3.5 替换Zap日志框架

替代原生fmt.Printf,实现结构化日志输出:

// 初始化Zap日志funcinitLogger(){config:=zap.NewProductionConfig()config.EncoderConfig=zapcore.EncoderConfig{TimeKey:"time",LevelKey:"level",NameKey:"logger",CallerKey:"caller",FunctionKey:zapcore.OmitKey,MessageKey:"msg",StacktraceKey:"stacktrace",LineEnding:zapcore.DefaultLineEnding,EncodeLevel:zapcore.CapitalLevelEncoder,EncodeTime:zapcore.ISO8601TimeEncoder,EncodeDuration:zapcore.SecondsDurationEncoder,EncodeCaller:zapcore.ShortCallerEncoder,}config.Level=zap.NewAtomicLevelAt(zap.InfoLevel)varerrerrorlogger,err=config.Build()iferr!=nil{panic(fmt.Sprintf("初始化日志失败: %v",err))}deferlogger.Sync()}

四、CA证书配置

4.1 生成CA证书

启动代理时会自动生成CA证书(路径:./proxy_ca/ca.crt),需要将证书导入客户端信任列表。

4.2 不同系统证书导入

Ubuntu/Debian
sudocpca.crt /usr/local/share/ca-certificates/sudoupdate-ca-certificates
AnolisOS/CentOS/RHEL
dnfinstall-y ca-certificatescpca.crt /etc/pki/ca-trust/source/anchors/ update-ca-trust extract
临时测试(跳过证书验证)
curl-x http://192.168.56.1:8080 --proxy-insecure -O https://github.com/labring/sealos/releases/download/v5.1.1/sealos_5.1.1_linux_amd64.tar.gz

五、运行与测试

5.1 编译运行

# 编译go build -o myproxy main.go# 运行(指定上游代理)./myproxy -l0.0.0.0:8080 -u http://192.168.56.1:10811

5.2 客户端测试

# 下载文件(自动缓存)curl-x http://192.168.56.1:8080 -O https://github.com/labring/sealos/releases/download/v5.1.1/sealos_5.1.1_linux_amd64.tar.gz# 验证缓存(第二次下载会命中缓存)curl-x http://192.168.56.1:8080 -O https://github.com/labring/sealos/releases/download/v5.1.1/sealos_5.1.1_linux_amd64.tar.gz

六、关键问题排查

6.1 CONNECT请求301重定向

  • 原因:Go net/http默认路径规范化导致
  • 解决:自定义Handler完全接管请求,绕过ServeMux

6.2 use of closed network connection

  • 原因:handleConnect中defer conn.Close()提前关闭连接
  • 解决:移除defer,由handleHTTPSMitm负责连接关闭

6.3 tls: bad record MAC

  • 原因:客户端不信任代理CA证书
  • 解决:导入CA证书或使用–proxy-insecure跳过验证

七、总结

本文实现的代理服务器具备以下核心能力:

  1. 支持HTTP/HTTPS全量代理,解决了Go原生库的301重定向问题
  2. 集成上游代理,可通过代理访问外部资源
  3. 基于文件扩展名的缓存策略,减少重复下载
  4. 替换Zap日志框架,实现结构化、分级别的日志输出
  5. 跨系统的CA证书配置方案,适配Ubuntu/AnolisOS等发行版

该代理可广泛应用于开发环境、内网镜像加速、资源缓存等场景,完整代码已开源至Gitee,可直接部署使用。

附:命令行参数说明

参数简写说明默认值
–listen-addr-l监听地址0.0.0.0:8080
–cache-dir-d缓存目录./proxy_cache
–ca-dir-cCA证书目录./proxy_ca
–upstream-proxy-u上游代理地址
–help-h显示帮助-
http://www.jsqmd.com/news/378512/

相关文章:

  • 2026年靠谱的粉末包装机厂家推荐:粉末包装机品牌哪家强? - 深度智识库
  • 2026年性价比高的润色企业大盘点,靠谱品牌别错过 - 工业推荐榜
  • 幸运水分仪靠谱吗,看看维修成本和市场口碑就知道 - mypinpai
  • 京东e卡高价回收,帮你快速变现! - 团团收购物卡回收
  • 银川设备搬运选哪家?尖兵搬家,专业护航各类单位设备安全转运 - 宁夏壹山网络
  • 如何为金融与制造行业选型?2026年瀑布管理软件全面评测与推荐,直击流程标准化痛点 - 品牌推荐
  • 2026年长沙GEO正规机构哪家性价比高,为你揭晓 - 工业品网
  • 2026年热门的远程激光灯/婚礼激光灯哪家强公司实力参考(精选) - 品牌宣传支持者
  • 2026年产品管理平台推荐:基于行业应用实测评价,针对规划与追溯痛点精准指南 - 品牌推荐
  • 2026年枕式包装机厂家实力推荐:食品包装机、五金配件包装机、颗粒包装机、粉末包装机源头工厂精选,解析技术创新与稳定产能核心优势 - 深度智识库
  • Admin.NET开源版微服务改造记录
  • 百元保费百万保额!首信保险代理联合泰康在线推出“安心保百万重疾险” - 包罗万闻
  • 2026年口碑好的桑蚕丝绒/混纺丝绒推荐几家可靠供应商参考 - 品牌宣传支持者
  • 2026年国内枕式包装机品牌TOP5:规模实力优选榜单+数据背书 - 深度智识库
  • 2026食用面碱头部企业推荐:品质与口碑兼具,型煤淀粉/纸袋淀粉/锅包肉专用粉/复合淀粉,食用面碱供应商怎么选择 - 品牌推荐师
  • 构建高效系统:IO操作扩展技术全解析
  • 深耕专业,引领行业!首信保险代理获任广东保险中介行业协会第四届保险代理专业委员会副主任委员单位 - 包罗万闻
  • 瑞祥商联卡闲置别浪费!靠谱的回收方式,可可收亲测好用 - 可可收
  • 新春臻选健康好物,iHerb守护全家日常美好 - 博客万
  • 2026年苏州加热盘生产厂排名,如何选择靠谱品牌 - mypinpai
  • Nodejs+vue+ElementUI的美食商城交流平台的设计与实现
  • 如何选择适配复杂场景的平台?2026年项目集管理平台评测与推荐,直击数据孤岛痛点 - 品牌推荐
  • 如何选择适配敏捷与瀑布的项目工具?2026年project管理系统全面评测与推荐 - 品牌推荐
  • 提升SEO效果的长尾关键词运用与应用策略解析
  • 2026年食品包装机厂家推荐:食品包装机服务商权威测评与深度解析 - 深度智识库
  • 专科生必看!碾压级的降AI率平台 —— 千笔·降AI率助手
  • Nodejs+vue+ElementUI的校园电影网站的设计与实现express-mysql
  • 2026年项目集管理工具推荐:大型企业战略级场景深度评测,解决多项目协同与资源统筹痛点 - 品牌推荐
  • 实测对比后一键生成论文工具 千笔写作工具 VS 锐智 AI 本科生必备
  • 2026年专业读写台品牌排名,佳视路读写台对坐姿有帮助吗 - myqiye