Merge pull request #75289 from dims/update-http2-dep-go-1.12

Update golang.org/x/net/... dependencies to release-branch.go1.12
pull/564/head
Kubernetes Prow Robot 2019-03-13 04:33:46 -07:00 committed by GitHub
commit e7d09ceb50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 5568 additions and 4380 deletions

51
Godeps/Godeps.json generated
View File

@ -3,6 +3,9 @@
"GoVersion": "go1.12",
"GodepVersion": "v80-k8s-r1",
"Packages": [
"golang.org/x/net/internal/nettest",
"golang.org/x/net/internal/socks",
"golang.org/x/net/internal/sockstest",
"github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
"github.com/bazelbuild/buildtools/buildozer",
"github.com/cespare/prettybench",
@ -2385,8 +2388,8 @@
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-middleware",
"Comment": "v1.0.0-4-g498ae206fc3cfe",
"Rev": "498ae206fc3cfe81cd82e48c1d4354026fa5f9ec"
"Comment": "v1.0.0-8-gcfaf5686ec79ff",
"Rev": "cfaf5686ec79ff8344257723b6f5ba1ae0ffeb4d"
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
@ -3622,55 +3625,67 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/context/ctxhttp",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/html",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/html/atom",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/html/charset",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/nettest",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/socks",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/sockstest",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/proxy",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/trace",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/websocket",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

109
Godeps/LICENSES generated
View File

@ -101156,6 +101156,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/golang.org/x/net/http/httpguts licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/golang.org/x/net/LICENSE 5d4950ecb7b26d2c5e4e7b4e0dd74707
================================================================================
================================================================================
= vendor/golang.org/x/net/http2 licensed under: =
@ -101262,7 +101297,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
= vendor/golang.org/x/net/internal/timeseries licensed under: =
= vendor/golang.org/x/net/internal/nettest licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
@ -101297,7 +101332,77 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
= vendor/golang.org/x/net/lex/httplex licensed under: =
= vendor/golang.org/x/net/internal/socks licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/golang.org/x/net/LICENSE 5d4950ecb7b26d2c5e4e7b4e0dd74707
================================================================================
================================================================================
= vendor/golang.org/x/net/internal/sockstest licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/golang.org/x/net/LICENSE 5d4950ecb7b26d2c5e4e7b4e0dd74707
================================================================================
================================================================================
= vendor/golang.org/x/net/internal/timeseries licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.

View File

@ -52,9 +52,23 @@ if [[ -d Godeps ]]; then
mv Godeps "${BACKUP}/Godeps"
fi
## Workaround "httplex" was dropped from golang.org/x/net repo and the code
## was moved to the "golang.org/x/net/http/httpguts" directory, we do not use
## this directly, however many packages we vendor are still using the older
## golang.org/x/net and we need to keep this until all those dependencies
## are switched to newer golang.org/x/net.
IGNORED_PACKAGES=(
"golang.org/x/net/lex/httplex"
)
REQUIRED_BINS=(
"golang.org/x/net/internal/nettest"
"golang.org/x/net/internal/socks"
"golang.org/x/net/internal/sockstest"
)
# Some things we want in godeps aren't code dependencies, so ./...
# won't pick them up.
REQUIRED_BINS=(
REQUIRED_BINS+=(
"github.com/bazelbuild/bazel-gazelle/cmd/gazelle"
"github.com/bazelbuild/buildtools/buildozer"
"github.com/cespare/prettybench"
@ -74,7 +88,7 @@ kube::log::status "Running godep save - this might take a while"
# This uses $(pwd) rather than ${KUBE_ROOT} because KUBE_ROOT will be
# realpath'ed, and godep barfs ("... is not using a known version control
# system") on our staging dirs.
GOPATH="${GOPATH}:$(pwd)/staging" ${KUBE_GODEP:?} save "${REQUIRED_BINS[@]}"
GOPATH="${GOPATH}:$(pwd)/staging" ${KUBE_GODEP:?} save -i $(IFS=,; echo "${IGNORED_PACKAGES[*]}") "${REQUIRED_BINS[@]}"
# create a symlink in vendor directory pointing to the staging client. This
# let other packages use the staging client as if it were vendored.

View File

@ -54,21 +54,21 @@
"ImportPath": "github.com/stretchr/testify/require",
"Rev": "c679ae2cc0cb27ec3293fea7e254e47386f05d69"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -488,7 +488,7 @@
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-middleware",
"Rev": "498ae206fc3cfe81cd82e48c1d4354026fa5f9ec"
"Rev": "cfaf5686ec79ff8344257723b6f5ba1ae0ffeb4d"
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
@ -688,35 +688,35 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/trace",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/websocket",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -120,31 +120,31 @@
},
{
"ImportPath": "golang.org/x/net/html",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/html/atom",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/websocket",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -468,7 +468,7 @@
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-middleware",
"Rev": "498ae206fc3cfe81cd82e48c1d4354026fa5f9ec"
"Rev": "cfaf5686ec79ff8344257723b6f5ba1ae0ffeb4d"
},
{
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
@ -696,35 +696,35 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/trace",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/websocket",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -168,23 +168,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -192,27 +192,27 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/context/ctxhttp",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -84,23 +84,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -18,21 +18,21 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -22,21 +22,21 @@
"ImportPath": "github.com/spf13/pflag",
"Rev": "583c0c0531f06d5278b7d917446061adc344b5cd"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -84,23 +84,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -18,21 +18,21 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -268,43 +268,43 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/html",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/html/atom",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/trace",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/websocket",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -18,21 +18,21 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -18,21 +18,21 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -18,21 +18,21 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -18,21 +18,21 @@
"ImportPath": "github.com/google/gofuzz",
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/text/secure/bidirule",

View File

@ -88,23 +88,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -84,23 +84,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -248,35 +248,35 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/trace",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/websocket",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -160,23 +160,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -96,23 +96,23 @@
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http/httpguts",
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/http2/hpack",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/net/idna",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
},
{
"ImportPath": "golang.org/x/net/lex/httplex",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"
"Rev": "65e2d4e15006aab9813ff8769e768bbf4bb667a0"
},
{
"ImportPath": "golang.org/x/oauth2",

View File

@ -1,8 +1,11 @@
package main
import (
"fmt"
"go/build"
"os"
"regexp"
"sort"
"strings"
)
@ -42,9 +45,19 @@ func LoadPackages(names ...string) (a []*Package, err error) {
if len(names) == 0 {
return nil, nil
}
pkgs := strings.Split(ignorePackages, ",")
sort.Strings(pkgs)
for _, i := range importPaths(names) {
p, err := listPackage(i)
if err != nil {
if len(pkgs) > 0 {
idx := sort.SearchStrings(pkgs, i)
if idx < len(pkgs) && pkgs[idx] == i {
fmt.Fprintf(os.Stderr, "warning: ignoring package %q \n", i)
continue
}
}
return nil, err
}
a = append(a, p)

View File

@ -64,12 +64,13 @@ For more about specifying packages, see 'go help packages'.
var (
saveR, saveT bool
ignorePackages string
)
func init() {
cmdSave.Flag.BoolVar(&saveR, "r", false, "rewrite import paths")
cmdSave.Flag.BoolVar(&saveT, "t", false, "save test files")
cmdSave.Flag.StringVar(&ignorePackages, "i", "", "list of packages to ignore separated by commas")
}
func runSave(cmd *Command, args []string) {

5
vendor/BUILD vendored
View File

@ -400,10 +400,13 @@ filegroup(
"//vendor/golang.org/x/lint:all-srcs",
"//vendor/golang.org/x/net/context:all-srcs",
"//vendor/golang.org/x/net/html:all-srcs",
"//vendor/golang.org/x/net/http/httpguts:all-srcs",
"//vendor/golang.org/x/net/http2:all-srcs",
"//vendor/golang.org/x/net/idna:all-srcs",
"//vendor/golang.org/x/net/internal/nettest:all-srcs",
"//vendor/golang.org/x/net/internal/socks:all-srcs",
"//vendor/golang.org/x/net/internal/sockstest:all-srcs",
"//vendor/golang.org/x/net/internal/timeseries:all-srcs",
"//vendor/golang.org/x/net/lex/httplex:all-srcs",
"//vendor/golang.org/x/net/proxy:all-srcs",
"//vendor/golang.org/x/net/trace:all-srcs",
"//vendor/golang.org/x/net/websocket:all-srcs",

View File

@ -1,7 +1,7 @@
sudo: false
language: go
go:
- 1.8.x
- 1.11.x
env:
- DEP_VERSION="0.3.2"
@ -15,7 +15,6 @@ install:
- dep ensure
script:
- make checkdocs
- make test
after_success:

View File

@ -1,166 +0,0 @@
# grpc_middleware
`import "github.com/grpc-ecosystem/go-grpc-middleware"`
* [Overview](#pkg-overview)
* [Imported Packages](#pkg-imports)
* [Index](#pkg-index)
## <a name="pkg-overview">Overview</a>
`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
### Middleware
gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
upstream gRPC codebase is relatively bare bones.
This package, and most of its child packages provides commonly needed middleware for gRPC:
client-side interceptors for retires, server-side interceptors for input validation and auth,
functions for chaining said interceptors, metadata convenience methods and more.
### Chaining
By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
the server side. `grpc_middleware` provides convenient chaining methods
Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
server chaining:
myServer := grpc.NewServer(
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
)
These interceptors will be executed from left to right: logging, monitoring and auth.
Here's an example for client side chaining:
clientConn, err = grpc.Dial(
address,
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
)
client = pb_testproto.NewTestServiceClient(clientConn)
resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
These interceptors will be executed from left to right: monitoring and then retry logic.
The retry interceptor will call every interceptor that follows it whenever when a retry happens.
### Writing Your Own
Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
For example, you may want to pass the identity of the caller from the auth interceptor all the way
to the handling function.
For example, a client side interceptor example for auth looks like:
func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
newCtx := context.WithValue(ctx, "user_id", "john@example.com")
return handler(newCtx, req)
}
Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
needed. For example:
func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
newStream := grpc_middleware.WrapServerStream(stream)
newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
return handler(srv, stream)
}
## <a name="pkg-imports">Imported Packages</a>
- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
## <a name="pkg-index">Index</a>
* [func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor](#ChainStreamClient)
* [func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor](#ChainStreamServer)
* [func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor](#ChainUnaryClient)
* [func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor](#ChainUnaryServer)
* [func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption](#WithStreamServerChain)
* [func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption](#WithUnaryServerChain)
* [type WrappedServerStream](#WrappedServerStream)
* [func WrapServerStream(stream grpc.ServerStream) \*WrappedServerStream](#WrapServerStream)
* [func (w \*WrappedServerStream) Context() context.Context](#WrappedServerStream.Context)
#### <a name="pkg-files">Package files</a>
[chain.go](./chain.go) [doc.go](./doc.go) [wrappers.go](./wrappers.go)
## <a name="ChainStreamClient">func</a> [ChainStreamClient](./chain.go#L136)
``` go
func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor
```
ChainStreamClient creates a single interceptor out of a chain of many interceptors.
Execution is done in left-to-right order, including passing of context.
For example ChainStreamClient(one, two, three) will execute one before two before three.
## <a name="ChainStreamServer">func</a> [ChainStreamServer](./chain.go#L58)
``` go
func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
```
ChainStreamServer creates a single interceptor out of a chain of many interceptors.
Execution is done in left-to-right order, including passing of context.
For example ChainUnaryServer(one, two, three) will execute one before two before three.
If you want to pass context between interceptors, use WrapServerStream.
## <a name="ChainUnaryClient">func</a> [ChainUnaryClient](./chain.go#L97)
``` go
func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
```
ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
Execution is done in left-to-right order, including passing of context.
For example ChainUnaryClient(one, two, three) will execute one before two before three.
## <a name="ChainUnaryServer">func</a> [ChainUnaryServer](./chain.go#L18)
``` go
func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
```
ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
Execution is done in left-to-right order, including passing of context.
For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
will see context changes of one and two.
## <a name="WithStreamServerChain">func</a> [WithStreamServerChain](./chain.go#L181)
``` go
func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption
```
WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
Basically syntactic sugar.
## <a name="WithUnaryServerChain">func</a> [WithUnaryServerChain](./chain.go#L175)
``` go
func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption
```
Chain creates a single interceptor out of a chain of many interceptors.
WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
Basically syntactic sugar.
## <a name="WrappedServerStream">type</a> [WrappedServerStream](./wrappers.go#L12-L16)
``` go
type WrappedServerStream struct {
grpc.ServerStream
// WrappedContext is the wrapper's own Context. You can assign it.
WrappedContext context.Context
}
```
WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
### <a name="WrapServerStream">func</a> [WrapServerStream](./wrappers.go#L24)
``` go
func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream
```
WrapServerStream returns a ServerStream that has the ability to overwrite context.
### <a name="WrappedServerStream.Context">func</a> (\*WrappedServerStream) [Context](./wrappers.go#L19)
``` go
func (w *WrappedServerStream) Context() context.Context
```
Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
- - -
Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd)

View File

@ -4,14 +4,14 @@
[[projects]]
name = "cloud.google.com/go"
packages = ["compute/metadata"]
revision = "2d3a6656c17a60b0815b7e06ab0be04eacb6e613"
version = "v0.16.0"
revision = "28a4bc8c44b3acbcc482cff0cdf7de29a4688b61"
version = "v0.35.1"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
version = "v1.1.1"
[[projects]]
name = "github.com/gogo/protobuf"
@ -23,7 +23,13 @@
branch = "master"
name = "github.com/golang/protobuf"
packages = ["jsonpb","proto","ptypes","ptypes/any","ptypes/duration","ptypes/struct","ptypes/timestamp"]
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
revision = "347cf4a86c1cb8d262994d8ef5924d4576c5b331"
[[projects]]
name = "github.com/konsorten/go-windows-terminal-sequences"
packages = ["."]
revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
version = "v1.0.1"
[[projects]]
name = "github.com/opentracing/opentracing-go"
@ -40,20 +46,20 @@
[[projects]]
name = "github.com/sirupsen/logrus"
packages = ["."]
revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
version = "v1.0.3"
revision = "e1e72e9de974bd926e5c56f83753fba2df402ce5"
version = "v1.3.0"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert","require","suite"]
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
version = "v1.1.4"
revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
version = "v1.3.0"
[[projects]]
name = "go.uber.org/atomic"
packages = ["."]
revision = "8474b86a5a6f79c443ce4b2992817ff32cf208b8"
version = "v1.3.1"
revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289"
version = "v1.3.2"
[[projects]]
name = "go.uber.org/multierr"
@ -64,56 +70,56 @@
[[projects]]
name = "go.uber.org/zap"
packages = [".","buffer","internal/bufferpool","internal/color","internal/exit","zapcore"]
revision = "35aad584952c3e7020db7b839f6b102de6271f89"
version = "v1.7.1"
revision = "ff33455a0e382e8a81d14dd7c922020b6b5e7982"
version = "v1.9.1"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = ["ssh/terminal"]
revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122"
revision = "b01c7a72566457eb1420261cdafef86638fc3861"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = ["context","context/ctxhttp","http2","http2/hpack","idna","internal/timeseries","lex/httplex","trace"]
revision = "a8b9294777976932365dabb6640cf1468d95c70f"
packages = ["context","context/ctxhttp","http/httpguts","http2","http2/hpack","idna","internal/timeseries","trace"]
revision = "d26f9f9a57f3fab6a695bec0d84433c2c50f8bbf"
[[projects]]
branch = "master"
name = "golang.org/x/oauth2"
packages = [".","google","internal","jws","jwt"]
revision = "f95fa95eaa936d9d87489b15d1d18b97c1ba9c28"
revision = "99b60b757ec124ebb7d6b7e97f153b19c10ce163"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix","windows"]
revision = "13fcbd661c8ececa8807a29b48407d674b1d8ed8"
revision = "302c3dd5f1cc82baae8e44d9c3178e89b6e2b345"
[[projects]]
branch = "master"
name = "golang.org/x/text"
packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
revision = "75cc3cad82b5f47d3fb229ddda8c5167da14f294"
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
name = "google.golang.org/appengine"
packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","urlfetch"]
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
version = "v1.0.0"
revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
version = "v1.4.0"
[[projects]]
branch = "master"
name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"]
revision = "7f0da29060c682909f650ad8ed4e515bd74fa12a"
revision = "8ac453e89fca495c0d17f98932642f392e2a11f3"
[[projects]]
name = "google.golang.org/grpc"
packages = [".","balancer","balancer/roundrobin","codes","connectivity","credentials","credentials/oauth","encoding","grpclb/grpc_lb_v1/messages","grpclog","internal","keepalive","metadata","naming","peer","resolver","resolver/dns","resolver/passthrough","stats","status","tap","transport"]
revision = "5a9f7b402fe85096d2e1d0383435ee1876e863d0"
version = "v1.8.0"
packages = [".","balancer","balancer/base","balancer/roundrobin","binarylog/grpc_binarylog_v1","codes","connectivity","credentials","credentials/internal","credentials/oauth","encoding","encoding/proto","grpclog","internal","internal/backoff","internal/binarylog","internal/channelz","internal/envconfig","internal/grpcrand","internal/grpcsync","internal/syscall","internal/transport","keepalive","metadata","naming","peer","resolver","resolver/dns","resolver/passthrough","stats","status","tap"]
revision = "a02b0774206b209466313a0b525d2c738fe407eb"
version = "v1.18.0"
[solve-meta]
analyzer-name = "dep"

View File

@ -11,8 +11,6 @@
[gRPC Go](https://github.com/grpc/grpc-go) Middleware: interceptors, helpers, utilities.
**Important** The repo recently moved to `github.com/grpc-ecosystem/go-grpc-middleware`, please update your import paths.
## Middleware
[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for
@ -24,7 +22,7 @@ These are generic building blocks that make it easy to build multiple microservi
The purpose of this repository is to act as a go-to point for such reusable functionality. It contains
some of them itself, but also will link to useful external repos.
`grpc_middleware` itself provides support for chaining interceptors. See [Documentation](DOC.md), but here's an example:
`grpc_middleware` itself provides support for chaining interceptors, here's an example:
```go
import "github.com/grpc-ecosystem/go-grpc-middleware"

View File

@ -1,14 +1,8 @@
SHELL="/bin/bash"
SHELL=/bin/bash
GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/)
all: vet fmt docs test
docs:
./scripts/docs.sh generate
checkdocs:
./scripts/docs.sh check
all: vet fmt test
fmt:
go fmt $(GOFILES_NOVENDOR)
@ -19,4 +13,4 @@ vet:
test: vet
./scripts/test_all.sh
.PHONY: all docs validate test
.PHONY: all test

View File

@ -2,14 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"ctxhttp.go",
"ctxhttp_pre17.go",
],
srcs = ["ctxhttp.go"],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/context/ctxhttp",
importpath = "golang.org/x/net/context/ctxhttp",
visibility = ["//visibility:public"],
deps = ["//vendor/golang.org/x/net/context:go_default_library"],
)
filegroup(

View File

@ -2,18 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.7
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
package ctxhttp
import (
"context"
"io"
"net/http"
"net/url"
"strings"
"golang.org/x/net/context"
)
// Do sends an HTTP request with the provided http.Client and returns

View File

@ -1,147 +0,0 @@
// Copyright 2015 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.
// +build !go1.7
package ctxhttp
import (
"io"
"net/http"
"net/url"
"strings"
"golang.org/x/net/context"
)
func nop() {}
var (
testHookContextDoneBeforeHeaders = nop
testHookDoReturned = nop
testHookDidBodyClose = nop
)
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
// If the client is nil, http.DefaultClient is used.
// If the context is canceled or times out, ctx.Err() will be returned.
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
if client == nil {
client = http.DefaultClient
}
// TODO(djd): Respect any existing value of req.Cancel.
cancel := make(chan struct{})
req.Cancel = cancel
type responseAndError struct {
resp *http.Response
err error
}
result := make(chan responseAndError, 1)
// Make local copies of test hooks closed over by goroutines below.
// Prevents data races in tests.
testHookDoReturned := testHookDoReturned
testHookDidBodyClose := testHookDidBodyClose
go func() {
resp, err := client.Do(req)
testHookDoReturned()
result <- responseAndError{resp, err}
}()
var resp *http.Response
select {
case <-ctx.Done():
testHookContextDoneBeforeHeaders()
close(cancel)
// Clean up after the goroutine calling client.Do:
go func() {
if r := <-result; r.resp != nil {
testHookDidBodyClose()
r.resp.Body.Close()
}
}()
return nil, ctx.Err()
case r := <-result:
var err error
resp, err = r.resp, r.err
if err != nil {
return resp, err
}
}
c := make(chan struct{})
go func() {
select {
case <-ctx.Done():
close(cancel)
case <-c:
// The response's Body is closed.
}
}()
resp.Body = &notifyingReader{resp.Body, c}
return resp, nil
}
// Get issues a GET request via the Do function.
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
return Do(ctx, client, req)
}
// Head issues a HEAD request via the Do function.
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
req, err := http.NewRequest("HEAD", url, nil)
if err != nil {
return nil, err
}
return Do(ctx, client, req)
}
// Post issues a POST request via the Do function.
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", bodyType)
return Do(ctx, client, req)
}
// PostForm issues a POST request via the Do function.
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
}
// notifyingReader is an io.ReadCloser that closes the notify channel after
// Close is called or a Read fails on the underlying ReadCloser.
type notifyingReader struct {
io.ReadCloser
notify chan<- struct{}
}
func (r *notifyingReader) Read(p []byte) (int, error) {
n, err := r.ReadCloser.Read(p)
if err != nil && r.notify != nil {
close(r.notify)
r.notify = nil
}
return n, err
}
func (r *notifyingReader) Close() error {
err := r.ReadCloser.Close()
if r.notify != nil {
close(r.notify)
r.notify = nil
}
return err
}

View File

@ -306,7 +306,7 @@ func (t *table) push(i uint32, depth int) bool {
// The lists of element names and attribute keys were taken from
// https://html.spec.whatwg.org/multipage/indices.html#index
// as of the "HTML Living Standard - Last Updated 18 September 2017" version.
// as of the "HTML Living Standard - Last Updated 16 April 2018" version.
// "command", "keygen" and "menuitem" have been removed from the spec,
// but are kept here for backwards compatibility.
@ -665,6 +665,7 @@ var eventHandlers = []string{
// extra are ad-hoc values not covered by any of the lists above.
var extra = []string{
"acronym",
"align",
"annotation",
"annotation-xml",
@ -700,6 +701,8 @@ var extra = []string{
"plaintext",
"prompt",
"public",
"rb",
"rtc",
"spacer",
"strike",
"svg",

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
package html
// Section 12.2.3.2 of the HTML5 specification says "The following elements
// Section 12.2.4.2 of the HTML5 specification says "The following elements
// have varying levels of special parsing rules".
// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements
var isSpecialElementMap = map[string]bool{
@ -97,8 +97,16 @@ func isSpecialElement(element *Node) bool {
switch element.Namespace {
case "", "html":
return isSpecialElementMap[element.Data]
case "math":
switch element.Data {
case "mi", "mo", "mn", "ms", "mtext", "annotation-xml":
return true
}
case "svg":
return element.Data == "foreignObject"
switch element.Data {
case "foreignObject", "desc", "title":
return true
}
}
return false
}

4154
vendor/golang.org/x/net/html/entity.go generated vendored

File diff suppressed because it is too large Load Diff

View File

@ -67,7 +67,7 @@ func mathMLTextIntegrationPoint(n *Node) bool {
return false
}
// Section 12.2.5.5.
// Section 12.2.6.5.
var breakout = map[string]bool{
"b": true,
"big": true,
@ -115,7 +115,7 @@ var breakout = map[string]bool{
"var": true,
}
// Section 12.2.5.5.
// Section 12.2.6.5.
var svgTagNameAdjustments = map[string]string{
"altglyph": "altGlyph",
"altglyphdef": "altGlyphDef",
@ -155,7 +155,7 @@ var svgTagNameAdjustments = map[string]string{
"textpath": "textPath",
}
// Section 12.2.5.1
// Section 12.2.6.1
var mathMLAttributeAdjustments = map[string]string{
"definitionurl": "definitionURL",
}

33
vendor/golang.org/x/net/html/node.go generated vendored
View File

@ -21,9 +21,10 @@ const (
scopeMarkerNode
)
// Section 12.2.3.3 says "scope markers are inserted when entering applet
// elements, buttons, object elements, marquees, table cells, and table
// captions, and are used to prevent formatting from 'leaking'".
// Section 12.2.4.3 says "The markers are inserted when entering applet,
// object, marquee, template, td, th, and caption elements, and are used
// to prevent formatting from "leaking" into applet, object, marquee,
// template, td, th, and caption elements".
var scopeMarker = Node{Type: scopeMarkerNode}
// A Node consists of a NodeType and some Data (tag name for element nodes,
@ -173,6 +174,16 @@ func (s *nodeStack) index(n *Node) int {
return -1
}
// contains returns whether a is within s.
func (s *nodeStack) contains(a atom.Atom) bool {
for _, n := range *s {
if n.DataAtom == a && n.Namespace == "" {
return true
}
}
return false
}
// insert inserts a node at the given index.
func (s *nodeStack) insert(i int, n *Node) {
(*s) = append(*s, nil)
@ -191,3 +202,19 @@ func (s *nodeStack) remove(n *Node) {
(*s)[j] = nil
*s = (*s)[:j]
}
type insertionModeStack []insertionMode
func (s *insertionModeStack) pop() (im insertionMode) {
i := len(*s)
im = (*s)[i-1]
*s = (*s)[:i-1]
return im
}
func (s *insertionModeStack) top() insertionMode {
if i := len(*s); i > 0 {
return (*s)[i-1]
}
return nil
}

409
vendor/golang.org/x/net/html/parse.go generated vendored
View File

@ -25,20 +25,22 @@ type parser struct {
hasSelfClosingToken bool
// doc is the document root element.
doc *Node
// The stack of open elements (section 12.2.3.2) and active formatting
// elements (section 12.2.3.3).
// The stack of open elements (section 12.2.4.2) and active formatting
// elements (section 12.2.4.3).
oe, afe nodeStack
// Element pointers (section 12.2.3.4).
// Element pointers (section 12.2.4.4).
head, form *Node
// Other parsing state flags (section 12.2.3.5).
// Other parsing state flags (section 12.2.4.5).
scripting, framesetOK bool
// The stack of template insertion modes
templateStack insertionModeStack
// im is the current insertion mode.
im insertionMode
// originalIM is the insertion mode to go back to after completing a text
// or inTableText insertion mode.
originalIM insertionMode
// fosterParenting is whether new elements should be inserted according to
// the foster parenting rules (section 12.2.5.3).
// the foster parenting rules (section 12.2.6.1).
fosterParenting bool
// quirks is whether the parser is operating in "quirks mode."
quirks bool
@ -56,7 +58,7 @@ func (p *parser) top() *Node {
return p.doc
}
// Stop tags for use in popUntil. These come from section 12.2.3.2.
// Stop tags for use in popUntil. These come from section 12.2.4.2.
var (
defaultScopeStopTags = map[string][]a.Atom{
"": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},
@ -79,7 +81,7 @@ const (
// popUntil pops the stack of open elements at the highest element whose tag
// is in matchTags, provided there is no higher element in the scope's stop
// tags (as defined in section 12.2.3.2). It returns whether or not there was
// tags (as defined in section 12.2.4.2). It returns whether or not there was
// such an element. If there was not, popUntil leaves the stack unchanged.
//
// For example, the set of stop tags for table scope is: "html", "table". If
@ -126,7 +128,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
return -1
}
case tableScope:
if tagAtom == a.Html || tagAtom == a.Table {
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
return -1
}
case selectScope:
@ -162,17 +164,17 @@ func (p *parser) clearStackToContext(s scope) {
tagAtom := p.oe[i].DataAtom
switch s {
case tableScope:
if tagAtom == a.Html || tagAtom == a.Table {
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
p.oe = p.oe[:i+1]
return
}
case tableRowScope:
if tagAtom == a.Html || tagAtom == a.Tr {
if tagAtom == a.Html || tagAtom == a.Tr || tagAtom == a.Template {
p.oe = p.oe[:i+1]
return
}
case tableBodyScope:
if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead {
if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead || tagAtom == a.Template {
p.oe = p.oe[:i+1]
return
}
@ -183,7 +185,7 @@ func (p *parser) clearStackToContext(s scope) {
}
// generateImpliedEndTags pops nodes off the stack of open elements as long as
// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt.
// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.
// If exceptions are specified, nodes with that name will not be popped off.
func (p *parser) generateImpliedEndTags(exceptions ...string) {
var i int
@ -192,7 +194,7 @@ loop:
n := p.oe[i]
if n.Type == ElementNode {
switch n.DataAtom {
case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt:
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:
for _, except := range exceptions {
if n.Data == except {
break loop
@ -234,9 +236,9 @@ func (p *parser) shouldFosterParent() bool {
}
// fosterParent adds a child node according to the foster parenting rules.
// Section 12.2.5.3, "foster parenting".
// Section 12.2.6.1, "foster parenting".
func (p *parser) fosterParent(n *Node) {
var table, parent, prev *Node
var table, parent, prev, template *Node
var i int
for i = len(p.oe) - 1; i >= 0; i-- {
if p.oe[i].DataAtom == a.Table {
@ -245,6 +247,19 @@ func (p *parser) fosterParent(n *Node) {
}
}
var j int
for j = len(p.oe) - 1; j >= 0; j-- {
if p.oe[j].DataAtom == a.Template {
template = p.oe[j]
break
}
}
if template != nil && (table == nil || j > i) {
template.AppendChild(n)
return
}
if table == nil {
// The foster parent is the html element.
parent = p.oe[0]
@ -304,7 +319,7 @@ func (p *parser) addElement() {
})
}
// Section 12.2.3.3.
// Section 12.2.4.3.
func (p *parser) addFormattingElement() {
tagAtom, attr := p.tok.DataAtom, p.tok.Attr
p.addElement()
@ -351,7 +366,7 @@ findIdenticalElements:
p.afe = append(p.afe, p.top())
}
// Section 12.2.3.3.
// Section 12.2.4.3.
func (p *parser) clearActiveFormattingElements() {
for {
n := p.afe.pop()
@ -361,7 +376,7 @@ func (p *parser) clearActiveFormattingElements() {
}
}
// Section 12.2.3.3.
// Section 12.2.4.3.
func (p *parser) reconstructActiveFormattingElements() {
n := p.afe.top()
if n == nil {
@ -390,12 +405,12 @@ func (p *parser) reconstructActiveFormattingElements() {
}
}
// Section 12.2.4.
// Section 12.2.5.
func (p *parser) acknowledgeSelfClosingTag() {
p.hasSelfClosingToken = false
}
// An insertion mode (section 12.2.3.1) is the state transition function from
// An insertion mode (section 12.2.4.1) is the state transition function from
// a particular state in the HTML5 parser's state machine. It updates the
// parser's fields depending on parser.tok (where ErrorToken means EOF).
// It returns whether the token was consumed.
@ -403,7 +418,7 @@ type insertionMode func(*parser) bool
// setOriginalIM sets the insertion mode to return to after completing a text or
// inTableText insertion mode.
// Section 12.2.3.1, "using the rules for".
// Section 12.2.4.1, "using the rules for".
func (p *parser) setOriginalIM() {
if p.originalIM != nil {
panic("html: bad parser state: originalIM was set twice")
@ -411,18 +426,38 @@ func (p *parser) setOriginalIM() {
p.originalIM = p.im
}
// Section 12.2.3.1, "reset the insertion mode".
// Section 12.2.4.1, "reset the insertion mode".
func (p *parser) resetInsertionMode() {
for i := len(p.oe) - 1; i >= 0; i-- {
n := p.oe[i]
if i == 0 && p.context != nil {
last := i == 0
if last && p.context != nil {
n = p.context
}
switch n.DataAtom {
case a.Select:
if !last {
for ancestor, first := n, p.oe[0]; ancestor != first; {
if ancestor == first {
break
}
ancestor = p.oe[p.oe.index(ancestor)-1]
switch ancestor.DataAtom {
case a.Template:
p.im = inSelectIM
return
case a.Table:
p.im = inSelectInTableIM
return
}
}
}
p.im = inSelectIM
case a.Td, a.Th:
// TODO: remove this divergence from the HTML5 spec.
//
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.im = inCellIM
case a.Tr:
p.im = inRowIM
@ -434,25 +469,41 @@ func (p *parser) resetInsertionMode() {
p.im = inColumnGroupIM
case a.Table:
p.im = inTableIM
case a.Template:
// TODO: remove this divergence from the HTML5 spec.
if n.Namespace != "" {
continue
}
p.im = p.templateStack.top()
case a.Head:
p.im = inBodyIM
// TODO: remove this divergence from the HTML5 spec.
//
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.im = inHeadIM
case a.Body:
p.im = inBodyIM
case a.Frameset:
p.im = inFramesetIM
case a.Html:
p.im = beforeHeadIM
if p.head == nil {
p.im = beforeHeadIM
} else {
p.im = afterHeadIM
}
default:
if last {
p.im = inBodyIM
return
}
continue
}
return
}
p.im = inBodyIM
}
const whitespace = " \t\r\n\f"
// Section 12.2.5.4.1.
// Section 12.2.6.4.1.
func initialIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -479,7 +530,7 @@ func initialIM(p *parser) bool {
return false
}
// Section 12.2.5.4.2.
// Section 12.2.6.4.2.
func beforeHTMLIM(p *parser) bool {
switch p.tok.Type {
case DoctypeToken:
@ -517,7 +568,7 @@ func beforeHTMLIM(p *parser) bool {
return false
}
// Section 12.2.5.4.3.
// Section 12.2.6.4.3.
func beforeHeadIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -560,7 +611,7 @@ func beforeHeadIM(p *parser) bool {
return false
}
// Section 12.2.5.4.4.
// Section 12.2.6.4.4.
func inHeadIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -590,19 +641,41 @@ func inHeadIM(p *parser) bool {
case a.Head:
// Ignore the token.
return true
case a.Template:
p.addElement()
p.afe = append(p.afe, &scopeMarker)
p.framesetOK = false
p.im = inTemplateIM
p.templateStack = append(p.templateStack, inTemplateIM)
return true
}
case EndTagToken:
switch p.tok.DataAtom {
case a.Head:
n := p.oe.pop()
if n.DataAtom != a.Head {
panic("html: bad parser state: <head> element not found, in the in-head insertion mode")
}
p.oe.pop()
p.im = afterHeadIM
return true
case a.Body, a.Html, a.Br:
p.parseImpliedToken(EndTagToken, a.Head, a.Head.String())
return false
case a.Template:
if !p.oe.contains(a.Template) {
return true
}
// TODO: remove this divergence from the HTML5 spec.
//
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.generateImpliedEndTags()
for i := len(p.oe) - 1; i >= 0; i-- {
if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template {
p.oe = p.oe[:i]
break
}
}
p.clearActiveFormattingElements()
p.templateStack.pop()
p.resetInsertionMode()
return true
default:
// Ignore the token.
return true
@ -622,7 +695,7 @@ func inHeadIM(p *parser) bool {
return false
}
// Section 12.2.5.4.6.
// Section 12.2.6.4.6.
func afterHeadIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -648,7 +721,7 @@ func afterHeadIM(p *parser) bool {
p.addElement()
p.im = inFramesetIM
return true
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
p.oe = append(p.oe, p.head)
defer p.oe.remove(p.head)
return inHeadIM(p)
@ -660,6 +733,8 @@ func afterHeadIM(p *parser) bool {
switch p.tok.DataAtom {
case a.Body, a.Html, a.Br:
// Drop down to creating an implied <body> tag.
case a.Template:
return inHeadIM(p)
default:
// Ignore the token.
return true
@ -697,7 +772,7 @@ func copyAttributes(dst *Node, src Token) {
}
}
// Section 12.2.5.4.7.
// Section 12.2.6.4.7.
func inBodyIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -727,10 +802,16 @@ func inBodyIM(p *parser) bool {
case StartTagToken:
switch p.tok.DataAtom {
case a.Html:
if p.oe.contains(a.Template) {
return true
}
copyAttributes(p.oe[0], p.tok)
case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
return inHeadIM(p)
case a.Body:
if p.oe.contains(a.Template) {
return true
}
if len(p.oe) >= 2 {
body := p.oe[1]
if body.Type == ElementNode && body.DataAtom == a.Body {
@ -767,9 +848,13 @@ func inBodyIM(p *parser) bool {
// The newline, if any, will be dealt with by the TextToken case.
p.framesetOK = false
case a.Form:
if p.form == nil {
p.popUntil(buttonScope, a.P)
p.addElement()
if p.form != nil && !p.oe.contains(a.Template) {
// Ignore the token
return true
}
p.popUntil(buttonScope, a.P)
p.addElement()
if !p.oe.contains(a.Template) {
p.form = p.top()
}
case a.Li:
@ -903,6 +988,14 @@ func inBodyIM(p *parser) bool {
p.acknowledgeSelfClosingTag()
p.popUntil(buttonScope, a.P)
p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
if p.form == nil {
// NOTE: The 'isindex' element has been removed,
// and the 'template' element has not been designed to be
// collaborative with the index element.
//
// Ignore the token.
return true
}
if action != "" {
p.form.Attr = []Attribute{{Key: "action", Val: action}}
}
@ -952,11 +1045,16 @@ func inBodyIM(p *parser) bool {
}
p.reconstructActiveFormattingElements()
p.addElement()
case a.Rp, a.Rt:
case a.Rb, a.Rtc:
if p.elementInScope(defaultScope, a.Ruby) {
p.generateImpliedEndTags()
}
p.addElement()
case a.Rp, a.Rt:
if p.elementInScope(defaultScope, a.Ruby) {
p.generateImpliedEndTags("rtc")
}
p.addElement()
case a.Math, a.Svg:
p.reconstructActiveFormattingElements()
if p.tok.DataAtom == a.Math {
@ -993,15 +1091,29 @@ func inBodyIM(p *parser) bool {
case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
p.popUntil(defaultScope, p.tok.DataAtom)
case a.Form:
node := p.form
p.form = nil
i := p.indexOfElementInScope(defaultScope, a.Form)
if node == nil || i == -1 || p.oe[i] != node {
// Ignore the token.
return true
if p.oe.contains(a.Template) {
i := p.indexOfElementInScope(defaultScope, a.Form)
if i == -1 {
// Ignore the token.
return true
}
p.generateImpliedEndTags()
if p.oe[i].DataAtom != a.Form {
// Ignore the token.
return true
}
p.popUntil(defaultScope, a.Form)
} else {
node := p.form
p.form = nil
i := p.indexOfElementInScope(defaultScope, a.Form)
if node == nil || i == -1 || p.oe[i] != node {
// Ignore the token.
return true
}
p.generateImpliedEndTags()
p.oe.remove(node)
}
p.generateImpliedEndTags()
p.oe.remove(node)
case a.P:
if !p.elementInScope(buttonScope, a.P) {
p.parseImpliedToken(StartTagToken, a.P, a.P.String())
@ -1022,6 +1134,8 @@ func inBodyIM(p *parser) bool {
case a.Br:
p.tok.Type = StartTagToken
return false
case a.Template:
return inHeadIM(p)
default:
p.inBodyEndTagOther(p.tok.DataAtom)
}
@ -1030,6 +1144,21 @@ func inBodyIM(p *parser) bool {
Type: CommentNode,
Data: p.tok.Data,
})
case ErrorToken:
// TODO: remove this divergence from the HTML5 spec.
if len(p.templateStack) > 0 {
p.im = inTemplateIM
return false
} else {
for _, e := range p.oe {
switch e.DataAtom {
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,
a.Thead, a.Tr, a.Body, a.Html:
default:
return true
}
}
}
}
return true
@ -1160,7 +1289,7 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
}
// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
// "Any other end tag" handling from 12.2.5.5 The rules for parsing tokens in foreign content
// "Any other end tag" handling from 12.2.6.5 The rules for parsing tokens in foreign content
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
for i := len(p.oe) - 1; i >= 0; i-- {
@ -1174,7 +1303,7 @@ func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
}
}
// Section 12.2.5.4.8.
// Section 12.2.6.4.8.
func textIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1203,12 +1332,9 @@ func textIM(p *parser) bool {
return p.tok.Type == EndTagToken
}
// Section 12.2.5.4.9.
// Section 12.2.6.4.9.
func inTableIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
// Stop parsing.
return true
case TextToken:
p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1)
switch p.oe.top().DataAtom {
@ -1249,7 +1375,7 @@ func inTableIM(p *parser) bool {
}
// Ignore the token.
return true
case a.Style, a.Script:
case a.Style, a.Script, a.Template:
return inHeadIM(p)
case a.Input:
for _, t := range p.tok.Attr {
@ -1261,7 +1387,7 @@ func inTableIM(p *parser) bool {
}
// Otherwise drop down to the default action.
case a.Form:
if p.form != nil {
if p.oe.contains(a.Template) || p.form != nil {
// Ignore the token.
return true
}
@ -1291,6 +1417,8 @@ func inTableIM(p *parser) bool {
case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
// Ignore the token.
return true
case a.Template:
return inHeadIM(p)
}
case CommentToken:
p.addChild(&Node{
@ -1301,6 +1429,8 @@ func inTableIM(p *parser) bool {
case DoctypeToken:
// Ignore the token.
return true
case ErrorToken:
return inBodyIM(p)
}
p.fosterParenting = true
@ -1309,7 +1439,7 @@ func inTableIM(p *parser) bool {
return inBodyIM(p)
}
// Section 12.2.5.4.11.
// Section 12.2.6.4.11.
func inCaptionIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@ -1355,7 +1485,7 @@ func inCaptionIM(p *parser) bool {
return inBodyIM(p)
}
// Section 12.2.5.4.12.
// Section 12.2.6.4.12.
func inColumnGroupIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -1386,11 +1516,13 @@ func inColumnGroupIM(p *parser) bool {
p.oe.pop()
p.acknowledgeSelfClosingTag()
return true
case a.Template:
return inHeadIM(p)
}
case EndTagToken:
switch p.tok.DataAtom {
case a.Colgroup:
if p.oe.top().DataAtom != a.Html {
if p.oe.top().DataAtom == a.Colgroup {
p.oe.pop()
p.im = inTableIM
}
@ -1398,17 +1530,21 @@ func inColumnGroupIM(p *parser) bool {
case a.Col:
// Ignore the token.
return true
case a.Template:
return inHeadIM(p)
}
case ErrorToken:
return inBodyIM(p)
}
if p.oe.top().DataAtom != a.Html {
p.oe.pop()
p.im = inTableIM
return false
if p.oe.top().DataAtom != a.Colgroup {
return true
}
return true
p.oe.pop()
p.im = inTableIM
return false
}
// Section 12.2.5.4.13.
// Section 12.2.6.4.13.
func inTableBodyIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@ -1460,7 +1596,7 @@ func inTableBodyIM(p *parser) bool {
return inTableIM(p)
}
// Section 12.2.5.4.14.
// Section 12.2.6.4.14.
func inRowIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@ -1511,7 +1647,7 @@ func inRowIM(p *parser) bool {
return inTableIM(p)
}
// Section 12.2.5.4.15.
// Section 12.2.6.4.15.
func inCellIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@ -1560,12 +1696,9 @@ func inCellIM(p *parser) bool {
return inBodyIM(p)
}
// Section 12.2.5.4.16.
// Section 12.2.6.4.16.
func inSelectIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
// Stop parsing.
return true
case TextToken:
p.addText(strings.Replace(p.tok.Data, "\x00", "", -1))
case StartTagToken:
@ -1586,8 +1719,12 @@ func inSelectIM(p *parser) bool {
}
p.addElement()
case a.Select:
p.tok.Type = EndTagToken
return false
if p.popUntil(selectScope, a.Select) {
p.resetInsertionMode()
} else {
// Ignore the token.
return true
}
case a.Input, a.Keygen, a.Textarea:
if p.elementInScope(selectScope, a.Select) {
p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
@ -1597,7 +1734,7 @@ func inSelectIM(p *parser) bool {
p.tokenizer.NextIsNotRawText()
// Ignore the token.
return true
case a.Script:
case a.Script, a.Template:
return inHeadIM(p)
}
case EndTagToken:
@ -1617,7 +1754,12 @@ func inSelectIM(p *parser) bool {
case a.Select:
if p.popUntil(selectScope, a.Select) {
p.resetInsertionMode()
} else {
// Ignore the token.
return true
}
case a.Template:
return inHeadIM(p)
}
case CommentToken:
p.addChild(&Node{
@ -1627,30 +1769,107 @@ func inSelectIM(p *parser) bool {
case DoctypeToken:
// Ignore the token.
return true
case ErrorToken:
return inBodyIM(p)
}
return true
}
// Section 12.2.5.4.17.
// Section 12.2.6.4.17.
func inSelectInTableIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken, EndTagToken:
switch p.tok.DataAtom {
case a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:
if p.tok.Type == StartTagToken || p.elementInScope(tableScope, p.tok.DataAtom) {
p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
return false
} else {
if p.tok.Type == EndTagToken && !p.elementInScope(tableScope, p.tok.DataAtom) {
// Ignore the token.
return true
}
// This is like p.popUntil(selectScope, a.Select), but it also
// matches <math select>, not just <select>. Matching the MathML
// tag is arguably incorrect (conceptually), but it mimics what
// Chromium does.
for i := len(p.oe) - 1; i >= 0; i-- {
if n := p.oe[i]; n.DataAtom == a.Select {
p.oe = p.oe[:i]
break
}
}
p.resetInsertionMode()
return false
}
}
return inSelectIM(p)
}
// Section 12.2.5.4.18.
// Section 12.2.6.4.18.
func inTemplateIM(p *parser) bool {
switch p.tok.Type {
case TextToken, CommentToken, DoctypeToken:
return inBodyIM(p)
case StartTagToken:
switch p.tok.DataAtom {
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
return inHeadIM(p)
case a.Caption, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:
p.templateStack.pop()
p.templateStack = append(p.templateStack, inTableIM)
p.im = inTableIM
return false
case a.Col:
p.templateStack.pop()
p.templateStack = append(p.templateStack, inColumnGroupIM)
p.im = inColumnGroupIM
return false
case a.Tr:
p.templateStack.pop()
p.templateStack = append(p.templateStack, inTableBodyIM)
p.im = inTableBodyIM
return false
case a.Td, a.Th:
p.templateStack.pop()
p.templateStack = append(p.templateStack, inRowIM)
p.im = inRowIM
return false
default:
p.templateStack.pop()
p.templateStack = append(p.templateStack, inBodyIM)
p.im = inBodyIM
return false
}
case EndTagToken:
switch p.tok.DataAtom {
case a.Template:
return inHeadIM(p)
default:
// Ignore the token.
return true
}
case ErrorToken:
if !p.oe.contains(a.Template) {
// Ignore the token.
return true
}
// TODO: remove this divergence from the HTML5 spec.
//
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.generateImpliedEndTags()
for i := len(p.oe) - 1; i >= 0; i-- {
if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template {
p.oe = p.oe[:i]
break
}
}
p.clearActiveFormattingElements()
p.templateStack.pop()
p.resetInsertionMode()
return false
}
return false
}
// Section 12.2.6.4.19.
func afterBodyIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1688,7 +1907,7 @@ func afterBodyIM(p *parser) bool {
return false
}
// Section 12.2.5.4.19.
// Section 12.2.6.4.20.
func inFramesetIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1738,7 +1957,7 @@ func inFramesetIM(p *parser) bool {
return true
}
// Section 12.2.5.4.20.
// Section 12.2.6.4.21.
func afterFramesetIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1777,7 +1996,7 @@ func afterFramesetIM(p *parser) bool {
return true
}
// Section 12.2.5.4.21.
// Section 12.2.6.4.22.
func afterAfterBodyIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1806,7 +2025,7 @@ func afterAfterBodyIM(p *parser) bool {
return false
}
// Section 12.2.5.4.22.
// Section 12.2.6.4.23.
func afterAfterFramesetIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1844,7 +2063,7 @@ func afterAfterFramesetIM(p *parser) bool {
const whitespaceOrNUL = whitespace + "\x00"
// Section 12.2.5.5.
// Section 12.2.6.5
func parseForeignContent(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -1924,7 +2143,7 @@ func parseForeignContent(p *parser) bool {
return true
}
// Section 12.2.5.
// Section 12.2.6.
func (p *parser) inForeignContent() bool {
if len(p.oe) == 0 {
return false
@ -2012,6 +2231,15 @@ func (p *parser) parse() error {
}
// Parse returns the parse tree for the HTML from the given Reader.
//
// It implements the HTML5 parsing algorithm
// (https://html.spec.whatwg.org/multipage/syntax.html#tree-construction),
// which is very complicated. The resultant tree can contain implicitly created
// nodes that have no explicit <tag> listed in r's data, and nodes' parents can
// differ from the nesting implied by a naive processing of start and end
// <tag>s. Conversely, explicit <tag>s in r's data can be silently dropped,
// with no corresponding node in the resulting tree.
//
// The input is assumed to be UTF-8 encoded.
func Parse(r io.Reader) (*Node, error) {
p := &parser{
@ -2033,6 +2261,8 @@ func Parse(r io.Reader) (*Node, error) {
// ParseFragment parses a fragment of HTML and returns the nodes that were
// found. If the fragment is the InnerHTML for an existing element, pass that
// element in context.
//
// It has the same intricacies as Parse.
func ParseFragment(r io.Reader, context *Node) ([]*Node, error) {
contextTag := ""
if context != nil {
@ -2064,6 +2294,9 @@ func ParseFragment(r io.Reader, context *Node) ([]*Node, error) {
}
p.doc.AppendChild(root)
p.oe = nodeStack{root}
if context != nil && context.DataAtom == a.Template {
p.templateStack = append(p.templateStack, inTemplateIM)
}
p.resetInsertionMode()
for n := context; n != nil; n = n.Parent {

View File

@ -2,9 +2,12 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["httplex.go"],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/lex/httplex",
importpath = "golang.org/x/net/lex/httplex",
srcs = [
"guts.go",
"httplex.go",
],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/http/httpguts",
importpath = "golang.org/x/net/http/httpguts",
visibility = ["//visibility:public"],
deps = ["//vendor/golang.org/x/net/idna:go_default_library"],
)

50
vendor/golang.org/x/net/http/httpguts/guts.go generated vendored Normal file
View File

@ -0,0 +1,50 @@
// Copyright 2018 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 httpguts provides functions implementing various details
// of the HTTP specification.
//
// This package is shared by the standard library (which vendors it)
// and x/net/http2. It comes with no API stability promise.
package httpguts
import (
"net/textproto"
"strings"
)
// ValidTrailerHeader reports whether name is a valid header field name to appear
// in trailers.
// See RFC 7230, Section 4.1.2
func ValidTrailerHeader(name string) bool {
name = textproto.CanonicalMIMEHeaderKey(name)
if strings.HasPrefix(name, "If-") || badTrailer[name] {
return false
}
return true
}
var badTrailer = map[string]bool{
"Authorization": true,
"Cache-Control": true,
"Connection": true,
"Content-Encoding": true,
"Content-Length": true,
"Content-Range": true,
"Content-Type": true,
"Expect": true,
"Host": true,
"Keep-Alive": true,
"Max-Forwards": true,
"Pragma": true,
"Proxy-Authenticate": true,
"Proxy-Authorization": true,
"Proxy-Connection": true,
"Range": true,
"Realm": true,
"Te": true,
"Trailer": true,
"Transfer-Encoding": true,
"Www-Authenticate": true,
}

View File

@ -2,12 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package httplex contains rules around lexical matters of various
// HTTP-related specifications.
//
// This package is shared by the standard library (which vendors it)
// and x/net/http2. It comes with no API stability promise.
package httplex
package httpguts
import (
"net"

14
vendor/golang.org/x/net/http2/BUILD generated vendored
View File

@ -5,23 +5,15 @@ go_library(
srcs = [
"ciphers.go",
"client_conn_pool.go",
"configure_transport.go",
"databuffer.go",
"errors.go",
"flow.go",
"frame.go",
"go16.go",
"go17.go",
"go17_not18.go",
"go18.go",
"go19.go",
"go111.go",
"gotrack.go",
"headermap.go",
"http2.go",
"not_go16.go",
"not_go17.go",
"not_go18.go",
"not_go19.go",
"not_go111.go",
"pipe.go",
"server.go",
"transport.go",
@ -34,9 +26,9 @@ go_library(
importpath = "golang.org/x/net/http2",
visibility = ["//visibility:public"],
deps = [
"//vendor/golang.org/x/net/http/httpguts:go_default_library",
"//vendor/golang.org/x/net/http2/hpack:go_default_library",
"//vendor/golang.org/x/net/idna:go_default_library",
"//vendor/golang.org/x/net/lex/httplex:go_default_library",
],
)

View File

@ -52,9 +52,31 @@ const (
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) {
if isConnectionCloseRequest(req) && dialOnMiss {
// It gets its own connection.
traceGetConn(req, addr)
const singleUse = true
cc, err := p.t.dialClientConn(addr, singleUse)
if err != nil {
@ -64,7 +86,10 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
}
p.mu.Lock()
for _, cc := range p.conns[addr] {
if cc.CanTakeNewRequest() {
if st := cc.idleState(); st.canTakeNewRequest {
if p.shouldTraceGetConn(st) {
traceGetConn(req, addr)
}
p.mu.Unlock()
return cc, nil
}
@ -73,6 +98,7 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
p.mu.Unlock()
return nil, ErrNoCachedConn
}
traceGetConn(req, addr)
call := p.getStartDialLocked(addr)
p.mu.Unlock()
<-call.done

View File

@ -1,80 +0,0 @@
// Copyright 2015 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.
// +build go1.6
package http2
import (
"crypto/tls"
"fmt"
"net/http"
)
func configureTransport(t1 *http.Transport) (*Transport, error) {
connPool := new(clientConnPool)
t2 := &Transport{
ConnPool: noDialClientConnPool{connPool},
t1: t1,
}
connPool.t = t2
if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
return nil, err
}
if t1.TLSClientConfig == nil {
t1.TLSClientConfig = new(tls.Config)
}
if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
}
if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
}
upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
addr := authorityAddr("https", authority)
if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
go c.Close()
return erringRoundTripper{err}
} else if !used {
// Turns out we don't need this c.
// For example, two goroutines made requests to the same host
// at the same time, both kicking off TCP dials. (since protocol
// was unknown)
go c.Close()
}
return t2
}
if m := t1.TLSNextProto; len(m) == 0 {
t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
"h2": upgradeFn,
}
} else {
m["h2"] = upgradeFn
}
return t2, nil
}
// registerHTTPSProtocol calls Transport.RegisterProtocol but
// converting panics into errors.
func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
t.RegisterProtocol("https", rt)
return nil
}
// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
// if there's already has a cached connection to the host.
type noDialH2RoundTripper struct{ t *Transport }
func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
res, err := rt.t.RoundTrip(req)
if isNoCachedConnError(err) {
return nil, http.ErrSkipAltProtocol
}
return res, err
}

View File

@ -41,10 +41,10 @@ func (f *flow) take(n int32) {
// add adds n bytes (positive or negative) to the flow control window.
// It returns false if the sum would exceed 2^31-1.
func (f *flow) add(n int32) bool {
remain := (1<<31 - 1) - f.n
if n > remain {
return false
sum := f.n + n
if (sum > n) == (f.n > 0) {
f.n = sum
return true
}
f.n += n
return true
return false
}

View File

@ -14,8 +14,8 @@ import (
"strings"
"sync"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/lex/httplex"
)
const frameHeaderLen = 9
@ -733,32 +733,67 @@ func (f *SettingsFrame) IsAck() bool {
return f.FrameHeader.Flags.Has(FlagSettingsAck)
}
func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) {
func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {
f.checkValid()
buf := f.p
for len(buf) > 0 {
settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
if settingID == s {
return binary.BigEndian.Uint32(buf[2:6]), true
for i := 0; i < f.NumSettings(); i++ {
if s := f.Setting(i); s.ID == id {
return s.Val, true
}
buf = buf[6:]
}
return 0, false
}
// Setting returns the setting from the frame at the given 0-based index.
// The index must be >= 0 and less than f.NumSettings().
func (f *SettingsFrame) Setting(i int) Setting {
buf := f.p
return Setting{
ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
}
}
func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }
// HasDuplicates reports whether f contains any duplicate setting IDs.
func (f *SettingsFrame) HasDuplicates() bool {
num := f.NumSettings()
if num == 0 {
return false
}
// If it's small enough (the common case), just do the n^2
// thing and avoid a map allocation.
if num < 10 {
for i := 0; i < num; i++ {
idi := f.Setting(i).ID
for j := i + 1; j < num; j++ {
idj := f.Setting(j).ID
if idi == idj {
return true
}
}
}
return false
}
seen := map[SettingID]bool{}
for i := 0; i < num; i++ {
id := f.Setting(i).ID
if seen[id] {
return true
}
seen[id] = true
}
return false
}
// ForeachSetting runs fn for each setting.
// It stops and returns the first error.
func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
f.checkValid()
buf := f.p
for len(buf) > 0 {
if err := fn(Setting{
SettingID(binary.BigEndian.Uint16(buf[:2])),
binary.BigEndian.Uint32(buf[2:6]),
}); err != nil {
for i := 0; i < f.NumSettings(); i++ {
if err := fn(f.Setting(i)); err != nil {
return err
}
buf = buf[6:]
}
return nil
}
@ -1442,7 +1477,7 @@ func (fr *Framer) maxHeaderStringLen() int {
}
// readMetaFrame returns 0 or more CONTINUATION frames from fr and
// merge them into into the provided hf and returns a MetaHeadersFrame
// merge them into the provided hf and returns a MetaHeadersFrame
// with the decoded hpack values.
func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
if fr.AllowIllegalReads {
@ -1462,7 +1497,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
if VerboseLogs && fr.logReads {
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
}
if !httplex.ValidHeaderFieldValue(hf.Value) {
if !httpguts.ValidHeaderFieldValue(hf.Value) {
invalid = headerFieldValueError(hf.Value)
}
isPseudo := strings.HasPrefix(hf.Name, ":")

29
vendor/golang.org/x/net/http2/go111.go generated vendored Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2018 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.
// +build go1.11
package http2
import (
"net/http/httptrace"
"net/textproto"
)
func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool {
return trace != nil && trace.WroteHeaderField != nil
}
func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {
if trace != nil && trace.WroteHeaderField != nil {
trace.WroteHeaderField(k, []string{v})
}
}
func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
if trace != nil {
return trace.Got1xxResponse
}
return nil
}

View File

@ -1,16 +0,0 @@
// Copyright 2016 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.
// +build go1.6
package http2
import (
"net/http"
"time"
)
func transportExpectContinueTimeout(t1 *http.Transport) time.Duration {
return t1.ExpectContinueTimeout
}

106
vendor/golang.org/x/net/http2/go17.go generated vendored
View File

@ -1,106 +0,0 @@
// Copyright 2016 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.
// +build go1.7
package http2
import (
"context"
"net"
"net/http"
"net/http/httptrace"
"time"
)
type contextContext interface {
context.Context
}
func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
ctx, cancel = context.WithCancel(context.Background())
ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
if hs := opts.baseConfig(); hs != nil {
ctx = context.WithValue(ctx, http.ServerContextKey, hs)
}
return
}
func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) {
return context.WithCancel(ctx)
}
func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
return req.WithContext(ctx)
}
type clientTrace httptrace.ClientTrace
func reqContext(r *http.Request) context.Context { return r.Context() }
func (t *Transport) idleConnTimeout() time.Duration {
if t.t1 != nil {
return t.t1.IdleConnTimeout
}
return 0
}
func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
func traceGotConn(req *http.Request, cc *ClientConn) {
trace := httptrace.ContextClientTrace(req.Context())
if trace == nil || trace.GotConn == nil {
return
}
ci := httptrace.GotConnInfo{Conn: cc.tconn}
cc.mu.Lock()
ci.Reused = cc.nextStreamID > 1
ci.WasIdle = len(cc.streams) == 0 && ci.Reused
if ci.WasIdle && !cc.lastActive.IsZero() {
ci.IdleTime = time.Now().Sub(cc.lastActive)
}
cc.mu.Unlock()
trace.GotConn(ci)
}
func traceWroteHeaders(trace *clientTrace) {
if trace != nil && trace.WroteHeaders != nil {
trace.WroteHeaders()
}
}
func traceGot100Continue(trace *clientTrace) {
if trace != nil && trace.Got100Continue != nil {
trace.Got100Continue()
}
}
func traceWait100Continue(trace *clientTrace) {
if trace != nil && trace.Wait100Continue != nil {
trace.Wait100Continue()
}
}
func traceWroteRequest(trace *clientTrace, err error) {
if trace != nil && trace.WroteRequest != nil {
trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
}
}
func traceFirstResponseByte(trace *clientTrace) {
if trace != nil && trace.GotFirstResponseByte != nil {
trace.GotFirstResponseByte()
}
}
func requestTrace(req *http.Request) *clientTrace {
trace := httptrace.ContextClientTrace(req.Context())
return (*clientTrace)(trace)
}
// Ping sends a PING frame to the server and waits for the ack.
func (cc *ClientConn) Ping(ctx context.Context) error {
return cc.ping(ctx)
}

View File

@ -1,36 +0,0 @@
// Copyright 2016 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.
// +build go1.7,!go1.8
package http2
import "crypto/tls"
// temporary copy of Go 1.7's private tls.Config.clone:
func cloneTLSConfig(c *tls.Config) *tls.Config {
return &tls.Config{
Rand: c.Rand,
Time: c.Time,
Certificates: c.Certificates,
NameToCertificate: c.NameToCertificate,
GetCertificate: c.GetCertificate,
RootCAs: c.RootCAs,
NextProtos: c.NextProtos,
ServerName: c.ServerName,
ClientAuth: c.ClientAuth,
ClientCAs: c.ClientCAs,
InsecureSkipVerify: c.InsecureSkipVerify,
CipherSuites: c.CipherSuites,
PreferServerCipherSuites: c.PreferServerCipherSuites,
SessionTicketsDisabled: c.SessionTicketsDisabled,
SessionTicketKey: c.SessionTicketKey,
ClientSessionCache: c.ClientSessionCache,
MinVersion: c.MinVersion,
MaxVersion: c.MaxVersion,
CurvePreferences: c.CurvePreferences,
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
Renegotiation: c.Renegotiation,
}
}

View File

@ -1,56 +0,0 @@
// Copyright 2015 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.
// +build go1.8
package http2
import (
"crypto/tls"
"io"
"net/http"
)
func cloneTLSConfig(c *tls.Config) *tls.Config {
c2 := c.Clone()
c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264
return c2
}
var _ http.Pusher = (*responseWriter)(nil)
// Push implements http.Pusher.
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
internalOpts := pushOptions{}
if opts != nil {
internalOpts.Method = opts.Method
internalOpts.Header = opts.Header
}
return w.push(target, internalOpts)
}
func configureServer18(h1 *http.Server, h2 *Server) error {
if h2.IdleTimeout == 0 {
if h1.IdleTimeout != 0 {
h2.IdleTimeout = h1.IdleTimeout
} else {
h2.IdleTimeout = h1.ReadTimeout
}
}
return nil
}
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil && panicValue != http.ErrAbortHandler
}
func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
return req.GetBody
}
func reqBodyIsNoBody(body io.ReadCloser) bool {
return body == http.NoBody
}
func go18httpNoBody() io.ReadCloser { return http.NoBody } // for tests only

View File

@ -1,16 +0,0 @@
// Copyright 2015 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.
// +build go1.9
package http2
import (
"net/http"
)
func configureServer19(s *http.Server, conf *Server) error {
s.RegisterOnShutdown(conf.state.startGracefulShutdown)
return nil
}

View File

@ -7,15 +7,21 @@ package http2
import (
"net/http"
"strings"
"sync"
)
var (
commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
commonBuildOnce sync.Once
commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case
commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case
)
func init() {
for _, v := range []string{
func buildCommonHeaderMapsOnce() {
commonBuildOnce.Do(buildCommonHeaderMaps)
}
func buildCommonHeaderMaps() {
common := []string{
"accept",
"accept-charset",
"accept-encoding",
@ -63,7 +69,10 @@ func init() {
"vary",
"via",
"www-authenticate",
} {
}
commonLowerHeader = make(map[string]string, len(common))
commonCanonHeader = make(map[string]string, len(common))
for _, v := range common {
chk := http.CanonicalHeaderKey(v)
commonLowerHeader[chk] = v
commonCanonHeader[v] = chk
@ -71,6 +80,7 @@ func init() {
}
func lowerHeader(v string) string {
buildCommonHeaderMapsOnce()
if s, ok := commonLowerHeader[v]; ok {
return s
}

View File

@ -206,7 +206,7 @@ func appendVarInt(dst []byte, n byte, i uint64) []byte {
}
// appendHpackString appends s, as encoded in "String Literal"
// representation, to dst and returns the the extended buffer.
// representation, to dst and returns the extended buffer.
//
// s will be encoded in Huffman codes only when it produces strictly
// shorter byte string.

View File

@ -92,6 +92,8 @@ type Decoder struct {
// saveBuf is previous data passed to Write which we weren't able
// to fully parse before. Unlike buf, we own this data.
saveBuf bytes.Buffer
firstField bool // processing the first field of the header block
}
// NewDecoder returns a new decoder with the provided maximum dynamic
@ -101,6 +103,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod
d := &Decoder{
emit: emitFunc,
emitEnabled: true,
firstField: true,
}
d.dynTab.table.init()
d.dynTab.allowedMaxSize = maxDynamicTableSize
@ -226,11 +229,15 @@ func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
return hf, nil
}
// Close declares that the decoding is complete and resets the Decoder
// to be reused again for a new header block. If there is any remaining
// data in the decoder's buffer, Close returns an error.
func (d *Decoder) Close() error {
if d.saveBuf.Len() > 0 {
d.saveBuf.Reset()
return DecodingError{errors.New("truncated headers")}
}
d.firstField = true
return nil
}
@ -266,6 +273,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) {
d.saveBuf.Write(d.buf)
return len(p), nil
}
d.firstField = false
if err != nil {
break
}
@ -389,6 +397,12 @@ func (d *Decoder) callEmit(hf HeaderField) error {
// (same invariants and behavior as parseHeaderFieldRepr)
func (d *Decoder) parseDynamicTableSizeUpdate() error {
// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
// beginning of the first header block following the change to the dynamic table size.
if !d.firstField && d.dynTab.size > 0 {
return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
}
buf := d.buf
size, buf, err := readVarInt(5, buf)
if err != nil {

View File

@ -47,6 +47,7 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
// If maxLen is greater than 0, attempts to write more to buf than
// maxLen bytes will return ErrStringLength.
func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
rootHuffmanNode := getRootHuffmanNode()
n := rootHuffmanNode
// cur is the bit buffer that has not been fed into n.
// cbits is the number of low order bits in cur that are valid.
@ -106,7 +107,7 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
type node struct {
// children is non-nil for internal nodes
children []*node
children *[256]*node
// The following are only valid if children is nil:
codeLen uint8 // number of bits that led to the output of sym
@ -114,22 +115,31 @@ type node struct {
}
func newInternalNode() *node {
return &node{children: make([]*node, 256)}
return &node{children: new([256]*node)}
}
var rootHuffmanNode = newInternalNode()
var (
buildRootOnce sync.Once
lazyRootHuffmanNode *node
)
func init() {
func getRootHuffmanNode() *node {
buildRootOnce.Do(buildRootHuffmanNode)
return lazyRootHuffmanNode
}
func buildRootHuffmanNode() {
if len(huffmanCodes) != 256 {
panic("unexpected size")
}
lazyRootHuffmanNode = newInternalNode()
for i, code := range huffmanCodes {
addDecoderNode(byte(i), code, huffmanCodeLen[i])
}
}
func addDecoderNode(sym byte, code uint32, codeLen uint8) {
cur := rootHuffmanNode
cur := lazyRootHuffmanNode
for codeLen > 8 {
codeLen -= 8
i := uint8(code >> codeLen)

View File

@ -29,7 +29,7 @@ import (
"strings"
"sync"
"golang.org/x/net/lex/httplex"
"golang.org/x/net/http/httpguts"
)
var (
@ -179,7 +179,7 @@ var (
)
// validWireHeaderFieldName reports whether v is a valid header field
// name (key). See httplex.ValidHeaderName for the base rules.
// name (key). See httpguts.ValidHeaderName for the base rules.
//
// Further, http2 says:
// "Just as in HTTP/1.x, header field names are strings of ASCII
@ -191,7 +191,7 @@ func validWireHeaderFieldName(v string) bool {
return false
}
for _, r := range v {
if !httplex.IsTokenRune(r) {
if !httpguts.IsTokenRune(r) {
return false
}
if 'A' <= r && r <= 'Z' {
@ -201,19 +201,12 @@ func validWireHeaderFieldName(v string) bool {
return true
}
var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
func init() {
for i := 100; i <= 999; i++ {
if v := http.StatusText(i); v != "" {
httpCodeStringCommon[i] = strconv.Itoa(i)
}
}
}
func httpCodeString(code int) string {
if s, ok := httpCodeStringCommon[code]; ok {
return s
switch code {
case 200:
return "200"
case 404:
return "404"
}
return strconv.Itoa(code)
}
@ -312,7 +305,7 @@ func mustUint31(v int32) uint32 {
}
// bodyAllowedForStatus reports whether a given response status code
// permits a body. See RFC 2616, section 4.4.
// permits a body. See RFC 7230, section 3.3.
func bodyAllowedForStatus(status int) bool {
switch {
case status >= 100 && status <= 199:

20
vendor/golang.org/x/net/http2/not_go111.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// Copyright 2018 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.
// +build !go1.11
package http2
import (
"net/http/httptrace"
"net/textproto"
)
func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { return false }
func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {}
func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
return nil
}

View File

@ -1,21 +0,0 @@
// Copyright 2015 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.
// +build !go1.6
package http2
import (
"net/http"
"time"
)
func configureTransport(t1 *http.Transport) (*Transport, error) {
return nil, errTransportVersion
}
func transportExpectContinueTimeout(t1 *http.Transport) time.Duration {
return 0
}

View File

@ -1,87 +0,0 @@
// Copyright 2016 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.
// +build !go1.7
package http2
import (
"crypto/tls"
"net"
"net/http"
"time"
)
type contextContext interface {
Done() <-chan struct{}
Err() error
}
type fakeContext struct{}
func (fakeContext) Done() <-chan struct{} { return nil }
func (fakeContext) Err() error { panic("should not be called") }
func reqContext(r *http.Request) fakeContext {
return fakeContext{}
}
func setResponseUncompressed(res *http.Response) {
// Nothing.
}
type clientTrace struct{}
func requestTrace(*http.Request) *clientTrace { return nil }
func traceGotConn(*http.Request, *ClientConn) {}
func traceFirstResponseByte(*clientTrace) {}
func traceWroteHeaders(*clientTrace) {}
func traceWroteRequest(*clientTrace, error) {}
func traceGot100Continue(trace *clientTrace) {}
func traceWait100Continue(trace *clientTrace) {}
func nop() {}
func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
return nil, nop
}
func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) {
return ctx, nop
}
func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
return req
}
// temporary copy of Go 1.6's private tls.Config.clone:
func cloneTLSConfig(c *tls.Config) *tls.Config {
return &tls.Config{
Rand: c.Rand,
Time: c.Time,
Certificates: c.Certificates,
NameToCertificate: c.NameToCertificate,
GetCertificate: c.GetCertificate,
RootCAs: c.RootCAs,
NextProtos: c.NextProtos,
ServerName: c.ServerName,
ClientAuth: c.ClientAuth,
ClientCAs: c.ClientCAs,
InsecureSkipVerify: c.InsecureSkipVerify,
CipherSuites: c.CipherSuites,
PreferServerCipherSuites: c.PreferServerCipherSuites,
SessionTicketsDisabled: c.SessionTicketsDisabled,
SessionTicketKey: c.SessionTicketKey,
ClientSessionCache: c.ClientSessionCache,
MinVersion: c.MinVersion,
MaxVersion: c.MaxVersion,
CurvePreferences: c.CurvePreferences,
}
}
func (cc *ClientConn) Ping(ctx contextContext) error {
return cc.ping(ctx)
}
func (t *Transport) idleConnTimeout() time.Duration { return 0 }

View File

@ -1,29 +0,0 @@
// Copyright 2016 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.
// +build !go1.8
package http2
import (
"io"
"net/http"
)
func configureServer18(h1 *http.Server, h2 *Server) error {
// No IdleTimeout to sync prior to Go 1.8.
return nil
}
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil
}
func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
return nil
}
func reqBodyIsNoBody(io.ReadCloser) bool { return false }
func go18httpNoBody() io.ReadCloser { return nil } // for tests only

View File

@ -28,6 +28,7 @@ package http2
import (
"bufio"
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
@ -46,6 +47,7 @@ import (
"sync"
"time"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/http2/hpack"
)
@ -208,12 +210,14 @@ func ConfigureServer(s *http.Server, conf *Server) error {
conf = new(Server)
}
conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
if err := configureServer18(s, conf); err != nil {
return err
}
if err := configureServer19(s, conf); err != nil {
return err
if h1, h2 := s, conf; h2.IdleTimeout == 0 {
if h1.IdleTimeout != 0 {
h2.IdleTimeout = h1.IdleTimeout
} else {
h2.IdleTimeout = h1.ReadTimeout
}
}
s.RegisterOnShutdown(conf.state.startGracefulShutdown)
if s.TLSConfig == nil {
s.TLSConfig = new(tls.Config)
@ -406,7 +410,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
// addresses during development.
//
// TODO: optionally enforce? Or enforce at the time we receive
// a new request, and verify the the ServerName matches the :authority?
// a new request, and verify the ServerName matches the :authority?
// But that precludes proxy situations, perhaps.
//
// So for now, do nothing here again.
@ -434,6 +438,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
sc.serve()
}
func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {
ctx, cancel = context.WithCancel(context.Background())
ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
if hs := opts.baseConfig(); hs != nil {
ctx = context.WithValue(ctx, http.ServerContextKey, hs)
}
return
}
func (sc *serverConn) rejectConn(err ErrCode, debug string) {
sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
// ignoring errors. hanging up anyway.
@ -449,7 +462,7 @@ type serverConn struct {
conn net.Conn
bw *bufferedWriter // writing to conn
handler http.Handler
baseCtx contextContext
baseCtx context.Context
framer *Framer
doneServing chan struct{} // closed when serverConn.serve ends
readFrameCh chan readFrameResult // written by serverConn.readFrames
@ -529,7 +542,7 @@ type stream struct {
id uint32
body *pipe // non-nil if expecting DATA frames
cw closeWaiter // closed wait stream transitions to closed state
ctx contextContext
ctx context.Context
cancelCtx func()
// owned by serverConn's serve loop:
@ -662,6 +675,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
func (sc *serverConn) canonicalHeader(v string) string {
sc.serveG.check()
buildCommonHeaderMapsOnce()
cv, ok := commonCanonHeader[v]
if ok {
return cv
@ -1108,7 +1122,7 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
// errHandlerPanicked is the error given to any callers blocked in a read from
// Request.Body when the main goroutine panics. Since most handlers read in the
// the main ServeHTTP goroutine, this will show up rarely.
// main ServeHTTP goroutine, this will show up rarely.
var errHandlerPanicked = errors.New("http2: handler panicked")
// wroteFrame is called on the serve goroutine with the result of
@ -1486,6 +1500,12 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
}
return nil
}
if f.NumSettings() > 100 || f.HasDuplicates() {
// This isn't actually in the spec, but hang up on
// suspiciously large settings frames or those with
// duplicate entries.
return ConnectionError(ErrCodeProtocol)
}
if err := f.ForeachSetting(sc.processSetting); err != nil {
return err
}
@ -1607,7 +1627,10 @@ func (sc *serverConn) processData(f *DataFrame) error {
// Sender sending more than they'd declared?
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
return streamError(id, ErrCodeStreamClosed)
// 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
// DATA frame payload lengths that form the body.
return streamError(id, ErrCodeProtocol)
}
if f.Length > 0 {
// Check whether the client has flow control quota.
@ -1717,6 +1740,13 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
// processing this frame.
return nil
}
// RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
// WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
// this state, it MUST respond with a stream error (Section 5.4.2) of
// type STREAM_CLOSED.
if st.state == stateHalfClosedRemote {
return streamError(id, ErrCodeStreamClosed)
}
return st.processTrailerHeaders(f)
}
@ -1817,7 +1847,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
if st.trailer != nil {
for _, hf := range f.RegularFields() {
key := sc.canonicalHeader(hf.Name)
if !ValidTrailerHeader(key) {
if !httpguts.ValidTrailerHeader(key) {
// TODO: send more details to the peer somehow. But http2 has
// no way to send debug data at a stream level. Discuss with
// HTTP folk.
@ -1858,7 +1888,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
panic("internal error: cannot create stream with id 0")
}
ctx, cancelCtx := contextWithCancel(sc.baseCtx)
ctx, cancelCtx := context.WithCancel(sc.baseCtx)
st := &stream{
sc: sc,
id: id,
@ -2024,7 +2054,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
Body: body,
Trailer: trailer,
}
req = requestWithContext(req, st.ctx)
req = req.WithContext(st.ctx)
rws := responseWriterStatePool.Get().(*responseWriterState)
bwSave := rws.bw
@ -2052,7 +2082,7 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler
stream: rw.rws.stream,
})
// Same as net/http:
if shouldLogPanic(e) {
if e != nil && e != http.ErrAbortHandler {
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
@ -2284,8 +2314,8 @@ func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) !=
// written in the trailers at the end of the response.
func (rws *responseWriterState) declareTrailer(k string) {
k = http.CanonicalHeaderKey(k)
if !ValidTrailerHeader(k) {
// Forbidden by RFC 2616 14.40.
if !httpguts.ValidTrailerHeader(k) {
// Forbidden by RFC 7230, section 4.1.2.
rws.conn.logf("ignoring invalid trailer %q", k)
return
}
@ -2335,6 +2365,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
foreachHeaderElement(v, rws.declareTrailer)
}
// "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
// but respect "Connection" == "close" to mean sending a GOAWAY and tearing
// down the TCP connection when idle, like we do for HTTP/1.
// TODO: remove more Connection-specific header fields here, in addition
// to "Connection".
if _, ok := rws.snapHeader["Connection"]; ok {
v := rws.snapHeader.Get("Connection")
delete(rws.snapHeader, "Connection")
if v == "close" {
rws.conn.startGracefulShutdown()
}
}
endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
streamID: rws.stream.id,
@ -2406,7 +2449,7 @@ const TrailerPrefix = "Trailer:"
// after the header has already been flushed. Because the Go
// ResponseWriter interface has no way to set Trailers (only the
// Header), and because we didn't want to expand the ResponseWriter
// interface, and because nobody used trailers, and because RFC 2616
// interface, and because nobody used trailers, and because RFC 7230
// says you SHOULD (but not must) predeclare any trailers in the
// header, the official ResponseWriter rules said trailers in Go must
// be predeclared, and then we reuse the same ResponseWriter.Header()
@ -2601,14 +2644,9 @@ var (
ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
)
// pushOptions is the internal version of http.PushOptions, which we
// cannot include here because it's only defined in Go 1.8 and later.
type pushOptions struct {
Method string
Header http.Header
}
var _ http.Pusher = (*responseWriter)(nil)
func (w *responseWriter) push(target string, opts pushOptions) error {
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
st := w.rws.stream
sc := st.sc
sc.serveG.checkNotOn()
@ -2619,6 +2657,10 @@ func (w *responseWriter) push(target string, opts pushOptions) error {
return ErrRecursivePush
}
if opts == nil {
opts = new(http.PushOptions)
}
// Default options.
if opts.Method == "" {
opts.Method = "GET"
@ -2790,7 +2832,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
}
// foreachHeaderElement splits v according to the "#rule" construction
// in RFC 2616 section 2.1 and calls fn for each non-empty element.
// in RFC 7230 section 7 and calls fn for each non-empty element.
func foreachHeaderElement(v string, fn func(string)) {
v = textproto.TrimString(v)
if v == "" {
@ -2838,41 +2880,6 @@ func new400Handler(err error) http.HandlerFunc {
}
}
// ValidTrailerHeader reports whether name is a valid header field name to appear
// in trailers.
// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
func ValidTrailerHeader(name string) bool {
name = http.CanonicalHeaderKey(name)
if strings.HasPrefix(name, "If-") || badTrailer[name] {
return false
}
return true
}
var badTrailer = map[string]bool{
"Authorization": true,
"Cache-Control": true,
"Connection": true,
"Content-Encoding": true,
"Content-Length": true,
"Content-Range": true,
"Content-Type": true,
"Expect": true,
"Host": true,
"Keep-Alive": true,
"Max-Forwards": true,
"Pragma": true,
"Proxy-Authenticate": true,
"Proxy-Authorization": true,
"Proxy-Connection": true,
"Range": true,
"Realm": true,
"Te": true,
"Trailer": true,
"Transfer-Encoding": true,
"Www-Authenticate": true,
}
// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
// disabled. See comments on h1ServerShutdownChan above for why
// the code is written this way.

View File

@ -10,6 +10,7 @@ import (
"bufio"
"bytes"
"compress/gzip"
"context"
"crypto/rand"
"crypto/tls"
"errors"
@ -21,15 +22,17 @@ import (
mathrand "math/rand"
"net"
"net/http"
"net/http/httptrace"
"net/textproto"
"sort"
"strconv"
"strings"
"sync"
"time"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/idna"
"golang.org/x/net/lex/httplex"
)
const (
@ -94,6 +97,16 @@ type Transport struct {
// to mean no limit.
MaxHeaderListSize uint32
// StrictMaxConcurrentStreams controls whether the server's
// SETTINGS_MAX_CONCURRENT_STREAMS should be respected
// globally. If false, new TCP connections are created to the
// server as needed to keep each under the per-connection
// SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the
// server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as
// a global limit and callers of RoundTrip block when needed,
// waiting for their turn.
StrictMaxConcurrentStreams bool
// t1, if non-nil, is the standard library Transport using
// this transport. Its settings are used (but not its
// RoundTrip method, etc).
@ -117,16 +130,56 @@ func (t *Transport) disableCompression() bool {
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
}
var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
// It requires Go 1.6 or later and returns an error if the net/http package is too old
// or if t1 has already been HTTP/2-enabled.
// It returns an error if t1 has already been HTTP/2-enabled.
func ConfigureTransport(t1 *http.Transport) error {
_, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
_, err := configureTransport(t1)
return err
}
func configureTransport(t1 *http.Transport) (*Transport, error) {
connPool := new(clientConnPool)
t2 := &Transport{
ConnPool: noDialClientConnPool{connPool},
t1: t1,
}
connPool.t = t2
if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
return nil, err
}
if t1.TLSClientConfig == nil {
t1.TLSClientConfig = new(tls.Config)
}
if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
}
if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
}
upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
addr := authorityAddr("https", authority)
if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
go c.Close()
return erringRoundTripper{err}
} else if !used {
// Turns out we don't need this c.
// For example, two goroutines made requests to the same host
// at the same time, both kicking off TCP dials. (since protocol
// was unknown)
go c.Close()
}
return t2
}
if m := t1.TLSNextProto; len(m) == 0 {
t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
"h2": upgradeFn,
}
} else {
m["h2"] = upgradeFn
}
return t2, nil
}
func (t *Transport) connPool() ClientConnPool {
t.connPoolOnce.Do(t.initConnPool)
return t.connPoolOrDef
@ -159,6 +212,7 @@ type ClientConn struct {
cond *sync.Cond // hold mu; broadcast on flow/closed changes
flow flow // our conn-level flow control quota (cs.flow is per stream)
inflow flow // peer's conn-level flow control
closing bool
closed bool
wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received
@ -190,7 +244,7 @@ type ClientConn struct {
type clientStream struct {
cc *ClientConn
req *http.Request
trace *clientTrace // or nil
trace *httptrace.ClientTrace // or nil
ID uint32
resc chan resAndError
bufPipe pipe // buffered pipe with the flow-controlled response payload
@ -211,9 +265,10 @@ type clientStream struct {
done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
// owned by clientConnReadLoop:
firstByte bool // got the first response byte
pastHeaders bool // got first MetaHeadersFrame (actual headers)
pastTrailers bool // got optional second MetaHeadersFrame (trailers)
firstByte bool // got the first response byte
pastHeaders bool // got first MetaHeadersFrame (actual headers)
pastTrailers bool // got optional second MetaHeadersFrame (trailers)
num1xx uint8 // number of 1xx responses seen
trailer http.Header // accumulated trailers
resTrailer *http.Header // client's Response.Trailer
@ -223,7 +278,7 @@ type clientStream struct {
// channel to be signaled. A non-nil error is returned only if the request was
// canceled.
func awaitRequestCancel(req *http.Request, done <-chan struct{}) error {
ctx := reqContext(req)
ctx := req.Context()
if req.Cancel == nil && ctx.Done() == nil {
return nil
}
@ -237,6 +292,17 @@ func awaitRequestCancel(req *http.Request, done <-chan struct{}) error {
}
}
var got1xxFuncForTests func(int, textproto.MIMEHeader) error
// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func,
// if any. It returns nil if not set or if the Go version is too old.
func (cs *clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error {
if fn := got1xxFuncForTests; fn != nil {
return fn
}
return traceGot1xxResponseFunc(cs.trace)
}
// awaitRequestCancel waits for the user to cancel a request, its context to
// expire, or for the request to be done (any way it might be removed from the
// cc.streams map: peer reset, successful completion, TCP connection breakage,
@ -387,8 +453,8 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
select {
case <-time.After(time.Second * time.Duration(backoff)):
continue
case <-reqContext(req).Done():
return nil, reqContext(req).Err()
case <-req.Context().Done():
return nil, req.Context().Err()
}
}
}
@ -423,27 +489,35 @@ func shouldRetryRequest(req *http.Request, err error, afterBodyWrite bool) (*htt
if !canRetryError(err) {
return nil, err
}
// If the Body is nil (or http.NoBody), it's safe to reuse
// this request and its Body.
if req.Body == nil || req.Body == http.NoBody {
return req, nil
}
// If the request body can be reset back to its original
// state via the optional req.GetBody, do that.
if req.GetBody != nil {
// TODO: consider a req.Body.Close here? or audit that all caller paths do?
body, err := req.GetBody()
if err != nil {
return nil, err
}
newReq := *req
newReq.Body = body
return &newReq, nil
}
// The Request.Body can't reset back to the beginning, but we
// don't seem to have started to read from it yet, so reuse
// the request directly. The "afterBodyWrite" means the
// bodyWrite process has started, which becomes true before
// the first Read.
if !afterBodyWrite {
return req, nil
}
// If the Body is nil (or http.NoBody), it's safe to reuse
// this request and its Body.
if req.Body == nil || reqBodyIsNoBody(req.Body) {
return req, nil
}
// Otherwise we depend on the Request having its GetBody
// func defined.
getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody
if getBody == nil {
return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
}
body, err := getBody()
if err != nil {
return nil, err
}
newReq := *req
newReq.Body = body
return &newReq, nil
return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
}
func canRetryError(err error) bool {
@ -471,7 +545,7 @@ func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, er
func (t *Transport) newTLSConfig(host string) *tls.Config {
cfg := new(tls.Config)
if t.TLSClientConfig != nil {
*cfg = *cloneTLSConfig(t.TLSClientConfig)
*cfg = *t.TLSClientConfig.Clone()
}
if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
@ -522,7 +596,7 @@ func (t *Transport) expectContinueTimeout() time.Duration {
if t.t1 == nil {
return 0
}
return transportExpectContinueTimeout(t.t1)
return t.t1.ExpectContinueTimeout
}
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
@ -567,6 +641,10 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
// henc in response to SETTINGS frames?
cc.henc = hpack.NewEncoder(&cc.hbuf)
if t.AllowHTTP {
cc.nextStreamID = 3
}
if cs, ok := c.(connectionStater); ok {
state := cs.ConnectionState()
cc.tlsState = &state
@ -626,12 +704,43 @@ func (cc *ClientConn) CanTakeNewRequest() bool {
return cc.canTakeNewRequestLocked()
}
func (cc *ClientConn) canTakeNewRequestLocked() bool {
// clientConnIdleState describes the suitability of a client
// connection to initiate a new RoundTrip request.
type clientConnIdleState struct {
canTakeNewRequest bool
freshConn bool // whether it's unused by any previous request
}
func (cc *ClientConn) idleState() clientConnIdleState {
cc.mu.Lock()
defer cc.mu.Unlock()
return cc.idleStateLocked()
}
func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
if cc.singleUse && cc.nextStreamID > 1 {
return false
return
}
return cc.goAway == nil && !cc.closed &&
int64(cc.nextStreamID)+int64(cc.pendingRequests) < math.MaxInt32
var maxConcurrentOkay bool
if cc.t.StrictMaxConcurrentStreams {
// We'll tell the caller we can take a new request to
// prevent the caller from dialing a new TCP
// connection, but then we'll block later before
// writing it.
maxConcurrentOkay = true
} else {
maxConcurrentOkay = int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams)
}
st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32
st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest
return
}
func (cc *ClientConn) canTakeNewRequestLocked() bool {
st := cc.idleStateLocked()
return st.canTakeNewRequest
}
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
@ -661,6 +770,87 @@ func (cc *ClientConn) closeIfIdle() {
cc.tconn.Close()
}
var shutdownEnterWaitStateHook = func() {}
// Shutdown gracefully close the client connection, waiting for running streams to complete.
func (cc *ClientConn) Shutdown(ctx context.Context) error {
if err := cc.sendGoAway(); err != nil {
return err
}
// Wait for all in-flight streams to complete or connection to close
done := make(chan error, 1)
cancelled := false // guarded by cc.mu
go func() {
cc.mu.Lock()
defer cc.mu.Unlock()
for {
if len(cc.streams) == 0 || cc.closed {
cc.closed = true
done <- cc.tconn.Close()
break
}
if cancelled {
break
}
cc.cond.Wait()
}
}()
shutdownEnterWaitStateHook()
select {
case err := <-done:
return err
case <-ctx.Done():
cc.mu.Lock()
// Free the goroutine above
cancelled = true
cc.cond.Broadcast()
cc.mu.Unlock()
return ctx.Err()
}
}
func (cc *ClientConn) sendGoAway() error {
cc.mu.Lock()
defer cc.mu.Unlock()
cc.wmu.Lock()
defer cc.wmu.Unlock()
if cc.closing {
// GOAWAY sent already
return nil
}
// Send a graceful shutdown frame to server
maxStreamID := cc.nextStreamID
if err := cc.fr.WriteGoAway(maxStreamID, ErrCodeNo, nil); err != nil {
return err
}
if err := cc.bw.Flush(); err != nil {
return err
}
// Prevent new requests
cc.closing = true
return nil
}
// Close closes the client connection immediately.
//
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
func (cc *ClientConn) Close() error {
cc.mu.Lock()
defer cc.cond.Broadcast()
defer cc.mu.Unlock()
err := errors.New("http2: client connection force closed via ClientConn.Close")
for id, cs := range cc.streams {
select {
case cs.resc <- resAndError{err: err}:
default:
}
cs.bufPipe.CloseWithError(err)
delete(cc.streams, id)
}
cc.closed = true
return cc.tconn.Close()
}
const maxAllocFrameSize = 512 << 10
// frameBuffer returns a scratch buffer suitable for writing DATA frames.
@ -743,7 +933,7 @@ func checkConnHeaders(req *http.Request) error {
if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
}
if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") {
if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !strings.EqualFold(vv[0], "close") && !strings.EqualFold(vv[0], "keep-alive")) {
return fmt.Errorf("http2: invalid Connection request header: %q", vv)
}
return nil
@ -753,7 +943,7 @@ func checkConnHeaders(req *http.Request) error {
// req.ContentLength, where 0 actually means zero (not unknown) and -1
// means unknown.
func actualContentLength(req *http.Request) int64 {
if req.Body == nil || reqBodyIsNoBody(req.Body) {
if req.Body == nil || req.Body == http.NoBody {
return 0
}
if req.ContentLength != 0 {
@ -823,7 +1013,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf
cs := cc.newStream()
cs.req = req
cs.trace = requestTrace(req)
cs.trace = httptrace.ContextClientTrace(req.Context())
cs.requestedGzip = requestedGzip
bodyWriter := cc.t.getBodyWriterState(cs, body)
cs.on100 = bodyWriter.on100
@ -861,7 +1051,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf
readLoopResCh := cs.resc
bodyWritten := false
ctx := reqContext(req)
ctx := req.Context()
handleReadLoopResponse := func(re resAndError) (*http.Response, bool, error) {
res := re.res
@ -931,6 +1121,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf
default:
}
if err != nil {
cc.forgetStreamID(cs.ID)
return nil, cs.getStartedWrite(), err
}
bodyWritten = true
@ -951,6 +1142,9 @@ func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error {
for {
cc.lastActive = time.Now()
if cc.closed || !cc.canTakeNewRequestLocked() {
if waitingForConn != nil {
close(waitingForConn)
}
return errClientConnUnusable
}
if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
@ -1049,6 +1243,7 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (
sawEOF = true
err = nil
} else if err != nil {
cc.writeStreamReset(cs.ID, ErrCodeCancel, err)
return err
}
@ -1174,7 +1369,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
if host == "" {
host = req.URL.Host
}
host, err := httplex.PunycodeHostPort(host)
host, err := httpguts.PunycodeHostPort(host)
if err != nil {
return nil, err
}
@ -1199,11 +1394,11 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
// potentially pollute our hpack state. (We want to be able to
// continue to reuse the hpack encoder for future requests)
for k, vv := range req.Header {
if !httplex.ValidHeaderFieldName(k) {
if !httpguts.ValidHeaderFieldName(k) {
return nil, fmt.Errorf("invalid HTTP header name %q", k)
}
for _, v := range vv {
if !httplex.ValidHeaderFieldValue(v) {
if !httpguts.ValidHeaderFieldValue(v) {
return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k)
}
}
@ -1284,9 +1479,16 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
return nil, errRequestHeaderListSize
}
trace := httptrace.ContextClientTrace(req.Context())
traceHeaders := traceHasWroteHeaderField(trace)
// Header list size is ok. Write the headers.
enumerateHeaders(func(name, value string) {
cc.writeHeader(strings.ToLower(name), value)
name = strings.ToLower(name)
cc.writeHeader(name, value)
if traceHeaders {
traceWroteHeaderField(trace, name, value)
}
})
return cc.hbuf.Bytes(), nil
@ -1608,8 +1810,7 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {
// is the detail.
//
// As a special case, handleResponse may return (nil, nil) to skip the
// frame (currently only used for 100 expect continue). This special
// case is going away after Issue 13851 is fixed.
// frame (currently only used for 1xx responses).
func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
if f.Truncated {
return nil, errResponseHeaderListSize
@ -1624,15 +1825,6 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
}
if statusCode == 100 {
traceGot100Continue(cs.trace)
if cs.on100 != nil {
cs.on100() // forces any write delay timer to fire
}
cs.pastHeaders = false // do it all again
return nil, nil
}
header := make(http.Header)
res := &http.Response{
Proto: "HTTP/2.0",
@ -1657,6 +1849,27 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
}
}
if statusCode >= 100 && statusCode <= 199 {
cs.num1xx++
const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http
if cs.num1xx > max1xxResponses {
return nil, errors.New("http2: too many 1xx informational responses")
}
if fn := cs.get1xxTraceFunc(); fn != nil {
if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil {
return nil, err
}
}
if statusCode == 100 {
traceGot100Continue(cs.trace)
if cs.on100 != nil {
cs.on100() // forces any write delay timer to fire
}
}
cs.pastHeaders = false // do it all again
return nil, nil
}
streamEnded := f.StreamEnded()
isHead := cs.req.Method == "HEAD"
if !streamEnded || isHead {
@ -1689,7 +1902,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
res.Header.Del("Content-Length")
res.ContentLength = -1
res.Body = &gzipReader{body: res.Body}
setResponseUncompressed(res)
res.Uncompressed = true
}
return res, nil
}
@ -2066,8 +2279,7 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
}
// Ping sends a PING frame to the server and waits for the ack.
// Public implementation is in go17.go and not_go17.go
func (cc *ClientConn) ping(ctx contextContext) error {
func (cc *ClientConn) Ping(ctx context.Context) error {
c := make(chan struct{})
// Generate a random payload
var p [8]byte
@ -2244,7 +2456,7 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body
}
s.delay = t.expectContinueTimeout()
if s.delay == 0 ||
!httplex.HeaderValuesContainsToken(
!httpguts.HeaderValuesContainsToken(
cs.req.Header["Expect"],
"100-continue") {
return
@ -2299,5 +2511,93 @@ func (s bodyWriterState) scheduleBodyWrite() {
// isConnectionCloseRequest reports whether req should use its own
// connection for a single request and then close the connection.
func isConnectionCloseRequest(req *http.Request) bool {
return req.Close || httplex.HeaderValuesContainsToken(req.Header["Connection"], "close")
return req.Close || httpguts.HeaderValuesContainsToken(req.Header["Connection"], "close")
}
// registerHTTPSProtocol calls Transport.RegisterProtocol but
// converting panics into errors.
func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
t.RegisterProtocol("https", rt)
return nil
}
// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
// if there's already has a cached connection to the host.
// (The field is exported so it can be accessed via reflect from net/http; tested
// by TestNoDialH2RoundTripperType)
type noDialH2RoundTripper struct{ *Transport }
func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
res, err := rt.Transport.RoundTrip(req)
if isNoCachedConnError(err) {
return nil, http.ErrSkipAltProtocol
}
return res, err
}
func (t *Transport) idleConnTimeout() time.Duration {
if t.t1 != nil {
return t.t1.IdleConnTimeout
}
return 0
}
func traceGetConn(req *http.Request, hostPort string) {
trace := httptrace.ContextClientTrace(req.Context())
if trace == nil || trace.GetConn == nil {
return
}
trace.GetConn(hostPort)
}
func traceGotConn(req *http.Request, cc *ClientConn) {
trace := httptrace.ContextClientTrace(req.Context())
if trace == nil || trace.GotConn == nil {
return
}
ci := httptrace.GotConnInfo{Conn: cc.tconn}
cc.mu.Lock()
ci.Reused = cc.nextStreamID > 1
ci.WasIdle = len(cc.streams) == 0 && ci.Reused
if ci.WasIdle && !cc.lastActive.IsZero() {
ci.IdleTime = time.Now().Sub(cc.lastActive)
}
cc.mu.Unlock()
trace.GotConn(ci)
}
func traceWroteHeaders(trace *httptrace.ClientTrace) {
if trace != nil && trace.WroteHeaders != nil {
trace.WroteHeaders()
}
}
func traceGot100Continue(trace *httptrace.ClientTrace) {
if trace != nil && trace.Got100Continue != nil {
trace.Got100Continue()
}
}
func traceWait100Continue(trace *httptrace.ClientTrace) {
if trace != nil && trace.Wait100Continue != nil {
trace.Wait100Continue()
}
}
func traceWroteRequest(trace *httptrace.ClientTrace, err error) {
if trace != nil && trace.WroteRequest != nil {
trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
}
}
func traceFirstResponseByte(trace *httptrace.ClientTrace) {
if trace != nil && trace.GotFirstResponseByte != nil {
trace.GotFirstResponseByte()
}
}

View File

@ -11,8 +11,8 @@ import (
"net/http"
"net/url"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/lex/httplex"
)
// writeFramer is implemented by any type that is used to write frames.
@ -199,7 +199,7 @@ func (w *writeResHeaders) staysWithinBuffer(max int) bool {
// TODO: this is a common one. It'd be nice to return true
// here and get into the fast path if we could be clever and
// calculate the size fast enough, or at least a conservative
// uppper bound that usually fires. (Maybe if w.h and
// upper bound that usually fires. (Maybe if w.h and
// w.trailers are nil, so we don't need to enumerate it.)
// Otherwise I'm afraid that just calculating the length to
// answer this question would be slower than the ~2µs benefit.
@ -329,7 +329,7 @@ func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
}
// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
// is encoded only only if k is in keys.
// is encoded only if k is in keys.
func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
if keys == nil {
sorter := sorterPool.Get().(*sorter)
@ -350,7 +350,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
}
isTE := k == "transfer-encoding"
for _, v := range vv {
if !httplex.ValidHeaderFieldValue(v) {
if !httpguts.ValidHeaderFieldValue(v) {
// TODO: return an error? golang.org/issue/14048
// For now just omit it.
continue

33
vendor/golang.org/x/net/internal/nettest/BUILD generated vendored Normal file
View File

@ -0,0 +1,33 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"helper_bsd.go",
"helper_nobsd.go",
"helper_posix.go",
"helper_stub.go",
"helper_unix.go",
"helper_windows.go",
"interface.go",
"rlimit.go",
"stack.go",
],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/internal/nettest",
importpath = "golang.org/x/net/internal/nettest",
visibility = ["//vendor/golang.org/x/net:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

24
vendor/golang.org/x/net/internal/nettest/helper_bsd.go generated vendored Normal file
View File

@ -0,0 +1,24 @@
// Copyright 2016 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.
// +build darwin dragonfly freebsd netbsd openbsd
package nettest
import (
"runtime"
)
func supportsIPv6MulticastDeliveryOnLoopback() bool {
switch runtime.GOOS {
case "freebsd":
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
// Even after the fix, it looks like the latest
// kernels don't deliver link-local scoped multicast
// packets correctly.
return false
default:
return true
}
}

View File

@ -2,15 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !go1.9
// +build aix linux solaris
package http2
package nettest
import (
"net/http"
)
func configureServer19(s *http.Server, conf *Server) error {
// not supported prior to go1.9
return nil
func supportsIPv6MulticastDeliveryOnLoopback() bool {
return true
}

View File

@ -0,0 +1,31 @@
// Copyright 2014 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.
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package nettest
import (
"os"
"syscall"
)
func protocolNotSupported(err error) bool {
switch err := err.(type) {
case syscall.Errno:
switch err {
case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT:
return true
}
case *os.SyscallError:
switch err := err.Err.(type) {
case syscall.Errno:
switch err {
case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT:
return true
}
}
}
return false
}

View File

@ -0,0 +1,28 @@
// Copyright 2014 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.
// +build js nacl plan9
package nettest
import (
"fmt"
"runtime"
)
func maxOpenFiles() int {
return defaultMaxOpenFiles
}
func supportsRawIPSocket() (string, bool) {
return fmt.Sprintf("not supported on %s", runtime.GOOS), false
}
func supportsIPv6MulticastDeliveryOnLoopback() bool {
return false
}
func protocolNotSupported(err error) bool {
return false
}

View File

@ -0,0 +1,29 @@
// Copyright 2015 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.
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package nettest
import (
"fmt"
"os"
"runtime"
"syscall"
)
func maxOpenFiles() int {
var rlim syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
return defaultMaxOpenFiles
}
return int(rlim.Cur)
}
func supportsRawIPSocket() (string, bool) {
if os.Getuid() != 0 {
return fmt.Sprintf("must be root on %s", runtime.GOOS), false
}
return "", true
}

View File

@ -0,0 +1,38 @@
// Copyright 2015 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 nettest
import (
"fmt"
"runtime"
"syscall"
)
func maxOpenFiles() int {
return 4 * defaultMaxOpenFiles /* actually it's 16581375 */
}
func supportsRawIPSocket() (string, bool) {
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:
// Note: To use a socket of type SOCK_RAW requires administrative privileges.
// Users running Winsock applications that use raw sockets must be a member of
// the Administrators group on the local computer, otherwise raw socket calls
// will fail with an error code of WSAEACCES. On Windows Vista and later, access
// for raw sockets is enforced at socket creation. In earlier versions of Windows,
// access for raw sockets is enforced during other socket operations.
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0)
if err == syscall.WSAEACCES {
return fmt.Sprintf("no access to raw socket allowed on %s", runtime.GOOS), false
}
if err != nil {
return err.Error(), false
}
syscall.Closesocket(s)
return "", true
}
func supportsIPv6MulticastDeliveryOnLoopback() bool {
return true
}

94
vendor/golang.org/x/net/internal/nettest/interface.go generated vendored Normal file
View File

@ -0,0 +1,94 @@
// Copyright 2012 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 nettest
import "net"
// IsMulticastCapable reports whether ifi is an IP multicast-capable
// network interface. Network must be "ip", "ip4" or "ip6".
func IsMulticastCapable(network string, ifi *net.Interface) (net.IP, bool) {
switch network {
case "ip", "ip4", "ip6":
default:
return nil, false
}
if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
return nil, false
}
return hasRoutableIP(network, ifi)
}
// RoutedInterface returns a network interface that can route IP
// traffic and satisfies flags. It returns nil when an appropriate
// network interface is not found. Network must be "ip", "ip4" or
// "ip6".
func RoutedInterface(network string, flags net.Flags) *net.Interface {
switch network {
case "ip", "ip4", "ip6":
default:
return nil
}
ift, err := net.Interfaces()
if err != nil {
return nil
}
for _, ifi := range ift {
if ifi.Flags&flags != flags {
continue
}
if _, ok := hasRoutableIP(network, &ifi); !ok {
continue
}
return &ifi
}
return nil
}
func hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) {
ifat, err := ifi.Addrs()
if err != nil {
return nil, false
}
for _, ifa := range ifat {
switch ifa := ifa.(type) {
case *net.IPAddr:
if ip := routableIP(network, ifa.IP); ip != nil {
return ip, true
}
case *net.IPNet:
if ip := routableIP(network, ifa.IP); ip != nil {
return ip, true
}
}
}
return nil, false
}
func routableIP(network string, ip net.IP) net.IP {
if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() {
return nil
}
switch network {
case "ip4":
if ip := ip.To4(); ip != nil {
return ip
}
case "ip6":
if ip.IsLoopback() { // addressing scope of the loopback address depends on each implementation
return nil
}
if ip := ip.To16(); ip != nil && ip.To4() == nil {
return ip
}
default:
if ip := ip.To4(); ip != nil {
return ip
}
if ip := ip.To16(); ip != nil {
return ip
}
}
return nil
}

11
vendor/golang.org/x/net/internal/nettest/rlimit.go generated vendored Normal file
View File

@ -0,0 +1,11 @@
// Copyright 2015 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 nettest
const defaultMaxOpenFiles = 256
// MaxOpenFiles returns the maximum number of open files for the
// caller's process.
func MaxOpenFiles() int { return maxOpenFiles() }

152
vendor/golang.org/x/net/internal/nettest/stack.go generated vendored Normal file
View File

@ -0,0 +1,152 @@
// Copyright 2014 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 nettest provides utilities for network testing.
package nettest
import (
"fmt"
"io/ioutil"
"net"
"os"
"runtime"
)
var (
supportsIPv4 bool
supportsIPv6 bool
)
func init() {
if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
ln.Close()
supportsIPv4 = true
}
if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
ln.Close()
supportsIPv6 = true
}
}
// SupportsIPv4 reports whether the platform supports IPv4 networking
// functionality.
func SupportsIPv4() bool { return supportsIPv4 }
// SupportsIPv6 reports whether the platform supports IPv6 networking
// functionality.
func SupportsIPv6() bool { return supportsIPv6 }
// SupportsRawIPSocket reports whether the platform supports raw IP
// sockets.
func SupportsRawIPSocket() (string, bool) {
return supportsRawIPSocket()
}
// SupportsIPv6MulticastDeliveryOnLoopback reports whether the
// platform supports IPv6 multicast packet delivery on software
// loopback interface.
func SupportsIPv6MulticastDeliveryOnLoopback() bool {
return supportsIPv6MulticastDeliveryOnLoopback()
}
// ProtocolNotSupported reports whether err is a protocol not
// supported error.
func ProtocolNotSupported(err error) bool {
return protocolNotSupported(err)
}
// TestableNetwork reports whether network is testable on the current
// platform configuration.
func TestableNetwork(network string) bool {
// This is based on logic from standard library's
// net/platform_test.go.
switch network {
case "unix", "unixgram":
switch runtime.GOOS {
case "android", "js", "nacl", "plan9", "windows":
return false
}
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
return false
}
case "unixpacket":
switch runtime.GOOS {
case "aix", "android", "darwin", "freebsd", "js", "nacl", "plan9", "windows":
return false
case "netbsd":
// It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown.
if runtime.GOARCH == "386" {
return false
}
}
}
return true
}
// NewLocalListener returns a listener which listens to a loopback IP
// address or local file system path.
// Network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
func NewLocalListener(network string) (net.Listener, error) {
switch network {
case "tcp":
if supportsIPv4 {
if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
return ln, nil
}
}
if supportsIPv6 {
return net.Listen("tcp6", "[::1]:0")
}
case "tcp4":
if supportsIPv4 {
return net.Listen("tcp4", "127.0.0.1:0")
}
case "tcp6":
if supportsIPv6 {
return net.Listen("tcp6", "[::1]:0")
}
case "unix", "unixpacket":
return net.Listen(network, localPath())
}
return nil, fmt.Errorf("%s is not supported", network)
}
// NewLocalPacketListener returns a packet listener which listens to a
// loopback IP address or local file system path.
// Network must be "udp", "udp4", "udp6" or "unixgram".
func NewLocalPacketListener(network string) (net.PacketConn, error) {
switch network {
case "udp":
if supportsIPv4 {
if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
return c, nil
}
}
if supportsIPv6 {
return net.ListenPacket("udp6", "[::1]:0")
}
case "udp4":
if supportsIPv4 {
return net.ListenPacket("udp4", "127.0.0.1:0")
}
case "udp6":
if supportsIPv6 {
return net.ListenPacket("udp6", "[::1]:0")
}
case "unixgram":
return net.ListenPacket(network, localPath())
}
return nil, fmt.Errorf("%s is not supported", network)
}
func localPath() string {
f, err := ioutil.TempFile("", "nettest")
if err != nil {
panic(err)
}
path := f.Name()
f.Close()
os.Remove(path)
return path
}

26
vendor/golang.org/x/net/internal/socks/BUILD generated vendored Normal file
View File

@ -0,0 +1,26 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"client.go",
"socks.go",
],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/internal/socks",
importpath = "golang.org/x/net/internal/socks",
visibility = ["//vendor/golang.org/x/net:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

168
vendor/golang.org/x/net/internal/socks/client.go generated vendored Normal file
View File

@ -0,0 +1,168 @@
// Copyright 2018 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 socks
import (
"context"
"errors"
"io"
"net"
"strconv"
"time"
)
var (
noDeadline = time.Time{}
aLongTimeAgo = time.Unix(1, 0)
)
func (d *Dialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
host, port, err := splitHostPort(address)
if err != nil {
return nil, err
}
if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
c.SetDeadline(deadline)
defer c.SetDeadline(noDeadline)
}
if ctx != context.Background() {
errCh := make(chan error, 1)
done := make(chan struct{})
defer func() {
close(done)
if ctxErr == nil {
ctxErr = <-errCh
}
}()
go func() {
select {
case <-ctx.Done():
c.SetDeadline(aLongTimeAgo)
errCh <- ctx.Err()
case <-done:
errCh <- nil
}
}()
}
b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
b = append(b, Version5)
if len(d.AuthMethods) == 0 || d.Authenticate == nil {
b = append(b, 1, byte(AuthMethodNotRequired))
} else {
ams := d.AuthMethods
if len(ams) > 255 {
return nil, errors.New("too many authentication methods")
}
b = append(b, byte(len(ams)))
for _, am := range ams {
b = append(b, byte(am))
}
}
if _, ctxErr = c.Write(b); ctxErr != nil {
return
}
if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
return
}
if b[0] != Version5 {
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
}
am := AuthMethod(b[1])
if am == AuthMethodNoAcceptableMethods {
return nil, errors.New("no acceptable authentication methods")
}
if d.Authenticate != nil {
if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
return
}
}
b = b[:0]
b = append(b, Version5, byte(d.cmd), 0)
if ip := net.ParseIP(host); ip != nil {
if ip4 := ip.To4(); ip4 != nil {
b = append(b, AddrTypeIPv4)
b = append(b, ip4...)
} else if ip6 := ip.To16(); ip6 != nil {
b = append(b, AddrTypeIPv6)
b = append(b, ip6...)
} else {
return nil, errors.New("unknown address type")
}
} else {
if len(host) > 255 {
return nil, errors.New("FQDN too long")
}
b = append(b, AddrTypeFQDN)
b = append(b, byte(len(host)))
b = append(b, host...)
}
b = append(b, byte(port>>8), byte(port))
if _, ctxErr = c.Write(b); ctxErr != nil {
return
}
if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
return
}
if b[0] != Version5 {
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
}
if cmdErr := Reply(b[1]); cmdErr != StatusSucceeded {
return nil, errors.New("unknown error " + cmdErr.String())
}
if b[2] != 0 {
return nil, errors.New("non-zero reserved field")
}
l := 2
var a Addr
switch b[3] {
case AddrTypeIPv4:
l += net.IPv4len
a.IP = make(net.IP, net.IPv4len)
case AddrTypeIPv6:
l += net.IPv6len
a.IP = make(net.IP, net.IPv6len)
case AddrTypeFQDN:
if _, err := io.ReadFull(c, b[:1]); err != nil {
return nil, err
}
l += int(b[0])
default:
return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
}
if cap(b) < l {
b = make([]byte, l)
} else {
b = b[:l]
}
if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
return
}
if a.IP != nil {
copy(a.IP, b)
} else {
a.Name = string(b[:len(b)-2])
}
a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
return &a, nil
}
func splitHostPort(address string) (string, int, error) {
host, port, err := net.SplitHostPort(address)
if err != nil {
return "", 0, err
}
portnum, err := strconv.Atoi(port)
if err != nil {
return "", 0, err
}
if 1 > portnum || portnum > 0xffff {
return "", 0, errors.New("port number out of range " + port)
}
return host, portnum, nil
}

317
vendor/golang.org/x/net/internal/socks/socks.go generated vendored Normal file
View File

@ -0,0 +1,317 @@
// Copyright 2018 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 socks provides a SOCKS version 5 client implementation.
//
// SOCKS protocol version 5 is defined in RFC 1928.
// Username/Password authentication for SOCKS version 5 is defined in
// RFC 1929.
package socks
import (
"context"
"errors"
"io"
"net"
"strconv"
)
// A Command represents a SOCKS command.
type Command int
func (cmd Command) String() string {
switch cmd {
case CmdConnect:
return "socks connect"
case cmdBind:
return "socks bind"
default:
return "socks " + strconv.Itoa(int(cmd))
}
}
// An AuthMethod represents a SOCKS authentication method.
type AuthMethod int
// A Reply represents a SOCKS command reply code.
type Reply int
func (code Reply) String() string {
switch code {
case StatusSucceeded:
return "succeeded"
case 0x01:
return "general SOCKS server failure"
case 0x02:
return "connection not allowed by ruleset"
case 0x03:
return "network unreachable"
case 0x04:
return "host unreachable"
case 0x05:
return "connection refused"
case 0x06:
return "TTL expired"
case 0x07:
return "command not supported"
case 0x08:
return "address type not supported"
default:
return "unknown code: " + strconv.Itoa(int(code))
}
}
// Wire protocol constants.
const (
Version5 = 0x05
AddrTypeIPv4 = 0x01
AddrTypeFQDN = 0x03
AddrTypeIPv6 = 0x04
CmdConnect Command = 0x01 // establishes an active-open forward proxy connection
cmdBind Command = 0x02 // establishes a passive-open forward proxy connection
AuthMethodNotRequired AuthMethod = 0x00 // no authentication required
AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
StatusSucceeded Reply = 0x00
)
// An Addr represents a SOCKS-specific address.
// Either Name or IP is used exclusively.
type Addr struct {
Name string // fully-qualified domain name
IP net.IP
Port int
}
func (a *Addr) Network() string { return "socks" }
func (a *Addr) String() string {
if a == nil {
return "<nil>"
}
port := strconv.Itoa(a.Port)
if a.IP == nil {
return net.JoinHostPort(a.Name, port)
}
return net.JoinHostPort(a.IP.String(), port)
}
// A Conn represents a forward proxy connection.
type Conn struct {
net.Conn
boundAddr net.Addr
}
// BoundAddr returns the address assigned by the proxy server for
// connecting to the command target address from the proxy server.
func (c *Conn) BoundAddr() net.Addr {
if c == nil {
return nil
}
return c.boundAddr
}
// A Dialer holds SOCKS-specific options.
type Dialer struct {
cmd Command // either CmdConnect or cmdBind
proxyNetwork string // network between a proxy server and a client
proxyAddress string // proxy server address
// ProxyDial specifies the optional dial function for
// establishing the transport connection.
ProxyDial func(context.Context, string, string) (net.Conn, error)
// AuthMethods specifies the list of request authention
// methods.
// If empty, SOCKS client requests only AuthMethodNotRequired.
AuthMethods []AuthMethod
// Authenticate specifies the optional authentication
// function. It must be non-nil when AuthMethods is not empty.
// It must return an error when the authentication is failed.
Authenticate func(context.Context, io.ReadWriter, AuthMethod) error
}
// DialContext connects to the provided address on the provided
// network.
//
// The returned error value may be a net.OpError. When the Op field of
// net.OpError contains "socks", the Source field contains a proxy
// server address and the Addr field contains a command target
// address.
//
// See func Dial of the net package of standard library for a
// description of the network and address parameters.
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if ctx == nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
}
var err error
var c net.Conn
if d.ProxyDial != nil {
c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
} else {
var dd net.Dialer
c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
}
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
a, err := d.connect(ctx, c, address)
if err != nil {
c.Close()
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
return &Conn{Conn: c, boundAddr: a}, nil
}
// DialWithConn initiates a connection from SOCKS server to the target
// network and address using the connection c that is already
// connected to the SOCKS server.
//
// It returns the connection's local address assigned by the SOCKS
// server.
func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if ctx == nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
}
a, err := d.connect(ctx, c, address)
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
return a, nil
}
// Dial connects to the provided address on the provided network.
//
// Unlike DialContext, it returns a raw transport connection instead
// of a forward proxy connection.
//
// Deprecated: Use DialContext or DialWithConn instead.
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
var err error
var c net.Conn
if d.ProxyDial != nil {
c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
} else {
c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
}
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
c.Close()
return nil, err
}
return c, nil
}
func (d *Dialer) validateTarget(network, address string) error {
switch network {
case "tcp", "tcp6", "tcp4":
default:
return errors.New("network not implemented")
}
switch d.cmd {
case CmdConnect, cmdBind:
default:
return errors.New("command not implemented")
}
return nil
}
func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
for i, s := range []string{d.proxyAddress, address} {
host, port, err := splitHostPort(s)
if err != nil {
return nil, nil, err
}
a := &Addr{Port: port}
a.IP = net.ParseIP(host)
if a.IP == nil {
a.Name = host
}
if i == 0 {
proxy = a
} else {
dst = a
}
}
return
}
// NewDialer returns a new Dialer that dials through the provided
// proxy server's network and address.
func NewDialer(network, address string) *Dialer {
return &Dialer{proxyNetwork: network, proxyAddress: address, cmd: CmdConnect}
}
const (
authUsernamePasswordVersion = 0x01
authStatusSucceeded = 0x00
)
// UsernamePassword are the credentials for the username/password
// authentication method.
type UsernamePassword struct {
Username string
Password string
}
// Authenticate authenticates a pair of username and password with the
// proxy server.
func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error {
switch auth {
case AuthMethodNotRequired:
return nil
case AuthMethodUsernamePassword:
if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 {
return errors.New("invalid username/password")
}
b := []byte{authUsernamePasswordVersion}
b = append(b, byte(len(up.Username)))
b = append(b, up.Username...)
b = append(b, byte(len(up.Password)))
b = append(b, up.Password...)
// TODO(mikio): handle IO deadlines and cancelation if
// necessary
if _, err := rw.Write(b); err != nil {
return err
}
if _, err := io.ReadFull(rw, b[:2]); err != nil {
return err
}
if b[0] != authUsernamePasswordVersion {
return errors.New("invalid username/password version")
}
if b[1] != authStatusSucceeded {
return errors.New("username/password authentication failed")
}
return nil
}
return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
}

27
vendor/golang.org/x/net/internal/sockstest/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["server.go"],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/internal/sockstest",
importpath = "golang.org/x/net/internal/sockstest",
visibility = ["//vendor/golang.org/x/net:__subpackages__"],
deps = [
"//vendor/golang.org/x/net/internal/nettest:go_default_library",
"//vendor/golang.org/x/net/internal/socks:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

241
vendor/golang.org/x/net/internal/sockstest/server.go generated vendored Normal file
View File

@ -0,0 +1,241 @@
// Copyright 2018 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 sockstest provides utilities for SOCKS testing.
package sockstest
import (
"errors"
"io"
"net"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/internal/socks"
)
// An AuthRequest represents an authentication request.
type AuthRequest struct {
Version int
Methods []socks.AuthMethod
}
// ParseAuthRequest parses an authentication request.
func ParseAuthRequest(b []byte) (*AuthRequest, error) {
if len(b) < 2 {
return nil, errors.New("short auth request")
}
if b[0] != socks.Version5 {
return nil, errors.New("unexpected protocol version")
}
if len(b)-2 < int(b[1]) {
return nil, errors.New("short auth request")
}
req := &AuthRequest{Version: int(b[0])}
if b[1] > 0 {
req.Methods = make([]socks.AuthMethod, b[1])
for i, m := range b[2 : 2+b[1]] {
req.Methods[i] = socks.AuthMethod(m)
}
}
return req, nil
}
// MarshalAuthReply returns an authentication reply in wire format.
func MarshalAuthReply(ver int, m socks.AuthMethod) ([]byte, error) {
return []byte{byte(ver), byte(m)}, nil
}
// A CmdRequest repesents a command request.
type CmdRequest struct {
Version int
Cmd socks.Command
Addr socks.Addr
}
// ParseCmdRequest parses a command request.
func ParseCmdRequest(b []byte) (*CmdRequest, error) {
if len(b) < 7 {
return nil, errors.New("short cmd request")
}
if b[0] != socks.Version5 {
return nil, errors.New("unexpected protocol version")
}
if socks.Command(b[1]) != socks.CmdConnect {
return nil, errors.New("unexpected command")
}
if b[2] != 0 {
return nil, errors.New("non-zero reserved field")
}
req := &CmdRequest{Version: int(b[0]), Cmd: socks.Command(b[1])}
l := 2
off := 4
switch b[3] {
case socks.AddrTypeIPv4:
l += net.IPv4len
req.Addr.IP = make(net.IP, net.IPv4len)
case socks.AddrTypeIPv6:
l += net.IPv6len
req.Addr.IP = make(net.IP, net.IPv6len)
case socks.AddrTypeFQDN:
l += int(b[4])
off = 5
default:
return nil, errors.New("unknown address type")
}
if len(b[off:]) < l {
return nil, errors.New("short cmd request")
}
if req.Addr.IP != nil {
copy(req.Addr.IP, b[off:])
} else {
req.Addr.Name = string(b[off : off+l-2])
}
req.Addr.Port = int(b[off+l-2])<<8 | int(b[off+l-1])
return req, nil
}
// MarshalCmdReply returns a command reply in wire format.
func MarshalCmdReply(ver int, reply socks.Reply, a *socks.Addr) ([]byte, error) {
b := make([]byte, 4)
b[0] = byte(ver)
b[1] = byte(reply)
if a.Name != "" {
if len(a.Name) > 255 {
return nil, errors.New("fqdn too long")
}
b[3] = socks.AddrTypeFQDN
b = append(b, byte(len(a.Name)))
b = append(b, a.Name...)
} else if ip4 := a.IP.To4(); ip4 != nil {
b[3] = socks.AddrTypeIPv4
b = append(b, ip4...)
} else if ip6 := a.IP.To16(); ip6 != nil {
b[3] = socks.AddrTypeIPv6
b = append(b, ip6...)
} else {
return nil, errors.New("unknown address type")
}
b = append(b, byte(a.Port>>8), byte(a.Port))
return b, nil
}
// A Server repesents a server for handshake testing.
type Server struct {
ln net.Listener
}
// Addr rerurns a server address.
func (s *Server) Addr() net.Addr {
return s.ln.Addr()
}
// TargetAddr returns a fake final destination address.
//
// The returned address is only valid for testing with Server.
func (s *Server) TargetAddr() net.Addr {
a := s.ln.Addr()
switch a := a.(type) {
case *net.TCPAddr:
if a.IP.To4() != nil {
return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 5963}
}
if a.IP.To16() != nil && a.IP.To4() == nil {
return &net.TCPAddr{IP: net.IPv6loopback, Port: 5963}
}
}
return nil
}
// Close closes the server.
func (s *Server) Close() error {
return s.ln.Close()
}
func (s *Server) serve(authFunc, cmdFunc func(io.ReadWriter, []byte) error) {
c, err := s.ln.Accept()
if err != nil {
return
}
defer c.Close()
go s.serve(authFunc, cmdFunc)
b := make([]byte, 512)
n, err := c.Read(b)
if err != nil {
return
}
if err := authFunc(c, b[:n]); err != nil {
return
}
n, err = c.Read(b)
if err != nil {
return
}
if err := cmdFunc(c, b[:n]); err != nil {
return
}
}
// NewServer returns a new server.
//
// The provided authFunc and cmdFunc must parse requests and return
// appropriate replies to clients.
func NewServer(authFunc, cmdFunc func(io.ReadWriter, []byte) error) (*Server, error) {
var err error
s := new(Server)
s.ln, err = nettest.NewLocalListener("tcp")
if err != nil {
return nil, err
}
go s.serve(authFunc, cmdFunc)
return s, nil
}
// NoAuthRequired handles a no-authentication-required signaling.
func NoAuthRequired(rw io.ReadWriter, b []byte) error {
req, err := ParseAuthRequest(b)
if err != nil {
return err
}
b, err = MarshalAuthReply(req.Version, socks.AuthMethodNotRequired)
if err != nil {
return err
}
n, err := rw.Write(b)
if err != nil {
return err
}
if n != len(b) {
return errors.New("short write")
}
return nil
}
// NoProxyRequired handles a command signaling without constructing a
// proxy connection to the final destination.
func NoProxyRequired(rw io.ReadWriter, b []byte) error {
req, err := ParseCmdRequest(b)
if err != nil {
return err
}
req.Addr.Port += 1
if req.Addr.Name != "" {
req.Addr.Name = "boundaddr.doesnotexist"
} else if req.Addr.IP.To4() != nil {
req.Addr.IP = net.IPv4(127, 0, 0, 1)
} else {
req.Addr.IP = net.IPv6loopback
}
b, err = MarshalCmdReply(socks.Version5, socks.StatusSucceeded, &req.Addr)
if err != nil {
return err
}
n, err := rw.Write(b)
if err != nil {
return err
}
if n != len(b) {
return errors.New("short write")
}
return nil
}

View File

@ -11,6 +11,7 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/proxy",
importpath = "golang.org/x/net/proxy",
visibility = ["//visibility:public"],
deps = ["//vendor/golang.org/x/net/internal/socks:go_default_library"],
)
filegroup(

View File

@ -79,8 +79,13 @@ func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
}
switch u.Scheme {
case "socks5":
return SOCKS5("tcp", u.Host, auth, forward)
case "socks5", "socks5h":
addr := u.Hostname()
port := u.Port()
if port == "" {
port = "1080"
}
return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward)
}
// If the scheme doesn't match any of the built-in schemes, see if it

View File

@ -5,210 +5,32 @@
package proxy
import (
"errors"
"io"
"context"
"net"
"strconv"
"golang.org/x/net/internal/socks"
)
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
// with an optional username and password. See RFC 1928 and RFC 1929.
func SOCKS5(network, addr string, auth *Auth, forward Dialer) (Dialer, error) {
s := &socks5{
network: network,
addr: addr,
forward: forward,
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given
// address with an optional username and password.
// See RFC 1928 and RFC 1929.
func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) {
d := socks.NewDialer(network, address)
if forward != nil {
d.ProxyDial = func(_ context.Context, network string, address string) (net.Conn, error) {
return forward.Dial(network, address)
}
}
if auth != nil {
s.user = auth.User
s.password = auth.Password
up := socks.UsernamePassword{
Username: auth.User,
Password: auth.Password,
}
d.AuthMethods = []socks.AuthMethod{
socks.AuthMethodNotRequired,
socks.AuthMethodUsernamePassword,
}
d.Authenticate = up.Authenticate
}
return s, nil
}
type socks5 struct {
user, password string
network, addr string
forward Dialer
}
const socks5Version = 5
const (
socks5AuthNone = 0
socks5AuthPassword = 2
)
const socks5Connect = 1
const (
socks5IP4 = 1
socks5Domain = 3
socks5IP6 = 4
)
var socks5Errors = []string{
"",
"general failure",
"connection forbidden",
"network unreachable",
"host unreachable",
"connection refused",
"TTL expired",
"command not supported",
"address type not supported",
}
// Dial connects to the address addr on the given network via the SOCKS5 proxy.
func (s *socks5) Dial(network, addr string) (net.Conn, error) {
switch network {
case "tcp", "tcp6", "tcp4":
default:
return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
}
conn, err := s.forward.Dial(s.network, s.addr)
if err != nil {
return nil, err
}
if err := s.connect(conn, addr); err != nil {
conn.Close()
return nil, err
}
return conn, nil
}
// connect takes an existing connection to a socks5 proxy server,
// and commands the server to extend that connection to target,
// which must be a canonical address with a host and port.
func (s *socks5) connect(conn net.Conn, target string) error {
host, portStr, err := net.SplitHostPort(target)
if err != nil {
return err
}
port, err := strconv.Atoi(portStr)
if err != nil {
return errors.New("proxy: failed to parse port number: " + portStr)
}
if port < 1 || port > 0xffff {
return errors.New("proxy: port number out of range: " + portStr)
}
// the size here is just an estimate
buf := make([]byte, 0, 6+len(host))
buf = append(buf, socks5Version)
if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword)
} else {
buf = append(buf, 1 /* num auth methods */, socks5AuthNone)
}
if _, err := conn.Write(buf); err != nil {
return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
if buf[0] != 5 {
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
}
if buf[1] == 0xff {
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
}
// See RFC 1929
if buf[1] == socks5AuthPassword {
buf = buf[:0]
buf = append(buf, 1 /* password protocol version */)
buf = append(buf, uint8(len(s.user)))
buf = append(buf, s.user...)
buf = append(buf, uint8(len(s.password)))
buf = append(buf, s.password...)
if _, err := conn.Write(buf); err != nil {
return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
if buf[1] != 0 {
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
}
}
buf = buf[:0]
buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */)
if ip := net.ParseIP(host); ip != nil {
if ip4 := ip.To4(); ip4 != nil {
buf = append(buf, socks5IP4)
ip = ip4
} else {
buf = append(buf, socks5IP6)
}
buf = append(buf, ip...)
} else {
if len(host) > 255 {
return errors.New("proxy: destination host name too long: " + host)
}
buf = append(buf, socks5Domain)
buf = append(buf, byte(len(host)))
buf = append(buf, host...)
}
buf = append(buf, byte(port>>8), byte(port))
if _, err := conn.Write(buf); err != nil {
return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
if _, err := io.ReadFull(conn, buf[:4]); err != nil {
return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
failure := "unknown error"
if int(buf[1]) < len(socks5Errors) {
failure = socks5Errors[buf[1]]
}
if len(failure) > 0 {
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
}
bytesToDiscard := 0
switch buf[3] {
case socks5IP4:
bytesToDiscard = net.IPv4len
case socks5IP6:
bytesToDiscard = net.IPv6len
case socks5Domain:
_, err := io.ReadFull(conn, buf[:1])
if err != nil {
return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
bytesToDiscard = int(buf[0])
default:
return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
}
if cap(buf) < bytesToDiscard {
buf = make([]byte, bytesToDiscard)
} else {
buf = buf[:bytesToDiscard]
}
if _, err := io.ReadFull(conn, buf); err != nil {
return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
// Also need to discard the port number
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
}
return nil
return d, nil
}

View File

@ -6,16 +6,11 @@ go_library(
"events.go",
"histogram.go",
"trace.go",
"trace_go16.go",
"trace_go17.go",
],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/net/trace",
importpath = "golang.org/x/net/trace",
visibility = ["//visibility:public"],
deps = [
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/golang.org/x/net/internal/timeseries:go_default_library",
],
deps = ["//vendor/golang.org/x/net/internal/timeseries:go_default_library"],
)
filegroup(

View File

@ -64,12 +64,14 @@ package trace
import (
"bytes"
"context"
"fmt"
"html/template"
"io"
"log"
"net"
"net/http"
"net/url"
"runtime"
"sort"
"strconv"
@ -84,6 +86,12 @@ import (
// FOR DEBUGGING ONLY. This will slow down the program.
var DebugUseAfterFinish = false
// HTTP ServeMux paths.
const (
debugRequestsPath = "/debug/requests"
debugEventsPath = "/debug/events"
)
// AuthRequest determines whether a specific request is permitted to load the
// /debug/requests or /debug/events pages.
//
@ -110,10 +118,29 @@ var AuthRequest = func(req *http.Request) (any, sensitive bool) {
}
func init() {
_, pat := http.DefaultServeMux.Handler(&http.Request{URL: &url.URL{Path: debugRequestsPath}})
if pat == debugRequestsPath {
panic("/debug/requests is already registered. You may have two independent copies of " +
"golang.org/x/net/trace in your binary, trying to maintain separate state. This may " +
"involve a vendored copy of golang.org/x/net/trace.")
}
// TODO(jbd): Serve Traces from /debug/traces in the future?
// There is no requirement for a request to be present to have traces.
http.HandleFunc("/debug/requests", Traces)
http.HandleFunc("/debug/events", Events)
http.HandleFunc(debugRequestsPath, Traces)
http.HandleFunc(debugEventsPath, Events)
}
// NewContext returns a copy of the parent context
// and associates it with a Trace.
func NewContext(ctx context.Context, tr Trace) context.Context {
return context.WithValue(ctx, contextKey, tr)
}
// FromContext returns the Trace bound to the context, if any.
func FromContext(ctx context.Context) (tr Trace, ok bool) {
tr, ok = ctx.Value(contextKey).(Trace)
return
}
// Traces responds with traces from the program.
@ -368,7 +395,11 @@ func New(family, title string) Trace {
}
func (tr *trace) Finish() {
tr.Elapsed = time.Now().Sub(tr.Start)
elapsed := time.Now().Sub(tr.Start)
tr.mu.Lock()
tr.Elapsed = elapsed
tr.mu.Unlock()
if DebugUseAfterFinish {
buf := make([]byte, 4<<10) // 4 KB should be enough
n := runtime.Stack(buf, false)
@ -381,14 +412,17 @@ func (tr *trace) Finish() {
m.Remove(tr)
f := getFamily(tr.Family, true)
tr.mu.RLock() // protects tr fields in Cond.match calls
for _, b := range f.Buckets {
if b.Cond.match(tr) {
b.Add(tr)
}
}
tr.mu.RUnlock()
// Add a sample of elapsed time as microseconds to the family's timeseries
h := new(histogram)
h.addMeasurement(tr.Elapsed.Nanoseconds() / 1e3)
h.addMeasurement(elapsed.Nanoseconds() / 1e3)
f.LatencyMu.Lock()
f.Latency.Add(h)
f.LatencyMu.Unlock()
@ -684,25 +718,20 @@ type trace struct {
// Title is the title of this trace.
Title string
// Timing information.
Start time.Time
Elapsed time.Duration // zero while active
// Start time of the this trace.
Start time.Time
// Trace information if non-zero.
traceID uint64
spanID uint64
// Whether this trace resulted in an error.
IsError bool
// Append-only sequence of events (modulo discards).
mu sync.RWMutex
events []event
events []event // Append-only sequence of events (modulo discards).
maxEvents int
recycler func(interface{})
IsError bool // Whether this trace resulted in an error.
Elapsed time.Duration // Elapsed time for this trace, zero while active.
traceID uint64 // Trace information if non-zero.
spanID uint64
refs int32 // how many buckets this is in
recycler func(interface{})
disc discarded // scratch space to avoid allocation
refs int32 // how many buckets this is in
disc discarded // scratch space to avoid allocation
finishStack []byte // where finish was called, if DebugUseAfterFinish is set
@ -714,14 +743,18 @@ func (tr *trace) reset() {
tr.Family = ""
tr.Title = ""
tr.Start = time.Time{}
tr.mu.Lock()
tr.Elapsed = 0
tr.traceID = 0
tr.spanID = 0
tr.IsError = false
tr.maxEvents = 0
tr.events = nil
tr.refs = 0
tr.recycler = nil
tr.mu.Unlock()
tr.refs = 0
tr.disc = 0
tr.finishStack = nil
for i := range tr.eventsBuf {
@ -801,21 +834,31 @@ func (tr *trace) LazyPrintf(format string, a ...interface{}) {
tr.addEvent(&lazySprintf{format, a}, false, false)
}
func (tr *trace) SetError() { tr.IsError = true }
func (tr *trace) SetError() {
tr.mu.Lock()
tr.IsError = true
tr.mu.Unlock()
}
func (tr *trace) SetRecycler(f func(interface{})) {
tr.mu.Lock()
tr.recycler = f
tr.mu.Unlock()
}
func (tr *trace) SetTraceInfo(traceID, spanID uint64) {
tr.mu.Lock()
tr.traceID, tr.spanID = traceID, spanID
tr.mu.Unlock()
}
func (tr *trace) SetMaxEvents(m int) {
tr.mu.Lock()
// Always keep at least three events: first, discarded count, last.
if len(tr.events) == 0 && m > 3 {
tr.maxEvents = m
}
tr.mu.Unlock()
}
func (tr *trace) ref() {
@ -824,6 +867,7 @@ func (tr *trace) ref() {
func (tr *trace) unref() {
if atomic.AddInt32(&tr.refs, -1) == 0 {
tr.mu.RLock()
if tr.recycler != nil {
// freeTrace clears tr, so we hold tr.recycler and tr.events here.
go func(f func(interface{}), es []event) {
@ -834,6 +878,7 @@ func (tr *trace) unref() {
}
}(tr.recycler, tr.events)
}
tr.mu.RUnlock()
freeTrace(tr)
}
@ -844,7 +889,10 @@ func (tr *trace) When() string {
}
func (tr *trace) ElapsedTime() string {
tr.mu.RLock()
t := tr.Elapsed
tr.mu.RUnlock()
if t == 0 {
// Active trace.
t = time.Since(tr.Start)

View File

@ -1,21 +0,0 @@
// Copyright 2017 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.
// +build !go1.7
package trace
import "golang.org/x/net/context"
// NewContext returns a copy of the parent context
// and associates it with a Trace.
func NewContext(ctx context.Context, tr Trace) context.Context {
return context.WithValue(ctx, contextKey, tr)
}
// FromContext returns the Trace bound to the context, if any.
func FromContext(ctx context.Context) (tr Trace, ok bool) {
tr, ok = ctx.Value(contextKey).(Trace)
return
}

View File

@ -1,21 +0,0 @@
// Copyright 2017 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.
// +build go1.7
package trace
import "context"
// NewContext returns a copy of the parent context
// and associates it with a Trace.
func NewContext(ctx context.Context, tr Trace) context.Context {
return context.WithValue(ctx, contextKey, tr)
}
// FromContext returns the Trace bound to the context, if any.
func FromContext(ctx context.Context) (tr Trace, ok bool) {
tr, ok = ctx.Value(contextKey).(Trace)
return
}

View File

@ -241,7 +241,10 @@ func (ws *Conn) Close() error {
return err1
}
// IsClientConn reports whether ws is a client-side connection.
func (ws *Conn) IsClientConn() bool { return ws.request == nil }
// IsServerConn reports whether ws is a server-side connection.
func (ws *Conn) IsServerConn() bool { return ws.request != nil }
// LocalAddr returns the WebSocket Origin for the connection for client, or