aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/google.golang.org
diff options
context:
space:
mode:
authorAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
committerAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
commit15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/google.golang.org
parent07971ca38143c5faf951d152fba370ddcbe26ad5 (diff)
downloadterraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/google.golang.org')
-rw-r--r--vendor/google.golang.org/genproto/LICENSE202
-rw-r--r--vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go143
-rw-r--r--vendor/google.golang.org/grpc/.travis.yml21
-rw-r--r--vendor/google.golang.org/grpc/AUTHORS1
-rw-r--r--vendor/google.golang.org/grpc/CONTRIBUTING.md32
-rw-r--r--vendor/google.golang.org/grpc/LICENSE202
-rw-r--r--vendor/google.golang.org/grpc/Makefile52
-rw-r--r--vendor/google.golang.org/grpc/README.md45
-rw-r--r--vendor/google.golang.org/grpc/backoff.go98
-rw-r--r--vendor/google.golang.org/grpc/balancer.go397
-rw-r--r--vendor/google.golang.org/grpc/call.go309
-rw-r--r--vendor/google.golang.org/grpc/clientconn.go1158
-rw-r--r--vendor/google.golang.org/grpc/codec.go104
-rw-r--r--vendor/google.golang.org/grpc/codegen.sh17
-rw-r--r--vendor/google.golang.org/grpc/codes/code_string.go16
-rw-r--r--vendor/google.golang.org/grpc/codes/codes.go144
-rw-r--r--vendor/google.golang.org/grpc/connectivity/connectivity.go72
-rw-r--r--vendor/google.golang.org/grpc/coverage.sh48
-rw-r--r--vendor/google.golang.org/grpc/credentials/credentials.go219
-rw-r--r--vendor/google.golang.org/grpc/credentials/credentials_util_go17.go60
-rw-r--r--vendor/google.golang.org/grpc/credentials/credentials_util_go18.go38
-rw-r--r--vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go57
-rw-r--r--vendor/google.golang.org/grpc/doc.go24
-rw-r--r--vendor/google.golang.org/grpc/go16.go98
-rw-r--r--vendor/google.golang.org/grpc/go17.go98
-rw-r--r--vendor/google.golang.org/grpc/grpclb.go737
-rw-r--r--vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go629
-rw-r--r--vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto164
-rw-r--r--vendor/google.golang.org/grpc/grpclog/grpclog.go123
-rw-r--r--vendor/google.golang.org/grpc/grpclog/logger.go83
-rw-r--r--vendor/google.golang.org/grpc/grpclog/loggerv2.go195
-rw-r--r--vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go176
-rw-r--r--vendor/google.golang.org/grpc/health/grpc_health_v1/health.proto34
-rw-r--r--vendor/google.golang.org/grpc/health/health.go70
-rw-r--r--vendor/google.golang.org/grpc/interceptor.go75
-rw-r--r--vendor/google.golang.org/grpc/internal/internal.go34
-rw-r--r--vendor/google.golang.org/grpc/keepalive/keepalive.go65
-rw-r--r--vendor/google.golang.org/grpc/metadata/metadata.go141
-rw-r--r--vendor/google.golang.org/grpc/naming/dns_resolver.go292
-rw-r--r--vendor/google.golang.org/grpc/naming/go17.go34
-rw-r--r--vendor/google.golang.org/grpc/naming/go18.go28
-rw-r--r--vendor/google.golang.org/grpc/naming/naming.go59
-rw-r--r--vendor/google.golang.org/grpc/peer/peer.go51
-rw-r--r--vendor/google.golang.org/grpc/proxy.go130
-rw-r--r--vendor/google.golang.org/grpc/rpc_util.go524
-rw-r--r--vendor/google.golang.org/grpc/server.go1159
-rw-r--r--vendor/google.golang.org/grpc/stats/handlers.go64
-rw-r--r--vendor/google.golang.org/grpc/stats/stats.go210
-rw-r--r--vendor/google.golang.org/grpc/status/status.go168
-rw-r--r--vendor/google.golang.org/grpc/stream.go661
-rw-r--r--vendor/google.golang.org/grpc/tap/tap.go39
-rw-r--r--vendor/google.golang.org/grpc/trace.go104
-rw-r--r--vendor/google.golang.org/grpc/transport/bdp_estimator.go143
-rw-r--r--vendor/google.golang.org/grpc/transport/control.go246
-rw-r--r--vendor/google.golang.org/grpc/transport/go16.go45
-rw-r--r--vendor/google.golang.org/grpc/transport/go17.go46
-rw-r--r--vendor/google.golang.org/grpc/transport/handler_server.go393
-rw-r--r--vendor/google.golang.org/grpc/transport/http2_client.go1369
-rw-r--r--vendor/google.golang.org/grpc/transport/http2_server.go1195
-rw-r--r--vendor/google.golang.org/grpc/transport/http_util.go597
-rw-r--r--vendor/google.golang.org/grpc/transport/log.go50
-rw-r--r--vendor/google.golang.org/grpc/transport/transport.go730
62 files changed, 14518 insertions, 0 deletions
diff --git a/vendor/google.golang.org/genproto/LICENSE b/vendor/google.golang.org/genproto/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/vendor/google.golang.org/genproto/LICENSE
@@ -0,0 +1,202 @@
1
2 Apache License
3 Version 2.0, January 2004
4 http://www.apache.org/licenses/
5
6 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
8 1. Definitions.
9
10 "License" shall mean the terms and conditions for use, reproduction,
11 and distribution as defined by Sections 1 through 9 of this document.
12
13 "Licensor" shall mean the copyright owner or entity authorized by
14 the copyright owner that is granting the License.
15
16 "Legal Entity" shall mean the union of the acting entity and all
17 other entities that control, are controlled by, or are under common
18 control with that entity. For the purposes of this definition,
19 "control" means (i) the power, direct or indirect, to cause the
20 direction or management of such entity, whether by contract or
21 otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 outstanding shares, or (iii) beneficial ownership of such entity.
23
24 "You" (or "Your") shall mean an individual or Legal Entity
25 exercising permissions granted by this License.
26
27 "Source" form shall mean the preferred form for making modifications,
28 including but not limited to software source code, documentation
29 source, and configuration files.
30
31 "Object" form shall mean any form resulting from mechanical
32 transformation or translation of a Source form, including but
33 not limited to compiled object code, generated documentation,
34 and conversions to other media types.
35
36 "Work" shall mean the work of authorship, whether in Source or
37 Object form, made available under the License, as indicated by a
38 copyright notice that is included in or attached to the work
39 (an example is provided in the Appendix below).
40
41 "Derivative Works" shall mean any work, whether in Source or Object
42 form, that is based on (or derived from) the Work and for which the
43 editorial revisions, annotations, elaborations, or other modifications
44 represent, as a whole, an original work of authorship. For the purposes
45 of this License, Derivative Works shall not include works that remain
46 separable from, or merely link (or bind by name) to the interfaces of,
47 the Work and Derivative Works thereof.
48
49 "Contribution" shall mean any work of authorship, including
50 the original version of the Work and any modifications or additions
51 to that Work or Derivative Works thereof, that is intentionally
52 submitted to Licensor for inclusion in the Work by the copyright owner
53 or by an individual or Legal Entity authorized to submit on behalf of
54 the copyright owner. For the purposes of this definition, "submitted"
55 means any form of electronic, verbal, or written communication sent
56 to the Licensor or its representatives, including but not limited to
57 communication on electronic mailing lists, source code control systems,
58 and issue tracking systems that are managed by, or on behalf of, the
59 Licensor for the purpose of discussing and improving the Work, but
60 excluding communication that is conspicuously marked or otherwise
61 designated in writing by the copyright owner as "Not a Contribution."
62
63 "Contributor" shall mean Licensor and any individual or Legal Entity
64 on behalf of whom a Contribution has been received by Licensor and
65 subsequently incorporated within the Work.
66
67 2. Grant of Copyright License. Subject to the terms and conditions of
68 this License, each Contributor hereby grants to You a perpetual,
69 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 copyright license to reproduce, prepare Derivative Works of,
71 publicly display, publicly perform, sublicense, and distribute the
72 Work and such Derivative Works in Source or Object form.
73
74 3. Grant of Patent License. Subject to the terms and conditions of
75 this License, each Contributor hereby grants to You a perpetual,
76 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 (except as stated in this section) patent license to make, have made,
78 use, offer to sell, sell, import, and otherwise transfer the Work,
79 where such license applies only to those patent claims licensable
80 by such Contributor that are necessarily infringed by their
81 Contribution(s) alone or by combination of their Contribution(s)
82 with the Work to which such Contribution(s) was submitted. If You
83 institute patent litigation against any entity (including a
84 cross-claim or counterclaim in a lawsuit) alleging that the Work
85 or a Contribution incorporated within the Work constitutes direct
86 or contributory patent infringement, then any patent licenses
87 granted to You under this License for that Work shall terminate
88 as of the date such litigation is filed.
89
90 4. Redistribution. You may reproduce and distribute copies of the
91 Work or Derivative Works thereof in any medium, with or without
92 modifications, and in Source or Object form, provided that You
93 meet the following conditions:
94
95 (a) You must give any other recipients of the Work or
96 Derivative Works a copy of this License; and
97
98 (b) You must cause any modified files to carry prominent notices
99 stating that You changed the files; and
100
101 (c) You must retain, in the Source form of any Derivative Works
102 that You distribute, all copyright, patent, trademark, and
103 attribution notices from the Source form of the Work,
104 excluding those notices that do not pertain to any part of
105 the Derivative Works; and
106
107 (d) If the Work includes a "NOTICE" text file as part of its
108 distribution, then any Derivative Works that You distribute must
109 include a readable copy of the attribution notices contained
110 within such NOTICE file, excluding those notices that do not
111 pertain to any part of the Derivative Works, in at least one
112 of the following places: within a NOTICE text file distributed
113 as part of the Derivative Works; within the Source form or
114 documentation, if provided along with the Derivative Works; or,
115 within a display generated by the Derivative Works, if and
116 wherever such third-party notices normally appear. The contents
117 of the NOTICE file are for informational purposes only and
118 do not modify the License. You may add Your own attribution
119 notices within Derivative Works that You distribute, alongside
120 or as an addendum to the NOTICE text from the Work, provided
121 that such additional attribution notices cannot be construed
122 as modifying the License.
123
124 You may add Your own copyright statement to Your modifications and
125 may provide additional or different license terms and conditions
126 for use, reproduction, or distribution of Your modifications, or
127 for any such Derivative Works as a whole, provided Your use,
128 reproduction, and distribution of the Work otherwise complies with
129 the conditions stated in this License.
130
131 5. Submission of Contributions. Unless You explicitly state otherwise,
132 any Contribution intentionally submitted for inclusion in the Work
133 by You to the Licensor shall be under the terms and conditions of
134 this License, without any additional terms or conditions.
135 Notwithstanding the above, nothing herein shall supersede or modify
136 the terms of any separate license agreement you may have executed
137 with Licensor regarding such Contributions.
138
139 6. Trademarks. This License does not grant permission to use the trade
140 names, trademarks, service marks, or product names of the Licensor,
141 except as required for reasonable and customary use in describing the
142 origin of the Work and reproducing the content of the NOTICE file.
143
144 7. Disclaimer of Warranty. Unless required by applicable law or
145 agreed to in writing, Licensor provides the Work (and each
146 Contributor provides its Contributions) on an "AS IS" BASIS,
147 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 implied, including, without limitation, any warranties or conditions
149 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 PARTICULAR PURPOSE. You are solely responsible for determining the
151 appropriateness of using or redistributing the Work and assume any
152 risks associated with Your exercise of permissions under this License.
153
154 8. Limitation of Liability. In no event and under no legal theory,
155 whether in tort (including negligence), contract, or otherwise,
156 unless required by applicable law (such as deliberate and grossly
157 negligent acts) or agreed to in writing, shall any Contributor be
158 liable to You for damages, including any direct, indirect, special,
159 incidental, or consequential damages of any character arising as a
160 result of this License or out of the use or inability to use the
161 Work (including but not limited to damages for loss of goodwill,
162 work stoppage, computer failure or malfunction, or any and all
163 other commercial damages or losses), even if such Contributor
164 has been advised of the possibility of such damages.
165
166 9. Accepting Warranty or Additional Liability. While redistributing
167 the Work or Derivative Works thereof, You may choose to offer,
168 and charge a fee for, acceptance of support, warranty, indemnity,
169 or other liability obligations and/or rights consistent with this
170 License. However, in accepting such obligations, You may act only
171 on Your own behalf and on Your sole responsibility, not on behalf
172 of any other Contributor, and only if You agree to indemnify,
173 defend, and hold each Contributor harmless for any liability
174 incurred by, or claims asserted against, such Contributor by reason
175 of your accepting any such warranty or additional liability.
176
177 END OF TERMS AND CONDITIONS
178
179 APPENDIX: How to apply the Apache License to your work.
180
181 To apply the Apache License to your work, attach the following
182 boilerplate notice, with the fields enclosed by brackets "[]"
183 replaced with your own identifying information. (Don't include
184 the brackets!) The text should be enclosed in the appropriate
185 comment syntax for the file format. We also recommend that a
186 file or class name and description of purpose be included on the
187 same "printed page" as the copyright notice for easier
188 identification within third-party archives.
189
190 Copyright [yyyy] [name of copyright owner]
191
192 Licensed under the Apache License, Version 2.0 (the "License");
193 you may not use this file except in compliance with the License.
194 You may obtain a copy of the License at
195
196 http://www.apache.org/licenses/LICENSE-2.0
197
198 Unless required by applicable law or agreed to in writing, software
199 distributed under the License is distributed on an "AS IS" BASIS,
200 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 See the License for the specific language governing permissions and
202 limitations under the License.
diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go
new file mode 100644
index 0000000..8867ae7
--- /dev/null
+++ b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go
@@ -0,0 +1,143 @@
1// Code generated by protoc-gen-go. DO NOT EDIT.
2// source: google/rpc/status.proto
3
4/*
5Package status is a generated protocol buffer package.
6
7It is generated from these files:
8 google/rpc/status.proto
9
10It has these top-level messages:
11 Status
12*/
13package status
14
15import proto "github.com/golang/protobuf/proto"
16import fmt "fmt"
17import math "math"
18import google_protobuf "github.com/golang/protobuf/ptypes/any"
19
20// Reference imports to suppress errors if they are not otherwise used.
21var _ = proto.Marshal
22var _ = fmt.Errorf
23var _ = math.Inf
24
25// This is a compile-time assertion to ensure that this generated file
26// is compatible with the proto package it is being compiled against.
27// A compilation error at this line likely means your copy of the
28// proto package needs to be updated.
29const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
30
31// The `Status` type defines a logical error model that is suitable for different
32// programming environments, including REST APIs and RPC APIs. It is used by
33// [gRPC](https://github.com/grpc). The error model is designed to be:
34//
35// - Simple to use and understand for most users
36// - Flexible enough to meet unexpected needs
37//
38// # Overview
39//
40// The `Status` message contains three pieces of data: error code, error message,
41// and error details. The error code should be an enum value of
42// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The
43// error message should be a developer-facing English message that helps
44// developers *understand* and *resolve* the error. If a localized user-facing
45// error message is needed, put the localized message in the error details or
46// localize it in the client. The optional error details may contain arbitrary
47// information about the error. There is a predefined set of error detail types
48// in the package `google.rpc` that can be used for common error conditions.
49//
50// # Language mapping
51//
52// The `Status` message is the logical representation of the error model, but it
53// is not necessarily the actual wire format. When the `Status` message is
54// exposed in different client libraries and different wire protocols, it can be
55// mapped differently. For example, it will likely be mapped to some exceptions
56// in Java, but more likely mapped to some error codes in C.
57//
58// # Other uses
59//
60// The error model and the `Status` message can be used in a variety of
61// environments, either with or without APIs, to provide a
62// consistent developer experience across different environments.
63//
64// Example uses of this error model include:
65//
66// - Partial errors. If a service needs to return partial errors to the client,
67// it may embed the `Status` in the normal response to indicate the partial
68// errors.
69//
70// - Workflow errors. A typical workflow has multiple steps. Each step may
71// have a `Status` message for error reporting.
72//
73// - Batch operations. If a client uses batch request and batch response, the
74// `Status` message should be used directly inside batch response, one for
75// each error sub-response.
76//
77// - Asynchronous operations. If an API call embeds asynchronous operation
78// results in its response, the status of those operations should be
79// represented directly using the `Status` message.
80//
81// - Logging. If some API errors are stored in logs, the message `Status` could
82// be used directly after any stripping needed for security/privacy reasons.
83type Status struct {
84 // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
85 Code int32 `protobuf:"varint,1,opt,name=code" json:"code,omitempty"`
86 // A developer-facing error message, which should be in English. Any
87 // user-facing error message should be localized and sent in the
88 // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
89 Message string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"`
90 // A list of messages that carry the error details. There is a common set of
91 // message types for APIs to use.
92 Details []*google_protobuf.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"`
93}
94
95func (m *Status) Reset() { *m = Status{} }
96func (m *Status) String() string { return proto.CompactTextString(m) }
97func (*Status) ProtoMessage() {}
98func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
99
100func (m *Status) GetCode() int32 {
101 if m != nil {
102 return m.Code
103 }
104 return 0
105}
106
107func (m *Status) GetMessage() string {
108 if m != nil {
109 return m.Message
110 }
111 return ""
112}
113
114func (m *Status) GetDetails() []*google_protobuf.Any {
115 if m != nil {
116 return m.Details
117 }
118 return nil
119}
120
121func init() {
122 proto.RegisterType((*Status)(nil), "google.rpc.Status")
123}
124
125func init() { proto.RegisterFile("google/rpc/status.proto", fileDescriptor0) }
126
127var fileDescriptor0 = []byte{
128 // 209 bytes of a gzipped FileDescriptorProto
129 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0xcf, 0xcf, 0x4f,
130 0xcf, 0x49, 0xd5, 0x2f, 0x2a, 0x48, 0xd6, 0x2f, 0x2e, 0x49, 0x2c, 0x29, 0x2d, 0xd6, 0x2b, 0x28,
131 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x82, 0x48, 0xe8, 0x15, 0x15, 0x24, 0x4b, 0x49, 0x42, 0x15, 0x81,
132 0x65, 0x92, 0x4a, 0xd3, 0xf4, 0x13, 0xf3, 0x2a, 0x21, 0xca, 0x94, 0xd2, 0xb8, 0xd8, 0x82, 0xc1,
133 0xda, 0x84, 0x84, 0xb8, 0x58, 0x92, 0xf3, 0x53, 0x52, 0x25, 0x18, 0x15, 0x18, 0x35, 0x58, 0x83,
134 0xc0, 0x6c, 0x21, 0x09, 0x2e, 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0xf4, 0x54, 0x09, 0x26, 0x05,
135 0x46, 0x0d, 0xce, 0x20, 0x18, 0x57, 0x48, 0x8f, 0x8b, 0x3d, 0x25, 0xb5, 0x24, 0x31, 0x33, 0xa7,
136 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x44, 0x0f, 0x6a, 0x21, 0xcc, 0x12, 0x3d, 0xc7,
137 0xbc, 0xca, 0x20, 0x98, 0x22, 0xa7, 0x38, 0x2e, 0xbe, 0xe4, 0xfc, 0x5c, 0x3d, 0x84, 0xa3, 0x9c,
138 0xb8, 0x21, 0xf6, 0x06, 0x80, 0x94, 0x07, 0x30, 0x46, 0x99, 0x43, 0xa5, 0xd2, 0xf3, 0x73, 0x12,
139 0xf3, 0xd2, 0xf5, 0xf2, 0x8b, 0xd2, 0xf5, 0xd3, 0x53, 0xf3, 0xc0, 0x86, 0xe9, 0x43, 0xa4, 0x12,
140 0x0b, 0x32, 0x8b, 0x91, 0xfc, 0x69, 0x0d, 0xa1, 0x16, 0x31, 0x31, 0x07, 0x05, 0x38, 0x27, 0xb1,
141 0x81, 0x55, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa4, 0x53, 0xf0, 0x7c, 0x10, 0x01, 0x00,
142 0x00,
143}
diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml
new file mode 100644
index 0000000..88a785d
--- /dev/null
+++ b/vendor/google.golang.org/grpc/.travis.yml
@@ -0,0 +1,21 @@
1language: go
2
3go:
4 - 1.6.x
5 - 1.7.x
6 - 1.8.x
7
8go_import_path: google.golang.org/grpc
9
10before_install:
11 - if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then go get -u github.com/golang/lint/golint honnef.co/go/tools/cmd/staticcheck; fi
12 - go get -u golang.org/x/tools/cmd/goimports github.com/axw/gocov/gocov github.com/mattn/goveralls golang.org/x/tools/cmd/cover
13
14script:
15 - 'set -o pipefail && git ls-files "*.go" | xargs grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)\|DO NOT EDIT" 2>&1 | tee /dev/stderr | (! read)'
16 - 'set -o pipefail && gofmt -s -d -l . 2>&1 | tee /dev/stderr | (! read)'
17 - 'set -o pipefail && goimports -l . 2>&1 | tee /dev/stderr | (! read)'
18 - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then ! golint ./... | grep -vE "(_mock|_string|\.pb)\.go:"; fi'
19 - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then ! go tool vet -all . 2>&1 | grep -vF .pb.go:; fi' # https://github.com/golang/protobuf/issues/214
20 - make test testrace
21 - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then staticcheck -ignore google.golang.org/grpc/transport/transport_test.go:SA2002 ./...; fi' # TODO(menghanl): fix these
diff --git a/vendor/google.golang.org/grpc/AUTHORS b/vendor/google.golang.org/grpc/AUTHORS
new file mode 100644
index 0000000..e491a9e
--- /dev/null
+++ b/vendor/google.golang.org/grpc/AUTHORS
@@ -0,0 +1 @@
Google Inc.
diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md
new file mode 100644
index 0000000..a5c6e06
--- /dev/null
+++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md
@@ -0,0 +1,32 @@
1# How to contribute
2
3We definitely welcome your patches and contributions to gRPC!
4
5If you are new to github, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/)
6
7## Legal requirements
8
9In order to protect both you and ourselves, you will need to sign the
10[Contributor License Agreement](https://cla.developers.google.com/clas).
11
12## Guidelines for Pull Requests
13How to get your contributions merged smoothly and quickly.
14
15- Create **small PRs** that are narrowly focused on **addressing a single concern**. We often times receive PRs that are trying to fix several things at a time, but only one fix is considered acceptable, nothing gets merged and both author's & review's time is wasted. Create more PRs to address different concerns and everyone will be happy.
16
17- For speculative changes, consider opening an issue and discussing it first. If you are suggesting a behavioral or API change, consider starting with a [gRFC proposal](https://github.com/grpc/proposal).
18
19- Provide a good **PR description** as a record of **what** change is being made and **why** it was made. Link to a github issue if it exists.
20
21- Don't fix code style and formatting unless you are already changing that line to address an issue. PRs with irrelevant changes won't be merged. If you do want to fix formatting or style, do that in a separate PR.
22
23- Unless your PR is trivial, you should expect there will be reviewer comments that you'll need to address before merging. We expect you to be reasonably responsive to those comments, otherwise the PR will be closed after 2-3 weeks of inactivity.
24
25- Maintain **clean commit history** and use **meaningful commit messages**. PRs with messy commit history are difficult to review and won't be merged. Use `rebase -i upstream/master` to curate your commit history and/or to bring in latest changes from master (but avoid rebasing in the middle of a code review).
26
27- Keep your PR up to date with upstream/master (if there are merge conflicts, we can't really merge your change).
28
29- **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on.
30
31- Exceptions to the rules can be made if there's a compelling reason for doing so.
32
diff --git a/vendor/google.golang.org/grpc/LICENSE b/vendor/google.golang.org/grpc/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/vendor/google.golang.org/grpc/LICENSE
@@ -0,0 +1,202 @@
1
2 Apache License
3 Version 2.0, January 2004
4 http://www.apache.org/licenses/
5
6 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
8 1. Definitions.
9
10 "License" shall mean the terms and conditions for use, reproduction,
11 and distribution as defined by Sections 1 through 9 of this document.
12
13 "Licensor" shall mean the copyright owner or entity authorized by
14 the copyright owner that is granting the License.
15
16 "Legal Entity" shall mean the union of the acting entity and all
17 other entities that control, are controlled by, or are under common
18 control with that entity. For the purposes of this definition,
19 "control" means (i) the power, direct or indirect, to cause the
20 direction or management of such entity, whether by contract or
21 otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 outstanding shares, or (iii) beneficial ownership of such entity.
23
24 "You" (or "Your") shall mean an individual or Legal Entity
25 exercising permissions granted by this License.
26
27 "Source" form shall mean the preferred form for making modifications,
28 including but not limited to software source code, documentation
29 source, and configuration files.
30
31 "Object" form shall mean any form resulting from mechanical
32 transformation or translation of a Source form, including but
33 not limited to compiled object code, generated documentation,
34 and conversions to other media types.
35
36 "Work" shall mean the work of authorship, whether in Source or
37 Object form, made available under the License, as indicated by a
38 copyright notice that is included in or attached to the work
39 (an example is provided in the Appendix below).
40
41 "Derivative Works" shall mean any work, whether in Source or Object
42 form, that is based on (or derived from) the Work and for which the
43 editorial revisions, annotations, elaborations, or other modifications
44 represent, as a whole, an original work of authorship. For the purposes
45 of this License, Derivative Works shall not include works that remain
46 separable from, or merely link (or bind by name) to the interfaces of,
47 the Work and Derivative Works thereof.
48
49 "Contribution" shall mean any work of authorship, including
50 the original version of the Work and any modifications or additions
51 to that Work or Derivative Works thereof, that is intentionally
52 submitted to Licensor for inclusion in the Work by the copyright owner
53 or by an individual or Legal Entity authorized to submit on behalf of
54 the copyright owner. For the purposes of this definition, "submitted"
55 means any form of electronic, verbal, or written communication sent
56 to the Licensor or its representatives, including but not limited to
57 communication on electronic mailing lists, source code control systems,
58 and issue tracking systems that are managed by, or on behalf of, the
59 Licensor for the purpose of discussing and improving the Work, but
60 excluding communication that is conspicuously marked or otherwise
61 designated in writing by the copyright owner as "Not a Contribution."
62
63 "Contributor" shall mean Licensor and any individual or Legal Entity
64 on behalf of whom a Contribution has been received by Licensor and
65 subsequently incorporated within the Work.
66
67 2. Grant of Copyright License. Subject to the terms and conditions of
68 this License, each Contributor hereby grants to You a perpetual,
69 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 copyright license to reproduce, prepare Derivative Works of,
71 publicly display, publicly perform, sublicense, and distribute the
72 Work and such Derivative Works in Source or Object form.
73
74 3. Grant of Patent License. Subject to the terms and conditions of
75 this License, each Contributor hereby grants to You a perpetual,
76 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 (except as stated in this section) patent license to make, have made,
78 use, offer to sell, sell, import, and otherwise transfer the Work,
79 where such license applies only to those patent claims licensable
80 by such Contributor that are necessarily infringed by their
81 Contribution(s) alone or by combination of their Contribution(s)
82 with the Work to which such Contribution(s) was submitted. If You
83 institute patent litigation against any entity (including a
84 cross-claim or counterclaim in a lawsuit) alleging that the Work
85 or a Contribution incorporated within the Work constitutes direct
86 or contributory patent infringement, then any patent licenses
87 granted to You under this License for that Work shall terminate
88 as of the date such litigation is filed.
89
90 4. Redistribution. You may reproduce and distribute copies of the
91 Work or Derivative Works thereof in any medium, with or without
92 modifications, and in Source or Object form, provided that You
93 meet the following conditions:
94
95 (a) You must give any other recipients of the Work or
96 Derivative Works a copy of this License; and
97
98 (b) You must cause any modified files to carry prominent notices
99 stating that You changed the files; and
100
101 (c) You must retain, in the Source form of any Derivative Works
102 that You distribute, all copyright, patent, trademark, and
103 attribution notices from the Source form of the Work,
104 excluding those notices that do not pertain to any part of
105 the Derivative Works; and
106
107 (d) If the Work includes a "NOTICE" text file as part of its
108 distribution, then any Derivative Works that You distribute must
109 include a readable copy of the attribution notices contained
110 within such NOTICE file, excluding those notices that do not
111 pertain to any part of the Derivative Works, in at least one
112 of the following places: within a NOTICE text file distributed
113 as part of the Derivative Works; within the Source form or
114 documentation, if provided along with the Derivative Works; or,
115 within a display generated by the Derivative Works, if and
116 wherever such third-party notices normally appear. The contents
117 of the NOTICE file are for informational purposes only and
118 do not modify the License. You may add Your own attribution
119 notices within Derivative Works that You distribute, alongside
120 or as an addendum to the NOTICE text from the Work, provided
121 that such additional attribution notices cannot be construed
122 as modifying the License.
123
124 You may add Your own copyright statement to Your modifications and
125 may provide additional or different license terms and conditions
126 for use, reproduction, or distribution of Your modifications, or
127 for any such Derivative Works as a whole, provided Your use,
128 reproduction, and distribution of the Work otherwise complies with
129 the conditions stated in this License.
130
131 5. Submission of Contributions. Unless You explicitly state otherwise,
132 any Contribution intentionally submitted for inclusion in the Work
133 by You to the Licensor shall be under the terms and conditions of
134 this License, without any additional terms or conditions.
135 Notwithstanding the above, nothing herein shall supersede or modify
136 the terms of any separate license agreement you may have executed
137 with Licensor regarding such Contributions.
138
139 6. Trademarks. This License does not grant permission to use the trade
140 names, trademarks, service marks, or product names of the Licensor,
141 except as required for reasonable and customary use in describing the
142 origin of the Work and reproducing the content of the NOTICE file.
143
144 7. Disclaimer of Warranty. Unless required by applicable law or
145 agreed to in writing, Licensor provides the Work (and each
146 Contributor provides its Contributions) on an "AS IS" BASIS,
147 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 implied, including, without limitation, any warranties or conditions
149 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 PARTICULAR PURPOSE. You are solely responsible for determining the
151 appropriateness of using or redistributing the Work and assume any
152 risks associated with Your exercise of permissions under this License.
153
154 8. Limitation of Liability. In no event and under no legal theory,
155 whether in tort (including negligence), contract, or otherwise,
156 unless required by applicable law (such as deliberate and grossly
157 negligent acts) or agreed to in writing, shall any Contributor be
158 liable to You for damages, including any direct, indirect, special,
159 incidental, or consequential damages of any character arising as a
160 result of this License or out of the use or inability to use the
161 Work (including but not limited to damages for loss of goodwill,
162 work stoppage, computer failure or malfunction, or any and all
163 other commercial damages or losses), even if such Contributor
164 has been advised of the possibility of such damages.
165
166 9. Accepting Warranty or Additional Liability. While redistributing
167 the Work or Derivative Works thereof, You may choose to offer,
168 and charge a fee for, acceptance of support, warranty, indemnity,
169 or other liability obligations and/or rights consistent with this
170 License. However, in accepting such obligations, You may act only
171 on Your own behalf and on Your sole responsibility, not on behalf
172 of any other Contributor, and only if You agree to indemnify,
173 defend, and hold each Contributor harmless for any liability
174 incurred by, or claims asserted against, such Contributor by reason
175 of your accepting any such warranty or additional liability.
176
177 END OF TERMS AND CONDITIONS
178
179 APPENDIX: How to apply the Apache License to your work.
180
181 To apply the Apache License to your work, attach the following
182 boilerplate notice, with the fields enclosed by brackets "[]"
183 replaced with your own identifying information. (Don't include
184 the brackets!) The text should be enclosed in the appropriate
185 comment syntax for the file format. We also recommend that a
186 file or class name and description of purpose be included on the
187 same "printed page" as the copyright notice for easier
188 identification within third-party archives.
189
190 Copyright [yyyy] [name of copyright owner]
191
192 Licensed under the Apache License, Version 2.0 (the "License");
193 you may not use this file except in compliance with the License.
194 You may obtain a copy of the License at
195
196 http://www.apache.org/licenses/LICENSE-2.0
197
198 Unless required by applicable law or agreed to in writing, software
199 distributed under the License is distributed on an "AS IS" BASIS,
200 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 See the License for the specific language governing permissions and
202 limitations under the License.
diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile
new file mode 100644
index 0000000..03bb01f
--- /dev/null
+++ b/vendor/google.golang.org/grpc/Makefile
@@ -0,0 +1,52 @@
1all: test testrace
2
3deps:
4 go get -d -v google.golang.org/grpc/...
5
6updatedeps:
7 go get -d -v -u -f google.golang.org/grpc/...
8
9testdeps:
10 go get -d -v -t google.golang.org/grpc/...
11
12updatetestdeps:
13 go get -d -v -t -u -f google.golang.org/grpc/...
14
15build: deps
16 go build google.golang.org/grpc/...
17
18proto:
19 @ if ! which protoc > /dev/null; then \
20 echo "error: protoc not installed" >&2; \
21 exit 1; \
22 fi
23 go get -u -v github.com/golang/protobuf/protoc-gen-go
24 # use $$dir as the root for all proto files in the same directory
25 for dir in $$(git ls-files '*.proto' | xargs -n1 dirname | uniq); do \
26 protoc -I $$dir --go_out=plugins=grpc:$$dir $$dir/*.proto; \
27 done
28
29test: testdeps
30 go test -v -cpu 1,4 google.golang.org/grpc/...
31
32testrace: testdeps
33 go test -v -race -cpu 1,4 google.golang.org/grpc/...
34
35clean:
36 go clean -i google.golang.org/grpc/...
37
38coverage: testdeps
39 ./coverage.sh --coveralls
40
41.PHONY: \
42 all \
43 deps \
44 updatedeps \
45 testdeps \
46 updatetestdeps \
47 build \
48 proto \
49 test \
50 testrace \
51 clean \
52 coverage
diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md
new file mode 100644
index 0000000..72c7325
--- /dev/null
+++ b/vendor/google.golang.org/grpc/README.md
@@ -0,0 +1,45 @@
1# gRPC-Go
2
3[![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc)
4
5The Go implementation of [gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start: Go](https://grpc.io/docs/quickstart/go.html) guide.
6
7Installation
8------------
9
10To install this package, you need to install Go and setup your Go workspace on your computer. The simplest way to install the library is to run:
11
12```
13$ go get google.golang.org/grpc
14```
15
16Prerequisites
17-------------
18
19This requires Go 1.6 or later.
20
21Constraints
22-----------
23The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](http://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants.
24
25Documentation
26-------------
27See [API documentation](https://godoc.org/google.golang.org/grpc) for package and API descriptions and find examples in the [examples directory](examples/).
28
29Performance
30-----------
31See the current benchmarks for some of the languages supported in [this dashboard](https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5652536396611584&widget=490377658&container=1286539696).
32
33Status
34------
35General Availability [Google Cloud Platform Launch Stages](https://cloud.google.com/terms/launch-stages).
36
37FAQ
38---
39
40#### Compiling error, undefined: grpc.SupportPackageIsVersion
41
42Please update proto package, gRPC package and rebuild the proto files:
43 - `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`
44 - `go get -u google.golang.org/grpc`
45 - `protoc --go_out=plugins=grpc:. *.proto`
diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go
new file mode 100644
index 0000000..090fbe8
--- /dev/null
+++ b/vendor/google.golang.org/grpc/backoff.go
@@ -0,0 +1,98 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "math/rand"
23 "time"
24)
25
26// DefaultBackoffConfig uses values specified for backoff in
27// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
28var (
29 DefaultBackoffConfig = BackoffConfig{
30 MaxDelay: 120 * time.Second,
31 baseDelay: 1.0 * time.Second,
32 factor: 1.6,
33 jitter: 0.2,
34 }
35)
36
37// backoffStrategy defines the methodology for backing off after a grpc
38// connection failure.
39//
40// This is unexported until the gRPC project decides whether or not to allow
41// alternative backoff strategies. Once a decision is made, this type and its
42// method may be exported.
43type backoffStrategy interface {
44 // backoff returns the amount of time to wait before the next retry given
45 // the number of consecutive failures.
46 backoff(retries int) time.Duration
47}
48
49// BackoffConfig defines the parameters for the default gRPC backoff strategy.
50type BackoffConfig struct {
51 // MaxDelay is the upper bound of backoff delay.
52 MaxDelay time.Duration
53
54 // TODO(stevvooe): The following fields are not exported, as allowing
55 // changes would violate the current gRPC specification for backoff. If
56 // gRPC decides to allow more interesting backoff strategies, these fields
57 // may be opened up in the future.
58
59 // baseDelay is the amount of time to wait before retrying after the first
60 // failure.
61 baseDelay time.Duration
62
63 // factor is applied to the backoff after each retry.
64 factor float64
65
66 // jitter provides a range to randomize backoff delays.
67 jitter float64
68}
69
70func setDefaults(bc *BackoffConfig) {
71 md := bc.MaxDelay
72 *bc = DefaultBackoffConfig
73
74 if md > 0 {
75 bc.MaxDelay = md
76 }
77}
78
79func (bc BackoffConfig) backoff(retries int) time.Duration {
80 if retries == 0 {
81 return bc.baseDelay
82 }
83 backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay)
84 for backoff < max && retries > 0 {
85 backoff *= bc.factor
86 retries--
87 }
88 if backoff > max {
89 backoff = max
90 }
91 // Randomize backoff delays so that if a cluster of requests start at
92 // the same time, they won't operate in lockstep.
93 backoff *= 1 + bc.jitter*(rand.Float64()*2-1)
94 if backoff < 0 {
95 return 0
96 }
97 return time.Duration(backoff)
98}
diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go
new file mode 100644
index 0000000..cde472c
--- /dev/null
+++ b/vendor/google.golang.org/grpc/balancer.go
@@ -0,0 +1,397 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "fmt"
23 "net"
24 "sync"
25
26 "golang.org/x/net/context"
27 "google.golang.org/grpc/codes"
28 "google.golang.org/grpc/credentials"
29 "google.golang.org/grpc/grpclog"
30 "google.golang.org/grpc/naming"
31)
32
33// Address represents a server the client connects to.
34// This is the EXPERIMENTAL API and may be changed or extended in the future.
35type Address struct {
36 // Addr is the server address on which a connection will be established.
37 Addr string
38 // Metadata is the information associated with Addr, which may be used
39 // to make load balancing decision.
40 Metadata interface{}
41}
42
43// BalancerConfig specifies the configurations for Balancer.
44type BalancerConfig struct {
45 // DialCreds is the transport credential the Balancer implementation can
46 // use to dial to a remote load balancer server. The Balancer implementations
47 // can ignore this if it does not need to talk to another party securely.
48 DialCreds credentials.TransportCredentials
49 // Dialer is the custom dialer the Balancer implementation can use to dial
50 // to a remote load balancer server. The Balancer implementations
51 // can ignore this if it doesn't need to talk to remote balancer.
52 Dialer func(context.Context, string) (net.Conn, error)
53}
54
55// BalancerGetOptions configures a Get call.
56// This is the EXPERIMENTAL API and may be changed or extended in the future.
57type BalancerGetOptions struct {
58 // BlockingWait specifies whether Get should block when there is no
59 // connected address.
60 BlockingWait bool
61}
62
63// Balancer chooses network addresses for RPCs.
64// This is the EXPERIMENTAL API and may be changed or extended in the future.
65type Balancer interface {
66 // Start does the initialization work to bootstrap a Balancer. For example,
67 // this function may start the name resolution and watch the updates. It will
68 // be called when dialing.
69 Start(target string, config BalancerConfig) error
70 // Up informs the Balancer that gRPC has a connection to the server at
71 // addr. It returns down which is called once the connection to addr gets
72 // lost or closed.
73 // TODO: It is not clear how to construct and take advantage of the meaningful error
74 // parameter for down. Need realistic demands to guide.
75 Up(addr Address) (down func(error))
76 // Get gets the address of a server for the RPC corresponding to ctx.
77 // i) If it returns a connected address, gRPC internals issues the RPC on the
78 // connection to this address;
79 // ii) If it returns an address on which the connection is under construction
80 // (initiated by Notify(...)) but not connected, gRPC internals
81 // * fails RPC if the RPC is fail-fast and connection is in the TransientFailure or
82 // Shutdown state;
83 // or
84 // * issues RPC on the connection otherwise.
85 // iii) If it returns an address on which the connection does not exist, gRPC
86 // internals treats it as an error and will fail the corresponding RPC.
87 //
88 // Therefore, the following is the recommended rule when writing a custom Balancer.
89 // If opts.BlockingWait is true, it should return a connected address or
90 // block if there is no connected address. It should respect the timeout or
91 // cancellation of ctx when blocking. If opts.BlockingWait is false (for fail-fast
92 // RPCs), it should return an address it has notified via Notify(...) immediately
93 // instead of blocking.
94 //
95 // The function returns put which is called once the rpc has completed or failed.
96 // put can collect and report RPC stats to a remote load balancer.
97 //
98 // This function should only return the errors Balancer cannot recover by itself.
99 // gRPC internals will fail the RPC if an error is returned.
100 Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error)
101 // Notify returns a channel that is used by gRPC internals to watch the addresses
102 // gRPC needs to connect. The addresses might be from a name resolver or remote
103 // load balancer. gRPC internals will compare it with the existing connected
104 // addresses. If the address Balancer notified is not in the existing connected
105 // addresses, gRPC starts to connect the address. If an address in the existing
106 // connected addresses is not in the notification list, the corresponding connection
107 // is shutdown gracefully. Otherwise, there are no operations to take. Note that
108 // the Address slice must be the full list of the Addresses which should be connected.
109 // It is NOT delta.
110 Notify() <-chan []Address
111 // Close shuts down the balancer.
112 Close() error
113}
114
115// downErr implements net.Error. It is constructed by gRPC internals and passed to the down
116// call of Balancer.
117type downErr struct {
118 timeout bool
119 temporary bool
120 desc string
121}
122
123func (e downErr) Error() string { return e.desc }
124func (e downErr) Timeout() bool { return e.timeout }
125func (e downErr) Temporary() bool { return e.temporary }
126
127func downErrorf(timeout, temporary bool, format string, a ...interface{}) downErr {
128 return downErr{
129 timeout: timeout,
130 temporary: temporary,
131 desc: fmt.Sprintf(format, a...),
132 }
133}
134
135// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch
136// the name resolution updates and updates the addresses available correspondingly.
137func RoundRobin(r naming.Resolver) Balancer {
138 return &roundRobin{r: r}
139}
140
141type addrInfo struct {
142 addr Address
143 connected bool
144}
145
146type roundRobin struct {
147 r naming.Resolver
148 w naming.Watcher
149 addrs []*addrInfo // all the addresses the client should potentially connect
150 mu sync.Mutex
151 addrCh chan []Address // the channel to notify gRPC internals the list of addresses the client should connect to.
152 next int // index of the next address to return for Get()
153 waitCh chan struct{} // the channel to block when there is no connected address available
154 done bool // The Balancer is closed.
155}
156
157func (rr *roundRobin) watchAddrUpdates() error {
158 updates, err := rr.w.Next()
159 if err != nil {
160 grpclog.Warningf("grpc: the naming watcher stops working due to %v.", err)
161 return err
162 }
163 rr.mu.Lock()
164 defer rr.mu.Unlock()
165 for _, update := range updates {
166 addr := Address{
167 Addr: update.Addr,
168 Metadata: update.Metadata,
169 }
170 switch update.Op {
171 case naming.Add:
172 var exist bool
173 for _, v := range rr.addrs {
174 if addr == v.addr {
175 exist = true
176 grpclog.Infoln("grpc: The name resolver wanted to add an existing address: ", addr)
177 break
178 }
179 }
180 if exist {
181 continue
182 }
183 rr.addrs = append(rr.addrs, &addrInfo{addr: addr})
184 case naming.Delete:
185 for i, v := range rr.addrs {
186 if addr == v.addr {
187 copy(rr.addrs[i:], rr.addrs[i+1:])
188 rr.addrs = rr.addrs[:len(rr.addrs)-1]
189 break
190 }
191 }
192 default:
193 grpclog.Errorln("Unknown update.Op ", update.Op)
194 }
195 }
196 // Make a copy of rr.addrs and write it onto rr.addrCh so that gRPC internals gets notified.
197 open := make([]Address, len(rr.addrs))
198 for i, v := range rr.addrs {
199 open[i] = v.addr
200 }
201 if rr.done {
202 return ErrClientConnClosing
203 }
204 select {
205 case <-rr.addrCh:
206 default:
207 }
208 rr.addrCh <- open
209 return nil
210}
211
212func (rr *roundRobin) Start(target string, config BalancerConfig) error {
213 rr.mu.Lock()
214 defer rr.mu.Unlock()
215 if rr.done {
216 return ErrClientConnClosing
217 }
218 if rr.r == nil {
219 // If there is no name resolver installed, it is not needed to
220 // do name resolution. In this case, target is added into rr.addrs
221 // as the only address available and rr.addrCh stays nil.
222 rr.addrs = append(rr.addrs, &addrInfo{addr: Address{Addr: target}})
223 return nil
224 }
225 w, err := rr.r.Resolve(target)
226 if err != nil {
227 return err
228 }
229 rr.w = w
230 rr.addrCh = make(chan []Address, 1)
231 go func() {
232 for {
233 if err := rr.watchAddrUpdates(); err != nil {
234 return
235 }
236 }
237 }()
238 return nil
239}
240
241// Up sets the connected state of addr and sends notification if there are pending
242// Get() calls.
243func (rr *roundRobin) Up(addr Address) func(error) {
244 rr.mu.Lock()
245 defer rr.mu.Unlock()
246 var cnt int
247 for _, a := range rr.addrs {
248 if a.addr == addr {
249 if a.connected {
250 return nil
251 }
252 a.connected = true
253 }
254 if a.connected {
255 cnt++
256 }
257 }
258 // addr is only one which is connected. Notify the Get() callers who are blocking.
259 if cnt == 1 && rr.waitCh != nil {
260 close(rr.waitCh)
261 rr.waitCh = nil
262 }
263 return func(err error) {
264 rr.down(addr, err)
265 }
266}
267
268// down unsets the connected state of addr.
269func (rr *roundRobin) down(addr Address, err error) {
270 rr.mu.Lock()
271 defer rr.mu.Unlock()
272 for _, a := range rr.addrs {
273 if addr == a.addr {
274 a.connected = false
275 break
276 }
277 }
278}
279
280// Get returns the next addr in the rotation.
281func (rr *roundRobin) Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) {
282 var ch chan struct{}
283 rr.mu.Lock()
284 if rr.done {
285 rr.mu.Unlock()
286 err = ErrClientConnClosing
287 return
288 }
289
290 if len(rr.addrs) > 0 {
291 if rr.next >= len(rr.addrs) {
292 rr.next = 0
293 }
294 next := rr.next
295 for {
296 a := rr.addrs[next]
297 next = (next + 1) % len(rr.addrs)
298 if a.connected {
299 addr = a.addr
300 rr.next = next
301 rr.mu.Unlock()
302 return
303 }
304 if next == rr.next {
305 // Has iterated all the possible address but none is connected.
306 break
307 }
308 }
309 }
310 if !opts.BlockingWait {
311 if len(rr.addrs) == 0 {
312 rr.mu.Unlock()
313 err = Errorf(codes.Unavailable, "there is no address available")
314 return
315 }
316 // Returns the next addr on rr.addrs for failfast RPCs.
317 addr = rr.addrs[rr.next].addr
318 rr.next++
319 rr.mu.Unlock()
320 return
321 }
322 // Wait on rr.waitCh for non-failfast RPCs.
323 if rr.waitCh == nil {
324 ch = make(chan struct{})
325 rr.waitCh = ch
326 } else {
327 ch = rr.waitCh
328 }
329 rr.mu.Unlock()
330 for {
331 select {
332 case <-ctx.Done():
333 err = ctx.Err()
334 return
335 case <-ch:
336 rr.mu.Lock()
337 if rr.done {
338 rr.mu.Unlock()
339 err = ErrClientConnClosing
340 return
341 }
342
343 if len(rr.addrs) > 0 {
344 if rr.next >= len(rr.addrs) {
345 rr.next = 0
346 }
347 next := rr.next
348 for {
349 a := rr.addrs[next]
350 next = (next + 1) % len(rr.addrs)
351 if a.connected {
352 addr = a.addr
353 rr.next = next
354 rr.mu.Unlock()
355 return
356 }
357 if next == rr.next {
358 // Has iterated all the possible address but none is connected.
359 break
360 }
361 }
362 }
363 // The newly added addr got removed by Down() again.
364 if rr.waitCh == nil {
365 ch = make(chan struct{})
366 rr.waitCh = ch
367 } else {
368 ch = rr.waitCh
369 }
370 rr.mu.Unlock()
371 }
372 }
373}
374
375func (rr *roundRobin) Notify() <-chan []Address {
376 return rr.addrCh
377}
378
379func (rr *roundRobin) Close() error {
380 rr.mu.Lock()
381 defer rr.mu.Unlock()
382 if rr.done {
383 return errBalancerClosed
384 }
385 rr.done = true
386 if rr.w != nil {
387 rr.w.Close()
388 }
389 if rr.waitCh != nil {
390 close(rr.waitCh)
391 rr.waitCh = nil
392 }
393 if rr.addrCh != nil {
394 close(rr.addrCh)
395 }
396 return nil
397}
diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go
new file mode 100644
index 0000000..797190f
--- /dev/null
+++ b/vendor/google.golang.org/grpc/call.go
@@ -0,0 +1,309 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "bytes"
23 "io"
24 "time"
25
26 "golang.org/x/net/context"
27 "golang.org/x/net/trace"
28 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/peer"
30 "google.golang.org/grpc/stats"
31 "google.golang.org/grpc/status"
32 "google.golang.org/grpc/transport"
33)
34
35// recvResponse receives and parses an RPC response.
36// On error, it returns the error and indicates whether the call should be retried.
37//
38// TODO(zhaoq): Check whether the received message sequence is valid.
39// TODO ctx is used for stats collection and processing. It is the context passed from the application.
40func recvResponse(ctx context.Context, dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) (err error) {
41 // Try to acquire header metadata from the server if there is any.
42 defer func() {
43 if err != nil {
44 if _, ok := err.(transport.ConnectionError); !ok {
45 t.CloseStream(stream, err)
46 }
47 }
48 }()
49 c.headerMD, err = stream.Header()
50 if err != nil {
51 return
52 }
53 p := &parser{r: stream}
54 var inPayload *stats.InPayload
55 if dopts.copts.StatsHandler != nil {
56 inPayload = &stats.InPayload{
57 Client: true,
58 }
59 }
60 for {
61 if c.maxReceiveMessageSize == nil {
62 return Errorf(codes.Internal, "callInfo maxReceiveMessageSize field uninitialized(nil)")
63 }
64 if err = recv(p, dopts.codec, stream, dopts.dc, reply, *c.maxReceiveMessageSize, inPayload); err != nil {
65 if err == io.EOF {
66 break
67 }
68 return
69 }
70 }
71 if inPayload != nil && err == io.EOF && stream.Status().Code() == codes.OK {
72 // TODO in the current implementation, inTrailer may be handled before inPayload in some cases.
73 // Fix the order if necessary.
74 dopts.copts.StatsHandler.HandleRPC(ctx, inPayload)
75 }
76 c.trailerMD = stream.Trailer()
77 return nil
78}
79
80// sendRequest writes out various information of an RPC such as Context and Message.
81func sendRequest(ctx context.Context, dopts dialOptions, compressor Compressor, c *callInfo, callHdr *transport.CallHdr, stream *transport.Stream, t transport.ClientTransport, args interface{}, opts *transport.Options) (err error) {
82 defer func() {
83 if err != nil {
84 // If err is connection error, t will be closed, no need to close stream here.
85 if _, ok := err.(transport.ConnectionError); !ok {
86 t.CloseStream(stream, err)
87 }
88 }
89 }()
90 var (
91 cbuf *bytes.Buffer
92 outPayload *stats.OutPayload
93 )
94 if compressor != nil {
95 cbuf = new(bytes.Buffer)
96 }
97 if dopts.copts.StatsHandler != nil {
98 outPayload = &stats.OutPayload{
99 Client: true,
100 }
101 }
102 outBuf, err := encode(dopts.codec, args, compressor, cbuf, outPayload)
103 if err != nil {
104 return err
105 }
106 if c.maxSendMessageSize == nil {
107 return Errorf(codes.Internal, "callInfo maxSendMessageSize field uninitialized(nil)")
108 }
109 if len(outBuf) > *c.maxSendMessageSize {
110 return Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(outBuf), *c.maxSendMessageSize)
111 }
112 err = t.Write(stream, outBuf, opts)
113 if err == nil && outPayload != nil {
114 outPayload.SentTime = time.Now()
115 dopts.copts.StatsHandler.HandleRPC(ctx, outPayload)
116 }
117 // t.NewStream(...) could lead to an early rejection of the RPC (e.g., the service/method
118 // does not exist.) so that t.Write could get io.EOF from wait(...). Leave the following
119 // recvResponse to get the final status.
120 if err != nil && err != io.EOF {
121 return err
122 }
123 // Sent successfully.
124 return nil
125}
126
127// Invoke sends the RPC request on the wire and returns after response is received.
128// Invoke is called by generated code. Also users can call Invoke directly when it
129// is really needed in their use cases.
130func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) error {
131 if cc.dopts.unaryInt != nil {
132 return cc.dopts.unaryInt(ctx, method, args, reply, cc, invoke, opts...)
133 }
134 return invoke(ctx, method, args, reply, cc, opts...)
135}
136
137func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (e error) {
138 c := defaultCallInfo
139 mc := cc.GetMethodConfig(method)
140 if mc.WaitForReady != nil {
141 c.failFast = !*mc.WaitForReady
142 }
143
144 if mc.Timeout != nil && *mc.Timeout >= 0 {
145 var cancel context.CancelFunc
146 ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
147 defer cancel()
148 }
149
150 opts = append(cc.dopts.callOptions, opts...)
151 for _, o := range opts {
152 if err := o.before(&c); err != nil {
153 return toRPCErr(err)
154 }
155 }
156 defer func() {
157 for _, o := range opts {
158 o.after(&c)
159 }
160 }()
161
162 c.maxSendMessageSize = getMaxSize(mc.MaxReqSize, c.maxSendMessageSize, defaultClientMaxSendMessageSize)
163 c.maxReceiveMessageSize = getMaxSize(mc.MaxRespSize, c.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
164
165 if EnableTracing {
166 c.traceInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
167 defer c.traceInfo.tr.Finish()
168 c.traceInfo.firstLine.client = true
169 if deadline, ok := ctx.Deadline(); ok {
170 c.traceInfo.firstLine.deadline = deadline.Sub(time.Now())
171 }
172 c.traceInfo.tr.LazyLog(&c.traceInfo.firstLine, false)
173 // TODO(dsymonds): Arrange for c.traceInfo.firstLine.remoteAddr to be set.
174 defer func() {
175 if e != nil {
176 c.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{e}}, true)
177 c.traceInfo.tr.SetError()
178 }
179 }()
180 }
181 ctx = newContextWithRPCInfo(ctx)
182 sh := cc.dopts.copts.StatsHandler
183 if sh != nil {
184 ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: c.failFast})
185 begin := &stats.Begin{
186 Client: true,
187 BeginTime: time.Now(),
188 FailFast: c.failFast,
189 }
190 sh.HandleRPC(ctx, begin)
191 defer func() {
192 end := &stats.End{
193 Client: true,
194 EndTime: time.Now(),
195 Error: e,
196 }
197 sh.HandleRPC(ctx, end)
198 }()
199 }
200 topts := &transport.Options{
201 Last: true,
202 Delay: false,
203 }
204 for {
205 var (
206 err error
207 t transport.ClientTransport
208 stream *transport.Stream
209 // Record the put handler from Balancer.Get(...). It is called once the
210 // RPC has completed or failed.
211 put func()
212 )
213 // TODO(zhaoq): Need a formal spec of fail-fast.
214 callHdr := &transport.CallHdr{
215 Host: cc.authority,
216 Method: method,
217 }
218 if cc.dopts.cp != nil {
219 callHdr.SendCompress = cc.dopts.cp.Type()
220 }
221 if c.creds != nil {
222 callHdr.Creds = c.creds
223 }
224
225 gopts := BalancerGetOptions{
226 BlockingWait: !c.failFast,
227 }
228 t, put, err = cc.getTransport(ctx, gopts)
229 if err != nil {
230 // TODO(zhaoq): Probably revisit the error handling.
231 if _, ok := status.FromError(err); ok {
232 return err
233 }
234 if err == errConnClosing || err == errConnUnavailable {
235 if c.failFast {
236 return Errorf(codes.Unavailable, "%v", err)
237 }
238 continue
239 }
240 // All the other errors are treated as Internal errors.
241 return Errorf(codes.Internal, "%v", err)
242 }
243 if c.traceInfo.tr != nil {
244 c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true)
245 }
246 stream, err = t.NewStream(ctx, callHdr)
247 if err != nil {
248 if put != nil {
249 if _, ok := err.(transport.ConnectionError); ok {
250 // If error is connection error, transport was sending data on wire,
251 // and we are not sure if anything has been sent on wire.
252 // If error is not connection error, we are sure nothing has been sent.
253 updateRPCInfoInContext(ctx, rpcInfo{bytesSent: true, bytesReceived: false})
254 }
255 put()
256 }
257 if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast {
258 continue
259 }
260 return toRPCErr(err)
261 }
262 if peer, ok := peer.FromContext(stream.Context()); ok {
263 c.peer = peer
264 }
265 err = sendRequest(ctx, cc.dopts, cc.dopts.cp, &c, callHdr, stream, t, args, topts)
266 if err != nil {
267 if put != nil {
268 updateRPCInfoInContext(ctx, rpcInfo{
269 bytesSent: stream.BytesSent(),
270 bytesReceived: stream.BytesReceived(),
271 })
272 put()
273 }
274 // Retry a non-failfast RPC when
275 // i) there is a connection error; or
276 // ii) the server started to drain before this RPC was initiated.
277 if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast {
278 continue
279 }
280 return toRPCErr(err)
281 }
282 err = recvResponse(ctx, cc.dopts, t, &c, stream, reply)
283 if err != nil {
284 if put != nil {
285 updateRPCInfoInContext(ctx, rpcInfo{
286 bytesSent: stream.BytesSent(),
287 bytesReceived: stream.BytesReceived(),
288 })
289 put()
290 }
291 if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast {
292 continue
293 }
294 return toRPCErr(err)
295 }
296 if c.traceInfo.tr != nil {
297 c.traceInfo.tr.LazyLog(&payload{sent: false, msg: reply}, true)
298 }
299 t.CloseStream(stream, nil)
300 if put != nil {
301 updateRPCInfoInContext(ctx, rpcInfo{
302 bytesSent: stream.BytesSent(),
303 bytesReceived: stream.BytesReceived(),
304 })
305 put()
306 }
307 return stream.Status().Err()
308 }
309}
diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go
new file mode 100644
index 0000000..e3f6cb1
--- /dev/null
+++ b/vendor/google.golang.org/grpc/clientconn.go
@@ -0,0 +1,1158 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "errors"
23 "net"
24 "strings"
25 "sync"
26 "time"
27
28 "golang.org/x/net/context"
29 "golang.org/x/net/trace"
30 "google.golang.org/grpc/connectivity"
31 "google.golang.org/grpc/credentials"
32 "google.golang.org/grpc/grpclog"
33 "google.golang.org/grpc/keepalive"
34 "google.golang.org/grpc/stats"
35 "google.golang.org/grpc/transport"
36)
37
38var (
39 // ErrClientConnClosing indicates that the operation is illegal because
40 // the ClientConn is closing.
41 ErrClientConnClosing = errors.New("grpc: the client connection is closing")
42 // ErrClientConnTimeout indicates that the ClientConn cannot establish the
43 // underlying connections within the specified timeout.
44 // DEPRECATED: Please use context.DeadlineExceeded instead.
45 ErrClientConnTimeout = errors.New("grpc: timed out when dialing")
46
47 // errNoTransportSecurity indicates that there is no transport security
48 // being set for ClientConn. Users should either set one or explicitly
49 // call WithInsecure DialOption to disable security.
50 errNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)")
51 // errTransportCredentialsMissing indicates that users want to transmit security
52 // information (e.g., oauth2 token) which requires secure connection on an insecure
53 // connection.
54 errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)")
55 // errCredentialsConflict indicates that grpc.WithTransportCredentials()
56 // and grpc.WithInsecure() are both called for a connection.
57 errCredentialsConflict = errors.New("grpc: transport credentials are set for an insecure connection (grpc.WithTransportCredentials() and grpc.WithInsecure() are both called)")
58 // errNetworkIO indicates that the connection is down due to some network I/O error.
59 errNetworkIO = errors.New("grpc: failed with network I/O error")
60 // errConnDrain indicates that the connection starts to be drained and does not accept any new RPCs.
61 errConnDrain = errors.New("grpc: the connection is drained")
62 // errConnClosing indicates that the connection is closing.
63 errConnClosing = errors.New("grpc: the connection is closing")
64 // errConnUnavailable indicates that the connection is unavailable.
65 errConnUnavailable = errors.New("grpc: the connection is unavailable")
66 // errBalancerClosed indicates that the balancer is closed.
67 errBalancerClosed = errors.New("grpc: balancer is closed")
68 // minimum time to give a connection to complete
69 minConnectTimeout = 20 * time.Second
70)
71
72// dialOptions configure a Dial call. dialOptions are set by the DialOption
73// values passed to Dial.
74type dialOptions struct {
75 unaryInt UnaryClientInterceptor
76 streamInt StreamClientInterceptor
77 codec Codec
78 cp Compressor
79 dc Decompressor
80 bs backoffStrategy
81 balancer Balancer
82 block bool
83 insecure bool
84 timeout time.Duration
85 scChan <-chan ServiceConfig
86 copts transport.ConnectOptions
87 callOptions []CallOption
88}
89
90const (
91 defaultClientMaxReceiveMessageSize = 1024 * 1024 * 4
92 defaultClientMaxSendMessageSize = 1024 * 1024 * 4
93)
94
95// DialOption configures how we set up the connection.
96type DialOption func(*dialOptions)
97
98// WithInitialWindowSize returns a DialOption which sets the value for initial window size on a stream.
99// The lower bound for window size is 64K and any value smaller than that will be ignored.
100func WithInitialWindowSize(s int32) DialOption {
101 return func(o *dialOptions) {
102 o.copts.InitialWindowSize = s
103 }
104}
105
106// WithInitialConnWindowSize returns a DialOption which sets the value for initial window size on a connection.
107// The lower bound for window size is 64K and any value smaller than that will be ignored.
108func WithInitialConnWindowSize(s int32) DialOption {
109 return func(o *dialOptions) {
110 o.copts.InitialConnWindowSize = s
111 }
112}
113
114// WithMaxMsgSize returns a DialOption which sets the maximum message size the client can receive. Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead.
115func WithMaxMsgSize(s int) DialOption {
116 return WithDefaultCallOptions(MaxCallRecvMsgSize(s))
117}
118
119// WithDefaultCallOptions returns a DialOption which sets the default CallOptions for calls over the connection.
120func WithDefaultCallOptions(cos ...CallOption) DialOption {
121 return func(o *dialOptions) {
122 o.callOptions = append(o.callOptions, cos...)
123 }
124}
125
126// WithCodec returns a DialOption which sets a codec for message marshaling and unmarshaling.
127func WithCodec(c Codec) DialOption {
128 return func(o *dialOptions) {
129 o.codec = c
130 }
131}
132
133// WithCompressor returns a DialOption which sets a CompressorGenerator for generating message
134// compressor.
135func WithCompressor(cp Compressor) DialOption {
136 return func(o *dialOptions) {
137 o.cp = cp
138 }
139}
140
141// WithDecompressor returns a DialOption which sets a DecompressorGenerator for generating
142// message decompressor.
143func WithDecompressor(dc Decompressor) DialOption {
144 return func(o *dialOptions) {
145 o.dc = dc
146 }
147}
148
149// WithBalancer returns a DialOption which sets a load balancer.
150func WithBalancer(b Balancer) DialOption {
151 return func(o *dialOptions) {
152 o.balancer = b
153 }
154}
155
156// WithServiceConfig returns a DialOption which has a channel to read the service configuration.
157func WithServiceConfig(c <-chan ServiceConfig) DialOption {
158 return func(o *dialOptions) {
159 o.scChan = c
160 }
161}
162
163// WithBackoffMaxDelay configures the dialer to use the provided maximum delay
164// when backing off after failed connection attempts.
165func WithBackoffMaxDelay(md time.Duration) DialOption {
166 return WithBackoffConfig(BackoffConfig{MaxDelay: md})
167}
168
169// WithBackoffConfig configures the dialer to use the provided backoff
170// parameters after connection failures.
171//
172// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up
173// for use.
174func WithBackoffConfig(b BackoffConfig) DialOption {
175 // Set defaults to ensure that provided BackoffConfig is valid and
176 // unexported fields get default values.
177 setDefaults(&b)
178 return withBackoff(b)
179}
180
181// withBackoff sets the backoff strategy used for retries after a
182// failed connection attempt.
183//
184// This can be exported if arbitrary backoff strategies are allowed by gRPC.
185func withBackoff(bs backoffStrategy) DialOption {
186 return func(o *dialOptions) {
187 o.bs = bs
188 }
189}
190
191// WithBlock returns a DialOption which makes caller of Dial blocks until the underlying
192// connection is up. Without this, Dial returns immediately and connecting the server
193// happens in background.
194func WithBlock() DialOption {
195 return func(o *dialOptions) {
196 o.block = true
197 }
198}
199
200// WithInsecure returns a DialOption which disables transport security for this ClientConn.
201// Note that transport security is required unless WithInsecure is set.
202func WithInsecure() DialOption {
203 return func(o *dialOptions) {
204 o.insecure = true
205 }
206}
207
208// WithTransportCredentials returns a DialOption which configures a
209// connection level security credentials (e.g., TLS/SSL).
210func WithTransportCredentials(creds credentials.TransportCredentials) DialOption {
211 return func(o *dialOptions) {
212 o.copts.TransportCredentials = creds
213 }
214}
215
216// WithPerRPCCredentials returns a DialOption which sets
217// credentials and places auth state on each outbound RPC.
218func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption {
219 return func(o *dialOptions) {
220 o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds)
221 }
222}
223
224// WithTimeout returns a DialOption that configures a timeout for dialing a ClientConn
225// initially. This is valid if and only if WithBlock() is present.
226// Deprecated: use DialContext and context.WithTimeout instead.
227func WithTimeout(d time.Duration) DialOption {
228 return func(o *dialOptions) {
229 o.timeout = d
230 }
231}
232
233// WithDialer returns a DialOption that specifies a function to use for dialing network addresses.
234// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's
235// Temporary() method to decide if it should try to reconnect to the network address.
236func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
237 return func(o *dialOptions) {
238 o.copts.Dialer = func(ctx context.Context, addr string) (net.Conn, error) {
239 if deadline, ok := ctx.Deadline(); ok {
240 return f(addr, deadline.Sub(time.Now()))
241 }
242 return f(addr, 0)
243 }
244 }
245}
246
247// WithStatsHandler returns a DialOption that specifies the stats handler
248// for all the RPCs and underlying network connections in this ClientConn.
249func WithStatsHandler(h stats.Handler) DialOption {
250 return func(o *dialOptions) {
251 o.copts.StatsHandler = h
252 }
253}
254
255// FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on non-temporary dial errors.
256// If f is true, and dialer returns a non-temporary error, gRPC will fail the connection to the network
257// address and won't try to reconnect.
258// The default value of FailOnNonTempDialError is false.
259// This is an EXPERIMENTAL API.
260func FailOnNonTempDialError(f bool) DialOption {
261 return func(o *dialOptions) {
262 o.copts.FailOnNonTempDialError = f
263 }
264}
265
266// WithUserAgent returns a DialOption that specifies a user agent string for all the RPCs.
267func WithUserAgent(s string) DialOption {
268 return func(o *dialOptions) {
269 o.copts.UserAgent = s
270 }
271}
272
273// WithKeepaliveParams returns a DialOption that specifies keepalive paramaters for the client transport.
274func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption {
275 return func(o *dialOptions) {
276 o.copts.KeepaliveParams = kp
277 }
278}
279
280// WithUnaryInterceptor returns a DialOption that specifies the interceptor for unary RPCs.
281func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption {
282 return func(o *dialOptions) {
283 o.unaryInt = f
284 }
285}
286
287// WithStreamInterceptor returns a DialOption that specifies the interceptor for streaming RPCs.
288func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
289 return func(o *dialOptions) {
290 o.streamInt = f
291 }
292}
293
294// WithAuthority returns a DialOption that specifies the value to be used as
295// the :authority pseudo-header. This value only works with WithInsecure and
296// has no effect if TransportCredentials are present.
297func WithAuthority(a string) DialOption {
298 return func(o *dialOptions) {
299 o.copts.Authority = a
300 }
301}
302
303// Dial creates a client connection to the given target.
304func Dial(target string, opts ...DialOption) (*ClientConn, error) {
305 return DialContext(context.Background(), target, opts...)
306}
307
308// DialContext creates a client connection to the given target. ctx can be used to
309// cancel or expire the pending connection. Once this function returns, the
310// cancellation and expiration of ctx will be noop. Users should call ClientConn.Close
311// to terminate all the pending operations after this function returns.
312func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
313 cc := &ClientConn{
314 target: target,
315 csMgr: &connectivityStateManager{},
316 conns: make(map[Address]*addrConn),
317 }
318 cc.csEvltr = &connectivityStateEvaluator{csMgr: cc.csMgr}
319 cc.ctx, cc.cancel = context.WithCancel(context.Background())
320
321 for _, opt := range opts {
322 opt(&cc.dopts)
323 }
324 cc.mkp = cc.dopts.copts.KeepaliveParams
325
326 if cc.dopts.copts.Dialer == nil {
327 cc.dopts.copts.Dialer = newProxyDialer(
328 func(ctx context.Context, addr string) (net.Conn, error) {
329 return dialContext(ctx, "tcp", addr)
330 },
331 )
332 }
333
334 if cc.dopts.copts.UserAgent != "" {
335 cc.dopts.copts.UserAgent += " " + grpcUA
336 } else {
337 cc.dopts.copts.UserAgent = grpcUA
338 }
339
340 if cc.dopts.timeout > 0 {
341 var cancel context.CancelFunc
342 ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout)
343 defer cancel()
344 }
345
346 defer func() {
347 select {
348 case <-ctx.Done():
349 conn, err = nil, ctx.Err()
350 default:
351 }
352
353 if err != nil {
354 cc.Close()
355 }
356 }()
357
358 scSet := false
359 if cc.dopts.scChan != nil {
360 // Try to get an initial service config.
361 select {
362 case sc, ok := <-cc.dopts.scChan:
363 if ok {
364 cc.sc = sc
365 scSet = true
366 }
367 default:
368 }
369 }
370 // Set defaults.
371 if cc.dopts.codec == nil {
372 cc.dopts.codec = protoCodec{}
373 }
374 if cc.dopts.bs == nil {
375 cc.dopts.bs = DefaultBackoffConfig
376 }
377 creds := cc.dopts.copts.TransportCredentials
378 if creds != nil && creds.Info().ServerName != "" {
379 cc.authority = creds.Info().ServerName
380 } else if cc.dopts.insecure && cc.dopts.copts.Authority != "" {
381 cc.authority = cc.dopts.copts.Authority
382 } else {
383 cc.authority = target
384 }
385 waitC := make(chan error, 1)
386 go func() {
387 defer close(waitC)
388 if cc.dopts.balancer == nil && cc.sc.LB != nil {
389 cc.dopts.balancer = cc.sc.LB
390 }
391 if cc.dopts.balancer != nil {
392 var credsClone credentials.TransportCredentials
393 if creds != nil {
394 credsClone = creds.Clone()
395 }
396 config := BalancerConfig{
397 DialCreds: credsClone,
398 Dialer: cc.dopts.copts.Dialer,
399 }
400 if err := cc.dopts.balancer.Start(target, config); err != nil {
401 waitC <- err
402 return
403 }
404 ch := cc.dopts.balancer.Notify()
405 if ch != nil {
406 if cc.dopts.block {
407 doneChan := make(chan struct{})
408 go cc.lbWatcher(doneChan)
409 <-doneChan
410 } else {
411 go cc.lbWatcher(nil)
412 }
413 return
414 }
415 }
416 // No balancer, or no resolver within the balancer. Connect directly.
417 if err := cc.resetAddrConn(Address{Addr: target}, cc.dopts.block, nil); err != nil {
418 waitC <- err
419 return
420 }
421 }()
422 select {
423 case <-ctx.Done():
424 return nil, ctx.Err()
425 case err := <-waitC:
426 if err != nil {
427 return nil, err
428 }
429 }
430 if cc.dopts.scChan != nil && !scSet {
431 // Blocking wait for the initial service config.
432 select {
433 case sc, ok := <-cc.dopts.scChan:
434 if ok {
435 cc.sc = sc
436 }
437 case <-ctx.Done():
438 return nil, ctx.Err()
439 }
440 }
441 if cc.dopts.scChan != nil {
442 go cc.scWatcher()
443 }
444
445 return cc, nil
446}
447
448// connectivityStateEvaluator gets updated by addrConns when their
449// states transition, based on which it evaluates the state of
450// ClientConn.
451// Note: This code will eventually sit in the balancer in the new design.
452type connectivityStateEvaluator struct {
453 csMgr *connectivityStateManager
454 mu sync.Mutex
455 numReady uint64 // Number of addrConns in ready state.
456 numConnecting uint64 // Number of addrConns in connecting state.
457 numTransientFailure uint64 // Number of addrConns in transientFailure.
458}
459
460// recordTransition records state change happening in every addrConn and based on
461// that it evaluates what state the ClientConn is in.
462// It can only transition between connectivity.Ready, connectivity.Connecting and connectivity.TransientFailure. Other states,
463// Idle and connectivity.Shutdown are transitioned into by ClientConn; in the begining of the connection
464// before any addrConn is created ClientConn is in idle state. In the end when ClientConn
465// closes it is in connectivity.Shutdown state.
466// TODO Note that in later releases, a ClientConn with no activity will be put into an Idle state.
467func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) {
468 cse.mu.Lock()
469 defer cse.mu.Unlock()
470
471 // Update counters.
472 for idx, state := range []connectivity.State{oldState, newState} {
473 updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
474 switch state {
475 case connectivity.Ready:
476 cse.numReady += updateVal
477 case connectivity.Connecting:
478 cse.numConnecting += updateVal
479 case connectivity.TransientFailure:
480 cse.numTransientFailure += updateVal
481 }
482 }
483
484 // Evaluate.
485 if cse.numReady > 0 {
486 cse.csMgr.updateState(connectivity.Ready)
487 return
488 }
489 if cse.numConnecting > 0 {
490 cse.csMgr.updateState(connectivity.Connecting)
491 return
492 }
493 cse.csMgr.updateState(connectivity.TransientFailure)
494}
495
496// connectivityStateManager keeps the connectivity.State of ClientConn.
497// This struct will eventually be exported so the balancers can access it.
498type connectivityStateManager struct {
499 mu sync.Mutex
500 state connectivity.State
501 notifyChan chan struct{}
502}
503
504// updateState updates the connectivity.State of ClientConn.
505// If there's a change it notifies goroutines waiting on state change to
506// happen.
507func (csm *connectivityStateManager) updateState(state connectivity.State) {
508 csm.mu.Lock()
509 defer csm.mu.Unlock()
510 if csm.state == connectivity.Shutdown {
511 return
512 }
513 if csm.state == state {
514 return
515 }
516 csm.state = state
517 if csm.notifyChan != nil {
518 // There are other goroutines waiting on this channel.
519 close(csm.notifyChan)
520 csm.notifyChan = nil
521 }
522}
523
524func (csm *connectivityStateManager) getState() connectivity.State {
525 csm.mu.Lock()
526 defer csm.mu.Unlock()
527 return csm.state
528}
529
530func (csm *connectivityStateManager) getNotifyChan() <-chan struct{} {
531 csm.mu.Lock()
532 defer csm.mu.Unlock()
533 if csm.notifyChan == nil {
534 csm.notifyChan = make(chan struct{})
535 }
536 return csm.notifyChan
537}
538
539// ClientConn represents a client connection to an RPC server.
540type ClientConn struct {
541 ctx context.Context
542 cancel context.CancelFunc
543
544 target string
545 authority string
546 dopts dialOptions
547 csMgr *connectivityStateManager
548 csEvltr *connectivityStateEvaluator // This will eventually be part of balancer.
549
550 mu sync.RWMutex
551 sc ServiceConfig
552 conns map[Address]*addrConn
553 // Keepalive parameter can be updated if a GoAway is received.
554 mkp keepalive.ClientParameters
555}
556
557// WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or
558// ctx expires. A true value is returned in former case and false in latter.
559// This is an EXPERIMENTAL API.
560func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connectivity.State) bool {
561 ch := cc.csMgr.getNotifyChan()
562 if cc.csMgr.getState() != sourceState {
563 return true
564 }
565 select {
566 case <-ctx.Done():
567 return false
568 case <-ch:
569 return true
570 }
571}
572
573// GetState returns the connectivity.State of ClientConn.
574// This is an EXPERIMENTAL API.
575func (cc *ClientConn) GetState() connectivity.State {
576 return cc.csMgr.getState()
577}
578
579// lbWatcher watches the Notify channel of the balancer in cc and manages
580// connections accordingly. If doneChan is not nil, it is closed after the
581// first successfull connection is made.
582func (cc *ClientConn) lbWatcher(doneChan chan struct{}) {
583 defer func() {
584 // In case channel from cc.dopts.balancer.Notify() gets closed before a
585 // successful connection gets established, don't forget to notify the
586 // caller.
587 if doneChan != nil {
588 close(doneChan)
589 }
590 }()
591
592 for addrs := range cc.dopts.balancer.Notify() {
593 var (
594 add []Address // Addresses need to setup connections.
595 del []*addrConn // Connections need to tear down.
596 )
597 cc.mu.Lock()
598 for _, a := range addrs {
599 if _, ok := cc.conns[a]; !ok {
600 add = append(add, a)
601 }
602 }
603 for k, c := range cc.conns {
604 var keep bool
605 for _, a := range addrs {
606 if k == a {
607 keep = true
608 break
609 }
610 }
611 if !keep {
612 del = append(del, c)
613 delete(cc.conns, c.addr)
614 }
615 }
616 cc.mu.Unlock()
617 for _, a := range add {
618 var err error
619 if doneChan != nil {
620 err = cc.resetAddrConn(a, true, nil)
621 if err == nil {
622 close(doneChan)
623 doneChan = nil
624 }
625 } else {
626 err = cc.resetAddrConn(a, false, nil)
627 }
628 if err != nil {
629 grpclog.Warningf("Error creating connection to %v. Err: %v", a, err)
630 }
631 }
632 for _, c := range del {
633 c.tearDown(errConnDrain)
634 }
635 }
636}
637
638func (cc *ClientConn) scWatcher() {
639 for {
640 select {
641 case sc, ok := <-cc.dopts.scChan:
642 if !ok {
643 return
644 }
645 cc.mu.Lock()
646 // TODO: load balance policy runtime change is ignored.
647 // We may revist this decision in the future.
648 cc.sc = sc
649 cc.mu.Unlock()
650 case <-cc.ctx.Done():
651 return
652 }
653 }
654}
655
656// resetAddrConn creates an addrConn for addr and adds it to cc.conns.
657// If there is an old addrConn for addr, it will be torn down, using tearDownErr as the reason.
658// If tearDownErr is nil, errConnDrain will be used instead.
659//
660// We should never need to replace an addrConn with a new one. This function is only used
661// as newAddrConn to create new addrConn.
662// TODO rename this function and clean up the code.
663func (cc *ClientConn) resetAddrConn(addr Address, block bool, tearDownErr error) error {
664 ac := &addrConn{
665 cc: cc,
666 addr: addr,
667 dopts: cc.dopts,
668 }
669 ac.ctx, ac.cancel = context.WithCancel(cc.ctx)
670 ac.csEvltr = cc.csEvltr
671 if EnableTracing {
672 ac.events = trace.NewEventLog("grpc.ClientConn", ac.addr.Addr)
673 }
674 if !ac.dopts.insecure {
675 if ac.dopts.copts.TransportCredentials == nil {
676 return errNoTransportSecurity
677 }
678 } else {
679 if ac.dopts.copts.TransportCredentials != nil {
680 return errCredentialsConflict
681 }
682 for _, cd := range ac.dopts.copts.PerRPCCredentials {
683 if cd.RequireTransportSecurity() {
684 return errTransportCredentialsMissing
685 }
686 }
687 }
688 // Track ac in cc. This needs to be done before any getTransport(...) is called.
689 cc.mu.Lock()
690 if cc.conns == nil {
691 cc.mu.Unlock()
692 return ErrClientConnClosing
693 }
694 stale := cc.conns[ac.addr]
695 cc.conns[ac.addr] = ac
696 cc.mu.Unlock()
697 if stale != nil {
698 // There is an addrConn alive on ac.addr already. This could be due to
699 // a buggy Balancer that reports duplicated Addresses.
700 if tearDownErr == nil {
701 // tearDownErr is nil if resetAddrConn is called by
702 // 1) Dial
703 // 2) lbWatcher
704 // In both cases, the stale ac should drain, not close.
705 stale.tearDown(errConnDrain)
706 } else {
707 stale.tearDown(tearDownErr)
708 }
709 }
710 if block {
711 if err := ac.resetTransport(false); err != nil {
712 if err != errConnClosing {
713 // Tear down ac and delete it from cc.conns.
714 cc.mu.Lock()
715 delete(cc.conns, ac.addr)
716 cc.mu.Unlock()
717 ac.tearDown(err)
718 }
719 if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
720 return e.Origin()
721 }
722 return err
723 }
724 // Start to monitor the error status of transport.
725 go ac.transportMonitor()
726 } else {
727 // Start a goroutine connecting to the server asynchronously.
728 go func() {
729 if err := ac.resetTransport(false); err != nil {
730 grpclog.Warningf("Failed to dial %s: %v; please retry.", ac.addr.Addr, err)
731 if err != errConnClosing {
732 // Keep this ac in cc.conns, to get the reason it's torn down.
733 ac.tearDown(err)
734 }
735 return
736 }
737 ac.transportMonitor()
738 }()
739 }
740 return nil
741}
742
743// GetMethodConfig gets the method config of the input method.
744// If there's an exact match for input method (i.e. /service/method), we return
745// the corresponding MethodConfig.
746// If there isn't an exact match for the input method, we look for the default config
747// under the service (i.e /service/). If there is a default MethodConfig for
748// the serivce, we return it.
749// Otherwise, we return an empty MethodConfig.
750func (cc *ClientConn) GetMethodConfig(method string) MethodConfig {
751 // TODO: Avoid the locking here.
752 cc.mu.RLock()
753 defer cc.mu.RUnlock()
754 m, ok := cc.sc.Methods[method]
755 if !ok {
756 i := strings.LastIndex(method, "/")
757 m, _ = cc.sc.Methods[method[:i+1]]
758 }
759 return m
760}
761
762func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) (transport.ClientTransport, func(), error) {
763 var (
764 ac *addrConn
765 ok bool
766 put func()
767 )
768 if cc.dopts.balancer == nil {
769 // If balancer is nil, there should be only one addrConn available.
770 cc.mu.RLock()
771 if cc.conns == nil {
772 cc.mu.RUnlock()
773 return nil, nil, toRPCErr(ErrClientConnClosing)
774 }
775 for _, ac = range cc.conns {
776 // Break after the first iteration to get the first addrConn.
777 ok = true
778 break
779 }
780 cc.mu.RUnlock()
781 } else {
782 var (
783 addr Address
784 err error
785 )
786 addr, put, err = cc.dopts.balancer.Get(ctx, opts)
787 if err != nil {
788 return nil, nil, toRPCErr(err)
789 }
790 cc.mu.RLock()
791 if cc.conns == nil {
792 cc.mu.RUnlock()
793 return nil, nil, toRPCErr(ErrClientConnClosing)
794 }
795 ac, ok = cc.conns[addr]
796 cc.mu.RUnlock()
797 }
798 if !ok {
799 if put != nil {
800 updateRPCInfoInContext(ctx, rpcInfo{bytesSent: false, bytesReceived: false})
801 put()
802 }
803 return nil, nil, errConnClosing
804 }
805 t, err := ac.wait(ctx, cc.dopts.balancer != nil, !opts.BlockingWait)
806 if err != nil {
807 if put != nil {
808 updateRPCInfoInContext(ctx, rpcInfo{bytesSent: false, bytesReceived: false})
809 put()
810 }
811 return nil, nil, err
812 }
813 return t, put, nil
814}
815
816// Close tears down the ClientConn and all underlying connections.
817func (cc *ClientConn) Close() error {
818 cc.cancel()
819
820 cc.mu.Lock()
821 if cc.conns == nil {
822 cc.mu.Unlock()
823 return ErrClientConnClosing
824 }
825 conns := cc.conns
826 cc.conns = nil
827 cc.csMgr.updateState(connectivity.Shutdown)
828 cc.mu.Unlock()
829 if cc.dopts.balancer != nil {
830 cc.dopts.balancer.Close()
831 }
832 for _, ac := range conns {
833 ac.tearDown(ErrClientConnClosing)
834 }
835 return nil
836}
837
838// addrConn is a network connection to a given address.
839type addrConn struct {
840 ctx context.Context
841 cancel context.CancelFunc
842
843 cc *ClientConn
844 addr Address
845 dopts dialOptions
846 events trace.EventLog
847
848 csEvltr *connectivityStateEvaluator
849
850 mu sync.Mutex
851 state connectivity.State
852 down func(error) // the handler called when a connection is down.
853 // ready is closed and becomes nil when a new transport is up or failed
854 // due to timeout.
855 ready chan struct{}
856 transport transport.ClientTransport
857
858 // The reason this addrConn is torn down.
859 tearDownErr error
860}
861
862// adjustParams updates parameters used to create transports upon
863// receiving a GoAway.
864func (ac *addrConn) adjustParams(r transport.GoAwayReason) {
865 switch r {
866 case transport.TooManyPings:
867 v := 2 * ac.dopts.copts.KeepaliveParams.Time
868 ac.cc.mu.Lock()
869 if v > ac.cc.mkp.Time {
870 ac.cc.mkp.Time = v
871 }
872 ac.cc.mu.Unlock()
873 }
874}
875
876// printf records an event in ac's event log, unless ac has been closed.
877// REQUIRES ac.mu is held.
878func (ac *addrConn) printf(format string, a ...interface{}) {
879 if ac.events != nil {
880 ac.events.Printf(format, a...)
881 }
882}
883
884// errorf records an error in ac's event log, unless ac has been closed.
885// REQUIRES ac.mu is held.
886func (ac *addrConn) errorf(format string, a ...interface{}) {
887 if ac.events != nil {
888 ac.events.Errorf(format, a...)
889 }
890}
891
892// resetTransport recreates a transport to the address for ac.
893// For the old transport:
894// - if drain is true, it will be gracefully closed.
895// - otherwise, it will be closed.
896func (ac *addrConn) resetTransport(drain bool) error {
897 ac.mu.Lock()
898 if ac.state == connectivity.Shutdown {
899 ac.mu.Unlock()
900 return errConnClosing
901 }
902 ac.printf("connecting")
903 if ac.down != nil {
904 ac.down(downErrorf(false, true, "%v", errNetworkIO))
905 ac.down = nil
906 }
907 oldState := ac.state
908 ac.state = connectivity.Connecting
909 ac.csEvltr.recordTransition(oldState, ac.state)
910 t := ac.transport
911 ac.transport = nil
912 ac.mu.Unlock()
913 if t != nil && !drain {
914 t.Close()
915 }
916 ac.cc.mu.RLock()
917 ac.dopts.copts.KeepaliveParams = ac.cc.mkp
918 ac.cc.mu.RUnlock()
919 for retries := 0; ; retries++ {
920 ac.mu.Lock()
921 if ac.state == connectivity.Shutdown {
922 // ac.tearDown(...) has been invoked.
923 ac.mu.Unlock()
924 return errConnClosing
925 }
926 ac.mu.Unlock()
927 sleepTime := ac.dopts.bs.backoff(retries)
928 timeout := minConnectTimeout
929 if timeout < sleepTime {
930 timeout = sleepTime
931 }
932 ctx, cancel := context.WithTimeout(ac.ctx, timeout)
933 connectTime := time.Now()
934 sinfo := transport.TargetInfo{
935 Addr: ac.addr.Addr,
936 Metadata: ac.addr.Metadata,
937 }
938 newTransport, err := transport.NewClientTransport(ctx, sinfo, ac.dopts.copts)
939 // Don't call cancel in success path due to a race in Go 1.6:
940 // https://github.com/golang/go/issues/15078.
941 if err != nil {
942 cancel()
943
944 if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
945 return err
946 }
947 grpclog.Warningf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %v", err, ac.addr)
948 ac.mu.Lock()
949 if ac.state == connectivity.Shutdown {
950 // ac.tearDown(...) has been invoked.
951 ac.mu.Unlock()
952 return errConnClosing
953 }
954 ac.errorf("transient failure: %v", err)
955 oldState = ac.state
956 ac.state = connectivity.TransientFailure
957 ac.csEvltr.recordTransition(oldState, ac.state)
958 if ac.ready != nil {
959 close(ac.ready)
960 ac.ready = nil
961 }
962 ac.mu.Unlock()
963 timer := time.NewTimer(sleepTime - time.Since(connectTime))
964 select {
965 case <-timer.C:
966 case <-ac.ctx.Done():
967 timer.Stop()
968 return ac.ctx.Err()
969 }
970 timer.Stop()
971 continue
972 }
973 ac.mu.Lock()
974 ac.printf("ready")
975 if ac.state == connectivity.Shutdown {
976 // ac.tearDown(...) has been invoked.
977 ac.mu.Unlock()
978 newTransport.Close()
979 return errConnClosing
980 }
981 oldState = ac.state
982 ac.state = connectivity.Ready
983 ac.csEvltr.recordTransition(oldState, ac.state)
984 ac.transport = newTransport
985 if ac.ready != nil {
986 close(ac.ready)
987 ac.ready = nil
988 }
989 if ac.cc.dopts.balancer != nil {
990 ac.down = ac.cc.dopts.balancer.Up(ac.addr)
991 }
992 ac.mu.Unlock()
993 return nil
994 }
995}
996
997// Run in a goroutine to track the error in transport and create the
998// new transport if an error happens. It returns when the channel is closing.
999func (ac *addrConn) transportMonitor() {
1000 for {
1001 ac.mu.Lock()
1002 t := ac.transport
1003 ac.mu.Unlock()
1004 select {
1005 // This is needed to detect the teardown when
1006 // the addrConn is idle (i.e., no RPC in flight).
1007 case <-ac.ctx.Done():
1008 select {
1009 case <-t.Error():
1010 t.Close()
1011 default:
1012 }
1013 return
1014 case <-t.GoAway():
1015 ac.adjustParams(t.GetGoAwayReason())
1016 // If GoAway happens without any network I/O error, the underlying transport
1017 // will be gracefully closed, and a new transport will be created.
1018 // (The transport will be closed when all the pending RPCs finished or failed.)
1019 // If GoAway and some network I/O error happen concurrently, the underlying transport
1020 // will be closed, and a new transport will be created.
1021 var drain bool
1022 select {
1023 case <-t.Error():
1024 default:
1025 drain = true
1026 }
1027 if err := ac.resetTransport(drain); err != nil {
1028 grpclog.Infof("get error from resetTransport %v, transportMonitor returning", err)
1029 if err != errConnClosing {
1030 // Keep this ac in cc.conns, to get the reason it's torn down.
1031 ac.tearDown(err)
1032 }
1033 return
1034 }
1035 case <-t.Error():
1036 select {
1037 case <-ac.ctx.Done():
1038 t.Close()
1039 return
1040 case <-t.GoAway():
1041 ac.adjustParams(t.GetGoAwayReason())
1042 if err := ac.resetTransport(false); err != nil {
1043 grpclog.Infof("get error from resetTransport %v, transportMonitor returning", err)
1044 if err != errConnClosing {
1045 // Keep this ac in cc.conns, to get the reason it's torn down.
1046 ac.tearDown(err)
1047 }
1048 return
1049 }
1050 default:
1051 }
1052 ac.mu.Lock()
1053 if ac.state == connectivity.Shutdown {
1054 // ac has been shutdown.
1055 ac.mu.Unlock()
1056 return
1057 }
1058 oldState := ac.state
1059 ac.state = connectivity.TransientFailure
1060 ac.csEvltr.recordTransition(oldState, ac.state)
1061 ac.mu.Unlock()
1062 if err := ac.resetTransport(false); err != nil {
1063 grpclog.Infof("get error from resetTransport %v, transportMonitor returning", err)
1064 ac.mu.Lock()
1065 ac.printf("transport exiting: %v", err)
1066 ac.mu.Unlock()
1067 grpclog.Warningf("grpc: addrConn.transportMonitor exits due to: %v", err)
1068 if err != errConnClosing {
1069 // Keep this ac in cc.conns, to get the reason it's torn down.
1070 ac.tearDown(err)
1071 }
1072 return
1073 }
1074 }
1075 }
1076}
1077
1078// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or
1079// iv) transport is in connectivity.TransientFailure and there is a balancer/failfast is true.
1080func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (transport.ClientTransport, error) {
1081 for {
1082 ac.mu.Lock()
1083 switch {
1084 case ac.state == connectivity.Shutdown:
1085 if failfast || !hasBalancer {
1086 // RPC is failfast or balancer is nil. This RPC should fail with ac.tearDownErr.
1087 err := ac.tearDownErr
1088 ac.mu.Unlock()
1089 return nil, err
1090 }
1091 ac.mu.Unlock()
1092 return nil, errConnClosing
1093 case ac.state == connectivity.Ready:
1094 ct := ac.transport
1095 ac.mu.Unlock()
1096 return ct, nil
1097 case ac.state == connectivity.TransientFailure:
1098 if failfast || hasBalancer {
1099 ac.mu.Unlock()
1100 return nil, errConnUnavailable
1101 }
1102 }
1103 ready := ac.ready
1104 if ready == nil {
1105 ready = make(chan struct{})
1106 ac.ready = ready
1107 }
1108 ac.mu.Unlock()
1109 select {
1110 case <-ctx.Done():
1111 return nil, toRPCErr(ctx.Err())
1112 // Wait until the new transport is ready or failed.
1113 case <-ready:
1114 }
1115 }
1116}
1117
1118// tearDown starts to tear down the addrConn.
1119// TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in
1120// some edge cases (e.g., the caller opens and closes many addrConn's in a
1121// tight loop.
1122// tearDown doesn't remove ac from ac.cc.conns.
1123func (ac *addrConn) tearDown(err error) {
1124 ac.cancel()
1125
1126 ac.mu.Lock()
1127 defer ac.mu.Unlock()
1128 if ac.down != nil {
1129 ac.down(downErrorf(false, false, "%v", err))
1130 ac.down = nil
1131 }
1132 if err == errConnDrain && ac.transport != nil {
1133 // GracefulClose(...) may be executed multiple times when
1134 // i) receiving multiple GoAway frames from the server; or
1135 // ii) there are concurrent name resolver/Balancer triggered
1136 // address removal and GoAway.
1137 ac.transport.GracefulClose()
1138 }
1139 if ac.state == connectivity.Shutdown {
1140 return
1141 }
1142 oldState := ac.state
1143 ac.state = connectivity.Shutdown
1144 ac.tearDownErr = err
1145 ac.csEvltr.recordTransition(oldState, ac.state)
1146 if ac.events != nil {
1147 ac.events.Finish()
1148 ac.events = nil
1149 }
1150 if ac.ready != nil {
1151 close(ac.ready)
1152 ac.ready = nil
1153 }
1154 if ac.transport != nil && err != errConnDrain {
1155 ac.transport.Close()
1156 }
1157 return
1158}
diff --git a/vendor/google.golang.org/grpc/codec.go b/vendor/google.golang.org/grpc/codec.go
new file mode 100644
index 0000000..905b048
--- /dev/null
+++ b/vendor/google.golang.org/grpc/codec.go
@@ -0,0 +1,104 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "math"
23 "sync"
24
25 "github.com/golang/protobuf/proto"
26)
27
28// Codec defines the interface gRPC uses to encode and decode messages.
29// Note that implementations of this interface must be thread safe;
30// a Codec's methods can be called from concurrent goroutines.
31type Codec interface {
32 // Marshal returns the wire format of v.
33 Marshal(v interface{}) ([]byte, error)
34 // Unmarshal parses the wire format into v.
35 Unmarshal(data []byte, v interface{}) error
36 // String returns the name of the Codec implementation. The returned
37 // string will be used as part of content type in transmission.
38 String() string
39}
40
41// protoCodec is a Codec implementation with protobuf. It is the default codec for gRPC.
42type protoCodec struct {
43}
44
45type cachedProtoBuffer struct {
46 lastMarshaledSize uint32
47 proto.Buffer
48}
49
50func capToMaxInt32(val int) uint32 {
51 if val > math.MaxInt32 {
52 return uint32(math.MaxInt32)
53 }
54 return uint32(val)
55}
56
57func (p protoCodec) marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) {
58 protoMsg := v.(proto.Message)
59 newSlice := make([]byte, 0, cb.lastMarshaledSize)
60
61 cb.SetBuf(newSlice)
62 cb.Reset()
63 if err := cb.Marshal(protoMsg); err != nil {
64 return nil, err
65 }
66 out := cb.Bytes()
67 cb.lastMarshaledSize = capToMaxInt32(len(out))
68 return out, nil
69}
70
71func (p protoCodec) Marshal(v interface{}) ([]byte, error) {
72 cb := protoBufferPool.Get().(*cachedProtoBuffer)
73 out, err := p.marshal(v, cb)
74
75 // put back buffer and lose the ref to the slice
76 cb.SetBuf(nil)
77 protoBufferPool.Put(cb)
78 return out, err
79}
80
81func (p protoCodec) Unmarshal(data []byte, v interface{}) error {
82 cb := protoBufferPool.Get().(*cachedProtoBuffer)
83 cb.SetBuf(data)
84 v.(proto.Message).Reset()
85 err := cb.Unmarshal(v.(proto.Message))
86 cb.SetBuf(nil)
87 protoBufferPool.Put(cb)
88 return err
89}
90
91func (protoCodec) String() string {
92 return "proto"
93}
94
95var (
96 protoBufferPool = &sync.Pool{
97 New: func() interface{} {
98 return &cachedProtoBuffer{
99 Buffer: proto.Buffer{},
100 lastMarshaledSize: 16,
101 }
102 },
103 }
104)
diff --git a/vendor/google.golang.org/grpc/codegen.sh b/vendor/google.golang.org/grpc/codegen.sh
new file mode 100644
index 0000000..4cdc6ba
--- /dev/null
+++ b/vendor/google.golang.org/grpc/codegen.sh
@@ -0,0 +1,17 @@
1#!/usr/bin/env bash
2
3# This script serves as an example to demonstrate how to generate the gRPC-Go
4# interface and the related messages from .proto file.
5#
6# It assumes the installation of i) Google proto buffer compiler at
7# https://github.com/google/protobuf (after v2.6.1) and ii) the Go codegen
8# plugin at https://github.com/golang/protobuf (after 2015-02-20). If you have
9# not, please install them first.
10#
11# We recommend running this script at $GOPATH/src.
12#
13# If this is not what you need, feel free to make your own scripts. Again, this
14# script is for demonstration purpose.
15#
16proto=$1
17protoc --go_out=plugins=grpc:. $proto
diff --git a/vendor/google.golang.org/grpc/codes/code_string.go b/vendor/google.golang.org/grpc/codes/code_string.go
new file mode 100644
index 0000000..e6762d0
--- /dev/null
+++ b/vendor/google.golang.org/grpc/codes/code_string.go
@@ -0,0 +1,16 @@
1// generated by stringer -type=Code; DO NOT EDIT
2
3package codes
4
5import "fmt"
6
7const _Code_name = "OKCanceledUnknownInvalidArgumentDeadlineExceededNotFoundAlreadyExistsPermissionDeniedResourceExhaustedFailedPreconditionAbortedOutOfRangeUnimplementedInternalUnavailableDataLossUnauthenticated"
8
9var _Code_index = [...]uint8{0, 2, 10, 17, 32, 48, 56, 69, 85, 102, 120, 127, 137, 150, 158, 169, 177, 192}
10
11func (i Code) String() string {
12 if i+1 >= Code(len(_Code_index)) {
13 return fmt.Sprintf("Code(%d)", i)
14 }
15 return _Code_name[_Code_index[i]:_Code_index[i+1]]
16}
diff --git a/vendor/google.golang.org/grpc/codes/codes.go b/vendor/google.golang.org/grpc/codes/codes.go
new file mode 100644
index 0000000..21e7733
--- /dev/null
+++ b/vendor/google.golang.org/grpc/codes/codes.go
@@ -0,0 +1,144 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package codes defines the canonical error codes used by gRPC. It is
20// consistent across various languages.
21package codes // import "google.golang.org/grpc/codes"
22
23// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
24type Code uint32
25
26//go:generate stringer -type=Code
27
28const (
29 // OK is returned on success.
30 OK Code = 0
31
32 // Canceled indicates the operation was canceled (typically by the caller).
33 Canceled Code = 1
34
35 // Unknown error. An example of where this error may be returned is
36 // if a Status value received from another address space belongs to
37 // an error-space that is not known in this address space. Also
38 // errors raised by APIs that do not return enough error information
39 // may be converted to this error.
40 Unknown Code = 2
41
42 // InvalidArgument indicates client specified an invalid argument.
43 // Note that this differs from FailedPrecondition. It indicates arguments
44 // that are problematic regardless of the state of the system
45 // (e.g., a malformed file name).
46 InvalidArgument Code = 3
47
48 // DeadlineExceeded means operation expired before completion.
49 // For operations that change the state of the system, this error may be
50 // returned even if the operation has completed successfully. For
51 // example, a successful response from a server could have been delayed
52 // long enough for the deadline to expire.
53 DeadlineExceeded Code = 4
54
55 // NotFound means some requested entity (e.g., file or directory) was
56 // not found.
57 NotFound Code = 5
58
59 // AlreadyExists means an attempt to create an entity failed because one
60 // already exists.
61 AlreadyExists Code = 6
62
63 // PermissionDenied indicates the caller does not have permission to
64 // execute the specified operation. It must not be used for rejections
65 // caused by exhausting some resource (use ResourceExhausted
66 // instead for those errors). It must not be
67 // used if the caller cannot be identified (use Unauthenticated
68 // instead for those errors).
69 PermissionDenied Code = 7
70
71 // Unauthenticated indicates the request does not have valid
72 // authentication credentials for the operation.
73 Unauthenticated Code = 16
74
75 // ResourceExhausted indicates some resource has been exhausted, perhaps
76 // a per-user quota, or perhaps the entire file system is out of space.
77 ResourceExhausted Code = 8
78
79 // FailedPrecondition indicates operation was rejected because the
80 // system is not in a state required for the operation's execution.
81 // For example, directory to be deleted may be non-empty, an rmdir
82 // operation is applied to a non-directory, etc.
83 //
84 // A litmus test that may help a service implementor in deciding
85 // between FailedPrecondition, Aborted, and Unavailable:
86 // (a) Use Unavailable if the client can retry just the failing call.
87 // (b) Use Aborted if the client should retry at a higher-level
88 // (e.g., restarting a read-modify-write sequence).
89 // (c) Use FailedPrecondition if the client should not retry until
90 // the system state has been explicitly fixed. E.g., if an "rmdir"
91 // fails because the directory is non-empty, FailedPrecondition
92 // should be returned since the client should not retry unless
93 // they have first fixed up the directory by deleting files from it.
94 // (d) Use FailedPrecondition if the client performs conditional
95 // REST Get/Update/Delete on a resource and the resource on the
96 // server does not match the condition. E.g., conflicting
97 // read-modify-write on the same resource.
98 FailedPrecondition Code = 9
99
100 // Aborted indicates the operation was aborted, typically due to a
101 // concurrency issue like sequencer check failures, transaction aborts,
102 // etc.
103 //
104 // See litmus test above for deciding between FailedPrecondition,
105 // Aborted, and Unavailable.
106 Aborted Code = 10
107
108 // OutOfRange means operation was attempted past the valid range.
109 // E.g., seeking or reading past end of file.
110 //
111 // Unlike InvalidArgument, this error indicates a problem that may
112 // be fixed if the system state changes. For example, a 32-bit file
113 // system will generate InvalidArgument if asked to read at an
114 // offset that is not in the range [0,2^32-1], but it will generate
115 // OutOfRange if asked to read from an offset past the current
116 // file size.
117 //
118 // There is a fair bit of overlap between FailedPrecondition and
119 // OutOfRange. We recommend using OutOfRange (the more specific
120 // error) when it applies so that callers who are iterating through
121 // a space can easily look for an OutOfRange error to detect when
122 // they are done.
123 OutOfRange Code = 11
124
125 // Unimplemented indicates operation is not implemented or not
126 // supported/enabled in this service.
127 Unimplemented Code = 12
128
129 // Internal errors. Means some invariants expected by underlying
130 // system has been broken. If you see one of these errors,
131 // something is very broken.
132 Internal Code = 13
133
134 // Unavailable indicates the service is currently unavailable.
135 // This is a most likely a transient condition and may be corrected
136 // by retrying with a backoff.
137 //
138 // See litmus test above for deciding between FailedPrecondition,
139 // Aborted, and Unavailable.
140 Unavailable Code = 14
141
142 // DataLoss indicates unrecoverable data loss or corruption.
143 DataLoss Code = 15
144)
diff --git a/vendor/google.golang.org/grpc/connectivity/connectivity.go b/vendor/google.golang.org/grpc/connectivity/connectivity.go
new file mode 100644
index 0000000..568ef5d
--- /dev/null
+++ b/vendor/google.golang.org/grpc/connectivity/connectivity.go
@@ -0,0 +1,72 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package connectivity defines connectivity semantics.
20// For details, see https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md.
21// All APIs in this package are experimental.
22package connectivity
23
24import (
25 "golang.org/x/net/context"
26 "google.golang.org/grpc/grpclog"
27)
28
29// State indicates the state of connectivity.
30// It can be the state of a ClientConn or SubConn.
31type State int
32
33func (s State) String() string {
34 switch s {
35 case Idle:
36 return "IDLE"
37 case Connecting:
38 return "CONNECTING"
39 case Ready:
40 return "READY"
41 case TransientFailure:
42 return "TRANSIENT_FAILURE"
43 case Shutdown:
44 return "SHUTDOWN"
45 default:
46 grpclog.Errorf("unknown connectivity state: %d", s)
47 return "Invalid-State"
48 }
49}
50
51const (
52 // Idle indicates the ClientConn is idle.
53 Idle State = iota
54 // Connecting indicates the ClienConn is connecting.
55 Connecting
56 // Ready indicates the ClientConn is ready for work.
57 Ready
58 // TransientFailure indicates the ClientConn has seen a failure but expects to recover.
59 TransientFailure
60 // Shutdown indicates the ClientConn has started shutting down.
61 Shutdown
62)
63
64// Reporter reports the connectivity states.
65type Reporter interface {
66 // CurrentState returns the current state of the reporter.
67 CurrentState() State
68 // WaitForStateChange blocks until the reporter's state is different from the given state,
69 // and returns true.
70 // It returns false if <-ctx.Done() can proceed (ctx got timeout or got canceled).
71 WaitForStateChange(context.Context, State) bool
72}
diff --git a/vendor/google.golang.org/grpc/coverage.sh b/vendor/google.golang.org/grpc/coverage.sh
new file mode 100644
index 0000000..b85f918
--- /dev/null
+++ b/vendor/google.golang.org/grpc/coverage.sh
@@ -0,0 +1,48 @@
1#!/usr/bin/env bash
2
3
4set -e
5
6workdir=.cover
7profile="$workdir/cover.out"
8mode=set
9end2endtest="google.golang.org/grpc/test"
10
11generate_cover_data() {
12 rm -rf "$workdir"
13 mkdir "$workdir"
14
15 for pkg in "$@"; do
16 if [ $pkg == "google.golang.org/grpc" -o $pkg == "google.golang.org/grpc/transport" -o $pkg == "google.golang.org/grpc/metadata" -o $pkg == "google.golang.org/grpc/credentials" ]
17 then
18 f="$workdir/$(echo $pkg | tr / -)"
19 go test -covermode="$mode" -coverprofile="$f.cover" "$pkg"
20 go test -covermode="$mode" -coverpkg "$pkg" -coverprofile="$f.e2e.cover" "$end2endtest"
21 fi
22 done
23
24 echo "mode: $mode" >"$profile"
25 grep -h -v "^mode:" "$workdir"/*.cover >>"$profile"
26}
27
28show_cover_report() {
29 go tool cover -${1}="$profile"
30}
31
32push_to_coveralls() {
33 goveralls -coverprofile="$profile"
34}
35
36generate_cover_data $(go list ./...)
37show_cover_report func
38case "$1" in
39"")
40 ;;
41--html)
42 show_cover_report html ;;
43--coveralls)
44 push_to_coveralls ;;
45*)
46 echo >&2 "error: invalid option: $1" ;;
47esac
48rm -rf "$workdir"
diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go
new file mode 100644
index 0000000..2475fe8
--- /dev/null
+++ b/vendor/google.golang.org/grpc/credentials/credentials.go
@@ -0,0 +1,219 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package credentials implements various credentials supported by gRPC library,
20// which encapsulate all the state needed by a client to authenticate with a
21// server and make various assertions, e.g., about the client's identity, role,
22// or whether it is authorized to make a particular call.
23package credentials // import "google.golang.org/grpc/credentials"
24
25import (
26 "crypto/tls"
27 "crypto/x509"
28 "errors"
29 "fmt"
30 "io/ioutil"
31 "net"
32 "strings"
33
34 "golang.org/x/net/context"
35)
36
37var (
38 // alpnProtoStr are the specified application level protocols for gRPC.
39 alpnProtoStr = []string{"h2"}
40)
41
42// PerRPCCredentials defines the common interface for the credentials which need to
43// attach security information to every RPC (e.g., oauth2).
44type PerRPCCredentials interface {
45 // GetRequestMetadata gets the current request metadata, refreshing
46 // tokens if required. This should be called by the transport layer on
47 // each request, and the data should be populated in headers or other
48 // context. uri is the URI of the entry point for the request. When
49 // supported by the underlying implementation, ctx can be used for
50 // timeout and cancellation.
51 // TODO(zhaoq): Define the set of the qualified keys instead of leaving
52 // it as an arbitrary string.
53 GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
54 // RequireTransportSecurity indicates whether the credentials requires
55 // transport security.
56 RequireTransportSecurity() bool
57}
58
59// ProtocolInfo provides information regarding the gRPC wire protocol version,
60// security protocol, security protocol version in use, server name, etc.
61type ProtocolInfo struct {
62 // ProtocolVersion is the gRPC wire protocol version.
63 ProtocolVersion string
64 // SecurityProtocol is the security protocol in use.
65 SecurityProtocol string
66 // SecurityVersion is the security protocol version.
67 SecurityVersion string
68 // ServerName is the user-configured server name.
69 ServerName string
70}
71
72// AuthInfo defines the common interface for the auth information the users are interested in.
73type AuthInfo interface {
74 AuthType() string
75}
76
77var (
78 // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
79 // and the caller should not close rawConn.
80 ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
81)
82
83// TransportCredentials defines the common interface for all the live gRPC wire
84// protocols and supported transport security protocols (e.g., TLS, SSL).
85type TransportCredentials interface {
86 // ClientHandshake does the authentication handshake specified by the corresponding
87 // authentication protocol on rawConn for clients. It returns the authenticated
88 // connection and the corresponding auth information about the connection.
89 // Implementations must use the provided context to implement timely cancellation.
90 // gRPC will try to reconnect if the error returned is a temporary error
91 // (io.EOF, context.DeadlineExceeded or err.Temporary() == true).
92 // If the returned error is a wrapper error, implementations should make sure that
93 // the error implements Temporary() to have the correct retry behaviors.
94 ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
95 // ServerHandshake does the authentication handshake for servers. It returns
96 // the authenticated connection and the corresponding auth information about
97 // the connection.
98 ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
99 // Info provides the ProtocolInfo of this TransportCredentials.
100 Info() ProtocolInfo
101 // Clone makes a copy of this TransportCredentials.
102 Clone() TransportCredentials
103 // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server.
104 // gRPC internals also use it to override the virtual hosting name if it is set.
105 // It must be called before dialing. Currently, this is only used by grpclb.
106 OverrideServerName(string) error
107}
108
109// TLSInfo contains the auth information for a TLS authenticated connection.
110// It implements the AuthInfo interface.
111type TLSInfo struct {
112 State tls.ConnectionState
113}
114
115// AuthType returns the type of TLSInfo as a string.
116func (t TLSInfo) AuthType() string {
117 return "tls"
118}
119
120// tlsCreds is the credentials required for authenticating a connection using TLS.
121type tlsCreds struct {
122 // TLS configuration
123 config *tls.Config
124}
125
126func (c tlsCreds) Info() ProtocolInfo {
127 return ProtocolInfo{
128 SecurityProtocol: "tls",
129 SecurityVersion: "1.2",
130 ServerName: c.config.ServerName,
131 }
132}
133
134func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) {
135 // use local cfg to avoid clobbering ServerName if using multiple endpoints
136 cfg := cloneTLSConfig(c.config)
137 if cfg.ServerName == "" {
138 colonPos := strings.LastIndex(addr, ":")
139 if colonPos == -1 {
140 colonPos = len(addr)
141 }
142 cfg.ServerName = addr[:colonPos]
143 }
144 conn := tls.Client(rawConn, cfg)
145 errChannel := make(chan error, 1)
146 go func() {
147 errChannel <- conn.Handshake()
148 }()
149 select {
150 case err := <-errChannel:
151 if err != nil {
152 return nil, nil, err
153 }
154 case <-ctx.Done():
155 return nil, nil, ctx.Err()
156 }
157 return conn, TLSInfo{conn.ConnectionState()}, nil
158}
159
160func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
161 conn := tls.Server(rawConn, c.config)
162 if err := conn.Handshake(); err != nil {
163 return nil, nil, err
164 }
165 return conn, TLSInfo{conn.ConnectionState()}, nil
166}
167
168func (c *tlsCreds) Clone() TransportCredentials {
169 return NewTLS(c.config)
170}
171
172func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
173 c.config.ServerName = serverNameOverride
174 return nil
175}
176
177// NewTLS uses c to construct a TransportCredentials based on TLS.
178func NewTLS(c *tls.Config) TransportCredentials {
179 tc := &tlsCreds{cloneTLSConfig(c)}
180 tc.config.NextProtos = alpnProtoStr
181 return tc
182}
183
184// NewClientTLSFromCert constructs TLS credentials from the input certificate for client.
185// serverNameOverride is for testing only. If set to a non empty string,
186// it will override the virtual host name of authority (e.g. :authority header field) in requests.
187func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials {
188 return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
189}
190
191// NewClientTLSFromFile constructs TLS credentials from the input certificate file for client.
192// serverNameOverride is for testing only. If set to a non empty string,
193// it will override the virtual host name of authority (e.g. :authority header field) in requests.
194func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
195 b, err := ioutil.ReadFile(certFile)
196 if err != nil {
197 return nil, err
198 }
199 cp := x509.NewCertPool()
200 if !cp.AppendCertsFromPEM(b) {
201 return nil, fmt.Errorf("credentials: failed to append certificates")
202 }
203 return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
204}
205
206// NewServerTLSFromCert constructs TLS credentials from the input certificate for server.
207func NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials {
208 return NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}})
209}
210
211// NewServerTLSFromFile constructs TLS credentials from the input certificate file and key
212// file for server.
213func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) {
214 cert, err := tls.LoadX509KeyPair(certFile, keyFile)
215 if err != nil {
216 return nil, err
217 }
218 return NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}}), nil
219}
diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go b/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
new file mode 100644
index 0000000..60409aa
--- /dev/null
+++ b/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
@@ -0,0 +1,60 @@
1// +build go1.7
2// +build !go1.8
3
4/*
5 *
6 * Copyright 2016 gRPC authors.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21
22package credentials
23
24import (
25 "crypto/tls"
26)
27
28// cloneTLSConfig returns a shallow clone of the exported
29// fields of cfg, ignoring the unexported sync.Once, which
30// contains a mutex and must not be copied.
31//
32// If cfg is nil, a new zero tls.Config is returned.
33func cloneTLSConfig(cfg *tls.Config) *tls.Config {
34 if cfg == nil {
35 return &tls.Config{}
36 }
37 return &tls.Config{
38 Rand: cfg.Rand,
39 Time: cfg.Time,
40 Certificates: cfg.Certificates,
41 NameToCertificate: cfg.NameToCertificate,
42 GetCertificate: cfg.GetCertificate,
43 RootCAs: cfg.RootCAs,
44 NextProtos: cfg.NextProtos,
45 ServerName: cfg.ServerName,
46 ClientAuth: cfg.ClientAuth,
47 ClientCAs: cfg.ClientCAs,
48 InsecureSkipVerify: cfg.InsecureSkipVerify,
49 CipherSuites: cfg.CipherSuites,
50 PreferServerCipherSuites: cfg.PreferServerCipherSuites,
51 SessionTicketsDisabled: cfg.SessionTicketsDisabled,
52 SessionTicketKey: cfg.SessionTicketKey,
53 ClientSessionCache: cfg.ClientSessionCache,
54 MinVersion: cfg.MinVersion,
55 MaxVersion: cfg.MaxVersion,
56 CurvePreferences: cfg.CurvePreferences,
57 DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled,
58 Renegotiation: cfg.Renegotiation,
59 }
60}
diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go b/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go
new file mode 100644
index 0000000..93f0e1d
--- /dev/null
+++ b/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go
@@ -0,0 +1,38 @@
1// +build go1.8
2
3/*
4 *
5 * Copyright 2017 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package credentials
22
23import (
24 "crypto/tls"
25)
26
27// cloneTLSConfig returns a shallow clone of the exported
28// fields of cfg, ignoring the unexported sync.Once, which
29// contains a mutex and must not be copied.
30//
31// If cfg is nil, a new zero tls.Config is returned.
32func cloneTLSConfig(cfg *tls.Config) *tls.Config {
33 if cfg == nil {
34 return &tls.Config{}
35 }
36
37 return cfg.Clone()
38}
diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go b/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
new file mode 100644
index 0000000..d6bbcc9
--- /dev/null
+++ b/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
@@ -0,0 +1,57 @@
1// +build !go1.7
2
3/*
4 *
5 * Copyright 2016 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package credentials
22
23import (
24 "crypto/tls"
25)
26
27// cloneTLSConfig returns a shallow clone of the exported
28// fields of cfg, ignoring the unexported sync.Once, which
29// contains a mutex and must not be copied.
30//
31// If cfg is nil, a new zero tls.Config is returned.
32func cloneTLSConfig(cfg *tls.Config) *tls.Config {
33 if cfg == nil {
34 return &tls.Config{}
35 }
36 return &tls.Config{
37 Rand: cfg.Rand,
38 Time: cfg.Time,
39 Certificates: cfg.Certificates,
40 NameToCertificate: cfg.NameToCertificate,
41 GetCertificate: cfg.GetCertificate,
42 RootCAs: cfg.RootCAs,
43 NextProtos: cfg.NextProtos,
44 ServerName: cfg.ServerName,
45 ClientAuth: cfg.ClientAuth,
46 ClientCAs: cfg.ClientCAs,
47 InsecureSkipVerify: cfg.InsecureSkipVerify,
48 CipherSuites: cfg.CipherSuites,
49 PreferServerCipherSuites: cfg.PreferServerCipherSuites,
50 SessionTicketsDisabled: cfg.SessionTicketsDisabled,
51 SessionTicketKey: cfg.SessionTicketKey,
52 ClientSessionCache: cfg.ClientSessionCache,
53 MinVersion: cfg.MinVersion,
54 MaxVersion: cfg.MaxVersion,
55 CurvePreferences: cfg.CurvePreferences,
56 }
57}
diff --git a/vendor/google.golang.org/grpc/doc.go b/vendor/google.golang.org/grpc/doc.go
new file mode 100644
index 0000000..187adbb
--- /dev/null
+++ b/vendor/google.golang.org/grpc/doc.go
@@ -0,0 +1,24 @@
1/*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19/*
20Package grpc implements an RPC system called gRPC.
21
22See grpc.io for more information about gRPC.
23*/
24package grpc // import "google.golang.org/grpc"
diff --git a/vendor/google.golang.org/grpc/go16.go b/vendor/google.golang.org/grpc/go16.go
new file mode 100644
index 0000000..f3dbf21
--- /dev/null
+++ b/vendor/google.golang.org/grpc/go16.go
@@ -0,0 +1,98 @@
1// +build go1.6,!go1.7
2
3/*
4 *
5 * Copyright 2016 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package grpc
22
23import (
24 "fmt"
25 "io"
26 "net"
27 "net/http"
28 "os"
29
30 "golang.org/x/net/context"
31 "google.golang.org/grpc/codes"
32 "google.golang.org/grpc/status"
33 "google.golang.org/grpc/transport"
34)
35
36// dialContext connects to the address on the named network.
37func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
38 return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address)
39}
40
41func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {
42 req.Cancel = ctx.Done()
43 if err := req.Write(conn); err != nil {
44 return fmt.Errorf("failed to write the HTTP request: %v", err)
45 }
46 return nil
47}
48
49// toRPCErr converts an error into an error from the status package.
50func toRPCErr(err error) error {
51 if _, ok := status.FromError(err); ok {
52 return err
53 }
54 switch e := err.(type) {
55 case transport.StreamError:
56 return status.Error(e.Code, e.Desc)
57 case transport.ConnectionError:
58 return status.Error(codes.Unavailable, e.Desc)
59 default:
60 switch err {
61 case context.DeadlineExceeded:
62 return status.Error(codes.DeadlineExceeded, err.Error())
63 case context.Canceled:
64 return status.Error(codes.Canceled, err.Error())
65 case ErrClientConnClosing:
66 return status.Error(codes.FailedPrecondition, err.Error())
67 }
68 }
69 return status.Error(codes.Unknown, err.Error())
70}
71
72// convertCode converts a standard Go error into its canonical code. Note that
73// this is only used to translate the error returned by the server applications.
74func convertCode(err error) codes.Code {
75 switch err {
76 case nil:
77 return codes.OK
78 case io.EOF:
79 return codes.OutOfRange
80 case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
81 return codes.FailedPrecondition
82 case os.ErrInvalid:
83 return codes.InvalidArgument
84 case context.Canceled:
85 return codes.Canceled
86 case context.DeadlineExceeded:
87 return codes.DeadlineExceeded
88 }
89 switch {
90 case os.IsExist(err):
91 return codes.AlreadyExists
92 case os.IsNotExist(err):
93 return codes.NotFound
94 case os.IsPermission(err):
95 return codes.PermissionDenied
96 }
97 return codes.Unknown
98}
diff --git a/vendor/google.golang.org/grpc/go17.go b/vendor/google.golang.org/grpc/go17.go
new file mode 100644
index 0000000..a3421d9
--- /dev/null
+++ b/vendor/google.golang.org/grpc/go17.go
@@ -0,0 +1,98 @@
1// +build go1.7
2
3/*
4 *
5 * Copyright 2016 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package grpc
22
23import (
24 "context"
25 "io"
26 "net"
27 "net/http"
28 "os"
29
30 netctx "golang.org/x/net/context"
31 "google.golang.org/grpc/codes"
32 "google.golang.org/grpc/status"
33 "google.golang.org/grpc/transport"
34)
35
36// dialContext connects to the address on the named network.
37func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
38 return (&net.Dialer{}).DialContext(ctx, network, address)
39}
40
41func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {
42 req = req.WithContext(ctx)
43 if err := req.Write(conn); err != nil {
44 return err
45 }
46 return nil
47}
48
49// toRPCErr converts an error into an error from the status package.
50func toRPCErr(err error) error {
51 if _, ok := status.FromError(err); ok {
52 return err
53 }
54 switch e := err.(type) {
55 case transport.StreamError:
56 return status.Error(e.Code, e.Desc)
57 case transport.ConnectionError:
58 return status.Error(codes.Unavailable, e.Desc)
59 default:
60 switch err {
61 case context.DeadlineExceeded, netctx.DeadlineExceeded:
62 return status.Error(codes.DeadlineExceeded, err.Error())
63 case context.Canceled, netctx.Canceled:
64 return status.Error(codes.Canceled, err.Error())
65 case ErrClientConnClosing:
66 return status.Error(codes.FailedPrecondition, err.Error())
67 }
68 }
69 return status.Error(codes.Unknown, err.Error())
70}
71
72// convertCode converts a standard Go error into its canonical code. Note that
73// this is only used to translate the error returned by the server applications.
74func convertCode(err error) codes.Code {
75 switch err {
76 case nil:
77 return codes.OK
78 case io.EOF:
79 return codes.OutOfRange
80 case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
81 return codes.FailedPrecondition
82 case os.ErrInvalid:
83 return codes.InvalidArgument
84 case context.Canceled, netctx.Canceled:
85 return codes.Canceled
86 case context.DeadlineExceeded, netctx.DeadlineExceeded:
87 return codes.DeadlineExceeded
88 }
89 switch {
90 case os.IsExist(err):
91 return codes.AlreadyExists
92 case os.IsNotExist(err):
93 return codes.NotFound
94 case os.IsPermission(err):
95 return codes.PermissionDenied
96 }
97 return codes.Unknown
98}
diff --git a/vendor/google.golang.org/grpc/grpclb.go b/vendor/google.golang.org/grpc/grpclb.go
new file mode 100644
index 0000000..f7b6b7d
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclb.go
@@ -0,0 +1,737 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "errors"
23 "fmt"
24 "math/rand"
25 "net"
26 "sync"
27 "time"
28
29 "golang.org/x/net/context"
30 "google.golang.org/grpc/codes"
31 lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1"
32 "google.golang.org/grpc/grpclog"
33 "google.golang.org/grpc/metadata"
34 "google.golang.org/grpc/naming"
35)
36
37// Client API for LoadBalancer service.
38// Mostly copied from generated pb.go file.
39// To avoid circular dependency.
40type loadBalancerClient struct {
41 cc *ClientConn
42}
43
44func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...CallOption) (*balanceLoadClientStream, error) {
45 desc := &StreamDesc{
46 StreamName: "BalanceLoad",
47 ServerStreams: true,
48 ClientStreams: true,
49 }
50 stream, err := NewClientStream(ctx, desc, c.cc, "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...)
51 if err != nil {
52 return nil, err
53 }
54 x := &balanceLoadClientStream{stream}
55 return x, nil
56}
57
58type balanceLoadClientStream struct {
59 ClientStream
60}
61
62func (x *balanceLoadClientStream) Send(m *lbpb.LoadBalanceRequest) error {
63 return x.ClientStream.SendMsg(m)
64}
65
66func (x *balanceLoadClientStream) Recv() (*lbpb.LoadBalanceResponse, error) {
67 m := new(lbpb.LoadBalanceResponse)
68 if err := x.ClientStream.RecvMsg(m); err != nil {
69 return nil, err
70 }
71 return m, nil
72}
73
74// NewGRPCLBBalancer creates a grpclb load balancer.
75func NewGRPCLBBalancer(r naming.Resolver) Balancer {
76 return &balancer{
77 r: r,
78 }
79}
80
81type remoteBalancerInfo struct {
82 addr string
83 // the server name used for authentication with the remote LB server.
84 name string
85}
86
87// grpclbAddrInfo consists of the information of a backend server.
88type grpclbAddrInfo struct {
89 addr Address
90 connected bool
91 // dropForRateLimiting indicates whether this particular request should be
92 // dropped by the client for rate limiting.
93 dropForRateLimiting bool
94 // dropForLoadBalancing indicates whether this particular request should be
95 // dropped by the client for load balancing.
96 dropForLoadBalancing bool
97}
98
99type balancer struct {
100 r naming.Resolver
101 target string
102 mu sync.Mutex
103 seq int // a sequence number to make sure addrCh does not get stale addresses.
104 w naming.Watcher
105 addrCh chan []Address
106 rbs []remoteBalancerInfo
107 addrs []*grpclbAddrInfo
108 next int
109 waitCh chan struct{}
110 done bool
111 expTimer *time.Timer
112 rand *rand.Rand
113
114 clientStats lbpb.ClientStats
115}
116
117func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerInfo) error {
118 updates, err := w.Next()
119 if err != nil {
120 grpclog.Warningf("grpclb: failed to get next addr update from watcher: %v", err)
121 return err
122 }
123 b.mu.Lock()
124 defer b.mu.Unlock()
125 if b.done {
126 return ErrClientConnClosing
127 }
128 for _, update := range updates {
129 switch update.Op {
130 case naming.Add:
131 var exist bool
132 for _, v := range b.rbs {
133 // TODO: Is the same addr with different server name a different balancer?
134 if update.Addr == v.addr {
135 exist = true
136 break
137 }
138 }
139 if exist {
140 continue
141 }
142 md, ok := update.Metadata.(*naming.AddrMetadataGRPCLB)
143 if !ok {
144 // TODO: Revisit the handling here and may introduce some fallback mechanism.
145 grpclog.Errorf("The name resolution contains unexpected metadata %v", update.Metadata)
146 continue
147 }
148 switch md.AddrType {
149 case naming.Backend:
150 // TODO: Revisit the handling here and may introduce some fallback mechanism.
151 grpclog.Errorf("The name resolution does not give grpclb addresses")
152 continue
153 case naming.GRPCLB:
154 b.rbs = append(b.rbs, remoteBalancerInfo{
155 addr: update.Addr,
156 name: md.ServerName,
157 })
158 default:
159 grpclog.Errorf("Received unknow address type %d", md.AddrType)
160 continue
161 }
162 case naming.Delete:
163 for i, v := range b.rbs {
164 if update.Addr == v.addr {
165 copy(b.rbs[i:], b.rbs[i+1:])
166 b.rbs = b.rbs[:len(b.rbs)-1]
167 break
168 }
169 }
170 default:
171 grpclog.Errorf("Unknown update.Op %v", update.Op)
172 }
173 }
174 // TODO: Fall back to the basic round-robin load balancing if the resulting address is
175 // not a load balancer.
176 select {
177 case <-ch:
178 default:
179 }
180 ch <- b.rbs
181 return nil
182}
183
184func (b *balancer) serverListExpire(seq int) {
185 b.mu.Lock()
186 defer b.mu.Unlock()
187 // TODO: gRPC interanls do not clear the connections when the server list is stale.
188 // This means RPCs will keep using the existing server list until b receives new
189 // server list even though the list is expired. Revisit this behavior later.
190 if b.done || seq < b.seq {
191 return
192 }
193 b.next = 0
194 b.addrs = nil
195 // Ask grpc internals to close all the corresponding connections.
196 b.addrCh <- nil
197}
198
199func convertDuration(d *lbpb.Duration) time.Duration {
200 if d == nil {
201 return 0
202 }
203 return time.Duration(d.Seconds)*time.Second + time.Duration(d.Nanos)*time.Nanosecond
204}
205
206func (b *balancer) processServerList(l *lbpb.ServerList, seq int) {
207 if l == nil {
208 return
209 }
210 servers := l.GetServers()
211 expiration := convertDuration(l.GetExpirationInterval())
212 var (
213 sl []*grpclbAddrInfo
214 addrs []Address
215 )
216 for _, s := range servers {
217 md := metadata.Pairs("lb-token", s.LoadBalanceToken)
218 ip := net.IP(s.IpAddress)
219 ipStr := ip.String()
220 if ip.To4() == nil {
221 // Add square brackets to ipv6 addresses, otherwise net.Dial() and
222 // net.SplitHostPort() will return too many colons error.
223 ipStr = fmt.Sprintf("[%s]", ipStr)
224 }
225 addr := Address{
226 Addr: fmt.Sprintf("%s:%d", ipStr, s.Port),
227 Metadata: &md,
228 }
229 sl = append(sl, &grpclbAddrInfo{
230 addr: addr,
231 dropForRateLimiting: s.DropForRateLimiting,
232 dropForLoadBalancing: s.DropForLoadBalancing,
233 })
234 addrs = append(addrs, addr)
235 }
236 b.mu.Lock()
237 defer b.mu.Unlock()
238 if b.done || seq < b.seq {
239 return
240 }
241 if len(sl) > 0 {
242 // reset b.next to 0 when replacing the server list.
243 b.next = 0
244 b.addrs = sl
245 b.addrCh <- addrs
246 if b.expTimer != nil {
247 b.expTimer.Stop()
248 b.expTimer = nil
249 }
250 if expiration > 0 {
251 b.expTimer = time.AfterFunc(expiration, func() {
252 b.serverListExpire(seq)
253 })
254 }
255 }
256 return
257}
258
259func (b *balancer) sendLoadReport(s *balanceLoadClientStream, interval time.Duration, done <-chan struct{}) {
260 ticker := time.NewTicker(interval)
261 defer ticker.Stop()
262 for {
263 select {
264 case <-ticker.C:
265 case <-done:
266 return
267 }
268 b.mu.Lock()
269 stats := b.clientStats
270 b.clientStats = lbpb.ClientStats{} // Clear the stats.
271 b.mu.Unlock()
272 t := time.Now()
273 stats.Timestamp = &lbpb.Timestamp{
274 Seconds: t.Unix(),
275 Nanos: int32(t.Nanosecond()),
276 }
277 if err := s.Send(&lbpb.LoadBalanceRequest{
278 LoadBalanceRequestType: &lbpb.LoadBalanceRequest_ClientStats{
279 ClientStats: &stats,
280 },
281 }); err != nil {
282 grpclog.Errorf("grpclb: failed to send load report: %v", err)
283 return
284 }
285 }
286}
287
288func (b *balancer) callRemoteBalancer(lbc *loadBalancerClient, seq int) (retry bool) {
289 ctx, cancel := context.WithCancel(context.Background())
290 defer cancel()
291 stream, err := lbc.BalanceLoad(ctx)
292 if err != nil {
293 grpclog.Errorf("grpclb: failed to perform RPC to the remote balancer %v", err)
294 return
295 }
296 b.mu.Lock()
297 if b.done {
298 b.mu.Unlock()
299 return
300 }
301 b.mu.Unlock()
302 initReq := &lbpb.LoadBalanceRequest{
303 LoadBalanceRequestType: &lbpb.LoadBalanceRequest_InitialRequest{
304 InitialRequest: &lbpb.InitialLoadBalanceRequest{
305 Name: b.target,
306 },
307 },
308 }
309 if err := stream.Send(initReq); err != nil {
310 grpclog.Errorf("grpclb: failed to send init request: %v", err)
311 // TODO: backoff on retry?
312 return true
313 }
314 reply, err := stream.Recv()
315 if err != nil {
316 grpclog.Errorf("grpclb: failed to recv init response: %v", err)
317 // TODO: backoff on retry?
318 return true
319 }
320 initResp := reply.GetInitialResponse()
321 if initResp == nil {
322 grpclog.Errorf("grpclb: reply from remote balancer did not include initial response.")
323 return
324 }
325 // TODO: Support delegation.
326 if initResp.LoadBalancerDelegate != "" {
327 // delegation
328 grpclog.Errorf("TODO: Delegation is not supported yet.")
329 return
330 }
331 streamDone := make(chan struct{})
332 defer close(streamDone)
333 b.mu.Lock()
334 b.clientStats = lbpb.ClientStats{} // Clear client stats.
335 b.mu.Unlock()
336 if d := convertDuration(initResp.ClientStatsReportInterval); d > 0 {
337 go b.sendLoadReport(stream, d, streamDone)
338 }
339 // Retrieve the server list.
340 for {
341 reply, err := stream.Recv()
342 if err != nil {
343 grpclog.Errorf("grpclb: failed to recv server list: %v", err)
344 break
345 }
346 b.mu.Lock()
347 if b.done || seq < b.seq {
348 b.mu.Unlock()
349 return
350 }
351 b.seq++ // tick when receiving a new list of servers.
352 seq = b.seq
353 b.mu.Unlock()
354 if serverList := reply.GetServerList(); serverList != nil {
355 b.processServerList(serverList, seq)
356 }
357 }
358 return true
359}
360
361func (b *balancer) Start(target string, config BalancerConfig) error {
362 b.rand = rand.New(rand.NewSource(time.Now().Unix()))
363 // TODO: Fall back to the basic direct connection if there is no name resolver.
364 if b.r == nil {
365 return errors.New("there is no name resolver installed")
366 }
367 b.target = target
368 b.mu.Lock()
369 if b.done {
370 b.mu.Unlock()
371 return ErrClientConnClosing
372 }
373 b.addrCh = make(chan []Address)
374 w, err := b.r.Resolve(target)
375 if err != nil {
376 b.mu.Unlock()
377 grpclog.Errorf("grpclb: failed to resolve address: %v, err: %v", target, err)
378 return err
379 }
380 b.w = w
381 b.mu.Unlock()
382 balancerAddrsCh := make(chan []remoteBalancerInfo, 1)
383 // Spawn a goroutine to monitor the name resolution of remote load balancer.
384 go func() {
385 for {
386 if err := b.watchAddrUpdates(w, balancerAddrsCh); err != nil {
387 grpclog.Warningf("grpclb: the naming watcher stops working due to %v.\n", err)
388 close(balancerAddrsCh)
389 return
390 }
391 }
392 }()
393 // Spawn a goroutine to talk to the remote load balancer.
394 go func() {
395 var (
396 cc *ClientConn
397 // ccError is closed when there is an error in the current cc.
398 // A new rb should be picked from rbs and connected.
399 ccError chan struct{}
400 rb *remoteBalancerInfo
401 rbs []remoteBalancerInfo
402 rbIdx int
403 )
404
405 defer func() {
406 if ccError != nil {
407 select {
408 case <-ccError:
409 default:
410 close(ccError)
411 }
412 }
413 if cc != nil {
414 cc.Close()
415 }
416 }()
417
418 for {
419 var ok bool
420 select {
421 case rbs, ok = <-balancerAddrsCh:
422 if !ok {
423 return
424 }
425 foundIdx := -1
426 if rb != nil {
427 for i, trb := range rbs {
428 if trb == *rb {
429 foundIdx = i
430 break
431 }
432 }
433 }
434 if foundIdx >= 0 {
435 if foundIdx >= 1 {
436 // Move the address in use to the beginning of the list.
437 b.rbs[0], b.rbs[foundIdx] = b.rbs[foundIdx], b.rbs[0]
438 rbIdx = 0
439 }
440 continue // If found, don't dial new cc.
441 } else if len(rbs) > 0 {
442 // Pick a random one from the list, instead of always using the first one.
443 if l := len(rbs); l > 1 && rb != nil {
444 tmpIdx := b.rand.Intn(l - 1)
445 b.rbs[0], b.rbs[tmpIdx] = b.rbs[tmpIdx], b.rbs[0]
446 }
447 rbIdx = 0
448 rb = &rbs[0]
449 } else {
450 // foundIdx < 0 && len(rbs) <= 0.
451 rb = nil
452 }
453 case <-ccError:
454 ccError = nil
455 if rbIdx < len(rbs)-1 {
456 rbIdx++
457 rb = &rbs[rbIdx]
458 } else {
459 rb = nil
460 }
461 }
462
463 if rb == nil {
464 continue
465 }
466
467 if cc != nil {
468 cc.Close()
469 }
470 // Talk to the remote load balancer to get the server list.
471 var (
472 err error
473 dopts []DialOption
474 )
475 if creds := config.DialCreds; creds != nil {
476 if rb.name != "" {
477 if err := creds.OverrideServerName(rb.name); err != nil {
478 grpclog.Warningf("grpclb: failed to override the server name in the credentials: %v", err)
479 continue
480 }
481 }
482 dopts = append(dopts, WithTransportCredentials(creds))
483 } else {
484 dopts = append(dopts, WithInsecure())
485 }
486 if dialer := config.Dialer; dialer != nil {
487 // WithDialer takes a different type of function, so we instead use a special DialOption here.
488 dopts = append(dopts, func(o *dialOptions) { o.copts.Dialer = dialer })
489 }
490 ccError = make(chan struct{})
491 cc, err = Dial(rb.addr, dopts...)
492 if err != nil {
493 grpclog.Warningf("grpclb: failed to setup a connection to the remote balancer %v: %v", rb.addr, err)
494 close(ccError)
495 continue
496 }
497 b.mu.Lock()
498 b.seq++ // tick when getting a new balancer address
499 seq := b.seq
500 b.next = 0
501 b.mu.Unlock()
502 go func(cc *ClientConn, ccError chan struct{}) {
503 lbc := &loadBalancerClient{cc}
504 b.callRemoteBalancer(lbc, seq)
505 cc.Close()
506 select {
507 case <-ccError:
508 default:
509 close(ccError)
510 }
511 }(cc, ccError)
512 }
513 }()
514 return nil
515}
516
517func (b *balancer) down(addr Address, err error) {
518 b.mu.Lock()
519 defer b.mu.Unlock()
520 for _, a := range b.addrs {
521 if addr == a.addr {
522 a.connected = false
523 break
524 }
525 }
526}
527
528func (b *balancer) Up(addr Address) func(error) {
529 b.mu.Lock()
530 defer b.mu.Unlock()
531 if b.done {
532 return nil
533 }
534 var cnt int
535 for _, a := range b.addrs {
536 if a.addr == addr {
537 if a.connected {
538 return nil
539 }
540 a.connected = true
541 }
542 if a.connected && !a.dropForRateLimiting && !a.dropForLoadBalancing {
543 cnt++
544 }
545 }
546 // addr is the only one which is connected. Notify the Get() callers who are blocking.
547 if cnt == 1 && b.waitCh != nil {
548 close(b.waitCh)
549 b.waitCh = nil
550 }
551 return func(err error) {
552 b.down(addr, err)
553 }
554}
555
556func (b *balancer) Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) {
557 var ch chan struct{}
558 b.mu.Lock()
559 if b.done {
560 b.mu.Unlock()
561 err = ErrClientConnClosing
562 return
563 }
564 seq := b.seq
565
566 defer func() {
567 if err != nil {
568 return
569 }
570 put = func() {
571 s, ok := rpcInfoFromContext(ctx)
572 if !ok {
573 return
574 }
575 b.mu.Lock()
576 defer b.mu.Unlock()
577 if b.done || seq < b.seq {
578 return
579 }
580 b.clientStats.NumCallsFinished++
581 if !s.bytesSent {
582 b.clientStats.NumCallsFinishedWithClientFailedToSend++
583 } else if s.bytesReceived {
584 b.clientStats.NumCallsFinishedKnownReceived++
585 }
586 }
587 }()
588
589 b.clientStats.NumCallsStarted++
590 if len(b.addrs) > 0 {
591 if b.next >= len(b.addrs) {
592 b.next = 0
593 }
594 next := b.next
595 for {
596 a := b.addrs[next]
597 next = (next + 1) % len(b.addrs)
598 if a.connected {
599 if !a.dropForRateLimiting && !a.dropForLoadBalancing {
600 addr = a.addr
601 b.next = next
602 b.mu.Unlock()
603 return
604 }
605 if !opts.BlockingWait {
606 b.next = next
607 if a.dropForLoadBalancing {
608 b.clientStats.NumCallsFinished++
609 b.clientStats.NumCallsFinishedWithDropForLoadBalancing++
610 } else if a.dropForRateLimiting {
611 b.clientStats.NumCallsFinished++
612 b.clientStats.NumCallsFinishedWithDropForRateLimiting++
613 }
614 b.mu.Unlock()
615 err = Errorf(codes.Unavailable, "%s drops requests", a.addr.Addr)
616 return
617 }
618 }
619 if next == b.next {
620 // Has iterated all the possible address but none is connected.
621 break
622 }
623 }
624 }
625 if !opts.BlockingWait {
626 if len(b.addrs) == 0 {
627 b.clientStats.NumCallsFinished++
628 b.clientStats.NumCallsFinishedWithClientFailedToSend++
629 b.mu.Unlock()
630 err = Errorf(codes.Unavailable, "there is no address available")
631 return
632 }
633 // Returns the next addr on b.addrs for a failfast RPC.
634 addr = b.addrs[b.next].addr
635 b.next++
636 b.mu.Unlock()
637 return
638 }
639 // Wait on b.waitCh for non-failfast RPCs.
640 if b.waitCh == nil {
641 ch = make(chan struct{})
642 b.waitCh = ch
643 } else {
644 ch = b.waitCh
645 }
646 b.mu.Unlock()
647 for {
648 select {
649 case <-ctx.Done():
650 b.mu.Lock()
651 b.clientStats.NumCallsFinished++
652 b.clientStats.NumCallsFinishedWithClientFailedToSend++
653 b.mu.Unlock()
654 err = ctx.Err()
655 return
656 case <-ch:
657 b.mu.Lock()
658 if b.done {
659 b.clientStats.NumCallsFinished++
660 b.clientStats.NumCallsFinishedWithClientFailedToSend++
661 b.mu.Unlock()
662 err = ErrClientConnClosing
663 return
664 }
665
666 if len(b.addrs) > 0 {
667 if b.next >= len(b.addrs) {
668 b.next = 0
669 }
670 next := b.next
671 for {
672 a := b.addrs[next]
673 next = (next + 1) % len(b.addrs)
674 if a.connected {
675 if !a.dropForRateLimiting && !a.dropForLoadBalancing {
676 addr = a.addr
677 b.next = next
678 b.mu.Unlock()
679 return
680 }
681 if !opts.BlockingWait {
682 b.next = next
683 if a.dropForLoadBalancing {
684 b.clientStats.NumCallsFinished++
685 b.clientStats.NumCallsFinishedWithDropForLoadBalancing++
686 } else if a.dropForRateLimiting {
687 b.clientStats.NumCallsFinished++
688 b.clientStats.NumCallsFinishedWithDropForRateLimiting++
689 }
690 b.mu.Unlock()
691 err = Errorf(codes.Unavailable, "drop requests for the addreess %s", a.addr.Addr)
692 return
693 }
694 }
695 if next == b.next {
696 // Has iterated all the possible address but none is connected.
697 break
698 }
699 }
700 }
701 // The newly added addr got removed by Down() again.
702 if b.waitCh == nil {
703 ch = make(chan struct{})
704 b.waitCh = ch
705 } else {
706 ch = b.waitCh
707 }
708 b.mu.Unlock()
709 }
710 }
711}
712
713func (b *balancer) Notify() <-chan []Address {
714 return b.addrCh
715}
716
717func (b *balancer) Close() error {
718 b.mu.Lock()
719 defer b.mu.Unlock()
720 if b.done {
721 return errBalancerClosed
722 }
723 b.done = true
724 if b.expTimer != nil {
725 b.expTimer.Stop()
726 }
727 if b.waitCh != nil {
728 close(b.waitCh)
729 }
730 if b.addrCh != nil {
731 close(b.addrCh)
732 }
733 if b.w != nil {
734 b.w.Close()
735 }
736 return nil
737}
diff --git a/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go
new file mode 100644
index 0000000..f63941b
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go
@@ -0,0 +1,629 @@
1// Code generated by protoc-gen-go.
2// source: grpclb.proto
3// DO NOT EDIT!
4
5/*
6Package grpc_lb_v1 is a generated protocol buffer package.
7
8It is generated from these files:
9 grpclb.proto
10
11It has these top-level messages:
12 Duration
13 Timestamp
14 LoadBalanceRequest
15 InitialLoadBalanceRequest
16 ClientStats
17 LoadBalanceResponse
18 InitialLoadBalanceResponse
19 ServerList
20 Server
21*/
22package grpc_lb_v1
23
24import proto "github.com/golang/protobuf/proto"
25import fmt "fmt"
26import math "math"
27
28// Reference imports to suppress errors if they are not otherwise used.
29var _ = proto.Marshal
30var _ = fmt.Errorf
31var _ = math.Inf
32
33// This is a compile-time assertion to ensure that this generated file
34// is compatible with the proto package it is being compiled against.
35// A compilation error at this line likely means your copy of the
36// proto package needs to be updated.
37const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
38
39type Duration struct {
40 // Signed seconds of the span of time. Must be from -315,576,000,000
41 // to +315,576,000,000 inclusive.
42 Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
43 // Signed fractions of a second at nanosecond resolution of the span
44 // of time. Durations less than one second are represented with a 0
45 // `seconds` field and a positive or negative `nanos` field. For durations
46 // of one second or more, a non-zero value for the `nanos` field must be
47 // of the same sign as the `seconds` field. Must be from -999,999,999
48 // to +999,999,999 inclusive.
49 Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
50}
51
52func (m *Duration) Reset() { *m = Duration{} }
53func (m *Duration) String() string { return proto.CompactTextString(m) }
54func (*Duration) ProtoMessage() {}
55func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
56
57func (m *Duration) GetSeconds() int64 {
58 if m != nil {
59 return m.Seconds
60 }
61 return 0
62}
63
64func (m *Duration) GetNanos() int32 {
65 if m != nil {
66 return m.Nanos
67 }
68 return 0
69}
70
71type Timestamp struct {
72 // Represents seconds of UTC time since Unix epoch
73 // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
74 // 9999-12-31T23:59:59Z inclusive.
75 Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
76 // Non-negative fractions of a second at nanosecond resolution. Negative
77 // second values with fractions must still have non-negative nanos values
78 // that count forward in time. Must be from 0 to 999,999,999
79 // inclusive.
80 Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
81}
82
83func (m *Timestamp) Reset() { *m = Timestamp{} }
84func (m *Timestamp) String() string { return proto.CompactTextString(m) }
85func (*Timestamp) ProtoMessage() {}
86func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
87
88func (m *Timestamp) GetSeconds() int64 {
89 if m != nil {
90 return m.Seconds
91 }
92 return 0
93}
94
95func (m *Timestamp) GetNanos() int32 {
96 if m != nil {
97 return m.Nanos
98 }
99 return 0
100}
101
102type LoadBalanceRequest struct {
103 // Types that are valid to be assigned to LoadBalanceRequestType:
104 // *LoadBalanceRequest_InitialRequest
105 // *LoadBalanceRequest_ClientStats
106 LoadBalanceRequestType isLoadBalanceRequest_LoadBalanceRequestType `protobuf_oneof:"load_balance_request_type"`
107}
108
109func (m *LoadBalanceRequest) Reset() { *m = LoadBalanceRequest{} }
110func (m *LoadBalanceRequest) String() string { return proto.CompactTextString(m) }
111func (*LoadBalanceRequest) ProtoMessage() {}
112func (*LoadBalanceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
113
114type isLoadBalanceRequest_LoadBalanceRequestType interface {
115 isLoadBalanceRequest_LoadBalanceRequestType()
116}
117
118type LoadBalanceRequest_InitialRequest struct {
119 InitialRequest *InitialLoadBalanceRequest `protobuf:"bytes,1,opt,name=initial_request,json=initialRequest,oneof"`
120}
121type LoadBalanceRequest_ClientStats struct {
122 ClientStats *ClientStats `protobuf:"bytes,2,opt,name=client_stats,json=clientStats,oneof"`
123}
124
125func (*LoadBalanceRequest_InitialRequest) isLoadBalanceRequest_LoadBalanceRequestType() {}
126func (*LoadBalanceRequest_ClientStats) isLoadBalanceRequest_LoadBalanceRequestType() {}
127
128func (m *LoadBalanceRequest) GetLoadBalanceRequestType() isLoadBalanceRequest_LoadBalanceRequestType {
129 if m != nil {
130 return m.LoadBalanceRequestType
131 }
132 return nil
133}
134
135func (m *LoadBalanceRequest) GetInitialRequest() *InitialLoadBalanceRequest {
136 if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_InitialRequest); ok {
137 return x.InitialRequest
138 }
139 return nil
140}
141
142func (m *LoadBalanceRequest) GetClientStats() *ClientStats {
143 if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_ClientStats); ok {
144 return x.ClientStats
145 }
146 return nil
147}
148
149// XXX_OneofFuncs is for the internal use of the proto package.
150func (*LoadBalanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
151 return _LoadBalanceRequest_OneofMarshaler, _LoadBalanceRequest_OneofUnmarshaler, _LoadBalanceRequest_OneofSizer, []interface{}{
152 (*LoadBalanceRequest_InitialRequest)(nil),
153 (*LoadBalanceRequest_ClientStats)(nil),
154 }
155}
156
157func _LoadBalanceRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
158 m := msg.(*LoadBalanceRequest)
159 // load_balance_request_type
160 switch x := m.LoadBalanceRequestType.(type) {
161 case *LoadBalanceRequest_InitialRequest:
162 b.EncodeVarint(1<<3 | proto.WireBytes)
163 if err := b.EncodeMessage(x.InitialRequest); err != nil {
164 return err
165 }
166 case *LoadBalanceRequest_ClientStats:
167 b.EncodeVarint(2<<3 | proto.WireBytes)
168 if err := b.EncodeMessage(x.ClientStats); err != nil {
169 return err
170 }
171 case nil:
172 default:
173 return fmt.Errorf("LoadBalanceRequest.LoadBalanceRequestType has unexpected type %T", x)
174 }
175 return nil
176}
177
178func _LoadBalanceRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
179 m := msg.(*LoadBalanceRequest)
180 switch tag {
181 case 1: // load_balance_request_type.initial_request
182 if wire != proto.WireBytes {
183 return true, proto.ErrInternalBadWireType
184 }
185 msg := new(InitialLoadBalanceRequest)
186 err := b.DecodeMessage(msg)
187 m.LoadBalanceRequestType = &LoadBalanceRequest_InitialRequest{msg}
188 return true, err
189 case 2: // load_balance_request_type.client_stats
190 if wire != proto.WireBytes {
191 return true, proto.ErrInternalBadWireType
192 }
193 msg := new(ClientStats)
194 err := b.DecodeMessage(msg)
195 m.LoadBalanceRequestType = &LoadBalanceRequest_ClientStats{msg}
196 return true, err
197 default:
198 return false, nil
199 }
200}
201
202func _LoadBalanceRequest_OneofSizer(msg proto.Message) (n int) {
203 m := msg.(*LoadBalanceRequest)
204 // load_balance_request_type
205 switch x := m.LoadBalanceRequestType.(type) {
206 case *LoadBalanceRequest_InitialRequest:
207 s := proto.Size(x.InitialRequest)
208 n += proto.SizeVarint(1<<3 | proto.WireBytes)
209 n += proto.SizeVarint(uint64(s))
210 n += s
211 case *LoadBalanceRequest_ClientStats:
212 s := proto.Size(x.ClientStats)
213 n += proto.SizeVarint(2<<3 | proto.WireBytes)
214 n += proto.SizeVarint(uint64(s))
215 n += s
216 case nil:
217 default:
218 panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
219 }
220 return n
221}
222
223type InitialLoadBalanceRequest struct {
224 // Name of load balanced service (IE, balancer.service.com)
225 // length should be less than 256 bytes.
226 Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
227}
228
229func (m *InitialLoadBalanceRequest) Reset() { *m = InitialLoadBalanceRequest{} }
230func (m *InitialLoadBalanceRequest) String() string { return proto.CompactTextString(m) }
231func (*InitialLoadBalanceRequest) ProtoMessage() {}
232func (*InitialLoadBalanceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
233
234func (m *InitialLoadBalanceRequest) GetName() string {
235 if m != nil {
236 return m.Name
237 }
238 return ""
239}
240
241// Contains client level statistics that are useful to load balancing. Each
242// count except the timestamp should be reset to zero after reporting the stats.
243type ClientStats struct {
244 // The timestamp of generating the report.
245 Timestamp *Timestamp `protobuf:"bytes,1,opt,name=timestamp" json:"timestamp,omitempty"`
246 // The total number of RPCs that started.
247 NumCallsStarted int64 `protobuf:"varint,2,opt,name=num_calls_started,json=numCallsStarted" json:"num_calls_started,omitempty"`
248 // The total number of RPCs that finished.
249 NumCallsFinished int64 `protobuf:"varint,3,opt,name=num_calls_finished,json=numCallsFinished" json:"num_calls_finished,omitempty"`
250 // The total number of RPCs that were dropped by the client because of rate
251 // limiting.
252 NumCallsFinishedWithDropForRateLimiting int64 `protobuf:"varint,4,opt,name=num_calls_finished_with_drop_for_rate_limiting,json=numCallsFinishedWithDropForRateLimiting" json:"num_calls_finished_with_drop_for_rate_limiting,omitempty"`
253 // The total number of RPCs that were dropped by the client because of load
254 // balancing.
255 NumCallsFinishedWithDropForLoadBalancing int64 `protobuf:"varint,5,opt,name=num_calls_finished_with_drop_for_load_balancing,json=numCallsFinishedWithDropForLoadBalancing" json:"num_calls_finished_with_drop_for_load_balancing,omitempty"`
256 // The total number of RPCs that failed to reach a server except dropped RPCs.
257 NumCallsFinishedWithClientFailedToSend int64 `protobuf:"varint,6,opt,name=num_calls_finished_with_client_failed_to_send,json=numCallsFinishedWithClientFailedToSend" json:"num_calls_finished_with_client_failed_to_send,omitempty"`
258 // The total number of RPCs that finished and are known to have been received
259 // by a server.
260 NumCallsFinishedKnownReceived int64 `protobuf:"varint,7,opt,name=num_calls_finished_known_received,json=numCallsFinishedKnownReceived" json:"num_calls_finished_known_received,omitempty"`
261}
262
263func (m *ClientStats) Reset() { *m = ClientStats{} }
264func (m *ClientStats) String() string { return proto.CompactTextString(m) }
265func (*ClientStats) ProtoMessage() {}
266func (*ClientStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
267
268func (m *ClientStats) GetTimestamp() *Timestamp {
269 if m != nil {
270 return m.Timestamp
271 }
272 return nil
273}
274
275func (m *ClientStats) GetNumCallsStarted() int64 {
276 if m != nil {
277 return m.NumCallsStarted
278 }
279 return 0
280}
281
282func (m *ClientStats) GetNumCallsFinished() int64 {
283 if m != nil {
284 return m.NumCallsFinished
285 }
286 return 0
287}
288
289func (m *ClientStats) GetNumCallsFinishedWithDropForRateLimiting() int64 {
290 if m != nil {
291 return m.NumCallsFinishedWithDropForRateLimiting
292 }
293 return 0
294}
295
296func (m *ClientStats) GetNumCallsFinishedWithDropForLoadBalancing() int64 {
297 if m != nil {
298 return m.NumCallsFinishedWithDropForLoadBalancing
299 }
300 return 0
301}
302
303func (m *ClientStats) GetNumCallsFinishedWithClientFailedToSend() int64 {
304 if m != nil {
305 return m.NumCallsFinishedWithClientFailedToSend
306 }
307 return 0
308}
309
310func (m *ClientStats) GetNumCallsFinishedKnownReceived() int64 {
311 if m != nil {
312 return m.NumCallsFinishedKnownReceived
313 }
314 return 0
315}
316
317type LoadBalanceResponse struct {
318 // Types that are valid to be assigned to LoadBalanceResponseType:
319 // *LoadBalanceResponse_InitialResponse
320 // *LoadBalanceResponse_ServerList
321 LoadBalanceResponseType isLoadBalanceResponse_LoadBalanceResponseType `protobuf_oneof:"load_balance_response_type"`
322}
323
324func (m *LoadBalanceResponse) Reset() { *m = LoadBalanceResponse{} }
325func (m *LoadBalanceResponse) String() string { return proto.CompactTextString(m) }
326func (*LoadBalanceResponse) ProtoMessage() {}
327func (*LoadBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
328
329type isLoadBalanceResponse_LoadBalanceResponseType interface {
330 isLoadBalanceResponse_LoadBalanceResponseType()
331}
332
333type LoadBalanceResponse_InitialResponse struct {
334 InitialResponse *InitialLoadBalanceResponse `protobuf:"bytes,1,opt,name=initial_response,json=initialResponse,oneof"`
335}
336type LoadBalanceResponse_ServerList struct {
337 ServerList *ServerList `protobuf:"bytes,2,opt,name=server_list,json=serverList,oneof"`
338}
339
340func (*LoadBalanceResponse_InitialResponse) isLoadBalanceResponse_LoadBalanceResponseType() {}
341func (*LoadBalanceResponse_ServerList) isLoadBalanceResponse_LoadBalanceResponseType() {}
342
343func (m *LoadBalanceResponse) GetLoadBalanceResponseType() isLoadBalanceResponse_LoadBalanceResponseType {
344 if m != nil {
345 return m.LoadBalanceResponseType
346 }
347 return nil
348}
349
350func (m *LoadBalanceResponse) GetInitialResponse() *InitialLoadBalanceResponse {
351 if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_InitialResponse); ok {
352 return x.InitialResponse
353 }
354 return nil
355}
356
357func (m *LoadBalanceResponse) GetServerList() *ServerList {
358 if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_ServerList); ok {
359 return x.ServerList
360 }
361 return nil
362}
363
364// XXX_OneofFuncs is for the internal use of the proto package.
365func (*LoadBalanceResponse) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
366 return _LoadBalanceResponse_OneofMarshaler, _LoadBalanceResponse_OneofUnmarshaler, _LoadBalanceResponse_OneofSizer, []interface{}{
367 (*LoadBalanceResponse_InitialResponse)(nil),
368 (*LoadBalanceResponse_ServerList)(nil),
369 }
370}
371
372func _LoadBalanceResponse_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
373 m := msg.(*LoadBalanceResponse)
374 // load_balance_response_type
375 switch x := m.LoadBalanceResponseType.(type) {
376 case *LoadBalanceResponse_InitialResponse:
377 b.EncodeVarint(1<<3 | proto.WireBytes)
378 if err := b.EncodeMessage(x.InitialResponse); err != nil {
379 return err
380 }
381 case *LoadBalanceResponse_ServerList:
382 b.EncodeVarint(2<<3 | proto.WireBytes)
383 if err := b.EncodeMessage(x.ServerList); err != nil {
384 return err
385 }
386 case nil:
387 default:
388 return fmt.Errorf("LoadBalanceResponse.LoadBalanceResponseType has unexpected type %T", x)
389 }
390 return nil
391}
392
393func _LoadBalanceResponse_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
394 m := msg.(*LoadBalanceResponse)
395 switch tag {
396 case 1: // load_balance_response_type.initial_response
397 if wire != proto.WireBytes {
398 return true, proto.ErrInternalBadWireType
399 }
400 msg := new(InitialLoadBalanceResponse)
401 err := b.DecodeMessage(msg)
402 m.LoadBalanceResponseType = &LoadBalanceResponse_InitialResponse{msg}
403 return true, err
404 case 2: // load_balance_response_type.server_list
405 if wire != proto.WireBytes {
406 return true, proto.ErrInternalBadWireType
407 }
408 msg := new(ServerList)
409 err := b.DecodeMessage(msg)
410 m.LoadBalanceResponseType = &LoadBalanceResponse_ServerList{msg}
411 return true, err
412 default:
413 return false, nil
414 }
415}
416
417func _LoadBalanceResponse_OneofSizer(msg proto.Message) (n int) {
418 m := msg.(*LoadBalanceResponse)
419 // load_balance_response_type
420 switch x := m.LoadBalanceResponseType.(type) {
421 case *LoadBalanceResponse_InitialResponse:
422 s := proto.Size(x.InitialResponse)
423 n += proto.SizeVarint(1<<3 | proto.WireBytes)
424 n += proto.SizeVarint(uint64(s))
425 n += s
426 case *LoadBalanceResponse_ServerList:
427 s := proto.Size(x.ServerList)
428 n += proto.SizeVarint(2<<3 | proto.WireBytes)
429 n += proto.SizeVarint(uint64(s))
430 n += s
431 case nil:
432 default:
433 panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
434 }
435 return n
436}
437
438type InitialLoadBalanceResponse struct {
439 // This is an application layer redirect that indicates the client should use
440 // the specified server for load balancing. When this field is non-empty in
441 // the response, the client should open a separate connection to the
442 // load_balancer_delegate and call the BalanceLoad method. Its length should
443 // be less than 64 bytes.
444 LoadBalancerDelegate string `protobuf:"bytes,1,opt,name=load_balancer_delegate,json=loadBalancerDelegate" json:"load_balancer_delegate,omitempty"`
445 // This interval defines how often the client should send the client stats
446 // to the load balancer. Stats should only be reported when the duration is
447 // positive.
448 ClientStatsReportInterval *Duration `protobuf:"bytes,2,opt,name=client_stats_report_interval,json=clientStatsReportInterval" json:"client_stats_report_interval,omitempty"`
449}
450
451func (m *InitialLoadBalanceResponse) Reset() { *m = InitialLoadBalanceResponse{} }
452func (m *InitialLoadBalanceResponse) String() string { return proto.CompactTextString(m) }
453func (*InitialLoadBalanceResponse) ProtoMessage() {}
454func (*InitialLoadBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
455
456func (m *InitialLoadBalanceResponse) GetLoadBalancerDelegate() string {
457 if m != nil {
458 return m.LoadBalancerDelegate
459 }
460 return ""
461}
462
463func (m *InitialLoadBalanceResponse) GetClientStatsReportInterval() *Duration {
464 if m != nil {
465 return m.ClientStatsReportInterval
466 }
467 return nil
468}
469
470type ServerList struct {
471 // Contains a list of servers selected by the load balancer. The list will
472 // be updated when server resolutions change or as needed to balance load
473 // across more servers. The client should consume the server list in order
474 // unless instructed otherwise via the client_config.
475 Servers []*Server `protobuf:"bytes,1,rep,name=servers" json:"servers,omitempty"`
476 // Indicates the amount of time that the client should consider this server
477 // list as valid. It may be considered stale after waiting this interval of
478 // time after receiving the list. If the interval is not positive, the
479 // client can assume the list is valid until the next list is received.
480 ExpirationInterval *Duration `protobuf:"bytes,3,opt,name=expiration_interval,json=expirationInterval" json:"expiration_interval,omitempty"`
481}
482
483func (m *ServerList) Reset() { *m = ServerList{} }
484func (m *ServerList) String() string { return proto.CompactTextString(m) }
485func (*ServerList) ProtoMessage() {}
486func (*ServerList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
487
488func (m *ServerList) GetServers() []*Server {
489 if m != nil {
490 return m.Servers
491 }
492 return nil
493}
494
495func (m *ServerList) GetExpirationInterval() *Duration {
496 if m != nil {
497 return m.ExpirationInterval
498 }
499 return nil
500}
501
502// Contains server information. When none of the [drop_for_*] fields are true,
503// use the other fields. When drop_for_rate_limiting is true, ignore all other
504// fields. Use drop_for_load_balancing only when it is true and
505// drop_for_rate_limiting is false.
506type Server struct {
507 // A resolved address for the server, serialized in network-byte-order. It may
508 // either be an IPv4 or IPv6 address.
509 IpAddress []byte `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"`
510 // A resolved port number for the server.
511 Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"`
512 // An opaque but printable token given to the frontend for each pick. All
513 // frontend requests for that pick must include the token in its initial
514 // metadata. The token is used by the backend to verify the request and to
515 // allow the backend to report load to the gRPC LB system.
516 //
517 // Its length is variable but less than 50 bytes.
518 LoadBalanceToken string `protobuf:"bytes,3,opt,name=load_balance_token,json=loadBalanceToken" json:"load_balance_token,omitempty"`
519 // Indicates whether this particular request should be dropped by the client
520 // for rate limiting.
521 DropForRateLimiting bool `protobuf:"varint,4,opt,name=drop_for_rate_limiting,json=dropForRateLimiting" json:"drop_for_rate_limiting,omitempty"`
522 // Indicates whether this particular request should be dropped by the client
523 // for load balancing.
524 DropForLoadBalancing bool `protobuf:"varint,5,opt,name=drop_for_load_balancing,json=dropForLoadBalancing" json:"drop_for_load_balancing,omitempty"`
525}
526
527func (m *Server) Reset() { *m = Server{} }
528func (m *Server) String() string { return proto.CompactTextString(m) }
529func (*Server) ProtoMessage() {}
530func (*Server) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
531
532func (m *Server) GetIpAddress() []byte {
533 if m != nil {
534 return m.IpAddress
535 }
536 return nil
537}
538
539func (m *Server) GetPort() int32 {
540 if m != nil {
541 return m.Port
542 }
543 return 0
544}
545
546func (m *Server) GetLoadBalanceToken() string {
547 if m != nil {
548 return m.LoadBalanceToken
549 }
550 return ""
551}
552
553func (m *Server) GetDropForRateLimiting() bool {
554 if m != nil {
555 return m.DropForRateLimiting
556 }
557 return false
558}
559
560func (m *Server) GetDropForLoadBalancing() bool {
561 if m != nil {
562 return m.DropForLoadBalancing
563 }
564 return false
565}
566
567func init() {
568 proto.RegisterType((*Duration)(nil), "grpc.lb.v1.Duration")
569 proto.RegisterType((*Timestamp)(nil), "grpc.lb.v1.Timestamp")
570 proto.RegisterType((*LoadBalanceRequest)(nil), "grpc.lb.v1.LoadBalanceRequest")
571 proto.RegisterType((*InitialLoadBalanceRequest)(nil), "grpc.lb.v1.InitialLoadBalanceRequest")
572 proto.RegisterType((*ClientStats)(nil), "grpc.lb.v1.ClientStats")
573 proto.RegisterType((*LoadBalanceResponse)(nil), "grpc.lb.v1.LoadBalanceResponse")
574 proto.RegisterType((*InitialLoadBalanceResponse)(nil), "grpc.lb.v1.InitialLoadBalanceResponse")
575 proto.RegisterType((*ServerList)(nil), "grpc.lb.v1.ServerList")
576 proto.RegisterType((*Server)(nil), "grpc.lb.v1.Server")
577}
578
579func init() { proto.RegisterFile("grpclb.proto", fileDescriptor0) }
580
581var fileDescriptor0 = []byte{
582 // 733 bytes of a gzipped FileDescriptorProto
583 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x4e, 0x1b, 0x39,
584 0x14, 0x66, 0x36, 0xfc, 0xe5, 0x24, 0x5a, 0x58, 0x93, 0x85, 0xc0, 0xc2, 0x2e, 0x1b, 0xa9, 0x34,
585 0xaa, 0x68, 0x68, 0x43, 0x7b, 0xd1, 0x9f, 0x9b, 0x02, 0x45, 0x41, 0xe5, 0xa2, 0x72, 0xa8, 0x7a,
586 0x55, 0x59, 0x4e, 0xc6, 0x80, 0xc5, 0xc4, 0x9e, 0xda, 0x4e, 0x68, 0x2f, 0x7b, 0xd9, 0x47, 0xe9,
587 0x63, 0x54, 0x7d, 0x86, 0xbe, 0x4f, 0x65, 0x7b, 0x26, 0x33, 0x90, 0x1f, 0xd4, 0xbb, 0xf1, 0xf1,
588 0x77, 0xbe, 0xf3, 0xf9, 0xd8, 0xdf, 0x19, 0x28, 0x5f, 0xa8, 0xb8, 0x1b, 0x75, 0x1a, 0xb1, 0x92,
589 0x46, 0x22, 0xb0, 0xab, 0x46, 0xd4, 0x69, 0x0c, 0x1e, 0xd7, 0x9e, 0xc3, 0xe2, 0x51, 0x5f, 0x51,
590 0xc3, 0xa5, 0x40, 0x55, 0x58, 0xd0, 0xac, 0x2b, 0x45, 0xa8, 0xab, 0xc1, 0x76, 0x50, 0x2f, 0xe0,
591 0x74, 0x89, 0x2a, 0x30, 0x27, 0xa8, 0x90, 0xba, 0xfa, 0xc7, 0x76, 0x50, 0x9f, 0xc3, 0x7e, 0x51,
592 0x7b, 0x01, 0xc5, 0x33, 0xde, 0x63, 0xda, 0xd0, 0x5e, 0xfc, 0xdb, 0xc9, 0xdf, 0x03, 0x40, 0xa7,
593 0x92, 0x86, 0x07, 0x34, 0xa2, 0xa2, 0xcb, 0x30, 0xfb, 0xd8, 0x67, 0xda, 0xa0, 0xb7, 0xb0, 0xc4,
594 0x05, 0x37, 0x9c, 0x46, 0x44, 0xf9, 0x90, 0xa3, 0x2b, 0x35, 0xef, 0x35, 0x32, 0xd5, 0x8d, 0x13,
595 0x0f, 0x19, 0xcd, 0x6f, 0xcd, 0xe0, 0x3f, 0x93, 0xfc, 0x94, 0xf1, 0x25, 0x94, 0xbb, 0x11, 0x67,
596 0xc2, 0x10, 0x6d, 0xa8, 0xf1, 0x2a, 0x4a, 0xcd, 0xb5, 0x3c, 0xdd, 0xa1, 0xdb, 0x6f, 0xdb, 0xed,
597 0xd6, 0x0c, 0x2e, 0x75, 0xb3, 0xe5, 0xc1, 0x3f, 0xb0, 0x1e, 0x49, 0x1a, 0x92, 0x8e, 0x2f, 0x93,
598 0x8a, 0x22, 0xe6, 0x73, 0xcc, 0x6a, 0x7b, 0xb0, 0x3e, 0x51, 0x09, 0x42, 0x30, 0x2b, 0x68, 0x8f,
599 0x39, 0xf9, 0x45, 0xec, 0xbe, 0x6b, 0x5f, 0x67, 0xa1, 0x94, 0x2b, 0x86, 0xf6, 0xa1, 0x68, 0xd2,
600 0x0e, 0x26, 0xe7, 0xfc, 0x3b, 0x2f, 0x6c, 0xd8, 0x5e, 0x9c, 0xe1, 0xd0, 0x03, 0xf8, 0x4b, 0xf4,
601 0x7b, 0xa4, 0x4b, 0xa3, 0x48, 0xdb, 0x33, 0x29, 0xc3, 0x42, 0x77, 0xaa, 0x02, 0x5e, 0x12, 0xfd,
602 0xde, 0xa1, 0x8d, 0xb7, 0x7d, 0x18, 0xed, 0x02, 0xca, 0xb0, 0xe7, 0x5c, 0x70, 0x7d, 0xc9, 0xc2,
603 0x6a, 0xc1, 0x81, 0x97, 0x53, 0xf0, 0x71, 0x12, 0x47, 0x04, 0x1a, 0xa3, 0x68, 0x72, 0xcd, 0xcd,
604 0x25, 0x09, 0x95, 0x8c, 0xc9, 0xb9, 0x54, 0x44, 0x51, 0xc3, 0x48, 0xc4, 0x7b, 0xdc, 0x70, 0x71,
605 0x51, 0x9d, 0x75, 0x4c, 0xf7, 0x6f, 0x33, 0xbd, 0xe7, 0xe6, 0xf2, 0x48, 0xc9, 0xf8, 0x58, 0x2a,
606 0x4c, 0x0d, 0x3b, 0x4d, 0xe0, 0x88, 0xc2, 0xde, 0x9d, 0x05, 0x72, 0xed, 0xb6, 0x15, 0xe6, 0x5c,
607 0x85, 0xfa, 0x94, 0x0a, 0x59, 0xef, 0x6d, 0x89, 0x0f, 0xf0, 0x70, 0x52, 0x89, 0xe4, 0x19, 0x9c,
608 0x53, 0x1e, 0xb1, 0x90, 0x18, 0x49, 0x34, 0x13, 0x61, 0x75, 0xde, 0x15, 0xd8, 0x19, 0x57, 0xc0,
609 0x5f, 0xd5, 0xb1, 0xc3, 0x9f, 0xc9, 0x36, 0x13, 0x21, 0x6a, 0xc1, 0xff, 0x63, 0xe8, 0xaf, 0x84,
610 0xbc, 0x16, 0x44, 0xb1, 0x2e, 0xe3, 0x03, 0x16, 0x56, 0x17, 0x1c, 0xe5, 0xd6, 0x6d, 0xca, 0x37,
611 0x16, 0x85, 0x13, 0x50, 0xed, 0x47, 0x00, 0x2b, 0x37, 0x9e, 0x8d, 0x8e, 0xa5, 0xd0, 0x0c, 0xb5,
612 0x61, 0x39, 0x73, 0x80, 0x8f, 0x25, 0x4f, 0x63, 0xe7, 0x2e, 0x0b, 0x78, 0x74, 0x6b, 0x06, 0x2f,
613 0x0d, 0x3d, 0x90, 0x90, 0x3e, 0x83, 0x92, 0x66, 0x6a, 0xc0, 0x14, 0x89, 0xb8, 0x36, 0x89, 0x07,
614 0x56, 0xf3, 0x7c, 0x6d, 0xb7, 0x7d, 0xca, 0x9d, 0x87, 0x40, 0x0f, 0x57, 0x07, 0x9b, 0xb0, 0x71,
615 0xcb, 0x01, 0x9e, 0xd3, 0x5b, 0xe0, 0x5b, 0x00, 0x1b, 0x93, 0xa5, 0xa0, 0x27, 0xb0, 0x9a, 0x4f,
616 0x56, 0x24, 0x64, 0x11, 0xbb, 0xa0, 0x26, 0xb5, 0x45, 0x25, 0xca, 0x92, 0xd4, 0x51, 0xb2, 0x87,
617 0xde, 0xc1, 0x66, 0xde, 0xb2, 0x44, 0xb1, 0x58, 0x2a, 0x43, 0xb8, 0x30, 0x4c, 0x0d, 0x68, 0x94,
618 0xc8, 0xaf, 0xe4, 0xe5, 0xa7, 0x43, 0x0c, 0xaf, 0xe7, 0xdc, 0x8b, 0x5d, 0xde, 0x49, 0x92, 0x56,
619 0xfb, 0x12, 0x00, 0x64, 0xc7, 0x44, 0xbb, 0x76, 0x62, 0xd9, 0x95, 0x9d, 0x58, 0x85, 0x7a, 0xa9,
620 0x89, 0x46, 0xfb, 0x81, 0x53, 0x08, 0x7a, 0x0d, 0x2b, 0xec, 0x53, 0xcc, 0x7d, 0x95, 0x4c, 0x4a,
621 0x61, 0x8a, 0x14, 0x94, 0x25, 0x0c, 0x35, 0xfc, 0x0c, 0x60, 0xde, 0x53, 0xa3, 0x2d, 0x00, 0x1e,
622 0x13, 0x1a, 0x86, 0x8a, 0x69, 0x3f, 0x34, 0xcb, 0xb8, 0xc8, 0xe3, 0x57, 0x3e, 0x60, 0xe7, 0x87,
623 0x55, 0x9f, 0x4c, 0x4d, 0xf7, 0x6d, 0xed, 0x7c, 0xe3, 0x2e, 0x8c, 0xbc, 0x62, 0xc2, 0x69, 0x28,
624 0xe2, 0xe5, 0x5c, 0x2b, 0xcf, 0x6c, 0x1c, 0xed, 0xc3, 0xea, 0x14, 0xdb, 0x2e, 0xe2, 0x95, 0x70,
625 0x8c, 0x45, 0x9f, 0xc2, 0xda, 0x34, 0x2b, 0x2e, 0xe2, 0x4a, 0x38, 0xc6, 0x76, 0xcd, 0x0e, 0x94,
626 0x73, 0xf7, 0xaf, 0x10, 0x86, 0x52, 0xf2, 0x6d, 0xc3, 0xe8, 0xdf, 0x7c, 0x83, 0x46, 0x87, 0xe5,
627 0xc6, 0x7f, 0x13, 0xf7, 0xfd, 0x43, 0xaa, 0x07, 0x8f, 0x82, 0xce, 0xbc, 0xfb, 0x7d, 0xed, 0xff,
628 0x0a, 0x00, 0x00, 0xff, 0xff, 0x64, 0xbf, 0xda, 0x5e, 0xce, 0x06, 0x00, 0x00,
629}
diff --git a/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto
new file mode 100644
index 0000000..b13b343
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto
@@ -0,0 +1,164 @@
1// Copyright 2016 gRPC authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15syntax = "proto3";
16
17package grpc.lb.v1;
18
19message Duration {
20 // Signed seconds of the span of time. Must be from -315,576,000,000
21 // to +315,576,000,000 inclusive.
22 int64 seconds = 1;
23
24 // Signed fractions of a second at nanosecond resolution of the span
25 // of time. Durations less than one second are represented with a 0
26 // `seconds` field and a positive or negative `nanos` field. For durations
27 // of one second or more, a non-zero value for the `nanos` field must be
28 // of the same sign as the `seconds` field. Must be from -999,999,999
29 // to +999,999,999 inclusive.
30 int32 nanos = 2;
31}
32
33message Timestamp {
34
35 // Represents seconds of UTC time since Unix epoch
36 // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
37 // 9999-12-31T23:59:59Z inclusive.
38 int64 seconds = 1;
39
40 // Non-negative fractions of a second at nanosecond resolution. Negative
41 // second values with fractions must still have non-negative nanos values
42 // that count forward in time. Must be from 0 to 999,999,999
43 // inclusive.
44 int32 nanos = 2;
45}
46
47service LoadBalancer {
48 // Bidirectional rpc to get a list of servers.
49 rpc BalanceLoad(stream LoadBalanceRequest)
50 returns (stream LoadBalanceResponse);
51}
52
53message LoadBalanceRequest {
54 oneof load_balance_request_type {
55 // This message should be sent on the first request to the load balancer.
56 InitialLoadBalanceRequest initial_request = 1;
57
58 // The client stats should be periodically reported to the load balancer
59 // based on the duration defined in the InitialLoadBalanceResponse.
60 ClientStats client_stats = 2;
61 }
62}
63
64message InitialLoadBalanceRequest {
65 // Name of load balanced service (IE, balancer.service.com)
66 // length should be less than 256 bytes.
67 string name = 1;
68}
69
70// Contains client level statistics that are useful to load balancing. Each
71// count except the timestamp should be reset to zero after reporting the stats.
72message ClientStats {
73 // The timestamp of generating the report.
74 Timestamp timestamp = 1;
75
76 // The total number of RPCs that started.
77 int64 num_calls_started = 2;
78
79 // The total number of RPCs that finished.
80 int64 num_calls_finished = 3;
81
82 // The total number of RPCs that were dropped by the client because of rate
83 // limiting.
84 int64 num_calls_finished_with_drop_for_rate_limiting = 4;
85
86 // The total number of RPCs that were dropped by the client because of load
87 // balancing.
88 int64 num_calls_finished_with_drop_for_load_balancing = 5;
89
90 // The total number of RPCs that failed to reach a server except dropped RPCs.
91 int64 num_calls_finished_with_client_failed_to_send = 6;
92
93 // The total number of RPCs that finished and are known to have been received
94 // by a server.
95 int64 num_calls_finished_known_received = 7;
96}
97
98message LoadBalanceResponse {
99 oneof load_balance_response_type {
100 // This message should be sent on the first response to the client.
101 InitialLoadBalanceResponse initial_response = 1;
102
103 // Contains the list of servers selected by the load balancer. The client
104 // should send requests to these servers in the specified order.
105 ServerList server_list = 2;
106 }
107}
108
109message InitialLoadBalanceResponse {
110 // This is an application layer redirect that indicates the client should use
111 // the specified server for load balancing. When this field is non-empty in
112 // the response, the client should open a separate connection to the
113 // load_balancer_delegate and call the BalanceLoad method. Its length should
114 // be less than 64 bytes.
115 string load_balancer_delegate = 1;
116
117 // This interval defines how often the client should send the client stats
118 // to the load balancer. Stats should only be reported when the duration is
119 // positive.
120 Duration client_stats_report_interval = 2;
121}
122
123message ServerList {
124 // Contains a list of servers selected by the load balancer. The list will
125 // be updated when server resolutions change or as needed to balance load
126 // across more servers. The client should consume the server list in order
127 // unless instructed otherwise via the client_config.
128 repeated Server servers = 1;
129
130 // Indicates the amount of time that the client should consider this server
131 // list as valid. It may be considered stale after waiting this interval of
132 // time after receiving the list. If the interval is not positive, the
133 // client can assume the list is valid until the next list is received.
134 Duration expiration_interval = 3;
135}
136
137// Contains server information. When none of the [drop_for_*] fields are true,
138// use the other fields. When drop_for_rate_limiting is true, ignore all other
139// fields. Use drop_for_load_balancing only when it is true and
140// drop_for_rate_limiting is false.
141message Server {
142 // A resolved address for the server, serialized in network-byte-order. It may
143 // either be an IPv4 or IPv6 address.
144 bytes ip_address = 1;
145
146 // A resolved port number for the server.
147 int32 port = 2;
148
149 // An opaque but printable token given to the frontend for each pick. All
150 // frontend requests for that pick must include the token in its initial
151 // metadata. The token is used by the backend to verify the request and to
152 // allow the backend to report load to the gRPC LB system.
153 //
154 // Its length is variable but less than 50 bytes.
155 string load_balance_token = 3;
156
157 // Indicates whether this particular request should be dropped by the client
158 // for rate limiting.
159 bool drop_for_rate_limiting = 4;
160
161 // Indicates whether this particular request should be dropped by the client
162 // for load balancing.
163 bool drop_for_load_balancing = 5;
164}
diff --git a/vendor/google.golang.org/grpc/grpclog/grpclog.go b/vendor/google.golang.org/grpc/grpclog/grpclog.go
new file mode 100644
index 0000000..16a7d88
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclog/grpclog.go
@@ -0,0 +1,123 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package grpclog defines logging for grpc.
20//
21// All logs in transport package only go to verbose level 2.
22// All logs in other packages in grpc are logged in spite of the verbosity level.
23//
24// In the default logger,
25// severity level can be set by environment variable GRPC_GO_LOG_SEVERITY_LEVEL,
26// verbosity level can be set by GRPC_GO_LOG_VERBOSITY_LEVEL.
27package grpclog // import "google.golang.org/grpc/grpclog"
28
29import "os"
30
31var logger = newLoggerV2()
32
33// V reports whether verbosity level l is at least the requested verbose level.
34func V(l int) bool {
35 return logger.V(l)
36}
37
38// Info logs to the INFO log.
39func Info(args ...interface{}) {
40 logger.Info(args...)
41}
42
43// Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf.
44func Infof(format string, args ...interface{}) {
45 logger.Infof(format, args...)
46}
47
48// Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println.
49func Infoln(args ...interface{}) {
50 logger.Infoln(args...)
51}
52
53// Warning logs to the WARNING log.
54func Warning(args ...interface{}) {
55 logger.Warning(args...)
56}
57
58// Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf.
59func Warningf(format string, args ...interface{}) {
60 logger.Warningf(format, args...)
61}
62
63// Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println.
64func Warningln(args ...interface{}) {
65 logger.Warningln(args...)
66}
67
68// Error logs to the ERROR log.
69func Error(args ...interface{}) {
70 logger.Error(args...)
71}
72
73// Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf.
74func Errorf(format string, args ...interface{}) {
75 logger.Errorf(format, args...)
76}
77
78// Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println.
79func Errorln(args ...interface{}) {
80 logger.Errorln(args...)
81}
82
83// Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print.
84// It calls os.Exit() with exit code 1.
85func Fatal(args ...interface{}) {
86 logger.Fatal(args...)
87 // Make sure fatal logs will exit.
88 os.Exit(1)
89}
90
91// Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf.
92// It calles os.Exit() with exit code 1.
93func Fatalf(format string, args ...interface{}) {
94 logger.Fatalf(format, args...)
95 // Make sure fatal logs will exit.
96 os.Exit(1)
97}
98
99// Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println.
100// It calle os.Exit()) with exit code 1.
101func Fatalln(args ...interface{}) {
102 logger.Fatalln(args...)
103 // Make sure fatal logs will exit.
104 os.Exit(1)
105}
106
107// Print prints to the logger. Arguments are handled in the manner of fmt.Print.
108// Deprecated: use Info.
109func Print(args ...interface{}) {
110 logger.Info(args...)
111}
112
113// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
114// Deprecated: use Infof.
115func Printf(format string, args ...interface{}) {
116 logger.Infof(format, args...)
117}
118
119// Println prints to the logger. Arguments are handled in the manner of fmt.Println.
120// Deprecated: use Infoln.
121func Println(args ...interface{}) {
122 logger.Infoln(args...)
123}
diff --git a/vendor/google.golang.org/grpc/grpclog/logger.go b/vendor/google.golang.org/grpc/grpclog/logger.go
new file mode 100644
index 0000000..d03b239
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclog/logger.go
@@ -0,0 +1,83 @@
1/*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpclog
20
21// Logger mimics golang's standard Logger as an interface.
22// Deprecated: use LoggerV2.
23type Logger interface {
24 Fatal(args ...interface{})
25 Fatalf(format string, args ...interface{})
26 Fatalln(args ...interface{})
27 Print(args ...interface{})
28 Printf(format string, args ...interface{})
29 Println(args ...interface{})
30}
31
32// SetLogger sets the logger that is used in grpc. Call only from
33// init() functions.
34// Deprecated: use SetLoggerV2.
35func SetLogger(l Logger) {
36 logger = &loggerWrapper{Logger: l}
37}
38
39// loggerWrapper wraps Logger into a LoggerV2.
40type loggerWrapper struct {
41 Logger
42}
43
44func (g *loggerWrapper) Info(args ...interface{}) {
45 g.Logger.Print(args...)
46}
47
48func (g *loggerWrapper) Infoln(args ...interface{}) {
49 g.Logger.Println(args...)
50}
51
52func (g *loggerWrapper) Infof(format string, args ...interface{}) {
53 g.Logger.Printf(format, args...)
54}
55
56func (g *loggerWrapper) Warning(args ...interface{}) {
57 g.Logger.Print(args...)
58}
59
60func (g *loggerWrapper) Warningln(args ...interface{}) {
61 g.Logger.Println(args...)
62}
63
64func (g *loggerWrapper) Warningf(format string, args ...interface{}) {
65 g.Logger.Printf(format, args...)
66}
67
68func (g *loggerWrapper) Error(args ...interface{}) {
69 g.Logger.Print(args...)
70}
71
72func (g *loggerWrapper) Errorln(args ...interface{}) {
73 g.Logger.Println(args...)
74}
75
76func (g *loggerWrapper) Errorf(format string, args ...interface{}) {
77 g.Logger.Printf(format, args...)
78}
79
80func (g *loggerWrapper) V(l int) bool {
81 // Returns true for all verbose level.
82 return true
83}
diff --git a/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/vendor/google.golang.org/grpc/grpclog/loggerv2.go
new file mode 100644
index 0000000..d493257
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclog/loggerv2.go
@@ -0,0 +1,195 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpclog
20
21import (
22 "io"
23 "io/ioutil"
24 "log"
25 "os"
26 "strconv"
27)
28
29// LoggerV2 does underlying logging work for grpclog.
30type LoggerV2 interface {
31 // Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
32 Info(args ...interface{})
33 // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
34 Infoln(args ...interface{})
35 // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
36 Infof(format string, args ...interface{})
37 // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
38 Warning(args ...interface{})
39 // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
40 Warningln(args ...interface{})
41 // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
42 Warningf(format string, args ...interface{})
43 // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
44 Error(args ...interface{})
45 // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
46 Errorln(args ...interface{})
47 // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
48 Errorf(format string, args ...interface{})
49 // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
50 // gRPC ensures that all Fatal logs will exit with os.Exit(1).
51 // Implementations may also call os.Exit() with a non-zero exit code.
52 Fatal(args ...interface{})
53 // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
54 // gRPC ensures that all Fatal logs will exit with os.Exit(1).
55 // Implementations may also call os.Exit() with a non-zero exit code.
56 Fatalln(args ...interface{})
57 // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
58 // gRPC ensures that all Fatal logs will exit with os.Exit(1).
59 // Implementations may also call os.Exit() with a non-zero exit code.
60 Fatalf(format string, args ...interface{})
61 // V reports whether verbosity level l is at least the requested verbose level.
62 V(l int) bool
63}
64
65// SetLoggerV2 sets logger that is used in grpc to a V2 logger.
66// Not mutex-protected, should be called before any gRPC functions.
67func SetLoggerV2(l LoggerV2) {
68 logger = l
69}
70
71const (
72 // infoLog indicates Info severity.
73 infoLog int = iota
74 // warningLog indicates Warning severity.
75 warningLog
76 // errorLog indicates Error severity.
77 errorLog
78 // fatalLog indicates Fatal severity.
79 fatalLog
80)
81
82// severityName contains the string representation of each severity.
83var severityName = []string{
84 infoLog: "INFO",
85 warningLog: "WARNING",
86 errorLog: "ERROR",
87 fatalLog: "FATAL",
88}
89
90// loggerT is the default logger used by grpclog.
91type loggerT struct {
92 m []*log.Logger
93 v int
94}
95
96// NewLoggerV2 creates a loggerV2 with the provided writers.
97// Fatal logs will be written to errorW, warningW, infoW, followed by exit(1).
98// Error logs will be written to errorW, warningW and infoW.
99// Warning logs will be written to warningW and infoW.
100// Info logs will be written to infoW.
101func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 {
102 return NewLoggerV2WithVerbosity(infoW, warningW, errorW, 0)
103}
104
105// NewLoggerV2WithVerbosity creates a loggerV2 with the provided writers and
106// verbosity level.
107func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 {
108 var m []*log.Logger
109 m = append(m, log.New(infoW, severityName[infoLog]+": ", log.LstdFlags))
110 m = append(m, log.New(io.MultiWriter(infoW, warningW), severityName[warningLog]+": ", log.LstdFlags))
111 ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal.
112 m = append(m, log.New(ew, severityName[errorLog]+": ", log.LstdFlags))
113 m = append(m, log.New(ew, severityName[fatalLog]+": ", log.LstdFlags))
114 return &loggerT{m: m, v: v}
115}
116
117// newLoggerV2 creates a loggerV2 to be used as default logger.
118// All logs are written to stderr.
119func newLoggerV2() LoggerV2 {
120 errorW := ioutil.Discard
121 warningW := ioutil.Discard
122 infoW := ioutil.Discard
123
124 logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")
125 switch logLevel {
126 case "", "ERROR", "error": // If env is unset, set level to ERROR.
127 errorW = os.Stderr
128 case "WARNING", "warning":
129 warningW = os.Stderr
130 case "INFO", "info":
131 infoW = os.Stderr
132 }
133
134 var v int
135 vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")
136 if vl, err := strconv.Atoi(vLevel); err == nil {
137 v = vl
138 }
139 return NewLoggerV2WithVerbosity(infoW, warningW, errorW, v)
140}
141
142func (g *loggerT) Info(args ...interface{}) {
143 g.m[infoLog].Print(args...)
144}
145
146func (g *loggerT) Infoln(args ...interface{}) {
147 g.m[infoLog].Println(args...)
148}
149
150func (g *loggerT) Infof(format string, args ...interface{}) {
151 g.m[infoLog].Printf(format, args...)
152}
153
154func (g *loggerT) Warning(args ...interface{}) {
155 g.m[warningLog].Print(args...)
156}
157
158func (g *loggerT) Warningln(args ...interface{}) {
159 g.m[warningLog].Println(args...)
160}
161
162func (g *loggerT) Warningf(format string, args ...interface{}) {
163 g.m[warningLog].Printf(format, args...)
164}
165
166func (g *loggerT) Error(args ...interface{}) {
167 g.m[errorLog].Print(args...)
168}
169
170func (g *loggerT) Errorln(args ...interface{}) {
171 g.m[errorLog].Println(args...)
172}
173
174func (g *loggerT) Errorf(format string, args ...interface{}) {
175 g.m[errorLog].Printf(format, args...)
176}
177
178func (g *loggerT) Fatal(args ...interface{}) {
179 g.m[fatalLog].Fatal(args...)
180 // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit().
181}
182
183func (g *loggerT) Fatalln(args ...interface{}) {
184 g.m[fatalLog].Fatalln(args...)
185 // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit().
186}
187
188func (g *loggerT) Fatalf(format string, args ...interface{}) {
189 g.m[fatalLog].Fatalf(format, args...)
190 // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit().
191}
192
193func (g *loggerT) V(l int) bool {
194 return l <= g.v
195}
diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
new file mode 100644
index 0000000..89c4d45
--- /dev/null
+++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
@@ -0,0 +1,176 @@
1// Code generated by protoc-gen-go.
2// source: health.proto
3// DO NOT EDIT!
4
5/*
6Package grpc_health_v1 is a generated protocol buffer package.
7
8It is generated from these files:
9 health.proto
10
11It has these top-level messages:
12 HealthCheckRequest
13 HealthCheckResponse
14*/
15package grpc_health_v1
16
17import proto "github.com/golang/protobuf/proto"
18import fmt "fmt"
19import math "math"
20
21import (
22 context "golang.org/x/net/context"
23 grpc "google.golang.org/grpc"
24)
25
26// Reference imports to suppress errors if they are not otherwise used.
27var _ = proto.Marshal
28var _ = fmt.Errorf
29var _ = math.Inf
30
31// This is a compile-time assertion to ensure that this generated file
32// is compatible with the proto package it is being compiled against.
33// A compilation error at this line likely means your copy of the
34// proto package needs to be updated.
35const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
36
37type HealthCheckResponse_ServingStatus int32
38
39const (
40 HealthCheckResponse_UNKNOWN HealthCheckResponse_ServingStatus = 0
41 HealthCheckResponse_SERVING HealthCheckResponse_ServingStatus = 1
42 HealthCheckResponse_NOT_SERVING HealthCheckResponse_ServingStatus = 2
43)
44
45var HealthCheckResponse_ServingStatus_name = map[int32]string{
46 0: "UNKNOWN",
47 1: "SERVING",
48 2: "NOT_SERVING",
49}
50var HealthCheckResponse_ServingStatus_value = map[string]int32{
51 "UNKNOWN": 0,
52 "SERVING": 1,
53 "NOT_SERVING": 2,
54}
55
56func (x HealthCheckResponse_ServingStatus) String() string {
57 return proto.EnumName(HealthCheckResponse_ServingStatus_name, int32(x))
58}
59func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) {
60 return fileDescriptor0, []int{1, 0}
61}
62
63type HealthCheckRequest struct {
64 Service string `protobuf:"bytes,1,opt,name=service" json:"service,omitempty"`
65}
66
67func (m *HealthCheckRequest) Reset() { *m = HealthCheckRequest{} }
68func (m *HealthCheckRequest) String() string { return proto.CompactTextString(m) }
69func (*HealthCheckRequest) ProtoMessage() {}
70func (*HealthCheckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
71
72type HealthCheckResponse struct {
73 Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,enum=grpc.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"`
74}
75
76func (m *HealthCheckResponse) Reset() { *m = HealthCheckResponse{} }
77func (m *HealthCheckResponse) String() string { return proto.CompactTextString(m) }
78func (*HealthCheckResponse) ProtoMessage() {}
79func (*HealthCheckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
80
81func init() {
82 proto.RegisterType((*HealthCheckRequest)(nil), "grpc.health.v1.HealthCheckRequest")
83 proto.RegisterType((*HealthCheckResponse)(nil), "grpc.health.v1.HealthCheckResponse")
84 proto.RegisterEnum("grpc.health.v1.HealthCheckResponse_ServingStatus", HealthCheckResponse_ServingStatus_name, HealthCheckResponse_ServingStatus_value)
85}
86
87// Reference imports to suppress errors if they are not otherwise used.
88var _ context.Context
89var _ grpc.ClientConn
90
91// This is a compile-time assertion to ensure that this generated file
92// is compatible with the grpc package it is being compiled against.
93const _ = grpc.SupportPackageIsVersion4
94
95// Client API for Health service
96
97type HealthClient interface {
98 Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error)
99}
100
101type healthClient struct {
102 cc *grpc.ClientConn
103}
104
105func NewHealthClient(cc *grpc.ClientConn) HealthClient {
106 return &healthClient{cc}
107}
108
109func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) {
110 out := new(HealthCheckResponse)
111 err := grpc.Invoke(ctx, "/grpc.health.v1.Health/Check", in, out, c.cc, opts...)
112 if err != nil {
113 return nil, err
114 }
115 return out, nil
116}
117
118// Server API for Health service
119
120type HealthServer interface {
121 Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error)
122}
123
124func RegisterHealthServer(s *grpc.Server, srv HealthServer) {
125 s.RegisterService(&_Health_serviceDesc, srv)
126}
127
128func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
129 in := new(HealthCheckRequest)
130 if err := dec(in); err != nil {
131 return nil, err
132 }
133 if interceptor == nil {
134 return srv.(HealthServer).Check(ctx, in)
135 }
136 info := &grpc.UnaryServerInfo{
137 Server: srv,
138 FullMethod: "/grpc.health.v1.Health/Check",
139 }
140 handler := func(ctx context.Context, req interface{}) (interface{}, error) {
141 return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest))
142 }
143 return interceptor(ctx, in, info, handler)
144}
145
146var _Health_serviceDesc = grpc.ServiceDesc{
147 ServiceName: "grpc.health.v1.Health",
148 HandlerType: (*HealthServer)(nil),
149 Methods: []grpc.MethodDesc{
150 {
151 MethodName: "Check",
152 Handler: _Health_Check_Handler,
153 },
154 },
155 Streams: []grpc.StreamDesc{},
156 Metadata: "health.proto",
157}
158
159func init() { proto.RegisterFile("health.proto", fileDescriptor0) }
160
161var fileDescriptor0 = []byte{
162 // 204 bytes of a gzipped FileDescriptorProto
163 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x48, 0x4d, 0xcc,
164 0x29, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4b, 0x2f, 0x2a, 0x48, 0xd6, 0x83,
165 0x0a, 0x95, 0x19, 0x2a, 0xe9, 0x71, 0x09, 0x79, 0x80, 0x39, 0xce, 0x19, 0xa9, 0xc9, 0xd9, 0x41,
166 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0xa9, 0x45, 0x65, 0x99, 0xc9,
167 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x30, 0xae, 0xd2, 0x1c, 0x46, 0x2e, 0x61, 0x14,
168 0x0d, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x42, 0x9e, 0x5c, 0x6c, 0xc5, 0x25, 0x89, 0x25, 0xa5,
169 0xc5, 0x60, 0x0d, 0x7c, 0x46, 0x86, 0x7a, 0xa8, 0x16, 0xe9, 0x61, 0xd1, 0xa4, 0x17, 0x0c, 0x32,
170 0x34, 0x2f, 0x3d, 0x18, 0xac, 0x31, 0x08, 0x6a, 0x80, 0x92, 0x15, 0x17, 0x2f, 0x8a, 0x84, 0x10,
171 0x37, 0x17, 0x7b, 0xa8, 0x9f, 0xb7, 0x9f, 0x7f, 0xb8, 0x9f, 0x00, 0x03, 0x88, 0x13, 0xec, 0x1a,
172 0x14, 0xe6, 0xe9, 0xe7, 0x2e, 0xc0, 0x28, 0xc4, 0xcf, 0xc5, 0xed, 0xe7, 0x1f, 0x12, 0x0f, 0x13,
173 0x60, 0x32, 0x8a, 0xe2, 0x62, 0x83, 0x58, 0x24, 0x14, 0xc0, 0xc5, 0x0a, 0xb6, 0x4c, 0x48, 0x09,
174 0xaf, 0x4b, 0xc0, 0xfe, 0x95, 0x52, 0x26, 0xc2, 0xb5, 0x49, 0x6c, 0xe0, 0x10, 0x34, 0x06, 0x04,
175 0x00, 0x00, 0xff, 0xff, 0xac, 0x56, 0x2a, 0xcb, 0x51, 0x01, 0x00, 0x00,
176}
diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.proto b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.proto
new file mode 100644
index 0000000..6072fdc
--- /dev/null
+++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.proto
@@ -0,0 +1,34 @@
1// Copyright 2017 gRPC authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15syntax = "proto3";
16
17package grpc.health.v1;
18
19message HealthCheckRequest {
20 string service = 1;
21}
22
23message HealthCheckResponse {
24 enum ServingStatus {
25 UNKNOWN = 0;
26 SERVING = 1;
27 NOT_SERVING = 2;
28 }
29 ServingStatus status = 1;
30}
31
32service Health{
33 rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
34}
diff --git a/vendor/google.golang.org/grpc/health/health.go b/vendor/google.golang.org/grpc/health/health.go
new file mode 100644
index 0000000..4dccbc7
--- /dev/null
+++ b/vendor/google.golang.org/grpc/health/health.go
@@ -0,0 +1,70 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package health provides some utility functions to health-check a server. The implementation
20// is based on protobuf. Users need to write their own implementations if other IDLs are used.
21package health
22
23import (
24 "sync"
25
26 "golang.org/x/net/context"
27 "google.golang.org/grpc"
28 "google.golang.org/grpc/codes"
29 healthpb "google.golang.org/grpc/health/grpc_health_v1"
30)
31
32// Server implements `service Health`.
33type Server struct {
34 mu sync.Mutex
35 // statusMap stores the serving status of the services this Server monitors.
36 statusMap map[string]healthpb.HealthCheckResponse_ServingStatus
37}
38
39// NewServer returns a new Server.
40func NewServer() *Server {
41 return &Server{
42 statusMap: make(map[string]healthpb.HealthCheckResponse_ServingStatus),
43 }
44}
45
46// Check implements `service Health`.
47func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {
48 s.mu.Lock()
49 defer s.mu.Unlock()
50 if in.Service == "" {
51 // check the server overall health status.
52 return &healthpb.HealthCheckResponse{
53 Status: healthpb.HealthCheckResponse_SERVING,
54 }, nil
55 }
56 if status, ok := s.statusMap[in.Service]; ok {
57 return &healthpb.HealthCheckResponse{
58 Status: status,
59 }, nil
60 }
61 return nil, grpc.Errorf(codes.NotFound, "unknown service")
62}
63
64// SetServingStatus is called when need to reset the serving status of a service
65// or insert a new service entry into the statusMap.
66func (s *Server) SetServingStatus(service string, status healthpb.HealthCheckResponse_ServingStatus) {
67 s.mu.Lock()
68 s.statusMap[service] = status
69 s.mu.Unlock()
70}
diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go
new file mode 100644
index 0000000..06dc825
--- /dev/null
+++ b/vendor/google.golang.org/grpc/interceptor.go
@@ -0,0 +1,75 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "golang.org/x/net/context"
23)
24
25// UnaryInvoker is called by UnaryClientInterceptor to complete RPCs.
26type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error
27
28// UnaryClientInterceptor intercepts the execution of a unary RPC on the client. invoker is the handler to complete the RPC
29// and it is the responsibility of the interceptor to call it.
30// This is an EXPERIMENTAL API.
31type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error
32
33// Streamer is called by StreamClientInterceptor to create a ClientStream.
34type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error)
35
36// StreamClientInterceptor intercepts the creation of ClientStream. It may return a custom ClientStream to intercept all I/O
37// operations. streamer is the handler to create a ClientStream and it is the responsibility of the interceptor to call it.
38// This is an EXPERIMENTAL API.
39type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error)
40
41// UnaryServerInfo consists of various information about a unary RPC on
42// server side. All per-rpc information may be mutated by the interceptor.
43type UnaryServerInfo struct {
44 // Server is the service implementation the user provides. This is read-only.
45 Server interface{}
46 // FullMethod is the full RPC method string, i.e., /package.service/method.
47 FullMethod string
48}
49
50// UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal
51// execution of a unary RPC.
52type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)
53
54// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
55// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
56// of the service method implementation. It is the responsibility of the interceptor to invoke handler
57// to complete the RPC.
58type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
59
60// StreamServerInfo consists of various information about a streaming RPC on
61// server side. All per-rpc information may be mutated by the interceptor.
62type StreamServerInfo struct {
63 // FullMethod is the full RPC method string, i.e., /package.service/method.
64 FullMethod string
65 // IsClientStream indicates whether the RPC is a client streaming RPC.
66 IsClientStream bool
67 // IsServerStream indicates whether the RPC is a server streaming RPC.
68 IsServerStream bool
69}
70
71// StreamServerInterceptor provides a hook to intercept the execution of a streaming RPC on the server.
72// info contains all the information of this RPC the interceptor can operate on. And handler is the
73// service method implementation. It is the responsibility of the interceptor to invoke handler to
74// complete the RPC.
75type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error
diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go
new file mode 100644
index 0000000..0708383
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/internal.go
@@ -0,0 +1,34 @@
1/*
2 * Copyright 2016 gRPC authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18// Package internal contains gRPC-internal code for testing, to avoid polluting
19// the godoc of the top-level grpc package.
20package internal
21
22// TestingCloseConns closes all existing transports but keeps
23// grpcServer.lis accepting new connections.
24//
25// The provided grpcServer must be of type *grpc.Server. It is untyped
26// for circular dependency reasons.
27var TestingCloseConns func(grpcServer interface{})
28
29// TestingUseHandlerImpl enables the http.Handler-based server implementation.
30// It must be called before Serve and requires TLS credentials.
31//
32// The provided grpcServer must be of type *grpc.Server. It is untyped
33// for circular dependency reasons.
34var TestingUseHandlerImpl func(grpcServer interface{})
diff --git a/vendor/google.golang.org/grpc/keepalive/keepalive.go b/vendor/google.golang.org/grpc/keepalive/keepalive.go
new file mode 100644
index 0000000..f8adc7e
--- /dev/null
+++ b/vendor/google.golang.org/grpc/keepalive/keepalive.go
@@ -0,0 +1,65 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package keepalive defines configurable parameters for point-to-point healthcheck.
20package keepalive
21
22import (
23 "time"
24)
25
26// ClientParameters is used to set keepalive parameters on the client-side.
27// These configure how the client will actively probe to notice when a connection is broken
28// and send pings so intermediaries will be aware of the liveness of the connection.
29// Make sure these parameters are set in coordination with the keepalive policy on the server,
30// as incompatible settings can result in closing of connection.
31type ClientParameters struct {
32 // After a duration of this time if the client doesn't see any activity it pings the server to see if the transport is still alive.
33 Time time.Duration // The current default value is infinity.
34 // After having pinged for keepalive check, the client waits for a duration of Timeout and if no activity is seen even after that
35 // the connection is closed.
36 Timeout time.Duration // The current default value is 20 seconds.
37 // If true, client runs keepalive checks even with no active RPCs.
38 PermitWithoutStream bool // false by default.
39}
40
41// ServerParameters is used to set keepalive and max-age parameters on the server-side.
42type ServerParameters struct {
43 // MaxConnectionIdle is a duration for the amount of time after which an idle connection would be closed by sending a GoAway.
44 // Idleness duration is defined since the most recent time the number of outstanding RPCs became zero or the connection establishment.
45 MaxConnectionIdle time.Duration // The current default value is infinity.
46 // MaxConnectionAge is a duration for the maximum amount of time a connection may exist before it will be closed by sending a GoAway.
47 // A random jitter of +/-10% will be added to MaxConnectionAge to spread out connection storms.
48 MaxConnectionAge time.Duration // The current default value is infinity.
49 // MaxConnectinoAgeGrace is an additive period after MaxConnectionAge after which the connection will be forcibly closed.
50 MaxConnectionAgeGrace time.Duration // The current default value is infinity.
51 // After a duration of this time if the server doesn't see any activity it pings the client to see if the transport is still alive.
52 Time time.Duration // The current default value is 2 hours.
53 // After having pinged for keepalive check, the server waits for a duration of Timeout and if no activity is seen even after that
54 // the connection is closed.
55 Timeout time.Duration // The current default value is 20 seconds.
56}
57
58// EnforcementPolicy is used to set keepalive enforcement policy on the server-side.
59// Server will close connection with a client that violates this policy.
60type EnforcementPolicy struct {
61 // MinTime is the minimum amount of time a client should wait before sending a keepalive ping.
62 MinTime time.Duration // The current default value is 5 minutes.
63 // If true, server expects keepalive pings even when there are no active streams(RPCs).
64 PermitWithoutStream bool // false by default.
65}
diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go
new file mode 100644
index 0000000..be4f9e7
--- /dev/null
+++ b/vendor/google.golang.org/grpc/metadata/metadata.go
@@ -0,0 +1,141 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package metadata define the structure of the metadata supported by gRPC library.
20// Please refer to https://grpc.io/docs/guides/wire.html for more information about custom-metadata.
21package metadata // import "google.golang.org/grpc/metadata"
22
23import (
24 "fmt"
25 "strings"
26
27 "golang.org/x/net/context"
28)
29
30// DecodeKeyValue returns k, v, nil. It is deprecated and should not be used.
31func DecodeKeyValue(k, v string) (string, string, error) {
32 return k, v, nil
33}
34
35// MD is a mapping from metadata keys to values. Users should use the following
36// two convenience functions New and Pairs to generate MD.
37type MD map[string][]string
38
39// New creates an MD from a given key-value map.
40//
41// Only the following ASCII characters are allowed in keys:
42// - digits: 0-9
43// - uppercase letters: A-Z (normalized to lower)
44// - lowercase letters: a-z
45// - special characters: -_.
46// Uppercase letters are automatically converted to lowercase.
47func New(m map[string]string) MD {
48 md := MD{}
49 for k, val := range m {
50 key := strings.ToLower(k)
51 md[key] = append(md[key], val)
52 }
53 return md
54}
55
56// Pairs returns an MD formed by the mapping of key, value ...
57// Pairs panics if len(kv) is odd.
58//
59// Only the following ASCII characters are allowed in keys:
60// - digits: 0-9
61// - uppercase letters: A-Z (normalized to lower)
62// - lowercase letters: a-z
63// - special characters: -_.
64// Uppercase letters are automatically converted to lowercase.
65func Pairs(kv ...string) MD {
66 if len(kv)%2 == 1 {
67 panic(fmt.Sprintf("metadata: Pairs got the odd number of input pairs for metadata: %d", len(kv)))
68 }
69 md := MD{}
70 var key string
71 for i, s := range kv {
72 if i%2 == 0 {
73 key = strings.ToLower(s)
74 continue
75 }
76 md[key] = append(md[key], s)
77 }
78 return md
79}
80
81// Len returns the number of items in md.
82func (md MD) Len() int {
83 return len(md)
84}
85
86// Copy returns a copy of md.
87func (md MD) Copy() MD {
88 return Join(md)
89}
90
91// Join joins any number of mds into a single MD.
92// The order of values for each key is determined by the order in which
93// the mds containing those values are presented to Join.
94func Join(mds ...MD) MD {
95 out := MD{}
96 for _, md := range mds {
97 for k, v := range md {
98 out[k] = append(out[k], v...)
99 }
100 }
101 return out
102}
103
104type mdIncomingKey struct{}
105type mdOutgoingKey struct{}
106
107// NewContext is a wrapper for NewOutgoingContext(ctx, md). Deprecated.
108func NewContext(ctx context.Context, md MD) context.Context {
109 return NewOutgoingContext(ctx, md)
110}
111
112// NewIncomingContext creates a new context with incoming md attached.
113func NewIncomingContext(ctx context.Context, md MD) context.Context {
114 return context.WithValue(ctx, mdIncomingKey{}, md)
115}
116
117// NewOutgoingContext creates a new context with outgoing md attached.
118func NewOutgoingContext(ctx context.Context, md MD) context.Context {
119 return context.WithValue(ctx, mdOutgoingKey{}, md)
120}
121
122// FromContext is a wrapper for FromIncomingContext(ctx). Deprecated.
123func FromContext(ctx context.Context) (md MD, ok bool) {
124 return FromIncomingContext(ctx)
125}
126
127// FromIncomingContext returns the incoming metadata in ctx if it exists. The
128// returned MD should not be modified. Writing to it may cause races.
129// Modification should be made to copies of the returned MD.
130func FromIncomingContext(ctx context.Context) (md MD, ok bool) {
131 md, ok = ctx.Value(mdIncomingKey{}).(MD)
132 return
133}
134
135// FromOutgoingContext returns the outgoing metadata in ctx if it exists. The
136// returned MD should not be modified. Writing to it may cause races.
137// Modification should be made to the copies of the returned MD.
138func FromOutgoingContext(ctx context.Context) (md MD, ok bool) {
139 md, ok = ctx.Value(mdOutgoingKey{}).(MD)
140 return
141}
diff --git a/vendor/google.golang.org/grpc/naming/dns_resolver.go b/vendor/google.golang.org/grpc/naming/dns_resolver.go
new file mode 100644
index 0000000..efd37e3
--- /dev/null
+++ b/vendor/google.golang.org/grpc/naming/dns_resolver.go
@@ -0,0 +1,292 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package naming
20
21import (
22 "errors"
23 "fmt"
24 "net"
25 "strconv"
26 "time"
27
28 "golang.org/x/net/context"
29 "google.golang.org/grpc/grpclog"
30)
31
32const (
33 defaultPort = "443"
34 defaultFreq = time.Minute * 30
35)
36
37var (
38 errMissingAddr = errors.New("missing address")
39 errWatcherClose = errors.New("watcher has been closed")
40)
41
42// NewDNSResolverWithFreq creates a DNS Resolver that can resolve DNS names, and
43// create watchers that poll the DNS server using the frequency set by freq.
44func NewDNSResolverWithFreq(freq time.Duration) (Resolver, error) {
45 return &dnsResolver{freq: freq}, nil
46}
47
48// NewDNSResolver creates a DNS Resolver that can resolve DNS names, and create
49// watchers that poll the DNS server using the default frequency defined by defaultFreq.
50func NewDNSResolver() (Resolver, error) {
51 return NewDNSResolverWithFreq(defaultFreq)
52}
53
54// dnsResolver handles name resolution for names following the DNS scheme
55type dnsResolver struct {
56 // frequency of polling the DNS server that the watchers created by this resolver will use.
57 freq time.Duration
58}
59
60// formatIP returns ok = false if addr is not a valid textual representation of an IP address.
61// If addr is an IPv4 address, return the addr and ok = true.
62// If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true.
63func formatIP(addr string) (addrIP string, ok bool) {
64 ip := net.ParseIP(addr)
65 if ip == nil {
66 return "", false
67 }
68 if ip.To4() != nil {
69 return addr, true
70 }
71 return "[" + addr + "]", true
72}
73
74// parseTarget takes the user input target string, returns formatted host and port info.
75// If target doesn't specify a port, set the port to be the defaultPort.
76// If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets
77// are strippd when setting the host.
78// examples:
79// target: "www.google.com" returns host: "www.google.com", port: "443"
80// target: "ipv4-host:80" returns host: "ipv4-host", port: "80"
81// target: "[ipv6-host]" returns host: "ipv6-host", port: "443"
82// target: ":80" returns host: "localhost", port: "80"
83// target: ":" returns host: "localhost", port: "443"
84func parseTarget(target string) (host, port string, err error) {
85 if target == "" {
86 return "", "", errMissingAddr
87 }
88
89 if ip := net.ParseIP(target); ip != nil {
90 // target is an IPv4 or IPv6(without brackets) address
91 return target, defaultPort, nil
92 }
93 if host, port, err := net.SplitHostPort(target); err == nil {
94 // target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
95 if host == "" {
96 // Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed.
97 host = "localhost"
98 }
99 if port == "" {
100 // If the port field is empty(target ends with colon), e.g. "[::1]:", defaultPort is used.
101 port = defaultPort
102 }
103 return host, port, nil
104 }
105 if host, port, err := net.SplitHostPort(target + ":" + defaultPort); err == nil {
106 // target doesn't have port
107 return host, port, nil
108 }
109 return "", "", fmt.Errorf("invalid target address %v", target)
110}
111
112// Resolve creates a watcher that watches the name resolution of the target.
113func (r *dnsResolver) Resolve(target string) (Watcher, error) {
114 host, port, err := parseTarget(target)
115 if err != nil {
116 return nil, err
117 }
118
119 if net.ParseIP(host) != nil {
120 ipWatcher := &ipWatcher{
121 updateChan: make(chan *Update, 1),
122 }
123 host, _ = formatIP(host)
124 ipWatcher.updateChan <- &Update{Op: Add, Addr: host + ":" + port}
125 return ipWatcher, nil
126 }
127
128 ctx, cancel := context.WithCancel(context.Background())
129 return &dnsWatcher{
130 r: r,
131 host: host,
132 port: port,
133 ctx: ctx,
134 cancel: cancel,
135 t: time.NewTimer(0),
136 }, nil
137}
138
139// dnsWatcher watches for the name resolution update for a specific target
140type dnsWatcher struct {
141 r *dnsResolver
142 host string
143 port string
144 // The latest resolved address list
145 curAddrs []*Update
146 ctx context.Context
147 cancel context.CancelFunc
148 t *time.Timer
149}
150
151// ipWatcher watches for the name resolution update for an IP address.
152type ipWatcher struct {
153 updateChan chan *Update
154}
155
156// Next returns the adrress resolution Update for the target. For IP address,
157// the resolution is itself, thus polling name server is unncessary. Therefore,
158// Next() will return an Update the first time it is called, and will be blocked
159// for all following calls as no Update exisits until watcher is closed.
160func (i *ipWatcher) Next() ([]*Update, error) {
161 u, ok := <-i.updateChan
162 if !ok {
163 return nil, errWatcherClose
164 }
165 return []*Update{u}, nil
166}
167
168// Close closes the ipWatcher.
169func (i *ipWatcher) Close() {
170 close(i.updateChan)
171}
172
173// AddressType indicates the address type returned by name resolution.
174type AddressType uint8
175
176const (
177 // Backend indicates the server is a backend server.
178 Backend AddressType = iota
179 // GRPCLB indicates the server is a grpclb load balancer.
180 GRPCLB
181)
182
183// AddrMetadataGRPCLB contains the information the name resolver for grpclb should provide. The
184// name resolver used by the grpclb balancer is required to provide this type of metadata in
185// its address updates.
186type AddrMetadataGRPCLB struct {
187 // AddrType is the type of server (grpc load balancer or backend).
188 AddrType AddressType
189 // ServerName is the name of the grpc load balancer. Used for authentication.
190 ServerName string
191}
192
193// compileUpdate compares the old resolved addresses and newly resolved addresses,
194// and generates an update list
195func (w *dnsWatcher) compileUpdate(newAddrs []*Update) []*Update {
196 update := make(map[Update]bool)
197 for _, u := range newAddrs {
198 update[*u] = true
199 }
200 for _, u := range w.curAddrs {
201 if _, ok := update[*u]; ok {
202 delete(update, *u)
203 continue
204 }
205 update[Update{Addr: u.Addr, Op: Delete, Metadata: u.Metadata}] = true
206 }
207 res := make([]*Update, 0, len(update))
208 for k := range update {
209 tmp := k
210 res = append(res, &tmp)
211 }
212 return res
213}
214
215func (w *dnsWatcher) lookupSRV() []*Update {
216 var newAddrs []*Update
217 _, srvs, err := lookupSRV(w.ctx, "grpclb", "tcp", w.host)
218 if err != nil {
219 grpclog.Infof("grpc: failed dns SRV record lookup due to %v.\n", err)
220 return nil
221 }
222 for _, s := range srvs {
223 lbAddrs, err := lookupHost(w.ctx, s.Target)
224 if err != nil {
225 grpclog.Warningf("grpc: failed load banlacer address dns lookup due to %v.\n", err)
226 continue
227 }
228 for _, a := range lbAddrs {
229 a, ok := formatIP(a)
230 if !ok {
231 grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err)
232 continue
233 }
234 newAddrs = append(newAddrs, &Update{Addr: a + ":" + strconv.Itoa(int(s.Port)),
235 Metadata: AddrMetadataGRPCLB{AddrType: GRPCLB, ServerName: s.Target}})
236 }
237 }
238 return newAddrs
239}
240
241func (w *dnsWatcher) lookupHost() []*Update {
242 var newAddrs []*Update
243 addrs, err := lookupHost(w.ctx, w.host)
244 if err != nil {
245 grpclog.Warningf("grpc: failed dns A record lookup due to %v.\n", err)
246 return nil
247 }
248 for _, a := range addrs {
249 a, ok := formatIP(a)
250 if !ok {
251 grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err)
252 continue
253 }
254 newAddrs = append(newAddrs, &Update{Addr: a + ":" + w.port})
255 }
256 return newAddrs
257}
258
259func (w *dnsWatcher) lookup() []*Update {
260 newAddrs := w.lookupSRV()
261 if newAddrs == nil {
262 // If failed to get any balancer address (either no corresponding SRV for the
263 // target, or caused by failure during resolution/parsing of the balancer target),
264 // return any A record info available.
265 newAddrs = w.lookupHost()
266 }
267 result := w.compileUpdate(newAddrs)
268 w.curAddrs = newAddrs
269 return result
270}
271
272// Next returns the resolved address update(delta) for the target. If there's no
273// change, it will sleep for 30 mins and try to resolve again after that.
274func (w *dnsWatcher) Next() ([]*Update, error) {
275 for {
276 select {
277 case <-w.ctx.Done():
278 return nil, errWatcherClose
279 case <-w.t.C:
280 }
281 result := w.lookup()
282 // Next lookup should happen after an interval defined by w.r.freq.
283 w.t.Reset(w.r.freq)
284 if len(result) > 0 {
285 return result, nil
286 }
287 }
288}
289
290func (w *dnsWatcher) Close() {
291 w.cancel()
292}
diff --git a/vendor/google.golang.org/grpc/naming/go17.go b/vendor/google.golang.org/grpc/naming/go17.go
new file mode 100644
index 0000000..a537b08
--- /dev/null
+++ b/vendor/google.golang.org/grpc/naming/go17.go
@@ -0,0 +1,34 @@
1// +build go1.6, !go1.8
2
3/*
4 *
5 * Copyright 2017 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package naming
22
23import (
24 "net"
25
26 "golang.org/x/net/context"
27)
28
29var (
30 lookupHost = func(ctx context.Context, host string) ([]string, error) { return net.LookupHost(host) }
31 lookupSRV = func(ctx context.Context, service, proto, name string) (string, []*net.SRV, error) {
32 return net.LookupSRV(service, proto, name)
33 }
34)
diff --git a/vendor/google.golang.org/grpc/naming/go18.go b/vendor/google.golang.org/grpc/naming/go18.go
new file mode 100644
index 0000000..b5a0f84
--- /dev/null
+++ b/vendor/google.golang.org/grpc/naming/go18.go
@@ -0,0 +1,28 @@
1// +build go1.8
2
3/*
4 *
5 * Copyright 2017 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package naming
22
23import "net"
24
25var (
26 lookupHost = net.DefaultResolver.LookupHost
27 lookupSRV = net.DefaultResolver.LookupSRV
28)
diff --git a/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go
new file mode 100644
index 0000000..1af7e32
--- /dev/null
+++ b/vendor/google.golang.org/grpc/naming/naming.go
@@ -0,0 +1,59 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package naming defines the naming API and related data structures for gRPC.
20// The interface is EXPERIMENTAL and may be suject to change.
21package naming
22
23// Operation defines the corresponding operations for a name resolution change.
24type Operation uint8
25
26const (
27 // Add indicates a new address is added.
28 Add Operation = iota
29 // Delete indicates an exisiting address is deleted.
30 Delete
31)
32
33// Update defines a name resolution update. Notice that it is not valid having both
34// empty string Addr and nil Metadata in an Update.
35type Update struct {
36 // Op indicates the operation of the update.
37 Op Operation
38 // Addr is the updated address. It is empty string if there is no address update.
39 Addr string
40 // Metadata is the updated metadata. It is nil if there is no metadata update.
41 // Metadata is not required for a custom naming implementation.
42 Metadata interface{}
43}
44
45// Resolver creates a Watcher for a target to track its resolution changes.
46type Resolver interface {
47 // Resolve creates a Watcher for target.
48 Resolve(target string) (Watcher, error)
49}
50
51// Watcher watches for the updates on the specified target.
52type Watcher interface {
53 // Next blocks until an update or error happens. It may return one or more
54 // updates. The first call should get the full set of the results. It should
55 // return an error if and only if Watcher cannot recover.
56 Next() ([]*Update, error)
57 // Close closes the Watcher.
58 Close()
59}
diff --git a/vendor/google.golang.org/grpc/peer/peer.go b/vendor/google.golang.org/grpc/peer/peer.go
new file mode 100644
index 0000000..317b8b9
--- /dev/null
+++ b/vendor/google.golang.org/grpc/peer/peer.go
@@ -0,0 +1,51 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package peer defines various peer information associated with RPCs and
20// corresponding utils.
21package peer
22
23import (
24 "net"
25
26 "golang.org/x/net/context"
27 "google.golang.org/grpc/credentials"
28)
29
30// Peer contains the information of the peer for an RPC, such as the address
31// and authentication information.
32type Peer struct {
33 // Addr is the peer address.
34 Addr net.Addr
35 // AuthInfo is the authentication information of the transport.
36 // It is nil if there is no transport security being used.
37 AuthInfo credentials.AuthInfo
38}
39
40type peerKey struct{}
41
42// NewContext creates a new context with peer information attached.
43func NewContext(ctx context.Context, p *Peer) context.Context {
44 return context.WithValue(ctx, peerKey{}, p)
45}
46
47// FromContext returns the peer information in ctx if it exists.
48func FromContext(ctx context.Context) (p *Peer, ok bool) {
49 p, ok = ctx.Value(peerKey{}).(*Peer)
50 return
51}
diff --git a/vendor/google.golang.org/grpc/proxy.go b/vendor/google.golang.org/grpc/proxy.go
new file mode 100644
index 0000000..2d40236
--- /dev/null
+++ b/vendor/google.golang.org/grpc/proxy.go
@@ -0,0 +1,130 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "bufio"
23 "errors"
24 "fmt"
25 "io"
26 "net"
27 "net/http"
28 "net/http/httputil"
29 "net/url"
30
31 "golang.org/x/net/context"
32)
33
34var (
35 // errDisabled indicates that proxy is disabled for the address.
36 errDisabled = errors.New("proxy is disabled for the address")
37 // The following variable will be overwritten in the tests.
38 httpProxyFromEnvironment = http.ProxyFromEnvironment
39)
40
41func mapAddress(ctx context.Context, address string) (string, error) {
42 req := &http.Request{
43 URL: &url.URL{
44 Scheme: "https",
45 Host: address,
46 },
47 }
48 url, err := httpProxyFromEnvironment(req)
49 if err != nil {
50 return "", err
51 }
52 if url == nil {
53 return "", errDisabled
54 }
55 return url.Host, nil
56}
57
58// To read a response from a net.Conn, http.ReadResponse() takes a bufio.Reader.
59// It's possible that this reader reads more than what's need for the response and stores
60// those bytes in the buffer.
61// bufConn wraps the original net.Conn and the bufio.Reader to make sure we don't lose the
62// bytes in the buffer.
63type bufConn struct {
64 net.Conn
65 r io.Reader
66}
67
68func (c *bufConn) Read(b []byte) (int, error) {
69 return c.r.Read(b)
70}
71
72func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, addr string) (_ net.Conn, err error) {
73 defer func() {
74 if err != nil {
75 conn.Close()
76 }
77 }()
78
79 req := (&http.Request{
80 Method: http.MethodConnect,
81 URL: &url.URL{Host: addr},
82 Header: map[string][]string{"User-Agent": {grpcUA}},
83 })
84
85 if err := sendHTTPRequest(ctx, req, conn); err != nil {
86 return nil, fmt.Errorf("failed to write the HTTP request: %v", err)
87 }
88
89 r := bufio.NewReader(conn)
90 resp, err := http.ReadResponse(r, req)
91 if err != nil {
92 return nil, fmt.Errorf("reading server HTTP response: %v", err)
93 }
94 defer resp.Body.Close()
95 if resp.StatusCode != http.StatusOK {
96 dump, err := httputil.DumpResponse(resp, true)
97 if err != nil {
98 return nil, fmt.Errorf("failed to do connect handshake, status code: %s", resp.Status)
99 }
100 return nil, fmt.Errorf("failed to do connect handshake, response: %q", dump)
101 }
102
103 return &bufConn{Conn: conn, r: r}, nil
104}
105
106// newProxyDialer returns a dialer that connects to proxy first if necessary.
107// The returned dialer checks if a proxy is necessary, dial to the proxy with the
108// provided dialer, does HTTP CONNECT handshake and returns the connection.
109func newProxyDialer(dialer func(context.Context, string) (net.Conn, error)) func(context.Context, string) (net.Conn, error) {
110 return func(ctx context.Context, addr string) (conn net.Conn, err error) {
111 var skipHandshake bool
112 newAddr, err := mapAddress(ctx, addr)
113 if err != nil {
114 if err != errDisabled {
115 return nil, err
116 }
117 skipHandshake = true
118 newAddr = addr
119 }
120
121 conn, err = dialer(ctx, newAddr)
122 if err != nil {
123 return
124 }
125 if !skipHandshake {
126 conn, err = doHTTPConnectHandshake(ctx, conn, addr)
127 }
128 return
129 }
130}
diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go
new file mode 100644
index 0000000..9b9d388
--- /dev/null
+++ b/vendor/google.golang.org/grpc/rpc_util.go
@@ -0,0 +1,524 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "bytes"
23 "compress/gzip"
24 "encoding/binary"
25 "io"
26 "io/ioutil"
27 "math"
28 "sync"
29 "time"
30
31 "golang.org/x/net/context"
32 "google.golang.org/grpc/codes"
33 "google.golang.org/grpc/credentials"
34 "google.golang.org/grpc/metadata"
35 "google.golang.org/grpc/peer"
36 "google.golang.org/grpc/stats"
37 "google.golang.org/grpc/status"
38 "google.golang.org/grpc/transport"
39)
40
41// Compressor defines the interface gRPC uses to compress a message.
42type Compressor interface {
43 // Do compresses p into w.
44 Do(w io.Writer, p []byte) error
45 // Type returns the compression algorithm the Compressor uses.
46 Type() string
47}
48
49type gzipCompressor struct {
50 pool sync.Pool
51}
52
53// NewGZIPCompressor creates a Compressor based on GZIP.
54func NewGZIPCompressor() Compressor {
55 return &gzipCompressor{
56 pool: sync.Pool{
57 New: func() interface{} {
58 return gzip.NewWriter(ioutil.Discard)
59 },
60 },
61 }
62}
63
64func (c *gzipCompressor) Do(w io.Writer, p []byte) error {
65 z := c.pool.Get().(*gzip.Writer)
66 z.Reset(w)
67 if _, err := z.Write(p); err != nil {
68 return err
69 }
70 return z.Close()
71}
72
73func (c *gzipCompressor) Type() string {
74 return "gzip"
75}
76
77// Decompressor defines the interface gRPC uses to decompress a message.
78type Decompressor interface {
79 // Do reads the data from r and uncompress them.
80 Do(r io.Reader) ([]byte, error)
81 // Type returns the compression algorithm the Decompressor uses.
82 Type() string
83}
84
85type gzipDecompressor struct {
86 pool sync.Pool
87}
88
89// NewGZIPDecompressor creates a Decompressor based on GZIP.
90func NewGZIPDecompressor() Decompressor {
91 return &gzipDecompressor{}
92}
93
94func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
95 var z *gzip.Reader
96 switch maybeZ := d.pool.Get().(type) {
97 case nil:
98 newZ, err := gzip.NewReader(r)
99 if err != nil {
100 return nil, err
101 }
102 z = newZ
103 case *gzip.Reader:
104 z = maybeZ
105 if err := z.Reset(r); err != nil {
106 d.pool.Put(z)
107 return nil, err
108 }
109 }
110
111 defer func() {
112 z.Close()
113 d.pool.Put(z)
114 }()
115 return ioutil.ReadAll(z)
116}
117
118func (d *gzipDecompressor) Type() string {
119 return "gzip"
120}
121
122// callInfo contains all related configuration and information about an RPC.
123type callInfo struct {
124 failFast bool
125 headerMD metadata.MD
126 trailerMD metadata.MD
127 peer *peer.Peer
128 traceInfo traceInfo // in trace.go
129 maxReceiveMessageSize *int
130 maxSendMessageSize *int
131 creds credentials.PerRPCCredentials
132}
133
134var defaultCallInfo = callInfo{failFast: true}
135
136// CallOption configures a Call before it starts or extracts information from
137// a Call after it completes.
138type CallOption interface {
139 // before is called before the call is sent to any server. If before
140 // returns a non-nil error, the RPC fails with that error.
141 before(*callInfo) error
142
143 // after is called after the call has completed. after cannot return an
144 // error, so any failures should be reported via output parameters.
145 after(*callInfo)
146}
147
148// EmptyCallOption does not alter the Call configuration.
149// It can be embedded in another structure to carry satellite data for use
150// by interceptors.
151type EmptyCallOption struct{}
152
153func (EmptyCallOption) before(*callInfo) error { return nil }
154func (EmptyCallOption) after(*callInfo) {}
155
156type beforeCall func(c *callInfo) error
157
158func (o beforeCall) before(c *callInfo) error { return o(c) }
159func (o beforeCall) after(c *callInfo) {}
160
161type afterCall func(c *callInfo)
162
163func (o afterCall) before(c *callInfo) error { return nil }
164func (o afterCall) after(c *callInfo) { o(c) }
165
166// Header returns a CallOptions that retrieves the header metadata
167// for a unary RPC.
168func Header(md *metadata.MD) CallOption {
169 return afterCall(func(c *callInfo) {
170 *md = c.headerMD
171 })
172}
173
174// Trailer returns a CallOptions that retrieves the trailer metadata
175// for a unary RPC.
176func Trailer(md *metadata.MD) CallOption {
177 return afterCall(func(c *callInfo) {
178 *md = c.trailerMD
179 })
180}
181
182// Peer returns a CallOption that retrieves peer information for a
183// unary RPC.
184func Peer(peer *peer.Peer) CallOption {
185 return afterCall(func(c *callInfo) {
186 if c.peer != nil {
187 *peer = *c.peer
188 }
189 })
190}
191
192// FailFast configures the action to take when an RPC is attempted on broken
193// connections or unreachable servers. If failfast is true, the RPC will fail
194// immediately. Otherwise, the RPC client will block the call until a
195// connection is available (or the call is canceled or times out) and will retry
196// the call if it fails due to a transient error. Please refer to
197// https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
198// Note: failFast is default to true.
199func FailFast(failFast bool) CallOption {
200 return beforeCall(func(c *callInfo) error {
201 c.failFast = failFast
202 return nil
203 })
204}
205
206// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size the client can receive.
207func MaxCallRecvMsgSize(s int) CallOption {
208 return beforeCall(func(o *callInfo) error {
209 o.maxReceiveMessageSize = &s
210 return nil
211 })
212}
213
214// MaxCallSendMsgSize returns a CallOption which sets the maximum message size the client can send.
215func MaxCallSendMsgSize(s int) CallOption {
216 return beforeCall(func(o *callInfo) error {
217 o.maxSendMessageSize = &s
218 return nil
219 })
220}
221
222// PerRPCCredentials returns a CallOption that sets credentials.PerRPCCredentials
223// for a call.
224func PerRPCCredentials(creds credentials.PerRPCCredentials) CallOption {
225 return beforeCall(func(c *callInfo) error {
226 c.creds = creds
227 return nil
228 })
229}
230
231// The format of the payload: compressed or not?
232type payloadFormat uint8
233
234const (
235 compressionNone payloadFormat = iota // no compression
236 compressionMade
237)
238
239// parser reads complete gRPC messages from the underlying reader.
240type parser struct {
241 // r is the underlying reader.
242 // See the comment on recvMsg for the permissible
243 // error types.
244 r io.Reader
245
246 // The header of a gRPC message. Find more detail
247 // at https://grpc.io/docs/guides/wire.html.
248 header [5]byte
249}
250
251// recvMsg reads a complete gRPC message from the stream.
252//
253// It returns the message and its payload (compression/encoding)
254// format. The caller owns the returned msg memory.
255//
256// If there is an error, possible values are:
257// * io.EOF, when no messages remain
258// * io.ErrUnexpectedEOF
259// * of type transport.ConnectionError
260// * of type transport.StreamError
261// No other error values or types must be returned, which also means
262// that the underlying io.Reader must not return an incompatible
263// error.
264func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byte, err error) {
265 if _, err := p.r.Read(p.header[:]); err != nil {
266 return 0, nil, err
267 }
268
269 pf = payloadFormat(p.header[0])
270 length := binary.BigEndian.Uint32(p.header[1:])
271
272 if length == 0 {
273 return pf, nil, nil
274 }
275 if length > uint32(maxReceiveMessageSize) {
276 return 0, nil, Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
277 }
278 // TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
279 // of making it for each message:
280 msg = make([]byte, int(length))
281 if _, err := p.r.Read(msg); err != nil {
282 if err == io.EOF {
283 err = io.ErrUnexpectedEOF
284 }
285 return 0, nil, err
286 }
287 return pf, msg, nil
288}
289
290// encode serializes msg and prepends the message header. If msg is nil, it
291// generates the message header of 0 message length.
292func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer, outPayload *stats.OutPayload) ([]byte, error) {
293 var (
294 b []byte
295 length uint
296 )
297 if msg != nil {
298 var err error
299 // TODO(zhaoq): optimize to reduce memory alloc and copying.
300 b, err = c.Marshal(msg)
301 if err != nil {
302 return nil, Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
303 }
304 if outPayload != nil {
305 outPayload.Payload = msg
306 // TODO truncate large payload.
307 outPayload.Data = b
308 outPayload.Length = len(b)
309 }
310 if cp != nil {
311 if err := cp.Do(cbuf, b); err != nil {
312 return nil, Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
313 }
314 b = cbuf.Bytes()
315 }
316 length = uint(len(b))
317 }
318 if length > math.MaxUint32 {
319 return nil, Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", length)
320 }
321
322 const (
323 payloadLen = 1
324 sizeLen = 4
325 )
326
327 var buf = make([]byte, payloadLen+sizeLen+len(b))
328
329 // Write payload format
330 if cp == nil {
331 buf[0] = byte(compressionNone)
332 } else {
333 buf[0] = byte(compressionMade)
334 }
335 // Write length of b into buf
336 binary.BigEndian.PutUint32(buf[1:], uint32(length))
337 // Copy encoded msg to buf
338 copy(buf[5:], b)
339
340 if outPayload != nil {
341 outPayload.WireLength = len(buf)
342 }
343
344 return buf, nil
345}
346
347func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) error {
348 switch pf {
349 case compressionNone:
350 case compressionMade:
351 if dc == nil || recvCompress != dc.Type() {
352 return Errorf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
353 }
354 default:
355 return Errorf(codes.Internal, "grpc: received unexpected payload format %d", pf)
356 }
357 return nil
358}
359
360func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, inPayload *stats.InPayload) error {
361 pf, d, err := p.recvMsg(maxReceiveMessageSize)
362 if err != nil {
363 return err
364 }
365 if inPayload != nil {
366 inPayload.WireLength = len(d)
367 }
368 if err := checkRecvPayload(pf, s.RecvCompress(), dc); err != nil {
369 return err
370 }
371 if pf == compressionMade {
372 d, err = dc.Do(bytes.NewReader(d))
373 if err != nil {
374 return Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
375 }
376 }
377 if len(d) > maxReceiveMessageSize {
378 // TODO: Revisit the error code. Currently keep it consistent with java
379 // implementation.
380 return Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize)
381 }
382 if err := c.Unmarshal(d, m); err != nil {
383 return Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
384 }
385 if inPayload != nil {
386 inPayload.RecvTime = time.Now()
387 inPayload.Payload = m
388 // TODO truncate large payload.
389 inPayload.Data = d
390 inPayload.Length = len(d)
391 }
392 return nil
393}
394
395type rpcInfo struct {
396 bytesSent bool
397 bytesReceived bool
398}
399
400type rpcInfoContextKey struct{}
401
402func newContextWithRPCInfo(ctx context.Context) context.Context {
403 return context.WithValue(ctx, rpcInfoContextKey{}, &rpcInfo{})
404}
405
406func rpcInfoFromContext(ctx context.Context) (s *rpcInfo, ok bool) {
407 s, ok = ctx.Value(rpcInfoContextKey{}).(*rpcInfo)
408 return
409}
410
411func updateRPCInfoInContext(ctx context.Context, s rpcInfo) {
412 if ss, ok := rpcInfoFromContext(ctx); ok {
413 *ss = s
414 }
415 return
416}
417
418// Code returns the error code for err if it was produced by the rpc system.
419// Otherwise, it returns codes.Unknown.
420//
421// Deprecated; use status.FromError and Code method instead.
422func Code(err error) codes.Code {
423 if s, ok := status.FromError(err); ok {
424 return s.Code()
425 }
426 return codes.Unknown
427}
428
429// ErrorDesc returns the error description of err if it was produced by the rpc system.
430// Otherwise, it returns err.Error() or empty string when err is nil.
431//
432// Deprecated; use status.FromError and Message method instead.
433func ErrorDesc(err error) string {
434 if s, ok := status.FromError(err); ok {
435 return s.Message()
436 }
437 return err.Error()
438}
439
440// Errorf returns an error containing an error code and a description;
441// Errorf returns nil if c is OK.
442//
443// Deprecated; use status.Errorf instead.
444func Errorf(c codes.Code, format string, a ...interface{}) error {
445 return status.Errorf(c, format, a...)
446}
447
448// MethodConfig defines the configuration recommended by the service providers for a
449// particular method.
450// This is EXPERIMENTAL and subject to change.
451type MethodConfig struct {
452 // WaitForReady indicates whether RPCs sent to this method should wait until
453 // the connection is ready by default (!failfast). The value specified via the
454 // gRPC client API will override the value set here.
455 WaitForReady *bool
456 // Timeout is the default timeout for RPCs sent to this method. The actual
457 // deadline used will be the minimum of the value specified here and the value
458 // set by the application via the gRPC client API. If either one is not set,
459 // then the other will be used. If neither is set, then the RPC has no deadline.
460 Timeout *time.Duration
461 // MaxReqSize is the maximum allowed payload size for an individual request in a
462 // stream (client->server) in bytes. The size which is measured is the serialized
463 // payload after per-message compression (but before stream compression) in bytes.
464 // The actual value used is the minumum of the value specified here and the value set
465 // by the application via the gRPC client API. If either one is not set, then the other
466 // will be used. If neither is set, then the built-in default is used.
467 MaxReqSize *int
468 // MaxRespSize is the maximum allowed payload size for an individual response in a
469 // stream (server->client) in bytes.
470 MaxRespSize *int
471}
472
473// ServiceConfig is provided by the service provider and contains parameters for how
474// clients that connect to the service should behave.
475// This is EXPERIMENTAL and subject to change.
476type ServiceConfig struct {
477 // LB is the load balancer the service providers recommends. The balancer specified
478 // via grpc.WithBalancer will override this.
479 LB Balancer
480 // Methods contains a map for the methods in this service.
481 // If there is an exact match for a method (i.e. /service/method) in the map, use the corresponding MethodConfig.
482 // If there's no exact match, look for the default config for the service (/service/) and use the corresponding MethodConfig if it exists.
483 // Otherwise, the method has no MethodConfig to use.
484 Methods map[string]MethodConfig
485}
486
487func min(a, b *int) *int {
488 if *a < *b {
489 return a
490 }
491 return b
492}
493
494func getMaxSize(mcMax, doptMax *int, defaultVal int) *int {
495 if mcMax == nil && doptMax == nil {
496 return &defaultVal
497 }
498 if mcMax != nil && doptMax != nil {
499 return min(mcMax, doptMax)
500 }
501 if mcMax != nil {
502 return mcMax
503 }
504 return doptMax
505}
506
507// SupportPackageIsVersion3 is referenced from generated protocol buffer files.
508// The latest support package version is 4.
509// SupportPackageIsVersion3 is kept for compability. It will be removed in the
510// next support package version update.
511const SupportPackageIsVersion3 = true
512
513// SupportPackageIsVersion4 is referenced from generated protocol buffer files
514// to assert that that code is compatible with this version of the grpc package.
515//
516// This constant may be renamed in the future if a change in the generated code
517// requires a synchronised update of grpc-go and protoc-gen-go. This constant
518// should not be referenced from any other code.
519const SupportPackageIsVersion4 = true
520
521// Version is the current grpc version.
522const Version = "1.6.0-dev"
523
524const grpcUA = "grpc-go/" + Version
diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go
new file mode 100644
index 0000000..42733e2
--- /dev/null
+++ b/vendor/google.golang.org/grpc/server.go
@@ -0,0 +1,1159 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "bytes"
23 "errors"
24 "fmt"
25 "io"
26 "net"
27 "net/http"
28 "reflect"
29 "runtime"
30 "strings"
31 "sync"
32 "time"
33
34 "golang.org/x/net/context"
35 "golang.org/x/net/http2"
36 "golang.org/x/net/trace"
37 "google.golang.org/grpc/codes"
38 "google.golang.org/grpc/credentials"
39 "google.golang.org/grpc/grpclog"
40 "google.golang.org/grpc/internal"
41 "google.golang.org/grpc/keepalive"
42 "google.golang.org/grpc/metadata"
43 "google.golang.org/grpc/stats"
44 "google.golang.org/grpc/status"
45 "google.golang.org/grpc/tap"
46 "google.golang.org/grpc/transport"
47)
48
49const (
50 defaultServerMaxReceiveMessageSize = 1024 * 1024 * 4
51 defaultServerMaxSendMessageSize = 1024 * 1024 * 4
52)
53
54type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error)
55
56// MethodDesc represents an RPC service's method specification.
57type MethodDesc struct {
58 MethodName string
59 Handler methodHandler
60}
61
62// ServiceDesc represents an RPC service's specification.
63type ServiceDesc struct {
64 ServiceName string
65 // The pointer to the service interface. Used to check whether the user
66 // provided implementation satisfies the interface requirements.
67 HandlerType interface{}
68 Methods []MethodDesc
69 Streams []StreamDesc
70 Metadata interface{}
71}
72
73// service consists of the information of the server serving this service and
74// the methods in this service.
75type service struct {
76 server interface{} // the server for service methods
77 md map[string]*MethodDesc
78 sd map[string]*StreamDesc
79 mdata interface{}
80}
81
82// Server is a gRPC server to serve RPC requests.
83type Server struct {
84 opts options
85
86 mu sync.Mutex // guards following
87 lis map[net.Listener]bool
88 conns map[io.Closer]bool
89 serve bool
90 drain bool
91 ctx context.Context
92 cancel context.CancelFunc
93 // A CondVar to let GracefulStop() blocks until all the pending RPCs are finished
94 // and all the transport goes away.
95 cv *sync.Cond
96 m map[string]*service // service name -> service info
97 events trace.EventLog
98}
99
100type options struct {
101 creds credentials.TransportCredentials
102 codec Codec
103 cp Compressor
104 dc Decompressor
105 unaryInt UnaryServerInterceptor
106 streamInt StreamServerInterceptor
107 inTapHandle tap.ServerInHandle
108 statsHandler stats.Handler
109 maxConcurrentStreams uint32
110 maxReceiveMessageSize int
111 maxSendMessageSize int
112 useHandlerImpl bool // use http.Handler-based server
113 unknownStreamDesc *StreamDesc
114 keepaliveParams keepalive.ServerParameters
115 keepalivePolicy keepalive.EnforcementPolicy
116 initialWindowSize int32
117 initialConnWindowSize int32
118}
119
120var defaultServerOptions = options{
121 maxReceiveMessageSize: defaultServerMaxReceiveMessageSize,
122 maxSendMessageSize: defaultServerMaxSendMessageSize,
123}
124
125// A ServerOption sets options such as credentials, codec and keepalive parameters, etc.
126type ServerOption func(*options)
127
128// InitialWindowSize returns a ServerOption that sets window size for stream.
129// The lower bound for window size is 64K and any value smaller than that will be ignored.
130func InitialWindowSize(s int32) ServerOption {
131 return func(o *options) {
132 o.initialWindowSize = s
133 }
134}
135
136// InitialConnWindowSize returns a ServerOption that sets window size for a connection.
137// The lower bound for window size is 64K and any value smaller than that will be ignored.
138func InitialConnWindowSize(s int32) ServerOption {
139 return func(o *options) {
140 o.initialConnWindowSize = s
141 }
142}
143
144// KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server.
145func KeepaliveParams(kp keepalive.ServerParameters) ServerOption {
146 return func(o *options) {
147 o.keepaliveParams = kp
148 }
149}
150
151// KeepaliveEnforcementPolicy returns a ServerOption that sets keepalive enforcement policy for the server.
152func KeepaliveEnforcementPolicy(kep keepalive.EnforcementPolicy) ServerOption {
153 return func(o *options) {
154 o.keepalivePolicy = kep
155 }
156}
157
158// CustomCodec returns a ServerOption that sets a codec for message marshaling and unmarshaling.
159func CustomCodec(codec Codec) ServerOption {
160 return func(o *options) {
161 o.codec = codec
162 }
163}
164
165// RPCCompressor returns a ServerOption that sets a compressor for outbound messages.
166func RPCCompressor(cp Compressor) ServerOption {
167 return func(o *options) {
168 o.cp = cp
169 }
170}
171
172// RPCDecompressor returns a ServerOption that sets a decompressor for inbound messages.
173func RPCDecompressor(dc Decompressor) ServerOption {
174 return func(o *options) {
175 o.dc = dc
176 }
177}
178
179// MaxMsgSize returns a ServerOption to set the max message size in bytes the server can receive.
180// If this is not set, gRPC uses the default limit. Deprecated: use MaxRecvMsgSize instead.
181func MaxMsgSize(m int) ServerOption {
182 return MaxRecvMsgSize(m)
183}
184
185// MaxRecvMsgSize returns a ServerOption to set the max message size in bytes the server can receive.
186// If this is not set, gRPC uses the default 4MB.
187func MaxRecvMsgSize(m int) ServerOption {
188 return func(o *options) {
189 o.maxReceiveMessageSize = m
190 }
191}
192
193// MaxSendMsgSize returns a ServerOption to set the max message size in bytes the server can send.
194// If this is not set, gRPC uses the default 4MB.
195func MaxSendMsgSize(m int) ServerOption {
196 return func(o *options) {
197 o.maxSendMessageSize = m
198 }
199}
200
201// MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
202// of concurrent streams to each ServerTransport.
203func MaxConcurrentStreams(n uint32) ServerOption {
204 return func(o *options) {
205 o.maxConcurrentStreams = n
206 }
207}
208
209// Creds returns a ServerOption that sets credentials for server connections.
210func Creds(c credentials.TransportCredentials) ServerOption {
211 return func(o *options) {
212 o.creds = c
213 }
214}
215
216// UnaryInterceptor returns a ServerOption that sets the UnaryServerInterceptor for the
217// server. Only one unary interceptor can be installed. The construction of multiple
218// interceptors (e.g., chaining) can be implemented at the caller.
219func UnaryInterceptor(i UnaryServerInterceptor) ServerOption {
220 return func(o *options) {
221 if o.unaryInt != nil {
222 panic("The unary server interceptor was already set and may not be reset.")
223 }
224 o.unaryInt = i
225 }
226}
227
228// StreamInterceptor returns a ServerOption that sets the StreamServerInterceptor for the
229// server. Only one stream interceptor can be installed.
230func StreamInterceptor(i StreamServerInterceptor) ServerOption {
231 return func(o *options) {
232 if o.streamInt != nil {
233 panic("The stream server interceptor was already set and may not be reset.")
234 }
235 o.streamInt = i
236 }
237}
238
239// InTapHandle returns a ServerOption that sets the tap handle for all the server
240// transport to be created. Only one can be installed.
241func InTapHandle(h tap.ServerInHandle) ServerOption {
242 return func(o *options) {
243 if o.inTapHandle != nil {
244 panic("The tap handle was already set and may not be reset.")
245 }
246 o.inTapHandle = h
247 }
248}
249
250// StatsHandler returns a ServerOption that sets the stats handler for the server.
251func StatsHandler(h stats.Handler) ServerOption {
252 return func(o *options) {
253 o.statsHandler = h
254 }
255}
256
257// UnknownServiceHandler returns a ServerOption that allows for adding a custom
258// unknown service handler. The provided method is a bidi-streaming RPC service
259// handler that will be invoked instead of returning the "unimplemented" gRPC
260// error whenever a request is received for an unregistered service or method.
261// The handling function has full access to the Context of the request and the
262// stream, and the invocation passes through interceptors.
263func UnknownServiceHandler(streamHandler StreamHandler) ServerOption {
264 return func(o *options) {
265 o.unknownStreamDesc = &StreamDesc{
266 StreamName: "unknown_service_handler",
267 Handler: streamHandler,
268 // We need to assume that the users of the streamHandler will want to use both.
269 ClientStreams: true,
270 ServerStreams: true,
271 }
272 }
273}
274
275// NewServer creates a gRPC server which has no service registered and has not
276// started to accept requests yet.
277func NewServer(opt ...ServerOption) *Server {
278 opts := defaultServerOptions
279 for _, o := range opt {
280 o(&opts)
281 }
282 if opts.codec == nil {
283 // Set the default codec.
284 opts.codec = protoCodec{}
285 }
286 s := &Server{
287 lis: make(map[net.Listener]bool),
288 opts: opts,
289 conns: make(map[io.Closer]bool),
290 m: make(map[string]*service),
291 }
292 s.cv = sync.NewCond(&s.mu)
293 s.ctx, s.cancel = context.WithCancel(context.Background())
294 if EnableTracing {
295 _, file, line, _ := runtime.Caller(1)
296 s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line))
297 }
298 return s
299}
300
301// printf records an event in s's event log, unless s has been stopped.
302// REQUIRES s.mu is held.
303func (s *Server) printf(format string, a ...interface{}) {
304 if s.events != nil {
305 s.events.Printf(format, a...)
306 }
307}
308
309// errorf records an error in s's event log, unless s has been stopped.
310// REQUIRES s.mu is held.
311func (s *Server) errorf(format string, a ...interface{}) {
312 if s.events != nil {
313 s.events.Errorf(format, a...)
314 }
315}
316
317// RegisterService registers a service and its implementation to the gRPC
318// server. It is called from the IDL generated code. This must be called before
319// invoking Serve.
320func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
321 ht := reflect.TypeOf(sd.HandlerType).Elem()
322 st := reflect.TypeOf(ss)
323 if !st.Implements(ht) {
324 grpclog.Fatalf("grpc: Server.RegisterService found the handler of type %v that does not satisfy %v", st, ht)
325 }
326 s.register(sd, ss)
327}
328
329func (s *Server) register(sd *ServiceDesc, ss interface{}) {
330 s.mu.Lock()
331 defer s.mu.Unlock()
332 s.printf("RegisterService(%q)", sd.ServiceName)
333 if s.serve {
334 grpclog.Fatalf("grpc: Server.RegisterService after Server.Serve for %q", sd.ServiceName)
335 }
336 if _, ok := s.m[sd.ServiceName]; ok {
337 grpclog.Fatalf("grpc: Server.RegisterService found duplicate service registration for %q", sd.ServiceName)
338 }
339 srv := &service{
340 server: ss,
341 md: make(map[string]*MethodDesc),
342 sd: make(map[string]*StreamDesc),
343 mdata: sd.Metadata,
344 }
345 for i := range sd.Methods {
346 d := &sd.Methods[i]
347 srv.md[d.MethodName] = d
348 }
349 for i := range sd.Streams {
350 d := &sd.Streams[i]
351 srv.sd[d.StreamName] = d
352 }
353 s.m[sd.ServiceName] = srv
354}
355
356// MethodInfo contains the information of an RPC including its method name and type.
357type MethodInfo struct {
358 // Name is the method name only, without the service name or package name.
359 Name string
360 // IsClientStream indicates whether the RPC is a client streaming RPC.
361 IsClientStream bool
362 // IsServerStream indicates whether the RPC is a server streaming RPC.
363 IsServerStream bool
364}
365
366// ServiceInfo contains unary RPC method info, streaming RPC method info and metadata for a service.
367type ServiceInfo struct {
368 Methods []MethodInfo
369 // Metadata is the metadata specified in ServiceDesc when registering service.
370 Metadata interface{}
371}
372
373// GetServiceInfo returns a map from service names to ServiceInfo.
374// Service names include the package names, in the form of <package>.<service>.
375func (s *Server) GetServiceInfo() map[string]ServiceInfo {
376 ret := make(map[string]ServiceInfo)
377 for n, srv := range s.m {
378 methods := make([]MethodInfo, 0, len(srv.md)+len(srv.sd))
379 for m := range srv.md {
380 methods = append(methods, MethodInfo{
381 Name: m,
382 IsClientStream: false,
383 IsServerStream: false,
384 })
385 }
386 for m, d := range srv.sd {
387 methods = append(methods, MethodInfo{
388 Name: m,
389 IsClientStream: d.ClientStreams,
390 IsServerStream: d.ServerStreams,
391 })
392 }
393
394 ret[n] = ServiceInfo{
395 Methods: methods,
396 Metadata: srv.mdata,
397 }
398 }
399 return ret
400}
401
402var (
403 // ErrServerStopped indicates that the operation is now illegal because of
404 // the server being stopped.
405 ErrServerStopped = errors.New("grpc: the server has been stopped")
406)
407
408func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
409 if s.opts.creds == nil {
410 return rawConn, nil, nil
411 }
412 return s.opts.creds.ServerHandshake(rawConn)
413}
414
415// Serve accepts incoming connections on the listener lis, creating a new
416// ServerTransport and service goroutine for each. The service goroutines
417// read gRPC requests and then call the registered handlers to reply to them.
418// Serve returns when lis.Accept fails with fatal errors. lis will be closed when
419// this method returns.
420// Serve always returns non-nil error.
421func (s *Server) Serve(lis net.Listener) error {
422 s.mu.Lock()
423 s.printf("serving")
424 s.serve = true
425 if s.lis == nil {
426 s.mu.Unlock()
427 lis.Close()
428 return ErrServerStopped
429 }
430 s.lis[lis] = true
431 s.mu.Unlock()
432 defer func() {
433 s.mu.Lock()
434 if s.lis != nil && s.lis[lis] {
435 lis.Close()
436 delete(s.lis, lis)
437 }
438 s.mu.Unlock()
439 }()
440
441 var tempDelay time.Duration // how long to sleep on accept failure
442
443 for {
444 rawConn, err := lis.Accept()
445 if err != nil {
446 if ne, ok := err.(interface {
447 Temporary() bool
448 }); ok && ne.Temporary() {
449 if tempDelay == 0 {
450 tempDelay = 5 * time.Millisecond
451 } else {
452 tempDelay *= 2
453 }
454 if max := 1 * time.Second; tempDelay > max {
455 tempDelay = max
456 }
457 s.mu.Lock()
458 s.printf("Accept error: %v; retrying in %v", err, tempDelay)
459 s.mu.Unlock()
460 timer := time.NewTimer(tempDelay)
461 select {
462 case <-timer.C:
463 case <-s.ctx.Done():
464 }
465 timer.Stop()
466 continue
467 }
468 s.mu.Lock()
469 s.printf("done serving; Accept = %v", err)
470 s.mu.Unlock()
471 return err
472 }
473 tempDelay = 0
474 // Start a new goroutine to deal with rawConn
475 // so we don't stall this Accept loop goroutine.
476 go s.handleRawConn(rawConn)
477 }
478}
479
480// handleRawConn is run in its own goroutine and handles a just-accepted
481// connection that has not had any I/O performed on it yet.
482func (s *Server) handleRawConn(rawConn net.Conn) {
483 conn, authInfo, err := s.useTransportAuthenticator(rawConn)
484 if err != nil {
485 s.mu.Lock()
486 s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
487 s.mu.Unlock()
488 grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
489 // If serverHandShake returns ErrConnDispatched, keep rawConn open.
490 if err != credentials.ErrConnDispatched {
491 rawConn.Close()
492 }
493 return
494 }
495
496 s.mu.Lock()
497 if s.conns == nil {
498 s.mu.Unlock()
499 conn.Close()
500 return
501 }
502 s.mu.Unlock()
503
504 if s.opts.useHandlerImpl {
505 s.serveUsingHandler(conn)
506 } else {
507 s.serveHTTP2Transport(conn, authInfo)
508 }
509}
510
511// serveHTTP2Transport sets up a http/2 transport (using the
512// gRPC http2 server transport in transport/http2_server.go) and
513// serves streams on it.
514// This is run in its own goroutine (it does network I/O in
515// transport.NewServerTransport).
516func (s *Server) serveHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) {
517 config := &transport.ServerConfig{
518 MaxStreams: s.opts.maxConcurrentStreams,
519 AuthInfo: authInfo,
520 InTapHandle: s.opts.inTapHandle,
521 StatsHandler: s.opts.statsHandler,
522 KeepaliveParams: s.opts.keepaliveParams,
523 KeepalivePolicy: s.opts.keepalivePolicy,
524 InitialWindowSize: s.opts.initialWindowSize,
525 InitialConnWindowSize: s.opts.initialConnWindowSize,
526 }
527 st, err := transport.NewServerTransport("http2", c, config)
528 if err != nil {
529 s.mu.Lock()
530 s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err)
531 s.mu.Unlock()
532 c.Close()
533 grpclog.Warningln("grpc: Server.Serve failed to create ServerTransport: ", err)
534 return
535 }
536 if !s.addConn(st) {
537 st.Close()
538 return
539 }
540 s.serveStreams(st)
541}
542
543func (s *Server) serveStreams(st transport.ServerTransport) {
544 defer s.removeConn(st)
545 defer st.Close()
546 var wg sync.WaitGroup
547 st.HandleStreams(func(stream *transport.Stream) {
548 wg.Add(1)
549 go func() {
550 defer wg.Done()
551 s.handleStream(st, stream, s.traceInfo(st, stream))
552 }()
553 }, func(ctx context.Context, method string) context.Context {
554 if !EnableTracing {
555 return ctx
556 }
557 tr := trace.New("grpc.Recv."+methodFamily(method), method)
558 return trace.NewContext(ctx, tr)
559 })
560 wg.Wait()
561}
562
563var _ http.Handler = (*Server)(nil)
564
565// serveUsingHandler is called from handleRawConn when s is configured
566// to handle requests via the http.Handler interface. It sets up a
567// net/http.Server to handle the just-accepted conn. The http.Server
568// is configured to route all incoming requests (all HTTP/2 streams)
569// to ServeHTTP, which creates a new ServerTransport for each stream.
570// serveUsingHandler blocks until conn closes.
571//
572// This codepath is only used when Server.TestingUseHandlerImpl has
573// been configured. This lets the end2end tests exercise the ServeHTTP
574// method as one of the environment types.
575//
576// conn is the *tls.Conn that's already been authenticated.
577func (s *Server) serveUsingHandler(conn net.Conn) {
578 if !s.addConn(conn) {
579 conn.Close()
580 return
581 }
582 defer s.removeConn(conn)
583 h2s := &http2.Server{
584 MaxConcurrentStreams: s.opts.maxConcurrentStreams,
585 }
586 h2s.ServeConn(conn, &http2.ServeConnOpts{
587 Handler: s,
588 })
589}
590
591// ServeHTTP implements the Go standard library's http.Handler
592// interface by responding to the gRPC request r, by looking up
593// the requested gRPC method in the gRPC server s.
594//
595// The provided HTTP request must have arrived on an HTTP/2
596// connection. When using the Go standard library's server,
597// practically this means that the Request must also have arrived
598// over TLS.
599//
600// To share one port (such as 443 for https) between gRPC and an
601// existing http.Handler, use a root http.Handler such as:
602//
603// if r.ProtoMajor == 2 && strings.HasPrefix(
604// r.Header.Get("Content-Type"), "application/grpc") {
605// grpcServer.ServeHTTP(w, r)
606// } else {
607// yourMux.ServeHTTP(w, r)
608// }
609//
610// Note that ServeHTTP uses Go's HTTP/2 server implementation which is totally
611// separate from grpc-go's HTTP/2 server. Performance and features may vary
612// between the two paths. ServeHTTP does not support some gRPC features
613// available through grpc-go's HTTP/2 server, and it is currently EXPERIMENTAL
614// and subject to change.
615func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
616 st, err := transport.NewServerHandlerTransport(w, r)
617 if err != nil {
618 http.Error(w, err.Error(), http.StatusInternalServerError)
619 return
620 }
621 if !s.addConn(st) {
622 st.Close()
623 return
624 }
625 defer s.removeConn(st)
626 s.serveStreams(st)
627}
628
629// traceInfo returns a traceInfo and associates it with stream, if tracing is enabled.
630// If tracing is not enabled, it returns nil.
631func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) {
632 tr, ok := trace.FromContext(stream.Context())
633 if !ok {
634 return nil
635 }
636
637 trInfo = &traceInfo{
638 tr: tr,
639 }
640 trInfo.firstLine.client = false
641 trInfo.firstLine.remoteAddr = st.RemoteAddr()
642
643 if dl, ok := stream.Context().Deadline(); ok {
644 trInfo.firstLine.deadline = dl.Sub(time.Now())
645 }
646 return trInfo
647}
648
649func (s *Server) addConn(c io.Closer) bool {
650 s.mu.Lock()
651 defer s.mu.Unlock()
652 if s.conns == nil || s.drain {
653 return false
654 }
655 s.conns[c] = true
656 return true
657}
658
659func (s *Server) removeConn(c io.Closer) {
660 s.mu.Lock()
661 defer s.mu.Unlock()
662 if s.conns != nil {
663 delete(s.conns, c)
664 s.cv.Broadcast()
665 }
666}
667
668func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options) error {
669 var (
670 cbuf *bytes.Buffer
671 outPayload *stats.OutPayload
672 )
673 if cp != nil {
674 cbuf = new(bytes.Buffer)
675 }
676 if s.opts.statsHandler != nil {
677 outPayload = &stats.OutPayload{}
678 }
679 p, err := encode(s.opts.codec, msg, cp, cbuf, outPayload)
680 if err != nil {
681 grpclog.Errorln("grpc: server failed to encode response: ", err)
682 return err
683 }
684 if len(p) > s.opts.maxSendMessageSize {
685 return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(p), s.opts.maxSendMessageSize)
686 }
687 err = t.Write(stream, p, opts)
688 if err == nil && outPayload != nil {
689 outPayload.SentTime = time.Now()
690 s.opts.statsHandler.HandleRPC(stream.Context(), outPayload)
691 }
692 return err
693}
694
695func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc, trInfo *traceInfo) (err error) {
696 sh := s.opts.statsHandler
697 if sh != nil {
698 begin := &stats.Begin{
699 BeginTime: time.Now(),
700 }
701 sh.HandleRPC(stream.Context(), begin)
702 defer func() {
703 end := &stats.End{
704 EndTime: time.Now(),
705 }
706 if err != nil && err != io.EOF {
707 end.Error = toRPCErr(err)
708 }
709 sh.HandleRPC(stream.Context(), end)
710 }()
711 }
712 if trInfo != nil {
713 defer trInfo.tr.Finish()
714 trInfo.firstLine.client = false
715 trInfo.tr.LazyLog(&trInfo.firstLine, false)
716 defer func() {
717 if err != nil && err != io.EOF {
718 trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
719 trInfo.tr.SetError()
720 }
721 }()
722 }
723 if s.opts.cp != nil {
724 // NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
725 stream.SetSendCompress(s.opts.cp.Type())
726 }
727 p := &parser{r: stream}
728 pf, req, err := p.recvMsg(s.opts.maxReceiveMessageSize)
729 if err == io.EOF {
730 // The entire stream is done (for unary RPC only).
731 return err
732 }
733 if err == io.ErrUnexpectedEOF {
734 err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error())
735 }
736 if err != nil {
737 if st, ok := status.FromError(err); ok {
738 if e := t.WriteStatus(stream, st); e != nil {
739 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
740 }
741 } else {
742 switch st := err.(type) {
743 case transport.ConnectionError:
744 // Nothing to do here.
745 case transport.StreamError:
746 if e := t.WriteStatus(stream, status.New(st.Code, st.Desc)); e != nil {
747 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
748 }
749 default:
750 panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", st, st))
751 }
752 }
753 return err
754 }
755
756 if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil {
757 if st, ok := status.FromError(err); ok {
758 if e := t.WriteStatus(stream, st); e != nil {
759 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
760 }
761 return err
762 }
763 if e := t.WriteStatus(stream, status.New(codes.Internal, err.Error())); e != nil {
764 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
765 }
766
767 // TODO checkRecvPayload always return RPC error. Add a return here if necessary.
768 }
769 var inPayload *stats.InPayload
770 if sh != nil {
771 inPayload = &stats.InPayload{
772 RecvTime: time.Now(),
773 }
774 }
775 df := func(v interface{}) error {
776 if inPayload != nil {
777 inPayload.WireLength = len(req)
778 }
779 if pf == compressionMade {
780 var err error
781 req, err = s.opts.dc.Do(bytes.NewReader(req))
782 if err != nil {
783 return Errorf(codes.Internal, err.Error())
784 }
785 }
786 if len(req) > s.opts.maxReceiveMessageSize {
787 // TODO: Revisit the error code. Currently keep it consistent with
788 // java implementation.
789 return status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(req), s.opts.maxReceiveMessageSize)
790 }
791 if err := s.opts.codec.Unmarshal(req, v); err != nil {
792 return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err)
793 }
794 if inPayload != nil {
795 inPayload.Payload = v
796 inPayload.Data = req
797 inPayload.Length = len(req)
798 sh.HandleRPC(stream.Context(), inPayload)
799 }
800 if trInfo != nil {
801 trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true)
802 }
803 return nil
804 }
805 reply, appErr := md.Handler(srv.server, stream.Context(), df, s.opts.unaryInt)
806 if appErr != nil {
807 appStatus, ok := status.FromError(appErr)
808 if !ok {
809 // Convert appErr if it is not a grpc status error.
810 appErr = status.Error(convertCode(appErr), appErr.Error())
811 appStatus, _ = status.FromError(appErr)
812 }
813 if trInfo != nil {
814 trInfo.tr.LazyLog(stringer(appStatus.Message()), true)
815 trInfo.tr.SetError()
816 }
817 if e := t.WriteStatus(stream, appStatus); e != nil {
818 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status: %v", e)
819 }
820 return appErr
821 }
822 if trInfo != nil {
823 trInfo.tr.LazyLog(stringer("OK"), false)
824 }
825 opts := &transport.Options{
826 Last: true,
827 Delay: false,
828 }
829 if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil {
830 if err == io.EOF {
831 // The entire stream is done (for unary RPC only).
832 return err
833 }
834 if s, ok := status.FromError(err); ok {
835 if e := t.WriteStatus(stream, s); e != nil {
836 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status: %v", e)
837 }
838 } else {
839 switch st := err.(type) {
840 case transport.ConnectionError:
841 // Nothing to do here.
842 case transport.StreamError:
843 if e := t.WriteStatus(stream, status.New(st.Code, st.Desc)); e != nil {
844 grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
845 }
846 default:
847 panic(fmt.Sprintf("grpc: Unexpected error (%T) from sendResponse: %v", st, st))
848 }
849 }
850 return err
851 }
852 if trInfo != nil {
853 trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true)
854 }
855 // TODO: Should we be logging if writing status failed here, like above?
856 // Should the logging be in WriteStatus? Should we ignore the WriteStatus
857 // error or allow the stats handler to see it?
858 return t.WriteStatus(stream, status.New(codes.OK, ""))
859}
860
861func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) {
862 sh := s.opts.statsHandler
863 if sh != nil {
864 begin := &stats.Begin{
865 BeginTime: time.Now(),
866 }
867 sh.HandleRPC(stream.Context(), begin)
868 defer func() {
869 end := &stats.End{
870 EndTime: time.Now(),
871 }
872 if err != nil && err != io.EOF {
873 end.Error = toRPCErr(err)
874 }
875 sh.HandleRPC(stream.Context(), end)
876 }()
877 }
878 if s.opts.cp != nil {
879 stream.SetSendCompress(s.opts.cp.Type())
880 }
881 ss := &serverStream{
882 t: t,
883 s: stream,
884 p: &parser{r: stream},
885 codec: s.opts.codec,
886 cp: s.opts.cp,
887 dc: s.opts.dc,
888 maxReceiveMessageSize: s.opts.maxReceiveMessageSize,
889 maxSendMessageSize: s.opts.maxSendMessageSize,
890 trInfo: trInfo,
891 statsHandler: sh,
892 }
893 if ss.cp != nil {
894 ss.cbuf = new(bytes.Buffer)
895 }
896 if trInfo != nil {
897 trInfo.tr.LazyLog(&trInfo.firstLine, false)
898 defer func() {
899 ss.mu.Lock()
900 if err != nil && err != io.EOF {
901 ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
902 ss.trInfo.tr.SetError()
903 }
904 ss.trInfo.tr.Finish()
905 ss.trInfo.tr = nil
906 ss.mu.Unlock()
907 }()
908 }
909 var appErr error
910 var server interface{}
911 if srv != nil {
912 server = srv.server
913 }
914 if s.opts.streamInt == nil {
915 appErr = sd.Handler(server, ss)
916 } else {
917 info := &StreamServerInfo{
918 FullMethod: stream.Method(),
919 IsClientStream: sd.ClientStreams,
920 IsServerStream: sd.ServerStreams,
921 }
922 appErr = s.opts.streamInt(server, ss, info, sd.Handler)
923 }
924 if appErr != nil {
925 appStatus, ok := status.FromError(appErr)
926 if !ok {
927 switch err := appErr.(type) {
928 case transport.StreamError:
929 appStatus = status.New(err.Code, err.Desc)
930 default:
931 appStatus = status.New(convertCode(appErr), appErr.Error())
932 }
933 appErr = appStatus.Err()
934 }
935 if trInfo != nil {
936 ss.mu.Lock()
937 ss.trInfo.tr.LazyLog(stringer(appStatus.Message()), true)
938 ss.trInfo.tr.SetError()
939 ss.mu.Unlock()
940 }
941 t.WriteStatus(ss.s, appStatus)
942 // TODO: Should we log an error from WriteStatus here and below?
943 return appErr
944 }
945 if trInfo != nil {
946 ss.mu.Lock()
947 ss.trInfo.tr.LazyLog(stringer("OK"), false)
948 ss.mu.Unlock()
949 }
950 return t.WriteStatus(ss.s, status.New(codes.OK, ""))
951
952}
953
954func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) {
955 sm := stream.Method()
956 if sm != "" && sm[0] == '/' {
957 sm = sm[1:]
958 }
959 pos := strings.LastIndex(sm, "/")
960 if pos == -1 {
961 if trInfo != nil {
962 trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true)
963 trInfo.tr.SetError()
964 }
965 errDesc := fmt.Sprintf("malformed method name: %q", stream.Method())
966 if err := t.WriteStatus(stream, status.New(codes.ResourceExhausted, errDesc)); err != nil {
967 if trInfo != nil {
968 trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
969 trInfo.tr.SetError()
970 }
971 grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
972 }
973 if trInfo != nil {
974 trInfo.tr.Finish()
975 }
976 return
977 }
978 service := sm[:pos]
979 method := sm[pos+1:]
980 srv, ok := s.m[service]
981 if !ok {
982 if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil {
983 s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo)
984 return
985 }
986 if trInfo != nil {
987 trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true)
988 trInfo.tr.SetError()
989 }
990 errDesc := fmt.Sprintf("unknown service %v", service)
991 if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
992 if trInfo != nil {
993 trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
994 trInfo.tr.SetError()
995 }
996 grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
997 }
998 if trInfo != nil {
999 trInfo.tr.Finish()
1000 }
1001 return
1002 }
1003 // Unary RPC or Streaming RPC?
1004 if md, ok := srv.md[method]; ok {
1005 s.processUnaryRPC(t, stream, srv, md, trInfo)
1006 return
1007 }
1008 if sd, ok := srv.sd[method]; ok {
1009 s.processStreamingRPC(t, stream, srv, sd, trInfo)
1010 return
1011 }
1012 if trInfo != nil {
1013 trInfo.tr.LazyLog(&fmtStringer{"Unknown method %v", []interface{}{method}}, true)
1014 trInfo.tr.SetError()
1015 }
1016 if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil {
1017 s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo)
1018 return
1019 }
1020 errDesc := fmt.Sprintf("unknown method %v", method)
1021 if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
1022 if trInfo != nil {
1023 trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
1024 trInfo.tr.SetError()
1025 }
1026 grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
1027 }
1028 if trInfo != nil {
1029 trInfo.tr.Finish()
1030 }
1031}
1032
1033// Stop stops the gRPC server. It immediately closes all open
1034// connections and listeners.
1035// It cancels all active RPCs on the server side and the corresponding
1036// pending RPCs on the client side will get notified by connection
1037// errors.
1038func (s *Server) Stop() {
1039 s.mu.Lock()
1040 listeners := s.lis
1041 s.lis = nil
1042 st := s.conns
1043 s.conns = nil
1044 // interrupt GracefulStop if Stop and GracefulStop are called concurrently.
1045 s.cv.Broadcast()
1046 s.mu.Unlock()
1047
1048 for lis := range listeners {
1049 lis.Close()
1050 }
1051 for c := range st {
1052 c.Close()
1053 }
1054
1055 s.mu.Lock()
1056 s.cancel()
1057 if s.events != nil {
1058 s.events.Finish()
1059 s.events = nil
1060 }
1061 s.mu.Unlock()
1062}
1063
1064// GracefulStop stops the gRPC server gracefully. It stops the server from
1065// accepting new connections and RPCs and blocks until all the pending RPCs are
1066// finished.
1067func (s *Server) GracefulStop() {
1068 s.mu.Lock()
1069 defer s.mu.Unlock()
1070 if s.conns == nil {
1071 return
1072 }
1073 for lis := range s.lis {
1074 lis.Close()
1075 }
1076 s.lis = nil
1077 s.cancel()
1078 if !s.drain {
1079 for c := range s.conns {
1080 c.(transport.ServerTransport).Drain()
1081 }
1082 s.drain = true
1083 }
1084 for len(s.conns) != 0 {
1085 s.cv.Wait()
1086 }
1087 s.conns = nil
1088 if s.events != nil {
1089 s.events.Finish()
1090 s.events = nil
1091 }
1092}
1093
1094func init() {
1095 internal.TestingCloseConns = func(arg interface{}) {
1096 arg.(*Server).testingCloseConns()
1097 }
1098 internal.TestingUseHandlerImpl = func(arg interface{}) {
1099 arg.(*Server).opts.useHandlerImpl = true
1100 }
1101}
1102
1103// testingCloseConns closes all existing transports but keeps s.lis
1104// accepting new connections.
1105func (s *Server) testingCloseConns() {
1106 s.mu.Lock()
1107 for c := range s.conns {
1108 c.Close()
1109 delete(s.conns, c)
1110 }
1111 s.mu.Unlock()
1112}
1113
1114// SetHeader sets the header metadata.
1115// When called multiple times, all the provided metadata will be merged.
1116// All the metadata will be sent out when one of the following happens:
1117// - grpc.SendHeader() is called;
1118// - The first response is sent out;
1119// - An RPC status is sent out (error or success).
1120func SetHeader(ctx context.Context, md metadata.MD) error {
1121 if md.Len() == 0 {
1122 return nil
1123 }
1124 stream, ok := transport.StreamFromContext(ctx)
1125 if !ok {
1126 return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx)
1127 }
1128 return stream.SetHeader(md)
1129}
1130
1131// SendHeader sends header metadata. It may be called at most once.
1132// The provided md and headers set by SetHeader() will be sent.
1133func SendHeader(ctx context.Context, md metadata.MD) error {
1134 stream, ok := transport.StreamFromContext(ctx)
1135 if !ok {
1136 return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx)
1137 }
1138 t := stream.ServerTransport()
1139 if t == nil {
1140 grpclog.Fatalf("grpc: SendHeader: %v has no ServerTransport to send header metadata.", stream)
1141 }
1142 if err := t.WriteHeader(stream, md); err != nil {
1143 return toRPCErr(err)
1144 }
1145 return nil
1146}
1147
1148// SetTrailer sets the trailer metadata that will be sent when an RPC returns.
1149// When called more than once, all the provided metadata will be merged.
1150func SetTrailer(ctx context.Context, md metadata.MD) error {
1151 if md.Len() == 0 {
1152 return nil
1153 }
1154 stream, ok := transport.StreamFromContext(ctx)
1155 if !ok {
1156 return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx)
1157 }
1158 return stream.SetTrailer(md)
1159}
diff --git a/vendor/google.golang.org/grpc/stats/handlers.go b/vendor/google.golang.org/grpc/stats/handlers.go
new file mode 100644
index 0000000..05b384c
--- /dev/null
+++ b/vendor/google.golang.org/grpc/stats/handlers.go
@@ -0,0 +1,64 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package stats
20
21import (
22 "net"
23
24 "golang.org/x/net/context"
25)
26
27// ConnTagInfo defines the relevant information needed by connection context tagger.
28type ConnTagInfo struct {
29 // RemoteAddr is the remote address of the corresponding connection.
30 RemoteAddr net.Addr
31 // LocalAddr is the local address of the corresponding connection.
32 LocalAddr net.Addr
33}
34
35// RPCTagInfo defines the relevant information needed by RPC context tagger.
36type RPCTagInfo struct {
37 // FullMethodName is the RPC method in the format of /package.service/method.
38 FullMethodName string
39 // FailFast indicates if this RPC is failfast.
40 // This field is only valid on client side, it's always false on server side.
41 FailFast bool
42}
43
44// Handler defines the interface for the related stats handling (e.g., RPCs, connections).
45type Handler interface {
46 // TagRPC can attach some information to the given context.
47 // The context used for the rest lifetime of the RPC will be derived from
48 // the returned context.
49 TagRPC(context.Context, *RPCTagInfo) context.Context
50 // HandleRPC processes the RPC stats.
51 HandleRPC(context.Context, RPCStats)
52
53 // TagConn can attach some information to the given context.
54 // The returned context will be used for stats handling.
55 // For conn stats handling, the context used in HandleConn for this
56 // connection will be derived from the context returned.
57 // For RPC stats handling,
58 // - On server side, the context used in HandleRPC for all RPCs on this
59 // connection will be derived from the context returned.
60 // - On client side, the context is not derived from the context returned.
61 TagConn(context.Context, *ConnTagInfo) context.Context
62 // HandleConn processes the Conn stats.
63 HandleConn(context.Context, ConnStats)
64}
diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go
new file mode 100644
index 0000000..338a3a7
--- /dev/null
+++ b/vendor/google.golang.org/grpc/stats/stats.go
@@ -0,0 +1,210 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package stats is for collecting and reporting various network and RPC stats.
20// This package is for monitoring purpose only. All fields are read-only.
21// All APIs are experimental.
22package stats // import "google.golang.org/grpc/stats"
23
24import (
25 "net"
26 "time"
27)
28
29// RPCStats contains stats information about RPCs.
30type RPCStats interface {
31 isRPCStats()
32 // IsClient returns true if this RPCStats is from client side.
33 IsClient() bool
34}
35
36// Begin contains stats when an RPC begins.
37// FailFast is only valid if this Begin is from client side.
38type Begin struct {
39 // Client is true if this Begin is from client side.
40 Client bool
41 // BeginTime is the time when the RPC begins.
42 BeginTime time.Time
43 // FailFast indicates if this RPC is failfast.
44 FailFast bool
45}
46
47// IsClient indicates if the stats information is from client side.
48func (s *Begin) IsClient() bool { return s.Client }
49
50func (s *Begin) isRPCStats() {}
51
52// InPayload contains the information for an incoming payload.
53type InPayload struct {
54 // Client is true if this InPayload is from client side.
55 Client bool
56 // Payload is the payload with original type.
57 Payload interface{}
58 // Data is the serialized message payload.
59 Data []byte
60 // Length is the length of uncompressed data.
61 Length int
62 // WireLength is the length of data on wire (compressed, signed, encrypted).
63 WireLength int
64 // RecvTime is the time when the payload is received.
65 RecvTime time.Time
66}
67
68// IsClient indicates if the stats information is from client side.
69func (s *InPayload) IsClient() bool { return s.Client }
70
71func (s *InPayload) isRPCStats() {}
72
73// InHeader contains stats when a header is received.
74type InHeader struct {
75 // Client is true if this InHeader is from client side.
76 Client bool
77 // WireLength is the wire length of header.
78 WireLength int
79
80 // The following fields are valid only if Client is false.
81 // FullMethod is the full RPC method string, i.e., /package.service/method.
82 FullMethod string
83 // RemoteAddr is the remote address of the corresponding connection.
84 RemoteAddr net.Addr
85 // LocalAddr is the local address of the corresponding connection.
86 LocalAddr net.Addr
87 // Compression is the compression algorithm used for the RPC.
88 Compression string
89}
90
91// IsClient indicates if the stats information is from client side.
92func (s *InHeader) IsClient() bool { return s.Client }
93
94func (s *InHeader) isRPCStats() {}
95
96// InTrailer contains stats when a trailer is received.
97type InTrailer struct {
98 // Client is true if this InTrailer is from client side.
99 Client bool
100 // WireLength is the wire length of trailer.
101 WireLength int
102}
103
104// IsClient indicates if the stats information is from client side.
105func (s *InTrailer) IsClient() bool { return s.Client }
106
107func (s *InTrailer) isRPCStats() {}
108
109// OutPayload contains the information for an outgoing payload.
110type OutPayload struct {
111 // Client is true if this OutPayload is from client side.
112 Client bool
113 // Payload is the payload with original type.
114 Payload interface{}
115 // Data is the serialized message payload.
116 Data []byte
117 // Length is the length of uncompressed data.
118 Length int
119 // WireLength is the length of data on wire (compressed, signed, encrypted).
120 WireLength int
121 // SentTime is the time when the payload is sent.
122 SentTime time.Time
123}
124
125// IsClient indicates if this stats information is from client side.
126func (s *OutPayload) IsClient() bool { return s.Client }
127
128func (s *OutPayload) isRPCStats() {}
129
130// OutHeader contains stats when a header is sent.
131type OutHeader struct {
132 // Client is true if this OutHeader is from client side.
133 Client bool
134 // WireLength is the wire length of header.
135 WireLength int
136
137 // The following fields are valid only if Client is true.
138 // FullMethod is the full RPC method string, i.e., /package.service/method.
139 FullMethod string
140 // RemoteAddr is the remote address of the corresponding connection.
141 RemoteAddr net.Addr
142 // LocalAddr is the local address of the corresponding connection.
143 LocalAddr net.Addr
144 // Compression is the compression algorithm used for the RPC.
145 Compression string
146}
147
148// IsClient indicates if this stats information is from client side.
149func (s *OutHeader) IsClient() bool { return s.Client }
150
151func (s *OutHeader) isRPCStats() {}
152
153// OutTrailer contains stats when a trailer is sent.
154type OutTrailer struct {
155 // Client is true if this OutTrailer is from client side.
156 Client bool
157 // WireLength is the wire length of trailer.
158 WireLength int
159}
160
161// IsClient indicates if this stats information is from client side.
162func (s *OutTrailer) IsClient() bool { return s.Client }
163
164func (s *OutTrailer) isRPCStats() {}
165
166// End contains stats when an RPC ends.
167type End struct {
168 // Client is true if this End is from client side.
169 Client bool
170 // EndTime is the time when the RPC ends.
171 EndTime time.Time
172 // Error is the error the RPC ended with. It is an error generated from
173 // status.Status and can be converted back to status.Status using
174 // status.FromError if non-nil.
175 Error error
176}
177
178// IsClient indicates if this is from client side.
179func (s *End) IsClient() bool { return s.Client }
180
181func (s *End) isRPCStats() {}
182
183// ConnStats contains stats information about connections.
184type ConnStats interface {
185 isConnStats()
186 // IsClient returns true if this ConnStats is from client side.
187 IsClient() bool
188}
189
190// ConnBegin contains the stats of a connection when it is established.
191type ConnBegin struct {
192 // Client is true if this ConnBegin is from client side.
193 Client bool
194}
195
196// IsClient indicates if this is from client side.
197func (s *ConnBegin) IsClient() bool { return s.Client }
198
199func (s *ConnBegin) isConnStats() {}
200
201// ConnEnd contains the stats of a connection when it ends.
202type ConnEnd struct {
203 // Client is true if this ConnEnd is from client side.
204 Client bool
205}
206
207// IsClient indicates if this is from client side.
208func (s *ConnEnd) IsClient() bool { return s.Client }
209
210func (s *ConnEnd) isConnStats() {}
diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go
new file mode 100644
index 0000000..871dc4b
--- /dev/null
+++ b/vendor/google.golang.org/grpc/status/status.go
@@ -0,0 +1,168 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package status implements errors returned by gRPC. These errors are
20// serialized and transmitted on the wire between server and client, and allow
21// for additional data to be transmitted via the Details field in the status
22// proto. gRPC service handlers should return an error created by this
23// package, and gRPC clients should expect a corresponding error to be
24// returned from the RPC call.
25//
26// This package upholds the invariants that a non-nil error may not
27// contain an OK code, and an OK code must result in a nil error.
28package status
29
30import (
31 "errors"
32 "fmt"
33
34 "github.com/golang/protobuf/proto"
35 "github.com/golang/protobuf/ptypes"
36 spb "google.golang.org/genproto/googleapis/rpc/status"
37 "google.golang.org/grpc/codes"
38)
39
40// statusError is an alias of a status proto. It implements error and Status,
41// and a nil statusError should never be returned by this package.
42type statusError spb.Status
43
44func (se *statusError) Error() string {
45 p := (*spb.Status)(se)
46 return fmt.Sprintf("rpc error: code = %s desc = %s", codes.Code(p.GetCode()), p.GetMessage())
47}
48
49func (se *statusError) status() *Status {
50 return &Status{s: (*spb.Status)(se)}
51}
52
53// Status represents an RPC status code, message, and details. It is immutable
54// and should be created with New, Newf, or FromProto.
55type Status struct {
56 s *spb.Status
57}
58
59// Code returns the status code contained in s.
60func (s *Status) Code() codes.Code {
61 if s == nil || s.s == nil {
62 return codes.OK
63 }
64 return codes.Code(s.s.Code)
65}
66
67// Message returns the message contained in s.
68func (s *Status) Message() string {
69 if s == nil || s.s == nil {
70 return ""
71 }
72 return s.s.Message
73}
74
75// Proto returns s's status as an spb.Status proto message.
76func (s *Status) Proto() *spb.Status {
77 if s == nil {
78 return nil
79 }
80 return proto.Clone(s.s).(*spb.Status)
81}
82
83// Err returns an immutable error representing s; returns nil if s.Code() is
84// OK.
85func (s *Status) Err() error {
86 if s.Code() == codes.OK {
87 return nil
88 }
89 return (*statusError)(s.s)
90}
91
92// New returns a Status representing c and msg.
93func New(c codes.Code, msg string) *Status {
94 return &Status{s: &spb.Status{Code: int32(c), Message: msg}}
95}
96
97// Newf returns New(c, fmt.Sprintf(format, a...)).
98func Newf(c codes.Code, format string, a ...interface{}) *Status {
99 return New(c, fmt.Sprintf(format, a...))
100}
101
102// Error returns an error representing c and msg. If c is OK, returns nil.
103func Error(c codes.Code, msg string) error {
104 return New(c, msg).Err()
105}
106
107// Errorf returns Error(c, fmt.Sprintf(format, a...)).
108func Errorf(c codes.Code, format string, a ...interface{}) error {
109 return Error(c, fmt.Sprintf(format, a...))
110}
111
112// ErrorProto returns an error representing s. If s.Code is OK, returns nil.
113func ErrorProto(s *spb.Status) error {
114 return FromProto(s).Err()
115}
116
117// FromProto returns a Status representing s.
118func FromProto(s *spb.Status) *Status {
119 return &Status{s: proto.Clone(s).(*spb.Status)}
120}
121
122// FromError returns a Status representing err if it was produced from this
123// package, otherwise it returns nil, false.
124func FromError(err error) (s *Status, ok bool) {
125 if err == nil {
126 return &Status{s: &spb.Status{Code: int32(codes.OK)}}, true
127 }
128 if s, ok := err.(*statusError); ok {
129 return s.status(), true
130 }
131 return nil, false
132}
133
134// WithDetails returns a new status with the provided details messages appended to the status.
135// If any errors are encountered, it returns nil and the first error encountered.
136func (s *Status) WithDetails(details ...proto.Message) (*Status, error) {
137 if s.Code() == codes.OK {
138 return nil, errors.New("no error details for status with code OK")
139 }
140 // s.Code() != OK implies that s.Proto() != nil.
141 p := s.Proto()
142 for _, detail := range details {
143 any, err := ptypes.MarshalAny(detail)
144 if err != nil {
145 return nil, err
146 }
147 p.Details = append(p.Details, any)
148 }
149 return &Status{s: p}, nil
150}
151
152// Details returns a slice of details messages attached to the status.
153// If a detail cannot be decoded, the error is returned in place of the detail.
154func (s *Status) Details() []interface{} {
155 if s == nil || s.s == nil {
156 return nil
157 }
158 details := make([]interface{}, 0, len(s.s.Details))
159 for _, any := range s.s.Details {
160 detail := &ptypes.DynamicAny{}
161 if err := ptypes.UnmarshalAny(any, detail); err != nil {
162 details = append(details, err)
163 continue
164 }
165 details = append(details, detail.Message)
166 }
167 return details
168}
diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go
new file mode 100644
index 0000000..1c621ba
--- /dev/null
+++ b/vendor/google.golang.org/grpc/stream.go
@@ -0,0 +1,661 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "bytes"
23 "errors"
24 "io"
25 "sync"
26 "time"
27
28 "golang.org/x/net/context"
29 "golang.org/x/net/trace"
30 "google.golang.org/grpc/codes"
31 "google.golang.org/grpc/metadata"
32 "google.golang.org/grpc/peer"
33 "google.golang.org/grpc/stats"
34 "google.golang.org/grpc/status"
35 "google.golang.org/grpc/transport"
36)
37
38// StreamHandler defines the handler called by gRPC server to complete the
39// execution of a streaming RPC.
40type StreamHandler func(srv interface{}, stream ServerStream) error
41
42// StreamDesc represents a streaming RPC service's method specification.
43type StreamDesc struct {
44 StreamName string
45 Handler StreamHandler
46
47 // At least one of these is true.
48 ServerStreams bool
49 ClientStreams bool
50}
51
52// Stream defines the common interface a client or server stream has to satisfy.
53type Stream interface {
54 // Context returns the context for this stream.
55 Context() context.Context
56 // SendMsg blocks until it sends m, the stream is done or the stream
57 // breaks.
58 // On error, it aborts the stream and returns an RPC status on client
59 // side. On server side, it simply returns the error to the caller.
60 // SendMsg is called by generated code. Also Users can call SendMsg
61 // directly when it is really needed in their use cases.
62 // It's safe to have a goroutine calling SendMsg and another goroutine calling
63 // recvMsg on the same stream at the same time.
64 // But it is not safe to call SendMsg on the same stream in different goroutines.
65 SendMsg(m interface{}) error
66 // RecvMsg blocks until it receives a message or the stream is
67 // done. On client side, it returns io.EOF when the stream is done. On
68 // any other error, it aborts the stream and returns an RPC status. On
69 // server side, it simply returns the error to the caller.
70 // It's safe to have a goroutine calling SendMsg and another goroutine calling
71 // recvMsg on the same stream at the same time.
72 // But it is not safe to call RecvMsg on the same stream in different goroutines.
73 RecvMsg(m interface{}) error
74}
75
76// ClientStream defines the interface a client stream has to satisfy.
77type ClientStream interface {
78 // Header returns the header metadata received from the server if there
79 // is any. It blocks if the metadata is not ready to read.
80 Header() (metadata.MD, error)
81 // Trailer returns the trailer metadata from the server, if there is any.
82 // It must only be called after stream.CloseAndRecv has returned, or
83 // stream.Recv has returned a non-nil error (including io.EOF).
84 Trailer() metadata.MD
85 // CloseSend closes the send direction of the stream. It closes the stream
86 // when non-nil error is met.
87 CloseSend() error
88 // Stream.SendMsg() may return a non-nil error when something wrong happens sending
89 // the request. The returned error indicates the status of this sending, not the final
90 // status of the RPC.
91 // Always call Stream.RecvMsg() to get the final status if you care about the status of
92 // the RPC.
93 Stream
94}
95
96// NewClientStream creates a new Stream for the client side. This is called
97// by generated code.
98func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
99 if cc.dopts.streamInt != nil {
100 return cc.dopts.streamInt(ctx, desc, cc, method, newClientStream, opts...)
101 }
102 return newClientStream(ctx, desc, cc, method, opts...)
103}
104
105func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
106 var (
107 t transport.ClientTransport
108 s *transport.Stream
109 put func()
110 cancel context.CancelFunc
111 )
112 c := defaultCallInfo
113 mc := cc.GetMethodConfig(method)
114 if mc.WaitForReady != nil {
115 c.failFast = !*mc.WaitForReady
116 }
117
118 if mc.Timeout != nil {
119 ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
120 }
121
122 opts = append(cc.dopts.callOptions, opts...)
123 for _, o := range opts {
124 if err := o.before(&c); err != nil {
125 return nil, toRPCErr(err)
126 }
127 }
128 c.maxSendMessageSize = getMaxSize(mc.MaxReqSize, c.maxSendMessageSize, defaultClientMaxSendMessageSize)
129 c.maxReceiveMessageSize = getMaxSize(mc.MaxRespSize, c.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
130
131 callHdr := &transport.CallHdr{
132 Host: cc.authority,
133 Method: method,
134 // If it's not client streaming, we should already have the request to be sent,
135 // so we don't flush the header.
136 // If it's client streaming, the user may never send a request or send it any
137 // time soon, so we ask the transport to flush the header.
138 Flush: desc.ClientStreams,
139 }
140 if cc.dopts.cp != nil {
141 callHdr.SendCompress = cc.dopts.cp.Type()
142 }
143 if c.creds != nil {
144 callHdr.Creds = c.creds
145 }
146 var trInfo traceInfo
147 if EnableTracing {
148 trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
149 trInfo.firstLine.client = true
150 if deadline, ok := ctx.Deadline(); ok {
151 trInfo.firstLine.deadline = deadline.Sub(time.Now())
152 }
153 trInfo.tr.LazyLog(&trInfo.firstLine, false)
154 ctx = trace.NewContext(ctx, trInfo.tr)
155 defer func() {
156 if err != nil {
157 // Need to call tr.finish() if error is returned.
158 // Because tr will not be returned to caller.
159 trInfo.tr.LazyPrintf("RPC: [%v]", err)
160 trInfo.tr.SetError()
161 trInfo.tr.Finish()
162 }
163 }()
164 }
165 ctx = newContextWithRPCInfo(ctx)
166 sh := cc.dopts.copts.StatsHandler
167 if sh != nil {
168 ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: c.failFast})
169 begin := &stats.Begin{
170 Client: true,
171 BeginTime: time.Now(),
172 FailFast: c.failFast,
173 }
174 sh.HandleRPC(ctx, begin)
175 defer func() {
176 if err != nil {
177 // Only handle end stats if err != nil.
178 end := &stats.End{
179 Client: true,
180 Error: err,
181 }
182 sh.HandleRPC(ctx, end)
183 }
184 }()
185 }
186 gopts := BalancerGetOptions{
187 BlockingWait: !c.failFast,
188 }
189 for {
190 t, put, err = cc.getTransport(ctx, gopts)
191 if err != nil {
192 // TODO(zhaoq): Probably revisit the error handling.
193 if _, ok := status.FromError(err); ok {
194 return nil, err
195 }
196 if err == errConnClosing || err == errConnUnavailable {
197 if c.failFast {
198 return nil, Errorf(codes.Unavailable, "%v", err)
199 }
200 continue
201 }
202 // All the other errors are treated as Internal errors.
203 return nil, Errorf(codes.Internal, "%v", err)
204 }
205
206 s, err = t.NewStream(ctx, callHdr)
207 if err != nil {
208 if _, ok := err.(transport.ConnectionError); ok && put != nil {
209 // If error is connection error, transport was sending data on wire,
210 // and we are not sure if anything has been sent on wire.
211 // If error is not connection error, we are sure nothing has been sent.
212 updateRPCInfoInContext(ctx, rpcInfo{bytesSent: true, bytesReceived: false})
213 }
214 if put != nil {
215 put()
216 put = nil
217 }
218 if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast {
219 continue
220 }
221 return nil, toRPCErr(err)
222 }
223 break
224 }
225 // Set callInfo.peer object from stream's context.
226 if peer, ok := peer.FromContext(s.Context()); ok {
227 c.peer = peer
228 }
229 cs := &clientStream{
230 opts: opts,
231 c: c,
232 desc: desc,
233 codec: cc.dopts.codec,
234 cp: cc.dopts.cp,
235 dc: cc.dopts.dc,
236 cancel: cancel,
237
238 put: put,
239 t: t,
240 s: s,
241 p: &parser{r: s},
242
243 tracing: EnableTracing,
244 trInfo: trInfo,
245
246 statsCtx: ctx,
247 statsHandler: cc.dopts.copts.StatsHandler,
248 }
249 if cc.dopts.cp != nil {
250 cs.cbuf = new(bytes.Buffer)
251 }
252 // Listen on ctx.Done() to detect cancellation and s.Done() to detect normal termination
253 // when there is no pending I/O operations on this stream.
254 go func() {
255 select {
256 case <-t.Error():
257 // Incur transport error, simply exit.
258 case <-cc.ctx.Done():
259 cs.finish(ErrClientConnClosing)
260 cs.closeTransportStream(ErrClientConnClosing)
261 case <-s.Done():
262 // TODO: The trace of the RPC is terminated here when there is no pending
263 // I/O, which is probably not the optimal solution.
264 cs.finish(s.Status().Err())
265 cs.closeTransportStream(nil)
266 case <-s.GoAway():
267 cs.finish(errConnDrain)
268 cs.closeTransportStream(errConnDrain)
269 case <-s.Context().Done():
270 err := s.Context().Err()
271 cs.finish(err)
272 cs.closeTransportStream(transport.ContextErr(err))
273 }
274 }()
275 return cs, nil
276}
277
278// clientStream implements a client side Stream.
279type clientStream struct {
280 opts []CallOption
281 c callInfo
282 t transport.ClientTransport
283 s *transport.Stream
284 p *parser
285 desc *StreamDesc
286 codec Codec
287 cp Compressor
288 cbuf *bytes.Buffer
289 dc Decompressor
290 cancel context.CancelFunc
291
292 tracing bool // set to EnableTracing when the clientStream is created.
293
294 mu sync.Mutex
295 put func()
296 closed bool
297 finished bool
298 // trInfo.tr is set when the clientStream is created (if EnableTracing is true),
299 // and is set to nil when the clientStream's finish method is called.
300 trInfo traceInfo
301
302 // statsCtx keeps the user context for stats handling.
303 // All stats collection should use the statsCtx (instead of the stream context)
304 // so that all the generated stats for a particular RPC can be associated in the processing phase.
305 statsCtx context.Context
306 statsHandler stats.Handler
307}
308
309func (cs *clientStream) Context() context.Context {
310 return cs.s.Context()
311}
312
313func (cs *clientStream) Header() (metadata.MD, error) {
314 m, err := cs.s.Header()
315 if err != nil {
316 if _, ok := err.(transport.ConnectionError); !ok {
317 cs.closeTransportStream(err)
318 }
319 }
320 return m, err
321}
322
323func (cs *clientStream) Trailer() metadata.MD {
324 return cs.s.Trailer()
325}
326
327func (cs *clientStream) SendMsg(m interface{}) (err error) {
328 if cs.tracing {
329 cs.mu.Lock()
330 if cs.trInfo.tr != nil {
331 cs.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true)
332 }
333 cs.mu.Unlock()
334 }
335 // TODO Investigate how to signal the stats handling party.
336 // generate error stats if err != nil && err != io.EOF?
337 defer func() {
338 if err != nil {
339 cs.finish(err)
340 }
341 if err == nil {
342 return
343 }
344 if err == io.EOF {
345 // Specialize the process for server streaming. SendMesg is only called
346 // once when creating the stream object. io.EOF needs to be skipped when
347 // the rpc is early finished (before the stream object is created.).
348 // TODO: It is probably better to move this into the generated code.
349 if !cs.desc.ClientStreams && cs.desc.ServerStreams {
350 err = nil
351 }
352 return
353 }
354 if _, ok := err.(transport.ConnectionError); !ok {
355 cs.closeTransportStream(err)
356 }
357 err = toRPCErr(err)
358 }()
359 var outPayload *stats.OutPayload
360 if cs.statsHandler != nil {
361 outPayload = &stats.OutPayload{
362 Client: true,
363 }
364 }
365 out, err := encode(cs.codec, m, cs.cp, cs.cbuf, outPayload)
366 defer func() {
367 if cs.cbuf != nil {
368 cs.cbuf.Reset()
369 }
370 }()
371 if err != nil {
372 return err
373 }
374 if cs.c.maxSendMessageSize == nil {
375 return Errorf(codes.Internal, "callInfo maxSendMessageSize field uninitialized(nil)")
376 }
377 if len(out) > *cs.c.maxSendMessageSize {
378 return Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(out), *cs.c.maxSendMessageSize)
379 }
380 err = cs.t.Write(cs.s, out, &transport.Options{Last: false})
381 if err == nil && outPayload != nil {
382 outPayload.SentTime = time.Now()
383 cs.statsHandler.HandleRPC(cs.statsCtx, outPayload)
384 }
385 return err
386}
387
388func (cs *clientStream) RecvMsg(m interface{}) (err error) {
389 var inPayload *stats.InPayload
390 if cs.statsHandler != nil {
391 inPayload = &stats.InPayload{
392 Client: true,
393 }
394 }
395 if cs.c.maxReceiveMessageSize == nil {
396 return Errorf(codes.Internal, "callInfo maxReceiveMessageSize field uninitialized(nil)")
397 }
398 err = recv(cs.p, cs.codec, cs.s, cs.dc, m, *cs.c.maxReceiveMessageSize, inPayload)
399 defer func() {
400 // err != nil indicates the termination of the stream.
401 if err != nil {
402 cs.finish(err)
403 }
404 }()
405 if err == nil {
406 if cs.tracing {
407 cs.mu.Lock()
408 if cs.trInfo.tr != nil {
409 cs.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true)
410 }
411 cs.mu.Unlock()
412 }
413 if inPayload != nil {
414 cs.statsHandler.HandleRPC(cs.statsCtx, inPayload)
415 }
416 if !cs.desc.ClientStreams || cs.desc.ServerStreams {
417 return
418 }
419 // Special handling for client streaming rpc.
420 // This recv expects EOF or errors, so we don't collect inPayload.
421 if cs.c.maxReceiveMessageSize == nil {
422 return Errorf(codes.Internal, "callInfo maxReceiveMessageSize field uninitialized(nil)")
423 }
424 err = recv(cs.p, cs.codec, cs.s, cs.dc, m, *cs.c.maxReceiveMessageSize, nil)
425 cs.closeTransportStream(err)
426 if err == nil {
427 return toRPCErr(errors.New("grpc: client streaming protocol violation: get <nil>, want <EOF>"))
428 }
429 if err == io.EOF {
430 if se := cs.s.Status().Err(); se != nil {
431 return se
432 }
433 cs.finish(err)
434 return nil
435 }
436 return toRPCErr(err)
437 }
438 if _, ok := err.(transport.ConnectionError); !ok {
439 cs.closeTransportStream(err)
440 }
441 if err == io.EOF {
442 if statusErr := cs.s.Status().Err(); statusErr != nil {
443 return statusErr
444 }
445 // Returns io.EOF to indicate the end of the stream.
446 return
447 }
448 return toRPCErr(err)
449}
450
451func (cs *clientStream) CloseSend() (err error) {
452 err = cs.t.Write(cs.s, nil, &transport.Options{Last: true})
453 defer func() {
454 if err != nil {
455 cs.finish(err)
456 }
457 }()
458 if err == nil || err == io.EOF {
459 return nil
460 }
461 if _, ok := err.(transport.ConnectionError); !ok {
462 cs.closeTransportStream(err)
463 }
464 err = toRPCErr(err)
465 return
466}
467
468func (cs *clientStream) closeTransportStream(err error) {
469 cs.mu.Lock()
470 if cs.closed {
471 cs.mu.Unlock()
472 return
473 }
474 cs.closed = true
475 cs.mu.Unlock()
476 cs.t.CloseStream(cs.s, err)
477}
478
479func (cs *clientStream) finish(err error) {
480 cs.mu.Lock()
481 defer cs.mu.Unlock()
482 if cs.finished {
483 return
484 }
485 cs.finished = true
486 defer func() {
487 if cs.cancel != nil {
488 cs.cancel()
489 }
490 }()
491 for _, o := range cs.opts {
492 o.after(&cs.c)
493 }
494 if cs.put != nil {
495 updateRPCInfoInContext(cs.s.Context(), rpcInfo{
496 bytesSent: cs.s.BytesSent(),
497 bytesReceived: cs.s.BytesReceived(),
498 })
499 cs.put()
500 cs.put = nil
501 }
502 if cs.statsHandler != nil {
503 end := &stats.End{
504 Client: true,
505 EndTime: time.Now(),
506 }
507 if err != io.EOF {
508 // end.Error is nil if the RPC finished successfully.
509 end.Error = toRPCErr(err)
510 }
511 cs.statsHandler.HandleRPC(cs.statsCtx, end)
512 }
513 if !cs.tracing {
514 return
515 }
516 if cs.trInfo.tr != nil {
517 if err == nil || err == io.EOF {
518 cs.trInfo.tr.LazyPrintf("RPC: [OK]")
519 } else {
520 cs.trInfo.tr.LazyPrintf("RPC: [%v]", err)
521 cs.trInfo.tr.SetError()
522 }
523 cs.trInfo.tr.Finish()
524 cs.trInfo.tr = nil
525 }
526}
527
528// ServerStream defines the interface a server stream has to satisfy.
529type ServerStream interface {
530 // SetHeader sets the header metadata. It may be called multiple times.
531 // When call multiple times, all the provided metadata will be merged.
532 // All the metadata will be sent out when one of the following happens:
533 // - ServerStream.SendHeader() is called;
534 // - The first response is sent out;
535 // - An RPC status is sent out (error or success).
536 SetHeader(metadata.MD) error
537 // SendHeader sends the header metadata.
538 // The provided md and headers set by SetHeader() will be sent.
539 // It fails if called multiple times.
540 SendHeader(metadata.MD) error
541 // SetTrailer sets the trailer metadata which will be sent with the RPC status.
542 // When called more than once, all the provided metadata will be merged.
543 SetTrailer(metadata.MD)
544 Stream
545}
546
547// serverStream implements a server side Stream.
548type serverStream struct {
549 t transport.ServerTransport
550 s *transport.Stream
551 p *parser
552 codec Codec
553 cp Compressor
554 dc Decompressor
555 cbuf *bytes.Buffer
556 maxReceiveMessageSize int
557 maxSendMessageSize int
558 trInfo *traceInfo
559
560 statsHandler stats.Handler
561
562 mu sync.Mutex // protects trInfo.tr after the service handler runs.
563}
564
565func (ss *serverStream) Context() context.Context {
566 return ss.s.Context()
567}
568
569func (ss *serverStream) SetHeader(md metadata.MD) error {
570 if md.Len() == 0 {
571 return nil
572 }
573 return ss.s.SetHeader(md)
574}
575
576func (ss *serverStream) SendHeader(md metadata.MD) error {
577 return ss.t.WriteHeader(ss.s, md)
578}
579
580func (ss *serverStream) SetTrailer(md metadata.MD) {
581 if md.Len() == 0 {
582 return
583 }
584 ss.s.SetTrailer(md)
585 return
586}
587
588func (ss *serverStream) SendMsg(m interface{}) (err error) {
589 defer func() {
590 if ss.trInfo != nil {
591 ss.mu.Lock()
592 if ss.trInfo.tr != nil {
593 if err == nil {
594 ss.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true)
595 } else {
596 ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
597 ss.trInfo.tr.SetError()
598 }
599 }
600 ss.mu.Unlock()
601 }
602 }()
603 var outPayload *stats.OutPayload
604 if ss.statsHandler != nil {
605 outPayload = &stats.OutPayload{}
606 }
607 out, err := encode(ss.codec, m, ss.cp, ss.cbuf, outPayload)
608 defer func() {
609 if ss.cbuf != nil {
610 ss.cbuf.Reset()
611 }
612 }()
613 if err != nil {
614 return err
615 }
616 if len(out) > ss.maxSendMessageSize {
617 return Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(out), ss.maxSendMessageSize)
618 }
619 if err := ss.t.Write(ss.s, out, &transport.Options{Last: false}); err != nil {
620 return toRPCErr(err)
621 }
622 if outPayload != nil {
623 outPayload.SentTime = time.Now()
624 ss.statsHandler.HandleRPC(ss.s.Context(), outPayload)
625 }
626 return nil
627}
628
629func (ss *serverStream) RecvMsg(m interface{}) (err error) {
630 defer func() {
631 if ss.trInfo != nil {
632 ss.mu.Lock()
633 if ss.trInfo.tr != nil {
634 if err == nil {
635 ss.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true)
636 } else if err != io.EOF {
637 ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
638 ss.trInfo.tr.SetError()
639 }
640 }
641 ss.mu.Unlock()
642 }
643 }()
644 var inPayload *stats.InPayload
645 if ss.statsHandler != nil {
646 inPayload = &stats.InPayload{}
647 }
648 if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, inPayload); err != nil {
649 if err == io.EOF {
650 return err
651 }
652 if err == io.ErrUnexpectedEOF {
653 err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error())
654 }
655 return toRPCErr(err)
656 }
657 if inPayload != nil {
658 ss.statsHandler.HandleRPC(ss.s.Context(), inPayload)
659 }
660 return nil
661}
diff --git a/vendor/google.golang.org/grpc/tap/tap.go b/vendor/google.golang.org/grpc/tap/tap.go
new file mode 100644
index 0000000..decb678
--- /dev/null
+++ b/vendor/google.golang.org/grpc/tap/tap.go
@@ -0,0 +1,39 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package tap defines the function handles which are executed on the transport
20// layer of gRPC-Go and related information. Everything here is EXPERIMENTAL.
21package tap
22
23import (
24 "golang.org/x/net/context"
25)
26
27// Info defines the relevant information needed by the handles.
28type Info struct {
29 // FullMethodName is the string of grpc method (in the format of
30 // /package.service/method).
31 FullMethodName string
32 // TODO: More to be added.
33}
34
35// ServerInHandle defines the function which runs when a new stream is created
36// on the server side. Note that it is executed in the per-connection I/O goroutine(s) instead
37// of per-RPC goroutine. Therefore, users should NOT have any blocking/time-consuming
38// work in this handle. Otherwise all the RPCs would slow down.
39type ServerInHandle func(ctx context.Context, info *Info) (context.Context, error)
diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go
new file mode 100644
index 0000000..b419c9e
--- /dev/null
+++ b/vendor/google.golang.org/grpc/trace.go
@@ -0,0 +1,104 @@
1/*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package grpc
20
21import (
22 "bytes"
23 "fmt"
24 "io"
25 "net"
26 "strings"
27 "time"
28
29 "golang.org/x/net/trace"
30)
31
32// EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package.
33// This should only be set before any RPCs are sent or received by this program.
34var EnableTracing = true
35
36// methodFamily returns the trace family for the given method.
37// It turns "/pkg.Service/GetFoo" into "pkg.Service".
38func methodFamily(m string) string {
39 m = strings.TrimPrefix(m, "/") // remove leading slash
40 if i := strings.Index(m, "/"); i >= 0 {
41 m = m[:i] // remove everything from second slash
42 }
43 if i := strings.LastIndex(m, "."); i >= 0 {
44 m = m[i+1:] // cut down to last dotted component
45 }
46 return m
47}
48
49// traceInfo contains tracing information for an RPC.
50type traceInfo struct {
51 tr trace.Trace
52 firstLine firstLine
53}
54
55// firstLine is the first line of an RPC trace.
56type firstLine struct {
57 client bool // whether this is a client (outgoing) RPC
58 remoteAddr net.Addr
59 deadline time.Duration // may be zero
60}
61
62func (f *firstLine) String() string {
63 var line bytes.Buffer
64 io.WriteString(&line, "RPC: ")
65 if f.client {
66 io.WriteString(&line, "to")
67 } else {
68 io.WriteString(&line, "from")
69 }
70 fmt.Fprintf(&line, " %v deadline:", f.remoteAddr)
71 if f.deadline != 0 {
72 fmt.Fprint(&line, f.deadline)
73 } else {
74 io.WriteString(&line, "none")
75 }
76 return line.String()
77}
78
79// payload represents an RPC request or response payload.
80type payload struct {
81 sent bool // whether this is an outgoing payload
82 msg interface{} // e.g. a proto.Message
83 // TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?
84}
85
86func (p payload) String() string {
87 if p.sent {
88 return fmt.Sprintf("sent: %v", p.msg)
89 }
90 return fmt.Sprintf("recv: %v", p.msg)
91}
92
93type fmtStringer struct {
94 format string
95 a []interface{}
96}
97
98func (f *fmtStringer) String() string {
99 return fmt.Sprintf(f.format, f.a...)
100}
101
102type stringer string
103
104func (s stringer) String() string { return string(s) }
diff --git a/vendor/google.golang.org/grpc/transport/bdp_estimator.go b/vendor/google.golang.org/grpc/transport/bdp_estimator.go
new file mode 100644
index 0000000..667edb8
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/bdp_estimator.go
@@ -0,0 +1,143 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package transport
20
21import (
22 "sync"
23 "time"
24)
25
26const (
27 // bdpLimit is the maximum value the flow control windows
28 // will be increased to.
29 bdpLimit = (1 << 20) * 4
30 // alpha is a constant factor used to keep a moving average
31 // of RTTs.
32 alpha = 0.9
33 // If the current bdp sample is greater than or equal to
34 // our beta * our estimated bdp and the current bandwidth
35 // sample is the maximum bandwidth observed so far, we
36 // increase our bbp estimate by a factor of gamma.
37 beta = 0.66
38 // To put our bdp to be smaller than or equal to twice the real BDP,
39 // we should multiply our current sample with 4/3, however to round things out
40 // we use 2 as the multiplication factor.
41 gamma = 2
42)
43
44var (
45 // Adding arbitrary data to ping so that its ack can be
46 // identified.
47 // Easter-egg: what does the ping message say?
48 bdpPing = &ping{data: [8]byte{2, 4, 16, 16, 9, 14, 7, 7}}
49)
50
51type bdpEstimator struct {
52 // sentAt is the time when the ping was sent.
53 sentAt time.Time
54
55 mu sync.Mutex
56 // bdp is the current bdp estimate.
57 bdp uint32
58 // sample is the number of bytes received in one measurement cycle.
59 sample uint32
60 // bwMax is the maximum bandwidth noted so far (bytes/sec).
61 bwMax float64
62 // bool to keep track of the begining of a new measurement cycle.
63 isSent bool
64 // Callback to update the window sizes.
65 updateFlowControl func(n uint32)
66 // sampleCount is the number of samples taken so far.
67 sampleCount uint64
68 // round trip time (seconds)
69 rtt float64
70}
71
72// timesnap registers the time bdp ping was sent out so that
73// network rtt can be calculated when its ack is recieved.
74// It is called (by controller) when the bdpPing is
75// being written on the wire.
76func (b *bdpEstimator) timesnap(d [8]byte) {
77 if bdpPing.data != d {
78 return
79 }
80 b.sentAt = time.Now()
81}
82
83// add adds bytes to the current sample for calculating bdp.
84// It returns true only if a ping must be sent. This can be used
85// by the caller (handleData) to make decision about batching
86// a window update with it.
87func (b *bdpEstimator) add(n uint32) bool {
88 b.mu.Lock()
89 defer b.mu.Unlock()
90 if b.bdp == bdpLimit {
91 return false
92 }
93 if !b.isSent {
94 b.isSent = true
95 b.sample = n
96 b.sentAt = time.Time{}
97 b.sampleCount++
98 return true
99 }
100 b.sample += n
101 return false
102}
103
104// calculate is called when an ack for a bdp ping is received.
105// Here we calculate the current bdp and bandwidth sample and
106// decide if the flow control windows should go up.
107func (b *bdpEstimator) calculate(d [8]byte) {
108 // Check if the ping acked for was the bdp ping.
109 if bdpPing.data != d {
110 return
111 }
112 b.mu.Lock()
113 rttSample := time.Since(b.sentAt).Seconds()
114 if b.sampleCount < 10 {
115 // Bootstrap rtt with an average of first 10 rtt samples.
116 b.rtt += (rttSample - b.rtt) / float64(b.sampleCount)
117 } else {
118 // Heed to the recent past more.
119 b.rtt += (rttSample - b.rtt) * float64(alpha)
120 }
121 b.isSent = false
122 // The number of bytes accumalated so far in the sample is smaller
123 // than or equal to 1.5 times the real BDP on a saturated connection.
124 bwCurrent := float64(b.sample) / (b.rtt * float64(1.5))
125 if bwCurrent > b.bwMax {
126 b.bwMax = bwCurrent
127 }
128 // If the current sample (which is smaller than or equal to the 1.5 times the real BDP) is
129 // greater than or equal to 2/3rd our perceived bdp AND this is the maximum bandwidth seen so far, we
130 // should update our perception of the network BDP.
131 if float64(b.sample) >= beta*float64(b.bdp) && bwCurrent == b.bwMax && b.bdp != bdpLimit {
132 sampleFloat := float64(b.sample)
133 b.bdp = uint32(gamma * sampleFloat)
134 if b.bdp > bdpLimit {
135 b.bdp = bdpLimit
136 }
137 bdp := b.bdp
138 b.mu.Unlock()
139 b.updateFlowControl(bdp)
140 return
141 }
142 b.mu.Unlock()
143}
diff --git a/vendor/google.golang.org/grpc/transport/control.go b/vendor/google.golang.org/grpc/transport/control.go
new file mode 100644
index 0000000..501eb03
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/control.go
@@ -0,0 +1,246 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package transport
20
21import (
22 "fmt"
23 "math"
24 "sync"
25 "time"
26
27 "golang.org/x/net/http2"
28)
29
30const (
31 // The default value of flow control window size in HTTP2 spec.
32 defaultWindowSize = 65535
33 // The initial window size for flow control.
34 initialWindowSize = defaultWindowSize // for an RPC
35 infinity = time.Duration(math.MaxInt64)
36 defaultClientKeepaliveTime = infinity
37 defaultClientKeepaliveTimeout = time.Duration(20 * time.Second)
38 defaultMaxStreamsClient = 100
39 defaultMaxConnectionIdle = infinity
40 defaultMaxConnectionAge = infinity
41 defaultMaxConnectionAgeGrace = infinity
42 defaultServerKeepaliveTime = time.Duration(2 * time.Hour)
43 defaultServerKeepaliveTimeout = time.Duration(20 * time.Second)
44 defaultKeepalivePolicyMinTime = time.Duration(5 * time.Minute)
45 // max window limit set by HTTP2 Specs.
46 maxWindowSize = math.MaxInt32
47)
48
49// The following defines various control items which could flow through
50// the control buffer of transport. They represent different aspects of
51// control tasks, e.g., flow control, settings, streaming resetting, etc.
52type windowUpdate struct {
53 streamID uint32
54 increment uint32
55 flush bool
56}
57
58func (*windowUpdate) item() {}
59
60type settings struct {
61 ack bool
62 ss []http2.Setting
63}
64
65func (*settings) item() {}
66
67type resetStream struct {
68 streamID uint32
69 code http2.ErrCode
70}
71
72func (*resetStream) item() {}
73
74type goAway struct {
75 code http2.ErrCode
76 debugData []byte
77 headsUp bool
78 closeConn bool
79}
80
81func (*goAway) item() {}
82
83type flushIO struct {
84}
85
86func (*flushIO) item() {}
87
88type ping struct {
89 ack bool
90 data [8]byte
91}
92
93func (*ping) item() {}
94
95// quotaPool is a pool which accumulates the quota and sends it to acquire()
96// when it is available.
97type quotaPool struct {
98 c chan int
99
100 mu sync.Mutex
101 quota int
102}
103
104// newQuotaPool creates a quotaPool which has quota q available to consume.
105func newQuotaPool(q int) *quotaPool {
106 qb := &quotaPool{
107 c: make(chan int, 1),
108 }
109 if q > 0 {
110 qb.c <- q
111 } else {
112 qb.quota = q
113 }
114 return qb
115}
116
117// add cancels the pending quota sent on acquired, incremented by v and sends
118// it back on acquire.
119func (qb *quotaPool) add(v int) {
120 qb.mu.Lock()
121 defer qb.mu.Unlock()
122 select {
123 case n := <-qb.c:
124 qb.quota += n
125 default:
126 }
127 qb.quota += v
128 if qb.quota <= 0 {
129 return
130 }
131 // After the pool has been created, this is the only place that sends on
132 // the channel. Since mu is held at this point and any quota that was sent
133 // on the channel has been retrieved, we know that this code will always
134 // place any positive quota value on the channel.
135 select {
136 case qb.c <- qb.quota:
137 qb.quota = 0
138 default:
139 }
140}
141
142// acquire returns the channel on which available quota amounts are sent.
143func (qb *quotaPool) acquire() <-chan int {
144 return qb.c
145}
146
147// inFlow deals with inbound flow control
148type inFlow struct {
149 mu sync.Mutex
150 // The inbound flow control limit for pending data.
151 limit uint32
152 // pendingData is the overall data which have been received but not been
153 // consumed by applications.
154 pendingData uint32
155 // The amount of data the application has consumed but grpc has not sent
156 // window update for them. Used to reduce window update frequency.
157 pendingUpdate uint32
158 // delta is the extra window update given by receiver when an application
159 // is reading data bigger in size than the inFlow limit.
160 delta uint32
161}
162
163// newLimit updates the inflow window to a new value n.
164// It assumes that n is always greater than the old limit.
165func (f *inFlow) newLimit(n uint32) uint32 {
166 f.mu.Lock()
167 defer f.mu.Unlock()
168 d := n - f.limit
169 f.limit = n
170 return d
171}
172
173func (f *inFlow) maybeAdjust(n uint32) uint32 {
174 if n > uint32(math.MaxInt32) {
175 n = uint32(math.MaxInt32)
176 }
177 f.mu.Lock()
178 defer f.mu.Unlock()
179 // estSenderQuota is the receiver's view of the maximum number of bytes the sender
180 // can send without a window update.
181 estSenderQuota := int32(f.limit - (f.pendingData + f.pendingUpdate))
182 // estUntransmittedData is the maximum number of bytes the sends might not have put
183 // on the wire yet. A value of 0 or less means that we have already received all or
184 // more bytes than the application is requesting to read.
185 estUntransmittedData := int32(n - f.pendingData) // Casting into int32 since it could be negative.
186 // This implies that unless we send a window update, the sender won't be able to send all the bytes
187 // for this message. Therefore we must send an update over the limit since there's an active read
188 // request from the application.
189 if estUntransmittedData > estSenderQuota {
190 // Sender's window shouldn't go more than 2^31 - 1 as speecified in the HTTP spec.
191 if f.limit+n > maxWindowSize {
192 f.delta = maxWindowSize - f.limit
193 } else {
194 // Send a window update for the whole message and not just the difference between
195 // estUntransmittedData and estSenderQuota. This will be helpful in case the message
196 // is padded; We will fallback on the current available window(at least a 1/4th of the limit).
197 f.delta = n
198 }
199 return f.delta
200 }
201 return 0
202}
203
204// onData is invoked when some data frame is received. It updates pendingData.
205func (f *inFlow) onData(n uint32) error {
206 f.mu.Lock()
207 defer f.mu.Unlock()
208 f.pendingData += n
209 if f.pendingData+f.pendingUpdate > f.limit+f.delta {
210 return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate, f.limit)
211 }
212 return nil
213}
214
215// onRead is invoked when the application reads the data. It returns the window size
216// to be sent to the peer.
217func (f *inFlow) onRead(n uint32) uint32 {
218 f.mu.Lock()
219 defer f.mu.Unlock()
220 if f.pendingData == 0 {
221 return 0
222 }
223 f.pendingData -= n
224 if n > f.delta {
225 n -= f.delta
226 f.delta = 0
227 } else {
228 f.delta -= n
229 n = 0
230 }
231 f.pendingUpdate += n
232 if f.pendingUpdate >= f.limit/4 {
233 wu := f.pendingUpdate
234 f.pendingUpdate = 0
235 return wu
236 }
237 return 0
238}
239
240func (f *inFlow) resetPendingUpdate() uint32 {
241 f.mu.Lock()
242 defer f.mu.Unlock()
243 n := f.pendingUpdate
244 f.pendingUpdate = 0
245 return n
246}
diff --git a/vendor/google.golang.org/grpc/transport/go16.go b/vendor/google.golang.org/grpc/transport/go16.go
new file mode 100644
index 0000000..7cffee1
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/go16.go
@@ -0,0 +1,45 @@
1// +build go1.6,!go1.7
2
3/*
4 *
5 * Copyright 2016 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package transport
22
23import (
24 "net"
25
26 "google.golang.org/grpc/codes"
27
28 "golang.org/x/net/context"
29)
30
31// dialContext connects to the address on the named network.
32func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
33 return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address)
34}
35
36// ContextErr converts the error from context package into a StreamError.
37func ContextErr(err error) StreamError {
38 switch err {
39 case context.DeadlineExceeded:
40 return streamErrorf(codes.DeadlineExceeded, "%v", err)
41 case context.Canceled:
42 return streamErrorf(codes.Canceled, "%v", err)
43 }
44 return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err)
45}
diff --git a/vendor/google.golang.org/grpc/transport/go17.go b/vendor/google.golang.org/grpc/transport/go17.go
new file mode 100644
index 0000000..2464e69
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/go17.go
@@ -0,0 +1,46 @@
1// +build go1.7
2
3/*
4 *
5 * Copyright 2016 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package transport
22
23import (
24 "context"
25 "net"
26
27 "google.golang.org/grpc/codes"
28
29 netctx "golang.org/x/net/context"
30)
31
32// dialContext connects to the address on the named network.
33func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
34 return (&net.Dialer{}).DialContext(ctx, network, address)
35}
36
37// ContextErr converts the error from context package into a StreamError.
38func ContextErr(err error) StreamError {
39 switch err {
40 case context.DeadlineExceeded, netctx.DeadlineExceeded:
41 return streamErrorf(codes.DeadlineExceeded, "%v", err)
42 case context.Canceled, netctx.Canceled:
43 return streamErrorf(codes.Canceled, "%v", err)
44 }
45 return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err)
46}
diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go
new file mode 100644
index 0000000..27372b5
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/handler_server.go
@@ -0,0 +1,393 @@
1/*
2 *
3 * Copyright 2016 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// This file is the implementation of a gRPC server using HTTP/2 which
20// uses the standard Go http2 Server implementation (via the
21// http.Handler interface), rather than speaking low-level HTTP/2
22// frames itself. It is the implementation of *grpc.Server.ServeHTTP.
23
24package transport
25
26import (
27 "errors"
28 "fmt"
29 "io"
30 "net"
31 "net/http"
32 "strings"
33 "sync"
34 "time"
35
36 "golang.org/x/net/context"
37 "golang.org/x/net/http2"
38 "google.golang.org/grpc/codes"
39 "google.golang.org/grpc/credentials"
40 "google.golang.org/grpc/metadata"
41 "google.golang.org/grpc/peer"
42 "google.golang.org/grpc/status"
43)
44
45// NewServerHandlerTransport returns a ServerTransport handling gRPC
46// from inside an http.Handler. It requires that the http Server
47// supports HTTP/2.
48func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTransport, error) {
49 if r.ProtoMajor != 2 {
50 return nil, errors.New("gRPC requires HTTP/2")
51 }
52 if r.Method != "POST" {
53 return nil, errors.New("invalid gRPC request method")
54 }
55 if !validContentType(r.Header.Get("Content-Type")) {
56 return nil, errors.New("invalid gRPC request content-type")
57 }
58 if _, ok := w.(http.Flusher); !ok {
59 return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher")
60 }
61 if _, ok := w.(http.CloseNotifier); !ok {
62 return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier")
63 }
64
65 st := &serverHandlerTransport{
66 rw: w,
67 req: r,
68 closedCh: make(chan struct{}),
69 writes: make(chan func()),
70 }
71
72 if v := r.Header.Get("grpc-timeout"); v != "" {
73 to, err := decodeTimeout(v)
74 if err != nil {
75 return nil, streamErrorf(codes.Internal, "malformed time-out: %v", err)
76 }
77 st.timeoutSet = true
78 st.timeout = to
79 }
80
81 var metakv []string
82 if r.Host != "" {
83 metakv = append(metakv, ":authority", r.Host)
84 }
85 for k, vv := range r.Header {
86 k = strings.ToLower(k)
87 if isReservedHeader(k) && !isWhitelistedPseudoHeader(k) {
88 continue
89 }
90 for _, v := range vv {
91 v, err := decodeMetadataHeader(k, v)
92 if err != nil {
93 return nil, streamErrorf(codes.InvalidArgument, "malformed binary metadata: %v", err)
94 }
95 metakv = append(metakv, k, v)
96 }
97 }
98 st.headerMD = metadata.Pairs(metakv...)
99
100 return st, nil
101}
102
103// serverHandlerTransport is an implementation of ServerTransport
104// which replies to exactly one gRPC request (exactly one HTTP request),
105// using the net/http.Handler interface. This http.Handler is guaranteed
106// at this point to be speaking over HTTP/2, so it's able to speak valid
107// gRPC.
108type serverHandlerTransport struct {
109 rw http.ResponseWriter
110 req *http.Request
111 timeoutSet bool
112 timeout time.Duration
113 didCommonHeaders bool
114
115 headerMD metadata.MD
116
117 closeOnce sync.Once
118 closedCh chan struct{} // closed on Close
119
120 // writes is a channel of code to run serialized in the
121 // ServeHTTP (HandleStreams) goroutine. The channel is closed
122 // when WriteStatus is called.
123 writes chan func()
124}
125
126func (ht *serverHandlerTransport) Close() error {
127 ht.closeOnce.Do(ht.closeCloseChanOnce)
128 return nil
129}
130
131func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) }
132
133func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) }
134
135// strAddr is a net.Addr backed by either a TCP "ip:port" string, or
136// the empty string if unknown.
137type strAddr string
138
139func (a strAddr) Network() string {
140 if a != "" {
141 // Per the documentation on net/http.Request.RemoteAddr, if this is
142 // set, it's set to the IP:port of the peer (hence, TCP):
143 // https://golang.org/pkg/net/http/#Request
144 //
145 // If we want to support Unix sockets later, we can
146 // add our own grpc-specific convention within the
147 // grpc codebase to set RemoteAddr to a different
148 // format, or probably better: we can attach it to the
149 // context and use that from serverHandlerTransport.RemoteAddr.
150 return "tcp"
151 }
152 return ""
153}
154
155func (a strAddr) String() string { return string(a) }
156
157// do runs fn in the ServeHTTP goroutine.
158func (ht *serverHandlerTransport) do(fn func()) error {
159 // Avoid a panic writing to closed channel. Imperfect but maybe good enough.
160 select {
161 case <-ht.closedCh:
162 return ErrConnClosing
163 default:
164 select {
165 case ht.writes <- fn:
166 return nil
167 case <-ht.closedCh:
168 return ErrConnClosing
169 }
170
171 }
172}
173
174func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) error {
175 err := ht.do(func() {
176 ht.writeCommonHeaders(s)
177
178 // And flush, in case no header or body has been sent yet.
179 // This forces a separation of headers and trailers if this is the
180 // first call (for example, in end2end tests's TestNoService).
181 ht.rw.(http.Flusher).Flush()
182
183 h := ht.rw.Header()
184 h.Set("Grpc-Status", fmt.Sprintf("%d", st.Code()))
185 if m := st.Message(); m != "" {
186 h.Set("Grpc-Message", encodeGrpcMessage(m))
187 }
188
189 // TODO: Support Grpc-Status-Details-Bin
190
191 if md := s.Trailer(); len(md) > 0 {
192 for k, vv := range md {
193 // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
194 if isReservedHeader(k) {
195 continue
196 }
197 for _, v := range vv {
198 // http2 ResponseWriter mechanism to send undeclared Trailers after
199 // the headers have possibly been written.
200 h.Add(http2.TrailerPrefix+k, encodeMetadataHeader(k, v))
201 }
202 }
203 }
204 })
205 close(ht.writes)
206 return err
207}
208
209// writeCommonHeaders sets common headers on the first write
210// call (Write, WriteHeader, or WriteStatus).
211func (ht *serverHandlerTransport) writeCommonHeaders(s *Stream) {
212 if ht.didCommonHeaders {
213 return
214 }
215 ht.didCommonHeaders = true
216
217 h := ht.rw.Header()
218 h["Date"] = nil // suppress Date to make tests happy; TODO: restore
219 h.Set("Content-Type", "application/grpc")
220
221 // Predeclare trailers we'll set later in WriteStatus (after the body).
222 // This is a SHOULD in the HTTP RFC, and the way you add (known)
223 // Trailers per the net/http.ResponseWriter contract.
224 // See https://golang.org/pkg/net/http/#ResponseWriter
225 // and https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
226 h.Add("Trailer", "Grpc-Status")
227 h.Add("Trailer", "Grpc-Message")
228 // TODO: Support Grpc-Status-Details-Bin
229
230 if s.sendCompress != "" {
231 h.Set("Grpc-Encoding", s.sendCompress)
232 }
233}
234
235func (ht *serverHandlerTransport) Write(s *Stream, data []byte, opts *Options) error {
236 return ht.do(func() {
237 ht.writeCommonHeaders(s)
238 ht.rw.Write(data)
239 if !opts.Delay {
240 ht.rw.(http.Flusher).Flush()
241 }
242 })
243}
244
245func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error {
246 return ht.do(func() {
247 ht.writeCommonHeaders(s)
248 h := ht.rw.Header()
249 for k, vv := range md {
250 // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
251 if isReservedHeader(k) {
252 continue
253 }
254 for _, v := range vv {
255 v = encodeMetadataHeader(k, v)
256 h.Add(k, v)
257 }
258 }
259 ht.rw.WriteHeader(200)
260 ht.rw.(http.Flusher).Flush()
261 })
262}
263
264func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) {
265 // With this transport type there will be exactly 1 stream: this HTTP request.
266
267 var ctx context.Context
268 var cancel context.CancelFunc
269 if ht.timeoutSet {
270 ctx, cancel = context.WithTimeout(context.Background(), ht.timeout)
271 } else {
272 ctx, cancel = context.WithCancel(context.Background())
273 }
274
275 // requestOver is closed when either the request's context is done
276 // or the status has been written via WriteStatus.
277 requestOver := make(chan struct{})
278
279 // clientGone receives a single value if peer is gone, either
280 // because the underlying connection is dead or because the
281 // peer sends an http2 RST_STREAM.
282 clientGone := ht.rw.(http.CloseNotifier).CloseNotify()
283 go func() {
284 select {
285 case <-requestOver:
286 return
287 case <-ht.closedCh:
288 case <-clientGone:
289 }
290 cancel()
291 }()
292
293 req := ht.req
294
295 s := &Stream{
296 id: 0, // irrelevant
297 requestRead: func(int) {},
298 cancel: cancel,
299 buf: newRecvBuffer(),
300 st: ht,
301 method: req.URL.Path,
302 recvCompress: req.Header.Get("grpc-encoding"),
303 }
304 pr := &peer.Peer{
305 Addr: ht.RemoteAddr(),
306 }
307 if req.TLS != nil {
308 pr.AuthInfo = credentials.TLSInfo{State: *req.TLS}
309 }
310 ctx = metadata.NewIncomingContext(ctx, ht.headerMD)
311 ctx = peer.NewContext(ctx, pr)
312 s.ctx = newContextWithStream(ctx, s)
313 s.trReader = &transportReader{
314 reader: &recvBufferReader{ctx: s.ctx, recv: s.buf},
315 windowHandler: func(int) {},
316 }
317
318 // readerDone is closed when the Body.Read-ing goroutine exits.
319 readerDone := make(chan struct{})
320 go func() {
321 defer close(readerDone)
322
323 // TODO: minimize garbage, optimize recvBuffer code/ownership
324 const readSize = 8196
325 for buf := make([]byte, readSize); ; {
326 n, err := req.Body.Read(buf)
327 if n > 0 {
328 s.buf.put(recvMsg{data: buf[:n:n]})
329 buf = buf[n:]
330 }
331 if err != nil {
332 s.buf.put(recvMsg{err: mapRecvMsgError(err)})
333 return
334 }
335 if len(buf) == 0 {
336 buf = make([]byte, readSize)
337 }
338 }
339 }()
340
341 // startStream is provided by the *grpc.Server's serveStreams.
342 // It starts a goroutine serving s and exits immediately.
343 // The goroutine that is started is the one that then calls
344 // into ht, calling WriteHeader, Write, WriteStatus, Close, etc.
345 startStream(s)
346
347 ht.runStream()
348 close(requestOver)
349
350 // Wait for reading goroutine to finish.
351 req.Body.Close()
352 <-readerDone
353}
354
355func (ht *serverHandlerTransport) runStream() {
356 for {
357 select {
358 case fn, ok := <-ht.writes:
359 if !ok {
360 return
361 }
362 fn()
363 case <-ht.closedCh:
364 return
365 }
366 }
367}
368
369func (ht *serverHandlerTransport) Drain() {
370 panic("Drain() is not implemented")
371}
372
373// mapRecvMsgError returns the non-nil err into the appropriate
374// error value as expected by callers of *grpc.parser.recvMsg.
375// In particular, in can only be:
376// * io.EOF
377// * io.ErrUnexpectedEOF
378// * of type transport.ConnectionError
379// * of type transport.StreamError
380func mapRecvMsgError(err error) error {
381 if err == io.EOF || err == io.ErrUnexpectedEOF {
382 return err
383 }
384 if se, ok := err.(http2.StreamError); ok {
385 if code, ok := http2ErrConvTab[se.Code]; ok {
386 return StreamError{
387 Code: code,
388 Desc: se.Error(),
389 }
390 }
391 }
392 return connectionErrorf(true, err, err.Error())
393}
diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go
new file mode 100644
index 0000000..516ea06
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/http2_client.go
@@ -0,0 +1,1369 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package transport
20
21import (
22 "bytes"
23 "io"
24 "math"
25 "net"
26 "strings"
27 "sync"
28 "sync/atomic"
29 "time"
30
31 "golang.org/x/net/context"
32 "golang.org/x/net/http2"
33 "golang.org/x/net/http2/hpack"
34 "google.golang.org/grpc/codes"
35 "google.golang.org/grpc/credentials"
36 "google.golang.org/grpc/keepalive"
37 "google.golang.org/grpc/metadata"
38 "google.golang.org/grpc/peer"
39 "google.golang.org/grpc/stats"
40 "google.golang.org/grpc/status"
41)
42
43// http2Client implements the ClientTransport interface with HTTP2.
44type http2Client struct {
45 ctx context.Context
46 target string // server name/addr
47 userAgent string
48 md interface{}
49 conn net.Conn // underlying communication channel
50 remoteAddr net.Addr
51 localAddr net.Addr
52 authInfo credentials.AuthInfo // auth info about the connection
53 nextID uint32 // the next stream ID to be used
54
55 // writableChan synchronizes write access to the transport.
56 // A writer acquires the write lock by sending a value on writableChan
57 // and releases it by receiving from writableChan.
58 writableChan chan int
59 // shutdownChan is closed when Close is called.
60 // Blocking operations should select on shutdownChan to avoid
61 // blocking forever after Close.
62 // TODO(zhaoq): Maybe have a channel context?
63 shutdownChan chan struct{}
64 // errorChan is closed to notify the I/O error to the caller.
65 errorChan chan struct{}
66 // goAway is closed to notify the upper layer (i.e., addrConn.transportMonitor)
67 // that the server sent GoAway on this transport.
68 goAway chan struct{}
69 // awakenKeepalive is used to wake up keepalive when after it has gone dormant.
70 awakenKeepalive chan struct{}
71
72 framer *framer
73 hBuf *bytes.Buffer // the buffer for HPACK encoding
74 hEnc *hpack.Encoder // HPACK encoder
75
76 // controlBuf delivers all the control related tasks (e.g., window
77 // updates, reset streams, and various settings) to the controller.
78 controlBuf *controlBuffer
79 fc *inFlow
80 // sendQuotaPool provides flow control to outbound message.
81 sendQuotaPool *quotaPool
82 // streamsQuota limits the max number of concurrent streams.
83 streamsQuota *quotaPool
84
85 // The scheme used: https if TLS is on, http otherwise.
86 scheme string
87
88 isSecure bool
89
90 creds []credentials.PerRPCCredentials
91
92 // Boolean to keep track of reading activity on transport.
93 // 1 is true and 0 is false.
94 activity uint32 // Accessed atomically.
95 kp keepalive.ClientParameters
96
97 statsHandler stats.Handler
98
99 initialWindowSize int32
100
101 bdpEst *bdpEstimator
102 outQuotaVersion uint32
103
104 mu sync.Mutex // guard the following variables
105 state transportState // the state of underlying connection
106 activeStreams map[uint32]*Stream
107 // The max number of concurrent streams
108 maxStreams int
109 // the per-stream outbound flow control window size set by the peer.
110 streamSendQuota uint32
111 // prevGoAway ID records the Last-Stream-ID in the previous GOAway frame.
112 prevGoAwayID uint32
113 // goAwayReason records the http2.ErrCode and debug data received with the
114 // GoAway frame.
115 goAwayReason GoAwayReason
116}
117
118func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr string) (net.Conn, error) {
119 if fn != nil {
120 return fn(ctx, addr)
121 }
122 return dialContext(ctx, "tcp", addr)
123}
124
125func isTemporary(err error) bool {
126 switch err {
127 case io.EOF:
128 // Connection closures may be resolved upon retry, and are thus
129 // treated as temporary.
130 return true
131 case context.DeadlineExceeded:
132 // In Go 1.7, context.DeadlineExceeded implements Timeout(), and this
133 // special case is not needed. Until then, we need to keep this
134 // clause.
135 return true
136 }
137
138 switch err := err.(type) {
139 case interface {
140 Temporary() bool
141 }:
142 return err.Temporary()
143 case interface {
144 Timeout() bool
145 }:
146 // Timeouts may be resolved upon retry, and are thus treated as
147 // temporary.
148 return err.Timeout()
149 }
150 return false
151}
152
153// newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
154// and starts to receive messages on it. Non-nil error returns if construction
155// fails.
156func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (_ ClientTransport, err error) {
157 scheme := "http"
158 conn, err := dial(ctx, opts.Dialer, addr.Addr)
159 if err != nil {
160 if opts.FailOnNonTempDialError {
161 return nil, connectionErrorf(isTemporary(err), err, "transport: error while dialing: %v", err)
162 }
163 return nil, connectionErrorf(true, err, "transport: Error while dialing %v", err)
164 }
165 // Any further errors will close the underlying connection
166 defer func(conn net.Conn) {
167 if err != nil {
168 conn.Close()
169 }
170 }(conn)
171 var (
172 isSecure bool
173 authInfo credentials.AuthInfo
174 )
175 if creds := opts.TransportCredentials; creds != nil {
176 scheme = "https"
177 conn, authInfo, err = creds.ClientHandshake(ctx, addr.Addr, conn)
178 if err != nil {
179 // Credentials handshake errors are typically considered permanent
180 // to avoid retrying on e.g. bad certificates.
181 temp := isTemporary(err)
182 return nil, connectionErrorf(temp, err, "transport: authentication handshake failed: %v", err)
183 }
184 isSecure = true
185 }
186 kp := opts.KeepaliveParams
187 // Validate keepalive parameters.
188 if kp.Time == 0 {
189 kp.Time = defaultClientKeepaliveTime
190 }
191 if kp.Timeout == 0 {
192 kp.Timeout = defaultClientKeepaliveTimeout
193 }
194 dynamicWindow := true
195 icwz := int32(initialWindowSize)
196 if opts.InitialConnWindowSize >= defaultWindowSize {
197 icwz = opts.InitialConnWindowSize
198 dynamicWindow = false
199 }
200 var buf bytes.Buffer
201 t := &http2Client{
202 ctx: ctx,
203 target: addr.Addr,
204 userAgent: opts.UserAgent,
205 md: addr.Metadata,
206 conn: conn,
207 remoteAddr: conn.RemoteAddr(),
208 localAddr: conn.LocalAddr(),
209 authInfo: authInfo,
210 // The client initiated stream id is odd starting from 1.
211 nextID: 1,
212 writableChan: make(chan int, 1),
213 shutdownChan: make(chan struct{}),
214 errorChan: make(chan struct{}),
215 goAway: make(chan struct{}),
216 awakenKeepalive: make(chan struct{}, 1),
217 framer: newFramer(conn),
218 hBuf: &buf,
219 hEnc: hpack.NewEncoder(&buf),
220 controlBuf: newControlBuffer(),
221 fc: &inFlow{limit: uint32(icwz)},
222 sendQuotaPool: newQuotaPool(defaultWindowSize),
223 scheme: scheme,
224 state: reachable,
225 activeStreams: make(map[uint32]*Stream),
226 isSecure: isSecure,
227 creds: opts.PerRPCCredentials,
228 maxStreams: defaultMaxStreamsClient,
229 streamsQuota: newQuotaPool(defaultMaxStreamsClient),
230 streamSendQuota: defaultWindowSize,
231 kp: kp,
232 statsHandler: opts.StatsHandler,
233 initialWindowSize: initialWindowSize,
234 }
235 if opts.InitialWindowSize >= defaultWindowSize {
236 t.initialWindowSize = opts.InitialWindowSize
237 dynamicWindow = false
238 }
239 if dynamicWindow {
240 t.bdpEst = &bdpEstimator{
241 bdp: initialWindowSize,
242 updateFlowControl: t.updateFlowControl,
243 }
244 }
245 // Make sure awakenKeepalive can't be written upon.
246 // keepalive routine will make it writable, if need be.
247 t.awakenKeepalive <- struct{}{}
248 if t.statsHandler != nil {
249 t.ctx = t.statsHandler.TagConn(t.ctx, &stats.ConnTagInfo{
250 RemoteAddr: t.remoteAddr,
251 LocalAddr: t.localAddr,
252 })
253 connBegin := &stats.ConnBegin{
254 Client: true,
255 }
256 t.statsHandler.HandleConn(t.ctx, connBegin)
257 }
258 // Start the reader goroutine for incoming message. Each transport has
259 // a dedicated goroutine which reads HTTP2 frame from network. Then it
260 // dispatches the frame to the corresponding stream entity.
261 go t.reader()
262 // Send connection preface to server.
263 n, err := t.conn.Write(clientPreface)
264 if err != nil {
265 t.Close()
266 return nil, connectionErrorf(true, err, "transport: failed to write client preface: %v", err)
267 }
268 if n != len(clientPreface) {
269 t.Close()
270 return nil, connectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
271 }
272 if t.initialWindowSize != defaultWindowSize {
273 err = t.framer.writeSettings(true, http2.Setting{
274 ID: http2.SettingInitialWindowSize,
275 Val: uint32(t.initialWindowSize),
276 })
277 } else {
278 err = t.framer.writeSettings(true)
279 }
280 if err != nil {
281 t.Close()
282 return nil, connectionErrorf(true, err, "transport: failed to write initial settings frame: %v", err)
283 }
284 // Adjust the connection flow control window if needed.
285 if delta := uint32(icwz - defaultWindowSize); delta > 0 {
286 if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil {
287 t.Close()
288 return nil, connectionErrorf(true, err, "transport: failed to write window update: %v", err)
289 }
290 }
291 go t.controller()
292 if t.kp.Time != infinity {
293 go t.keepalive()
294 }
295 t.writableChan <- 0
296 return t, nil
297}
298
299func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
300 // TODO(zhaoq): Handle uint32 overflow of Stream.id.
301 s := &Stream{
302 id: t.nextID,
303 done: make(chan struct{}),
304 goAway: make(chan struct{}),
305 method: callHdr.Method,
306 sendCompress: callHdr.SendCompress,
307 buf: newRecvBuffer(),
308 fc: &inFlow{limit: uint32(t.initialWindowSize)},
309 sendQuotaPool: newQuotaPool(int(t.streamSendQuota)),
310 headerChan: make(chan struct{}),
311 }
312 t.nextID += 2
313 s.requestRead = func(n int) {
314 t.adjustWindow(s, uint32(n))
315 }
316 // The client side stream context should have exactly the same life cycle with the user provided context.
317 // That means, s.ctx should be read-only. And s.ctx is done iff ctx is done.
318 // So we use the original context here instead of creating a copy.
319 s.ctx = ctx
320 s.trReader = &transportReader{
321 reader: &recvBufferReader{
322 ctx: s.ctx,
323 goAway: s.goAway,
324 recv: s.buf,
325 },
326 windowHandler: func(n int) {
327 t.updateWindow(s, uint32(n))
328 },
329 }
330
331 return s
332}
333
334// NewStream creates a stream and registers it into the transport as "active"
335// streams.
336func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) {
337 pr := &peer.Peer{
338 Addr: t.remoteAddr,
339 }
340 // Attach Auth info if there is any.
341 if t.authInfo != nil {
342 pr.AuthInfo = t.authInfo
343 }
344 ctx = peer.NewContext(ctx, pr)
345 var (
346 authData = make(map[string]string)
347 audience string
348 )
349 // Create an audience string only if needed.
350 if len(t.creds) > 0 || callHdr.Creds != nil {
351 // Construct URI required to get auth request metadata.
352 var port string
353 if pos := strings.LastIndex(t.target, ":"); pos != -1 {
354 // Omit port if it is the default one.
355 if t.target[pos+1:] != "443" {
356 port = ":" + t.target[pos+1:]
357 }
358 }
359 pos := strings.LastIndex(callHdr.Method, "/")
360 if pos == -1 {
361 pos = len(callHdr.Method)
362 }
363 audience = "https://" + callHdr.Host + port + callHdr.Method[:pos]
364 }
365 for _, c := range t.creds {
366 data, err := c.GetRequestMetadata(ctx, audience)
367 if err != nil {
368 return nil, streamErrorf(codes.Internal, "transport: %v", err)
369 }
370 for k, v := range data {
371 // Capital header names are illegal in HTTP/2.
372 k = strings.ToLower(k)
373 authData[k] = v
374 }
375 }
376 callAuthData := make(map[string]string)
377 // Check if credentials.PerRPCCredentials were provided via call options.
378 // Note: if these credentials are provided both via dial options and call
379 // options, then both sets of credentials will be applied.
380 if callCreds := callHdr.Creds; callCreds != nil {
381 if !t.isSecure && callCreds.RequireTransportSecurity() {
382 return nil, streamErrorf(codes.Unauthenticated, "transport: cannot send secure credentials on an insecure conneciton")
383 }
384 data, err := callCreds.GetRequestMetadata(ctx, audience)
385 if err != nil {
386 return nil, streamErrorf(codes.Internal, "transport: %v", err)
387 }
388 for k, v := range data {
389 // Capital header names are illegal in HTTP/2
390 k = strings.ToLower(k)
391 callAuthData[k] = v
392 }
393 }
394 t.mu.Lock()
395 if t.activeStreams == nil {
396 t.mu.Unlock()
397 return nil, ErrConnClosing
398 }
399 if t.state == draining {
400 t.mu.Unlock()
401 return nil, ErrStreamDrain
402 }
403 if t.state != reachable {
404 t.mu.Unlock()
405 return nil, ErrConnClosing
406 }
407 t.mu.Unlock()
408 sq, err := wait(ctx, nil, nil, t.shutdownChan, t.streamsQuota.acquire())
409 if err != nil {
410 return nil, err
411 }
412 // Returns the quota balance back.
413 if sq > 1 {
414 t.streamsQuota.add(sq - 1)
415 }
416 if _, err := wait(ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
417 // Return the quota back now because there is no stream returned to the caller.
418 if _, ok := err.(StreamError); ok {
419 t.streamsQuota.add(1)
420 }
421 return nil, err
422 }
423 t.mu.Lock()
424 if t.state == draining {
425 t.mu.Unlock()
426 t.streamsQuota.add(1)
427 // Need to make t writable again so that the rpc in flight can still proceed.
428 t.writableChan <- 0
429 return nil, ErrStreamDrain
430 }
431 if t.state != reachable {
432 t.mu.Unlock()
433 return nil, ErrConnClosing
434 }
435 s := t.newStream(ctx, callHdr)
436 t.activeStreams[s.id] = s
437 // If the number of active streams change from 0 to 1, then check if keepalive
438 // has gone dormant. If so, wake it up.
439 if len(t.activeStreams) == 1 {
440 select {
441 case t.awakenKeepalive <- struct{}{}:
442 t.framer.writePing(false, false, [8]byte{})
443 default:
444 }
445 }
446
447 t.mu.Unlock()
448
449 // HPACK encodes various headers. Note that once WriteField(...) is
450 // called, the corresponding headers/continuation frame has to be sent
451 // because hpack.Encoder is stateful.
452 t.hBuf.Reset()
453 t.hEnc.WriteField(hpack.HeaderField{Name: ":method", Value: "POST"})
454 t.hEnc.WriteField(hpack.HeaderField{Name: ":scheme", Value: t.scheme})
455 t.hEnc.WriteField(hpack.HeaderField{Name: ":path", Value: callHdr.Method})
456 t.hEnc.WriteField(hpack.HeaderField{Name: ":authority", Value: callHdr.Host})
457 t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
458 t.hEnc.WriteField(hpack.HeaderField{Name: "user-agent", Value: t.userAgent})
459 t.hEnc.WriteField(hpack.HeaderField{Name: "te", Value: "trailers"})
460
461 if callHdr.SendCompress != "" {
462 t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress})
463 }
464 if dl, ok := ctx.Deadline(); ok {
465 // Send out timeout regardless its value. The server can detect timeout context by itself.
466 timeout := dl.Sub(time.Now())
467 t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)})
468 }
469
470 for k, v := range authData {
471 t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
472 }
473 for k, v := range callAuthData {
474 t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
475 }
476 var (
477 endHeaders bool
478 )
479 if md, ok := metadata.FromOutgoingContext(ctx); ok {
480 for k, vv := range md {
481 // HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
482 if isReservedHeader(k) {
483 continue
484 }
485 for _, v := range vv {
486 t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
487 }
488 }
489 }
490 if md, ok := t.md.(*metadata.MD); ok {
491 for k, vv := range *md {
492 if isReservedHeader(k) {
493 continue
494 }
495 for _, v := range vv {
496 t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
497 }
498 }
499 }
500 first := true
501 bufLen := t.hBuf.Len()
502 // Sends the headers in a single batch even when they span multiple frames.
503 for !endHeaders {
504 size := t.hBuf.Len()
505 if size > http2MaxFrameLen {
506 size = http2MaxFrameLen
507 } else {
508 endHeaders = true
509 }
510 var flush bool
511 if callHdr.Flush && endHeaders {
512 flush = true
513 }
514 if first {
515 // Sends a HeadersFrame to server to start a new stream.
516 p := http2.HeadersFrameParam{
517 StreamID: s.id,
518 BlockFragment: t.hBuf.Next(size),
519 EndStream: false,
520 EndHeaders: endHeaders,
521 }
522 // Do a force flush for the buffered frames iff it is the last headers frame
523 // and there is header metadata to be sent. Otherwise, there is flushing until
524 // the corresponding data frame is written.
525 err = t.framer.writeHeaders(flush, p)
526 first = false
527 } else {
528 // Sends Continuation frames for the leftover headers.
529 err = t.framer.writeContinuation(flush, s.id, endHeaders, t.hBuf.Next(size))
530 }
531 if err != nil {
532 t.notifyError(err)
533 return nil, connectionErrorf(true, err, "transport: %v", err)
534 }
535 }
536 s.mu.Lock()
537 s.bytesSent = true
538 s.mu.Unlock()
539
540 if t.statsHandler != nil {
541 outHeader := &stats.OutHeader{
542 Client: true,
543 WireLength: bufLen,
544 FullMethod: callHdr.Method,
545 RemoteAddr: t.remoteAddr,
546 LocalAddr: t.localAddr,
547 Compression: callHdr.SendCompress,
548 }
549 t.statsHandler.HandleRPC(s.ctx, outHeader)
550 }
551 t.writableChan <- 0
552 return s, nil
553}
554
555// CloseStream clears the footprint of a stream when the stream is not needed any more.
556// This must not be executed in reader's goroutine.
557func (t *http2Client) CloseStream(s *Stream, err error) {
558 t.mu.Lock()
559 if t.activeStreams == nil {
560 t.mu.Unlock()
561 return
562 }
563 if err != nil {
564 // notify in-flight streams, before the deletion
565 s.write(recvMsg{err: err})
566 }
567 delete(t.activeStreams, s.id)
568 if t.state == draining && len(t.activeStreams) == 0 {
569 // The transport is draining and s is the last live stream on t.
570 t.mu.Unlock()
571 t.Close()
572 return
573 }
574 t.mu.Unlock()
575 // rstStream is true in case the stream is being closed at the client-side
576 // and the server needs to be intimated about it by sending a RST_STREAM
577 // frame.
578 // To make sure this frame is written to the wire before the headers of the
579 // next stream waiting for streamsQuota, we add to streamsQuota pool only
580 // after having acquired the writableChan to send RST_STREAM out (look at
581 // the controller() routine).
582 var rstStream bool
583 var rstError http2.ErrCode
584 defer func() {
585 // In case, the client doesn't have to send RST_STREAM to server
586 // we can safely add back to streamsQuota pool now.
587 if !rstStream {
588 t.streamsQuota.add(1)
589 return
590 }
591 t.controlBuf.put(&resetStream{s.id, rstError})
592 }()
593 s.mu.Lock()
594 rstStream = s.rstStream
595 rstError = s.rstError
596 if s.state == streamDone {
597 s.mu.Unlock()
598 return
599 }
600 if !s.headerDone {
601 close(s.headerChan)
602 s.headerDone = true
603 }
604 s.state = streamDone
605 s.mu.Unlock()
606 if _, ok := err.(StreamError); ok {
607 rstStream = true
608 rstError = http2.ErrCodeCancel
609 }
610}
611
612// Close kicks off the shutdown process of the transport. This should be called
613// only once on a transport. Once it is called, the transport should not be
614// accessed any more.
615func (t *http2Client) Close() (err error) {
616 t.mu.Lock()
617 if t.state == closing {
618 t.mu.Unlock()
619 return
620 }
621 if t.state == reachable || t.state == draining {
622 close(t.errorChan)
623 }
624 t.state = closing
625 t.mu.Unlock()
626 close(t.shutdownChan)
627 err = t.conn.Close()
628 t.mu.Lock()
629 streams := t.activeStreams
630 t.activeStreams = nil
631 t.mu.Unlock()
632 // Notify all active streams.
633 for _, s := range streams {
634 s.mu.Lock()
635 if !s.headerDone {
636 close(s.headerChan)
637 s.headerDone = true
638 }
639 s.mu.Unlock()
640 s.write(recvMsg{err: ErrConnClosing})
641 }
642 if t.statsHandler != nil {
643 connEnd := &stats.ConnEnd{
644 Client: true,
645 }
646 t.statsHandler.HandleConn(t.ctx, connEnd)
647 }
648 return
649}
650
651func (t *http2Client) GracefulClose() error {
652 t.mu.Lock()
653 switch t.state {
654 case unreachable:
655 // The server may close the connection concurrently. t is not available for
656 // any streams. Close it now.
657 t.mu.Unlock()
658 t.Close()
659 return nil
660 case closing:
661 t.mu.Unlock()
662 return nil
663 }
664 if t.state == draining {
665 t.mu.Unlock()
666 return nil
667 }
668 t.state = draining
669 active := len(t.activeStreams)
670 t.mu.Unlock()
671 if active == 0 {
672 return t.Close()
673 }
674 return nil
675}
676
677// Write formats the data into HTTP2 data frame(s) and sends it out. The caller
678// should proceed only if Write returns nil.
679// TODO(zhaoq): opts.Delay is ignored in this implementation. Support it later
680// if it improves the performance.
681func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
682 r := bytes.NewBuffer(data)
683 var (
684 p []byte
685 oqv uint32
686 )
687 for {
688 oqv = atomic.LoadUint32(&t.outQuotaVersion)
689 if r.Len() > 0 || p != nil {
690 size := http2MaxFrameLen
691 // Wait until the stream has some quota to send the data.
692 sq, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, s.sendQuotaPool.acquire())
693 if err != nil {
694 return err
695 }
696 // Wait until the transport has some quota to send the data.
697 tq, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, t.sendQuotaPool.acquire())
698 if err != nil {
699 return err
700 }
701 if sq < size {
702 size = sq
703 }
704 if tq < size {
705 size = tq
706 }
707 if p == nil {
708 p = r.Next(size)
709 }
710 ps := len(p)
711 if ps < sq {
712 // Overbooked stream quota. Return it back.
713 s.sendQuotaPool.add(sq - ps)
714 }
715 if ps < tq {
716 // Overbooked transport quota. Return it back.
717 t.sendQuotaPool.add(tq - ps)
718 }
719 }
720 var (
721 endStream bool
722 forceFlush bool
723 )
724 if opts.Last && r.Len() == 0 {
725 endStream = true
726 }
727 // Indicate there is a writer who is about to write a data frame.
728 t.framer.adjustNumWriters(1)
729 // Got some quota. Try to acquire writing privilege on the transport.
730 if _, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, t.writableChan); err != nil {
731 if _, ok := err.(StreamError); ok || err == io.EOF {
732 // Return the connection quota back.
733 t.sendQuotaPool.add(len(p))
734 }
735 if t.framer.adjustNumWriters(-1) == 0 {
736 // This writer is the last one in this batch and has the
737 // responsibility to flush the buffered frames. It queues
738 // a flush request to controlBuf instead of flushing directly
739 // in order to avoid the race with other writing or flushing.
740 t.controlBuf.put(&flushIO{})
741 }
742 return err
743 }
744 select {
745 case <-s.ctx.Done():
746 t.sendQuotaPool.add(len(p))
747 if t.framer.adjustNumWriters(-1) == 0 {
748 t.controlBuf.put(&flushIO{})
749 }
750 t.writableChan <- 0
751 return ContextErr(s.ctx.Err())
752 default:
753 }
754 if oqv != atomic.LoadUint32(&t.outQuotaVersion) {
755 // InitialWindowSize settings frame must have been received after we
756 // acquired send quota but before we got the writable channel.
757 // We must forsake this write.
758 t.sendQuotaPool.add(len(p))
759 s.sendQuotaPool.add(len(p))
760 if t.framer.adjustNumWriters(-1) == 0 {
761 t.controlBuf.put(&flushIO{})
762 }
763 t.writableChan <- 0
764 continue
765 }
766 if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 {
767 // Do a force flush iff this is last frame for the entire gRPC message
768 // and the caller is the only writer at this moment.
769 forceFlush = true
770 }
771 // If WriteData fails, all the pending streams will be handled
772 // by http2Client.Close(). No explicit CloseStream() needs to be
773 // invoked.
774 if err := t.framer.writeData(forceFlush, s.id, endStream, p); err != nil {
775 t.notifyError(err)
776 return connectionErrorf(true, err, "transport: %v", err)
777 }
778 p = nil
779 if t.framer.adjustNumWriters(-1) == 0 {
780 t.framer.flushWrite()
781 }
782 t.writableChan <- 0
783 if r.Len() == 0 {
784 break
785 }
786 }
787 if !opts.Last {
788 return nil
789 }
790 s.mu.Lock()
791 if s.state != streamDone {
792 s.state = streamWriteDone
793 }
794 s.mu.Unlock()
795 return nil
796}
797
798func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) {
799 t.mu.Lock()
800 defer t.mu.Unlock()
801 s, ok := t.activeStreams[f.Header().StreamID]
802 return s, ok
803}
804
805// adjustWindow sends out extra window update over the initial window size
806// of stream if the application is requesting data larger in size than
807// the window.
808func (t *http2Client) adjustWindow(s *Stream, n uint32) {
809 s.mu.Lock()
810 defer s.mu.Unlock()
811 if s.state == streamDone {
812 return
813 }
814 if w := s.fc.maybeAdjust(n); w > 0 {
815 // Piggyback conneciton's window update along.
816 if cw := t.fc.resetPendingUpdate(); cw > 0 {
817 t.controlBuf.put(&windowUpdate{0, cw, false})
818 }
819 t.controlBuf.put(&windowUpdate{s.id, w, true})
820 }
821}
822
823// updateWindow adjusts the inbound quota for the stream and the transport.
824// Window updates will deliver to the controller for sending when
825// the cumulative quota exceeds the corresponding threshold.
826func (t *http2Client) updateWindow(s *Stream, n uint32) {
827 s.mu.Lock()
828 defer s.mu.Unlock()
829 if s.state == streamDone {
830 return
831 }
832 if w := s.fc.onRead(n); w > 0 {
833 if cw := t.fc.resetPendingUpdate(); cw > 0 {
834 t.controlBuf.put(&windowUpdate{0, cw, false})
835 }
836 t.controlBuf.put(&windowUpdate{s.id, w, true})
837 }
838}
839
840// updateFlowControl updates the incoming flow control windows
841// for the transport and the stream based on the current bdp
842// estimation.
843func (t *http2Client) updateFlowControl(n uint32) {
844 t.mu.Lock()
845 for _, s := range t.activeStreams {
846 s.fc.newLimit(n)
847 }
848 t.initialWindowSize = int32(n)
849 t.mu.Unlock()
850 t.controlBuf.put(&windowUpdate{0, t.fc.newLimit(n), false})
851 t.controlBuf.put(&settings{
852 ack: false,
853 ss: []http2.Setting{
854 {
855 ID: http2.SettingInitialWindowSize,
856 Val: uint32(n),
857 },
858 },
859 })
860}
861
862func (t *http2Client) handleData(f *http2.DataFrame) {
863 size := f.Header().Length
864 var sendBDPPing bool
865 if t.bdpEst != nil {
866 sendBDPPing = t.bdpEst.add(uint32(size))
867 }
868 // Decouple connection's flow control from application's read.
869 // An update on connection's flow control should not depend on
870 // whether user application has read the data or not. Such a
871 // restriction is already imposed on the stream's flow control,
872 // and therefore the sender will be blocked anyways.
873 // Decoupling the connection flow control will prevent other
874 // active(fast) streams from starving in presence of slow or
875 // inactive streams.
876 //
877 // Furthermore, if a bdpPing is being sent out we can piggyback
878 // connection's window update for the bytes we just received.
879 if sendBDPPing {
880 t.controlBuf.put(&windowUpdate{0, uint32(size), false})
881 t.controlBuf.put(bdpPing)
882 } else {
883 if err := t.fc.onData(uint32(size)); err != nil {
884 t.notifyError(connectionErrorf(true, err, "%v", err))
885 return
886 }
887 if w := t.fc.onRead(uint32(size)); w > 0 {
888 t.controlBuf.put(&windowUpdate{0, w, true})
889 }
890 }
891 // Select the right stream to dispatch.
892 s, ok := t.getStream(f)
893 if !ok {
894 return
895 }
896 if size > 0 {
897 s.mu.Lock()
898 if s.state == streamDone {
899 s.mu.Unlock()
900 return
901 }
902 if err := s.fc.onData(uint32(size)); err != nil {
903 s.rstStream = true
904 s.rstError = http2.ErrCodeFlowControl
905 s.finish(status.New(codes.Internal, err.Error()))
906 s.mu.Unlock()
907 s.write(recvMsg{err: io.EOF})
908 return
909 }
910 if f.Header().Flags.Has(http2.FlagDataPadded) {
911 if w := s.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 {
912 t.controlBuf.put(&windowUpdate{s.id, w, true})
913 }
914 }
915 s.mu.Unlock()
916 // TODO(bradfitz, zhaoq): A copy is required here because there is no
917 // guarantee f.Data() is consumed before the arrival of next frame.
918 // Can this copy be eliminated?
919 if len(f.Data()) > 0 {
920 data := make([]byte, len(f.Data()))
921 copy(data, f.Data())
922 s.write(recvMsg{data: data})
923 }
924 }
925 // The server has closed the stream without sending trailers. Record that
926 // the read direction is closed, and set the status appropriately.
927 if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) {
928 s.mu.Lock()
929 if s.state == streamDone {
930 s.mu.Unlock()
931 return
932 }
933 s.finish(status.New(codes.Internal, "server closed the stream without sending trailers"))
934 s.mu.Unlock()
935 s.write(recvMsg{err: io.EOF})
936 }
937}
938
939func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
940 s, ok := t.getStream(f)
941 if !ok {
942 return
943 }
944 s.mu.Lock()
945 if s.state == streamDone {
946 s.mu.Unlock()
947 return
948 }
949 if !s.headerDone {
950 close(s.headerChan)
951 s.headerDone = true
952 }
953 statusCode, ok := http2ErrConvTab[http2.ErrCode(f.ErrCode)]
954 if !ok {
955 warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error %v", f.ErrCode)
956 statusCode = codes.Unknown
957 }
958 s.finish(status.Newf(statusCode, "stream terminated by RST_STREAM with error code: %d", f.ErrCode))
959 s.mu.Unlock()
960 s.write(recvMsg{err: io.EOF})
961}
962
963func (t *http2Client) handleSettings(f *http2.SettingsFrame) {
964 if f.IsAck() {
965 return
966 }
967 var ss []http2.Setting
968 f.ForeachSetting(func(s http2.Setting) error {
969 ss = append(ss, s)
970 return nil
971 })
972 // The settings will be applied once the ack is sent.
973 t.controlBuf.put(&settings{ack: true, ss: ss})
974}
975
976func (t *http2Client) handlePing(f *http2.PingFrame) {
977 if f.IsAck() {
978 // Maybe it's a BDP ping.
979 if t.bdpEst != nil {
980 t.bdpEst.calculate(f.Data)
981 }
982 return
983 }
984 pingAck := &ping{ack: true}
985 copy(pingAck.data[:], f.Data[:])
986 t.controlBuf.put(pingAck)
987}
988
989func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
990 t.mu.Lock()
991 if t.state != reachable && t.state != draining {
992 t.mu.Unlock()
993 return
994 }
995 if f.ErrCode == http2.ErrCodeEnhanceYourCalm {
996 infof("Client received GoAway with http2.ErrCodeEnhanceYourCalm.")
997 }
998 id := f.LastStreamID
999 if id > 0 && id%2 != 1 {
1000 t.mu.Unlock()
1001 t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID))
1002 return
1003 }
1004 // A client can recieve multiple GoAways from server (look at https://github.com/grpc/grpc-go/issues/1387).
1005 // The idea is that the first GoAway will be sent with an ID of MaxInt32 and the second GoAway will be sent after an RTT delay
1006 // with the ID of the last stream the server will process.
1007 // Therefore, when we get the first GoAway we don't really close any streams. While in case of second GoAway we
1008 // close all streams created after the second GoAwayId. This way streams that were in-flight while the GoAway from server
1009 // was being sent don't get killed.
1010 select {
1011 case <-t.goAway: // t.goAway has been closed (i.e.,multiple GoAways).
1012 // If there are multiple GoAways the first one should always have an ID greater than the following ones.
1013 if id > t.prevGoAwayID {
1014 t.mu.Unlock()
1015 t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID))
1016 return
1017 }
1018 default:
1019 t.setGoAwayReason(f)
1020 close(t.goAway)
1021 t.state = draining
1022 }
1023 // All streams with IDs greater than the GoAwayId
1024 // and smaller than the previous GoAway ID should be killed.
1025 upperLimit := t.prevGoAwayID
1026 if upperLimit == 0 { // This is the first GoAway Frame.
1027 upperLimit = math.MaxUint32 // Kill all streams after the GoAway ID.
1028 }
1029 for streamID, stream := range t.activeStreams {
1030 if streamID > id && streamID <= upperLimit {
1031 close(stream.goAway)
1032 }
1033 }
1034 t.prevGoAwayID = id
1035 active := len(t.activeStreams)
1036 t.mu.Unlock()
1037 if active == 0 {
1038 t.Close()
1039 }
1040}
1041
1042// setGoAwayReason sets the value of t.goAwayReason based
1043// on the GoAway frame received.
1044// It expects a lock on transport's mutext to be held by
1045// the caller.
1046func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) {
1047 t.goAwayReason = NoReason
1048 switch f.ErrCode {
1049 case http2.ErrCodeEnhanceYourCalm:
1050 if string(f.DebugData()) == "too_many_pings" {
1051 t.goAwayReason = TooManyPings
1052 }
1053 }
1054}
1055
1056func (t *http2Client) GetGoAwayReason() GoAwayReason {
1057 t.mu.Lock()
1058 defer t.mu.Unlock()
1059 return t.goAwayReason
1060}
1061
1062func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) {
1063 id := f.Header().StreamID
1064 incr := f.Increment
1065 if id == 0 {
1066 t.sendQuotaPool.add(int(incr))
1067 return
1068 }
1069 if s, ok := t.getStream(f); ok {
1070 s.sendQuotaPool.add(int(incr))
1071 }
1072}
1073
1074// operateHeaders takes action on the decoded headers.
1075func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
1076 s, ok := t.getStream(frame)
1077 if !ok {
1078 return
1079 }
1080 s.mu.Lock()
1081 s.bytesReceived = true
1082 s.mu.Unlock()
1083 var state decodeState
1084 if err := state.decodeResponseHeader(frame); err != nil {
1085 s.mu.Lock()
1086 if !s.headerDone {
1087 close(s.headerChan)
1088 s.headerDone = true
1089 }
1090 s.mu.Unlock()
1091 s.write(recvMsg{err: err})
1092 // Something wrong. Stops reading even when there is remaining.
1093 return
1094 }
1095
1096 endStream := frame.StreamEnded()
1097 var isHeader bool
1098 defer func() {
1099 if t.statsHandler != nil {
1100 if isHeader {
1101 inHeader := &stats.InHeader{
1102 Client: true,
1103 WireLength: int(frame.Header().Length),
1104 }
1105 t.statsHandler.HandleRPC(s.ctx, inHeader)
1106 } else {
1107 inTrailer := &stats.InTrailer{
1108 Client: true,
1109 WireLength: int(frame.Header().Length),
1110 }
1111 t.statsHandler.HandleRPC(s.ctx, inTrailer)
1112 }
1113 }
1114 }()
1115
1116 s.mu.Lock()
1117 if !endStream {
1118 s.recvCompress = state.encoding
1119 }
1120 if !s.headerDone {
1121 if !endStream && len(state.mdata) > 0 {
1122 s.header = state.mdata
1123 }
1124 close(s.headerChan)
1125 s.headerDone = true
1126 isHeader = true
1127 }
1128 if !endStream || s.state == streamDone {
1129 s.mu.Unlock()
1130 return
1131 }
1132
1133 if len(state.mdata) > 0 {
1134 s.trailer = state.mdata
1135 }
1136 s.finish(state.status())
1137 s.mu.Unlock()
1138 s.write(recvMsg{err: io.EOF})
1139}
1140
1141func handleMalformedHTTP2(s *Stream, err error) {
1142 s.mu.Lock()
1143 if !s.headerDone {
1144 close(s.headerChan)
1145 s.headerDone = true
1146 }
1147 s.mu.Unlock()
1148 s.write(recvMsg{err: err})
1149}
1150
1151// reader runs as a separate goroutine in charge of reading data from network
1152// connection.
1153//
1154// TODO(zhaoq): currently one reader per transport. Investigate whether this is
1155// optimal.
1156// TODO(zhaoq): Check the validity of the incoming frame sequence.
1157func (t *http2Client) reader() {
1158 // Check the validity of server preface.
1159 frame, err := t.framer.readFrame()
1160 if err != nil {
1161 t.notifyError(err)
1162 return
1163 }
1164 atomic.CompareAndSwapUint32(&t.activity, 0, 1)
1165 sf, ok := frame.(*http2.SettingsFrame)
1166 if !ok {
1167 t.notifyError(err)
1168 return
1169 }
1170 t.handleSettings(sf)
1171
1172 // loop to keep reading incoming messages on this transport.
1173 for {
1174 frame, err := t.framer.readFrame()
1175 atomic.CompareAndSwapUint32(&t.activity, 0, 1)
1176 if err != nil {
1177 // Abort an active stream if the http2.Framer returns a
1178 // http2.StreamError. This can happen only if the server's response
1179 // is malformed http2.
1180 if se, ok := err.(http2.StreamError); ok {
1181 t.mu.Lock()
1182 s := t.activeStreams[se.StreamID]
1183 t.mu.Unlock()
1184 if s != nil {
1185 // use error detail to provide better err message
1186 handleMalformedHTTP2(s, streamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail()))
1187 }
1188 continue
1189 } else {
1190 // Transport error.
1191 t.notifyError(err)
1192 return
1193 }
1194 }
1195 switch frame := frame.(type) {
1196 case *http2.MetaHeadersFrame:
1197 t.operateHeaders(frame)
1198 case *http2.DataFrame:
1199 t.handleData(frame)
1200 case *http2.RSTStreamFrame:
1201 t.handleRSTStream(frame)
1202 case *http2.SettingsFrame:
1203 t.handleSettings(frame)
1204 case *http2.PingFrame:
1205 t.handlePing(frame)
1206 case *http2.GoAwayFrame:
1207 t.handleGoAway(frame)
1208 case *http2.WindowUpdateFrame:
1209 t.handleWindowUpdate(frame)
1210 default:
1211 errorf("transport: http2Client.reader got unhandled frame type %v.", frame)
1212 }
1213 }
1214}
1215
1216func (t *http2Client) applySettings(ss []http2.Setting) {
1217 for _, s := range ss {
1218 switch s.ID {
1219 case http2.SettingMaxConcurrentStreams:
1220 // TODO(zhaoq): This is a hack to avoid significant refactoring of the
1221 // code to deal with the unrealistic int32 overflow. Probably will try
1222 // to find a better way to handle this later.
1223 if s.Val > math.MaxInt32 {
1224 s.Val = math.MaxInt32
1225 }
1226 t.mu.Lock()
1227 ms := t.maxStreams
1228 t.maxStreams = int(s.Val)
1229 t.mu.Unlock()
1230 t.streamsQuota.add(int(s.Val) - ms)
1231 case http2.SettingInitialWindowSize:
1232 t.mu.Lock()
1233 for _, stream := range t.activeStreams {
1234 // Adjust the sending quota for each stream.
1235 stream.sendQuotaPool.add(int(s.Val) - int(t.streamSendQuota))
1236 }
1237 t.streamSendQuota = s.Val
1238 t.mu.Unlock()
1239 atomic.AddUint32(&t.outQuotaVersion, 1)
1240 }
1241 }
1242}
1243
1244// controller running in a separate goroutine takes charge of sending control
1245// frames (e.g., window update, reset stream, setting, etc.) to the server.
1246func (t *http2Client) controller() {
1247 for {
1248 select {
1249 case i := <-t.controlBuf.get():
1250 t.controlBuf.load()
1251 select {
1252 case <-t.writableChan:
1253 switch i := i.(type) {
1254 case *windowUpdate:
1255 t.framer.writeWindowUpdate(i.flush, i.streamID, i.increment)
1256 case *settings:
1257 if i.ack {
1258 t.framer.writeSettingsAck(true)
1259 t.applySettings(i.ss)
1260 } else {
1261 t.framer.writeSettings(true, i.ss...)
1262 }
1263 case *resetStream:
1264 // If the server needs to be to intimated about stream closing,
1265 // then we need to make sure the RST_STREAM frame is written to
1266 // the wire before the headers of the next stream waiting on
1267 // streamQuota. We ensure this by adding to the streamsQuota pool
1268 // only after having acquired the writableChan to send RST_STREAM.
1269 t.streamsQuota.add(1)
1270 t.framer.writeRSTStream(true, i.streamID, i.code)
1271 case *flushIO:
1272 t.framer.flushWrite()
1273 case *ping:
1274 if !i.ack {
1275 t.bdpEst.timesnap(i.data)
1276 }
1277 t.framer.writePing(true, i.ack, i.data)
1278 default:
1279 errorf("transport: http2Client.controller got unexpected item type %v\n", i)
1280 }
1281 t.writableChan <- 0
1282 continue
1283 case <-t.shutdownChan:
1284 return
1285 }
1286 case <-t.shutdownChan:
1287 return
1288 }
1289 }
1290}
1291
1292// keepalive running in a separate goroutune makes sure the connection is alive by sending pings.
1293func (t *http2Client) keepalive() {
1294 p := &ping{data: [8]byte{}}
1295 timer := time.NewTimer(t.kp.Time)
1296 for {
1297 select {
1298 case <-timer.C:
1299 if atomic.CompareAndSwapUint32(&t.activity, 1, 0) {
1300 timer.Reset(t.kp.Time)
1301 continue
1302 }
1303 // Check if keepalive should go dormant.
1304 t.mu.Lock()
1305 if len(t.activeStreams) < 1 && !t.kp.PermitWithoutStream {
1306 // Make awakenKeepalive writable.
1307 <-t.awakenKeepalive
1308 t.mu.Unlock()
1309 select {
1310 case <-t.awakenKeepalive:
1311 // If the control gets here a ping has been sent
1312 // need to reset the timer with keepalive.Timeout.
1313 case <-t.shutdownChan:
1314 return
1315 }
1316 } else {
1317 t.mu.Unlock()
1318 // Send ping.
1319 t.controlBuf.put(p)
1320 }
1321
1322 // By the time control gets here a ping has been sent one way or the other.
1323 timer.Reset(t.kp.Timeout)
1324 select {
1325 case <-timer.C:
1326 if atomic.CompareAndSwapUint32(&t.activity, 1, 0) {
1327 timer.Reset(t.kp.Time)
1328 continue
1329 }
1330 t.Close()
1331 return
1332 case <-t.shutdownChan:
1333 if !timer.Stop() {
1334 <-timer.C
1335 }
1336 return
1337 }
1338 case <-t.shutdownChan:
1339 if !timer.Stop() {
1340 <-timer.C
1341 }
1342 return
1343 }
1344 }
1345}
1346
1347func (t *http2Client) Error() <-chan struct{} {
1348 return t.errorChan
1349}
1350
1351func (t *http2Client) GoAway() <-chan struct{} {
1352 return t.goAway
1353}
1354
1355func (t *http2Client) notifyError(err error) {
1356 t.mu.Lock()
1357 // make sure t.errorChan is closed only once.
1358 if t.state == draining {
1359 t.mu.Unlock()
1360 t.Close()
1361 return
1362 }
1363 if t.state == reachable {
1364 t.state = unreachable
1365 close(t.errorChan)
1366 infof("transport: http2Client.notifyError got notified that the client transport was broken %v.", err)
1367 }
1368 t.mu.Unlock()
1369}
diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go
new file mode 100644
index 0000000..b6f93e3
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/http2_server.go
@@ -0,0 +1,1195 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package transport
20
21import (
22 "bytes"
23 "errors"
24 "io"
25 "math"
26 "math/rand"
27 "net"
28 "strconv"
29 "sync"
30 "sync/atomic"
31 "time"
32
33 "github.com/golang/protobuf/proto"
34 "golang.org/x/net/context"
35 "golang.org/x/net/http2"
36 "golang.org/x/net/http2/hpack"
37 "google.golang.org/grpc/codes"
38 "google.golang.org/grpc/credentials"
39 "google.golang.org/grpc/keepalive"
40 "google.golang.org/grpc/metadata"
41 "google.golang.org/grpc/peer"
42 "google.golang.org/grpc/stats"
43 "google.golang.org/grpc/status"
44 "google.golang.org/grpc/tap"
45)
46
47// ErrIllegalHeaderWrite indicates that setting header is illegal because of
48// the stream's state.
49var ErrIllegalHeaderWrite = errors.New("transport: the stream is done or WriteHeader was already called")
50
51// http2Server implements the ServerTransport interface with HTTP2.
52type http2Server struct {
53 ctx context.Context
54 conn net.Conn
55 remoteAddr net.Addr
56 localAddr net.Addr
57 maxStreamID uint32 // max stream ID ever seen
58 authInfo credentials.AuthInfo // auth info about the connection
59 inTapHandle tap.ServerInHandle
60 // writableChan synchronizes write access to the transport.
61 // A writer acquires the write lock by receiving a value on writableChan
62 // and releases it by sending on writableChan.
63 writableChan chan int
64 // shutdownChan is closed when Close is called.
65 // Blocking operations should select on shutdownChan to avoid
66 // blocking forever after Close.
67 shutdownChan chan struct{}
68 framer *framer
69 hBuf *bytes.Buffer // the buffer for HPACK encoding
70 hEnc *hpack.Encoder // HPACK encoder
71 // The max number of concurrent streams.
72 maxStreams uint32
73 // controlBuf delivers all the control related tasks (e.g., window
74 // updates, reset streams, and various settings) to the controller.
75 controlBuf *controlBuffer
76 fc *inFlow
77 // sendQuotaPool provides flow control to outbound message.
78 sendQuotaPool *quotaPool
79 stats stats.Handler
80 // Flag to keep track of reading activity on transport.
81 // 1 is true and 0 is false.
82 activity uint32 // Accessed atomically.
83 // Keepalive and max-age parameters for the server.
84 kp keepalive.ServerParameters
85
86 // Keepalive enforcement policy.
87 kep keepalive.EnforcementPolicy
88 // The time instance last ping was received.
89 lastPingAt time.Time
90 // Number of times the client has violated keepalive ping policy so far.
91 pingStrikes uint8
92 // Flag to signify that number of ping strikes should be reset to 0.
93 // This is set whenever data or header frames are sent.
94 // 1 means yes.
95 resetPingStrikes uint32 // Accessed atomically.
96 initialWindowSize int32
97 bdpEst *bdpEstimator
98
99 outQuotaVersion uint32
100
101 mu sync.Mutex // guard the following
102
103 // drainChan is initialized when drain(...) is called the first time.
104 // After which the server writes out the first GoAway(with ID 2^31-1) frame.
105 // Then an independent goroutine will be launched to later send the second GoAway.
106 // During this time we don't want to write another first GoAway(with ID 2^31 -1) frame.
107 // Thus call to drain(...) will be a no-op if drainChan is already initialized since draining is
108 // already underway.
109 drainChan chan struct{}
110 state transportState
111 activeStreams map[uint32]*Stream
112 // the per-stream outbound flow control window size set by the peer.
113 streamSendQuota uint32
114 // idle is the time instant when the connection went idle.
115 // This is either the begining of the connection or when the number of
116 // RPCs go down to 0.
117 // When the connection is busy, this value is set to 0.
118 idle time.Time
119}
120
121// newHTTP2Server constructs a ServerTransport based on HTTP2. ConnectionError is
122// returned if something goes wrong.
123func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) {
124 framer := newFramer(conn)
125 // Send initial settings as connection preface to client.
126 var isettings []http2.Setting
127 // TODO(zhaoq): Have a better way to signal "no limit" because 0 is
128 // permitted in the HTTP2 spec.
129 maxStreams := config.MaxStreams
130 if maxStreams == 0 {
131 maxStreams = math.MaxUint32
132 } else {
133 isettings = append(isettings, http2.Setting{
134 ID: http2.SettingMaxConcurrentStreams,
135 Val: maxStreams,
136 })
137 }
138 dynamicWindow := true
139 iwz := int32(initialWindowSize)
140 if config.InitialWindowSize >= defaultWindowSize {
141 iwz = config.InitialWindowSize
142 dynamicWindow = false
143 }
144 icwz := int32(initialWindowSize)
145 if config.InitialConnWindowSize >= defaultWindowSize {
146 icwz = config.InitialConnWindowSize
147 dynamicWindow = false
148 }
149 if iwz != defaultWindowSize {
150 isettings = append(isettings, http2.Setting{
151 ID: http2.SettingInitialWindowSize,
152 Val: uint32(iwz)})
153 }
154 if err := framer.writeSettings(true, isettings...); err != nil {
155 return nil, connectionErrorf(true, err, "transport: %v", err)
156 }
157 // Adjust the connection flow control window if needed.
158 if delta := uint32(icwz - defaultWindowSize); delta > 0 {
159 if err := framer.writeWindowUpdate(true, 0, delta); err != nil {
160 return nil, connectionErrorf(true, err, "transport: %v", err)
161 }
162 }
163 kp := config.KeepaliveParams
164 if kp.MaxConnectionIdle == 0 {
165 kp.MaxConnectionIdle = defaultMaxConnectionIdle
166 }
167 if kp.MaxConnectionAge == 0 {
168 kp.MaxConnectionAge = defaultMaxConnectionAge
169 }
170 // Add a jitter to MaxConnectionAge.
171 kp.MaxConnectionAge += getJitter(kp.MaxConnectionAge)
172 if kp.MaxConnectionAgeGrace == 0 {
173 kp.MaxConnectionAgeGrace = defaultMaxConnectionAgeGrace
174 }
175 if kp.Time == 0 {
176 kp.Time = defaultServerKeepaliveTime
177 }
178 if kp.Timeout == 0 {
179 kp.Timeout = defaultServerKeepaliveTimeout
180 }
181 kep := config.KeepalivePolicy
182 if kep.MinTime == 0 {
183 kep.MinTime = defaultKeepalivePolicyMinTime
184 }
185 var buf bytes.Buffer
186 t := &http2Server{
187 ctx: context.Background(),
188 conn: conn,
189 remoteAddr: conn.RemoteAddr(),
190 localAddr: conn.LocalAddr(),
191 authInfo: config.AuthInfo,
192 framer: framer,
193 hBuf: &buf,
194 hEnc: hpack.NewEncoder(&buf),
195 maxStreams: maxStreams,
196 inTapHandle: config.InTapHandle,
197 controlBuf: newControlBuffer(),
198 fc: &inFlow{limit: uint32(icwz)},
199 sendQuotaPool: newQuotaPool(defaultWindowSize),
200 state: reachable,
201 writableChan: make(chan int, 1),
202 shutdownChan: make(chan struct{}),
203 activeStreams: make(map[uint32]*Stream),
204 streamSendQuota: defaultWindowSize,
205 stats: config.StatsHandler,
206 kp: kp,
207 idle: time.Now(),
208 kep: kep,
209 initialWindowSize: iwz,
210 }
211 if dynamicWindow {
212 t.bdpEst = &bdpEstimator{
213 bdp: initialWindowSize,
214 updateFlowControl: t.updateFlowControl,
215 }
216 }
217 if t.stats != nil {
218 t.ctx = t.stats.TagConn(t.ctx, &stats.ConnTagInfo{
219 RemoteAddr: t.remoteAddr,
220 LocalAddr: t.localAddr,
221 })
222 connBegin := &stats.ConnBegin{}
223 t.stats.HandleConn(t.ctx, connBegin)
224 }
225 go t.controller()
226 go t.keepalive()
227 t.writableChan <- 0
228 return t, nil
229}
230
231// operateHeader takes action on the decoded headers.
232func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (close bool) {
233 buf := newRecvBuffer()
234 s := &Stream{
235 id: frame.Header().StreamID,
236 st: t,
237 buf: buf,
238 fc: &inFlow{limit: uint32(t.initialWindowSize)},
239 }
240
241 var state decodeState
242 for _, hf := range frame.Fields {
243 if err := state.processHeaderField(hf); err != nil {
244 if se, ok := err.(StreamError); ok {
245 t.controlBuf.put(&resetStream{s.id, statusCodeConvTab[se.Code]})
246 }
247 return
248 }
249 }
250
251 if frame.StreamEnded() {
252 // s is just created by the caller. No lock needed.
253 s.state = streamReadDone
254 }
255 s.recvCompress = state.encoding
256 if state.timeoutSet {
257 s.ctx, s.cancel = context.WithTimeout(t.ctx, state.timeout)
258 } else {
259 s.ctx, s.cancel = context.WithCancel(t.ctx)
260 }
261 pr := &peer.Peer{
262 Addr: t.remoteAddr,
263 }
264 // Attach Auth info if there is any.
265 if t.authInfo != nil {
266 pr.AuthInfo = t.authInfo
267 }
268 s.ctx = peer.NewContext(s.ctx, pr)
269 // Cache the current stream to the context so that the server application
270 // can find out. Required when the server wants to send some metadata
271 // back to the client (unary call only).
272 s.ctx = newContextWithStream(s.ctx, s)
273 // Attach the received metadata to the context.
274 if len(state.mdata) > 0 {
275 s.ctx = metadata.NewIncomingContext(s.ctx, state.mdata)
276 }
277 s.trReader = &transportReader{
278 reader: &recvBufferReader{
279 ctx: s.ctx,
280 recv: s.buf,
281 },
282 windowHandler: func(n int) {
283 t.updateWindow(s, uint32(n))
284 },
285 }
286 s.recvCompress = state.encoding
287 s.method = state.method
288 if t.inTapHandle != nil {
289 var err error
290 info := &tap.Info{
291 FullMethodName: state.method,
292 }
293 s.ctx, err = t.inTapHandle(s.ctx, info)
294 if err != nil {
295 warningf("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err)
296 t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
297 return
298 }
299 }
300 t.mu.Lock()
301 if t.state != reachable {
302 t.mu.Unlock()
303 return
304 }
305 if uint32(len(t.activeStreams)) >= t.maxStreams {
306 t.mu.Unlock()
307 t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
308 return
309 }
310 if s.id%2 != 1 || s.id <= t.maxStreamID {
311 t.mu.Unlock()
312 // illegal gRPC stream id.
313 errorf("transport: http2Server.HandleStreams received an illegal stream id: %v", s.id)
314 return true
315 }
316 t.maxStreamID = s.id
317 s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota))
318 t.activeStreams[s.id] = s
319 if len(t.activeStreams) == 1 {
320 t.idle = time.Time{}
321 }
322 t.mu.Unlock()
323 s.requestRead = func(n int) {
324 t.adjustWindow(s, uint32(n))
325 }
326 s.ctx = traceCtx(s.ctx, s.method)
327 if t.stats != nil {
328 s.ctx = t.stats.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method})
329 inHeader := &stats.InHeader{
330 FullMethod: s.method,
331 RemoteAddr: t.remoteAddr,
332 LocalAddr: t.localAddr,
333 Compression: s.recvCompress,
334 WireLength: int(frame.Header().Length),
335 }
336 t.stats.HandleRPC(s.ctx, inHeader)
337 }
338 handle(s)
339 return
340}
341
342// HandleStreams receives incoming streams using the given handler. This is
343// typically run in a separate goroutine.
344// traceCtx attaches trace to ctx and returns the new context.
345func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.Context, string) context.Context) {
346 // Check the validity of client preface.
347 preface := make([]byte, len(clientPreface))
348 if _, err := io.ReadFull(t.conn, preface); err != nil {
349 // Only log if it isn't a simple tcp accept check (ie: tcp balancer doing open/close socket)
350 if err != io.EOF {
351 errorf("transport: http2Server.HandleStreams failed to receive the preface from client: %v", err)
352 }
353 t.Close()
354 return
355 }
356 if !bytes.Equal(preface, clientPreface) {
357 errorf("transport: http2Server.HandleStreams received bogus greeting from client: %q", preface)
358 t.Close()
359 return
360 }
361
362 frame, err := t.framer.readFrame()
363 if err == io.EOF || err == io.ErrUnexpectedEOF {
364 t.Close()
365 return
366 }
367 if err != nil {
368 errorf("transport: http2Server.HandleStreams failed to read initial settings frame: %v", err)
369 t.Close()
370 return
371 }
372 atomic.StoreUint32(&t.activity, 1)
373 sf, ok := frame.(*http2.SettingsFrame)
374 if !ok {
375 errorf("transport: http2Server.HandleStreams saw invalid preface type %T from client", frame)
376 t.Close()
377 return
378 }
379 t.handleSettings(sf)
380
381 for {
382 frame, err := t.framer.readFrame()
383 atomic.StoreUint32(&t.activity, 1)
384 if err != nil {
385 if se, ok := err.(http2.StreamError); ok {
386 t.mu.Lock()
387 s := t.activeStreams[se.StreamID]
388 t.mu.Unlock()
389 if s != nil {
390 t.closeStream(s)
391 }
392 t.controlBuf.put(&resetStream{se.StreamID, se.Code})
393 continue
394 }
395 if err == io.EOF || err == io.ErrUnexpectedEOF {
396 t.Close()
397 return
398 }
399 warningf("transport: http2Server.HandleStreams failed to read frame: %v", err)
400 t.Close()
401 return
402 }
403 switch frame := frame.(type) {
404 case *http2.MetaHeadersFrame:
405 if t.operateHeaders(frame, handle, traceCtx) {
406 t.Close()
407 break
408 }
409 case *http2.DataFrame:
410 t.handleData(frame)
411 case *http2.RSTStreamFrame:
412 t.handleRSTStream(frame)
413 case *http2.SettingsFrame:
414 t.handleSettings(frame)
415 case *http2.PingFrame:
416 t.handlePing(frame)
417 case *http2.WindowUpdateFrame:
418 t.handleWindowUpdate(frame)
419 case *http2.GoAwayFrame:
420 // TODO: Handle GoAway from the client appropriately.
421 default:
422 errorf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
423 }
424 }
425}
426
427func (t *http2Server) getStream(f http2.Frame) (*Stream, bool) {
428 t.mu.Lock()
429 defer t.mu.Unlock()
430 if t.activeStreams == nil {
431 // The transport is closing.
432 return nil, false
433 }
434 s, ok := t.activeStreams[f.Header().StreamID]
435 if !ok {
436 // The stream is already done.
437 return nil, false
438 }
439 return s, true
440}
441
442// adjustWindow sends out extra window update over the initial window size
443// of stream if the application is requesting data larger in size than
444// the window.
445func (t *http2Server) adjustWindow(s *Stream, n uint32) {
446 s.mu.Lock()
447 defer s.mu.Unlock()
448 if s.state == streamDone {
449 return
450 }
451 if w := s.fc.maybeAdjust(n); w > 0 {
452 if cw := t.fc.resetPendingUpdate(); cw > 0 {
453 t.controlBuf.put(&windowUpdate{0, cw, false})
454 }
455 t.controlBuf.put(&windowUpdate{s.id, w, true})
456 }
457}
458
459// updateWindow adjusts the inbound quota for the stream and the transport.
460// Window updates will deliver to the controller for sending when
461// the cumulative quota exceeds the corresponding threshold.
462func (t *http2Server) updateWindow(s *Stream, n uint32) {
463 s.mu.Lock()
464 defer s.mu.Unlock()
465 if s.state == streamDone {
466 return
467 }
468 if w := s.fc.onRead(n); w > 0 {
469 if cw := t.fc.resetPendingUpdate(); cw > 0 {
470 t.controlBuf.put(&windowUpdate{0, cw, false})
471 }
472 t.controlBuf.put(&windowUpdate{s.id, w, true})
473 }
474}
475
476// updateFlowControl updates the incoming flow control windows
477// for the transport and the stream based on the current bdp
478// estimation.
479func (t *http2Server) updateFlowControl(n uint32) {
480 t.mu.Lock()
481 for _, s := range t.activeStreams {
482 s.fc.newLimit(n)
483 }
484 t.initialWindowSize = int32(n)
485 t.mu.Unlock()
486 t.controlBuf.put(&windowUpdate{0, t.fc.newLimit(n), false})
487 t.controlBuf.put(&settings{
488 ack: false,
489 ss: []http2.Setting{
490 {
491 ID: http2.SettingInitialWindowSize,
492 Val: uint32(n),
493 },
494 },
495 })
496
497}
498
499func (t *http2Server) handleData(f *http2.DataFrame) {
500 size := f.Header().Length
501 var sendBDPPing bool
502 if t.bdpEst != nil {
503 sendBDPPing = t.bdpEst.add(uint32(size))
504 }
505 // Decouple connection's flow control from application's read.
506 // An update on connection's flow control should not depend on
507 // whether user application has read the data or not. Such a
508 // restriction is already imposed on the stream's flow control,
509 // and therefore the sender will be blocked anyways.
510 // Decoupling the connection flow control will prevent other
511 // active(fast) streams from starving in presence of slow or
512 // inactive streams.
513 //
514 // Furthermore, if a bdpPing is being sent out we can piggyback
515 // connection's window update for the bytes we just received.
516 if sendBDPPing {
517 t.controlBuf.put(&windowUpdate{0, uint32(size), false})
518 t.controlBuf.put(bdpPing)
519 } else {
520 if err := t.fc.onData(uint32(size)); err != nil {
521 errorf("transport: http2Server %v", err)
522 t.Close()
523 return
524 }
525 if w := t.fc.onRead(uint32(size)); w > 0 {
526 t.controlBuf.put(&windowUpdate{0, w, true})
527 }
528 }
529 // Select the right stream to dispatch.
530 s, ok := t.getStream(f)
531 if !ok {
532 return
533 }
534 if size > 0 {
535 s.mu.Lock()
536 if s.state == streamDone {
537 s.mu.Unlock()
538 return
539 }
540 if err := s.fc.onData(uint32(size)); err != nil {
541 s.mu.Unlock()
542 t.closeStream(s)
543 t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
544 return
545 }
546 if f.Header().Flags.Has(http2.FlagDataPadded) {
547 if w := s.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 {
548 t.controlBuf.put(&windowUpdate{s.id, w, true})
549 }
550 }
551 s.mu.Unlock()
552 // TODO(bradfitz, zhaoq): A copy is required here because there is no
553 // guarantee f.Data() is consumed before the arrival of next frame.
554 // Can this copy be eliminated?
555 if len(f.Data()) > 0 {
556 data := make([]byte, len(f.Data()))
557 copy(data, f.Data())
558 s.write(recvMsg{data: data})
559 }
560 }
561 if f.Header().Flags.Has(http2.FlagDataEndStream) {
562 // Received the end of stream from the client.
563 s.mu.Lock()
564 if s.state != streamDone {
565 s.state = streamReadDone
566 }
567 s.mu.Unlock()
568 s.write(recvMsg{err: io.EOF})
569 }
570}
571
572func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) {
573 s, ok := t.getStream(f)
574 if !ok {
575 return
576 }
577 t.closeStream(s)
578}
579
580func (t *http2Server) handleSettings(f *http2.SettingsFrame) {
581 if f.IsAck() {
582 return
583 }
584 var ss []http2.Setting
585 f.ForeachSetting(func(s http2.Setting) error {
586 ss = append(ss, s)
587 return nil
588 })
589 // The settings will be applied once the ack is sent.
590 t.controlBuf.put(&settings{ack: true, ss: ss})
591}
592
593const (
594 maxPingStrikes = 2
595 defaultPingTimeout = 2 * time.Hour
596)
597
598func (t *http2Server) handlePing(f *http2.PingFrame) {
599 if f.IsAck() {
600 if f.Data == goAwayPing.data && t.drainChan != nil {
601 close(t.drainChan)
602 return
603 }
604 // Maybe it's a BDP ping.
605 if t.bdpEst != nil {
606 t.bdpEst.calculate(f.Data)
607 }
608 return
609 }
610 pingAck := &ping{ack: true}
611 copy(pingAck.data[:], f.Data[:])
612 t.controlBuf.put(pingAck)
613
614 now := time.Now()
615 defer func() {
616 t.lastPingAt = now
617 }()
618 // A reset ping strikes means that we don't need to check for policy
619 // violation for this ping and the pingStrikes counter should be set
620 // to 0.
621 if atomic.CompareAndSwapUint32(&t.resetPingStrikes, 1, 0) {
622 t.pingStrikes = 0
623 return
624 }
625 t.mu.Lock()
626 ns := len(t.activeStreams)
627 t.mu.Unlock()
628 if ns < 1 && !t.kep.PermitWithoutStream {
629 // Keepalive shouldn't be active thus, this new ping should
630 // have come after atleast defaultPingTimeout.
631 if t.lastPingAt.Add(defaultPingTimeout).After(now) {
632 t.pingStrikes++
633 }
634 } else {
635 // Check if keepalive policy is respected.
636 if t.lastPingAt.Add(t.kep.MinTime).After(now) {
637 t.pingStrikes++
638 }
639 }
640
641 if t.pingStrikes > maxPingStrikes {
642 // Send goaway and close the connection.
643 t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings"), closeConn: true})
644 }
645}
646
647func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) {
648 id := f.Header().StreamID
649 incr := f.Increment
650 if id == 0 {
651 t.sendQuotaPool.add(int(incr))
652 return
653 }
654 if s, ok := t.getStream(f); ok {
655 s.sendQuotaPool.add(int(incr))
656 }
657}
658
659func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) error {
660 first := true
661 endHeaders := false
662 var err error
663 defer func() {
664 if err == nil {
665 // Reset ping strikes when seding headers since that might cause the
666 // peer to send ping.
667 atomic.StoreUint32(&t.resetPingStrikes, 1)
668 }
669 }()
670 // Sends the headers in a single batch.
671 for !endHeaders {
672 size := t.hBuf.Len()
673 if size > http2MaxFrameLen {
674 size = http2MaxFrameLen
675 } else {
676 endHeaders = true
677 }
678 if first {
679 p := http2.HeadersFrameParam{
680 StreamID: s.id,
681 BlockFragment: b.Next(size),
682 EndStream: endStream,
683 EndHeaders: endHeaders,
684 }
685 err = t.framer.writeHeaders(endHeaders, p)
686 first = false
687 } else {
688 err = t.framer.writeContinuation(endHeaders, s.id, endHeaders, b.Next(size))
689 }
690 if err != nil {
691 t.Close()
692 return connectionErrorf(true, err, "transport: %v", err)
693 }
694 }
695 return nil
696}
697
698// WriteHeader sends the header metedata md back to the client.
699func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
700 s.mu.Lock()
701 if s.headerOk || s.state == streamDone {
702 s.mu.Unlock()
703 return ErrIllegalHeaderWrite
704 }
705 s.headerOk = true
706 if md.Len() > 0 {
707 if s.header.Len() > 0 {
708 s.header = metadata.Join(s.header, md)
709 } else {
710 s.header = md
711 }
712 }
713 md = s.header
714 s.mu.Unlock()
715 if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
716 return err
717 }
718 t.hBuf.Reset()
719 t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
720 t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
721 if s.sendCompress != "" {
722 t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
723 }
724 for k, vv := range md {
725 if isReservedHeader(k) {
726 // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
727 continue
728 }
729 for _, v := range vv {
730 t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
731 }
732 }
733 bufLen := t.hBuf.Len()
734 if err := t.writeHeaders(s, t.hBuf, false); err != nil {
735 return err
736 }
737 if t.stats != nil {
738 outHeader := &stats.OutHeader{
739 WireLength: bufLen,
740 }
741 t.stats.HandleRPC(s.Context(), outHeader)
742 }
743 t.writableChan <- 0
744 return nil
745}
746
747// WriteStatus sends stream status to the client and terminates the stream.
748// There is no further I/O operations being able to perform on this stream.
749// TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early
750// OK is adopted.
751func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
752 var headersSent, hasHeader bool
753 s.mu.Lock()
754 if s.state == streamDone {
755 s.mu.Unlock()
756 return nil
757 }
758 if s.headerOk {
759 headersSent = true
760 }
761 if s.header.Len() > 0 {
762 hasHeader = true
763 }
764 s.mu.Unlock()
765
766 if !headersSent && hasHeader {
767 t.WriteHeader(s, nil)
768 headersSent = true
769 }
770
771 if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
772 return err
773 }
774 t.hBuf.Reset()
775 if !headersSent {
776 t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
777 t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
778 }
779 t.hEnc.WriteField(
780 hpack.HeaderField{
781 Name: "grpc-status",
782 Value: strconv.Itoa(int(st.Code())),
783 })
784 t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())})
785
786 if p := st.Proto(); p != nil && len(p.Details) > 0 {
787 stBytes, err := proto.Marshal(p)
788 if err != nil {
789 // TODO: return error instead, when callers are able to handle it.
790 panic(err)
791 }
792
793 t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
794 }
795
796 // Attach the trailer metadata.
797 for k, vv := range s.trailer {
798 // Clients don't tolerate reading restricted headers after some non restricted ones were sent.
799 if isReservedHeader(k) {
800 continue
801 }
802 for _, v := range vv {
803 t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
804 }
805 }
806 bufLen := t.hBuf.Len()
807 if err := t.writeHeaders(s, t.hBuf, true); err != nil {
808 t.Close()
809 return err
810 }
811 if t.stats != nil {
812 outTrailer := &stats.OutTrailer{
813 WireLength: bufLen,
814 }
815 t.stats.HandleRPC(s.Context(), outTrailer)
816 }
817 t.closeStream(s)
818 t.writableChan <- 0
819 return nil
820}
821
822// Write converts the data into HTTP2 data frame and sends it out. Non-nil error
823// is returns if it fails (e.g., framing error, transport error).
824func (t *http2Server) Write(s *Stream, data []byte, opts *Options) (err error) {
825 // TODO(zhaoq): Support multi-writers for a single stream.
826 var writeHeaderFrame bool
827 s.mu.Lock()
828 if s.state == streamDone {
829 s.mu.Unlock()
830 return streamErrorf(codes.Unknown, "the stream has been done")
831 }
832 if !s.headerOk {
833 writeHeaderFrame = true
834 }
835 s.mu.Unlock()
836 if writeHeaderFrame {
837 t.WriteHeader(s, nil)
838 }
839 r := bytes.NewBuffer(data)
840 var (
841 p []byte
842 oqv uint32
843 )
844 for {
845 if r.Len() == 0 && p == nil {
846 return nil
847 }
848 oqv = atomic.LoadUint32(&t.outQuotaVersion)
849 size := http2MaxFrameLen
850 // Wait until the stream has some quota to send the data.
851 sq, err := wait(s.ctx, nil, nil, t.shutdownChan, s.sendQuotaPool.acquire())
852 if err != nil {
853 return err
854 }
855 // Wait until the transport has some quota to send the data.
856 tq, err := wait(s.ctx, nil, nil, t.shutdownChan, t.sendQuotaPool.acquire())
857 if err != nil {
858 return err
859 }
860 if sq < size {
861 size = sq
862 }
863 if tq < size {
864 size = tq
865 }
866 if p == nil {
867 p = r.Next(size)
868 }
869 ps := len(p)
870 if ps < sq {
871 // Overbooked stream quota. Return it back.
872 s.sendQuotaPool.add(sq - ps)
873 }
874 if ps < tq {
875 // Overbooked transport quota. Return it back.
876 t.sendQuotaPool.add(tq - ps)
877 }
878 t.framer.adjustNumWriters(1)
879 // Got some quota. Try to acquire writing privilege on the
880 // transport.
881 if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil {
882 if _, ok := err.(StreamError); ok {
883 // Return the connection quota back.
884 t.sendQuotaPool.add(ps)
885 }
886 if t.framer.adjustNumWriters(-1) == 0 {
887 // This writer is the last one in this batch and has the
888 // responsibility to flush the buffered frames. It queues
889 // a flush request to controlBuf instead of flushing directly
890 // in order to avoid the race with other writing or flushing.
891 t.controlBuf.put(&flushIO{})
892 }
893 return err
894 }
895 select {
896 case <-s.ctx.Done():
897 t.sendQuotaPool.add(ps)
898 if t.framer.adjustNumWriters(-1) == 0 {
899 t.controlBuf.put(&flushIO{})
900 }
901 t.writableChan <- 0
902 return ContextErr(s.ctx.Err())
903 default:
904 }
905 if oqv != atomic.LoadUint32(&t.outQuotaVersion) {
906 // InitialWindowSize settings frame must have been received after we
907 // acquired send quota but before we got the writable channel.
908 // We must forsake this write.
909 t.sendQuotaPool.add(ps)
910 s.sendQuotaPool.add(ps)
911 if t.framer.adjustNumWriters(-1) == 0 {
912 t.controlBuf.put(&flushIO{})
913 }
914 t.writableChan <- 0
915 continue
916 }
917 var forceFlush bool
918 if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 && !opts.Last {
919 forceFlush = true
920 }
921 // Reset ping strikes when sending data since this might cause
922 // the peer to send ping.
923 atomic.StoreUint32(&t.resetPingStrikes, 1)
924 if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil {
925 t.Close()
926 return connectionErrorf(true, err, "transport: %v", err)
927 }
928 p = nil
929 if t.framer.adjustNumWriters(-1) == 0 {
930 t.framer.flushWrite()
931 }
932 t.writableChan <- 0
933 }
934
935}
936
937func (t *http2Server) applySettings(ss []http2.Setting) {
938 for _, s := range ss {
939 if s.ID == http2.SettingInitialWindowSize {
940 t.mu.Lock()
941 defer t.mu.Unlock()
942 for _, stream := range t.activeStreams {
943 stream.sendQuotaPool.add(int(s.Val) - int(t.streamSendQuota))
944 }
945 t.streamSendQuota = s.Val
946 atomic.AddUint32(&t.outQuotaVersion, 1)
947 }
948
949 }
950}
951
952// keepalive running in a separate goroutine does the following:
953// 1. Gracefully closes an idle connection after a duration of keepalive.MaxConnectionIdle.
954// 2. Gracefully closes any connection after a duration of keepalive.MaxConnectionAge.
955// 3. Forcibly closes a connection after an additive period of keepalive.MaxConnectionAgeGrace over keepalive.MaxConnectionAge.
956// 4. Makes sure a connection is alive by sending pings with a frequency of keepalive.Time and closes a non-responsive connection
957// after an additional duration of keepalive.Timeout.
958func (t *http2Server) keepalive() {
959 p := &ping{}
960 var pingSent bool
961 maxIdle := time.NewTimer(t.kp.MaxConnectionIdle)
962 maxAge := time.NewTimer(t.kp.MaxConnectionAge)
963 keepalive := time.NewTimer(t.kp.Time)
964 // NOTE: All exit paths of this function should reset their
965 // respecitve timers. A failure to do so will cause the
966 // following clean-up to deadlock and eventually leak.
967 defer func() {
968 if !maxIdle.Stop() {
969 <-maxIdle.C
970 }
971 if !maxAge.Stop() {
972 <-maxAge.C
973 }
974 if !keepalive.Stop() {
975 <-keepalive.C
976 }
977 }()
978 for {
979 select {
980 case <-maxIdle.C:
981 t.mu.Lock()
982 idle := t.idle
983 if idle.IsZero() { // The connection is non-idle.
984 t.mu.Unlock()
985 maxIdle.Reset(t.kp.MaxConnectionIdle)
986 continue
987 }
988 val := t.kp.MaxConnectionIdle - time.Since(idle)
989 t.mu.Unlock()
990 if val <= 0 {
991 // The connection has been idle for a duration of keepalive.MaxConnectionIdle or more.
992 // Gracefully close the connection.
993 t.drain(http2.ErrCodeNo, []byte{})
994 // Reseting the timer so that the clean-up doesn't deadlock.
995 maxIdle.Reset(infinity)
996 return
997 }
998 maxIdle.Reset(val)
999 case <-maxAge.C:
1000 t.drain(http2.ErrCodeNo, []byte{})
1001 maxAge.Reset(t.kp.MaxConnectionAgeGrace)
1002 select {
1003 case <-maxAge.C:
1004 // Close the connection after grace period.
1005 t.Close()
1006 // Reseting the timer so that the clean-up doesn't deadlock.
1007 maxAge.Reset(infinity)
1008 case <-t.shutdownChan:
1009 }
1010 return
1011 case <-keepalive.C:
1012 if atomic.CompareAndSwapUint32(&t.activity, 1, 0) {
1013 pingSent = false
1014 keepalive.Reset(t.kp.Time)
1015 continue
1016 }
1017 if pingSent {
1018 t.Close()
1019 // Reseting the timer so that the clean-up doesn't deadlock.
1020 keepalive.Reset(infinity)
1021 return
1022 }
1023 pingSent = true
1024 t.controlBuf.put(p)
1025 keepalive.Reset(t.kp.Timeout)
1026 case <-t.shutdownChan:
1027 return
1028 }
1029 }
1030}
1031
1032var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}}
1033
1034// controller running in a separate goroutine takes charge of sending control
1035// frames (e.g., window update, reset stream, setting, etc.) to the server.
1036func (t *http2Server) controller() {
1037 for {
1038 select {
1039 case i := <-t.controlBuf.get():
1040 t.controlBuf.load()
1041 select {
1042 case <-t.writableChan:
1043 switch i := i.(type) {
1044 case *windowUpdate:
1045 t.framer.writeWindowUpdate(i.flush, i.streamID, i.increment)
1046 case *settings:
1047 if i.ack {
1048 t.framer.writeSettingsAck(true)
1049 t.applySettings(i.ss)
1050 } else {
1051 t.framer.writeSettings(true, i.ss...)
1052 }
1053 case *resetStream:
1054 t.framer.writeRSTStream(true, i.streamID, i.code)
1055 case *goAway:
1056 t.mu.Lock()
1057 if t.state == closing {
1058 t.mu.Unlock()
1059 // The transport is closing.
1060 return
1061 }
1062 sid := t.maxStreamID
1063 if !i.headsUp {
1064 // Stop accepting more streams now.
1065 t.state = draining
1066 t.mu.Unlock()
1067 t.framer.writeGoAway(true, sid, i.code, i.debugData)
1068 if i.closeConn {
1069 // Abruptly close the connection following the GoAway.
1070 t.Close()
1071 }
1072 t.writableChan <- 0
1073 continue
1074 }
1075 t.mu.Unlock()
1076 // For a graceful close, send out a GoAway with stream ID of MaxUInt32,
1077 // Follow that with a ping and wait for the ack to come back or a timer
1078 // to expire. During this time accept new streams since they might have
1079 // originated before the GoAway reaches the client.
1080 // After getting the ack or timer expiration send out another GoAway this
1081 // time with an ID of the max stream server intends to process.
1082 t.framer.writeGoAway(true, math.MaxUint32, http2.ErrCodeNo, []byte{})
1083 t.framer.writePing(true, false, goAwayPing.data)
1084 go func() {
1085 timer := time.NewTimer(time.Minute)
1086 defer timer.Stop()
1087 select {
1088 case <-t.drainChan:
1089 case <-timer.C:
1090 case <-t.shutdownChan:
1091 return
1092 }
1093 t.controlBuf.put(&goAway{code: i.code, debugData: i.debugData})
1094 }()
1095 case *flushIO:
1096 t.framer.flushWrite()
1097 case *ping:
1098 if !i.ack {
1099 t.bdpEst.timesnap(i.data)
1100 }
1101 t.framer.writePing(true, i.ack, i.data)
1102 default:
1103 errorf("transport: http2Server.controller got unexpected item type %v\n", i)
1104 }
1105 t.writableChan <- 0
1106 continue
1107 case <-t.shutdownChan:
1108 return
1109 }
1110 case <-t.shutdownChan:
1111 return
1112 }
1113 }
1114}
1115
1116// Close starts shutting down the http2Server transport.
1117// TODO(zhaoq): Now the destruction is not blocked on any pending streams. This
1118// could cause some resource issue. Revisit this later.
1119func (t *http2Server) Close() (err error) {
1120 t.mu.Lock()
1121 if t.state == closing {
1122 t.mu.Unlock()
1123 return errors.New("transport: Close() was already called")
1124 }
1125 t.state = closing
1126 streams := t.activeStreams
1127 t.activeStreams = nil
1128 t.mu.Unlock()
1129 close(t.shutdownChan)
1130 err = t.conn.Close()
1131 // Cancel all active streams.
1132 for _, s := range streams {
1133 s.cancel()
1134 }
1135 if t.stats != nil {
1136 connEnd := &stats.ConnEnd{}
1137 t.stats.HandleConn(t.ctx, connEnd)
1138 }
1139 return
1140}
1141
1142// closeStream clears the footprint of a stream when the stream is not needed
1143// any more.
1144func (t *http2Server) closeStream(s *Stream) {
1145 t.mu.Lock()
1146 delete(t.activeStreams, s.id)
1147 if len(t.activeStreams) == 0 {
1148 t.idle = time.Now()
1149 }
1150 if t.state == draining && len(t.activeStreams) == 0 {
1151 defer t.Close()
1152 }
1153 t.mu.Unlock()
1154 // In case stream sending and receiving are invoked in separate
1155 // goroutines (e.g., bi-directional streaming), cancel needs to be
1156 // called to interrupt the potential blocking on other goroutines.
1157 s.cancel()
1158 s.mu.Lock()
1159 if s.state == streamDone {
1160 s.mu.Unlock()
1161 return
1162 }
1163 s.state = streamDone
1164 s.mu.Unlock()
1165}
1166
1167func (t *http2Server) RemoteAddr() net.Addr {
1168 return t.remoteAddr
1169}
1170
1171func (t *http2Server) Drain() {
1172 t.drain(http2.ErrCodeNo, []byte{})
1173}
1174
1175func (t *http2Server) drain(code http2.ErrCode, debugData []byte) {
1176 t.mu.Lock()
1177 defer t.mu.Unlock()
1178 if t.drainChan != nil {
1179 return
1180 }
1181 t.drainChan = make(chan struct{})
1182 t.controlBuf.put(&goAway{code: code, debugData: debugData, headsUp: true})
1183}
1184
1185var rgen = rand.New(rand.NewSource(time.Now().UnixNano()))
1186
1187func getJitter(v time.Duration) time.Duration {
1188 if v == infinity {
1189 return 0
1190 }
1191 // Generate a jitter between +/- 10% of the value.
1192 r := int64(v / 10)
1193 j := rgen.Int63n(2*r) - r
1194 return time.Duration(j)
1195}
diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go
new file mode 100644
index 0000000..685c6fb
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/http_util.go
@@ -0,0 +1,597 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19package transport
20
21import (
22 "bufio"
23 "bytes"
24 "encoding/base64"
25 "fmt"
26 "io"
27 "net"
28 "net/http"
29 "strconv"
30 "strings"
31 "sync/atomic"
32 "time"
33
34 "github.com/golang/protobuf/proto"
35 "golang.org/x/net/http2"
36 "golang.org/x/net/http2/hpack"
37 spb "google.golang.org/genproto/googleapis/rpc/status"
38 "google.golang.org/grpc/codes"
39 "google.golang.org/grpc/status"
40)
41
42const (
43 // http2MaxFrameLen specifies the max length of a HTTP2 frame.
44 http2MaxFrameLen = 16384 // 16KB frame
45 // http://http2.github.io/http2-spec/#SettingValues
46 http2InitHeaderTableSize = 4096
47 // http2IOBufSize specifies the buffer size for sending frames.
48 http2IOBufSize = 32 * 1024
49)
50
51var (
52 clientPreface = []byte(http2.ClientPreface)
53 http2ErrConvTab = map[http2.ErrCode]codes.Code{
54 http2.ErrCodeNo: codes.Internal,
55 http2.ErrCodeProtocol: codes.Internal,
56 http2.ErrCodeInternal: codes.Internal,
57 http2.ErrCodeFlowControl: codes.ResourceExhausted,
58 http2.ErrCodeSettingsTimeout: codes.Internal,
59 http2.ErrCodeStreamClosed: codes.Internal,
60 http2.ErrCodeFrameSize: codes.Internal,
61 http2.ErrCodeRefusedStream: codes.Unavailable,
62 http2.ErrCodeCancel: codes.Canceled,
63 http2.ErrCodeCompression: codes.Internal,
64 http2.ErrCodeConnect: codes.Internal,
65 http2.ErrCodeEnhanceYourCalm: codes.ResourceExhausted,
66 http2.ErrCodeInadequateSecurity: codes.PermissionDenied,
67 http2.ErrCodeHTTP11Required: codes.FailedPrecondition,
68 }
69 statusCodeConvTab = map[codes.Code]http2.ErrCode{
70 codes.Internal: http2.ErrCodeInternal,
71 codes.Canceled: http2.ErrCodeCancel,
72 codes.Unavailable: http2.ErrCodeRefusedStream,
73 codes.ResourceExhausted: http2.ErrCodeEnhanceYourCalm,
74 codes.PermissionDenied: http2.ErrCodeInadequateSecurity,
75 }
76 httpStatusConvTab = map[int]codes.Code{
77 // 400 Bad Request - INTERNAL.
78 http.StatusBadRequest: codes.Internal,
79 // 401 Unauthorized - UNAUTHENTICATED.
80 http.StatusUnauthorized: codes.Unauthenticated,
81 // 403 Forbidden - PERMISSION_DENIED.
82 http.StatusForbidden: codes.PermissionDenied,
83 // 404 Not Found - UNIMPLEMENTED.
84 http.StatusNotFound: codes.Unimplemented,
85 // 429 Too Many Requests - UNAVAILABLE.
86 http.StatusTooManyRequests: codes.Unavailable,
87 // 502 Bad Gateway - UNAVAILABLE.
88 http.StatusBadGateway: codes.Unavailable,
89 // 503 Service Unavailable - UNAVAILABLE.
90 http.StatusServiceUnavailable: codes.Unavailable,
91 // 504 Gateway timeout - UNAVAILABLE.
92 http.StatusGatewayTimeout: codes.Unavailable,
93 }
94)
95
96// Records the states during HPACK decoding. Must be reset once the
97// decoding of the entire headers are finished.
98type decodeState struct {
99 encoding string
100 // statusGen caches the stream status received from the trailer the server
101 // sent. Client side only. Do not access directly. After all trailers are
102 // parsed, use the status method to retrieve the status.
103 statusGen *status.Status
104 // rawStatusCode and rawStatusMsg are set from the raw trailer fields and are not
105 // intended for direct access outside of parsing.
106 rawStatusCode *int
107 rawStatusMsg string
108 httpStatus *int
109 // Server side only fields.
110 timeoutSet bool
111 timeout time.Duration
112 method string
113 // key-value metadata map from the peer.
114 mdata map[string][]string
115}
116
117// isReservedHeader checks whether hdr belongs to HTTP2 headers
118// reserved by gRPC protocol. Any other headers are classified as the
119// user-specified metadata.
120func isReservedHeader(hdr string) bool {
121 if hdr != "" && hdr[0] == ':' {
122 return true
123 }
124 switch hdr {
125 case "content-type",
126 "grpc-message-type",
127 "grpc-encoding",
128 "grpc-message",
129 "grpc-status",
130 "grpc-timeout",
131 "grpc-status-details-bin",
132 "te":
133 return true
134 default:
135 return false
136 }
137}
138
139// isWhitelistedPseudoHeader checks whether hdr belongs to HTTP2 pseudoheaders
140// that should be propagated into metadata visible to users.
141func isWhitelistedPseudoHeader(hdr string) bool {
142 switch hdr {
143 case ":authority":
144 return true
145 default:
146 return false
147 }
148}
149
150func validContentType(t string) bool {
151 e := "application/grpc"
152 if !strings.HasPrefix(t, e) {
153 return false
154 }
155 // Support variations on the content-type
156 // (e.g. "application/grpc+blah", "application/grpc;blah").
157 if len(t) > len(e) && t[len(e)] != '+' && t[len(e)] != ';' {
158 return false
159 }
160 return true
161}
162
163func (d *decodeState) status() *status.Status {
164 if d.statusGen == nil {
165 // No status-details were provided; generate status using code/msg.
166 d.statusGen = status.New(codes.Code(int32(*(d.rawStatusCode))), d.rawStatusMsg)
167 }
168 return d.statusGen
169}
170
171const binHdrSuffix = "-bin"
172
173func encodeBinHeader(v []byte) string {
174 return base64.RawStdEncoding.EncodeToString(v)
175}
176
177func decodeBinHeader(v string) ([]byte, error) {
178 if len(v)%4 == 0 {
179 // Input was padded, or padding was not necessary.
180 return base64.StdEncoding.DecodeString(v)
181 }
182 return base64.RawStdEncoding.DecodeString(v)
183}
184
185func encodeMetadataHeader(k, v string) string {
186 if strings.HasSuffix(k, binHdrSuffix) {
187 return encodeBinHeader(([]byte)(v))
188 }
189 return v
190}
191
192func decodeMetadataHeader(k, v string) (string, error) {
193 if strings.HasSuffix(k, binHdrSuffix) {
194 b, err := decodeBinHeader(v)
195 return string(b), err
196 }
197 return v, nil
198}
199
200func (d *decodeState) decodeResponseHeader(frame *http2.MetaHeadersFrame) error {
201 for _, hf := range frame.Fields {
202 if err := d.processHeaderField(hf); err != nil {
203 return err
204 }
205 }
206
207 // If grpc status exists, no need to check further.
208 if d.rawStatusCode != nil || d.statusGen != nil {
209 return nil
210 }
211
212 // If grpc status doesn't exist and http status doesn't exist,
213 // then it's a malformed header.
214 if d.httpStatus == nil {
215 return streamErrorf(codes.Internal, "malformed header: doesn't contain status(gRPC or HTTP)")
216 }
217
218 if *(d.httpStatus) != http.StatusOK {
219 code, ok := httpStatusConvTab[*(d.httpStatus)]
220 if !ok {
221 code = codes.Unknown
222 }
223 return streamErrorf(code, http.StatusText(*(d.httpStatus)))
224 }
225
226 // gRPC status doesn't exist and http status is OK.
227 // Set rawStatusCode to be unknown and return nil error.
228 // So that, if the stream has ended this Unknown status
229 // will be propogated to the user.
230 // Otherwise, it will be ignored. In which case, status from
231 // a later trailer, that has StreamEnded flag set, is propogated.
232 code := int(codes.Unknown)
233 d.rawStatusCode = &code
234 return nil
235
236}
237
238func (d *decodeState) processHeaderField(f hpack.HeaderField) error {
239 switch f.Name {
240 case "content-type":
241 if !validContentType(f.Value) {
242 return streamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value)
243 }
244 case "grpc-encoding":
245 d.encoding = f.Value
246 case "grpc-status":
247 code, err := strconv.Atoi(f.Value)
248 if err != nil {
249 return streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)
250 }
251 d.rawStatusCode = &code
252 case "grpc-message":
253 d.rawStatusMsg = decodeGrpcMessage(f.Value)
254 case "grpc-status-details-bin":
255 v, err := decodeBinHeader(f.Value)
256 if err != nil {
257 return streamErrorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err)
258 }
259 s := &spb.Status{}
260 if err := proto.Unmarshal(v, s); err != nil {
261 return streamErrorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err)
262 }
263 d.statusGen = status.FromProto(s)
264 case "grpc-timeout":
265 d.timeoutSet = true
266 var err error
267 if d.timeout, err = decodeTimeout(f.Value); err != nil {
268 return streamErrorf(codes.Internal, "transport: malformed time-out: %v", err)
269 }
270 case ":path":
271 d.method = f.Value
272 case ":status":
273 code, err := strconv.Atoi(f.Value)
274 if err != nil {
275 return streamErrorf(codes.Internal, "transport: malformed http-status: %v", err)
276 }
277 d.httpStatus = &code
278 default:
279 if !isReservedHeader(f.Name) || isWhitelistedPseudoHeader(f.Name) {
280 if d.mdata == nil {
281 d.mdata = make(map[string][]string)
282 }
283 v, err := decodeMetadataHeader(f.Name, f.Value)
284 if err != nil {
285 errorf("Failed to decode metadata header (%q, %q): %v", f.Name, f.Value, err)
286 return nil
287 }
288 d.mdata[f.Name] = append(d.mdata[f.Name], v)
289 }
290 }
291 return nil
292}
293
294type timeoutUnit uint8
295
296const (
297 hour timeoutUnit = 'H'
298 minute timeoutUnit = 'M'
299 second timeoutUnit = 'S'
300 millisecond timeoutUnit = 'm'
301 microsecond timeoutUnit = 'u'
302 nanosecond timeoutUnit = 'n'
303)
304
305func timeoutUnitToDuration(u timeoutUnit) (d time.Duration, ok bool) {
306 switch u {
307 case hour:
308 return time.Hour, true
309 case minute:
310 return time.Minute, true
311 case second:
312 return time.Second, true
313 case millisecond:
314 return time.Millisecond, true
315 case microsecond:
316 return time.Microsecond, true
317 case nanosecond:
318 return time.Nanosecond, true
319 default:
320 }
321 return
322}
323
324const maxTimeoutValue int64 = 100000000 - 1
325
326// div does integer division and round-up the result. Note that this is
327// equivalent to (d+r-1)/r but has less chance to overflow.
328func div(d, r time.Duration) int64 {
329 if m := d % r; m > 0 {
330 return int64(d/r + 1)
331 }
332 return int64(d / r)
333}
334
335// TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it.
336func encodeTimeout(t time.Duration) string {
337 if t <= 0 {
338 return "0n"
339 }
340 if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
341 return strconv.FormatInt(d, 10) + "n"
342 }
343 if d := div(t, time.Microsecond); d <= maxTimeoutValue {
344 return strconv.FormatInt(d, 10) + "u"
345 }
346 if d := div(t, time.Millisecond); d <= maxTimeoutValue {
347 return strconv.FormatInt(d, 10) + "m"
348 }
349 if d := div(t, time.Second); d <= maxTimeoutValue {
350 return strconv.FormatInt(d, 10) + "S"
351 }
352 if d := div(t, time.Minute); d <= maxTimeoutValue {
353 return strconv.FormatInt(d, 10) + "M"
354 }
355 // Note that maxTimeoutValue * time.Hour > MaxInt64.
356 return strconv.FormatInt(div(t, time.Hour), 10) + "H"
357}
358
359func decodeTimeout(s string) (time.Duration, error) {
360 size := len(s)
361 if size < 2 {
362 return 0, fmt.Errorf("transport: timeout string is too short: %q", s)
363 }
364 unit := timeoutUnit(s[size-1])
365 d, ok := timeoutUnitToDuration(unit)
366 if !ok {
367 return 0, fmt.Errorf("transport: timeout unit is not recognized: %q", s)
368 }
369 t, err := strconv.ParseInt(s[:size-1], 10, 64)
370 if err != nil {
371 return 0, err
372 }
373 return d * time.Duration(t), nil
374}
375
376const (
377 spaceByte = ' '
378 tildaByte = '~'
379 percentByte = '%'
380)
381
382// encodeGrpcMessage is used to encode status code in header field
383// "grpc-message".
384// It checks to see if each individual byte in msg is an
385// allowable byte, and then either percent encoding or passing it through.
386// When percent encoding, the byte is converted into hexadecimal notation
387// with a '%' prepended.
388func encodeGrpcMessage(msg string) string {
389 if msg == "" {
390 return ""
391 }
392 lenMsg := len(msg)
393 for i := 0; i < lenMsg; i++ {
394 c := msg[i]
395 if !(c >= spaceByte && c < tildaByte && c != percentByte) {
396 return encodeGrpcMessageUnchecked(msg)
397 }
398 }
399 return msg
400}
401
402func encodeGrpcMessageUnchecked(msg string) string {
403 var buf bytes.Buffer
404 lenMsg := len(msg)
405 for i := 0; i < lenMsg; i++ {
406 c := msg[i]
407 if c >= spaceByte && c < tildaByte && c != percentByte {
408 buf.WriteByte(c)
409 } else {
410 buf.WriteString(fmt.Sprintf("%%%02X", c))
411 }
412 }
413 return buf.String()
414}
415
416// decodeGrpcMessage decodes the msg encoded by encodeGrpcMessage.
417func decodeGrpcMessage(msg string) string {
418 if msg == "" {
419 return ""
420 }
421 lenMsg := len(msg)
422 for i := 0; i < lenMsg; i++ {
423 if msg[i] == percentByte && i+2 < lenMsg {
424 return decodeGrpcMessageUnchecked(msg)
425 }
426 }
427 return msg
428}
429
430func decodeGrpcMessageUnchecked(msg string) string {
431 var buf bytes.Buffer
432 lenMsg := len(msg)
433 for i := 0; i < lenMsg; i++ {
434 c := msg[i]
435 if c == percentByte && i+2 < lenMsg {
436 parsed, err := strconv.ParseUint(msg[i+1:i+3], 16, 8)
437 if err != nil {
438 buf.WriteByte(c)
439 } else {
440 buf.WriteByte(byte(parsed))
441 i += 2
442 }
443 } else {
444 buf.WriteByte(c)
445 }
446 }
447 return buf.String()
448}
449
450type framer struct {
451 numWriters int32
452 reader io.Reader
453 writer *bufio.Writer
454 fr *http2.Framer
455}
456
457func newFramer(conn net.Conn) *framer {
458 f := &framer{
459 reader: bufio.NewReaderSize(conn, http2IOBufSize),
460 writer: bufio.NewWriterSize(conn, http2IOBufSize),
461 }
462 f.fr = http2.NewFramer(f.writer, f.reader)
463 // Opt-in to Frame reuse API on framer to reduce garbage.
464 // Frames aren't safe to read from after a subsequent call to ReadFrame.
465 f.fr.SetReuseFrames()
466 f.fr.ReadMetaHeaders = hpack.NewDecoder(http2InitHeaderTableSize, nil)
467 return f
468}
469
470func (f *framer) adjustNumWriters(i int32) int32 {
471 return atomic.AddInt32(&f.numWriters, i)
472}
473
474// The following writeXXX functions can only be called when the caller gets
475// unblocked from writableChan channel (i.e., owns the privilege to write).
476
477func (f *framer) writeContinuation(forceFlush bool, streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
478 if err := f.fr.WriteContinuation(streamID, endHeaders, headerBlockFragment); err != nil {
479 return err
480 }
481 if forceFlush {
482 return f.writer.Flush()
483 }
484 return nil
485}
486
487func (f *framer) writeData(forceFlush bool, streamID uint32, endStream bool, data []byte) error {
488 if err := f.fr.WriteData(streamID, endStream, data); err != nil {
489 return err
490 }
491 if forceFlush {
492 return f.writer.Flush()
493 }
494 return nil
495}
496
497func (f *framer) writeGoAway(forceFlush bool, maxStreamID uint32, code http2.ErrCode, debugData []byte) error {
498 if err := f.fr.WriteGoAway(maxStreamID, code, debugData); err != nil {
499 return err
500 }
501 if forceFlush {
502 return f.writer.Flush()
503 }
504 return nil
505}
506
507func (f *framer) writeHeaders(forceFlush bool, p http2.HeadersFrameParam) error {
508 if err := f.fr.WriteHeaders(p); err != nil {
509 return err
510 }
511 if forceFlush {
512 return f.writer.Flush()
513 }
514 return nil
515}
516
517func (f *framer) writePing(forceFlush, ack bool, data [8]byte) error {
518 if err := f.fr.WritePing(ack, data); err != nil {
519 return err
520 }
521 if forceFlush {
522 return f.writer.Flush()
523 }
524 return nil
525}
526
527func (f *framer) writePriority(forceFlush bool, streamID uint32, p http2.PriorityParam) error {
528 if err := f.fr.WritePriority(streamID, p); err != nil {
529 return err
530 }
531 if forceFlush {
532 return f.writer.Flush()
533 }
534 return nil
535}
536
537func (f *framer) writePushPromise(forceFlush bool, p http2.PushPromiseParam) error {
538 if err := f.fr.WritePushPromise(p); err != nil {
539 return err
540 }
541 if forceFlush {
542 return f.writer.Flush()
543 }
544 return nil
545}
546
547func (f *framer) writeRSTStream(forceFlush bool, streamID uint32, code http2.ErrCode) error {
548 if err := f.fr.WriteRSTStream(streamID, code); err != nil {
549 return err
550 }
551 if forceFlush {
552 return f.writer.Flush()
553 }
554 return nil
555}
556
557func (f *framer) writeSettings(forceFlush bool, settings ...http2.Setting) error {
558 if err := f.fr.WriteSettings(settings...); err != nil {
559 return err
560 }
561 if forceFlush {
562 return f.writer.Flush()
563 }
564 return nil
565}
566
567func (f *framer) writeSettingsAck(forceFlush bool) error {
568 if err := f.fr.WriteSettingsAck(); err != nil {
569 return err
570 }
571 if forceFlush {
572 return f.writer.Flush()
573 }
574 return nil
575}
576
577func (f *framer) writeWindowUpdate(forceFlush bool, streamID, incr uint32) error {
578 if err := f.fr.WriteWindowUpdate(streamID, incr); err != nil {
579 return err
580 }
581 if forceFlush {
582 return f.writer.Flush()
583 }
584 return nil
585}
586
587func (f *framer) flushWrite() error {
588 return f.writer.Flush()
589}
590
591func (f *framer) readFrame() (http2.Frame, error) {
592 return f.fr.ReadFrame()
593}
594
595func (f *framer) errorDetail() error {
596 return f.fr.ErrorDetail()
597}
diff --git a/vendor/google.golang.org/grpc/transport/log.go b/vendor/google.golang.org/grpc/transport/log.go
new file mode 100644
index 0000000..ac8e358
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/log.go
@@ -0,0 +1,50 @@
1/*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// This file contains wrappers for grpclog functions.
20// The transport package only logs to verbose level 2 by default.
21
22package transport
23
24import "google.golang.org/grpc/grpclog"
25
26const logLevel = 2
27
28func infof(format string, args ...interface{}) {
29 if grpclog.V(logLevel) {
30 grpclog.Infof(format, args...)
31 }
32}
33
34func warningf(format string, args ...interface{}) {
35 if grpclog.V(logLevel) {
36 grpclog.Warningf(format, args...)
37 }
38}
39
40func errorf(format string, args ...interface{}) {
41 if grpclog.V(logLevel) {
42 grpclog.Errorf(format, args...)
43 }
44}
45
46func fatalf(format string, args ...interface{}) {
47 if grpclog.V(logLevel) {
48 grpclog.Fatalf(format, args...)
49 }
50}
diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go
new file mode 100644
index 0000000..ec0fe67
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/transport.go
@@ -0,0 +1,730 @@
1/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package transport defines and implements message oriented communication
20// channel to complete various transactions (e.g., an RPC).
21package transport // import "google.golang.org/grpc/transport"
22
23import (
24 "fmt"
25 "io"
26 "net"
27 "sync"
28
29 "golang.org/x/net/context"
30 "golang.org/x/net/http2"
31 "google.golang.org/grpc/codes"
32 "google.golang.org/grpc/credentials"
33 "google.golang.org/grpc/keepalive"
34 "google.golang.org/grpc/metadata"
35 "google.golang.org/grpc/stats"
36 "google.golang.org/grpc/status"
37 "google.golang.org/grpc/tap"
38)
39
40// recvMsg represents the received msg from the transport. All transport
41// protocol specific info has been removed.
42type recvMsg struct {
43 data []byte
44 // nil: received some data
45 // io.EOF: stream is completed. data is nil.
46 // other non-nil error: transport failure. data is nil.
47 err error
48}
49
50// recvBuffer is an unbounded channel of recvMsg structs.
51// Note recvBuffer differs from controlBuffer only in that recvBuffer
52// holds a channel of only recvMsg structs instead of objects implementing "item" interface.
53// recvBuffer is written to much more often than
54// controlBuffer and using strict recvMsg structs helps avoid allocation in "recvBuffer.put"
55type recvBuffer struct {
56 c chan recvMsg
57 mu sync.Mutex
58 backlog []recvMsg
59}
60
61func newRecvBuffer() *recvBuffer {
62 b := &recvBuffer{
63 c: make(chan recvMsg, 1),
64 }
65 return b
66}
67
68func (b *recvBuffer) put(r recvMsg) {
69 b.mu.Lock()
70 defer b.mu.Unlock()
71 if len(b.backlog) == 0 {
72 select {
73 case b.c <- r:
74 return
75 default:
76 }
77 }
78 b.backlog = append(b.backlog, r)
79}
80
81func (b *recvBuffer) load() {
82 b.mu.Lock()
83 defer b.mu.Unlock()
84 if len(b.backlog) > 0 {
85 select {
86 case b.c <- b.backlog[0]:
87 b.backlog[0] = recvMsg{}
88 b.backlog = b.backlog[1:]
89 default:
90 }
91 }
92}
93
94// get returns the channel that receives a recvMsg in the buffer.
95//
96// Upon receipt of a recvMsg, the caller should call load to send another
97// recvMsg onto the channel if there is any.
98func (b *recvBuffer) get() <-chan recvMsg {
99 return b.c
100}
101
102// recvBufferReader implements io.Reader interface to read the data from
103// recvBuffer.
104type recvBufferReader struct {
105 ctx context.Context
106 goAway chan struct{}
107 recv *recvBuffer
108 last []byte // Stores the remaining data in the previous calls.
109 err error
110}
111
112// Read reads the next len(p) bytes from last. If last is drained, it tries to
113// read additional data from recv. It blocks if there no additional data available
114// in recv. If Read returns any non-nil error, it will continue to return that error.
115func (r *recvBufferReader) Read(p []byte) (n int, err error) {
116 if r.err != nil {
117 return 0, r.err
118 }
119 n, r.err = r.read(p)
120 return n, r.err
121}
122
123func (r *recvBufferReader) read(p []byte) (n int, err error) {
124 if r.last != nil && len(r.last) > 0 {
125 // Read remaining data left in last call.
126 copied := copy(p, r.last)
127 r.last = r.last[copied:]
128 return copied, nil
129 }
130 select {
131 case <-r.ctx.Done():
132 return 0, ContextErr(r.ctx.Err())
133 case <-r.goAway:
134 return 0, ErrStreamDrain
135 case m := <-r.recv.get():
136 r.recv.load()
137 if m.err != nil {
138 return 0, m.err
139 }
140 copied := copy(p, m.data)
141 r.last = m.data[copied:]
142 return copied, nil
143 }
144}
145
146// All items in an out of a controlBuffer should be the same type.
147type item interface {
148 item()
149}
150
151// controlBuffer is an unbounded channel of item.
152type controlBuffer struct {
153 c chan item
154 mu sync.Mutex
155 backlog []item
156}
157
158func newControlBuffer() *controlBuffer {
159 b := &controlBuffer{
160 c: make(chan item, 1),
161 }
162 return b
163}
164
165func (b *controlBuffer) put(r item) {
166 b.mu.Lock()
167 defer b.mu.Unlock()
168 if len(b.backlog) == 0 {
169 select {
170 case b.c <- r:
171 return
172 default:
173 }
174 }
175 b.backlog = append(b.backlog, r)
176}
177
178func (b *controlBuffer) load() {
179 b.mu.Lock()
180 defer b.mu.Unlock()
181 if len(b.backlog) > 0 {
182 select {
183 case b.c <- b.backlog[0]:
184 b.backlog[0] = nil
185 b.backlog = b.backlog[1:]
186 default:
187 }
188 }
189}
190
191// get returns the channel that receives an item in the buffer.
192//
193// Upon receipt of an item, the caller should call load to send another
194// item onto the channel if there is any.
195func (b *controlBuffer) get() <-chan item {
196 return b.c
197}
198
199type streamState uint8
200
201const (
202 streamActive streamState = iota
203 streamWriteDone // EndStream sent
204 streamReadDone // EndStream received
205 streamDone // the entire stream is finished.
206)
207
208// Stream represents an RPC in the transport layer.
209type Stream struct {
210 id uint32
211 // nil for client side Stream.
212 st ServerTransport
213 // ctx is the associated context of the stream.
214 ctx context.Context
215 // cancel is always nil for client side Stream.
216 cancel context.CancelFunc
217 // done is closed when the final status arrives.
218 done chan struct{}
219 // goAway is closed when the server sent GoAways signal before this stream was initiated.
220 goAway chan struct{}
221 // method records the associated RPC method of the stream.
222 method string
223 recvCompress string
224 sendCompress string
225 buf *recvBuffer
226 trReader io.Reader
227 fc *inFlow
228 recvQuota uint32
229
230 // TODO: Remote this unused variable.
231 // The accumulated inbound quota pending for window update.
232 updateQuota uint32
233
234 // Callback to state application's intentions to read data. This
235 // is used to adjust flow control, if need be.
236 requestRead func(int)
237
238 sendQuotaPool *quotaPool
239 // Close headerChan to indicate the end of reception of header metadata.
240 headerChan chan struct{}
241 // header caches the received header metadata.
242 header metadata.MD
243 // The key-value map of trailer metadata.
244 trailer metadata.MD
245
246 mu sync.RWMutex // guard the following
247 // headerOK becomes true from the first header is about to send.
248 headerOk bool
249 state streamState
250 // true iff headerChan is closed. Used to avoid closing headerChan
251 // multiple times.
252 headerDone bool
253 // the status error received from the server.
254 status *status.Status
255 // rstStream indicates whether a RST_STREAM frame needs to be sent
256 // to the server to signify that this stream is closing.
257 rstStream bool
258 // rstError is the error that needs to be sent along with the RST_STREAM frame.
259 rstError http2.ErrCode
260 // bytesSent and bytesReceived indicates whether any bytes have been sent or
261 // received on this stream.
262 bytesSent bool
263 bytesReceived bool
264}
265
266// RecvCompress returns the compression algorithm applied to the inbound
267// message. It is empty string if there is no compression applied.
268func (s *Stream) RecvCompress() string {
269 return s.recvCompress
270}
271
272// SetSendCompress sets the compression algorithm to the stream.
273func (s *Stream) SetSendCompress(str string) {
274 s.sendCompress = str
275}
276
277// Done returns a chanel which is closed when it receives the final status
278// from the server.
279func (s *Stream) Done() <-chan struct{} {
280 return s.done
281}
282
283// GoAway returns a channel which is closed when the server sent GoAways signal
284// before this stream was initiated.
285func (s *Stream) GoAway() <-chan struct{} {
286 return s.goAway
287}
288
289// Header acquires the key-value pairs of header metadata once it
290// is available. It blocks until i) the metadata is ready or ii) there is no
291// header metadata or iii) the stream is canceled/expired.
292func (s *Stream) Header() (metadata.MD, error) {
293 var err error
294 select {
295 case <-s.ctx.Done():
296 err = ContextErr(s.ctx.Err())
297 case <-s.goAway:
298 err = ErrStreamDrain
299 case <-s.headerChan:
300 return s.header.Copy(), nil
301 }
302 // Even if the stream is closed, header is returned if available.
303 select {
304 case <-s.headerChan:
305 return s.header.Copy(), nil
306 default:
307 }
308 return nil, err
309}
310
311// Trailer returns the cached trailer metedata. Note that if it is not called
312// after the entire stream is done, it could return an empty MD. Client
313// side only.
314func (s *Stream) Trailer() metadata.MD {
315 s.mu.RLock()
316 defer s.mu.RUnlock()
317 return s.trailer.Copy()
318}
319
320// ServerTransport returns the underlying ServerTransport for the stream.
321// The client side stream always returns nil.
322func (s *Stream) ServerTransport() ServerTransport {
323 return s.st
324}
325
326// Context returns the context of the stream.
327func (s *Stream) Context() context.Context {
328 return s.ctx
329}
330
331// Method returns the method for the stream.
332func (s *Stream) Method() string {
333 return s.method
334}
335
336// Status returns the status received from the server.
337func (s *Stream) Status() *status.Status {
338 return s.status
339}
340
341// SetHeader sets the header metadata. This can be called multiple times.
342// Server side only.
343func (s *Stream) SetHeader(md metadata.MD) error {
344 s.mu.Lock()
345 defer s.mu.Unlock()
346 if s.headerOk || s.state == streamDone {
347 return ErrIllegalHeaderWrite
348 }
349 if md.Len() == 0 {
350 return nil
351 }
352 s.header = metadata.Join(s.header, md)
353 return nil
354}
355
356// SetTrailer sets the trailer metadata which will be sent with the RPC status
357// by the server. This can be called multiple times. Server side only.
358func (s *Stream) SetTrailer(md metadata.MD) error {
359 if md.Len() == 0 {
360 return nil
361 }
362 s.mu.Lock()
363 defer s.mu.Unlock()
364 s.trailer = metadata.Join(s.trailer, md)
365 return nil
366}
367
368func (s *Stream) write(m recvMsg) {
369 s.buf.put(m)
370}
371
372// Read reads all p bytes from the wire for this stream.
373func (s *Stream) Read(p []byte) (n int, err error) {
374 // Don't request a read if there was an error earlier
375 if er := s.trReader.(*transportReader).er; er != nil {
376 return 0, er
377 }
378 s.requestRead(len(p))
379 return io.ReadFull(s.trReader, p)
380}
381
382// tranportReader reads all the data available for this Stream from the transport and
383// passes them into the decoder, which converts them into a gRPC message stream.
384// The error is io.EOF when the stream is done or another non-nil error if
385// the stream broke.
386type transportReader struct {
387 reader io.Reader
388 // The handler to control the window update procedure for both this
389 // particular stream and the associated transport.
390 windowHandler func(int)
391 er error
392}
393
394func (t *transportReader) Read(p []byte) (n int, err error) {
395 n, err = t.reader.Read(p)
396 if err != nil {
397 t.er = err
398 return
399 }
400 t.windowHandler(n)
401 return
402}
403
404// finish sets the stream's state and status, and closes the done channel.
405// s.mu must be held by the caller. st must always be non-nil.
406func (s *Stream) finish(st *status.Status) {
407 s.status = st
408 s.state = streamDone
409 close(s.done)
410}
411
412// BytesSent indicates whether any bytes have been sent on this stream.
413func (s *Stream) BytesSent() bool {
414 s.mu.Lock()
415 defer s.mu.Unlock()
416 return s.bytesSent
417}
418
419// BytesReceived indicates whether any bytes have been received on this stream.
420func (s *Stream) BytesReceived() bool {
421 s.mu.Lock()
422 defer s.mu.Unlock()
423 return s.bytesReceived
424}
425
426// GoString is implemented by Stream so context.String() won't
427// race when printing %#v.
428func (s *Stream) GoString() string {
429 return fmt.Sprintf("<stream: %p, %v>", s, s.method)
430}
431
432// The key to save transport.Stream in the context.
433type streamKey struct{}
434
435// newContextWithStream creates a new context from ctx and attaches stream
436// to it.
437func newContextWithStream(ctx context.Context, stream *Stream) context.Context {
438 return context.WithValue(ctx, streamKey{}, stream)
439}
440
441// StreamFromContext returns the stream saved in ctx.
442func StreamFromContext(ctx context.Context) (s *Stream, ok bool) {
443 s, ok = ctx.Value(streamKey{}).(*Stream)
444 return
445}
446
447// state of transport
448type transportState int
449
450const (
451 reachable transportState = iota
452 unreachable
453 closing
454 draining
455)
456
457// ServerConfig consists of all the configurations to establish a server transport.
458type ServerConfig struct {
459 MaxStreams uint32
460 AuthInfo credentials.AuthInfo
461 InTapHandle tap.ServerInHandle
462 StatsHandler stats.Handler
463 KeepaliveParams keepalive.ServerParameters
464 KeepalivePolicy keepalive.EnforcementPolicy
465 InitialWindowSize int32
466 InitialConnWindowSize int32
467}
468
469// NewServerTransport creates a ServerTransport with conn or non-nil error
470// if it fails.
471func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (ServerTransport, error) {
472 return newHTTP2Server(conn, config)
473}
474
475// ConnectOptions covers all relevant options for communicating with the server.
476type ConnectOptions struct {
477 // UserAgent is the application user agent.
478 UserAgent string
479 // Authority is the :authority pseudo-header to use. This field has no effect if
480 // TransportCredentials is set.
481 Authority string
482 // Dialer specifies how to dial a network address.
483 Dialer func(context.Context, string) (net.Conn, error)
484 // FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors.
485 FailOnNonTempDialError bool
486 // PerRPCCredentials stores the PerRPCCredentials required to issue RPCs.
487 PerRPCCredentials []credentials.PerRPCCredentials
488 // TransportCredentials stores the Authenticator required to setup a client connection.
489 TransportCredentials credentials.TransportCredentials
490 // KeepaliveParams stores the keepalive parameters.
491 KeepaliveParams keepalive.ClientParameters
492 // StatsHandler stores the handler for stats.
493 StatsHandler stats.Handler
494 // InitialWindowSize sets the intial window size for a stream.
495 InitialWindowSize int32
496 // InitialConnWindowSize sets the intial window size for a connection.
497 InitialConnWindowSize int32
498}
499
500// TargetInfo contains the information of the target such as network address and metadata.
501type TargetInfo struct {
502 Addr string
503 Metadata interface{}
504}
505
506// NewClientTransport establishes the transport with the required ConnectOptions
507// and returns it to the caller.
508func NewClientTransport(ctx context.Context, target TargetInfo, opts ConnectOptions) (ClientTransport, error) {
509 return newHTTP2Client(ctx, target, opts)
510}
511
512// Options provides additional hints and information for message
513// transmission.
514type Options struct {
515 // Last indicates whether this write is the last piece for
516 // this stream.
517 Last bool
518
519 // Delay is a hint to the transport implementation for whether
520 // the data could be buffered for a batching write. The
521 // Transport implementation may ignore the hint.
522 Delay bool
523}
524
525// CallHdr carries the information of a particular RPC.
526type CallHdr struct {
527 // Host specifies the peer's host.
528 Host string
529
530 // Method specifies the operation to perform.
531 Method string
532
533 // RecvCompress specifies the compression algorithm applied on
534 // inbound messages.
535 RecvCompress string
536
537 // SendCompress specifies the compression algorithm applied on
538 // outbound message.
539 SendCompress string
540
541 // Creds specifies credentials.PerRPCCredentials for a call.
542 Creds credentials.PerRPCCredentials
543
544 // Flush indicates whether a new stream command should be sent
545 // to the peer without waiting for the first data. This is
546 // only a hint.
547 // If it's true, the transport may modify the flush decision
548 // for performance purposes.
549 // If it's false, new stream will never be flushed.
550 Flush bool
551}
552
553// ClientTransport is the common interface for all gRPC client-side transport
554// implementations.
555type ClientTransport interface {
556 // Close tears down this transport. Once it returns, the transport
557 // should not be accessed any more. The caller must make sure this
558 // is called only once.
559 Close() error
560
561 // GracefulClose starts to tear down the transport. It stops accepting
562 // new RPCs and wait the completion of the pending RPCs.
563 GracefulClose() error
564
565 // Write sends the data for the given stream. A nil stream indicates
566 // the write is to be performed on the transport as a whole.
567 Write(s *Stream, data []byte, opts *Options) error
568
569 // NewStream creates a Stream for an RPC.
570 NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error)
571
572 // CloseStream clears the footprint of a stream when the stream is
573 // not needed any more. The err indicates the error incurred when
574 // CloseStream is called. Must be called when a stream is finished
575 // unless the associated transport is closing.
576 CloseStream(stream *Stream, err error)
577
578 // Error returns a channel that is closed when some I/O error
579 // happens. Typically the caller should have a goroutine to monitor
580 // this in order to take action (e.g., close the current transport
581 // and create a new one) in error case. It should not return nil
582 // once the transport is initiated.
583 Error() <-chan struct{}
584
585 // GoAway returns a channel that is closed when ClientTransport
586 // receives the draining signal from the server (e.g., GOAWAY frame in
587 // HTTP/2).
588 GoAway() <-chan struct{}
589
590 // GetGoAwayReason returns the reason why GoAway frame was received.
591 GetGoAwayReason() GoAwayReason
592}
593
594// ServerTransport is the common interface for all gRPC server-side transport
595// implementations.
596//
597// Methods may be called concurrently from multiple goroutines, but
598// Write methods for a given Stream will be called serially.
599type ServerTransport interface {
600 // HandleStreams receives incoming streams using the given handler.
601 HandleStreams(func(*Stream), func(context.Context, string) context.Context)
602
603 // WriteHeader sends the header metadata for the given stream.
604 // WriteHeader may not be called on all streams.
605 WriteHeader(s *Stream, md metadata.MD) error
606
607 // Write sends the data for the given stream.
608 // Write may not be called on all streams.
609 Write(s *Stream, data []byte, opts *Options) error
610
611 // WriteStatus sends the status of a stream to the client. WriteStatus is
612 // the final call made on a stream and always occurs.
613 WriteStatus(s *Stream, st *status.Status) error
614
615 // Close tears down the transport. Once it is called, the transport
616 // should not be accessed any more. All the pending streams and their
617 // handlers will be terminated asynchronously.
618 Close() error
619
620 // RemoteAddr returns the remote network address.
621 RemoteAddr() net.Addr
622
623 // Drain notifies the client this ServerTransport stops accepting new RPCs.
624 Drain()
625}
626
627// streamErrorf creates an StreamError with the specified error code and description.
628func streamErrorf(c codes.Code, format string, a ...interface{}) StreamError {
629 return StreamError{
630 Code: c,
631 Desc: fmt.Sprintf(format, a...),
632 }
633}
634
635// connectionErrorf creates an ConnectionError with the specified error description.
636func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
637 return ConnectionError{
638 Desc: fmt.Sprintf(format, a...),
639 temp: temp,
640 err: e,
641 }
642}
643
644// ConnectionError is an error that results in the termination of the
645// entire connection and the retry of all the active streams.
646type ConnectionError struct {
647 Desc string
648 temp bool
649 err error
650}
651
652func (e ConnectionError) Error() string {
653 return fmt.Sprintf("connection error: desc = %q", e.Desc)
654}
655
656// Temporary indicates if this connection error is temporary or fatal.
657func (e ConnectionError) Temporary() bool {
658 return e.temp
659}
660
661// Origin returns the original error of this connection error.
662func (e ConnectionError) Origin() error {
663 // Never return nil error here.
664 // If the original error is nil, return itself.
665 if e.err == nil {
666 return e
667 }
668 return e.err
669}
670
671var (
672 // ErrConnClosing indicates that the transport is closing.
673 ErrConnClosing = connectionErrorf(true, nil, "transport is closing")
674 // ErrStreamDrain indicates that the stream is rejected by the server because
675 // the server stops accepting new RPCs.
676 ErrStreamDrain = streamErrorf(codes.Unavailable, "the server stops accepting new RPCs")
677)
678
679// TODO: See if we can replace StreamError with status package errors.
680
681// StreamError is an error that only affects one stream within a connection.
682type StreamError struct {
683 Code codes.Code
684 Desc string
685}
686
687func (e StreamError) Error() string {
688 return fmt.Sprintf("stream error: code = %s desc = %q", e.Code, e.Desc)
689}
690
691// wait blocks until it can receive from ctx.Done, closing, or proceed.
692// If it receives from ctx.Done, it returns 0, the StreamError for ctx.Err.
693// If it receives from done, it returns 0, io.EOF if ctx is not done; otherwise
694// it return the StreamError for ctx.Err.
695// If it receives from goAway, it returns 0, ErrStreamDrain.
696// If it receives from closing, it returns 0, ErrConnClosing.
697// If it receives from proceed, it returns the received integer, nil.
698func wait(ctx context.Context, done, goAway, closing <-chan struct{}, proceed <-chan int) (int, error) {
699 select {
700 case <-ctx.Done():
701 return 0, ContextErr(ctx.Err())
702 case <-done:
703 // User cancellation has precedence.
704 select {
705 case <-ctx.Done():
706 return 0, ContextErr(ctx.Err())
707 default:
708 }
709 return 0, io.EOF
710 case <-goAway:
711 return 0, ErrStreamDrain
712 case <-closing:
713 return 0, ErrConnClosing
714 case i := <-proceed:
715 return i, nil
716 }
717}
718
719// GoAwayReason contains the reason for the GoAway frame received.
720type GoAwayReason uint8
721
722const (
723 // Invalid indicates that no GoAway frame is received.
724 Invalid GoAwayReason = 0
725 // NoReason is the default value when GoAway frame is received.
726 NoReason GoAwayReason = 1
727 // TooManyPings indicates that a GoAway frame with ErrCodeEnhanceYourCalm
728 // was recieved and that the debug data said "too_many_pings".
729 TooManyPings GoAwayReason = 2
730)