vendor,go.*: update x/crypto and x/text modules
Update the vendored golang.org/x/crypto and golang.org/x/text modules to the latest versions, which in turn updates the vendored copy of the golang.org/x/net and golang.org/x/sys modules. Updating these modules' entries in vendor/modules.txt and go.{mod,sum} means we will not be flagged by security scanners regarding either CVE-2021-38561 or CVE-2022-27191, neither of which should actually affect Git LFS. The Git LFS client should not be affected by CVE-2021-38561 as it pertains the Go x/text/language package and specifically the BCP 47 tag functions, which Git LFS does not use. The Git LFS client should not be affected by CVE-2022-27191 as it pertains to the Go x/crypto/ssh package and specifically a crash vulnerability in the SSH server functions, which Git LFS does not use. The specific commands run to perform this update were: go get golang.org/x/crypto@latest && go get golang.org/x/text@latest && go mod tidy && go mod vendor
This commit is contained in:
parent
efc4bcba18
commit
c175fdb049
6
go.mod
6
go.mod
@ -22,11 +22,11 @@ require (
|
|||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d
|
github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
|
||||||
golang.org/x/text v0.3.5 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.11
|
go 1.11
|
||||||
|
16
go.sum
16
go.sum
@ -68,17 +68,16 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -86,14 +85,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
@ -32,7 +32,7 @@ import (
|
|||||||
// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
|
// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
|
||||||
// doing:
|
// doing:
|
||||||
//
|
//
|
||||||
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
|
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
|
||||||
//
|
//
|
||||||
// Remember to get a good random salt. At least 8 bytes is recommended by the
|
// Remember to get a good random salt. At least 8 bytes is recommended by the
|
||||||
// RFC.
|
// RFC.
|
||||||
|
10
vendor/golang.org/x/net/http/httpguts/httplex.go
generated
vendored
10
vendor/golang.org/x/net/http/httpguts/httplex.go
generated
vendored
@ -137,11 +137,13 @@ func trimOWS(x string) string {
|
|||||||
// contains token amongst its comma-separated tokens, ASCII
|
// contains token amongst its comma-separated tokens, ASCII
|
||||||
// case-insensitively.
|
// case-insensitively.
|
||||||
func headerValueContainsToken(v string, token string) bool {
|
func headerValueContainsToken(v string, token string) bool {
|
||||||
v = trimOWS(v)
|
for comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {
|
||||||
if comma := strings.IndexByte(v, ','); comma != -1 {
|
if tokenEqual(trimOWS(v[:comma]), token) {
|
||||||
return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
|
return true
|
||||||
|
}
|
||||||
|
v = v[comma+1:]
|
||||||
}
|
}
|
||||||
return tokenEqual(v, token)
|
return tokenEqual(trimOWS(v), token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// lowerASCII returns the ASCII lowercase version of b.
|
// lowerASCII returns the ASCII lowercase version of b.
|
||||||
|
4
vendor/golang.org/x/net/http/httpproxy/proxy.go
generated
vendored
4
vendor/golang.org/x/net/http/httpproxy/proxy.go
generated
vendored
@ -113,8 +113,8 @@ func getEnvAny(names ...string) string {
|
|||||||
// environment, or a proxy should not be used for the given request, as
|
// environment, or a proxy should not be used for the given request, as
|
||||||
// defined by NO_PROXY.
|
// defined by NO_PROXY.
|
||||||
//
|
//
|
||||||
// As a special case, if req.URL.Host is "localhost" (with or without a
|
// As a special case, if req.URL.Host is "localhost" or a loopback address
|
||||||
// port number), then a nil URL and nil error will be returned.
|
// (with or without a port number), then a nil URL and nil error will be returned.
|
||||||
func (cfg *Config) ProxyFunc() func(reqURL *url.URL) (*url.URL, error) {
|
func (cfg *Config) ProxyFunc() func(reqURL *url.URL) (*url.URL, error) {
|
||||||
// Preprocess the Config settings for more efficient evaluation.
|
// Preprocess the Config settings for more efficient evaluation.
|
||||||
cfg1 := &config{
|
cfg1 := &config{
|
||||||
|
2
vendor/golang.org/x/net/http2/Dockerfile
generated
vendored
2
vendor/golang.org/x/net/http2/Dockerfile
generated
vendored
@ -38,7 +38,7 @@ RUN make
|
|||||||
RUN make install
|
RUN make install
|
||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
|
RUN wget https://curl.se/download/curl-7.45.0.tar.gz
|
||||||
RUN tar -zxvf curl-7.45.0.tar.gz
|
RUN tar -zxvf curl-7.45.0.tar.gz
|
||||||
WORKDIR /root/curl-7.45.0
|
WORKDIR /root/curl-7.45.0
|
||||||
RUN ./configure --with-ssl --with-nghttp2=/usr/local
|
RUN ./configure --with-ssl --with-nghttp2=/usr/local
|
||||||
|
20
vendor/golang.org/x/net/http2/README
generated
vendored
20
vendor/golang.org/x/net/http2/README
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
This is a work-in-progress HTTP/2 implementation for Go.
|
|
||||||
|
|
||||||
It will eventually live in the Go standard library and won't require
|
|
||||||
any changes to your code to use. It will just be automatic.
|
|
||||||
|
|
||||||
Status:
|
|
||||||
|
|
||||||
* The server support is pretty good. A few things are missing
|
|
||||||
but are being worked on.
|
|
||||||
* The client work has just started but shares a lot of code
|
|
||||||
is coming along much quicker.
|
|
||||||
|
|
||||||
Docs are at https://godoc.org/golang.org/x/net/http2
|
|
||||||
|
|
||||||
Demo test server at https://http2.golang.org/
|
|
||||||
|
|
||||||
Help & bug reports welcome!
|
|
||||||
|
|
||||||
Contributing: https://golang.org/doc/contribute.html
|
|
||||||
Bugs: https://golang.org/issue/new?title=x/net/http2:+
|
|
53
vendor/golang.org/x/net/http2/ascii.go
generated
vendored
Normal file
53
vendor/golang.org/x/net/http2/ascii.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package http2
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// The HTTP protocols are defined in terms of ASCII, not Unicode. This file
|
||||||
|
// contains helper functions which may use Unicode-aware functions which would
|
||||||
|
// otherwise be unsafe and could introduce vulnerabilities if used improperly.
|
||||||
|
|
||||||
|
// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
|
||||||
|
// are equal, ASCII-case-insensitively.
|
||||||
|
func asciiEqualFold(s, t string) bool {
|
||||||
|
if len(s) != len(t) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if lower(s[i]) != lower(t[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// lower returns the ASCII lowercase version of b.
|
||||||
|
func lower(b byte) byte {
|
||||||
|
if 'A' <= b && b <= 'Z' {
|
||||||
|
return b + ('a' - 'A')
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// isASCIIPrint returns whether s is ASCII and printable according to
|
||||||
|
// https://tools.ietf.org/html/rfc20#section-4.2.
|
||||||
|
func isASCIIPrint(s string) bool {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] < ' ' || s[i] > '~' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// asciiToLower returns the lowercase version of s if s is ASCII and printable,
|
||||||
|
// and whether or not it was.
|
||||||
|
func asciiToLower(s string) (lower string, ok bool) {
|
||||||
|
if !isASCIIPrint(s) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return strings.ToLower(s), true
|
||||||
|
}
|
120
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
120
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
@ -7,13 +7,21 @@
|
|||||||
package http2
|
package http2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ClientConnPool manages a pool of HTTP/2 client connections.
|
// ClientConnPool manages a pool of HTTP/2 client connections.
|
||||||
type ClientConnPool interface {
|
type ClientConnPool interface {
|
||||||
|
// GetClientConn returns a specific HTTP/2 connection (usually
|
||||||
|
// a TLS-TCP connection) to an HTTP/2 server. On success, the
|
||||||
|
// returned ClientConn accounts for the upcoming RoundTrip
|
||||||
|
// call, so the caller should not omit it. If the caller needs
|
||||||
|
// to, ClientConn.RoundTrip can be called with a bogus
|
||||||
|
// new(http.Request) to release the stream reservation.
|
||||||
GetClientConn(req *http.Request, addr string) (*ClientConn, error)
|
GetClientConn(req *http.Request, addr string) (*ClientConn, error)
|
||||||
MarkDead(*ClientConn)
|
MarkDead(*ClientConn)
|
||||||
}
|
}
|
||||||
@ -40,7 +48,7 @@ type clientConnPool struct {
|
|||||||
conns map[string][]*ClientConn // key is host:port
|
conns map[string][]*ClientConn // key is host:port
|
||||||
dialing map[string]*dialCall // currently in-flight dials
|
dialing map[string]*dialCall // currently in-flight dials
|
||||||
keys map[*ClientConn][]string
|
keys map[*ClientConn][]string
|
||||||
addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
|
addConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
|
func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
|
||||||
@ -52,87 +60,85 @@ const (
|
|||||||
noDialOnMiss = false
|
noDialOnMiss = false
|
||||||
)
|
)
|
||||||
|
|
||||||
// shouldTraceGetConn reports whether getClientConn should call any
|
|
||||||
// ClientTrace.GetConn hook associated with the http.Request.
|
|
||||||
//
|
|
||||||
// This complexity is needed to avoid double calls of the GetConn hook
|
|
||||||
// during the back-and-forth between net/http and x/net/http2 (when the
|
|
||||||
// net/http.Transport is upgraded to also speak http2), as well as support
|
|
||||||
// the case where x/net/http2 is being used directly.
|
|
||||||
func (p *clientConnPool) shouldTraceGetConn(st clientConnIdleState) bool {
|
|
||||||
// If our Transport wasn't made via ConfigureTransport, always
|
|
||||||
// trace the GetConn hook if provided, because that means the
|
|
||||||
// http2 package is being used directly and it's the one
|
|
||||||
// dialing, as opposed to net/http.
|
|
||||||
if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Otherwise, only use the GetConn hook if this connection has
|
|
||||||
// been used previously for other requests. For fresh
|
|
||||||
// connections, the net/http package does the dialing.
|
|
||||||
return !st.freshConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
|
func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
|
||||||
|
// TODO(dneil): Dial a new connection when t.DisableKeepAlives is set?
|
||||||
if isConnectionCloseRequest(req) && dialOnMiss {
|
if isConnectionCloseRequest(req) && dialOnMiss {
|
||||||
// It gets its own connection.
|
// It gets its own connection.
|
||||||
traceGetConn(req, addr)
|
traceGetConn(req, addr)
|
||||||
const singleUse = true
|
const singleUse = true
|
||||||
cc, err := p.t.dialClientConn(addr, singleUse)
|
cc, err := p.t.dialClientConn(req.Context(), addr, singleUse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
p.mu.Lock()
|
for {
|
||||||
for _, cc := range p.conns[addr] {
|
p.mu.Lock()
|
||||||
if st := cc.idleState(); st.canTakeNewRequest {
|
for _, cc := range p.conns[addr] {
|
||||||
if p.shouldTraceGetConn(st) {
|
if cc.ReserveNewRequest() {
|
||||||
traceGetConn(req, addr)
|
// When a connection is presented to us by the net/http package,
|
||||||
|
// the GetConn hook has already been called.
|
||||||
|
// Don't call it a second time here.
|
||||||
|
if !cc.getConnCalled {
|
||||||
|
traceGetConn(req, addr)
|
||||||
|
}
|
||||||
|
cc.getConnCalled = false
|
||||||
|
p.mu.Unlock()
|
||||||
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !dialOnMiss {
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
|
return nil, ErrNoCachedConn
|
||||||
|
}
|
||||||
|
traceGetConn(req, addr)
|
||||||
|
call := p.getStartDialLocked(req.Context(), addr)
|
||||||
|
p.mu.Unlock()
|
||||||
|
<-call.done
|
||||||
|
if shouldRetryDial(call, req) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cc, err := call.res, call.err
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cc.ReserveNewRequest() {
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !dialOnMiss {
|
|
||||||
p.mu.Unlock()
|
|
||||||
return nil, ErrNoCachedConn
|
|
||||||
}
|
|
||||||
traceGetConn(req, addr)
|
|
||||||
call := p.getStartDialLocked(addr)
|
|
||||||
p.mu.Unlock()
|
|
||||||
<-call.done
|
|
||||||
return call.res, call.err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dialCall is an in-flight Transport dial call to a host.
|
// dialCall is an in-flight Transport dial call to a host.
|
||||||
type dialCall struct {
|
type dialCall struct {
|
||||||
_ incomparable
|
_ incomparable
|
||||||
p *clientConnPool
|
p *clientConnPool
|
||||||
|
// the context associated with the request
|
||||||
|
// that created this dialCall
|
||||||
|
ctx context.Context
|
||||||
done chan struct{} // closed when done
|
done chan struct{} // closed when done
|
||||||
res *ClientConn // valid after done is closed
|
res *ClientConn // valid after done is closed
|
||||||
err error // valid after done is closed
|
err error // valid after done is closed
|
||||||
}
|
}
|
||||||
|
|
||||||
// requires p.mu is held.
|
// requires p.mu is held.
|
||||||
func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
|
func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *dialCall {
|
||||||
if call, ok := p.dialing[addr]; ok {
|
if call, ok := p.dialing[addr]; ok {
|
||||||
// A dial is already in-flight. Don't start another.
|
// A dial is already in-flight. Don't start another.
|
||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
call := &dialCall{p: p, done: make(chan struct{})}
|
call := &dialCall{p: p, done: make(chan struct{}), ctx: ctx}
|
||||||
if p.dialing == nil {
|
if p.dialing == nil {
|
||||||
p.dialing = make(map[string]*dialCall)
|
p.dialing = make(map[string]*dialCall)
|
||||||
}
|
}
|
||||||
p.dialing[addr] = call
|
p.dialing[addr] = call
|
||||||
go call.dial(addr)
|
go call.dial(call.ctx, addr)
|
||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
|
|
||||||
// run in its own goroutine.
|
// run in its own goroutine.
|
||||||
func (c *dialCall) dial(addr string) {
|
func (c *dialCall) dial(ctx context.Context, addr string) {
|
||||||
const singleUse = false // shared conn
|
const singleUse = false // shared conn
|
||||||
c.res, c.err = c.p.t.dialClientConn(addr, singleUse)
|
c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
|
||||||
close(c.done)
|
close(c.done)
|
||||||
|
|
||||||
c.p.mu.Lock()
|
c.p.mu.Lock()
|
||||||
@ -195,6 +201,7 @@ func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
c.err = err
|
c.err = err
|
||||||
} else {
|
} else {
|
||||||
|
cc.getConnCalled = true // already called by the net/http package
|
||||||
p.addConnLocked(key, cc)
|
p.addConnLocked(key, cc)
|
||||||
}
|
}
|
||||||
delete(p.addConnCalls, key)
|
delete(p.addConnCalls, key)
|
||||||
@ -276,3 +283,28 @@ type noDialClientConnPool struct{ *clientConnPool }
|
|||||||
func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
|
func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
|
||||||
return p.getClientConn(req, addr, noDialOnMiss)
|
return p.getClientConn(req, addr, noDialOnMiss)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shouldRetryDial reports whether the current request should
|
||||||
|
// retry dialing after the call finished unsuccessfully, for example
|
||||||
|
// if the dial was canceled because of a context cancellation or
|
||||||
|
// deadline expiry.
|
||||||
|
func shouldRetryDial(call *dialCall, req *http.Request) bool {
|
||||||
|
if call.err == nil {
|
||||||
|
// No error, no need to retry
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if call.ctx == req.Context() {
|
||||||
|
// If the call has the same context as the request, the dial
|
||||||
|
// should not be retried, since any cancellation will have come
|
||||||
|
// from this request.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {
|
||||||
|
// If the call error is not because of a context cancellation or a deadline expiry,
|
||||||
|
// the dial should not be retried.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Only retry if the error is a context cancellation error or deadline expiry
|
||||||
|
// and the context associated with the call was canceled or expired.
|
||||||
|
return call.ctx.Err() != nil
|
||||||
|
}
|
||||||
|
12
vendor/golang.org/x/net/http2/errors.go
generated
vendored
12
vendor/golang.org/x/net/http2/errors.go
generated
vendored
@ -53,6 +53,13 @@ func (e ErrCode) String() string {
|
|||||||
return fmt.Sprintf("unknown error code 0x%x", uint32(e))
|
return fmt.Sprintf("unknown error code 0x%x", uint32(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e ErrCode) stringToken() string {
|
||||||
|
if s, ok := errCodeName[e]; ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e))
|
||||||
|
}
|
||||||
|
|
||||||
// ConnectionError is an error that results in the termination of the
|
// ConnectionError is an error that results in the termination of the
|
||||||
// entire connection.
|
// entire connection.
|
||||||
type ConnectionError ErrCode
|
type ConnectionError ErrCode
|
||||||
@ -67,6 +74,11 @@ type StreamError struct {
|
|||||||
Cause error // optional additional detail
|
Cause error // optional additional detail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// errFromPeer is a sentinel error value for StreamError.Cause to
|
||||||
|
// indicate that the StreamError was sent from the peer over the wire
|
||||||
|
// and wasn't locally generated in the Transport.
|
||||||
|
var errFromPeer = errors.New("received from peer")
|
||||||
|
|
||||||
func streamError(id uint32, code ErrCode) StreamError {
|
func streamError(id uint32, code ErrCode) StreamError {
|
||||||
return StreamError{StreamID: id, Code: code}
|
return StreamError{StreamID: id, Code: code}
|
||||||
}
|
}
|
||||||
|
62
vendor/golang.org/x/net/http2/frame.go
generated
vendored
62
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@ -122,7 +122,7 @@ var flagName = map[FrameType]map[Flags]string{
|
|||||||
// a frameParser parses a frame given its FrameHeader and payload
|
// a frameParser parses a frame given its FrameHeader and payload
|
||||||
// bytes. The length of payload will always equal fh.Length (which
|
// bytes. The length of payload will always equal fh.Length (which
|
||||||
// might be 0).
|
// might be 0).
|
||||||
type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error)
|
type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
|
||||||
|
|
||||||
var frameParsers = map[FrameType]frameParser{
|
var frameParsers = map[FrameType]frameParser{
|
||||||
FrameData: parseDataFrame,
|
FrameData: parseDataFrame,
|
||||||
@ -267,6 +267,11 @@ type Framer struct {
|
|||||||
lastFrame Frame
|
lastFrame Frame
|
||||||
errDetail error
|
errDetail error
|
||||||
|
|
||||||
|
// countError is a non-nil func that's called on a frame parse
|
||||||
|
// error with some unique error path token. It's initialized
|
||||||
|
// from Transport.CountError or Server.CountError.
|
||||||
|
countError func(errToken string)
|
||||||
|
|
||||||
// lastHeaderStream is non-zero if the last frame was an
|
// lastHeaderStream is non-zero if the last frame was an
|
||||||
// unfinished HEADERS/CONTINUATION.
|
// unfinished HEADERS/CONTINUATION.
|
||||||
lastHeaderStream uint32
|
lastHeaderStream uint32
|
||||||
@ -426,6 +431,7 @@ func NewFramer(w io.Writer, r io.Reader) *Framer {
|
|||||||
fr := &Framer{
|
fr := &Framer{
|
||||||
w: w,
|
w: w,
|
||||||
r: r,
|
r: r,
|
||||||
|
countError: func(string) {},
|
||||||
logReads: logFrameReads,
|
logReads: logFrameReads,
|
||||||
logWrites: logFrameWrites,
|
logWrites: logFrameWrites,
|
||||||
debugReadLoggerf: log.Printf,
|
debugReadLoggerf: log.Printf,
|
||||||
@ -500,7 +506,7 @@ func (fr *Framer) ReadFrame() (Frame, error) {
|
|||||||
if _, err := io.ReadFull(fr.r, payload); err != nil {
|
if _, err := io.ReadFull(fr.r, payload); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload)
|
f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ce, ok := err.(connError); ok {
|
if ce, ok := err.(connError); ok {
|
||||||
return nil, fr.connError(ce.Code, ce.Reason)
|
return nil, fr.connError(ce.Code, ce.Reason)
|
||||||
@ -588,13 +594,14 @@ func (f *DataFrame) Data() []byte {
|
|||||||
return f.data
|
return f.data
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
|
func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||||
if fh.StreamID == 0 {
|
if fh.StreamID == 0 {
|
||||||
// DATA frames MUST be associated with a stream. If a
|
// DATA frames MUST be associated with a stream. If a
|
||||||
// DATA frame is received whose stream identifier
|
// DATA frame is received whose stream identifier
|
||||||
// field is 0x0, the recipient MUST respond with a
|
// field is 0x0, the recipient MUST respond with a
|
||||||
// connection error (Section 5.4.1) of type
|
// connection error (Section 5.4.1) of type
|
||||||
// PROTOCOL_ERROR.
|
// PROTOCOL_ERROR.
|
||||||
|
countError("frame_data_stream_0")
|
||||||
return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
|
return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
|
||||||
}
|
}
|
||||||
f := fc.getDataFrame()
|
f := fc.getDataFrame()
|
||||||
@ -605,6 +612,7 @@ func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, erro
|
|||||||
var err error
|
var err error
|
||||||
payload, padSize, err = readByte(payload)
|
payload, padSize, err = readByte(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
countError("frame_data_pad_byte_short")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,6 +621,7 @@ func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, erro
|
|||||||
// length of the frame payload, the recipient MUST
|
// length of the frame payload, the recipient MUST
|
||||||
// treat this as a connection error.
|
// treat this as a connection error.
|
||||||
// Filed: https://github.com/http2/http2-spec/issues/610
|
// Filed: https://github.com/http2/http2-spec/issues/610
|
||||||
|
countError("frame_data_pad_too_big")
|
||||||
return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
|
return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
|
||||||
}
|
}
|
||||||
f.data = payload[:len(payload)-int(padSize)]
|
f.data = payload[:len(payload)-int(padSize)]
|
||||||
@ -695,7 +704,7 @@ type SettingsFrame struct {
|
|||||||
p []byte
|
p []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||||
if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
|
if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
|
||||||
// When this (ACK 0x1) bit is set, the payload of the
|
// When this (ACK 0x1) bit is set, the payload of the
|
||||||
// SETTINGS frame MUST be empty. Receipt of a
|
// SETTINGS frame MUST be empty. Receipt of a
|
||||||
@ -703,6 +712,7 @@ func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error)
|
|||||||
// field value other than 0 MUST be treated as a
|
// field value other than 0 MUST be treated as a
|
||||||
// connection error (Section 5.4.1) of type
|
// connection error (Section 5.4.1) of type
|
||||||
// FRAME_SIZE_ERROR.
|
// FRAME_SIZE_ERROR.
|
||||||
|
countError("frame_settings_ack_with_length")
|
||||||
return nil, ConnectionError(ErrCodeFrameSize)
|
return nil, ConnectionError(ErrCodeFrameSize)
|
||||||
}
|
}
|
||||||
if fh.StreamID != 0 {
|
if fh.StreamID != 0 {
|
||||||
@ -713,14 +723,17 @@ func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error)
|
|||||||
// field is anything other than 0x0, the endpoint MUST
|
// field is anything other than 0x0, the endpoint MUST
|
||||||
// respond with a connection error (Section 5.4.1) of
|
// respond with a connection error (Section 5.4.1) of
|
||||||
// type PROTOCOL_ERROR.
|
// type PROTOCOL_ERROR.
|
||||||
|
countError("frame_settings_has_stream")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
if len(p)%6 != 0 {
|
if len(p)%6 != 0 {
|
||||||
|
countError("frame_settings_mod_6")
|
||||||
// Expecting even number of 6 byte settings.
|
// Expecting even number of 6 byte settings.
|
||||||
return nil, ConnectionError(ErrCodeFrameSize)
|
return nil, ConnectionError(ErrCodeFrameSize)
|
||||||
}
|
}
|
||||||
f := &SettingsFrame{FrameHeader: fh, p: p}
|
f := &SettingsFrame{FrameHeader: fh, p: p}
|
||||||
if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
|
if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
|
||||||
|
countError("frame_settings_window_size_too_big")
|
||||||
// Values above the maximum flow control window size of 2^31 - 1 MUST
|
// Values above the maximum flow control window size of 2^31 - 1 MUST
|
||||||
// be treated as a connection error (Section 5.4.1) of type
|
// be treated as a connection error (Section 5.4.1) of type
|
||||||
// FLOW_CONTROL_ERROR.
|
// FLOW_CONTROL_ERROR.
|
||||||
@ -832,11 +845,13 @@ type PingFrame struct {
|
|||||||
|
|
||||||
func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
|
func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
|
||||||
|
|
||||||
func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
|
func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||||
if len(payload) != 8 {
|
if len(payload) != 8 {
|
||||||
|
countError("frame_ping_length")
|
||||||
return nil, ConnectionError(ErrCodeFrameSize)
|
return nil, ConnectionError(ErrCodeFrameSize)
|
||||||
}
|
}
|
||||||
if fh.StreamID != 0 {
|
if fh.StreamID != 0 {
|
||||||
|
countError("frame_ping_has_stream")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
f := &PingFrame{FrameHeader: fh}
|
f := &PingFrame{FrameHeader: fh}
|
||||||
@ -872,11 +887,13 @@ func (f *GoAwayFrame) DebugData() []byte {
|
|||||||
return f.debugData
|
return f.debugData
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||||
if fh.StreamID != 0 {
|
if fh.StreamID != 0 {
|
||||||
|
countError("frame_goaway_has_stream")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
if len(p) < 8 {
|
if len(p) < 8 {
|
||||||
|
countError("frame_goaway_short")
|
||||||
return nil, ConnectionError(ErrCodeFrameSize)
|
return nil, ConnectionError(ErrCodeFrameSize)
|
||||||
}
|
}
|
||||||
return &GoAwayFrame{
|
return &GoAwayFrame{
|
||||||
@ -912,7 +929,7 @@ func (f *UnknownFrame) Payload() []byte {
|
|||||||
return f.p
|
return f.p
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||||
return &UnknownFrame{fh, p}, nil
|
return &UnknownFrame{fh, p}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,8 +940,9 @@ type WindowUpdateFrame struct {
|
|||||||
Increment uint32 // never read with high bit set
|
Increment uint32 // never read with high bit set
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||||
if len(p) != 4 {
|
if len(p) != 4 {
|
||||||
|
countError("frame_windowupdate_bad_len")
|
||||||
return nil, ConnectionError(ErrCodeFrameSize)
|
return nil, ConnectionError(ErrCodeFrameSize)
|
||||||
}
|
}
|
||||||
inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
|
inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
|
||||||
@ -936,8 +954,10 @@ func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, err
|
|||||||
// control window MUST be treated as a connection
|
// control window MUST be treated as a connection
|
||||||
// error (Section 5.4.1).
|
// error (Section 5.4.1).
|
||||||
if fh.StreamID == 0 {
|
if fh.StreamID == 0 {
|
||||||
|
countError("frame_windowupdate_zero_inc_conn")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
|
countError("frame_windowupdate_zero_inc_stream")
|
||||||
return nil, streamError(fh.StreamID, ErrCodeProtocol)
|
return nil, streamError(fh.StreamID, ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
return &WindowUpdateFrame{
|
return &WindowUpdateFrame{
|
||||||
@ -988,7 +1008,7 @@ func (f *HeadersFrame) HasPriority() bool {
|
|||||||
return f.FrameHeader.Flags.Has(FlagHeadersPriority)
|
return f.FrameHeader.Flags.Has(FlagHeadersPriority)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
|
func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
|
||||||
hf := &HeadersFrame{
|
hf := &HeadersFrame{
|
||||||
FrameHeader: fh,
|
FrameHeader: fh,
|
||||||
}
|
}
|
||||||
@ -997,11 +1017,13 @@ func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err er
|
|||||||
// is received whose stream identifier field is 0x0, the recipient MUST
|
// is received whose stream identifier field is 0x0, the recipient MUST
|
||||||
// respond with a connection error (Section 5.4.1) of type
|
// respond with a connection error (Section 5.4.1) of type
|
||||||
// PROTOCOL_ERROR.
|
// PROTOCOL_ERROR.
|
||||||
|
countError("frame_headers_zero_stream")
|
||||||
return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
|
return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
|
||||||
}
|
}
|
||||||
var padLength uint8
|
var padLength uint8
|
||||||
if fh.Flags.Has(FlagHeadersPadded) {
|
if fh.Flags.Has(FlagHeadersPadded) {
|
||||||
if p, padLength, err = readByte(p); err != nil {
|
if p, padLength, err = readByte(p); err != nil {
|
||||||
|
countError("frame_headers_pad_short")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1009,16 +1031,19 @@ func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err er
|
|||||||
var v uint32
|
var v uint32
|
||||||
p, v, err = readUint32(p)
|
p, v, err = readUint32(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
countError("frame_headers_prio_short")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hf.Priority.StreamDep = v & 0x7fffffff
|
hf.Priority.StreamDep = v & 0x7fffffff
|
||||||
hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
|
hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
|
||||||
p, hf.Priority.Weight, err = readByte(p)
|
p, hf.Priority.Weight, err = readByte(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
countError("frame_headers_prio_weight_short")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(p)-int(padLength) <= 0 {
|
if len(p)-int(padLength) < 0 {
|
||||||
|
countError("frame_headers_pad_too_big")
|
||||||
return nil, streamError(fh.StreamID, ErrCodeProtocol)
|
return nil, streamError(fh.StreamID, ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
hf.headerFragBuf = p[:len(p)-int(padLength)]
|
hf.headerFragBuf = p[:len(p)-int(padLength)]
|
||||||
@ -1125,11 +1150,13 @@ func (p PriorityParam) IsZero() bool {
|
|||||||
return p == PriorityParam{}
|
return p == PriorityParam{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
|
func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||||
if fh.StreamID == 0 {
|
if fh.StreamID == 0 {
|
||||||
|
countError("frame_priority_zero_stream")
|
||||||
return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
|
return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
|
||||||
}
|
}
|
||||||
if len(payload) != 5 {
|
if len(payload) != 5 {
|
||||||
|
countError("frame_priority_bad_length")
|
||||||
return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
|
return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
|
||||||
}
|
}
|
||||||
v := binary.BigEndian.Uint32(payload[:4])
|
v := binary.BigEndian.Uint32(payload[:4])
|
||||||
@ -1172,11 +1199,13 @@ type RSTStreamFrame struct {
|
|||||||
ErrCode ErrCode
|
ErrCode ErrCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||||
if len(p) != 4 {
|
if len(p) != 4 {
|
||||||
|
countError("frame_rststream_bad_len")
|
||||||
return nil, ConnectionError(ErrCodeFrameSize)
|
return nil, ConnectionError(ErrCodeFrameSize)
|
||||||
}
|
}
|
||||||
if fh.StreamID == 0 {
|
if fh.StreamID == 0 {
|
||||||
|
countError("frame_rststream_zero_stream")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
|
return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
|
||||||
@ -1202,8 +1231,9 @@ type ContinuationFrame struct {
|
|||||||
headerFragBuf []byte
|
headerFragBuf []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||||
if fh.StreamID == 0 {
|
if fh.StreamID == 0 {
|
||||||
|
countError("frame_continuation_zero_stream")
|
||||||
return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
|
return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
|
||||||
}
|
}
|
||||||
return &ContinuationFrame{fh, p}, nil
|
return &ContinuationFrame{fh, p}, nil
|
||||||
@ -1252,7 +1282,7 @@ func (f *PushPromiseFrame) HeadersEnded() bool {
|
|||||||
return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
|
return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
|
func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
|
||||||
pp := &PushPromiseFrame{
|
pp := &PushPromiseFrame{
|
||||||
FrameHeader: fh,
|
FrameHeader: fh,
|
||||||
}
|
}
|
||||||
@ -1263,6 +1293,7 @@ func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err err
|
|||||||
// with. If the stream identifier field specifies the value
|
// with. If the stream identifier field specifies the value
|
||||||
// 0x0, a recipient MUST respond with a connection error
|
// 0x0, a recipient MUST respond with a connection error
|
||||||
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||||
|
countError("frame_pushpromise_zero_stream")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
// The PUSH_PROMISE frame includes optional padding.
|
// The PUSH_PROMISE frame includes optional padding.
|
||||||
@ -1270,18 +1301,21 @@ func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err err
|
|||||||
var padLength uint8
|
var padLength uint8
|
||||||
if fh.Flags.Has(FlagPushPromisePadded) {
|
if fh.Flags.Has(FlagPushPromisePadded) {
|
||||||
if p, padLength, err = readByte(p); err != nil {
|
if p, padLength, err = readByte(p); err != nil {
|
||||||
|
countError("frame_pushpromise_pad_short")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p, pp.PromiseID, err = readUint32(p)
|
p, pp.PromiseID, err = readUint32(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
countError("frame_pushpromise_promiseid_short")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pp.PromiseID = pp.PromiseID & (1<<31 - 1)
|
pp.PromiseID = pp.PromiseID & (1<<31 - 1)
|
||||||
|
|
||||||
if int(padLength) > len(p) {
|
if int(padLength) > len(p) {
|
||||||
// like the DATA frame, error out if padding is longer than the body.
|
// like the DATA frame, error out if padding is longer than the body.
|
||||||
|
countError("frame_pushpromise_pad_too_big")
|
||||||
return nil, ConnectionError(ErrCodeProtocol)
|
return nil, ConnectionError(ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
pp.headerFragBuf = p[:len(p)-int(padLength)]
|
pp.headerFragBuf = p[:len(p)-int(padLength)]
|
||||||
|
27
vendor/golang.org/x/net/http2/go115.go
generated
vendored
Normal file
27
vendor/golang.org/x/net/http2/go115.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.15
|
||||||
|
// +build go1.15
|
||||||
|
|
||||||
|
package http2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
)
|
||||||
|
|
||||||
|
// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
|
||||||
|
// connection.
|
||||||
|
func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
|
||||||
|
dialer := &tls.Dialer{
|
||||||
|
Config: cfg,
|
||||||
|
}
|
||||||
|
cn, err := dialer.DialContext(ctx, network, addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
|
||||||
|
return tlsCn, nil
|
||||||
|
}
|
7
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
7
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
@ -6,7 +6,6 @@ package http2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,10 +78,10 @@ func buildCommonHeaderMaps() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func lowerHeader(v string) string {
|
func lowerHeader(v string) (lower string, ascii bool) {
|
||||||
buildCommonHeaderMapsOnce()
|
buildCommonHeaderMapsOnce()
|
||||||
if s, ok := commonLowerHeader[v]; ok {
|
if s, ok := commonLowerHeader[v]; ok {
|
||||||
return s
|
return s, true
|
||||||
}
|
}
|
||||||
return strings.ToLower(v)
|
return asciiToLower(v)
|
||||||
}
|
}
|
||||||
|
38
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
38
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
@ -140,25 +140,29 @@ func buildRootHuffmanNode() {
|
|||||||
panic("unexpected size")
|
panic("unexpected size")
|
||||||
}
|
}
|
||||||
lazyRootHuffmanNode = newInternalNode()
|
lazyRootHuffmanNode = newInternalNode()
|
||||||
for i, code := range huffmanCodes {
|
// allocate a leaf node for each of the 256 symbols
|
||||||
addDecoderNode(byte(i), code, huffmanCodeLen[i])
|
leaves := new([256]node)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addDecoderNode(sym byte, code uint32, codeLen uint8) {
|
for sym, code := range huffmanCodes {
|
||||||
cur := lazyRootHuffmanNode
|
codeLen := huffmanCodeLen[sym]
|
||||||
for codeLen > 8 {
|
|
||||||
codeLen -= 8
|
cur := lazyRootHuffmanNode
|
||||||
i := uint8(code >> codeLen)
|
for codeLen > 8 {
|
||||||
if cur.children[i] == nil {
|
codeLen -= 8
|
||||||
cur.children[i] = newInternalNode()
|
i := uint8(code >> codeLen)
|
||||||
|
if cur.children[i] == nil {
|
||||||
|
cur.children[i] = newInternalNode()
|
||||||
|
}
|
||||||
|
cur = cur.children[i]
|
||||||
|
}
|
||||||
|
shift := 8 - codeLen
|
||||||
|
start, end := int(uint8(code<<shift)), int(1<<shift)
|
||||||
|
|
||||||
|
leaves[sym].sym = byte(sym)
|
||||||
|
leaves[sym].codeLen = codeLen
|
||||||
|
for i := start; i < start+end; i++ {
|
||||||
|
cur.children[i] = &leaves[sym]
|
||||||
}
|
}
|
||||||
cur = cur.children[i]
|
|
||||||
}
|
|
||||||
shift := 8 - codeLen
|
|
||||||
start, end := int(uint8(code<<shift)), int(1<<shift)
|
|
||||||
for i := start; i < start+end; i++ {
|
|
||||||
cur.children[i] = &node{sym: sym, codeLen: codeLen}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
vendor/golang.org/x/net/http2/not_go115.go
generated
vendored
Normal file
31
vendor/golang.org/x/net/http2/not_go115.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.15
|
||||||
|
// +build !go1.15
|
||||||
|
|
||||||
|
package http2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
)
|
||||||
|
|
||||||
|
// dialTLSWithContext opens a TLS connection.
|
||||||
|
func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
|
||||||
|
cn, err := tls.Dial(network, addr, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := cn.Handshake(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cfg.InsecureSkipVerify {
|
||||||
|
return cn, nil
|
||||||
|
}
|
||||||
|
if err := cn.VerifyHostname(cfg.ServerName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cn, nil
|
||||||
|
}
|
11
vendor/golang.org/x/net/http2/pipe.go
generated
vendored
11
vendor/golang.org/x/net/http2/pipe.go
generated
vendored
@ -30,6 +30,17 @@ type pipeBuffer interface {
|
|||||||
io.Reader
|
io.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setBuffer initializes the pipe buffer.
|
||||||
|
// It has no effect if the pipe is already closed.
|
||||||
|
func (p *pipe) setBuffer(b pipeBuffer) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
if p.err != nil || p.breakErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.b = b
|
||||||
|
}
|
||||||
|
|
||||||
func (p *pipe) Len() int {
|
func (p *pipe) Len() int {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
150
vendor/golang.org/x/net/http2/server.go
generated
vendored
150
vendor/golang.org/x/net/http2/server.go
generated
vendored
@ -130,6 +130,12 @@ type Server struct {
|
|||||||
// If nil, a default scheduler is chosen.
|
// If nil, a default scheduler is chosen.
|
||||||
NewWriteScheduler func() WriteScheduler
|
NewWriteScheduler func() WriteScheduler
|
||||||
|
|
||||||
|
// CountError, if non-nil, is called on HTTP/2 server errors.
|
||||||
|
// It's intended to increment a metric for monitoring, such
|
||||||
|
// as an expvar or Prometheus metric.
|
||||||
|
// The errType consists of only ASCII word characters.
|
||||||
|
CountError func(errType string)
|
||||||
|
|
||||||
// Internal state. This is a pointer (rather than embedded directly)
|
// Internal state. This is a pointer (rather than embedded directly)
|
||||||
// so that we don't embed a Mutex in this struct, which will make the
|
// so that we don't embed a Mutex in this struct, which will make the
|
||||||
// struct non-copyable, which might break some callers.
|
// struct non-copyable, which might break some callers.
|
||||||
@ -231,13 +237,12 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
|||||||
|
|
||||||
if s.TLSConfig == nil {
|
if s.TLSConfig == nil {
|
||||||
s.TLSConfig = new(tls.Config)
|
s.TLSConfig = new(tls.Config)
|
||||||
} else if s.TLSConfig.CipherSuites != nil {
|
} else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
|
||||||
// If they already provided a CipherSuite list, return
|
// If they already provided a TLS 1.0–1.2 CipherSuite list, return an
|
||||||
// an error if it has a bad order or is missing
|
// error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or
|
||||||
// ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
|
// ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
|
||||||
haveRequired := false
|
haveRequired := false
|
||||||
sawBad := false
|
for _, cs := range s.TLSConfig.CipherSuites {
|
||||||
for i, cs := range s.TLSConfig.CipherSuites {
|
|
||||||
switch cs {
|
switch cs {
|
||||||
case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||||
// Alternative MTI cipher to not discourage ECDSA-only servers.
|
// Alternative MTI cipher to not discourage ECDSA-only servers.
|
||||||
@ -245,14 +250,9 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
|||||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
|
||||||
haveRequired = true
|
haveRequired = true
|
||||||
}
|
}
|
||||||
if isBadCipher(cs) {
|
|
||||||
sawBad = true
|
|
||||||
} else if sawBad {
|
|
||||||
return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !haveRequired {
|
if !haveRequired {
|
||||||
return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).")
|
return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,16 +265,12 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
|||||||
|
|
||||||
s.TLSConfig.PreferServerCipherSuites = true
|
s.TLSConfig.PreferServerCipherSuites = true
|
||||||
|
|
||||||
haveNPN := false
|
if !strSliceContains(s.TLSConfig.NextProtos, NextProtoTLS) {
|
||||||
for _, p := range s.TLSConfig.NextProtos {
|
|
||||||
if p == NextProtoTLS {
|
|
||||||
haveNPN = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !haveNPN {
|
|
||||||
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
|
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
|
||||||
}
|
}
|
||||||
|
if !strSliceContains(s.TLSConfig.NextProtos, "http/1.1") {
|
||||||
|
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1")
|
||||||
|
}
|
||||||
|
|
||||||
if s.TLSNextProto == nil {
|
if s.TLSNextProto == nil {
|
||||||
s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
|
s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
|
||||||
@ -415,6 +411,9 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
|
|||||||
sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
|
sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
|
||||||
|
|
||||||
fr := NewFramer(sc.bw, c)
|
fr := NewFramer(sc.bw, c)
|
||||||
|
if s.CountError != nil {
|
||||||
|
fr.countError = s.CountError
|
||||||
|
}
|
||||||
fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
|
fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
|
||||||
fr.MaxHeaderListSize = sc.maxHeaderListSize()
|
fr.MaxHeaderListSize = sc.maxHeaderListSize()
|
||||||
fr.SetMaxReadFrameSize(s.maxReadFrameSize())
|
fr.SetMaxReadFrameSize(s.maxReadFrameSize())
|
||||||
@ -826,7 +825,7 @@ func (sc *serverConn) serve() {
|
|||||||
})
|
})
|
||||||
sc.unackedSettings++
|
sc.unackedSettings++
|
||||||
|
|
||||||
// Each connection starts with intialWindowSize inflow tokens.
|
// Each connection starts with initialWindowSize inflow tokens.
|
||||||
// If a higher value is configured, we add more tokens.
|
// If a higher value is configured, we add more tokens.
|
||||||
if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 {
|
if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 {
|
||||||
sc.sendWindowUpdate(nil, int(diff))
|
sc.sendWindowUpdate(nil, int(diff))
|
||||||
@ -866,6 +865,15 @@ func (sc *serverConn) serve() {
|
|||||||
case res := <-sc.wroteFrameCh:
|
case res := <-sc.wroteFrameCh:
|
||||||
sc.wroteFrame(res)
|
sc.wroteFrame(res)
|
||||||
case res := <-sc.readFrameCh:
|
case res := <-sc.readFrameCh:
|
||||||
|
// Process any written frames before reading new frames from the client since a
|
||||||
|
// written frame could have triggered a new stream to be started.
|
||||||
|
if sc.writingFrameAsync {
|
||||||
|
select {
|
||||||
|
case wroteRes := <-sc.wroteFrameCh:
|
||||||
|
sc.wroteFrame(wroteRes)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
if !sc.processFrameFromReader(res) {
|
if !sc.processFrameFromReader(res) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1400,7 +1408,7 @@ func (sc *serverConn) processFrame(f Frame) error {
|
|||||||
// First frame received must be SETTINGS.
|
// First frame received must be SETTINGS.
|
||||||
if !sc.sawFirstSettings {
|
if !sc.sawFirstSettings {
|
||||||
if _, ok := f.(*SettingsFrame); !ok {
|
if _, ok := f.(*SettingsFrame); !ok {
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("first_settings", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
sc.sawFirstSettings = true
|
sc.sawFirstSettings = true
|
||||||
}
|
}
|
||||||
@ -1425,7 +1433,7 @@ func (sc *serverConn) processFrame(f Frame) error {
|
|||||||
case *PushPromiseFrame:
|
case *PushPromiseFrame:
|
||||||
// A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
|
// A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
|
||||||
// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("push_promise", ConnectionError(ErrCodeProtocol))
|
||||||
default:
|
default:
|
||||||
sc.vlogf("http2: server ignoring frame: %v", f.Header())
|
sc.vlogf("http2: server ignoring frame: %v", f.Header())
|
||||||
return nil
|
return nil
|
||||||
@ -1445,7 +1453,7 @@ func (sc *serverConn) processPing(f *PingFrame) error {
|
|||||||
// identifier field value other than 0x0, the recipient MUST
|
// identifier field value other than 0x0, the recipient MUST
|
||||||
// respond with a connection error (Section 5.4.1) of type
|
// respond with a connection error (Section 5.4.1) of type
|
||||||
// PROTOCOL_ERROR."
|
// PROTOCOL_ERROR."
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
|
if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
|
||||||
return nil
|
return nil
|
||||||
@ -1464,7 +1472,7 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
|
|||||||
// or PRIORITY on a stream in this state MUST be
|
// or PRIORITY on a stream in this state MUST be
|
||||||
// treated as a connection error (Section 5.4.1) of
|
// treated as a connection error (Section 5.4.1) of
|
||||||
// type PROTOCOL_ERROR."
|
// type PROTOCOL_ERROR."
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("stream_idle", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if st == nil {
|
if st == nil {
|
||||||
// "WINDOW_UPDATE can be sent by a peer that has sent a
|
// "WINDOW_UPDATE can be sent by a peer that has sent a
|
||||||
@ -1475,7 +1483,7 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !st.flow.add(int32(f.Increment)) {
|
if !st.flow.add(int32(f.Increment)) {
|
||||||
return streamError(f.StreamID, ErrCodeFlowControl)
|
return sc.countError("bad_flow", streamError(f.StreamID, ErrCodeFlowControl))
|
||||||
}
|
}
|
||||||
default: // connection-level flow control
|
default: // connection-level flow control
|
||||||
if !sc.flow.add(int32(f.Increment)) {
|
if !sc.flow.add(int32(f.Increment)) {
|
||||||
@ -1496,7 +1504,7 @@ func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
|
|||||||
// identifying an idle stream is received, the
|
// identifying an idle stream is received, the
|
||||||
// recipient MUST treat this as a connection error
|
// recipient MUST treat this as a connection error
|
||||||
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("reset_idle_stream", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if st != nil {
|
if st != nil {
|
||||||
st.cancelCtx()
|
st.cancelCtx()
|
||||||
@ -1548,7 +1556,7 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
|
|||||||
// Why is the peer ACKing settings we never sent?
|
// Why is the peer ACKing settings we never sent?
|
||||||
// The spec doesn't mention this case, but
|
// The spec doesn't mention this case, but
|
||||||
// hang up on them anyway.
|
// hang up on them anyway.
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("ack_mystery", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1556,7 +1564,7 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
|
|||||||
// This isn't actually in the spec, but hang up on
|
// This isn't actually in the spec, but hang up on
|
||||||
// suspiciously large settings frames or those with
|
// suspiciously large settings frames or those with
|
||||||
// duplicate entries.
|
// duplicate entries.
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("settings_big_or_dups", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if err := f.ForeachSetting(sc.processSetting); err != nil {
|
if err := f.ForeachSetting(sc.processSetting); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1623,7 +1631,7 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
|
|||||||
// control window to exceed the maximum size as a
|
// control window to exceed the maximum size as a
|
||||||
// connection error (Section 5.4.1) of type
|
// connection error (Section 5.4.1) of type
|
||||||
// FLOW_CONTROL_ERROR."
|
// FLOW_CONTROL_ERROR."
|
||||||
return ConnectionError(ErrCodeFlowControl)
|
return sc.countError("setting_win_size", ConnectionError(ErrCodeFlowControl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1656,7 +1664,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||||||
// or PRIORITY on a stream in this state MUST be
|
// or PRIORITY on a stream in this state MUST be
|
||||||
// treated as a connection error (Section 5.4.1) of
|
// treated as a connection error (Section 5.4.1) of
|
||||||
// type PROTOCOL_ERROR."
|
// type PROTOCOL_ERROR."
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("data_on_idle", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
|
|
||||||
// "If a DATA frame is received whose stream is not in "open"
|
// "If a DATA frame is received whose stream is not in "open"
|
||||||
@ -1673,7 +1681,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||||||
// and return any flow control bytes since we're not going
|
// and return any flow control bytes since we're not going
|
||||||
// to consume them.
|
// to consume them.
|
||||||
if sc.inflow.available() < int32(f.Length) {
|
if sc.inflow.available() < int32(f.Length) {
|
||||||
return streamError(id, ErrCodeFlowControl)
|
return sc.countError("data_flow", streamError(id, ErrCodeFlowControl))
|
||||||
}
|
}
|
||||||
// Deduct the flow control from inflow, since we're
|
// Deduct the flow control from inflow, since we're
|
||||||
// going to immediately add it back in
|
// going to immediately add it back in
|
||||||
@ -1686,7 +1694,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||||||
// Already have a stream error in flight. Don't send another.
|
// Already have a stream error in flight. Don't send another.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return streamError(id, ErrCodeStreamClosed)
|
return sc.countError("closed", streamError(id, ErrCodeStreamClosed))
|
||||||
}
|
}
|
||||||
if st.body == nil {
|
if st.body == nil {
|
||||||
panic("internal error: should have a body in this state")
|
panic("internal error: should have a body in this state")
|
||||||
@ -1698,12 +1706,12 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||||||
// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
|
// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
|
||||||
// value of a content-length header field does not equal the sum of the
|
// value of a content-length header field does not equal the sum of the
|
||||||
// DATA frame payload lengths that form the body.
|
// DATA frame payload lengths that form the body.
|
||||||
return streamError(id, ErrCodeProtocol)
|
return sc.countError("send_too_much", streamError(id, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if f.Length > 0 {
|
if f.Length > 0 {
|
||||||
// Check whether the client has flow control quota.
|
// Check whether the client has flow control quota.
|
||||||
if st.inflow.available() < int32(f.Length) {
|
if st.inflow.available() < int32(f.Length) {
|
||||||
return streamError(id, ErrCodeFlowControl)
|
return sc.countError("flow_on_data_length", streamError(id, ErrCodeFlowControl))
|
||||||
}
|
}
|
||||||
st.inflow.take(int32(f.Length))
|
st.inflow.take(int32(f.Length))
|
||||||
|
|
||||||
@ -1711,7 +1719,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||||||
wrote, err := st.body.Write(data)
|
wrote, err := st.body.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sc.sendWindowUpdate(nil, int(f.Length)-wrote)
|
sc.sendWindowUpdate(nil, int(f.Length)-wrote)
|
||||||
return streamError(id, ErrCodeStreamClosed)
|
return sc.countError("body_write_err", streamError(id, ErrCodeStreamClosed))
|
||||||
}
|
}
|
||||||
if wrote != len(data) {
|
if wrote != len(data) {
|
||||||
panic("internal error: bad Writer")
|
panic("internal error: bad Writer")
|
||||||
@ -1797,7 +1805,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
// stream identifier MUST respond with a connection error
|
// stream identifier MUST respond with a connection error
|
||||||
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||||
if id%2 != 1 {
|
if id%2 != 1 {
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("headers_even", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
// A HEADERS frame can be used to create a new stream or
|
// A HEADERS frame can be used to create a new stream or
|
||||||
// send a trailer for an open one. If we already have a stream
|
// send a trailer for an open one. If we already have a stream
|
||||||
@ -1814,7 +1822,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
// this state, it MUST respond with a stream error (Section 5.4.2) of
|
// this state, it MUST respond with a stream error (Section 5.4.2) of
|
||||||
// type STREAM_CLOSED.
|
// type STREAM_CLOSED.
|
||||||
if st.state == stateHalfClosedRemote {
|
if st.state == stateHalfClosedRemote {
|
||||||
return streamError(id, ErrCodeStreamClosed)
|
return sc.countError("headers_half_closed", streamError(id, ErrCodeStreamClosed))
|
||||||
}
|
}
|
||||||
return st.processTrailerHeaders(f)
|
return st.processTrailerHeaders(f)
|
||||||
}
|
}
|
||||||
@ -1825,7 +1833,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
// receives an unexpected stream identifier MUST respond with
|
// receives an unexpected stream identifier MUST respond with
|
||||||
// a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
// a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||||
if id <= sc.maxClientStreamID {
|
if id <= sc.maxClientStreamID {
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("stream_went_down", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
sc.maxClientStreamID = id
|
sc.maxClientStreamID = id
|
||||||
|
|
||||||
@ -1842,14 +1850,14 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
if sc.curClientStreams+1 > sc.advMaxStreams {
|
if sc.curClientStreams+1 > sc.advMaxStreams {
|
||||||
if sc.unackedSettings == 0 {
|
if sc.unackedSettings == 0 {
|
||||||
// They should know better.
|
// They should know better.
|
||||||
return streamError(id, ErrCodeProtocol)
|
return sc.countError("over_max_streams", streamError(id, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
// Assume it's a network race, where they just haven't
|
// Assume it's a network race, where they just haven't
|
||||||
// received our last SETTINGS update. But actually
|
// received our last SETTINGS update. But actually
|
||||||
// this can't happen yet, because we don't yet provide
|
// this can't happen yet, because we don't yet provide
|
||||||
// a way for users to adjust server parameters at
|
// a way for users to adjust server parameters at
|
||||||
// runtime.
|
// runtime.
|
||||||
return streamError(id, ErrCodeRefusedStream)
|
return sc.countError("over_max_streams_race", streamError(id, ErrCodeRefusedStream))
|
||||||
}
|
}
|
||||||
|
|
||||||
initialState := stateOpen
|
initialState := stateOpen
|
||||||
@ -1859,7 +1867,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
st := sc.newStream(id, 0, initialState)
|
st := sc.newStream(id, 0, initialState)
|
||||||
|
|
||||||
if f.HasPriority() {
|
if f.HasPriority() {
|
||||||
if err := checkPriority(f.StreamID, f.Priority); err != nil {
|
if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sc.writeSched.AdjustStream(st.id, f.Priority)
|
sc.writeSched.AdjustStream(st.id, f.Priority)
|
||||||
@ -1903,15 +1911,15 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
|
|||||||
sc := st.sc
|
sc := st.sc
|
||||||
sc.serveG.check()
|
sc.serveG.check()
|
||||||
if st.gotTrailerHeader {
|
if st.gotTrailerHeader {
|
||||||
return ConnectionError(ErrCodeProtocol)
|
return sc.countError("dup_trailers", ConnectionError(ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
st.gotTrailerHeader = true
|
st.gotTrailerHeader = true
|
||||||
if !f.StreamEnded() {
|
if !f.StreamEnded() {
|
||||||
return streamError(st.id, ErrCodeProtocol)
|
return sc.countError("trailers_not_ended", streamError(st.id, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(f.PseudoFields()) > 0 {
|
if len(f.PseudoFields()) > 0 {
|
||||||
return streamError(st.id, ErrCodeProtocol)
|
return sc.countError("trailers_pseudo", streamError(st.id, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
if st.trailer != nil {
|
if st.trailer != nil {
|
||||||
for _, hf := range f.RegularFields() {
|
for _, hf := range f.RegularFields() {
|
||||||
@ -1920,7 +1928,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
|
|||||||
// TODO: send more details to the peer somehow. But http2 has
|
// TODO: send more details to the peer somehow. But http2 has
|
||||||
// no way to send debug data at a stream level. Discuss with
|
// no way to send debug data at a stream level. Discuss with
|
||||||
// HTTP folk.
|
// HTTP folk.
|
||||||
return streamError(st.id, ErrCodeProtocol)
|
return sc.countError("trailers_bogus", streamError(st.id, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
st.trailer[key] = append(st.trailer[key], hf.Value)
|
st.trailer[key] = append(st.trailer[key], hf.Value)
|
||||||
}
|
}
|
||||||
@ -1929,13 +1937,13 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkPriority(streamID uint32, p PriorityParam) error {
|
func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error {
|
||||||
if streamID == p.StreamDep {
|
if streamID == p.StreamDep {
|
||||||
// Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
|
// Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
|
||||||
// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
|
// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
|
||||||
// Section 5.3.3 says that a stream can depend on one of its dependencies,
|
// Section 5.3.3 says that a stream can depend on one of its dependencies,
|
||||||
// so it's only self-dependencies that are forbidden.
|
// so it's only self-dependencies that are forbidden.
|
||||||
return streamError(streamID, ErrCodeProtocol)
|
return sc.countError("priority", streamError(streamID, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1944,7 +1952,7 @@ func (sc *serverConn) processPriority(f *PriorityFrame) error {
|
|||||||
if sc.inGoAway {
|
if sc.inGoAway {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := checkPriority(f.StreamID, f.PriorityParam); err != nil {
|
if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
|
sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
|
||||||
@ -2001,7 +2009,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
|||||||
isConnect := rp.method == "CONNECT"
|
isConnect := rp.method == "CONNECT"
|
||||||
if isConnect {
|
if isConnect {
|
||||||
if rp.path != "" || rp.scheme != "" || rp.authority == "" {
|
if rp.path != "" || rp.scheme != "" || rp.authority == "" {
|
||||||
return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
|
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
} else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
|
} else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
|
||||||
// See 8.1.2.6 Malformed Requests and Responses:
|
// See 8.1.2.6 Malformed Requests and Responses:
|
||||||
@ -2014,13 +2022,13 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
|
|||||||
// "All HTTP/2 requests MUST include exactly one valid
|
// "All HTTP/2 requests MUST include exactly one valid
|
||||||
// value for the :method, :scheme, and :path
|
// value for the :method, :scheme, and :path
|
||||||
// pseudo-header fields"
|
// pseudo-header fields"
|
||||||
return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
|
return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyOpen := !f.StreamEnded()
|
bodyOpen := !f.StreamEnded()
|
||||||
if rp.method == "HEAD" && bodyOpen {
|
if rp.method == "HEAD" && bodyOpen {
|
||||||
// HEAD requests can't have bodies
|
// HEAD requests can't have bodies
|
||||||
return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
|
return nil, nil, sc.countError("head_body", streamError(f.StreamID, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
|
|
||||||
rp.header = make(http.Header)
|
rp.header = make(http.Header)
|
||||||
@ -2103,7 +2111,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
|
|||||||
var err error
|
var err error
|
||||||
url_, err = url.ParseRequestURI(rp.path)
|
url_, err = url.ParseRequestURI(rp.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, streamError(st.id, ErrCodeProtocol)
|
return nil, nil, sc.countError("bad_path", streamError(st.id, ErrCodeProtocol))
|
||||||
}
|
}
|
||||||
requestURI = rp.path
|
requestURI = rp.path
|
||||||
}
|
}
|
||||||
@ -2789,8 +2797,12 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
|
|||||||
// but PUSH_PROMISE requests cannot have a body.
|
// but PUSH_PROMISE requests cannot have a body.
|
||||||
// http://tools.ietf.org/html/rfc7540#section-8.2
|
// http://tools.ietf.org/html/rfc7540#section-8.2
|
||||||
// Also disallow Host, since the promised URL must be absolute.
|
// Also disallow Host, since the promised URL must be absolute.
|
||||||
switch strings.ToLower(k) {
|
if asciiEqualFold(k, "content-length") ||
|
||||||
case "content-length", "content-encoding", "trailer", "te", "expect", "host":
|
asciiEqualFold(k, "content-encoding") ||
|
||||||
|
asciiEqualFold(k, "trailer") ||
|
||||||
|
asciiEqualFold(k, "te") ||
|
||||||
|
asciiEqualFold(k, "expect") ||
|
||||||
|
asciiEqualFold(k, "host") {
|
||||||
return fmt.Errorf("promised request headers cannot include %q", k)
|
return fmt.Errorf("promised request headers cannot include %q", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2982,3 +2994,31 @@ func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sc *serverConn) countError(name string, err error) error {
|
||||||
|
if sc == nil || sc.srv == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f := sc.srv.CountError
|
||||||
|
if f == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var typ string
|
||||||
|
var code ErrCode
|
||||||
|
switch e := err.(type) {
|
||||||
|
case ConnectionError:
|
||||||
|
typ = "conn"
|
||||||
|
code = ErrCode(e)
|
||||||
|
case StreamError:
|
||||||
|
typ = "stream"
|
||||||
|
code = ErrCode(e.Code)
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
codeStr := errCodeName[code]
|
||||||
|
if codeStr == "" {
|
||||||
|
codeStr = strconv.Itoa(int(code))
|
||||||
|
}
|
||||||
|
f(fmt.Sprintf("%s_%s_%s", typ, codeStr, name))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
1628
vendor/golang.org/x/net/http2/transport.go
generated
vendored
1628
vendor/golang.org/x/net/http2/transport.go
generated
vendored
File diff suppressed because it is too large
Load Diff
7
vendor/golang.org/x/net/http2/write.go
generated
vendored
7
vendor/golang.org/x/net/http2/write.go
generated
vendored
@ -341,7 +341,12 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
|
|||||||
}
|
}
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
vv := h[k]
|
vv := h[k]
|
||||||
k = lowerHeader(k)
|
k, ascii := lowerHeader(k)
|
||||||
|
if !ascii {
|
||||||
|
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
|
||||||
|
// field names have to be ASCII characters (just as in HTTP/1.x).
|
||||||
|
continue
|
||||||
|
}
|
||||||
if !validWireHeaderFieldName(k) {
|
if !validWireHeaderFieldName(k) {
|
||||||
// Skip it as backup paranoia. Per
|
// Skip it as backup paranoia. Per
|
||||||
// golang.org/issue/14048, these should
|
// golang.org/issue/14048, these should
|
||||||
|
14
vendor/golang.org/x/net/idna/go118.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/idna/go118.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.18
|
||||||
|
// +build go1.18
|
||||||
|
|
||||||
|
package idna
|
||||||
|
|
||||||
|
// Transitional processing is disabled by default in Go 1.18.
|
||||||
|
// https://golang.org/issue/47510
|
||||||
|
const transitionalLookup = false
|
117
vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
117
vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
@ -59,23 +59,22 @@ type Option func(*options)
|
|||||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||||
// compatibility. It is used by most browsers when resolving domain names. This
|
// compatibility. It is used by some browsers when resolving domain names. This
|
||||||
// option is only meaningful if combined with MapForLookup.
|
// option is only meaningful if combined with MapForLookup.
|
||||||
func Transitional(transitional bool) Option {
|
func Transitional(transitional bool) Option {
|
||||||
return func(o *options) { o.transitional = true }
|
return func(o *options) { o.transitional = transitional }
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||||
// are longer than allowed by the RFC.
|
// are longer than allowed by the RFC.
|
||||||
|
//
|
||||||
|
// This option corresponds to the VerifyDnsLength flag in UTS #46.
|
||||||
func VerifyDNSLength(verify bool) Option {
|
func VerifyDNSLength(verify bool) Option {
|
||||||
return func(o *options) { o.verifyDNSLength = verify }
|
return func(o *options) { o.verifyDNSLength = verify }
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
||||||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
||||||
//
|
|
||||||
// This is the behavior suggested by the UTS #46 and is adopted by some
|
|
||||||
// browsers.
|
|
||||||
func RemoveLeadingDots(remove bool) Option {
|
func RemoveLeadingDots(remove bool) Option {
|
||||||
return func(o *options) { o.removeLeadingDots = remove }
|
return func(o *options) { o.removeLeadingDots = remove }
|
||||||
}
|
}
|
||||||
@ -83,6 +82,8 @@ func RemoveLeadingDots(remove bool) Option {
|
|||||||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
// ValidateLabels sets whether to check the mandatory label validation criteria
|
||||||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
||||||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
||||||
|
// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
|
||||||
|
// in UTS #46.
|
||||||
func ValidateLabels(enable bool) Option {
|
func ValidateLabels(enable bool) Option {
|
||||||
return func(o *options) {
|
return func(o *options) {
|
||||||
// Don't override existing mappings, but set one that at least checks
|
// Don't override existing mappings, but set one that at least checks
|
||||||
@ -91,25 +92,48 @@ func ValidateLabels(enable bool) Option {
|
|||||||
o.mapping = normalize
|
o.mapping = normalize
|
||||||
}
|
}
|
||||||
o.trie = trie
|
o.trie = trie
|
||||||
o.validateLabels = enable
|
o.checkJoiners = enable
|
||||||
o.fromPuny = validateFromPunycode
|
o.checkHyphens = enable
|
||||||
|
if enable {
|
||||||
|
o.fromPuny = validateFromPunycode
|
||||||
|
} else {
|
||||||
|
o.fromPuny = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckHyphens sets whether to check for correct use of hyphens ('-') in
|
||||||
|
// labels. Most web browsers do not have this option set, since labels such as
|
||||||
|
// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
|
||||||
|
//
|
||||||
|
// This option corresponds to the CheckHyphens flag in UTS #46.
|
||||||
|
func CheckHyphens(enable bool) Option {
|
||||||
|
return func(o *options) { o.checkHyphens = enable }
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
|
||||||
|
// A of RFC 5892, concerning the use of joiner runes.
|
||||||
|
//
|
||||||
|
// This option corresponds to the CheckJoiners flag in UTS #46.
|
||||||
|
func CheckJoiners(enable bool) Option {
|
||||||
|
return func(o *options) {
|
||||||
|
o.trie = trie
|
||||||
|
o.checkJoiners = enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrictDomainName limits the set of permissible ASCII characters to those
|
// StrictDomainName limits the set of permissible ASCII characters to those
|
||||||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
||||||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration.
|
// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
|
||||||
|
// but is only useful if ValidateLabels is set.
|
||||||
//
|
//
|
||||||
// This option is useful, for instance, for browsers that allow characters
|
// This option is useful, for instance, for browsers that allow characters
|
||||||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
// outside this range, for example a '_' (U+005F LOW LINE). See
|
||||||
// http://www.rfc-editor.org/std/std3.txt for more details This option
|
// http://www.rfc-editor.org/std/std3.txt for more details.
|
||||||
// corresponds to the UseSTD3ASCIIRules option in UTS #46.
|
//
|
||||||
|
// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
|
||||||
func StrictDomainName(use bool) Option {
|
func StrictDomainName(use bool) Option {
|
||||||
return func(o *options) {
|
return func(o *options) { o.useSTD3Rules = use }
|
||||||
o.trie = trie
|
|
||||||
o.useSTD3Rules = use
|
|
||||||
o.fromPuny = validateFromPunycode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: the following options pull in tables. The tables should not be linked
|
// NOTE: the following options pull in tables. The tables should not be linked
|
||||||
@ -117,6 +141,8 @@ func StrictDomainName(use bool) Option {
|
|||||||
|
|
||||||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
||||||
// that relies on proper validation of labels should include this rule.
|
// that relies on proper validation of labels should include this rule.
|
||||||
|
//
|
||||||
|
// This option corresponds to the CheckBidi flag in UTS #46.
|
||||||
func BidiRule() Option {
|
func BidiRule() Option {
|
||||||
return func(o *options) { o.bidirule = bidirule.ValidString }
|
return func(o *options) { o.bidirule = bidirule.ValidString }
|
||||||
}
|
}
|
||||||
@ -152,7 +178,8 @@ func MapForLookup() Option {
|
|||||||
type options struct {
|
type options struct {
|
||||||
transitional bool
|
transitional bool
|
||||||
useSTD3Rules bool
|
useSTD3Rules bool
|
||||||
validateLabels bool
|
checkHyphens bool
|
||||||
|
checkJoiners bool
|
||||||
verifyDNSLength bool
|
verifyDNSLength bool
|
||||||
removeLeadingDots bool
|
removeLeadingDots bool
|
||||||
|
|
||||||
@ -225,8 +252,11 @@ func (p *Profile) String() string {
|
|||||||
if p.useSTD3Rules {
|
if p.useSTD3Rules {
|
||||||
s += ":UseSTD3Rules"
|
s += ":UseSTD3Rules"
|
||||||
}
|
}
|
||||||
if p.validateLabels {
|
if p.checkHyphens {
|
||||||
s += ":ValidateLabels"
|
s += ":CheckHyphens"
|
||||||
|
}
|
||||||
|
if p.checkJoiners {
|
||||||
|
s += ":CheckJoiners"
|
||||||
}
|
}
|
||||||
if p.verifyDNSLength {
|
if p.verifyDNSLength {
|
||||||
s += ":VerifyDNSLength"
|
s += ":VerifyDNSLength"
|
||||||
@ -254,26 +284,29 @@ var (
|
|||||||
|
|
||||||
punycode = &Profile{}
|
punycode = &Profile{}
|
||||||
lookup = &Profile{options{
|
lookup = &Profile{options{
|
||||||
transitional: true,
|
transitional: transitionalLookup,
|
||||||
useSTD3Rules: true,
|
useSTD3Rules: true,
|
||||||
validateLabels: true,
|
checkHyphens: true,
|
||||||
trie: trie,
|
checkJoiners: true,
|
||||||
fromPuny: validateFromPunycode,
|
trie: trie,
|
||||||
mapping: validateAndMap,
|
fromPuny: validateFromPunycode,
|
||||||
bidirule: bidirule.ValidString,
|
mapping: validateAndMap,
|
||||||
|
bidirule: bidirule.ValidString,
|
||||||
}}
|
}}
|
||||||
display = &Profile{options{
|
display = &Profile{options{
|
||||||
useSTD3Rules: true,
|
useSTD3Rules: true,
|
||||||
validateLabels: true,
|
checkHyphens: true,
|
||||||
trie: trie,
|
checkJoiners: true,
|
||||||
fromPuny: validateFromPunycode,
|
trie: trie,
|
||||||
mapping: validateAndMap,
|
fromPuny: validateFromPunycode,
|
||||||
bidirule: bidirule.ValidString,
|
mapping: validateAndMap,
|
||||||
|
bidirule: bidirule.ValidString,
|
||||||
}}
|
}}
|
||||||
registration = &Profile{options{
|
registration = &Profile{options{
|
||||||
useSTD3Rules: true,
|
useSTD3Rules: true,
|
||||||
validateLabels: true,
|
|
||||||
verifyDNSLength: true,
|
verifyDNSLength: true,
|
||||||
|
checkHyphens: true,
|
||||||
|
checkJoiners: true,
|
||||||
trie: trie,
|
trie: trie,
|
||||||
fromPuny: validateFromPunycode,
|
fromPuny: validateFromPunycode,
|
||||||
mapping: validateRegistration,
|
mapping: validateRegistration,
|
||||||
@ -340,7 +373,7 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
|
|||||||
}
|
}
|
||||||
isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight
|
isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight
|
||||||
labels.set(u)
|
labels.set(u)
|
||||||
if err == nil && p.validateLabels {
|
if err == nil && p.fromPuny != nil {
|
||||||
err = p.fromPuny(p, u)
|
err = p.fromPuny(p, u)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -681,16 +714,18 @@ func (p *Profile) validateLabel(s string) (err error) {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !p.validateLabels {
|
if p.checkHyphens {
|
||||||
|
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
||||||
|
return &labelError{s, "V2"}
|
||||||
|
}
|
||||||
|
if s[0] == '-' || s[len(s)-1] == '-' {
|
||||||
|
return &labelError{s, "V3"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !p.checkJoiners {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
trie := p.trie // p.validateLabels is only set if trie is set.
|
trie := p.trie // p.checkJoiners is only set if trie is set.
|
||||||
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
|
||||||
return &labelError{s, "V2"}
|
|
||||||
}
|
|
||||||
if s[0] == '-' || s[len(s)-1] == '-' {
|
|
||||||
return &labelError{s, "V3"}
|
|
||||||
}
|
|
||||||
// TODO: merge the use of this in the trie.
|
// TODO: merge the use of this in the trie.
|
||||||
v, sz := trie.lookupString(s)
|
v, sz := trie.lookupString(s)
|
||||||
x := info(v)
|
x := info(v)
|
||||||
|
97
vendor/golang.org/x/net/idna/idna9.0.0.go
generated
vendored
97
vendor/golang.org/x/net/idna/idna9.0.0.go
generated
vendored
@ -58,23 +58,22 @@ type Option func(*options)
|
|||||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||||
// compatibility. It is used by most browsers when resolving domain names. This
|
// compatibility. It is used by some browsers when resolving domain names. This
|
||||||
// option is only meaningful if combined with MapForLookup.
|
// option is only meaningful if combined with MapForLookup.
|
||||||
func Transitional(transitional bool) Option {
|
func Transitional(transitional bool) Option {
|
||||||
return func(o *options) { o.transitional = true }
|
return func(o *options) { o.transitional = transitional }
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||||
// are longer than allowed by the RFC.
|
// are longer than allowed by the RFC.
|
||||||
|
//
|
||||||
|
// This option corresponds to the VerifyDnsLength flag in UTS #46.
|
||||||
func VerifyDNSLength(verify bool) Option {
|
func VerifyDNSLength(verify bool) Option {
|
||||||
return func(o *options) { o.verifyDNSLength = verify }
|
return func(o *options) { o.verifyDNSLength = verify }
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
||||||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
||||||
//
|
|
||||||
// This is the behavior suggested by the UTS #46 and is adopted by some
|
|
||||||
// browsers.
|
|
||||||
func RemoveLeadingDots(remove bool) Option {
|
func RemoveLeadingDots(remove bool) Option {
|
||||||
return func(o *options) { o.removeLeadingDots = remove }
|
return func(o *options) { o.removeLeadingDots = remove }
|
||||||
}
|
}
|
||||||
@ -82,6 +81,8 @@ func RemoveLeadingDots(remove bool) Option {
|
|||||||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
// ValidateLabels sets whether to check the mandatory label validation criteria
|
||||||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
||||||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
||||||
|
// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
|
||||||
|
// in UTS #46.
|
||||||
func ValidateLabels(enable bool) Option {
|
func ValidateLabels(enable bool) Option {
|
||||||
return func(o *options) {
|
return func(o *options) {
|
||||||
// Don't override existing mappings, but set one that at least checks
|
// Don't override existing mappings, but set one that at least checks
|
||||||
@ -90,25 +91,48 @@ func ValidateLabels(enable bool) Option {
|
|||||||
o.mapping = normalize
|
o.mapping = normalize
|
||||||
}
|
}
|
||||||
o.trie = trie
|
o.trie = trie
|
||||||
o.validateLabels = enable
|
o.checkJoiners = enable
|
||||||
o.fromPuny = validateFromPunycode
|
o.checkHyphens = enable
|
||||||
|
if enable {
|
||||||
|
o.fromPuny = validateFromPunycode
|
||||||
|
} else {
|
||||||
|
o.fromPuny = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckHyphens sets whether to check for correct use of hyphens ('-') in
|
||||||
|
// labels. Most web browsers do not have this option set, since labels such as
|
||||||
|
// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
|
||||||
|
//
|
||||||
|
// This option corresponds to the CheckHyphens flag in UTS #46.
|
||||||
|
func CheckHyphens(enable bool) Option {
|
||||||
|
return func(o *options) { o.checkHyphens = enable }
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
|
||||||
|
// A of RFC 5892, concerning the use of joiner runes.
|
||||||
|
//
|
||||||
|
// This option corresponds to the CheckJoiners flag in UTS #46.
|
||||||
|
func CheckJoiners(enable bool) Option {
|
||||||
|
return func(o *options) {
|
||||||
|
o.trie = trie
|
||||||
|
o.checkJoiners = enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrictDomainName limits the set of permissable ASCII characters to those
|
// StrictDomainName limits the set of permissable ASCII characters to those
|
||||||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
||||||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration.
|
// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
|
||||||
|
// but is only useful if ValidateLabels is set.
|
||||||
//
|
//
|
||||||
// This option is useful, for instance, for browsers that allow characters
|
// This option is useful, for instance, for browsers that allow characters
|
||||||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
// outside this range, for example a '_' (U+005F LOW LINE). See
|
||||||
// http://www.rfc-editor.org/std/std3.txt for more details This option
|
// http://www.rfc-editor.org/std/std3.txt for more details.
|
||||||
// corresponds to the UseSTD3ASCIIRules option in UTS #46.
|
//
|
||||||
|
// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
|
||||||
func StrictDomainName(use bool) Option {
|
func StrictDomainName(use bool) Option {
|
||||||
return func(o *options) {
|
return func(o *options) { o.useSTD3Rules = use }
|
||||||
o.trie = trie
|
|
||||||
o.useSTD3Rules = use
|
|
||||||
o.fromPuny = validateFromPunycode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: the following options pull in tables. The tables should not be linked
|
// NOTE: the following options pull in tables. The tables should not be linked
|
||||||
@ -116,6 +140,8 @@ func StrictDomainName(use bool) Option {
|
|||||||
|
|
||||||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
||||||
// that relies on proper validation of labels should include this rule.
|
// that relies on proper validation of labels should include this rule.
|
||||||
|
//
|
||||||
|
// This option corresponds to the CheckBidi flag in UTS #46.
|
||||||
func BidiRule() Option {
|
func BidiRule() Option {
|
||||||
return func(o *options) { o.bidirule = bidirule.ValidString }
|
return func(o *options) { o.bidirule = bidirule.ValidString }
|
||||||
}
|
}
|
||||||
@ -152,7 +178,8 @@ func MapForLookup() Option {
|
|||||||
type options struct {
|
type options struct {
|
||||||
transitional bool
|
transitional bool
|
||||||
useSTD3Rules bool
|
useSTD3Rules bool
|
||||||
validateLabels bool
|
checkHyphens bool
|
||||||
|
checkJoiners bool
|
||||||
verifyDNSLength bool
|
verifyDNSLength bool
|
||||||
removeLeadingDots bool
|
removeLeadingDots bool
|
||||||
|
|
||||||
@ -225,8 +252,11 @@ func (p *Profile) String() string {
|
|||||||
if p.useSTD3Rules {
|
if p.useSTD3Rules {
|
||||||
s += ":UseSTD3Rules"
|
s += ":UseSTD3Rules"
|
||||||
}
|
}
|
||||||
if p.validateLabels {
|
if p.checkHyphens {
|
||||||
s += ":ValidateLabels"
|
s += ":CheckHyphens"
|
||||||
|
}
|
||||||
|
if p.checkJoiners {
|
||||||
|
s += ":CheckJoiners"
|
||||||
}
|
}
|
||||||
if p.verifyDNSLength {
|
if p.verifyDNSLength {
|
||||||
s += ":VerifyDNSLength"
|
s += ":VerifyDNSLength"
|
||||||
@ -255,9 +285,10 @@ var (
|
|||||||
punycode = &Profile{}
|
punycode = &Profile{}
|
||||||
lookup = &Profile{options{
|
lookup = &Profile{options{
|
||||||
transitional: true,
|
transitional: true,
|
||||||
useSTD3Rules: true,
|
|
||||||
validateLabels: true,
|
|
||||||
removeLeadingDots: true,
|
removeLeadingDots: true,
|
||||||
|
useSTD3Rules: true,
|
||||||
|
checkHyphens: true,
|
||||||
|
checkJoiners: true,
|
||||||
trie: trie,
|
trie: trie,
|
||||||
fromPuny: validateFromPunycode,
|
fromPuny: validateFromPunycode,
|
||||||
mapping: validateAndMap,
|
mapping: validateAndMap,
|
||||||
@ -265,8 +296,9 @@ var (
|
|||||||
}}
|
}}
|
||||||
display = &Profile{options{
|
display = &Profile{options{
|
||||||
useSTD3Rules: true,
|
useSTD3Rules: true,
|
||||||
validateLabels: true,
|
|
||||||
removeLeadingDots: true,
|
removeLeadingDots: true,
|
||||||
|
checkHyphens: true,
|
||||||
|
checkJoiners: true,
|
||||||
trie: trie,
|
trie: trie,
|
||||||
fromPuny: validateFromPunycode,
|
fromPuny: validateFromPunycode,
|
||||||
mapping: validateAndMap,
|
mapping: validateAndMap,
|
||||||
@ -274,8 +306,9 @@ var (
|
|||||||
}}
|
}}
|
||||||
registration = &Profile{options{
|
registration = &Profile{options{
|
||||||
useSTD3Rules: true,
|
useSTD3Rules: true,
|
||||||
validateLabels: true,
|
|
||||||
verifyDNSLength: true,
|
verifyDNSLength: true,
|
||||||
|
checkHyphens: true,
|
||||||
|
checkJoiners: true,
|
||||||
trie: trie,
|
trie: trie,
|
||||||
fromPuny: validateFromPunycode,
|
fromPuny: validateFromPunycode,
|
||||||
mapping: validateRegistration,
|
mapping: validateRegistration,
|
||||||
@ -339,7 +372,7 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
labels.set(u)
|
labels.set(u)
|
||||||
if err == nil && p.validateLabels {
|
if err == nil && p.fromPuny != nil {
|
||||||
err = p.fromPuny(p, u)
|
err = p.fromPuny(p, u)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -629,16 +662,18 @@ func (p *Profile) validateLabel(s string) error {
|
|||||||
if p.bidirule != nil && !p.bidirule(s) {
|
if p.bidirule != nil && !p.bidirule(s) {
|
||||||
return &labelError{s, "B"}
|
return &labelError{s, "B"}
|
||||||
}
|
}
|
||||||
if !p.validateLabels {
|
if p.checkHyphens {
|
||||||
|
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
||||||
|
return &labelError{s, "V2"}
|
||||||
|
}
|
||||||
|
if s[0] == '-' || s[len(s)-1] == '-' {
|
||||||
|
return &labelError{s, "V3"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !p.checkJoiners {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
trie := p.trie // p.validateLabels is only set if trie is set.
|
trie := p.trie // p.checkJoiners is only set if trie is set.
|
||||||
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
|
||||||
return &labelError{s, "V2"}
|
|
||||||
}
|
|
||||||
if s[0] == '-' || s[len(s)-1] == '-' {
|
|
||||||
return &labelError{s, "V3"}
|
|
||||||
}
|
|
||||||
// TODO: merge the use of this in the trie.
|
// TODO: merge the use of this in the trie.
|
||||||
v, sz := trie.lookupString(s)
|
v, sz := trie.lookupString(s)
|
||||||
x := info(v)
|
x := info(v)
|
||||||
|
12
vendor/golang.org/x/net/idna/pre_go118.go
generated
vendored
Normal file
12
vendor/golang.org/x/net/idna/pre_go118.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.18
|
||||||
|
// +build !go1.18
|
||||||
|
|
||||||
|
package idna
|
||||||
|
|
||||||
|
const transitionalLookup = true
|
36
vendor/golang.org/x/net/idna/punycode.go
generated
vendored
36
vendor/golang.org/x/net/idna/punycode.go
generated
vendored
@ -49,6 +49,7 @@ func decode(encoded string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i, n, bias := int32(0), initialN, initialBias
|
i, n, bias := int32(0), initialN, initialBias
|
||||||
|
overflow := false
|
||||||
for pos < len(encoded) {
|
for pos < len(encoded) {
|
||||||
oldI, w := i, int32(1)
|
oldI, w := i, int32(1)
|
||||||
for k := base; ; k += base {
|
for k := base; ; k += base {
|
||||||
@ -60,29 +61,32 @@ func decode(encoded string) (string, error) {
|
|||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
i += digit * w
|
i, overflow = madd(i, digit, w)
|
||||||
if i < 0 {
|
if overflow {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
t := k - bias
|
t := k - bias
|
||||||
if t < tmin {
|
if k <= bias {
|
||||||
t = tmin
|
t = tmin
|
||||||
} else if t > tmax {
|
} else if k >= bias+tmax {
|
||||||
t = tmax
|
t = tmax
|
||||||
}
|
}
|
||||||
if digit < t {
|
if digit < t {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w *= base - t
|
w, overflow = madd(0, w, base-t)
|
||||||
if w >= math.MaxInt32/base {
|
if overflow {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(output) >= 1024 {
|
||||||
|
return "", punyError(encoded)
|
||||||
|
}
|
||||||
x := int32(len(output) + 1)
|
x := int32(len(output) + 1)
|
||||||
bias = adapt(i-oldI, x, oldI == 0)
|
bias = adapt(i-oldI, x, oldI == 0)
|
||||||
n += i / x
|
n += i / x
|
||||||
i %= x
|
i %= x
|
||||||
if n > utf8.MaxRune || len(output) >= 1024 {
|
if n < 0 || n > utf8.MaxRune {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
output = append(output, 0)
|
output = append(output, 0)
|
||||||
@ -115,6 +119,7 @@ func encode(prefix, s string) (string, error) {
|
|||||||
if b > 0 {
|
if b > 0 {
|
||||||
output = append(output, '-')
|
output = append(output, '-')
|
||||||
}
|
}
|
||||||
|
overflow := false
|
||||||
for remaining != 0 {
|
for remaining != 0 {
|
||||||
m := int32(0x7fffffff)
|
m := int32(0x7fffffff)
|
||||||
for _, r := range s {
|
for _, r := range s {
|
||||||
@ -122,8 +127,8 @@ func encode(prefix, s string) (string, error) {
|
|||||||
m = r
|
m = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delta += (m - n) * (h + 1)
|
delta, overflow = madd(delta, m-n, h+1)
|
||||||
if delta < 0 {
|
if overflow {
|
||||||
return "", punyError(s)
|
return "", punyError(s)
|
||||||
}
|
}
|
||||||
n = m
|
n = m
|
||||||
@ -141,9 +146,9 @@ func encode(prefix, s string) (string, error) {
|
|||||||
q := delta
|
q := delta
|
||||||
for k := base; ; k += base {
|
for k := base; ; k += base {
|
||||||
t := k - bias
|
t := k - bias
|
||||||
if t < tmin {
|
if k <= bias {
|
||||||
t = tmin
|
t = tmin
|
||||||
} else if t > tmax {
|
} else if k >= bias+tmax {
|
||||||
t = tmax
|
t = tmax
|
||||||
}
|
}
|
||||||
if q < t {
|
if q < t {
|
||||||
@ -164,6 +169,15 @@ func encode(prefix, s string) (string, error) {
|
|||||||
return string(output), nil
|
return string(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// madd computes a + (b * c), detecting overflow.
|
||||||
|
func madd(a, b, c int32) (next int32, overflow bool) {
|
||||||
|
p := int64(b) * int64(c)
|
||||||
|
if p > math.MaxInt32-int64(a) {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
return a + int32(p), false
|
||||||
|
}
|
||||||
|
|
||||||
func decodeDigit(x byte) (digit int32, ok bool) {
|
func decodeDigit(x byte) (digit int32, ok bool) {
|
||||||
switch {
|
switch {
|
||||||
case '0' <= x && x <= '9':
|
case '0' <= x && x <= '9':
|
||||||
|
20629
vendor/golang.org/x/net/publicsuffix/table.go
generated
vendored
20629
vendor/golang.org/x/net/publicsuffix/table.go
generated
vendored
File diff suppressed because it is too large
Load Diff
133
vendor/golang.org/x/text/internal/language/language.go
generated
vendored
133
vendor/golang.org/x/text/internal/language/language.go
generated
vendored
@ -251,6 +251,13 @@ func (t Tag) Parent() Tag {
|
|||||||
|
|
||||||
// ParseExtension parses s as an extension and returns it on success.
|
// ParseExtension parses s as an extension and returns it on success.
|
||||||
func ParseExtension(s string) (ext string, err error) {
|
func ParseExtension(s string) (ext string, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
ext = ""
|
||||||
|
err = ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
scan := makeScannerString(s)
|
scan := makeScannerString(s)
|
||||||
var end int
|
var end int
|
||||||
if n := len(scan.token); n != 1 {
|
if n := len(scan.token); n != 1 {
|
||||||
@ -303,9 +310,17 @@ func (t Tag) Extensions() []string {
|
|||||||
// are of the allowed values defined for the Unicode locale extension ('u') in
|
// are of the allowed values defined for the Unicode locale extension ('u') in
|
||||||
// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
|
// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
|
||||||
// TypeForKey will traverse the inheritance chain to get the correct value.
|
// TypeForKey will traverse the inheritance chain to get the correct value.
|
||||||
|
//
|
||||||
|
// If there are multiple types associated with a key, only the first will be
|
||||||
|
// returned. If there is no type associated with a key, it returns the empty
|
||||||
|
// string.
|
||||||
func (t Tag) TypeForKey(key string) string {
|
func (t Tag) TypeForKey(key string) string {
|
||||||
if start, end, _ := t.findTypeForKey(key); end != start {
|
if _, start, end, _ := t.findTypeForKey(key); end != start {
|
||||||
return t.str[start:end]
|
s := t.str[start:end]
|
||||||
|
if p := strings.IndexByte(s, '-'); p >= 0 {
|
||||||
|
s = s[:p]
|
||||||
|
}
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -329,13 +344,13 @@ func (t Tag) SetTypeForKey(key, value string) (Tag, error) {
|
|||||||
|
|
||||||
// Remove the setting if value is "".
|
// Remove the setting if value is "".
|
||||||
if value == "" {
|
if value == "" {
|
||||||
start, end, _ := t.findTypeForKey(key)
|
start, sep, end, _ := t.findTypeForKey(key)
|
||||||
if start != end {
|
if start != sep {
|
||||||
// Remove key tag and leading '-'.
|
|
||||||
start -= 4
|
|
||||||
|
|
||||||
// Remove a possible empty extension.
|
// Remove a possible empty extension.
|
||||||
if (end == len(t.str) || t.str[end+2] == '-') && t.str[start-2] == '-' {
|
switch {
|
||||||
|
case t.str[start-2] != '-': // has previous elements.
|
||||||
|
case end == len(t.str), // end of string
|
||||||
|
end+2 < len(t.str) && t.str[end+2] == '-': // end of extension
|
||||||
start -= 2
|
start -= 2
|
||||||
}
|
}
|
||||||
if start == int(t.pVariant) && end == len(t.str) {
|
if start == int(t.pVariant) && end == len(t.str) {
|
||||||
@ -381,14 +396,14 @@ func (t Tag) SetTypeForKey(key, value string) (Tag, error) {
|
|||||||
t.str = string(buf[:uStart+len(b)])
|
t.str = string(buf[:uStart+len(b)])
|
||||||
} else {
|
} else {
|
||||||
s := t.str
|
s := t.str
|
||||||
start, end, hasExt := t.findTypeForKey(key)
|
start, sep, end, hasExt := t.findTypeForKey(key)
|
||||||
if start == end {
|
if start == sep {
|
||||||
if hasExt {
|
if hasExt {
|
||||||
b = b[2:]
|
b = b[2:]
|
||||||
}
|
}
|
||||||
t.str = fmt.Sprintf("%s-%s%s", s[:start], b, s[end:])
|
t.str = fmt.Sprintf("%s-%s%s", s[:sep], b, s[end:])
|
||||||
} else {
|
} else {
|
||||||
t.str = fmt.Sprintf("%s%s%s", s[:start], value, s[end:])
|
t.str = fmt.Sprintf("%s-%s%s", s[:start+3], value, s[end:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t, nil
|
return t, nil
|
||||||
@ -399,10 +414,10 @@ func (t Tag) SetTypeForKey(key, value string) (Tag, error) {
|
|||||||
// wasn't found. The hasExt return value reports whether an -u extension was present.
|
// wasn't found. The hasExt return value reports whether an -u extension was present.
|
||||||
// Note: the extensions are typically very small and are likely to contain
|
// Note: the extensions are typically very small and are likely to contain
|
||||||
// only one key-type pair.
|
// only one key-type pair.
|
||||||
func (t Tag) findTypeForKey(key string) (start, end int, hasExt bool) {
|
func (t Tag) findTypeForKey(key string) (start, sep, end int, hasExt bool) {
|
||||||
p := int(t.pExt)
|
p := int(t.pExt)
|
||||||
if len(key) != 2 || p == len(t.str) || p == 0 {
|
if len(key) != 2 || p == len(t.str) || p == 0 {
|
||||||
return p, p, false
|
return p, p, p, false
|
||||||
}
|
}
|
||||||
s := t.str
|
s := t.str
|
||||||
|
|
||||||
@ -410,10 +425,10 @@ func (t Tag) findTypeForKey(key string) (start, end int, hasExt bool) {
|
|||||||
for p++; s[p] != 'u'; p++ {
|
for p++; s[p] != 'u'; p++ {
|
||||||
if s[p] > 'u' {
|
if s[p] > 'u' {
|
||||||
p--
|
p--
|
||||||
return p, p, false
|
return p, p, p, false
|
||||||
}
|
}
|
||||||
if p = nextExtension(s, p); p == len(s) {
|
if p = nextExtension(s, p); p == len(s) {
|
||||||
return len(s), len(s), false
|
return len(s), len(s), len(s), false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Proceed to the hyphen following the extension name.
|
// Proceed to the hyphen following the extension name.
|
||||||
@ -424,40 +439,28 @@ func (t Tag) findTypeForKey(key string) (start, end int, hasExt bool) {
|
|||||||
|
|
||||||
// Iterate over keys until we get the end of a section.
|
// Iterate over keys until we get the end of a section.
|
||||||
for {
|
for {
|
||||||
// p points to the hyphen preceding the current token.
|
end = p
|
||||||
if p3 := p + 3; s[p3] == '-' {
|
for p++; p < len(s) && s[p] != '-'; p++ {
|
||||||
// Found a key.
|
}
|
||||||
// Check whether we just processed the key that was requested.
|
n := p - end - 1
|
||||||
if curKey == key {
|
if n <= 2 && curKey == key {
|
||||||
return start, p, true
|
if sep < end {
|
||||||
|
sep++
|
||||||
}
|
}
|
||||||
// Set to the next key and continue scanning type tokens.
|
return start, sep, end, true
|
||||||
curKey = s[p+1 : p3]
|
}
|
||||||
|
switch n {
|
||||||
|
case 0, // invalid string
|
||||||
|
1: // next extension
|
||||||
|
return end, end, end, true
|
||||||
|
case 2:
|
||||||
|
// next key
|
||||||
|
curKey = s[end+1 : p]
|
||||||
if curKey > key {
|
if curKey > key {
|
||||||
return p, p, true
|
return end, end, end, true
|
||||||
}
|
}
|
||||||
// Start of the type token sequence.
|
start = end
|
||||||
start = p + 4
|
sep = p
|
||||||
// A type is at least 3 characters long.
|
|
||||||
p += 7 // 4 + 3
|
|
||||||
} else {
|
|
||||||
// Attribute or type, which is at least 3 characters long.
|
|
||||||
p += 4
|
|
||||||
}
|
|
||||||
// p points past the third character of a type or attribute.
|
|
||||||
max := p + 5 // maximum length of token plus hyphen.
|
|
||||||
if len(s) < max {
|
|
||||||
max = len(s)
|
|
||||||
}
|
|
||||||
for ; p < max && s[p] != '-'; p++ {
|
|
||||||
}
|
|
||||||
// Bail if we have exhausted all tokens or if the next token starts
|
|
||||||
// a new extension.
|
|
||||||
if p == len(s) || s[p+2] == '-' {
|
|
||||||
if curKey == key {
|
|
||||||
return start, p, true
|
|
||||||
}
|
|
||||||
return p, p, true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,7 +468,14 @@ func (t Tag) findTypeForKey(key string) (start, end int, hasExt bool) {
|
|||||||
// ParseBase parses a 2- or 3-letter ISO 639 code.
|
// ParseBase parses a 2- or 3-letter ISO 639 code.
|
||||||
// It returns a ValueError if s is a well-formed but unknown language identifier
|
// It returns a ValueError if s is a well-formed but unknown language identifier
|
||||||
// or another error if another error occurred.
|
// or another error if another error occurred.
|
||||||
func ParseBase(s string) (Language, error) {
|
func ParseBase(s string) (l Language, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
l = 0
|
||||||
|
err = ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if n := len(s); n < 2 || 3 < n {
|
if n := len(s); n < 2 || 3 < n {
|
||||||
return 0, ErrSyntax
|
return 0, ErrSyntax
|
||||||
}
|
}
|
||||||
@ -476,7 +486,14 @@ func ParseBase(s string) (Language, error) {
|
|||||||
// ParseScript parses a 4-letter ISO 15924 code.
|
// ParseScript parses a 4-letter ISO 15924 code.
|
||||||
// It returns a ValueError if s is a well-formed but unknown script identifier
|
// It returns a ValueError if s is a well-formed but unknown script identifier
|
||||||
// or another error if another error occurred.
|
// or another error if another error occurred.
|
||||||
func ParseScript(s string) (Script, error) {
|
func ParseScript(s string) (scr Script, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
scr = 0
|
||||||
|
err = ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if len(s) != 4 {
|
if len(s) != 4 {
|
||||||
return 0, ErrSyntax
|
return 0, ErrSyntax
|
||||||
}
|
}
|
||||||
@ -493,7 +510,14 @@ func EncodeM49(r int) (Region, error) {
|
|||||||
// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code.
|
// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code.
|
||||||
// It returns a ValueError if s is a well-formed but unknown region identifier
|
// It returns a ValueError if s is a well-formed but unknown region identifier
|
||||||
// or another error if another error occurred.
|
// or another error if another error occurred.
|
||||||
func ParseRegion(s string) (Region, error) {
|
func ParseRegion(s string) (r Region, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
r = 0
|
||||||
|
err = ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if n := len(s); n < 2 || 3 < n {
|
if n := len(s); n < 2 || 3 < n {
|
||||||
return 0, ErrSyntax
|
return 0, ErrSyntax
|
||||||
}
|
}
|
||||||
@ -582,7 +606,14 @@ type Variant struct {
|
|||||||
|
|
||||||
// ParseVariant parses and returns a Variant. An error is returned if s is not
|
// ParseVariant parses and returns a Variant. An error is returned if s is not
|
||||||
// a valid variant.
|
// a valid variant.
|
||||||
func ParseVariant(s string) (Variant, error) {
|
func ParseVariant(s string) (v Variant, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
v = Variant{}
|
||||||
|
err = ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
s = strings.ToLower(s)
|
s = strings.ToLower(s)
|
||||||
if id, ok := variantIndex[s]; ok {
|
if id, ok := variantIndex[s]; ok {
|
||||||
return Variant{id, s}, nil
|
return Variant{id, s}, nil
|
||||||
|
35
vendor/golang.org/x/text/internal/language/parse.go
generated
vendored
35
vendor/golang.org/x/text/internal/language/parse.go
generated
vendored
@ -138,7 +138,7 @@ func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) {
|
|||||||
b = make([]byte, n)
|
b = make([]byte, n)
|
||||||
copy(b, s.b[:oldStart])
|
copy(b, s.b[:oldStart])
|
||||||
} else {
|
} else {
|
||||||
b = s.b[:n:n]
|
b = s.b[:n]
|
||||||
}
|
}
|
||||||
copy(b[end:], s.b[oldEnd:])
|
copy(b[end:], s.b[oldEnd:])
|
||||||
s.b = b
|
s.b = b
|
||||||
@ -232,6 +232,13 @@ func Parse(s string) (t Tag, err error) {
|
|||||||
if s == "" {
|
if s == "" {
|
||||||
return Und, ErrSyntax
|
return Und, ErrSyntax
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
t = Und
|
||||||
|
err = ErrSyntax
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
if len(s) <= maxAltTaglen {
|
if len(s) <= maxAltTaglen {
|
||||||
b := [maxAltTaglen]byte{}
|
b := [maxAltTaglen]byte{}
|
||||||
for i, c := range s {
|
for i, c := range s {
|
||||||
@ -483,7 +490,7 @@ func parseExtensions(scan *scanner) int {
|
|||||||
func parseExtension(scan *scanner) int {
|
func parseExtension(scan *scanner) int {
|
||||||
start, end := scan.start, scan.end
|
start, end := scan.start, scan.end
|
||||||
switch scan.token[0] {
|
switch scan.token[0] {
|
||||||
case 'u':
|
case 'u': // https://www.ietf.org/rfc/rfc6067.txt
|
||||||
attrStart := end
|
attrStart := end
|
||||||
scan.scan()
|
scan.scan()
|
||||||
for last := []byte{}; len(scan.token) > 2; scan.scan() {
|
for last := []byte{}; len(scan.token) > 2; scan.scan() {
|
||||||
@ -503,27 +510,29 @@ func parseExtension(scan *scanner) int {
|
|||||||
last = scan.token
|
last = scan.token
|
||||||
end = scan.end
|
end = scan.end
|
||||||
}
|
}
|
||||||
|
// Scan key-type sequences. A key is of length 2 and may be followed
|
||||||
|
// by 0 or more "type" subtags from 3 to the maximum of 8 letters.
|
||||||
var last, key []byte
|
var last, key []byte
|
||||||
for attrEnd := end; len(scan.token) == 2; last = key {
|
for attrEnd := end; len(scan.token) == 2; last = key {
|
||||||
key = scan.token
|
key = scan.token
|
||||||
keyEnd := scan.end
|
end = scan.end
|
||||||
end = scan.acceptMinSize(3)
|
for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() {
|
||||||
|
end = scan.end
|
||||||
|
}
|
||||||
// TODO: check key value validity
|
// TODO: check key value validity
|
||||||
if keyEnd == end || bytes.Compare(key, last) != 1 {
|
if bytes.Compare(key, last) != 1 || scan.err != nil {
|
||||||
// We have an invalid key or the keys are not sorted.
|
// We have an invalid key or the keys are not sorted.
|
||||||
// Start scanning keys from scratch and reorder.
|
// Start scanning keys from scratch and reorder.
|
||||||
p := attrEnd + 1
|
p := attrEnd + 1
|
||||||
scan.next = p
|
scan.next = p
|
||||||
keys := [][]byte{}
|
keys := [][]byte{}
|
||||||
for scan.scan(); len(scan.token) == 2; {
|
for scan.scan(); len(scan.token) == 2; {
|
||||||
keyStart, keyEnd := scan.start, scan.end
|
keyStart := scan.start
|
||||||
end = scan.acceptMinSize(3)
|
end = scan.end
|
||||||
if keyEnd != end {
|
for scan.scan(); end < scan.end && len(scan.token) > 2; scan.scan() {
|
||||||
keys = append(keys, scan.b[keyStart:end])
|
end = scan.end
|
||||||
} else {
|
|
||||||
scan.setError(ErrSyntax)
|
|
||||||
end = keyStart
|
|
||||||
}
|
}
|
||||||
|
keys = append(keys, scan.b[keyStart:end])
|
||||||
}
|
}
|
||||||
sort.Stable(bytesSort{keys, 2})
|
sort.Stable(bytesSort{keys, 2})
|
||||||
if n := len(keys); n > 0 {
|
if n := len(keys); n > 0 {
|
||||||
@ -547,7 +556,7 @@ func parseExtension(scan *scanner) int {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 't':
|
case 't': // https://www.ietf.org/rfc/rfc6497.txt
|
||||||
scan.scan()
|
scan.scan()
|
||||||
if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) {
|
if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) {
|
||||||
_, end = parseTag(scan)
|
_, end = parseTag(scan)
|
||||||
|
1
vendor/golang.org/x/text/language/go1_1.go
generated
vendored
1
vendor/golang.org/x/text/language/go1_1.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.2
|
||||||
// +build !go1.2
|
// +build !go1.2
|
||||||
|
|
||||||
package language
|
package language
|
||||||
|
1
vendor/golang.org/x/text/language/go1_2.go
generated
vendored
1
vendor/golang.org/x/text/language/go1_2.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.2
|
||||||
// +build go1.2
|
// +build go1.2
|
||||||
|
|
||||||
package language
|
package language
|
||||||
|
4
vendor/golang.org/x/text/language/language.go
generated
vendored
4
vendor/golang.org/x/text/language/language.go
generated
vendored
@ -412,6 +412,10 @@ func (t Tag) Extensions() []Extension {
|
|||||||
// are of the allowed values defined for the Unicode locale extension ('u') in
|
// are of the allowed values defined for the Unicode locale extension ('u') in
|
||||||
// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
|
// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
|
||||||
// TypeForKey will traverse the inheritance chain to get the correct value.
|
// TypeForKey will traverse the inheritance chain to get the correct value.
|
||||||
|
//
|
||||||
|
// If there are multiple types associated with a key, only the first will be
|
||||||
|
// returned. If there is no type associated with a key, it returns the empty
|
||||||
|
// string.
|
||||||
func (t Tag) TypeForKey(key string) string {
|
func (t Tag) TypeForKey(key string) string {
|
||||||
if !compact.Tag(t).MayHaveExtensions() {
|
if !compact.Tag(t).MayHaveExtensions() {
|
||||||
if key != "rg" && key != "va" {
|
if key != "rg" && key != "va" {
|
||||||
|
22
vendor/golang.org/x/text/language/parse.go
generated
vendored
22
vendor/golang.org/x/text/language/parse.go
generated
vendored
@ -43,6 +43,13 @@ func Parse(s string) (t Tag, err error) {
|
|||||||
// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
|
// https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
|
||||||
// The resulting tag is canonicalized using the canonicalization type c.
|
// The resulting tag is canonicalized using the canonicalization type c.
|
||||||
func (c CanonType) Parse(s string) (t Tag, err error) {
|
func (c CanonType) Parse(s string) (t Tag, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
t = Tag{}
|
||||||
|
err = language.ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
tt, err := language.Parse(s)
|
tt, err := language.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return makeTag(tt), err
|
return makeTag(tt), err
|
||||||
@ -79,6 +86,13 @@ func Compose(part ...interface{}) (t Tag, err error) {
|
|||||||
// tag is returned after canonicalizing using CanonType c. If one or more errors
|
// tag is returned after canonicalizing using CanonType c. If one or more errors
|
||||||
// are encountered, one of the errors is returned.
|
// are encountered, one of the errors is returned.
|
||||||
func (c CanonType) Compose(part ...interface{}) (t Tag, err error) {
|
func (c CanonType) Compose(part ...interface{}) (t Tag, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
t = Tag{}
|
||||||
|
err = language.ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
var b language.Builder
|
var b language.Builder
|
||||||
if err = update(&b, part...); err != nil {
|
if err = update(&b, part...); err != nil {
|
||||||
return und, err
|
return und, err
|
||||||
@ -142,6 +156,14 @@ var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight")
|
|||||||
// Tags with a weight of zero will be dropped. An error will be returned if the
|
// Tags with a weight of zero will be dropped. An error will be returned if the
|
||||||
// input could not be parsed.
|
// input could not be parsed.
|
||||||
func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) {
|
func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) {
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
tag = nil
|
||||||
|
q = nil
|
||||||
|
err = language.ErrSyntax
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
var entry string
|
var entry string
|
||||||
for s != "" {
|
for s != "" {
|
||||||
if entry, s = split(s, ','); entry == "" {
|
if entry, s = split(s, ','); entry == "" {
|
||||||
|
8
vendor/golang.org/x/text/language/tables.go
generated
vendored
8
vendor/golang.org/x/text/language/tables.go
generated
vendored
@ -47,7 +47,7 @@ const (
|
|||||||
_Zzzz = 251
|
_Zzzz = 251
|
||||||
)
|
)
|
||||||
|
|
||||||
var regionToGroups = []uint8{ // 357 elements
|
var regionToGroups = []uint8{ // 358 elements
|
||||||
// Entry 0 - 3F
|
// Entry 0 - 3F
|
||||||
0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04,
|
0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00,
|
||||||
@ -98,8 +98,8 @@ var regionToGroups = []uint8{ // 357 elements
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
} // Size: 381 bytes
|
} // Size: 382 bytes
|
||||||
|
|
||||||
var paradigmLocales = [][3]uint16{ // 3 elements
|
var paradigmLocales = [][3]uint16{ // 3 elements
|
||||||
0: [3]uint16{0x139, 0x0, 0x7b},
|
0: [3]uint16{0x139, 0x0, 0x7b},
|
||||||
@ -295,4 +295,4 @@ var matchRegion = []regionIntelligibility{ // 15 elements
|
|||||||
14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5},
|
14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5},
|
||||||
} // Size: 114 bytes
|
} // Size: 114 bytes
|
||||||
|
|
||||||
// Total table size 1471 bytes (1KiB); checksum: 4CB1CD46
|
// Total table size 1472 bytes (1KiB); checksum: F86C669
|
||||||
|
1
vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
generated
vendored
1
vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.10
|
||||||
// +build go1.10
|
// +build go1.10
|
||||||
|
|
||||||
package bidirule
|
package bidirule
|
||||||
|
1
vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go
generated
vendored
1
vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.10
|
||||||
// +build !go1.10
|
// +build !go1.10
|
||||||
|
|
||||||
package bidirule
|
package bidirule
|
||||||
|
1
vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.10 && !go1.13
|
||||||
// +build go1.10,!go1.13
|
// +build go1.10,!go1.13
|
||||||
|
|
||||||
package bidi
|
package bidi
|
||||||
|
1
vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.13 && !go1.14
|
||||||
// +build go1.13,!go1.14
|
// +build go1.13,!go1.14
|
||||||
|
|
||||||
package bidi
|
package bidi
|
||||||
|
1
vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.14 && !go1.16
|
||||||
// +build go1.14,!go1.16
|
// +build go1.14,!go1.16
|
||||||
|
|
||||||
package bidi
|
package bidi
|
||||||
|
1
vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.16
|
||||||
// +build go1.16
|
// +build go1.16
|
||||||
|
|
||||||
package bidi
|
package bidi
|
||||||
|
1
vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build !go1.10
|
||||||
// +build !go1.10
|
// +build !go1.10
|
||||||
|
|
||||||
package bidi
|
package bidi
|
||||||
|
1
vendor/golang.org/x/text/unicode/norm/tables10.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/norm/tables10.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.10 && !go1.13
|
||||||
// +build go1.10,!go1.13
|
// +build go1.10,!go1.13
|
||||||
|
|
||||||
package norm
|
package norm
|
||||||
|
1
vendor/golang.org/x/text/unicode/norm/tables11.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/norm/tables11.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.13 && !go1.14
|
||||||
// +build go1.13,!go1.14
|
// +build go1.13,!go1.14
|
||||||
|
|
||||||
package norm
|
package norm
|
||||||
|
1
vendor/golang.org/x/text/unicode/norm/tables12.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/norm/tables12.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.14 && !go1.16
|
||||||
// +build go1.14,!go1.16
|
// +build go1.14,!go1.16
|
||||||
|
|
||||||
package norm
|
package norm
|
||||||
|
1
vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build go1.16
|
||||||
// +build go1.16
|
// +build go1.16
|
||||||
|
|
||||||
package norm
|
package norm
|
||||||
|
1
vendor/golang.org/x/text/unicode/norm/tables9.0.0.go
generated
vendored
1
vendor/golang.org/x/text/unicode/norm/tables9.0.0.go
generated
vendored
@ -1,5 +1,6 @@
|
|||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build !go1.10
|
||||||
// +build !go1.10
|
// +build !go1.10
|
||||||
|
|
||||||
package norm
|
package norm
|
||||||
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -96,10 +96,10 @@ github.com/xeipuuv/gojsonpointer
|
|||||||
github.com/xeipuuv/gojsonreference
|
github.com/xeipuuv/gojsonreference
|
||||||
# github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d
|
# github.com/xeipuuv/gojsonschema v0.0.0-20170210233622-6b67b3fab74d
|
||||||
github.com/xeipuuv/gojsonschema
|
github.com/xeipuuv/gojsonschema
|
||||||
# golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa
|
# golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||||
golang.org/x/crypto/md4
|
golang.org/x/crypto/md4
|
||||||
golang.org/x/crypto/pbkdf2
|
golang.org/x/crypto/pbkdf2
|
||||||
# golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
# golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
||||||
golang.org/x/net/http/httpguts
|
golang.org/x/net/http/httpguts
|
||||||
golang.org/x/net/http/httpproxy
|
golang.org/x/net/http/httpproxy
|
||||||
golang.org/x/net/http2
|
golang.org/x/net/http2
|
||||||
@ -112,7 +112,7 @@ golang.org/x/sync/semaphore
|
|||||||
golang.org/x/sys/internal/unsafeheader
|
golang.org/x/sys/internal/unsafeheader
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/text v0.3.5
|
# golang.org/x/text v0.3.7
|
||||||
golang.org/x/text/internal/language
|
golang.org/x/text/internal/language
|
||||||
golang.org/x/text/internal/language/compact
|
golang.org/x/text/internal/language/compact
|
||||||
golang.org/x/text/internal/tag
|
golang.org/x/text/internal/tag
|
||||||
|
Loading…
Reference in New Issue
Block a user