go net/url:无法解码 %ya,而浏览器更加宽容,

v1uwarro  于 6个月前  发布在  Go
关注(0)|答案(6)|浏览(42)

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

go version go1.11.4 freebsd/amd64

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

是的

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

go env GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="freebsd" GOOS="freebsd" GOPATH="/root/go" GOPROXY="" GORACE="" GOROOT="/usr/local/go" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/freebsd_amd64" GCCGO="gccgo" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="" 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=/tmp/go-build246043989=/tmp/go-build -gno-record-gcc-switches"

$ go env

你做了什么?

Yandex网页应用( https://yandex.ru/search )定期发送请求,例如:

https://yandex.ru/clck/click/reqid=1545391593487252-912524167688176914537851-man1-1492/path=690.491.59/vars=-no=19,-blob=aYLIB2m%yAdp%sgHabbJBw__/*https://yandex.ru/search/?text=%D0%BF%D1%80%D0%BE%D0%BC%D0%BE%D0%BA%D0%BE%D0%B4%20%D0%BE%D1%81%D0%B5%D1%82%D0%B8%D0%BD%D1%81%D0%BA%D0%B8%D0%B5%20%D0%BF%D0%B8%D1%80%D0%BE%D0%B3%D0%B8%20ospirogi&lr=213

我使用url.ParseRequestURI()解析这个URL,它返回一个错误,但我认为这个URL是有效的。

你期望看到什么?

解析后的URL。

你看到了什么?

错误:

parse https://yandex.ru/clck/click/reqid=1545391593487252-912524167688176914537851-man1-1492/path=690.491.59/vars=-no=19,-blob=aYLIB2m%yAdp%sgHabbJBw__/*https://yandex.ru/search/?text=%D0%BF%D1%80%D0%BE%D0%BC%D0%BE%D0%BA%D0%BE%D0%B4%20%D0%BE%D1%81%D0%B5%D1%82%D0%B8%D0%BD%D1%81%D0%BA%D0%B8%D0%B5%20%D0%BF%D0%B8%D1%80%D0%BE%D0%B3%D0%B8%20ospirogi&lr=213: invalid URL escape "%yA"
eh57zj3b

eh57zj3b1#

根据标准RFC 3986的第2.1节,百分比编码字符必须具有以下形式:
pct-encoded = "%" HEXDIG HEXDIG
而百分号(%)本身必须编码为:
由于百分号("%")字符作为百分比编码八位字节的指示符,因此该八位字节必须以"%25"的形式进行百分比编码才能用作URI中的数据。
因此,字符序列%yA肯定是一个无效的百分比编码字符。尽管如此,大多数URL解析器(尤其是Web浏览器)对此类错误更加宽容。

14ifxucb

14ifxucb2#

谢谢,我会等待决定。

oknwwptz

oknwwptz3#

一个较短的版本是 http://site/x%ya 。问题在于解码路径。在这里,URL.Path字段可能被设置为什么值还不清楚。没有任何东西会往返传递到 x%ya 。这个URL是否意味着等同于 /x%25ya ,即在解码后变为 "/x%ya"?
Apache或Nginx会做什么?

j0pj023g

j0pj023g4#

这个URL是否意味着它在解码后等同于/x%ya,即在解码后为"/x%ya"?
我认为是的。但是我已经用Nginx(列出目录模式和反向代理)测试了这个情况,它只接受像http://site/x%25ya这样的URL,而不是http://site/x%ya

h4cxqtbf

h4cxqtbf5#

我查阅了WHATWG URL标准关于这个问题的内容。我不是说Go必须遵循它,只是举个例子。
https://url.spec.whatwg.org/#path-state
否则,执行以下步骤:

  1. 如果c不是URL码点且不是U+0025(%),则报验证错误。
  2. 如果c是U+0025(%)且剩余部分不以两个ASCII十六进制数字开头,则报验证错误。
  3. 使用路径百分比编码集对c进行UTF-8百分比编码,并将结果追加到缓冲区。
    首先,“验证错误”不是一个硬错误:解析器可能会继续,并单独报告错误。
    其次,我认为他们不希望解析器在解析URL的路径部分时自动解码百分比编码。第3点意味着某些字符,如{,在解析时应转换为%7B
uqdfh47h

uqdfh47h6#

可以通过使用单独的URL解析器来解决这个问题,例如https://github.com/nlnwa/whatwg-url,但不幸的是,net/http坚持通过net/url解析URL本身,并且不允许用字符串覆盖Request-URI。

相关问题