mirror of
https://github.com/kubernetes/client-go.git
synced 2025-09-26 15:17:05 +00:00
Merge pull request #75289 from dims/update-http2-dep-go-1.12
Update golang.org/x/net/... dependencies to release-branch.go1.12 Kubernetes-commit: e7d09ceb5019153831b4921ff35a170e46f634d2
This commit is contained in:
178
Godeps/Godeps.json
generated
178
Godeps/Godeps.json
generated
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/client-go",
|
"ImportPath": "k8s.io/client-go",
|
||||||
"GoVersion": "go1.12",
|
"GoVersion": "go1.12",
|
||||||
"GodepVersion": "v80-k8s-r1",
|
"GodepVersion": "v80",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
@@ -272,355 +272,355 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
|
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/apps/v1",
|
"ImportPath": "k8s.io/api/apps/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/apps/v1beta1",
|
"ImportPath": "k8s.io/api/apps/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/apps/v1beta2",
|
"ImportPath": "k8s.io/api/apps/v1beta2",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/auditregistration/v1alpha1",
|
"ImportPath": "k8s.io/api/auditregistration/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/authentication/v1",
|
"ImportPath": "k8s.io/api/authentication/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/authentication/v1beta1",
|
"ImportPath": "k8s.io/api/authentication/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/authorization/v1",
|
"ImportPath": "k8s.io/api/authorization/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/authorization/v1beta1",
|
"ImportPath": "k8s.io/api/authorization/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/autoscaling/v1",
|
"ImportPath": "k8s.io/api/autoscaling/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
|
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/autoscaling/v2beta2",
|
"ImportPath": "k8s.io/api/autoscaling/v2beta2",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/batch/v1",
|
"ImportPath": "k8s.io/api/batch/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/batch/v1beta1",
|
"ImportPath": "k8s.io/api/batch/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/batch/v2alpha1",
|
"ImportPath": "k8s.io/api/batch/v2alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/certificates/v1beta1",
|
"ImportPath": "k8s.io/api/certificates/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/coordination/v1",
|
"ImportPath": "k8s.io/api/coordination/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/coordination/v1beta1",
|
"ImportPath": "k8s.io/api/coordination/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/core/v1",
|
"ImportPath": "k8s.io/api/core/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/events/v1beta1",
|
"ImportPath": "k8s.io/api/events/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/extensions/v1beta1",
|
"ImportPath": "k8s.io/api/extensions/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/imagepolicy/v1alpha1",
|
"ImportPath": "k8s.io/api/imagepolicy/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/networking/v1",
|
"ImportPath": "k8s.io/api/networking/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/networking/v1beta1",
|
"ImportPath": "k8s.io/api/networking/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/node/v1alpha1",
|
"ImportPath": "k8s.io/api/node/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/node/v1beta1",
|
"ImportPath": "k8s.io/api/node/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/policy/v1beta1",
|
"ImportPath": "k8s.io/api/policy/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/rbac/v1",
|
"ImportPath": "k8s.io/api/rbac/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/rbac/v1alpha1",
|
"ImportPath": "k8s.io/api/rbac/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/rbac/v1beta1",
|
"ImportPath": "k8s.io/api/rbac/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/scheduling/v1",
|
"ImportPath": "k8s.io/api/scheduling/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
|
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/scheduling/v1beta1",
|
"ImportPath": "k8s.io/api/scheduling/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/settings/v1alpha1",
|
"ImportPath": "k8s.io/api/settings/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/storage/v1",
|
"ImportPath": "k8s.io/api/storage/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/storage/v1alpha1",
|
"ImportPath": "k8s.io/api/storage/v1alpha1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/api/storage/v1beta1",
|
"ImportPath": "k8s.io/api/storage/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "3c12c96769cc4f6df2245f283ee74992c94fa4ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "c9defaaddf6f05ecb2dd115c1bed600265501daf"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/klog",
|
"ImportPath": "k8s.io/klog",
|
||||||
|
5
vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
5
vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
@@ -2,18 +2,15 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.7
|
|
||||||
|
|
||||||
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
|
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
|
||||||
package ctxhttp
|
package ctxhttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Do sends an HTTP request with the provided http.Client and returns
|
// Do sends an HTTP request with the provided http.Client and returns
|
||||||
|
147
vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
generated
vendored
147
vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
generated
vendored
@@ -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 = ¬ifyingReader{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
|
|
||||||
}
|
|
50
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
Normal file
50
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
Normal 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,
|
||||||
|
}
|
@@ -2,12 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package httplex contains rules around lexical matters of various
|
package httpguts
|
||||||
// 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
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
28
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
28
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
@@ -52,9 +52,31 @@ const (
|
|||||||
noDialOnMiss = false
|
noDialOnMiss = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// shouldTraceGetConn reports whether getClientConn should call any
|
||||||
|
// ClientTrace.GetConn hook associated with the http.Request.
|
||||||
|
//
|
||||||
|
// This complexity is needed to avoid double calls of the GetConn hook
|
||||||
|
// during the back-and-forth between net/http and x/net/http2 (when the
|
||||||
|
// net/http.Transport is upgraded to also speak http2), as well as support
|
||||||
|
// the case where x/net/http2 is being used directly.
|
||||||
|
func (p *clientConnPool) shouldTraceGetConn(st clientConnIdleState) bool {
|
||||||
|
// If our Transport wasn't made via ConfigureTransport, always
|
||||||
|
// trace the GetConn hook if provided, because that means the
|
||||||
|
// http2 package is being used directly and it's the one
|
||||||
|
// dialing, as opposed to net/http.
|
||||||
|
if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// Otherwise, only use the GetConn hook if this connection has
|
||||||
|
// been used previously for other requests. For fresh
|
||||||
|
// connections, the net/http package does the dialing.
|
||||||
|
return !st.freshConn
|
||||||
|
}
|
||||||
|
|
||||||
func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
|
func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
|
||||||
if isConnectionCloseRequest(req) && dialOnMiss {
|
if isConnectionCloseRequest(req) && dialOnMiss {
|
||||||
// It gets its own connection.
|
// It gets its own connection.
|
||||||
|
traceGetConn(req, addr)
|
||||||
const singleUse = true
|
const singleUse = true
|
||||||
cc, err := p.t.dialClientConn(addr, singleUse)
|
cc, err := p.t.dialClientConn(addr, singleUse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -64,7 +86,10 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
|
|||||||
}
|
}
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
for _, cc := range p.conns[addr] {
|
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()
|
p.mu.Unlock()
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
@@ -73,6 +98,7 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
|
|||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
return nil, ErrNoCachedConn
|
return nil, ErrNoCachedConn
|
||||||
}
|
}
|
||||||
|
traceGetConn(req, addr)
|
||||||
call := p.getStartDialLocked(addr)
|
call := p.getStartDialLocked(addr)
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
<-call.done
|
<-call.done
|
||||||
|
80
vendor/golang.org/x/net/http2/configure_transport.go
generated
vendored
80
vendor/golang.org/x/net/http2/configure_transport.go
generated
vendored
@@ -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
|
|
||||||
}
|
|
10
vendor/golang.org/x/net/http2/flow.go
generated
vendored
10
vendor/golang.org/x/net/http2/flow.go
generated
vendored
@@ -41,10 +41,10 @@ func (f *flow) take(n int32) {
|
|||||||
// add adds n bytes (positive or negative) to the flow control window.
|
// add adds n bytes (positive or negative) to the flow control window.
|
||||||
// It returns false if the sum would exceed 2^31-1.
|
// It returns false if the sum would exceed 2^31-1.
|
||||||
func (f *flow) add(n int32) bool {
|
func (f *flow) add(n int32) bool {
|
||||||
remain := (1<<31 - 1) - f.n
|
sum := f.n + n
|
||||||
if n > remain {
|
if (sum > n) == (f.n > 0) {
|
||||||
return false
|
f.n = sum
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
f.n += n
|
return false
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
69
vendor/golang.org/x/net/http2/frame.go
generated
vendored
69
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@@ -14,8 +14,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/net/http/httpguts"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"golang.org/x/net/lex/httplex"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const frameHeaderLen = 9
|
const frameHeaderLen = 9
|
||||||
@@ -733,32 +733,67 @@ func (f *SettingsFrame) IsAck() bool {
|
|||||||
return f.FrameHeader.Flags.Has(FlagSettingsAck)
|
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()
|
f.checkValid()
|
||||||
buf := f.p
|
for i := 0; i < f.NumSettings(); i++ {
|
||||||
for len(buf) > 0 {
|
if s := f.Setting(i); s.ID == id {
|
||||||
settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
|
return s.Val, true
|
||||||
if settingID == s {
|
|
||||||
return binary.BigEndian.Uint32(buf[2:6]), true
|
|
||||||
}
|
}
|
||||||
buf = buf[6:]
|
|
||||||
}
|
}
|
||||||
return 0, false
|
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.
|
// ForeachSetting runs fn for each setting.
|
||||||
// It stops and returns the first error.
|
// It stops and returns the first error.
|
||||||
func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
|
func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
|
||||||
f.checkValid()
|
f.checkValid()
|
||||||
buf := f.p
|
for i := 0; i < f.NumSettings(); i++ {
|
||||||
for len(buf) > 0 {
|
if err := fn(f.Setting(i)); err != nil {
|
||||||
if err := fn(Setting{
|
|
||||||
SettingID(binary.BigEndian.Uint16(buf[:2])),
|
|
||||||
binary.BigEndian.Uint32(buf[2:6]),
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buf = buf[6:]
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1442,7 +1477,7 @@ func (fr *Framer) maxHeaderStringLen() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readMetaFrame returns 0 or more CONTINUATION frames from fr and
|
// 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.
|
// with the decoded hpack values.
|
||||||
func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
||||||
if fr.AllowIllegalReads {
|
if fr.AllowIllegalReads {
|
||||||
@@ -1462,7 +1497,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
|||||||
if VerboseLogs && fr.logReads {
|
if VerboseLogs && fr.logReads {
|
||||||
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
|
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
|
||||||
}
|
}
|
||||||
if !httplex.ValidHeaderFieldValue(hf.Value) {
|
if !httpguts.ValidHeaderFieldValue(hf.Value) {
|
||||||
invalid = headerFieldValueError(hf.Value)
|
invalid = headerFieldValueError(hf.Value)
|
||||||
}
|
}
|
||||||
isPseudo := strings.HasPrefix(hf.Name, ":")
|
isPseudo := strings.HasPrefix(hf.Name, ":")
|
||||||
|
29
vendor/golang.org/x/net/http2/go111.go
generated
vendored
Normal file
29
vendor/golang.org/x/net/http2/go111.go
generated
vendored
Normal 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
|
||||||
|
}
|
16
vendor/golang.org/x/net/http2/go16.go
generated
vendored
16
vendor/golang.org/x/net/http2/go16.go
generated
vendored
@@ -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
106
vendor/golang.org/x/net/http2/go17.go
generated
vendored
@@ -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)
|
|
||||||
}
|
|
36
vendor/golang.org/x/net/http2/go17_not18.go
generated
vendored
36
vendor/golang.org/x/net/http2/go17_not18.go
generated
vendored
@@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
56
vendor/golang.org/x/net/http2/go18.go
generated
vendored
56
vendor/golang.org/x/net/http2/go18.go
generated
vendored
@@ -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
|
|
16
vendor/golang.org/x/net/http2/go19.go
generated
vendored
16
vendor/golang.org/x/net/http2/go19.go
generated
vendored
@@ -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
|
|
||||||
}
|
|
20
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
20
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
@@ -7,15 +7,21 @@ package http2
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
|
commonBuildOnce sync.Once
|
||||||
commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
|
commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case
|
||||||
|
commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func buildCommonHeaderMapsOnce() {
|
||||||
for _, v := range []string{
|
commonBuildOnce.Do(buildCommonHeaderMaps)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildCommonHeaderMaps() {
|
||||||
|
common := []string{
|
||||||
"accept",
|
"accept",
|
||||||
"accept-charset",
|
"accept-charset",
|
||||||
"accept-encoding",
|
"accept-encoding",
|
||||||
@@ -63,7 +69,10 @@ func init() {
|
|||||||
"vary",
|
"vary",
|
||||||
"via",
|
"via",
|
||||||
"www-authenticate",
|
"www-authenticate",
|
||||||
} {
|
}
|
||||||
|
commonLowerHeader = make(map[string]string, len(common))
|
||||||
|
commonCanonHeader = make(map[string]string, len(common))
|
||||||
|
for _, v := range common {
|
||||||
chk := http.CanonicalHeaderKey(v)
|
chk := http.CanonicalHeaderKey(v)
|
||||||
commonLowerHeader[chk] = v
|
commonLowerHeader[chk] = v
|
||||||
commonCanonHeader[v] = chk
|
commonCanonHeader[v] = chk
|
||||||
@@ -71,6 +80,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func lowerHeader(v string) string {
|
func lowerHeader(v string) string {
|
||||||
|
buildCommonHeaderMapsOnce()
|
||||||
if s, ok := commonLowerHeader[v]; ok {
|
if s, ok := commonLowerHeader[v]; ok {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
@@ -206,7 +206,7 @@ func appendVarInt(dst []byte, n byte, i uint64) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// appendHpackString appends s, as encoded in "String Literal"
|
// 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
|
// s will be encoded in Huffman codes only when it produces strictly
|
||||||
// shorter byte string.
|
// shorter byte string.
|
||||||
|
14
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
14
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
@@ -92,6 +92,8 @@ type Decoder struct {
|
|||||||
// saveBuf is previous data passed to Write which we weren't able
|
// saveBuf is previous data passed to Write which we weren't able
|
||||||
// to fully parse before. Unlike buf, we own this data.
|
// to fully parse before. Unlike buf, we own this data.
|
||||||
saveBuf bytes.Buffer
|
saveBuf bytes.Buffer
|
||||||
|
|
||||||
|
firstField bool // processing the first field of the header block
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDecoder returns a new decoder with the provided maximum dynamic
|
// 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{
|
d := &Decoder{
|
||||||
emit: emitFunc,
|
emit: emitFunc,
|
||||||
emitEnabled: true,
|
emitEnabled: true,
|
||||||
|
firstField: true,
|
||||||
}
|
}
|
||||||
d.dynTab.table.init()
|
d.dynTab.table.init()
|
||||||
d.dynTab.allowedMaxSize = maxDynamicTableSize
|
d.dynTab.allowedMaxSize = maxDynamicTableSize
|
||||||
@@ -226,11 +229,15 @@ func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
|
|||||||
return hf, nil
|
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 {
|
func (d *Decoder) Close() error {
|
||||||
if d.saveBuf.Len() > 0 {
|
if d.saveBuf.Len() > 0 {
|
||||||
d.saveBuf.Reset()
|
d.saveBuf.Reset()
|
||||||
return DecodingError{errors.New("truncated headers")}
|
return DecodingError{errors.New("truncated headers")}
|
||||||
}
|
}
|
||||||
|
d.firstField = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +273,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) {
|
|||||||
d.saveBuf.Write(d.buf)
|
d.saveBuf.Write(d.buf)
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
d.firstField = false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -389,6 +397,12 @@ func (d *Decoder) callEmit(hf HeaderField) error {
|
|||||||
|
|
||||||
// (same invariants and behavior as parseHeaderFieldRepr)
|
// (same invariants and behavior as parseHeaderFieldRepr)
|
||||||
func (d *Decoder) parseDynamicTableSizeUpdate() error {
|
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
|
buf := d.buf
|
||||||
size, buf, err := readVarInt(5, buf)
|
size, buf, err := readVarInt(5, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
20
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
20
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
@@ -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
|
// If maxLen is greater than 0, attempts to write more to buf than
|
||||||
// maxLen bytes will return ErrStringLength.
|
// maxLen bytes will return ErrStringLength.
|
||||||
func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
|
func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
|
||||||
|
rootHuffmanNode := getRootHuffmanNode()
|
||||||
n := rootHuffmanNode
|
n := rootHuffmanNode
|
||||||
// cur is the bit buffer that has not been fed into n.
|
// 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.
|
// 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 {
|
type node struct {
|
||||||
// children is non-nil for internal nodes
|
// children is non-nil for internal nodes
|
||||||
children []*node
|
children *[256]*node
|
||||||
|
|
||||||
// The following are only valid if children is nil:
|
// The following are only valid if children is nil:
|
||||||
codeLen uint8 // number of bits that led to the output of sym
|
codeLen uint8 // number of bits that led to the output of sym
|
||||||
@@ -114,22 +115,31 @@ type node struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newInternalNode() *node {
|
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 {
|
if len(huffmanCodes) != 256 {
|
||||||
panic("unexpected size")
|
panic("unexpected size")
|
||||||
}
|
}
|
||||||
|
lazyRootHuffmanNode = newInternalNode()
|
||||||
for i, code := range huffmanCodes {
|
for i, code := range huffmanCodes {
|
||||||
addDecoderNode(byte(i), code, huffmanCodeLen[i])
|
addDecoderNode(byte(i), code, huffmanCodeLen[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDecoderNode(sym byte, code uint32, codeLen uint8) {
|
func addDecoderNode(sym byte, code uint32, codeLen uint8) {
|
||||||
cur := rootHuffmanNode
|
cur := lazyRootHuffmanNode
|
||||||
for codeLen > 8 {
|
for codeLen > 8 {
|
||||||
codeLen -= 8
|
codeLen -= 8
|
||||||
i := uint8(code >> codeLen)
|
i := uint8(code >> codeLen)
|
||||||
|
25
vendor/golang.org/x/net/http2/http2.go
generated
vendored
25
vendor/golang.org/x/net/http2/http2.go
generated
vendored
@@ -29,7 +29,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/net/lex/httplex"
|
"golang.org/x/net/http/httpguts"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -179,7 +179,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// validWireHeaderFieldName reports whether v is a valid header field
|
// 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:
|
// Further, http2 says:
|
||||||
// "Just as in HTTP/1.x, header field names are strings of ASCII
|
// "Just as in HTTP/1.x, header field names are strings of ASCII
|
||||||
@@ -191,7 +191,7 @@ func validWireHeaderFieldName(v string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, r := range v {
|
for _, r := range v {
|
||||||
if !httplex.IsTokenRune(r) {
|
if !httpguts.IsTokenRune(r) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if 'A' <= r && r <= 'Z' {
|
if 'A' <= r && r <= 'Z' {
|
||||||
@@ -201,19 +201,12 @@ func validWireHeaderFieldName(v string) bool {
|
|||||||
return true
|
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 {
|
func httpCodeString(code int) string {
|
||||||
if s, ok := httpCodeStringCommon[code]; ok {
|
switch code {
|
||||||
return s
|
case 200:
|
||||||
|
return "200"
|
||||||
|
case 404:
|
||||||
|
return "404"
|
||||||
}
|
}
|
||||||
return strconv.Itoa(code)
|
return strconv.Itoa(code)
|
||||||
}
|
}
|
||||||
@@ -312,7 +305,7 @@ func mustUint31(v int32) uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bodyAllowedForStatus reports whether a given response status code
|
// 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 {
|
func bodyAllowedForStatus(status int) bool {
|
||||||
switch {
|
switch {
|
||||||
case status >= 100 && status <= 199:
|
case status >= 100 && status <= 199:
|
||||||
|
20
vendor/golang.org/x/net/http2/not_go111.go
generated
vendored
Normal file
20
vendor/golang.org/x/net/http2/not_go111.go
generated
vendored
Normal 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
|
||||||
|
}
|
21
vendor/golang.org/x/net/http2/not_go16.go
generated
vendored
21
vendor/golang.org/x/net/http2/not_go16.go
generated
vendored
@@ -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
|
|
||||||
|
|
||||||
}
|
|
87
vendor/golang.org/x/net/http2/not_go17.go
generated
vendored
87
vendor/golang.org/x/net/http2/not_go17.go
generated
vendored
@@ -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 }
|
|
29
vendor/golang.org/x/net/http2/not_go18.go
generated
vendored
29
vendor/golang.org/x/net/http2/not_go18.go
generated
vendored
@@ -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
|
|
16
vendor/golang.org/x/net/http2/not_go19.go
generated
vendored
16
vendor/golang.org/x/net/http2/not_go19.go
generated
vendored
@@ -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.9
|
|
||||||
|
|
||||||
package http2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func configureServer19(s *http.Server, conf *Server) error {
|
|
||||||
// not supported prior to go1.9
|
|
||||||
return nil
|
|
||||||
}
|
|
127
vendor/golang.org/x/net/http2/server.go
generated
vendored
127
vendor/golang.org/x/net/http2/server.go
generated
vendored
@@ -28,6 +28,7 @@ package http2
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -46,6 +47,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/http/httpguts"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -208,12 +210,14 @@ func ConfigureServer(s *http.Server, conf *Server) error {
|
|||||||
conf = new(Server)
|
conf = new(Server)
|
||||||
}
|
}
|
||||||
conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
|
conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
|
||||||
if err := configureServer18(s, conf); err != nil {
|
if h1, h2 := s, conf; h2.IdleTimeout == 0 {
|
||||||
return err
|
if h1.IdleTimeout != 0 {
|
||||||
}
|
h2.IdleTimeout = h1.IdleTimeout
|
||||||
if err := configureServer19(s, conf); err != nil {
|
} else {
|
||||||
return err
|
h2.IdleTimeout = h1.ReadTimeout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
s.RegisterOnShutdown(conf.state.startGracefulShutdown)
|
||||||
|
|
||||||
if s.TLSConfig == nil {
|
if s.TLSConfig == nil {
|
||||||
s.TLSConfig = new(tls.Config)
|
s.TLSConfig = new(tls.Config)
|
||||||
@@ -406,7 +410,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
|
|||||||
// addresses during development.
|
// addresses during development.
|
||||||
//
|
//
|
||||||
// TODO: optionally enforce? Or enforce at the time we receive
|
// 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.
|
// But that precludes proxy situations, perhaps.
|
||||||
//
|
//
|
||||||
// So for now, do nothing here again.
|
// So for now, do nothing here again.
|
||||||
@@ -434,6 +438,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
|
|||||||
sc.serve()
|
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) {
|
func (sc *serverConn) rejectConn(err ErrCode, debug string) {
|
||||||
sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
|
sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
|
||||||
// ignoring errors. hanging up anyway.
|
// ignoring errors. hanging up anyway.
|
||||||
@@ -449,7 +462,7 @@ type serverConn struct {
|
|||||||
conn net.Conn
|
conn net.Conn
|
||||||
bw *bufferedWriter // writing to conn
|
bw *bufferedWriter // writing to conn
|
||||||
handler http.Handler
|
handler http.Handler
|
||||||
baseCtx contextContext
|
baseCtx context.Context
|
||||||
framer *Framer
|
framer *Framer
|
||||||
doneServing chan struct{} // closed when serverConn.serve ends
|
doneServing chan struct{} // closed when serverConn.serve ends
|
||||||
readFrameCh chan readFrameResult // written by serverConn.readFrames
|
readFrameCh chan readFrameResult // written by serverConn.readFrames
|
||||||
@@ -529,7 +542,7 @@ type stream struct {
|
|||||||
id uint32
|
id uint32
|
||||||
body *pipe // non-nil if expecting DATA frames
|
body *pipe // non-nil if expecting DATA frames
|
||||||
cw closeWaiter // closed wait stream transitions to closed state
|
cw closeWaiter // closed wait stream transitions to closed state
|
||||||
ctx contextContext
|
ctx context.Context
|
||||||
cancelCtx func()
|
cancelCtx func()
|
||||||
|
|
||||||
// owned by serverConn's serve loop:
|
// 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 {
|
func (sc *serverConn) canonicalHeader(v string) string {
|
||||||
sc.serveG.check()
|
sc.serveG.check()
|
||||||
|
buildCommonHeaderMapsOnce()
|
||||||
cv, ok := commonCanonHeader[v]
|
cv, ok := commonCanonHeader[v]
|
||||||
if ok {
|
if ok {
|
||||||
return cv
|
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
|
// 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
|
// 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")
|
var errHandlerPanicked = errors.New("http2: handler panicked")
|
||||||
|
|
||||||
// wroteFrame is called on the serve goroutine with the result of
|
// wroteFrame is called on the serve goroutine with the result of
|
||||||
@@ -1486,6 +1500,12 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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 {
|
if err := f.ForeachSetting(sc.processSetting); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1607,7 +1627,10 @@ func (sc *serverConn) processData(f *DataFrame) error {
|
|||||||
// Sender sending more than they'd declared?
|
// Sender sending more than they'd declared?
|
||||||
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
|
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))
|
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 {
|
if f.Length > 0 {
|
||||||
// Check whether the client has flow control quota.
|
// Check whether the client has flow control quota.
|
||||||
@@ -1717,6 +1740,13 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
// processing this frame.
|
// processing this frame.
|
||||||
return nil
|
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)
|
return st.processTrailerHeaders(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1817,7 +1847,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
|
|||||||
if st.trailer != nil {
|
if st.trailer != nil {
|
||||||
for _, hf := range f.RegularFields() {
|
for _, hf := range f.RegularFields() {
|
||||||
key := sc.canonicalHeader(hf.Name)
|
key := sc.canonicalHeader(hf.Name)
|
||||||
if !ValidTrailerHeader(key) {
|
if !httpguts.ValidTrailerHeader(key) {
|
||||||
// TODO: send more details to the peer somehow. But http2 has
|
// TODO: send more details to the peer somehow. But http2 has
|
||||||
// no way to send debug data at a stream level. Discuss with
|
// no way to send debug data at a stream level. Discuss with
|
||||||
// HTTP folk.
|
// HTTP folk.
|
||||||
@@ -1858,7 +1888,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
|
|||||||
panic("internal error: cannot create stream with id 0")
|
panic("internal error: cannot create stream with id 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancelCtx := contextWithCancel(sc.baseCtx)
|
ctx, cancelCtx := context.WithCancel(sc.baseCtx)
|
||||||
st := &stream{
|
st := &stream{
|
||||||
sc: sc,
|
sc: sc,
|
||||||
id: id,
|
id: id,
|
||||||
@@ -2024,7 +2054,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
|
|||||||
Body: body,
|
Body: body,
|
||||||
Trailer: trailer,
|
Trailer: trailer,
|
||||||
}
|
}
|
||||||
req = requestWithContext(req, st.ctx)
|
req = req.WithContext(st.ctx)
|
||||||
|
|
||||||
rws := responseWriterStatePool.Get().(*responseWriterState)
|
rws := responseWriterStatePool.Get().(*responseWriterState)
|
||||||
bwSave := rws.bw
|
bwSave := rws.bw
|
||||||
@@ -2052,7 +2082,7 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler
|
|||||||
stream: rw.rws.stream,
|
stream: rw.rws.stream,
|
||||||
})
|
})
|
||||||
// Same as net/http:
|
// Same as net/http:
|
||||||
if shouldLogPanic(e) {
|
if e != nil && e != http.ErrAbortHandler {
|
||||||
const size = 64 << 10
|
const size = 64 << 10
|
||||||
buf := make([]byte, size)
|
buf := make([]byte, size)
|
||||||
buf = buf[:runtime.Stack(buf, false)]
|
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.
|
// written in the trailers at the end of the response.
|
||||||
func (rws *responseWriterState) declareTrailer(k string) {
|
func (rws *responseWriterState) declareTrailer(k string) {
|
||||||
k = http.CanonicalHeaderKey(k)
|
k = http.CanonicalHeaderKey(k)
|
||||||
if !ValidTrailerHeader(k) {
|
if !httpguts.ValidTrailerHeader(k) {
|
||||||
// Forbidden by RFC 2616 14.40.
|
// Forbidden by RFC 7230, section 4.1.2.
|
||||||
rws.conn.logf("ignoring invalid trailer %q", k)
|
rws.conn.logf("ignoring invalid trailer %q", k)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2335,6 +2365,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
|||||||
foreachHeaderElement(v, rws.declareTrailer)
|
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
|
endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
|
||||||
err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
|
err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
|
||||||
streamID: rws.stream.id,
|
streamID: rws.stream.id,
|
||||||
@@ -2406,7 +2449,7 @@ const TrailerPrefix = "Trailer:"
|
|||||||
// after the header has already been flushed. Because the Go
|
// after the header has already been flushed. Because the Go
|
||||||
// ResponseWriter interface has no way to set Trailers (only the
|
// ResponseWriter interface has no way to set Trailers (only the
|
||||||
// Header), and because we didn't want to expand the ResponseWriter
|
// 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
|
// says you SHOULD (but not must) predeclare any trailers in the
|
||||||
// header, the official ResponseWriter rules said trailers in Go must
|
// header, the official ResponseWriter rules said trailers in Go must
|
||||||
// be predeclared, and then we reuse the same ResponseWriter.Header()
|
// 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")
|
ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
|
||||||
)
|
)
|
||||||
|
|
||||||
// pushOptions is the internal version of http.PushOptions, which we
|
var _ http.Pusher = (*responseWriter)(nil)
|
||||||
// cannot include here because it's only defined in Go 1.8 and later.
|
|
||||||
type pushOptions struct {
|
|
||||||
Method string
|
|
||||||
Header http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *responseWriter) push(target string, opts pushOptions) error {
|
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
|
||||||
st := w.rws.stream
|
st := w.rws.stream
|
||||||
sc := st.sc
|
sc := st.sc
|
||||||
sc.serveG.checkNotOn()
|
sc.serveG.checkNotOn()
|
||||||
@@ -2619,6 +2657,10 @@ func (w *responseWriter) push(target string, opts pushOptions) error {
|
|||||||
return ErrRecursivePush
|
return ErrRecursivePush
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts == nil {
|
||||||
|
opts = new(http.PushOptions)
|
||||||
|
}
|
||||||
|
|
||||||
// Default options.
|
// Default options.
|
||||||
if opts.Method == "" {
|
if opts.Method == "" {
|
||||||
opts.Method = "GET"
|
opts.Method = "GET"
|
||||||
@@ -2790,7 +2832,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// foreachHeaderElement splits v according to the "#rule" construction
|
// 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)) {
|
func foreachHeaderElement(v string, fn func(string)) {
|
||||||
v = textproto.TrimString(v)
|
v = textproto.TrimString(v)
|
||||||
if 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
|
// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
|
||||||
// disabled. See comments on h1ServerShutdownChan above for why
|
// disabled. See comments on h1ServerShutdownChan above for why
|
||||||
// the code is written this way.
|
// the code is written this way.
|
||||||
|
422
vendor/golang.org/x/net/http2/transport.go
generated
vendored
422
vendor/golang.org/x/net/http2/transport.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -21,15 +22,17 @@ import (
|
|||||||
mathrand "math/rand"
|
mathrand "math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptrace"
|
||||||
|
"net/textproto"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/http/httpguts"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"golang.org/x/net/idna"
|
"golang.org/x/net/idna"
|
||||||
"golang.org/x/net/lex/httplex"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -94,6 +97,16 @@ type Transport struct {
|
|||||||
// to mean no limit.
|
// to mean no limit.
|
||||||
MaxHeaderListSize uint32
|
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
|
// t1, if non-nil, is the standard library Transport using
|
||||||
// this transport. Its settings are used (but not its
|
// this transport. Its settings are used (but not its
|
||||||
// RoundTrip method, etc).
|
// RoundTrip method, etc).
|
||||||
@@ -117,16 +130,56 @@ func (t *Transport) disableCompression() bool {
|
|||||||
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
|
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.
|
// 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
|
// It returns an error if t1 has already been HTTP/2-enabled.
|
||||||
// or if t1 has already been HTTP/2-enabled.
|
|
||||||
func ConfigureTransport(t1 *http.Transport) error {
|
func ConfigureTransport(t1 *http.Transport) error {
|
||||||
_, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
|
_, err := configureTransport(t1)
|
||||||
return err
|
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 {
|
func (t *Transport) connPool() ClientConnPool {
|
||||||
t.connPoolOnce.Do(t.initConnPool)
|
t.connPoolOnce.Do(t.initConnPool)
|
||||||
return t.connPoolOrDef
|
return t.connPoolOrDef
|
||||||
@@ -159,6 +212,7 @@ type ClientConn struct {
|
|||||||
cond *sync.Cond // hold mu; broadcast on flow/closed changes
|
cond *sync.Cond // hold mu; broadcast on flow/closed changes
|
||||||
flow flow // our conn-level flow control quota (cs.flow is per stream)
|
flow flow // our conn-level flow control quota (cs.flow is per stream)
|
||||||
inflow flow // peer's conn-level flow control
|
inflow flow // peer's conn-level flow control
|
||||||
|
closing bool
|
||||||
closed bool
|
closed bool
|
||||||
wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
|
wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
|
||||||
goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received
|
goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received
|
||||||
@@ -190,7 +244,7 @@ type ClientConn struct {
|
|||||||
type clientStream struct {
|
type clientStream struct {
|
||||||
cc *ClientConn
|
cc *ClientConn
|
||||||
req *http.Request
|
req *http.Request
|
||||||
trace *clientTrace // or nil
|
trace *httptrace.ClientTrace // or nil
|
||||||
ID uint32
|
ID uint32
|
||||||
resc chan resAndError
|
resc chan resAndError
|
||||||
bufPipe pipe // buffered pipe with the flow-controlled response payload
|
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
|
done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
|
||||||
|
|
||||||
// owned by clientConnReadLoop:
|
// owned by clientConnReadLoop:
|
||||||
firstByte bool // got the first response byte
|
firstByte bool // got the first response byte
|
||||||
pastHeaders bool // got first MetaHeadersFrame (actual headers)
|
pastHeaders bool // got first MetaHeadersFrame (actual headers)
|
||||||
pastTrailers bool // got optional second MetaHeadersFrame (trailers)
|
pastTrailers bool // got optional second MetaHeadersFrame (trailers)
|
||||||
|
num1xx uint8 // number of 1xx responses seen
|
||||||
|
|
||||||
trailer http.Header // accumulated trailers
|
trailer http.Header // accumulated trailers
|
||||||
resTrailer *http.Header // client's Response.Trailer
|
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
|
// channel to be signaled. A non-nil error is returned only if the request was
|
||||||
// canceled.
|
// canceled.
|
||||||
func awaitRequestCancel(req *http.Request, done <-chan struct{}) error {
|
func awaitRequestCancel(req *http.Request, done <-chan struct{}) error {
|
||||||
ctx := reqContext(req)
|
ctx := req.Context()
|
||||||
if req.Cancel == nil && ctx.Done() == nil {
|
if req.Cancel == nil && ctx.Done() == nil {
|
||||||
return 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
|
// 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
|
// 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,
|
// 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 {
|
select {
|
||||||
case <-time.After(time.Second * time.Duration(backoff)):
|
case <-time.After(time.Second * time.Duration(backoff)):
|
||||||
continue
|
continue
|
||||||
case <-reqContext(req).Done():
|
case <-req.Context().Done():
|
||||||
return nil, reqContext(req).Err()
|
return nil, req.Context().Err()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,27 +489,35 @@ func shouldRetryRequest(req *http.Request, err error, afterBodyWrite bool) (*htt
|
|||||||
if !canRetryError(err) {
|
if !canRetryError(err) {
|
||||||
return nil, 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 {
|
if !afterBodyWrite {
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
// If the Body is nil (or http.NoBody), it's safe to reuse
|
|
||||||
// this request and its Body.
|
return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func canRetryError(err error) bool {
|
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 {
|
func (t *Transport) newTLSConfig(host string) *tls.Config {
|
||||||
cfg := new(tls.Config)
|
cfg := new(tls.Config)
|
||||||
if t.TLSClientConfig != nil {
|
if t.TLSClientConfig != nil {
|
||||||
*cfg = *cloneTLSConfig(t.TLSClientConfig)
|
*cfg = *t.TLSClientConfig.Clone()
|
||||||
}
|
}
|
||||||
if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
|
if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
|
||||||
cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
|
cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
|
||||||
@@ -522,7 +596,7 @@ func (t *Transport) expectContinueTimeout() time.Duration {
|
|||||||
if t.t1 == nil {
|
if t.t1 == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return transportExpectContinueTimeout(t.t1)
|
return t.t1.ExpectContinueTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
|
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?
|
// henc in response to SETTINGS frames?
|
||||||
cc.henc = hpack.NewEncoder(&cc.hbuf)
|
cc.henc = hpack.NewEncoder(&cc.hbuf)
|
||||||
|
|
||||||
|
if t.AllowHTTP {
|
||||||
|
cc.nextStreamID = 3
|
||||||
|
}
|
||||||
|
|
||||||
if cs, ok := c.(connectionStater); ok {
|
if cs, ok := c.(connectionStater); ok {
|
||||||
state := cs.ConnectionState()
|
state := cs.ConnectionState()
|
||||||
cc.tlsState = &state
|
cc.tlsState = &state
|
||||||
@@ -626,12 +704,43 @@ func (cc *ClientConn) CanTakeNewRequest() bool {
|
|||||||
return cc.canTakeNewRequestLocked()
|
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 {
|
if cc.singleUse && cc.nextStreamID > 1 {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
return cc.goAway == nil && !cc.closed &&
|
var maxConcurrentOkay bool
|
||||||
int64(cc.nextStreamID)+int64(cc.pendingRequests) < math.MaxInt32
|
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
|
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
|
||||||
@@ -661,6 +770,87 @@ func (cc *ClientConn) closeIfIdle() {
|
|||||||
cc.tconn.Close()
|
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
|
const maxAllocFrameSize = 512 << 10
|
||||||
|
|
||||||
// frameBuffer returns a scratch buffer suitable for writing DATA frames.
|
// 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") {
|
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)
|
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 fmt.Errorf("http2: invalid Connection request header: %q", vv)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -753,7 +943,7 @@ func checkConnHeaders(req *http.Request) error {
|
|||||||
// req.ContentLength, where 0 actually means zero (not unknown) and -1
|
// req.ContentLength, where 0 actually means zero (not unknown) and -1
|
||||||
// means unknown.
|
// means unknown.
|
||||||
func actualContentLength(req *http.Request) int64 {
|
func actualContentLength(req *http.Request) int64 {
|
||||||
if req.Body == nil || reqBodyIsNoBody(req.Body) {
|
if req.Body == nil || req.Body == http.NoBody {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if req.ContentLength != 0 {
|
if req.ContentLength != 0 {
|
||||||
@@ -823,7 +1013,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf
|
|||||||
|
|
||||||
cs := cc.newStream()
|
cs := cc.newStream()
|
||||||
cs.req = req
|
cs.req = req
|
||||||
cs.trace = requestTrace(req)
|
cs.trace = httptrace.ContextClientTrace(req.Context())
|
||||||
cs.requestedGzip = requestedGzip
|
cs.requestedGzip = requestedGzip
|
||||||
bodyWriter := cc.t.getBodyWriterState(cs, body)
|
bodyWriter := cc.t.getBodyWriterState(cs, body)
|
||||||
cs.on100 = bodyWriter.on100
|
cs.on100 = bodyWriter.on100
|
||||||
@@ -861,7 +1051,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf
|
|||||||
|
|
||||||
readLoopResCh := cs.resc
|
readLoopResCh := cs.resc
|
||||||
bodyWritten := false
|
bodyWritten := false
|
||||||
ctx := reqContext(req)
|
ctx := req.Context()
|
||||||
|
|
||||||
handleReadLoopResponse := func(re resAndError) (*http.Response, bool, error) {
|
handleReadLoopResponse := func(re resAndError) (*http.Response, bool, error) {
|
||||||
res := re.res
|
res := re.res
|
||||||
@@ -931,6 +1121,7 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cc.forgetStreamID(cs.ID)
|
||||||
return nil, cs.getStartedWrite(), err
|
return nil, cs.getStartedWrite(), err
|
||||||
}
|
}
|
||||||
bodyWritten = true
|
bodyWritten = true
|
||||||
@@ -951,6 +1142,9 @@ func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error {
|
|||||||
for {
|
for {
|
||||||
cc.lastActive = time.Now()
|
cc.lastActive = time.Now()
|
||||||
if cc.closed || !cc.canTakeNewRequestLocked() {
|
if cc.closed || !cc.canTakeNewRequestLocked() {
|
||||||
|
if waitingForConn != nil {
|
||||||
|
close(waitingForConn)
|
||||||
|
}
|
||||||
return errClientConnUnusable
|
return errClientConnUnusable
|
||||||
}
|
}
|
||||||
if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
|
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
|
sawEOF = true
|
||||||
err = nil
|
err = nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
cc.writeStreamReset(cs.ID, ErrCodeCancel, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1174,7 +1369,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
|
|||||||
if host == "" {
|
if host == "" {
|
||||||
host = req.URL.Host
|
host = req.URL.Host
|
||||||
}
|
}
|
||||||
host, err := httplex.PunycodeHostPort(host)
|
host, err := httpguts.PunycodeHostPort(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// potentially pollute our hpack state. (We want to be able to
|
||||||
// continue to reuse the hpack encoder for future requests)
|
// continue to reuse the hpack encoder for future requests)
|
||||||
for k, vv := range req.Header {
|
for k, vv := range req.Header {
|
||||||
if !httplex.ValidHeaderFieldName(k) {
|
if !httpguts.ValidHeaderFieldName(k) {
|
||||||
return nil, fmt.Errorf("invalid HTTP header name %q", k)
|
return nil, fmt.Errorf("invalid HTTP header name %q", k)
|
||||||
}
|
}
|
||||||
for _, v := range vv {
|
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)
|
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
|
return nil, errRequestHeaderListSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace := httptrace.ContextClientTrace(req.Context())
|
||||||
|
traceHeaders := traceHasWroteHeaderField(trace)
|
||||||
|
|
||||||
// Header list size is ok. Write the headers.
|
// Header list size is ok. Write the headers.
|
||||||
enumerateHeaders(func(name, value string) {
|
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
|
return cc.hbuf.Bytes(), nil
|
||||||
@@ -1608,8 +1810,7 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {
|
|||||||
// is the detail.
|
// is the detail.
|
||||||
//
|
//
|
||||||
// As a special case, handleResponse may return (nil, nil) to skip the
|
// As a special case, handleResponse may return (nil, nil) to skip the
|
||||||
// frame (currently only used for 100 expect continue). This special
|
// frame (currently only used for 1xx responses).
|
||||||
// case is going away after Issue 13851 is fixed.
|
|
||||||
func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
|
func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
|
||||||
if f.Truncated {
|
if f.Truncated {
|
||||||
return nil, errResponseHeaderListSize
|
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")
|
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)
|
header := make(http.Header)
|
||||||
res := &http.Response{
|
res := &http.Response{
|
||||||
Proto: "HTTP/2.0",
|
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()
|
streamEnded := f.StreamEnded()
|
||||||
isHead := cs.req.Method == "HEAD"
|
isHead := cs.req.Method == "HEAD"
|
||||||
if !streamEnded || isHead {
|
if !streamEnded || isHead {
|
||||||
@@ -1689,7 +1902,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
|||||||
res.Header.Del("Content-Length")
|
res.Header.Del("Content-Length")
|
||||||
res.ContentLength = -1
|
res.ContentLength = -1
|
||||||
res.Body = &gzipReader{body: res.Body}
|
res.Body = &gzipReader{body: res.Body}
|
||||||
setResponseUncompressed(res)
|
res.Uncompressed = true
|
||||||
}
|
}
|
||||||
return res, nil
|
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.
|
// 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 context.Context) error {
|
||||||
func (cc *ClientConn) ping(ctx contextContext) error {
|
|
||||||
c := make(chan struct{})
|
c := make(chan struct{})
|
||||||
// Generate a random payload
|
// Generate a random payload
|
||||||
var p [8]byte
|
var p [8]byte
|
||||||
@@ -2244,7 +2456,7 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body
|
|||||||
}
|
}
|
||||||
s.delay = t.expectContinueTimeout()
|
s.delay = t.expectContinueTimeout()
|
||||||
if s.delay == 0 ||
|
if s.delay == 0 ||
|
||||||
!httplex.HeaderValuesContainsToken(
|
!httpguts.HeaderValuesContainsToken(
|
||||||
cs.req.Header["Expect"],
|
cs.req.Header["Expect"],
|
||||||
"100-continue") {
|
"100-continue") {
|
||||||
return
|
return
|
||||||
@@ -2299,5 +2511,93 @@ func (s bodyWriterState) scheduleBodyWrite() {
|
|||||||
// isConnectionCloseRequest reports whether req should use its own
|
// isConnectionCloseRequest reports whether req should use its own
|
||||||
// connection for a single request and then close the connection.
|
// connection for a single request and then close the connection.
|
||||||
func isConnectionCloseRequest(req *http.Request) bool {
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
vendor/golang.org/x/net/http2/write.go
generated
vendored
8
vendor/golang.org/x/net/http2/write.go
generated
vendored
@@ -11,8 +11,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"golang.org/x/net/http/httpguts"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"golang.org/x/net/lex/httplex"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// writeFramer is implemented by any type that is used to write frames.
|
// 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
|
// 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
|
// here and get into the fast path if we could be clever and
|
||||||
// calculate the size fast enough, or at least a conservative
|
// 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.)
|
// w.trailers are nil, so we don't need to enumerate it.)
|
||||||
// Otherwise I'm afraid that just calculating the length to
|
// Otherwise I'm afraid that just calculating the length to
|
||||||
// answer this question would be slower than the ~2µs benefit.
|
// 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])
|
// 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) {
|
func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
|
||||||
if keys == nil {
|
if keys == nil {
|
||||||
sorter := sorterPool.Get().(*sorter)
|
sorter := sorterPool.Get().(*sorter)
|
||||||
@@ -350,7 +350,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
|
|||||||
}
|
}
|
||||||
isTE := k == "transfer-encoding"
|
isTE := k == "transfer-encoding"
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
if !httplex.ValidHeaderFieldValue(v) {
|
if !httpguts.ValidHeaderFieldValue(v) {
|
||||||
// TODO: return an error? golang.org/issue/14048
|
// TODO: return an error? golang.org/issue/14048
|
||||||
// For now just omit it.
|
// For now just omit it.
|
||||||
continue
|
continue
|
||||||
|
Reference in New Issue
Block a user