`cmd/go:验证从go-get=1查询接收到的模块代理URLs`

wi3ka0sx  于 5个月前  发布在  Go
关注(0)|答案(7)|浏览(43)

你使用的Go版本是什么( go version )?

Go提示在 CL 170879 或更高版本。

这个问题在最新版本中是否重现?

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env

GOARCH="amd64"

GOBIN=""

GOCACHE=SHOWS_CORRECTLY

GOEXE=""

GOFLAGS=""

GOHOSTARCH="amd64"

GOHOSTOS="darwin"

GOOS="darwin"

GOPATH=SHOWS_CORRECTLY

GOPROXY=""

GORACE=""

GOROOT="/usr/local/Cellar/go/1.12.2/libexec"

GOTMPDIR=""

GOTOOLDIR="/usr/local/Cellar/go/1.12.2/libexec/pkg/tool/darwin_amd64"

GCCGO="gccgo"

CC="clang"

CXX="clang++"

CGO_ENABLED="1"

GOMOD=SHOWS_CORRECTLY

CGO_CFLAGS="-g -O2"

CGO_CPPFLAGS=""

CGO_CXXFLAGS="-g -O2"

CGO_FFLAGS="-g -O2"

CGO_LDFLAGS="-g -O2"

PKG_CONFIG="pkg-config"

GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j0/qxnj38ld075bj80p9hs2dqlw0000gn/T/go-build144819988=/tmp/go-build -gno-record-gcc-switches -fno-common"

你做了什么?

在travis上,当运行针对主分支的测试时,无法下载模块。我不确定这是否是因为travis,还是可以在其他地方复制。

你期望看到什么?

成功下载模块

你看到了什么?

go: github.com/golang-migrate/migrate/v4@v4.3.0 requires
	github.com/fsouza/fake-gcs-server@v1.5.0 requires
	cloud.google.com/go@v0.36.0 requires
	golang.org/x/build@v0.0.0-20190111050920-041ab4dc3f9d requires
	dmitri.shuralyov.com/app/changes@v0.0.0-20180602232624-0a106ad413e3: Get https:///dmitri.shuralyov.com/app/changes/@v/v0.0.0-20180602232624-0a106ad413e3.info: http: no Host in request URL
The command "go mod download" failed and exited with 1 during .

具体来说,URL中的3个斜杠(/)。删除斜杠可以正确解析。

sc4hvdpw

sc4hvdpw2#

dmitri.shuralyov.com 目前正在提供非常不寻常的 go-import 标签:

~/go/src$ curl -L dmitri.shuralyov.com/app/changes?go-get=1
<meta name="go-import" content="dmitri.shuralyov.com/app/changes git https://dmitri.shuralyov.com/app/changes">
<meta name="go-import" content="dmitri.shuralyov.com/app/changes mod https://">
<meta name="go-source" content="dmitri.shuralyov.com/app/changes https://dmitri.shuralyov.com/app/changes https://gotools.org/dmitri.shuralyov.com/app/changes https://gotools.org/dmitri.shuralyov.com/app/changes#{file}-L{line}">

请注意第二行:它包括一个裸露的 https://,依赖于模块代理协议来填充主机名。根据 @dmitshur 的说法(在 Go 1.11 中),这曾经起作用,但现在已经不再起作用了,我怀疑这是一个好事。

ruoxqz4g

ruoxqz4g3#

Assigning to Dmitri to either update his server, or make a convincing argument that we should allow the bare https:// . 🙂

3npbholx

3npbholx5#

我编辑了原始问题,使其更清楚地表明这仅影响Go tip。Go 1.12和Go 1.11不受影响。
我认为有两个问题,一个在cmd/go中,另一个是当前如何提供dmitri.shuralyov.com/app/changes的 vanity import path:

  1. go命令在遇到无效/不受支持的模块代理URL时可以返回更好的错误信息。"https://"是一个有效的URL:它指定了HTTPS方案,但没有主机和路径;参见https://play.golang.org/p/vmTPnZffjDf。但我认为这不是一个有效的模块代理URL。我认为一个模块代理URL必须有一个非空的主机。
  2. dmitri.shuralyov.com/app/changes的 vanity import path目前使用"https://"作为模块代理URL。这在Go 1.11和1.12中曾经起作用(也许是无意中发生的),在Go tip之后不再起作用。我认为 vanity import path 应该更改为返回一个具有非空主机的模块代理URL,以便它能在Go 1.13及以后继续工作。

**编辑于2019年5月18日:**这个问题已经在提交shurcooL/home@17791dc中修复,参见cmd/go:从go-get=1查询接收到的模块代理URL验证#32006(评论)。

由于它只影响tip,而不是当前发布的Go稳定版本,我正在利用上述 vanity import path 作为了解新的Go tip行为的机会,并学习如何最好地处理这样的URL。
我计划在接下来的几天内修复dmitri.shuralyov.com/app/changes的 vanity import path,但请告诉我如果在Go tip中不起作用是否比我知道的问题更破坏性,我会尽快解决。

背景

模块代理协议文档没有非常正式地说明模块代理的URL是如何与路径的其他部分拼接在一起的。它只是说:
向Go模块代理发送的GET请求是:
GET $GOPROXY//@v/list 返回给定模块的所有已知版本的列表,每行一个。
GET $GOPROXY/<module>/@v/list文本没有明确说明哪些类型的有效URL允许用于$GOPROXY。"https://"碰巧在1.11和1.12中起作用。
这样做的好处是可以让 vanity import path 在不重复的情况下为一个模块提供URL。也就是说,对于一个 vanity import path example.com/foo,它的 @v/list 端点可以在 " https://example.com/foo/@v/list " 而不是 " https://example.com/example.com/foo/@v/list " 或 " https://example.com/moduleproxy/example.com/foo/@v/list " 上提供服务,后者更冗长。
然而,在花了更多时间思考和与一些人讨论之后,我认为 $GOPROXY URL需要有一个受支持的方案和一个非空的主机。我无法找到一种简单明了的方法来使一个空主机的URL起作用。
不幸的是,这意味着一个由其自己的域提供的带有 vanity import path 的模块将具有由于重复主机而更冗长的模块代理URL,但这似乎是值得付出的权衡。如果有人对此有更多想法,我很乐意听取。

vom3gejh

vom3gejh6#

我已经在以路径 dmitri.shuralyov.com 开头的模块的 commit shurcooL/home@17791dc 中更改了用于提供模块的模块代理 URL。现在,URL中包含一个非空的主机:

$ curl -L 'https://dmitri.shuralyov.com/app/changes?go-get=1'
<meta name="go-import" content="dmitri.shuralyov.com/app/changes git https://dmitri.shuralyov.com/app/changes">
<meta name="go-import" content="dmitri.shuralyov.com/app/changes mod https://dmitri.shuralyov.com/api/module">
<meta name="go-source" content="dmitri.shuralyov.com/app/changes https://dmitri.shuralyov.com/app/changes https://gotools.org/dmitri.shuralyov.com/app/changes https://gotools.org/dmitri.shuralyov.com/app/changes#{file}-L{line}">

因此,这些模块可以使用 Go 1.11、1.12 和最新版本成功获取。
为了让我们能够继续测试这个问题并改进 go 命令在遇到无效的模块代理 URL 时所做的错误报告,我在这里留下了一个仍然使用 "https://" 作为模块代理 URL 的测试模块:
https://dmitri.shuralyov.com/test/modtest2
这是最新 Go 版本(commit 1ab063c)在尝试获取它(直接获取,没有本地 GOPROXY)时的当前错误消息:

$ gotip version
go version devel +1ab063c Fri May 17 22:32:30 2019 +0000 darwin/amd64
$ export GO111MODULE=on
$ export GOPROXY=direct
$ export GOPATH=$(mktemp -d)
$ cd $(mktemp -d)
$ gotip mod init m
go: creating new go.mod: module m
$ gotip get dmitri.shuralyov.com/test/modtest2
go: finding dmitri.shuralyov.com/test/modtest2 v0.0.0
go: dmitri.shuralyov.com/test/modtest2@v0.0.0: Get https:///dmitri.shuralyov.com/test/modtest2/@v/v0.0.0.info: http: no Host in request URL
zbdgwd5y

zbdgwd5y7#

https://golang.org/cl/191945提到了这个问题:cmd/go: validate module proxy URLs received from go get queries

相关问题