您当前的位置:首页 > 生活百科 > 社保

Golang模块代理goproxy.io源码研读

时间:2019-09-02 10:55:22  来源:  作者:
Golang模块代理goproxy.io源码研读

 

goproxy.io是一款很好用的Golang Module Proxy,解决了国内用户无法直接下载Golang模块依赖的问题。

本文准备研读一下其开源代码github.com/goproxyio/goproxy,了解下其实现原理。

goproxy工程的主要目录结构如下:

goproxy
 ├ build
 │ └ generate.sh
 ├ pkg
 │ └ proxy
 │ └ proxy.go
 └ main.go

main.go头部有一行代码:

//go:generate ./build/generate.sh

下面会解释其作用。

1 建立一个Golang Proxy服务需要实现哪些功能

$ go help goproxy
...
A Go module proxy is any web server that can respond to GET requests for
URLs of a specified form. The requests have no query parameters, so even
a site serving from a fixed file system (including a file:/// URL)
can be a module proxy.
The GET requests sent to a Go module proxy are:
GET $GOPROXY/<module>/@v/list returns a list of all known versions of the
given module, one per line.
GET $GOPROXY/<module>/@v/.info returns JSON-formatted metadata
about that version of the given module.
GET $GOPROXY/<module>/@v/.mod returns the go.mod file
for that version of the given module.
GET $GOPROXY/<module>/@v/.zip returns the zip archive
for that version of the given module.
...

从如上说明可知,使用诸如go get等go命令会从vcs下载所需模块,设置GOPROXY环境变量即可指定Go Module Proxy服务,其为不带参数URL的GET请求提供服务,为模块下载作了一层包装。

其主要提供如下几个接口:

a)GET $GOPROXY/<module>/@v/list

该接口返回给定模块的已知版本号列表,每行一个。

b)GET $GOPROXY/<module>/@v/<version>.info

该接口返回给定模块在给定版本的JSON格式的元数据信息。

c)GET $GOPROXY/<module>/@v/<version>.mod

该接口返回给定模块在给定版本的go.mod的内容。

d)GET $GOPROXY/<module>/@v/<version>.zip

该接口返回给定模块在给定版本的.zip压缩包。

为避免大小写敏感型文件系统服务问题,<module>及<version>会对大写字母加密,即将大写字母转换为!加小写字母的方式。

如github.com/Azure编码为github.com/!azure。

JSON格式的元数据信息对应的Go内置结构体为:

type Info struct {
 Version string // version string
 Time time.Time // commit time
}

给定模块在给定版本的.zip压缩包内的文件树结构与模块源码树结构一致,且模块及版本未使用大写字母加密。

不论go命令直接访问vcs还是从Proxy下载,其均会将模块的info、mod及zip文件组合到一起,置于$GOPATH/pkg/mod/cache/download本地缓存。

因缓存路径与请求路径对应,所以对$GOPATH/pkg/mod/cache/download文件夹以https://example.com/proxy提供服务即可访问到缓存的模块。

2 goproxy/build/generate.sh

当执行go generate命令时,Go会扫描当前包相关的源码文件,找出所有包含//go:generate的特殊注释,并执行注释指定的脚本。

因goproxy.io工程需要使用内置的模块获取包,而由上一篇文章“Golang 模块获取包modfetch研读”可知,modfetch、modload等模块获取包是位于cmd/go/internal路径下的,所以无法直接引用,main.go所指向的goproxy/build/generate.sh这个脚本即是用来将modfetch、modload等内部包及其依赖包拷贝至当前工作目录下,以便直接引用。

3 goproxy/main.go

main.go负责接收http请求,此外检查git有没有安装(因Go从诸如github.com等vcs下载新的依赖包需要依赖git工具),构造Golang Module的工作目录cacheDir等。

4 goproxy/pkg/proxy/proxy.go

proxy.go是该工程的核心代码,其会根据main.go传入的cacheDir设置工作目录。然后分别为后缀为.info,.mod,.zip,/@v/list,/@latest的几种类型的请求提供服务。

对如上类型的请求,会调用modfetch等包的内置函数来辅助实现,关于modfetch中几个核心函数的功能及用法,请参考上一篇博文:Golang 模块获取包modfetch研读。

a)若请求后缀为/@v/list,/@latest

因请求的是所有可用版本号或最新版本,所以必须请求vcs系统,所以可以使用modfetch.Lookup函数。

若是/@v/list,返回repo.Versions(""),若是/@latest,返回repo.Latest()。

b)若请求后缀为.info

使用modfetch.Stat函数,传入模块路径及版本号即可获取到修订信息,然后返回即可。

c)若请求后缀为.mod

使用modfetch.GoMod函数(源码中使用的是GoModFile,其实因需返回go.mod内容,使用GoMod即可),传入模块路径及版本号返回go.mod信息即可。

d)若请求后缀为.zip

使用modfetch.DownloadZip函数,其会返回文件路径,然后http.ServeFile即可。

如上即为goproxy.io对Go Module Proxy的实现,总体思路较清晰,代码较简洁。使用goproxy.io或将该开源代码搭建至一台国外ECS上,基本可以解决国内用户对Go Module无法直接下载的问题。

不过对于深度用户,有诸如权限管理、私有依赖管理等更高的需求。微软的工程师针对这些行业通用需求,实现了一个叫athens的工具,有机会可以学习一下。

原文链接:https://leileiluoluo.com/posts/goproxyio.html

本文作者:磊磊落落的博客,原创授权发布



Tags:goproxy.io   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
goproxy.io是一款很好用的Golang Module Proxy,解决了国内用户无法直接下载Golang模块依赖的问题。本文准备研读一下其开源代码github.com/goproxyio/goproxy,了解下其实现原...【详细内容】
2019-09-02  Tags: goproxy.io  点击:(406)  评论:(0)  加入收藏
▌简易百科推荐
导读:在生活中,人们经常会因为更换工作、经济压力等原因,造成养老和医保缴费中断。养老保险大家都比较重视,因为它会影响退休。但是,医保断缴3个月以上,会有哪些影响?万一断缴,该怎...【详细内容】
2021-12-27  人事通    Tags:医保断缴   点击:(5)  评论:(0)  加入收藏
对于参保人来说我们平时缴纳的社保里有一项是养老保险这样退休以后就可以领取养老金啦 但你知道领取养老金需要满足什么条件吗?弄懂领取养老金的条件只要记住两个关键词“15...【详细内容】
2021-12-23  新华融媒大三农    Tags:养老金   点击:(9)  评论:(0)  加入收藏
谁要办基本医疗保险关系转移接续?​​​​基本医保关系转移接续有哪几种情况?转移接续办理流程是怎样的?戳图了解...【详细内容】
2021-12-22    中国政府网  Tags:医保关系转移   点击:(12)  评论:(0)  加入收藏
来源 北京公积金编辑 高珊珊流程编辑 严圣淼...【详细内容】
2021-12-22    北京日报客户端  Tags:公积金   点击:(12)  评论:(0)  加入收藏
哈喽大家好,我是会计讲师老张,前两期文章我分享了失业保险网上领取步骤和医疗保险网上查询,今天我给大家分享养老保险网上如何查询!很多人一直在缴纳养老保险,可是想查询自己的缴...【详细内容】
2021-12-22  z老师讲会计    Tags:养老保险   点击:(16)  评论:(0)  加入收藏
关于退休办理医保补交的问题!我办理完退休手续后!又办理医保退休!补交了63个月的医保缴费!因为医保退休女职工要求必须连续交够20年!我企业下岗失业从2003年到2009年一直没交医...【详细内容】
2021-12-21  海棠花爱生活  今日头条  Tags:医保补交   点击:(7)  评论:(0)  加入收藏
针对老年人的养老问题,我国也是一直沿用的社会福利保障制度,只需要在自己退休之前交满十五年就可以了,对此就有不少人问道,是不是只要按最低标准交满15年社保,就能够满足自己退休...【详细内容】
2021-12-17  荣哥侃事    Tags:退休   点击:(11)  评论:(0)  加入收藏
12月份,为什么社保突然要补交1000多元呢?究竟是怎么回事呢?今年很多企业单位的在职人员,包括机关事业单位的在职人员,由于你所在地区上一年度社会平均工资的出台时间比较晚,导致这...【详细内容】
2021-12-14  社保小达人    Tags:社保   点击:(21)  评论:(0)  加入收藏
2021年,全国基本医保参保人数已达13.6亿人!医保卡几乎每个人都有,但是你真的知道它怎么使用吗?别人为什么看病能报销几万甚至十几万,而你却只能报销几千块钱!这里面到底有什么猫腻...【详细内容】
2021-12-14  海力保险经纪    Tags:医保卡   点击:(16)  评论:(0)  加入收藏
小王:我9月份从公司辞职了,现在待业在家,还没找到新工作,想自己交职工养老保险,怎么办理?老李:我在摆夜市摊儿,生意还不错,可是没有公司为我缴纳社保,我自己可以参加职工养老保险吗?社...【详细内容】
2021-12-13  社保小书童    Tags:社保   点击:(22)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条