日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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

本文作者:磊磊落落的博客,原創授權發布

分享到:
標簽:goproxy io
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定