mirror of https://github.com/grpc/grpc.git
commit
2240a13d76
4103 changed files with 248143 additions and 145081 deletions
@ -1,8 +1,11 @@ |
||||
-Wall |
||||
-Wc++-compat |
||||
-Ithird_party/googletest/include |
||||
-Ithird_party/googletest |
||||
-Iinclude |
||||
-Igens |
||||
-I. |
||||
-Ithird_party/boringssl/include |
||||
-Ithird_party/benchmark/include |
||||
-Ithird_party/zlib |
||||
-Ithird_party/protobuf/src |
||||
|
@ -0,0 +1,6 @@ |
||||
# Auto-generated by the tools/mkowners/mkowners.py tool |
||||
# Uses OWNERS files in different modules throughout the |
||||
# repository as the source of truth for module ownership. |
||||
/**/OWNERS @markdroth @nicolasnoble @ctiller |
||||
/bazel/** @nicolasnoble @dgquintas @ctiller |
||||
/src/core/ext/filters/client_channel/** @markdroth @dgquintas @ctiller |
@ -0,0 +1,31 @@ |
||||
Please answer these questions before submitting your issue. |
||||
|
||||
### Should this be an issue in the gRPC issue tracker? |
||||
|
||||
Create new issues for bugs and feature requests. An issue needs to be actionable. General gRPC discussions and usage questions belong to: |
||||
- [grpc.io mailing list](https://groups.google.com/forum/#!forum/grpc-io) |
||||
- [StackOverflow, with `grpc` tag](http://stackoverflow.com/questions/tagged/grpc) |
||||
|
||||
*Please don't double post your questions in more locations; we are monitoring both channels, and the time spent de-duplicating questions is better spent answering more user questions.* |
||||
|
||||
### What version of gRPC and what language are you using? |
||||
|
||||
|
||||
### What operating system (Linux, Windows, …) and version? |
||||
|
||||
|
||||
### What runtime / compiler are you using (e.g. python version or version of gcc) |
||||
|
||||
|
||||
### What did you do? |
||||
If possible, provide a recipe for reproducing the error. Try being specific and include code snippets if helpful. |
||||
|
||||
### What did you expect to see? |
||||
|
||||
|
||||
### What did you see instead? |
||||
|
||||
Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). |
||||
|
||||
### Anything else we should know about your project / environment? |
||||
|
@ -0,0 +1,74 @@ |
||||
[VARIABLES] |
||||
|
||||
# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection |
||||
# not include "unused_" and "ignored_" by default? |
||||
dummy-variables-rgx=^ignored_|^unused_ |
||||
|
||||
[DESIGN] |
||||
|
||||
# NOTE(nathaniel): Not particularly attached to this value; it just seems to |
||||
# be what works for us at the moment (excepting the dead-code-walking Beta |
||||
# API). |
||||
max-args=6 |
||||
|
||||
[MISCELLANEOUS] |
||||
|
||||
# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and |
||||
# "NOTE(<username or issue link>): ". We do not allow "TODO:", |
||||
# "TODO(<username>):", "FIXME:", or anything else. |
||||
notes=FIXME,XXX |
||||
|
||||
[MESSAGES CONTROL] |
||||
|
||||
disable= |
||||
# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279): |
||||
# Enable cyclic-import after a 1.7-or-later pylint release that |
||||
# recognizes our disable=cyclic-import suppressions. |
||||
cyclic-import, |
||||
# TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the |
||||
# Beta API is removed. |
||||
duplicate-code, |
||||
# TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to |
||||
# understand enum and concurrent.futures; look into this later with the |
||||
# latest pylint version. |
||||
import-error, |
||||
# TODO(https://github.com/grpc/grpc/issues/261): Enable this one. |
||||
# Should take a little configuration but not much. |
||||
invalid-name, |
||||
# TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to |
||||
# work for now? Try with a later pylint? |
||||
locally-disabled, |
||||
# NOTE(nathaniel): We don't write doc strings for most private code |
||||
# elements. |
||||
missing-docstring, |
||||
# NOTE(nathaniel): In numeric comparisons it is better to have the |
||||
# lesser (or lesser-or-equal-to) quantity on the left when the |
||||
# expression is true than it is to worry about which is an identifier |
||||
# and which a literal value. |
||||
misplaced-comparison-constant, |
||||
# NOTE(nathaniel): Our completely abstract interface classes don't have |
||||
# constructors. |
||||
no-init, |
||||
# TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play |
||||
# nicely with some of our code being implemented in Cython. Maybe in a |
||||
# later version? |
||||
no-name-in-module, |
||||
# TODO(https://github.com/grpc/grpc/issues/261): Suppress these where |
||||
# the odd shape of the authentication portion of the API forces them on |
||||
# us and enable everywhere else. |
||||
protected-access, |
||||
# NOTE(nathaniel): Pylint and I will probably never agree on this. |
||||
too-few-public-methods, |
||||
# NOTE(nathaniel): Pylint and I wil probably never agree on this for |
||||
# private classes. For public classes maybe? |
||||
too-many-instance-attributes, |
||||
# NOTE(nathaniel): Some of our modules have a lot of lines... of |
||||
# specification and documentation. Maybe if this were |
||||
# lines-of-code-based we would use it. |
||||
too-many-lines, |
||||
# TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have |
||||
# this one if we extracted just a few more helper functions... |
||||
too-many-nested-blocks, |
||||
# NOTE(nathaniel): I have disputed the premise of this inspection from |
||||
# the beginning and will continue to do so until it goes away for good. |
||||
useless-else-on-loop, |
@ -0,0 +1,30 @@ |
||||
{ |
||||
"version": "0.2.0", |
||||
"configurations": [ |
||||
{ |
||||
"type": "node", |
||||
"request": "launch", |
||||
"name": "Mocha Tests", |
||||
"cwd": "${workspaceRoot}", |
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha", |
||||
"windows": { |
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd" |
||||
}, |
||||
"runtimeArgs": [ |
||||
"-u", |
||||
"tdd", |
||||
"--timeout", |
||||
"999999", |
||||
"--colors", |
||||
"${workspaceRoot}/src/node/test" |
||||
], |
||||
"internalConsoleOptions": "openOnSessionStart" |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"request": "attach", |
||||
"name": "Attach to Process", |
||||
"port": 5858 |
||||
} |
||||
] |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@ |
||||
## Community Code of Conduct |
||||
|
||||
gRPC follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). |
@ -1,28 +1,202 @@ |
||||
Copyright 2015, Google Inc. |
||||
All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
|
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above |
||||
copyright notice, this list of conditions and the following disclaimer |
||||
in the documentation and/or other materials provided with the |
||||
distribution. |
||||
* Neither the name of Google Inc. nor the names of its |
||||
contributors may be used to endorse or promote products derived from |
||||
this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
APPENDIX: How to apply the Apache License to your work. |
||||
|
||||
To apply the Apache License to your work, attach the following |
||||
boilerplate notice, with the fields enclosed by brackets "[]" |
||||
replaced with your own identifying information. (Don't include |
||||
the brackets!) The text should be enclosed in the appropriate |
||||
comment syntax for the file format. We also recommend that a |
||||
file or class name and description of purpose be included on the |
||||
same "printed page" as the copyright notice for easier |
||||
identification within third-party archives. |
||||
|
||||
Copyright [yyyy] [name of copyright owner] |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
|
@ -0,0 +1,13 @@ |
||||
Copyright 2014 gRPC authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
@ -0,0 +1,17 @@ |
||||
# Top level ownership |
||||
|
||||
# nothing listed here until GitHub CODEOWNERS gets better |
||||
# we need: |
||||
# 1. owners to be able to self-approve |
||||
# 2. authors to be able to select approvers |
||||
|
||||
# OWNERS file approvers |
||||
# POLICY: at least three owners are needed before adding any OWNERS |
||||
# REASON: GitHub does not recognize an author as able to give approval |
||||
# for a change; without this policy authors that are owners would |
||||
# be forced to rely on one reviewer, which would consequently |
||||
# lead to a bus factor of one to changes to that code |
||||
@markdroth **/OWNERS |
||||
@nicolasnoble **/OWNERS |
||||
@ctiller **/OWNERS |
||||
|
@ -1,22 +0,0 @@ |
||||
Additional IP Rights Grant (Patents) |
||||
|
||||
"This implementation" means the copyrightable works distributed by |
||||
Google as part of the GRPC project. |
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive, |
||||
no-charge, royalty-free, irrevocable (except as stated in this section) |
||||
patent license to make, have made, use, offer to sell, sell, import, |
||||
transfer and otherwise run, modify and propagate the contents of this |
||||
implementation of GRPC, where such license applies only to those patent |
||||
claims, both currently owned or controlled by Google and acquired in |
||||
the future, licensable by Google that are necessarily infringed by this |
||||
implementation of GRPC. This grant does not include claims that would be |
||||
infringed only as a consequence of further modification of this |
||||
implementation. If you or your agent or exclusive licensee institute or |
||||
order or agree to the institution of patent litigation against any |
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging |
||||
that this implementation of GRPC or any code incorporated within this |
||||
implementation of GRPC constitutes direct or contributory patent |
||||
infringement, or inducement of patent infringement, then any patent |
||||
rights granted to you under this License for this implementation of GRPC |
||||
shall terminate as of the date such litigation is filed. |
@ -0,0 +1,89 @@ |
||||
bind( |
||||
name = "nanopb", |
||||
actual = "//third_party/nanopb", |
||||
) |
||||
|
||||
bind( |
||||
name = "libssl", |
||||
actual = "@boringssl//:ssl", |
||||
) |
||||
|
||||
bind( |
||||
name = "zlib", |
||||
actual = "@submodule_zlib//:z", |
||||
) |
||||
|
||||
bind( |
||||
name = "protobuf", |
||||
actual = "@com_google_protobuf//:protobuf", |
||||
) |
||||
|
||||
bind( |
||||
name = "protobuf_clib", |
||||
actual = "@com_google_protobuf//:protoc_lib", |
||||
) |
||||
|
||||
bind( |
||||
name = "protocol_compiler", |
||||
actual = "@com_google_protobuf//:protoc", |
||||
) |
||||
|
||||
bind( |
||||
name = "cares", |
||||
actual = "@submodule_cares//:ares", |
||||
) |
||||
|
||||
bind( |
||||
name = "gtest", |
||||
actual = "@submodule_gtest//:gtest", |
||||
) |
||||
|
||||
bind( |
||||
name = "benchmark", |
||||
actual = "@submodule_benchmark//:benchmark", |
||||
) |
||||
|
||||
bind( |
||||
name = "gflags", |
||||
actual = "@com_github_gflags_gflags//:gflags", |
||||
) |
||||
|
||||
local_repository( |
||||
name = "boringssl", |
||||
path = "third_party/boringssl-with-bazel", |
||||
) |
||||
|
||||
new_local_repository( |
||||
name = "submodule_zlib", |
||||
build_file = "third_party/zlib.BUILD", |
||||
path = "third_party/zlib", |
||||
) |
||||
|
||||
new_local_repository( |
||||
name = "com_google_protobuf", |
||||
build_file = "third_party/protobuf/BUILD", |
||||
path = "third_party/protobuf", |
||||
) |
||||
|
||||
new_local_repository( |
||||
name = "submodule_gtest", |
||||
build_file = "third_party/gtest.BUILD", |
||||
path = "third_party/googletest", |
||||
) |
||||
|
||||
local_repository( |
||||
name = "com_github_gflags_gflags", |
||||
path = "third_party/gflags", |
||||
) |
||||
|
||||
new_local_repository( |
||||
name = "submodule_benchmark", |
||||
path = "third_party/benchmark", |
||||
build_file = "third_party/benchmark.BUILD", |
||||
) |
||||
|
||||
new_local_repository( |
||||
name = "submodule_cares", |
||||
path = "third_party/cares", |
||||
build_file = "third_party/cares/cares.BUILD", |
||||
) |
@ -0,0 +1,31 @@ |
||||
# Copyright 2017 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
licenses(["notice"]) # Apache v2 |
||||
|
||||
package(default_visibility = ["//:__subpackages__"]) |
||||
|
||||
load(":cc_grpc_library.bzl", "cc_grpc_library") |
||||
|
||||
proto_library( |
||||
name = "well_known_protos_list", |
||||
srcs = ["@com_google_protobuf//:well_known_protos"], |
||||
) |
||||
|
||||
cc_grpc_library( |
||||
name = "well_known_protos", |
||||
srcs = "well_known_protos_list", |
||||
proto_only = True, |
||||
deps = [], |
||||
) |
@ -0,0 +1,5 @@ |
||||
set noparent |
||||
@nicolasnoble |
||||
@dgquintas |
||||
@ctiller |
||||
|
@ -0,0 +1,82 @@ |
||||
"""Generates and compiles C++ grpc stubs from proto_library rules.""" |
||||
|
||||
load("//:bazel/generate_cc.bzl", "generate_cc") |
||||
|
||||
def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mock, use_external = False, **kwargs): |
||||
"""Generates C++ grpc classes from a .proto file. |
||||
|
||||
Assumes the generated classes will be used in cc_api_version = 2. |
||||
|
||||
Arguments: |
||||
name: name of rule. |
||||
srcs: a single proto_library, which wraps the .proto files with services. |
||||
deps: a list of C++ proto_library (or cc_proto_library) which provides |
||||
the compiled code of any message that the services depend on. |
||||
well_known_protos: Should this library additionally depend on well known |
||||
protos |
||||
use_external: When True the grpc deps are prefixed with //external. This |
||||
allows grpc to be used as a dependency in other bazel projects. |
||||
generate_mock: When true GMOCk code for client stub is generated. |
||||
**kwargs: rest of arguments, e.g., compatible_with and visibility. |
||||
""" |
||||
if len(srcs) > 1: |
||||
fail("Only one srcs value supported", "srcs") |
||||
|
||||
proto_target = "_" + name + "_only" |
||||
codegen_target = "_" + name + "_codegen" |
||||
codegen_grpc_target = "_" + name + "_grpc_codegen" |
||||
proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(':') == -1] |
||||
proto_deps += [dep.split(':')[0] + ':' + "_" + dep.split(':')[1] + "_only" for dep in deps if dep.find(':') != -1] |
||||
|
||||
native.proto_library( |
||||
name = proto_target, |
||||
srcs = srcs, |
||||
deps = proto_deps, |
||||
**kwargs |
||||
) |
||||
|
||||
generate_cc( |
||||
name = codegen_target, |
||||
srcs = [proto_target], |
||||
well_known_protos = well_known_protos, |
||||
**kwargs |
||||
) |
||||
|
||||
if not proto_only: |
||||
if use_external: |
||||
# when this file is used by non-grpc projects |
||||
plugin = "//external:grpc_cpp_plugin" |
||||
else: |
||||
plugin = "//:grpc_cpp_plugin" |
||||
|
||||
generate_cc( |
||||
name = codegen_grpc_target, |
||||
srcs = [proto_target], |
||||
plugin = plugin, |
||||
well_known_protos = well_known_protos, |
||||
generate_mock = generate_mock, |
||||
**kwargs |
||||
) |
||||
|
||||
if use_external: |
||||
# when this file is used by non-grpc projects |
||||
grpc_deps = ["//external:grpc++", "//external:grpc++_codegen_proto", |
||||
"//external:protobuf"] |
||||
else: |
||||
grpc_deps = ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"] |
||||
|
||||
native.cc_library( |
||||
name = name, |
||||
srcs = [":" + codegen_grpc_target, ":" + codegen_target], |
||||
hdrs = [":" + codegen_grpc_target, ":" + codegen_target], |
||||
deps = deps + grpc_deps, |
||||
**kwargs |
||||
) |
||||
else: |
||||
native.cc_library( |
||||
name = name, |
||||
srcs = [":" + codegen_target], |
||||
hdrs = [":" + codegen_target], |
||||
deps = deps + ["//external:protobuf"], |
||||
**kwargs |
||||
) |
@ -0,0 +1,98 @@ |
||||
"""Generates C++ grpc stubs from proto_library rules. |
||||
|
||||
This is an internal rule used by cc_grpc_library, and shouldn't be used |
||||
directly. |
||||
""" |
||||
|
||||
def generate_cc_impl(ctx): |
||||
"""Implementation of the generate_cc rule.""" |
||||
protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] |
||||
includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports] |
||||
outs = [] |
||||
# label_len is length of the path from WORKSPACE root to the location of this build file |
||||
label_len = len(ctx.label.package) + 1 |
||||
if ctx.executable.plugin: |
||||
outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos] |
||||
outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos] |
||||
if ctx.attr.generate_mock: |
||||
outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] |
||||
else: |
||||
outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos] |
||||
outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos] |
||||
out_files = [ctx.new_file(out) for out in outs] |
||||
dir_out = str(ctx.genfiles_dir.path) |
||||
|
||||
arguments = [] |
||||
if ctx.executable.plugin: |
||||
arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] |
||||
flags = list(ctx.attr.flags) |
||||
if ctx.attr.generate_mock: |
||||
flags.append("generate_mock_code=true") |
||||
arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] |
||||
additional_input = [ctx.executable.plugin] |
||||
else: |
||||
arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] |
||||
additional_input = [] |
||||
arguments += ["-I{0}={0}".format(include.path) for include in includes] |
||||
arguments += [proto.path for proto in protos] |
||||
|
||||
# create a list of well known proto files if the argument is non-None |
||||
well_known_proto_files = [] |
||||
if ctx.attr.well_known_protos: |
||||
f = ctx.attr.well_known_protos.files.to_list()[0].dirname |
||||
if f != "external/com_google_protobuf/src/google/protobuf": |
||||
print("Error: Only @com_google_protobuf//:well_known_protos is supported") |
||||
else: |
||||
# f points to "external/com_google_protobuf/src/google/protobuf" |
||||
# add -I argument to protoc so it knows where to look for the proto files. |
||||
arguments += ["-I{0}".format(f + "/../..")] |
||||
well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] |
||||
|
||||
ctx.action( |
||||
inputs = protos + includes + additional_input + well_known_proto_files, |
||||
outputs = out_files, |
||||
executable = ctx.executable._protoc, |
||||
arguments = arguments, |
||||
) |
||||
|
||||
return struct(files=set(out_files)) |
||||
|
||||
_generate_cc = rule( |
||||
attrs = { |
||||
"srcs": attr.label_list( |
||||
mandatory = True, |
||||
non_empty = True, |
||||
providers = ["proto"], |
||||
), |
||||
"plugin": attr.label( |
||||
executable = True, |
||||
providers = ["files_to_run"], |
||||
cfg = "host", |
||||
), |
||||
"flags": attr.string_list( |
||||
mandatory = False, |
||||
allow_empty = True, |
||||
), |
||||
"well_known_protos" : attr.label( |
||||
mandatory = False, |
||||
), |
||||
"generate_mock" : attr.bool( |
||||
default = False, |
||||
mandatory = False, |
||||
), |
||||
"_protoc": attr.label( |
||||
default = Label("//external:protocol_compiler"), |
||||
executable = True, |
||||
cfg = "host", |
||||
), |
||||
}, |
||||
# We generate .h files, so we need to output to genfiles. |
||||
output_to_genfiles = True, |
||||
implementation = generate_cc_impl, |
||||
) |
||||
|
||||
def generate_cc(well_known_protos, **kwargs): |
||||
if well_known_protos: |
||||
_generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) |
||||
else: |
||||
_generate_cc(**kwargs) |
@ -0,0 +1,107 @@ |
||||
# Copyright 2016 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
# |
||||
# This is for the gRPC build system. This isn't intended to be used outsite of |
||||
# the BUILD file for gRPC. It contains the mapping for the template system we |
||||
# use to generate other platform's build system files. |
||||
# |
||||
# Please consider that there should be a high bar for additions and changes to |
||||
# this file. |
||||
# Each rule listed must be re-written for Google's internal build system, and |
||||
# each change must be ported from one to the other. |
||||
# |
||||
|
||||
def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], |
||||
external_deps = [], deps = [], standalone = False, |
||||
language = "C++", testonly = False, visibility = None, |
||||
alwayslink = 0): |
||||
copts = [] |
||||
if language.upper() == "C": |
||||
copts = ["-std=c99"] |
||||
native.cc_library( |
||||
name = name, |
||||
srcs = srcs, |
||||
hdrs = hdrs + public_hdrs, |
||||
deps = deps + ["//external:" + dep for dep in external_deps], |
||||
copts = copts, |
||||
visibility = visibility, |
||||
testonly = testonly, |
||||
linkopts = ["-pthread"], |
||||
includes = [ |
||||
"include" |
||||
], |
||||
alwayslink = alwayslink, |
||||
) |
||||
|
||||
def grpc_proto_plugin(name, srcs = [], deps = []): |
||||
native.cc_binary( |
||||
name = name, |
||||
srcs = srcs, |
||||
deps = deps, |
||||
) |
||||
|
||||
load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") |
||||
|
||||
def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = False, |
||||
has_services = True, use_external = False, generate_mock = False): |
||||
cc_grpc_library( |
||||
name = name, |
||||
srcs = srcs, |
||||
deps = deps, |
||||
well_known_protos = well_known_protos, |
||||
proto_only = not has_services, |
||||
use_external = use_external, |
||||
generate_mock = generate_mock, |
||||
) |
||||
|
||||
def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++"): |
||||
copts = [] |
||||
if language.upper() == "C": |
||||
copts = ["-std=c99"] |
||||
native.cc_test( |
||||
name = name, |
||||
srcs = srcs, |
||||
args = args, |
||||
data = data, |
||||
deps = deps + ["//external:" + dep for dep in external_deps], |
||||
copts = copts, |
||||
linkopts = ["-pthread"], |
||||
) |
||||
|
||||
def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []): |
||||
copts = [] |
||||
if language.upper() == "C": |
||||
copts = ["-std=c99"] |
||||
native.cc_binary( |
||||
name = name, |
||||
srcs = srcs, |
||||
args = args, |
||||
data = data, |
||||
testonly = testonly, |
||||
linkshared = linkshared, |
||||
deps = deps + ["//external:" + dep for dep in external_deps], |
||||
copts = copts, |
||||
linkopts = ["-pthread"] + linkopts, |
||||
) |
||||
|
||||
def grpc_generate_one_off_targets(): |
||||
pass |
||||
|
||||
def grpc_sh_test(name, srcs, args = [], data = []): |
||||
native.sh_test( |
||||
name = name, |
||||
srcs = srcs, |
||||
args = args, |
||||
data = data) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,17 @@ |
||||
# Copyright 2017 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
module GrpcBuildConfig |
||||
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-4.dll' |
||||
end |
@ -0,0 +1,16 @@ |
||||
option(gRPC_MSVC_STATIC_RUNTIME "Link with static msvc runtime libraries" OFF) |
||||
|
||||
if(gRPC_MSVC_STATIC_RUNTIME) |
||||
# switch from dynamic to static linking of msvcrt |
||||
foreach(flag_var |
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE |
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO |
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE |
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) |
||||
|
||||
if(${flag_var} MATCHES "/MD") |
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") |
||||
endif(${flag_var} MATCHES "/MD") |
||||
endforeach(flag_var) |
||||
endif() |
||||
|
@ -0,0 +1,779 @@ |
||||
// $Id$ |
||||
// vim:ft=javascript |
||||
|
||||
ARG_WITH("grpc", "grpc support", "no"); |
||||
|
||||
if (PHP_GRPC != "no") { |
||||
|
||||
grpc_source = |
||||
"src\\php\\ext\\grpc\\byte_buffer.c " + |
||||
"src\\php\\ext\\grpc\\call.c " + |
||||
"src\\php\\ext\\grpc\\call_credentials.c " + |
||||
"src\\php\\ext\\grpc\\channel.c " + |
||||
"src\\php\\ext\\grpc\\channel_credentials.c " + |
||||
"src\\php\\ext\\grpc\\completion_queue.c " + |
||||
"src\\php\\ext\\grpc\\php_grpc.c " + |
||||
"src\\php\\ext\\grpc\\server.c " + |
||||
"src\\php\\ext\\grpc\\server_credentials.c " + |
||||
"src\\php\\ext\\grpc\\timeval.c " + |
||||
"src\\core\\lib\\profiling\\basic_timers.c " + |
||||
"src\\core\\lib\\profiling\\stap_timers.c " + |
||||
"src\\core\\lib\\support\\alloc.c " + |
||||
"src\\core\\lib\\support\\arena.c " + |
||||
"src\\core\\lib\\support\\atm.c " + |
||||
"src\\core\\lib\\support\\avl.c " + |
||||
"src\\core\\lib\\support\\backoff.c " + |
||||
"src\\core\\lib\\support\\cmdline.c " + |
||||
"src\\core\\lib\\support\\cpu_iphone.c " + |
||||
"src\\core\\lib\\support\\cpu_linux.c " + |
||||
"src\\core\\lib\\support\\cpu_posix.c " + |
||||
"src\\core\\lib\\support\\cpu_windows.c " + |
||||
"src\\core\\lib\\support\\env_linux.c " + |
||||
"src\\core\\lib\\support\\env_posix.c " + |
||||
"src\\core\\lib\\support\\env_windows.c " + |
||||
"src\\core\\lib\\support\\histogram.c " + |
||||
"src\\core\\lib\\support\\host_port.c " + |
||||
"src\\core\\lib\\support\\log.c " + |
||||
"src\\core\\lib\\support\\log_android.c " + |
||||
"src\\core\\lib\\support\\log_linux.c " + |
||||
"src\\core\\lib\\support\\log_posix.c " + |
||||
"src\\core\\lib\\support\\log_windows.c " + |
||||
"src\\core\\lib\\support\\mpscq.c " + |
||||
"src\\core\\lib\\support\\murmur_hash.c " + |
||||
"src\\core\\lib\\support\\stack_lockfree.c " + |
||||
"src\\core\\lib\\support\\string.c " + |
||||
"src\\core\\lib\\support\\string_posix.c " + |
||||
"src\\core\\lib\\support\\string_util_windows.c " + |
||||
"src\\core\\lib\\support\\string_windows.c " + |
||||
"src\\core\\lib\\support\\subprocess_posix.c " + |
||||
"src\\core\\lib\\support\\subprocess_windows.c " + |
||||
"src\\core\\lib\\support\\sync.c " + |
||||
"src\\core\\lib\\support\\sync_posix.c " + |
||||
"src\\core\\lib\\support\\sync_windows.c " + |
||||
"src\\core\\lib\\support\\thd.c " + |
||||
"src\\core\\lib\\support\\thd_posix.c " + |
||||
"src\\core\\lib\\support\\thd_windows.c " + |
||||
"src\\core\\lib\\support\\time.c " + |
||||
"src\\core\\lib\\support\\time_posix.c " + |
||||
"src\\core\\lib\\support\\time_precise.c " + |
||||
"src\\core\\lib\\support\\time_windows.c " + |
||||
"src\\core\\lib\\support\\tls_pthread.c " + |
||||
"src\\core\\lib\\support\\tmpfile_msys.c " + |
||||
"src\\core\\lib\\support\\tmpfile_posix.c " + |
||||
"src\\core\\lib\\support\\tmpfile_windows.c " + |
||||
"src\\core\\lib\\support\\wrap_memcpy.c " + |
||||
"src\\core\\lib\\surface\\init.c " + |
||||
"src\\core\\lib\\channel\\channel_args.c " + |
||||
"src\\core\\lib\\channel\\channel_stack.c " + |
||||
"src\\core\\lib\\channel\\channel_stack_builder.c " + |
||||
"src\\core\\lib\\channel\\connected_channel.c " + |
||||
"src\\core\\lib\\channel\\handshaker.c " + |
||||
"src\\core\\lib\\channel\\handshaker_factory.c " + |
||||
"src\\core\\lib\\channel\\handshaker_registry.c " + |
||||
"src\\core\\lib\\compression\\compression.c " + |
||||
"src\\core\\lib\\compression\\message_compress.c " + |
||||
"src\\core\\lib\\compression\\stream_compression.c " + |
||||
"src\\core\\lib\\http\\format_request.c " + |
||||
"src\\core\\lib\\http\\httpcli.c " + |
||||
"src\\core\\lib\\http\\parser.c " + |
||||
"src\\core\\lib\\iomgr\\closure.c " + |
||||
"src\\core\\lib\\iomgr\\combiner.c " + |
||||
"src\\core\\lib\\iomgr\\endpoint.c " + |
||||
"src\\core\\lib\\iomgr\\endpoint_pair_posix.c " + |
||||
"src\\core\\lib\\iomgr\\endpoint_pair_uv.c " + |
||||
"src\\core\\lib\\iomgr\\endpoint_pair_windows.c " + |
||||
"src\\core\\lib\\iomgr\\error.c " + |
||||
"src\\core\\lib\\iomgr\\ev_epoll1_linux.c " + |
||||
"src\\core\\lib\\iomgr\\ev_epoll_limited_pollers_linux.c " + |
||||
"src\\core\\lib\\iomgr\\ev_epoll_thread_pool_linux.c " + |
||||
"src\\core\\lib\\iomgr\\ev_epollex_linux.c " + |
||||
"src\\core\\lib\\iomgr\\ev_epollsig_linux.c " + |
||||
"src\\core\\lib\\iomgr\\ev_poll_posix.c " + |
||||
"src\\core\\lib\\iomgr\\ev_posix.c " + |
||||
"src\\core\\lib\\iomgr\\ev_windows.c " + |
||||
"src\\core\\lib\\iomgr\\exec_ctx.c " + |
||||
"src\\core\\lib\\iomgr\\executor.c " + |
||||
"src\\core\\lib\\iomgr\\iocp_windows.c " + |
||||
"src\\core\\lib\\iomgr\\iomgr.c " + |
||||
"src\\core\\lib\\iomgr\\iomgr_posix.c " + |
||||
"src\\core\\lib\\iomgr\\iomgr_uv.c " + |
||||
"src\\core\\lib\\iomgr\\iomgr_windows.c " + |
||||
"src\\core\\lib\\iomgr\\is_epollexclusive_available.c " + |
||||
"src\\core\\lib\\iomgr\\load_file.c " + |
||||
"src\\core\\lib\\iomgr\\lockfree_event.c " + |
||||
"src\\core\\lib\\iomgr\\network_status_tracker.c " + |
||||
"src\\core\\lib\\iomgr\\polling_entity.c " + |
||||
"src\\core\\lib\\iomgr\\pollset_set_uv.c " + |
||||
"src\\core\\lib\\iomgr\\pollset_set_windows.c " + |
||||
"src\\core\\lib\\iomgr\\pollset_uv.c " + |
||||
"src\\core\\lib\\iomgr\\pollset_windows.c " + |
||||
"src\\core\\lib\\iomgr\\resolve_address_posix.c " + |
||||
"src\\core\\lib\\iomgr\\resolve_address_uv.c " + |
||||
"src\\core\\lib\\iomgr\\resolve_address_windows.c " + |
||||
"src\\core\\lib\\iomgr\\resource_quota.c " + |
||||
"src\\core\\lib\\iomgr\\sockaddr_utils.c " + |
||||
"src\\core\\lib\\iomgr\\socket_factory_posix.c " + |
||||
"src\\core\\lib\\iomgr\\socket_mutator.c " + |
||||
"src\\core\\lib\\iomgr\\socket_utils_common_posix.c " + |
||||
"src\\core\\lib\\iomgr\\socket_utils_linux.c " + |
||||
"src\\core\\lib\\iomgr\\socket_utils_posix.c " + |
||||
"src\\core\\lib\\iomgr\\socket_utils_uv.c " + |
||||
"src\\core\\lib\\iomgr\\socket_utils_windows.c " + |
||||
"src\\core\\lib\\iomgr\\socket_windows.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_client_posix.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_client_uv.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_client_windows.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_posix.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_server_posix.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_server_utils_posix_common.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_server_utils_posix_ifaddrs.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_server_utils_posix_noifaddrs.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_server_uv.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_server_windows.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_uv.c " + |
||||
"src\\core\\lib\\iomgr\\tcp_windows.c " + |
||||
"src\\core\\lib\\iomgr\\time_averaged_stats.c " + |
||||
"src\\core\\lib\\iomgr\\timer_generic.c " + |
||||
"src\\core\\lib\\iomgr\\timer_heap.c " + |
||||
"src\\core\\lib\\iomgr\\timer_manager.c " + |
||||
"src\\core\\lib\\iomgr\\timer_uv.c " + |
||||
"src\\core\\lib\\iomgr\\udp_server.c " + |
||||
"src\\core\\lib\\iomgr\\unix_sockets_posix.c " + |
||||
"src\\core\\lib\\iomgr\\unix_sockets_posix_noop.c " + |
||||
"src\\core\\lib\\iomgr\\wakeup_fd_cv.c " + |
||||
"src\\core\\lib\\iomgr\\wakeup_fd_eventfd.c " + |
||||
"src\\core\\lib\\iomgr\\wakeup_fd_nospecial.c " + |
||||
"src\\core\\lib\\iomgr\\wakeup_fd_pipe.c " + |
||||
"src\\core\\lib\\iomgr\\wakeup_fd_posix.c " + |
||||
"src\\core\\lib\\json\\json.c " + |
||||
"src\\core\\lib\\json\\json_reader.c " + |
||||
"src\\core\\lib\\json\\json_string.c " + |
||||
"src\\core\\lib\\json\\json_writer.c " + |
||||
"src\\core\\lib\\slice\\b64.c " + |
||||
"src\\core\\lib\\slice\\percent_encoding.c " + |
||||
"src\\core\\lib\\slice\\slice.c " + |
||||
"src\\core\\lib\\slice\\slice_buffer.c " + |
||||
"src\\core\\lib\\slice\\slice_hash_table.c " + |
||||
"src\\core\\lib\\slice\\slice_intern.c " + |
||||
"src\\core\\lib\\slice\\slice_string_helpers.c " + |
||||
"src\\core\\lib\\surface\\alarm.c " + |
||||
"src\\core\\lib\\surface\\api_trace.c " + |
||||
"src\\core\\lib\\surface\\byte_buffer.c " + |
||||
"src\\core\\lib\\surface\\byte_buffer_reader.c " + |
||||
"src\\core\\lib\\surface\\call.c " + |
||||
"src\\core\\lib\\surface\\call_details.c " + |
||||
"src\\core\\lib\\surface\\call_log_batch.c " + |
||||
"src\\core\\lib\\surface\\channel.c " + |
||||
"src\\core\\lib\\surface\\channel_init.c " + |
||||
"src\\core\\lib\\surface\\channel_ping.c " + |
||||
"src\\core\\lib\\surface\\channel_stack_type.c " + |
||||
"src\\core\\lib\\surface\\completion_queue.c " + |
||||
"src\\core\\lib\\surface\\completion_queue_factory.c " + |
||||
"src\\core\\lib\\surface\\event_string.c " + |
||||
"src\\core\\lib\\surface\\lame_client.cc " + |
||||
"src\\core\\lib\\surface\\metadata_array.c " + |
||||
"src\\core\\lib\\surface\\server.c " + |
||||
"src\\core\\lib\\surface\\validate_metadata.c " + |
||||
"src\\core\\lib\\surface\\version.c " + |
||||
"src\\core\\lib\\transport\\bdp_estimator.c " + |
||||
"src\\core\\lib\\transport\\byte_stream.c " + |
||||
"src\\core\\lib\\transport\\connectivity_state.c " + |
||||
"src\\core\\lib\\transport\\error_utils.c " + |
||||
"src\\core\\lib\\transport\\metadata.c " + |
||||
"src\\core\\lib\\transport\\metadata_batch.c " + |
||||
"src\\core\\lib\\transport\\pid_controller.c " + |
||||
"src\\core\\lib\\transport\\service_config.c " + |
||||
"src\\core\\lib\\transport\\static_metadata.c " + |
||||
"src\\core\\lib\\transport\\status_conversion.c " + |
||||
"src\\core\\lib\\transport\\timeout_encoding.c " + |
||||
"src\\core\\lib\\transport\\transport.c " + |
||||
"src\\core\\lib\\transport\\transport_op_string.c " + |
||||
"src\\core\\lib\\debug\\trace.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\server\\secure\\server_secure_chttp2.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\bin_decoder.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_plugin.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_transport.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\flow_control.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\frame_data.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\frame_goaway.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\frame_ping.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\frame_rst_stream.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\frame_settings.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\frame_window_update.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_encoder.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_parser.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_table.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\http2_settings.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\huffsyms.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\incoming_metadata.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\parsing.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\stream_lists.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\stream_map.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\varint.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\transport\\writing.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\alpn\\alpn.c " + |
||||
"src\\core\\ext\\filters\\http\\client\\http_client_filter.c " + |
||||
"src\\core\\ext\\filters\\http\\http_filters_plugin.c " + |
||||
"src\\core\\ext\\filters\\http\\message_compress\\message_compress_filter.c " + |
||||
"src\\core\\ext\\filters\\http\\server\\http_server_filter.c " + |
||||
"src\\core\\lib\\http\\httpcli_security_connector.c " + |
||||
"src\\core\\lib\\security\\context\\security_context.c " + |
||||
"src\\core\\lib\\security\\credentials\\composite\\composite_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\credentials_metadata.c " + |
||||
"src\\core\\lib\\security\\credentials\\fake\\fake_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\google_default\\credentials_generic.c " + |
||||
"src\\core\\lib\\security\\credentials\\google_default\\google_default_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\iam\\iam_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\jwt\\json_token.c " + |
||||
"src\\core\\lib\\security\\credentials\\jwt\\jwt_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\jwt\\jwt_verifier.c " + |
||||
"src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.c " + |
||||
"src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.c " + |
||||
"src\\core\\lib\\security\\transport\\client_auth_filter.c " + |
||||
"src\\core\\lib\\security\\transport\\lb_targets_info.c " + |
||||
"src\\core\\lib\\security\\transport\\secure_endpoint.c " + |
||||
"src\\core\\lib\\security\\transport\\security_connector.c " + |
||||
"src\\core\\lib\\security\\transport\\security_handshaker.c " + |
||||
"src\\core\\lib\\security\\transport\\server_auth_filter.c " + |
||||
"src\\core\\lib\\security\\transport\\tsi_error.c " + |
||||
"src\\core\\lib\\security\\util\\json_util.c " + |
||||
"src\\core\\lib\\surface\\init_secure.c " + |
||||
"src\\core\\tsi\\fake_transport_security.c " + |
||||
"src\\core\\tsi\\gts_transport_security.c " + |
||||
"src\\core\\tsi\\ssl_transport_security.c " + |
||||
"src\\core\\tsi\\transport_security.c " + |
||||
"src\\core\\tsi\\transport_security_adapter.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\server\\chttp2_server.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\client\\secure\\secure_channel_create.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\channel_connectivity.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\client_channel.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\client_channel_factory.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\client_channel_plugin.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\connector.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\http_proxy.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy_factory.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\parse_address.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\proxy_mapper.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver_factory.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver_registry.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\retry_throttle.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\subchannel.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\subchannel_index.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\uri_parser.c " + |
||||
"src\\core\\ext\\filters\\deadline\\deadline_filter.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\client\\chttp2_connector.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\server\\insecure\\server_chttp2.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\server\\insecure\\server_chttp2_posix.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create.c " + |
||||
"src\\core\\ext\\transport\\chttp2\\client\\insecure\\channel_create_posix.c " + |
||||
"src\\core\\ext\\transport\\inproc\\inproc_plugin.c " + |
||||
"src\\core\\ext\\transport\\inproc\\inproc_transport.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\client_load_reporting_filter.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_channel_secure.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_client_stats.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\load_balancer_api.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\load_balancer.pb.c " + |
||||
"third_party\\nanopb\\pb_common.c " + |
||||
"third_party\\nanopb\\pb_decode.c " + |
||||
"third_party\\nanopb\\pb_encode.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.c " + |
||||
"src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.c " + |
||||
"src\\core\\ext\\filters\\load_reporting\\load_reporting.c " + |
||||
"src\\core\\ext\\filters\\load_reporting\\load_reporting_filter.c " + |
||||
"src\\core\\ext\\census\\base_resources.c " + |
||||
"src\\core\\ext\\census\\context.c " + |
||||
"src\\core\\ext\\census\\gen\\census.pb.c " + |
||||
"src\\core\\ext\\census\\gen\\trace_context.pb.c " + |
||||
"src\\core\\ext\\census\\grpc_context.c " + |
||||
"src\\core\\ext\\census\\grpc_filter.c " + |
||||
"src\\core\\ext\\census\\grpc_plugin.c " + |
||||
"src\\core\\ext\\census\\initialize.c " + |
||||
"src\\core\\ext\\census\\intrusive_hash_map.c " + |
||||
"src\\core\\ext\\census\\mlog.c " + |
||||
"src\\core\\ext\\census\\operation.c " + |
||||
"src\\core\\ext\\census\\placeholders.c " + |
||||
"src\\core\\ext\\census\\resource.c " + |
||||
"src\\core\\ext\\census\\trace_context.c " + |
||||
"src\\core\\ext\\census\\tracing.c " + |
||||
"src\\core\\ext\\filters\\max_age\\max_age_filter.c " + |
||||
"src\\core\\ext\\filters\\message_size\\message_size_filter.c " + |
||||
"src\\core\\ext\\filters\\workarounds\\workaround_cronet_compression_filter.c " + |
||||
"src\\core\\ext\\filters\\workarounds\\workaround_utils.c " + |
||||
"src\\core\\plugin_registry\\grpc_plugin_registry.c " + |
||||
"src\\boringssl\\err_data.c " + |
||||
"third_party\\boringssl\\crypto\\aes\\aes.c " + |
||||
"third_party\\boringssl\\crypto\\aes\\key_wrap.c " + |
||||
"third_party\\boringssl\\crypto\\aes\\mode_wrappers.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_bitstr.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_bool.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_d2i_fp.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_dup.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_enum.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_gentm.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_i2d_fp.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_int.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_mbstr.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_object.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_octet.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_print.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_strnid.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_time.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_type.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_utctm.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\a_utf8.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\asn1_lib.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\asn1_par.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\asn_pack.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\f_enum.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\f_int.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\f_string.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\t_bitst.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\tasn_dec.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\tasn_enc.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\tasn_fre.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\tasn_new.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\tasn_typ.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\tasn_utl.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\time_support.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\x_bignum.c " + |
||||
"third_party\\boringssl\\crypto\\asn1\\x_long.c " + |
||||
"third_party\\boringssl\\crypto\\base64\\base64.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\bio.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\bio_mem.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\connect.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\fd.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\file.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\hexdump.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\pair.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\printf.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\socket.c " + |
||||
"third_party\\boringssl\\crypto\\bio\\socket_helper.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\add.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\asm\\x86_64-gcc.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\bn.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\bn_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\cmp.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\convert.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\ctx.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\div.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\exponentiation.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\gcd.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\generic.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\kronecker.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\montgomery.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\montgomery_inv.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\mul.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\prime.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\random.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\rsaz_exp.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\shift.c " + |
||||
"third_party\\boringssl\\crypto\\bn\\sqrt.c " + |
||||
"third_party\\boringssl\\crypto\\buf\\buf.c " + |
||||
"third_party\\boringssl\\crypto\\bytestring\\asn1_compat.c " + |
||||
"third_party\\boringssl\\crypto\\bytestring\\ber.c " + |
||||
"third_party\\boringssl\\crypto\\bytestring\\cbb.c " + |
||||
"third_party\\boringssl\\crypto\\bytestring\\cbs.c " + |
||||
"third_party\\boringssl\\crypto\\chacha\\chacha.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\aead.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\cipher.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\derive_key.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_aes.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_chacha20poly1305.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_des.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_null.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_rc2.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_rc4.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_ssl3.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\e_tls.c " + |
||||
"third_party\\boringssl\\crypto\\cipher\\tls_cbc.c " + |
||||
"third_party\\boringssl\\crypto\\cmac\\cmac.c " + |
||||
"third_party\\boringssl\\crypto\\conf\\conf.c " + |
||||
"third_party\\boringssl\\crypto\\cpu-aarch64-linux.c " + |
||||
"third_party\\boringssl\\crypto\\cpu-arm-linux.c " + |
||||
"third_party\\boringssl\\crypto\\cpu-arm.c " + |
||||
"third_party\\boringssl\\crypto\\cpu-intel.c " + |
||||
"third_party\\boringssl\\crypto\\cpu-ppc64le.c " + |
||||
"third_party\\boringssl\\crypto\\crypto.c " + |
||||
"third_party\\boringssl\\crypto\\curve25519\\curve25519.c " + |
||||
"third_party\\boringssl\\crypto\\curve25519\\spake25519.c " + |
||||
"third_party\\boringssl\\crypto\\curve25519\\x25519-x86_64.c " + |
||||
"third_party\\boringssl\\crypto\\des\\des.c " + |
||||
"third_party\\boringssl\\crypto\\dh\\check.c " + |
||||
"third_party\\boringssl\\crypto\\dh\\dh.c " + |
||||
"third_party\\boringssl\\crypto\\dh\\dh_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\dh\\params.c " + |
||||
"third_party\\boringssl\\crypto\\digest\\digest.c " + |
||||
"third_party\\boringssl\\crypto\\digest\\digests.c " + |
||||
"third_party\\boringssl\\crypto\\dsa\\dsa.c " + |
||||
"third_party\\boringssl\\crypto\\dsa\\dsa_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\ec.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\ec_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\ec_key.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\ec_montgomery.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\oct.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\p224-64.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\p256-64.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\p256-x86_64.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\simple.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\util-64.c " + |
||||
"third_party\\boringssl\\crypto\\ec\\wnaf.c " + |
||||
"third_party\\boringssl\\crypto\\ecdh\\ecdh.c " + |
||||
"third_party\\boringssl\\crypto\\ecdsa\\ecdsa.c " + |
||||
"third_party\\boringssl\\crypto\\ecdsa\\ecdsa_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\engine\\engine.c " + |
||||
"third_party\\boringssl\\crypto\\err\\err.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\digestsign.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\evp.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\evp_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\evp_ctx.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\p_dsa_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\p_ec.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\p_ec_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\p_rsa.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\p_rsa_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\pbkdf.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\print.c " + |
||||
"third_party\\boringssl\\crypto\\evp\\sign.c " + |
||||
"third_party\\boringssl\\crypto\\ex_data.c " + |
||||
"third_party\\boringssl\\crypto\\hkdf\\hkdf.c " + |
||||
"third_party\\boringssl\\crypto\\hmac\\hmac.c " + |
||||
"third_party\\boringssl\\crypto\\lhash\\lhash.c " + |
||||
"third_party\\boringssl\\crypto\\md4\\md4.c " + |
||||
"third_party\\boringssl\\crypto\\md5\\md5.c " + |
||||
"third_party\\boringssl\\crypto\\mem.c " + |
||||
"third_party\\boringssl\\crypto\\modes\\cbc.c " + |
||||
"third_party\\boringssl\\crypto\\modes\\cfb.c " + |
||||
"third_party\\boringssl\\crypto\\modes\\ctr.c " + |
||||
"third_party\\boringssl\\crypto\\modes\\gcm.c " + |
||||
"third_party\\boringssl\\crypto\\modes\\ofb.c " + |
||||
"third_party\\boringssl\\crypto\\modes\\polyval.c " + |
||||
"third_party\\boringssl\\crypto\\obj\\obj.c " + |
||||
"third_party\\boringssl\\crypto\\obj\\obj_xref.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_all.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_info.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_lib.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_oth.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_pk8.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_pkey.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_x509.c " + |
||||
"third_party\\boringssl\\crypto\\pem\\pem_xaux.c " + |
||||
"third_party\\boringssl\\crypto\\pkcs8\\p5_pbev2.c " + |
||||
"third_party\\boringssl\\crypto\\pkcs8\\p8_pkey.c " + |
||||
"third_party\\boringssl\\crypto\\pkcs8\\pkcs8.c " + |
||||
"third_party\\boringssl\\crypto\\poly1305\\poly1305.c " + |
||||
"third_party\\boringssl\\crypto\\poly1305\\poly1305_arm.c " + |
||||
"third_party\\boringssl\\crypto\\poly1305\\poly1305_vec.c " + |
||||
"third_party\\boringssl\\crypto\\pool\\pool.c " + |
||||
"third_party\\boringssl\\crypto\\rand\\deterministic.c " + |
||||
"third_party\\boringssl\\crypto\\rand\\fuchsia.c " + |
||||
"third_party\\boringssl\\crypto\\rand\\rand.c " + |
||||
"third_party\\boringssl\\crypto\\rand\\urandom.c " + |
||||
"third_party\\boringssl\\crypto\\rand\\windows.c " + |
||||
"third_party\\boringssl\\crypto\\rc4\\rc4.c " + |
||||
"third_party\\boringssl\\crypto\\refcount_c11.c " + |
||||
"third_party\\boringssl\\crypto\\refcount_lock.c " + |
||||
"third_party\\boringssl\\crypto\\rsa\\blinding.c " + |
||||
"third_party\\boringssl\\crypto\\rsa\\padding.c " + |
||||
"third_party\\boringssl\\crypto\\rsa\\rsa.c " + |
||||
"third_party\\boringssl\\crypto\\rsa\\rsa_asn1.c " + |
||||
"third_party\\boringssl\\crypto\\rsa\\rsa_impl.c " + |
||||
"third_party\\boringssl\\crypto\\sha\\sha1-altivec.c " + |
||||
"third_party\\boringssl\\crypto\\sha\\sha1.c " + |
||||
"third_party\\boringssl\\crypto\\sha\\sha256.c " + |
||||
"third_party\\boringssl\\crypto\\sha\\sha512.c " + |
||||
"third_party\\boringssl\\crypto\\stack\\stack.c " + |
||||
"third_party\\boringssl\\crypto\\thread.c " + |
||||
"third_party\\boringssl\\crypto\\thread_none.c " + |
||||
"third_party\\boringssl\\crypto\\thread_pthread.c " + |
||||
"third_party\\boringssl\\crypto\\thread_win.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\a_digest.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\a_sign.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\a_strex.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\a_verify.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\algorithm.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\asn1_gen.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\by_dir.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\by_file.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\i2d_pr.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\pkcs7.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\rsa_pss.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\t_crl.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\t_req.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\t_x509.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\t_x509a.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_att.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_cmp.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_d2.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_def.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_ext.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_lu.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_obj.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_r2x.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_req.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_set.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_trs.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_txt.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_v3.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_vfy.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509_vpm.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509cset.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509name.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509rset.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509spki.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x509type.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_algor.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_all.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_attrib.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_crl.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_exten.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_info.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_name.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_pkey.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_pubkey.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_req.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_sig.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_spki.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_val.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_x509.c " + |
||||
"third_party\\boringssl\\crypto\\x509\\x_x509a.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\pcy_cache.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\pcy_data.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\pcy_lib.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\pcy_map.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\pcy_node.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\pcy_tree.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_akey.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_akeya.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_alt.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_bcons.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_bitst.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_conf.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_cpols.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_crld.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_enum.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_extku.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_genn.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_ia5.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_info.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_int.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_lib.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_ncons.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_pci.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_pcia.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_pcons.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_pku.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_pmaps.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_prn.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_purp.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_skey.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_sxnet.c " + |
||||
"third_party\\boringssl\\crypto\\x509v3\\v3_utl.c " + |
||||
"third_party\\boringssl\\ssl\\bio_ssl.c " + |
||||
"third_party\\boringssl\\ssl\\custom_extensions.c " + |
||||
"third_party\\boringssl\\ssl\\d1_both.c " + |
||||
"third_party\\boringssl\\ssl\\d1_lib.c " + |
||||
"third_party\\boringssl\\ssl\\d1_pkt.c " + |
||||
"third_party\\boringssl\\ssl\\d1_srtp.c " + |
||||
"third_party\\boringssl\\ssl\\dtls_method.c " + |
||||
"third_party\\boringssl\\ssl\\dtls_record.c " + |
||||
"third_party\\boringssl\\ssl\\handshake_client.c " + |
||||
"third_party\\boringssl\\ssl\\handshake_server.c " + |
||||
"third_party\\boringssl\\ssl\\s3_both.c " + |
||||
"third_party\\boringssl\\ssl\\s3_lib.c " + |
||||
"third_party\\boringssl\\ssl\\s3_pkt.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_aead_ctx.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_asn1.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_buffer.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_cert.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_cipher.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_ecdh.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_file.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_lib.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_privkey.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_privkey_cc.cc " + |
||||
"third_party\\boringssl\\ssl\\ssl_session.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_stat.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_transcript.c " + |
||||
"third_party\\boringssl\\ssl\\ssl_x509.c " + |
||||
"third_party\\boringssl\\ssl\\t1_enc.c " + |
||||
"third_party\\boringssl\\ssl\\t1_lib.c " + |
||||
"third_party\\boringssl\\ssl\\tls13_both.c " + |
||||
"third_party\\boringssl\\ssl\\tls13_client.c " + |
||||
"third_party\\boringssl\\ssl\\tls13_enc.c " + |
||||
"third_party\\boringssl\\ssl\\tls13_server.c " + |
||||
"third_party\\boringssl\\ssl\\tls_method.c " + |
||||
"third_party\\boringssl\\ssl\\tls_record.c " + |
||||
"third_party\\zlib\\adler32.c " + |
||||
"third_party\\zlib\\compress.c " + |
||||
"third_party\\zlib\\crc32.c " + |
||||
"third_party\\zlib\\deflate.c " + |
||||
"third_party\\zlib\\gzclose.c " + |
||||
"third_party\\zlib\\gzlib.c " + |
||||
"third_party\\zlib\\gzread.c " + |
||||
"third_party\\zlib\\gzwrite.c " + |
||||
"third_party\\zlib\\infback.c " + |
||||
"third_party\\zlib\\inffast.c " + |
||||
"third_party\\zlib\\inflate.c " + |
||||
"third_party\\zlib\\inftrees.c " + |
||||
"third_party\\zlib\\trees.c " + |
||||
"third_party\\zlib\\uncompr.c " + |
||||
"third_party\\zlib\\zutil.c " + |
||||
""; |
||||
|
||||
EXTENSION("grpc", grpc_source, null, |
||||
"/DOPENSSL_NO_ASM /D_GNU_SOURCE /DWIN32_LEAN_AND_MEAN "+ |
||||
"/D_HAS_EXCEPTIONS=0 /DNOMINMAX /DGRPC_ARES=0 /D_WIN32_WINNT=0x600 "+ |
||||
"/I"+configure_module_dirname+" "+ |
||||
"/I"+configure_module_dirname+"\\include "+ |
||||
"/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+ |
||||
"/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+ |
||||
"/I"+configure_module_dirname+"\\third_party\\zlib"); |
||||
|
||||
base_dir = get_define('BUILD_DIR'); |
||||
FSO.CreateFolder(base_dir+"\\ext"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\boringssl"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census\\gen"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\fake"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\deadline"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\client"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\message_compress"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\server"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\load_reporting"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\max_age"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\message_size"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\workarounds"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\alpn"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client\\insecure"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client\\secure"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server\\insecure"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server\\secure"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\transport"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\inproc"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\channel"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\compression"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\debug"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\context"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\composite"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\fake"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\google_default"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\iam"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\jwt"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\support"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\surface"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\transport"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\plugin_registry"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext\\grpc"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\aes"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\asn1"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\base64"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bio"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bn"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bn\\asm"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\buf"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bytestring"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\chacha"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\cipher"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\cmac"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\conf"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\curve25519"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\des"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\dh"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\digest"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\dsa"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ec"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ecdh"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ecdsa"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\engine"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\err"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\evp"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\hkdf"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\hmac"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\lhash"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\md4"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\md5"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\modes"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\obj"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pem"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pkcs8"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\poly1305"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pool"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rand"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rc4"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rsa"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\sha"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\stack"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\x509"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\x509v3"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\ssl"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\nanopb"); |
||||
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\zlib"); |
||||
_build_dirs = new Array(); |
||||
for (i = 0; i < build_dirs.length; i++) { |
||||
if (build_dirs[i].indexOf('grpc') == -1) { |
||||
_build_dirs[_build_dirs.length] = build_dirs[i]; |
||||
} |
||||
} |
||||
build_dirs = _build_dirs; |
||||
|
||||
} |
@ -0,0 +1,158 @@ |
||||
# Combiner Explanation |
||||
## Talk by ctiller, notes by vjpai |
||||
|
||||
Typical way of doing critical section |
||||
|
||||
``` |
||||
mu.lock() |
||||
do_stuff() |
||||
mu.unlock() |
||||
``` |
||||
|
||||
An alternative way of doing it is |
||||
|
||||
``` |
||||
class combiner { |
||||
run(f) { |
||||
mu.lock() |
||||
f() |
||||
mu.unlock() |
||||
} |
||||
mutex mu; |
||||
} |
||||
|
||||
combiner.run(do_stuff) |
||||
``` |
||||
|
||||
If you have two threads calling combiner, there will be some kind of |
||||
queuing in place. It's called `combiner` because you can pass in more |
||||
than one do_stuff at once and they will run under a common `mu`. |
||||
|
||||
The implementation described above has the issue that you're blocking a thread |
||||
for a period of time, and this is considered harmful because it's an application thread that you're blocking. |
||||
|
||||
Instead, get a new property: |
||||
* Keep things running in serial execution |
||||
* Don't ever sleep the thread |
||||
* But maybe allow things to end up running on a different thread from where they were started |
||||
* This means that `do_stuff` doesn't necessarily run to completion when `combiner.run` is invoked |
||||
|
||||
``` |
||||
class combiner { |
||||
mpscq q; // multi-producer single-consumer queue can be made non-blocking |
||||
state s; // is it empty or executing |
||||
|
||||
run(f) { |
||||
if (q.push(f)) { |
||||
// q.push returns true if it's the first thing |
||||
while (q.pop(&f)) { // modulo some extra work to avoid races |
||||
f(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
The basic idea is that the first one to push onto the combiner |
||||
executes the work and then keeps executing functions from the queue |
||||
until the combiner is drained. |
||||
|
||||
Our combiner does some additional work, with the motivation of write-batching. |
||||
|
||||
We have a second tier of `run` called `run_finally`. Anything queued |
||||
onto `run_finally` runs after we have drained the queue. That means |
||||
that there is essentially a finally-queue. This is not guaranteed to |
||||
be final, but it's best-effort. In the process of running the finally |
||||
item, we might put something onto the main combiner queue and so we'll |
||||
need to re-enter. |
||||
|
||||
`chttp2` runs all ops in the run state except if it sees a write it puts that into a finally. That way anything else that gets put into the combiner can add to that write. |
||||
|
||||
``` |
||||
class combiner { |
||||
mpscq q; // multi-producer single-consumer queue can be made non-blocking |
||||
state s; // is it empty or executing |
||||
queue finally; // you can only do run_finally when you are already running something from the combiner |
||||
|
||||
run(f) { |
||||
if (q.push(f)) { |
||||
// q.push returns true if it's the first thing |
||||
loop: |
||||
while (q.pop(&f)) { // modulo some extra work to avoid races |
||||
f(); |
||||
} |
||||
while (finally.pop(&f)) { |
||||
f(); |
||||
} |
||||
goto loop; |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
So that explains how combiners work in general. In gRPC, there is |
||||
`start_batch(..., tag)` and then work only gets activated by somebody |
||||
calling `cq::next` which returns a tag. This gives an API-level |
||||
guarantee that there will be a thread doing polling to actually make |
||||
work happen. However, some operations are not covered by a poller |
||||
thread, such as cancellation that doesn't have a completion. Other |
||||
callbacks that don't have a completion are the internal work that gets |
||||
done before the batch gets completed. We need a condition called |
||||
`covered_by_poller` that means that the item will definitely need some |
||||
thread at some point to call `cq::next` . This includes those |
||||
callbacks that directly cause a completion but also those that are |
||||
indirectly required before getting a completion. If we can't tell for |
||||
sure for a specific path, we have to assumed it is not covered by |
||||
poller. |
||||
|
||||
The above combiner has the problem that it keeps draining for a |
||||
potentially infinite amount of time and that can lead to a huge tail |
||||
latency for some operations. So we can tweak it by returning to the application |
||||
if we know that it is valid to do so: |
||||
|
||||
``` |
||||
while (q.pop(&f)) { |
||||
f(); |
||||
if (control_can_be_returned && some_still_queued_thing_is_covered_by_poller) { |
||||
offload_combiner_work_to_some_other_thread(); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
`offload` is more than `break`; it does `break` but also causes some |
||||
other thread that is currently waiting on a poll to break out of its |
||||
poll. This is done by setting up a per-polling-island work-queue |
||||
(distributor) wakeup FD. The work-queue is the converse of the combiner; it |
||||
tries to spray events onto as many threads as possible to get as much concurrency as possible. |
||||
|
||||
So `offload` really does: |
||||
|
||||
``` |
||||
workqueue.run(continue_from_while_loop); |
||||
break; |
||||
``` |
||||
|
||||
This needs us to add another class variable for a `workqueue` |
||||
(which is really conceptually a distributor). |
||||
|
||||
``` |
||||
workqueue::run(f) { |
||||
q.push(f) |
||||
eventfd.wakeup() |
||||
} |
||||
|
||||
workqueue::readable() { |
||||
eventfd.consume(); |
||||
q.pop(&f); |
||||
f(); |
||||
if (!q.empty()) { |
||||
eventfd.wakeup(); // spray across as many threads as are waiting on this workqueue |
||||
} |
||||
} |
||||
``` |
||||
|
||||
In principle, `run_finally` could get starved, but this hasn't |
||||
happened in practice. If we were concerned about this, we could put a |
||||
limit on how many things come off the regular `q` before the `finally` |
||||
queue gets processed. |
||||
|
@ -0,0 +1,160 @@ |
||||
# gRPC Error |
||||
|
||||
## Background |
||||
|
||||
`grpc_error` is the c-core's opaque representation of an error. It holds a |
||||
collection of integers, strings, timestamps, and child errors that related to |
||||
the final error. |
||||
|
||||
always present are: |
||||
|
||||
* GRPC_ERROR_STR_FILE and GRPC_ERROR_INT_FILE_LINE - the source location where |
||||
the error was generated |
||||
* GRPC_ERROR_STR_DESCRIPTION - a human readable description of the error |
||||
* GRPC_ERROR_TIME_CREATED - a timestamp indicating when the error happened |
||||
|
||||
An error can also have children; these are other errors that are believed to |
||||
have contributed to this one. By accumulating children, we can begin to root |
||||
cause high level failures from low level failures, without having to derive |
||||
execution paths from log lines. |
||||
|
||||
grpc_errors are refcounted objects, which means they need strict ownership |
||||
semantics. An extra ref on an error can cause a memory leak, and a missing ref |
||||
can cause a crash. |
||||
|
||||
This document serves as a detailed overview of grpc_error's ownership rules. It |
||||
should help people use the errors, as well as help people debug refcount related |
||||
errors. |
||||
|
||||
## Clarification of Ownership |
||||
|
||||
If a particular function is said to "own" an error, that means it has the |
||||
responsibility of calling unref on the error. A function may have access to an |
||||
error without ownership of it. |
||||
|
||||
This means the function may use the error, but must not call unref on it, since |
||||
that will be done elsewhere in the code. A function that does not own an error |
||||
may explicitly take ownership of it by manually calling GRPC_ERROR_REF. |
||||
|
||||
## Ownership Rules |
||||
|
||||
There are three rules of error ownership, which we will go over in detail. |
||||
|
||||
* If `grpc_error` is returned by a function, the caller owns a ref to that |
||||
instance. |
||||
* If a `grpc_error` is passed to a `grpc_closure` callback function, then that |
||||
function does not own a ref to the error. |
||||
* if a `grpc_error` is passed to *any other function*, then that function |
||||
takes ownership of the error. |
||||
|
||||
### Rule 1 |
||||
|
||||
> If `grpc_error` is returned by a function, the caller owns a ref to that |
||||
> instance.* |
||||
|
||||
For example, in the following code block, error1 and error2 are owned by the |
||||
current function. |
||||
|
||||
```C |
||||
grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); |
||||
grpc_error* error2 = some_operation_that_might_fail(...); |
||||
``` |
||||
|
||||
The current function would have to explicitly call GRPC_ERROR_UNREF on the |
||||
errors, or pass them along to a function that would take over the ownership. |
||||
|
||||
### Rule 2 |
||||
|
||||
> If a `grpc_error` is passed to a `grpc_closure` callback function, then that |
||||
> function does not own a ref to the error. |
||||
|
||||
A `grpc_closure` callback function is any function that has the signature: |
||||
|
||||
```C |
||||
void (*cb)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); |
||||
``` |
||||
|
||||
This means that the error ownership is NOT transferred when a functions calls: |
||||
|
||||
```C |
||||
c->cb(exec_ctx, c->cb_arg, err); |
||||
``` |
||||
|
||||
The caller is still responsible for unref-ing the error. |
||||
|
||||
However, the above line is currently being phased out! It is safer to invoke |
||||
callbacks with `GRPC_CLOSURE_RUN` and `GRPC_CLOSURE_SCHED`. These functions are |
||||
not callbacks, so they will take ownership of the error passed to them. |
||||
|
||||
```C |
||||
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); |
||||
GRPC_CLOSURE_RUN(exec_ctx, cb, error); |
||||
// current function no longer has ownership of the error |
||||
``` |
||||
|
||||
If you schedule or run a closure, but still need ownership of the error, then |
||||
you must explicitly take a reference. |
||||
|
||||
```C |
||||
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); |
||||
GRPC_CLOSURE_RUN(exec_ctx, cb, GRPC_ERROR_REF(error)); |
||||
// do some other things with the error |
||||
GRPC_ERROR_UNREF(error); |
||||
``` |
||||
|
||||
Rule 2 is more important to keep in mind when **implementing** `grpc_closure` |
||||
callback functions. You must keep in mind that you do not own the error, and |
||||
must not unref it. More importantly, you cannot pass it to any function that |
||||
would take ownership of the error, without explicitly taking ownership yourself. |
||||
For example: |
||||
|
||||
```C |
||||
void on_some_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { |
||||
// this would cause a crash, because some_function will unref the error, |
||||
// and the caller of this callback will also unref it. |
||||
some_function(error); |
||||
|
||||
// this callback function must take ownership, so it can give that |
||||
// ownership to the function it is calling. |
||||
some_function(GRPC_ERROR_REF(error)); |
||||
} |
||||
``` |
||||
|
||||
### Rule 3 |
||||
|
||||
> if a `grpc_error` is passed to *any other function*, then that function takes |
||||
> ownership of the error. |
||||
|
||||
Take the following example: |
||||
|
||||
```C |
||||
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); |
||||
// do some things |
||||
some_function(error); |
||||
// can't use error anymore! might be gone. |
||||
``` |
||||
|
||||
When some_function is called, it takes over the ownership of the error, and it |
||||
will eventually unref it. So the caller can no longer safely use the error. |
||||
|
||||
If the caller needed to keep using the error (or passing it to other functions), |
||||
if would have to take on a reference to it. This is a common pattern seen. |
||||
|
||||
```C |
||||
void func() { |
||||
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error"); |
||||
some_function(GRPC_ERROR_REF(error)); |
||||
// do things |
||||
some_other_function(GRPC_ERROR_REF(error)); |
||||
// do more things |
||||
some_last_function(error); |
||||
} |
||||
``` |
||||
|
||||
The last call takes ownership and will eventually give the error its final |
||||
unref. |
||||
|
||||
When **implementing** a function that takes an error (and is not a |
||||
`grpc_closure` callback function), you must ensure the error is unref-ed either |
||||
by doing it explicitly with GRPC_ERROR_UNREF, or by passing the error to a |
||||
function that takes over the ownership. |
@ -0,0 +1,29 @@ |
||||
# C++ Performance Notes |
||||
|
||||
## Streaming write buffering |
||||
|
||||
Generally, each write operation (Write(), WritesDone()) implies a syscall. |
||||
gRPC will try to batch together separate write operations from different |
||||
threads, but currently cannot automatically infer batching in a single stream. |
||||
|
||||
If message k+1 in a stream does not rely on responses from message k, it's |
||||
possible to enable write batching by passing a WriteOptions argument to Write |
||||
with the buffer_hint set: |
||||
|
||||
~~~{.cpp} |
||||
stream_writer->Write(message, WriteOptions().set_buffer_hint()); |
||||
~~~ |
||||
|
||||
The write will be buffered until one of the following is true: |
||||
- the per-stream buffer is filled (controllable with the channel argument |
||||
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE) - this prevents infinite buffering leading |
||||
to OOM |
||||
- a subsequent Write without buffer_hint set is posted |
||||
- the call is finished for writing (WritesDone() called on the client, |
||||
or Finish() called on an async server stream, or the service handler returns |
||||
for a sync server stream) |
||||
|
||||
## Completion Queues and Threading in the Async API |
||||
|
||||
Right now, the best performance trade-off is having numcpu's threads and one |
||||
completion queue per thread. |
@ -1 +1 @@ |
||||
Moved to wait-for-ready.md |
||||
Moved to [wait-for-ready.md](wait-for-ready.md) |
||||
|
@ -0,0 +1,271 @@ |
||||
Negative HTTP/2 Interop Test Case Descriptions |
||||
======================================= |
||||
|
||||
Client and server use |
||||
[test.proto](../src/proto/grpc/testing/test.proto). |
||||
|
||||
Server |
||||
------ |
||||
The code for the custom http2 server can be found |
||||
[here](https://github.com/grpc/grpc/tree/master/test/http2_test). |
||||
It is responsible for handling requests and sending responses, and also for |
||||
fulfilling the behavior of each particular test case. |
||||
|
||||
Server should accept these arguments: |
||||
* --port=PORT |
||||
* The port the server will run on. For example, "8080" |
||||
* --test_case=TESTCASE |
||||
* The name of the test case to execute. For example, "goaway" |
||||
|
||||
Client |
||||
------ |
||||
|
||||
Clients implement test cases that test certain functionality. Each client is |
||||
provided the test case it is expected to run as a command-line parameter. Names |
||||
should be lowercase and without spaces. |
||||
|
||||
Clients should accept these arguments: |
||||
* --server_host=HOSTNAME |
||||
* The server host to connect to. For example, "localhost" or "127.0.0.1" |
||||
* --server_port=PORT |
||||
* The server port to connect to. For example, "8080" |
||||
* --test_case=TESTCASE |
||||
* The name of the test case to execute. For example, "goaway" |
||||
|
||||
Note |
||||
----- |
||||
|
||||
Note that the server and client must be invoked with the same test case or else |
||||
the test will be meaningless. For convenience, we provide a shell script wrapper |
||||
that invokes both server and client at the same time, with the same test_case. |
||||
This is the preferred way to run these tests. |
||||
|
||||
## Test Cases |
||||
|
||||
### goaway |
||||
|
||||
This test verifies that the client correctly responds to a goaway sent by the |
||||
server. The client should handle the goaway by switching to a new stream without |
||||
the user application having to do a thing. |
||||
|
||||
Client Procedure: |
||||
1. Client sends two UnaryCall requests (and sleeps for 1 second in-between). |
||||
TODO: resolve [9300](https://github.com/grpc/grpc/issues/9300) and remove the 1 second sleep |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* Both calls are successful. |
||||
* Response payload body is 314159 bytes in size. |
||||
|
||||
Server Procedure: |
||||
1. Server sends a GOAWAY after receiving the first UnaryCall. |
||||
|
||||
Server asserts: |
||||
* Two different connections were used from the client. |
||||
|
||||
### rst_after_header |
||||
|
||||
This test verifies that the client fails correctly when the server sends a |
||||
RST_STREAM immediately after sending headers to the client. |
||||
|
||||
Procedure: |
||||
1. Client sends UnaryCall with: |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* Call was not successful. |
||||
|
||||
Server Procedure: |
||||
1. Server sends a RST_STREAM with error code 0 after sending headers to the client. |
||||
|
||||
*At the moment the error code and message returned are not standardized throughout all |
||||
languages. Those checks will be added once all client languages behave the same way. [#9142](https://github.com/grpc/grpc/issues/9142) is in flight.* |
||||
|
||||
### rst_during_data |
||||
|
||||
This test verifies that the client fails "correctly" when the server sends a |
||||
RST_STREAM halfway through sending data to the client. |
||||
|
||||
Procedure: |
||||
1. Client sends UnaryCall with: |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* Call was not successful. |
||||
|
||||
Server Procedure: |
||||
1. Server sends a RST_STREAM with error code 0 after sending half of |
||||
the requested data to the client. |
||||
|
||||
### rst_after_data |
||||
|
||||
This test verifies that the client fails "correctly" when the server sends a |
||||
RST_STREAM after sending all of the data to the client. |
||||
|
||||
Procedure: |
||||
1. Client sends UnaryCall with: |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* Call was not successful. |
||||
|
||||
Server Procedure: |
||||
1. Server sends a RST_STREAM with error code 0 after sending all of the |
||||
data to the client. |
||||
|
||||
*Certain client languages allow the data to be accessed even though a RST_STREAM |
||||
was encountered. Once all client languages behave this way, checks will be added on |
||||
the incoming data.* |
||||
|
||||
### ping |
||||
|
||||
This test verifies that the client correctly acknowledges all pings it gets from the |
||||
server. |
||||
|
||||
Procedure: |
||||
1. Client sends UnaryCall with: |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* call was successful. |
||||
* response payload body is 314159 bytes in size. |
||||
|
||||
Server Procedure: |
||||
1. Server tracks the number of outstanding pings (i.e. +1 when it sends a ping, and -1 |
||||
when it receives an ack from the client). |
||||
2. Server sends pings before and after sending headers, also before and after sending data. |
||||
|
||||
Server Asserts: |
||||
* Number of outstanding pings is 0 when the connection is lost. |
||||
|
||||
### max_streams |
||||
|
||||
This test verifies that the client observes the MAX_CONCURRENT_STREAMS limit set by the server. |
||||
|
||||
Client Procedure: |
||||
1. Client sends initial UnaryCall to allow the server to update its MAX_CONCURRENT_STREAMS settings. |
||||
2. Client concurrently sends 10 UnaryCalls. |
||||
|
||||
Client Asserts: |
||||
* All UnaryCalls were successful, and had the correct type and payload size. |
||||
|
||||
Server Procedure: |
||||
1. Sets MAX_CONCURRENT_STREAMS to one after the connection is made. |
||||
|
||||
*The assertion that the MAX_CONCURRENT_STREAMS limit is upheld occurs in the http2 library we used.* |
||||
|
||||
### data_frame_padding |
||||
|
||||
This test verifies that the client can correctly receive padded http2 data |
||||
frames. It also stresses the client's flow control (there is a high chance |
||||
that the sender will deadlock if the client's flow control logic doesn't |
||||
correctly account for padding). |
||||
|
||||
Client Procedure: |
||||
(Note this is the same procedure as in the "large_unary" gRPC interop tests. |
||||
Clients should use their "large_unary" gRPC interop test implementations.) |
||||
Procedure: |
||||
1. Client calls UnaryCall with: |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* call was successful |
||||
* response payload body is 314159 bytes in size |
||||
* clients are free to assert that the response payload body contents are zero |
||||
and comparing the entire response message against a golden response |
||||
|
||||
Server Procedure: |
||||
1. Reply to the client's request with a `SimpleResponse`, with a payload |
||||
body length of `SimpleRequest.response_size`. But send it across specific |
||||
http2 data frames as follows: |
||||
* Each http2 data frame contains a 5 byte payload and 255 bytes of padding. |
||||
|
||||
* Note the 5 byte payload and 255 byte padding are partly arbitrary, |
||||
and other numbers are also ok. With 255 bytes of padding for each 5 bytes of |
||||
payload containing actual gRPC message, the 300KB response size will |
||||
multiply into around 15 megabytes of flow control debt, which should stress |
||||
flow control accounting. |
||||
|
||||
### no_df_padding_sanity_test |
||||
|
||||
This test verifies that the client can correctly receive a series of small |
||||
data frames. Note that this test is intentionally a slight variation of |
||||
"data_frame_padding", with the only difference being that this test doesn't use data |
||||
frame padding when the response is sent. This test is primarily meant to |
||||
prove correctness of the http2 server implementation and highlight failures |
||||
of the "data_frame_padding" test. |
||||
|
||||
Client Procedure: |
||||
(Note this is the same procedure as in the "large_unary" gRPC interop tests. |
||||
Clients should use their "large_unary" gRPC interop test implementations.) |
||||
Procedure: |
||||
1. Client calls UnaryCall with: |
||||
|
||||
``` |
||||
{ |
||||
response_size: 314159 |
||||
payload:{ |
||||
body: 271828 bytes of zeros |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Client asserts: |
||||
* call was successful |
||||
* response payload body is 314159 bytes in size |
||||
* clients are free to assert that the response payload body contents are zero |
||||
and comparing the entire response message against a golden response |
||||
|
||||
Server Procedure: |
||||
1. Reply to the client's request with a `SimpleResponse`, with a payload |
||||
body length of `SimpleRequest.response_size`. But send it across series of |
||||
http2 data frames that contain 5 bytes of "payload" and zero bytes of |
||||
"padding" (the padding flags on the data frames should not be set). |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 39 KiB |
@ -0,0 +1,45 @@ |
||||
gRPC Internationalization |
||||
========================= |
||||
|
||||
As a universal RPC framework, gRPC needs to be fully usable within/across different international environments. |
||||
This document describes gRPC API and behavior specifics when used in a non-english environment. |
||||
|
||||
## API Concepts |
||||
|
||||
While some API elements need to be able to represent non-english content, some are intentionally left as ASCII-only |
||||
for simplicity & performance reasons. |
||||
|
||||
### Method name (in RPC Invocation) |
||||
Method names are ASCII-only and may only contain characters allowed by HTTP/2 text header values. That should not |
||||
be very limiting as most gRPC services will use protobuf which only allows method names from an even more restricted ASCII subset. |
||||
Also, handling method names is a very hot code path so any additional encoding/decoding step is to be avoided. |
||||
|
||||
Recommended representation in language-specific APIs: string type. |
||||
|
||||
### Host name (in RPC Invocation) |
||||
Host names are punycode encoded, but the user is responsible for providing the punycode-encoded string if she wishes to use an internationalized host name. |
||||
|
||||
Recommended representation in language-specific APIs: string/unicode string. |
||||
|
||||
NOTE: overriding host name when invoking RPCs is only supported by C-core based gRPC implementations. |
||||
|
||||
### Status detail/message (accompanies RPC status code) |
||||
|
||||
Status messages are expected to contain national-alphabet characters. |
||||
Allowed values are unicode strings (content will be percent-encoded on the wire). |
||||
|
||||
Recommended representation in language-specific APIs: unicode string. |
||||
|
||||
### Metadata key |
||||
Allowed values are defined by HTTP/2 standard (metadata keys are represented as HTTP/2 header/trailer names). |
||||
|
||||
Recommended representation in language-specific APIs: string. |
||||
|
||||
### Metadata value (text-valued metadata) |
||||
Allowed values are defined by HTTP/2 standard (metadata values are represented as HTTP/2 header/trailer text values). |
||||
|
||||
Recommended representation in language-specific APIs: string. |
||||
|
||||
### Channel target (in channel creation) |
||||
|
||||
TBD |
@ -1,30 +1,65 @@ |
||||
#gRPC Naming and Discovery Support |
||||
# gRPC Name Resolution |
||||
|
||||
## Overview |
||||
|
||||
gRPC supports DNS as the default name-system. A number of alternative name-systems are used in various deployments. We propose an API that is general enough to support a range of name-systems and the corresponding syntax for names. The gRPC client library in various languages will provide a plugin mechanism so resolvers for different name-systems can be plugged in. |
||||
gRPC supports DNS as the default name-system. A number of alternative |
||||
name-systems are used in various deployments. We support an API that is |
||||
general enough to support a range of name-systems and the corresponding |
||||
syntax for names. The gRPC client library in various languages will |
||||
provide a plugin mechanism so resolvers for different name-systems can |
||||
be plugged in. |
||||
|
||||
## Detailed Proposal |
||||
## Detailed Design |
||||
|
||||
A fully qualified, self contained name used for gRPC channel construction uses the syntax: |
||||
### Name Syntax |
||||
|
||||
A fully qualified, self contained name used for gRPC channel construction |
||||
uses the syntax: |
||||
|
||||
``` |
||||
scheme://authority/endpoint_name |
||||
``` |
||||
|
||||
Here, scheme indicates the name-system to be used. Example schemes to be supported include: |
||||
Here, `scheme` indicates the name-system to be used. Currently, we |
||||
support the following schemes: |
||||
|
||||
- `dns` |
||||
|
||||
- `ipv4` (IPv4 address) |
||||
|
||||
- `ipv6` (IPv6 address) |
||||
|
||||
- `unix` (path to unix domain socket -- unix systems only) |
||||
|
||||
* `dns` |
||||
In the future, additional schemes such as `etcd` could be added. |
||||
|
||||
* `etcd` |
||||
The `authority` indicates some scheme-specific bootstrap information, e.g., |
||||
for DNS, the authority may include the IP[:port] of the DNS server to |
||||
use. Often, a DNS name may be used as the authority, since the ability to |
||||
resolve DNS names is already built into all gRPC client libraries. |
||||
|
||||
Authority indicates some scheme-specific bootstrap information, e.g., for DNS, the authority may include the IP[:port] of the DNS server to use. Often, a DNS name may used as the authority, since the ability to resolve DNS names is already built into all gRPC client libraries. |
||||
Finally, the `endpoint_name` indicates a concrete name to be looked up |
||||
in a given name-system identified by the scheme and the authority. The |
||||
syntax of the endpoint name is dictated by the scheme in use. |
||||
|
||||
Finally, the endpoint_name indicates a concrete name to be looked up in a given name-system identified by the scheme and the authority. The syntax of endpoint name is dictated by the scheme in use. |
||||
### Resolver Plugins |
||||
|
||||
### Plugins |
||||
The gRPC client library will use the specified scheme to pick the right |
||||
resolver plugin and pass it the fully qualified name string. |
||||
|
||||
The gRPC client library will switch on the scheme to pick the right resolver plugin and pass it the fully qualified name string. |
||||
Resolvers should be able to contact the authority and get a resolution |
||||
that they return back to the gRPC client library. The returned contents |
||||
include: |
||||
|
||||
Resolvers should be able to contact the authority and get a resolution that they return back to the gRPC client library. The returned contents include a list of IP:port, an optional config and optional auth config data to be used for channel authentication. The plugin API allows the resolvers to continuously watch an endpoint_name and return updated resolutions as needed. |
||||
- A list of resolved addresses, each of which has three attributes: |
||||
- The address itself, including both IP address and port. |
||||
- A boolean indicating whether the address is a backend address (i.e., |
||||
the address to use to contact the server directly) or a balancer |
||||
address (for cases where [external load balancing](load-balancing.md) |
||||
is in use). |
||||
- The name of the balancer, if the address is a balancer address. |
||||
This will be used to perform peer authorization. |
||||
- A [service config](service_config.md). |
||||
|
||||
The plugin API allows the resolvers to continuously watch an endpoint |
||||
and return updated resolutions as needed. |
||||
|
@ -0,0 +1,60 @@ |
||||
Server-side API for Authenticating Clients |
||||
========================================== |
||||
|
||||
NOTE: This document describes how server-side authentication works in C-core based gRPC implementations only. In gRPC Java and Go, server side authentication is handled differently. |
||||
|
||||
## AuthContext |
||||
|
||||
To perform server-side authentication, gRPC exposes the *authentication context* for each call. The context exposes important authentication-related information about the RPC such as the type of security/authentication type being used and the peer identity. |
||||
|
||||
The authentication context is structured as a multi-map of key-value pairs - the *auth properties*. In addition to that, for authenticated RPCs, the set of properties corresponding to a selected key will represent the verified identity of the caller - the *peer identity*. |
||||
|
||||
The contents of the *auth properties* are populated by an *auth interceptor*. The interceptor also chooses which property key will act as the peer identity (e.g. for client certificate authentication this property will be `"x509_common_name"` or `"x509_subject_alternative_name"`). |
||||
|
||||
WARNING: AuthContext is the only reliable source of truth when it comes to authenticating RPCs. Using any other call/context properties for authentication purposes is wrong and inherently unsafe. |
||||
|
||||
#### Example AuthContext contents |
||||
|
||||
For secure channel using mutual TLS authentication with both client and server certificates (test certificates from this repository are used). |
||||
|
||||
Populated auth properties: |
||||
``` |
||||
"transport_security_type": "ssl" # connection is secured using TLS/SSL |
||||
"x509_common_name": "*.test.google.com" # from client's certificate |
||||
"x509_pem_cert": "-----BEGIN CERTIFICATE-----\n..." # client's PEM encoded certificate |
||||
"x509_subject_alternative_name": "*.test.google.fr" |
||||
"x509_subject_alternative_name": "waterzooi.test.google.be" |
||||
"x509_subject_alternative_name": "*.test.youtube.com" |
||||
"x509_subject_alternative_name": "192.168.1.3" |
||||
``` |
||||
|
||||
The peer identity is set of all properties named `"x509_subject_alternative_name"`: |
||||
``` |
||||
peer_identity_property_name = "x509_subject_alternative_name" |
||||
``` |
||||
|
||||
## AuthProperty |
||||
|
||||
Auth properties are elements of the AuthContext. They have a name (a key of type string) and a value which can be a string or binary data. |
||||
|
||||
## Auth Interceptors |
||||
|
||||
Auth interceptors are gRPC components that populate contents of the auth context based on gRPC's internal state and/or call metadata. |
||||
gRPC comes with some basic "interceptors" already built-in. |
||||
|
||||
WARNING: While there is a public API that allows anyone to write their own custom interceptor, please think twice before using it. |
||||
There are legitimate uses for custom interceptors but you should keep in mind that as auth interceptors essentially decide which RPCs are authenticated and which are not, their code is very sensitive from the security perspective and getting things wrong might have serious consequences. If unsure, we strongly recommend to rely on official & proven interceptors that come with gRPC. |
||||
|
||||
#### Available auth interceptors |
||||
- TLS/SSL certificate authentication (built into gRPC's security layer, automatically used whenever you use a secure connection) |
||||
- (coming soon) JWT auth token authentication |
||||
- more will be added over time |
||||
|
||||
## Status (by language) |
||||
C-core exposes low level API to access auth context contents and to implement an auth interceptor. |
||||
In C++, the auth interceptor API is exposed as `AuthMetadataProcessor`. |
||||
|
||||
A high level API to access AuthContext contents is available in these languages: |
||||
- C++ |
||||
- C# (implementation in-progress) |
||||
- other languages coming soon |
@ -0,0 +1,150 @@ |
||||
Service Config in gRPC |
||||
====================== |
||||
|
||||
# Objective |
||||
|
||||
The service config is a mechanism that allows service owners to publish |
||||
parameters to be automatically used by all clients of their service. |
||||
|
||||
# Format |
||||
|
||||
The service config is a JSON string of the following form: |
||||
|
||||
``` |
||||
{ |
||||
// Load balancing policy name. |
||||
// Currently, the only selectable client-side policy provided with gRPC |
||||
// is 'round_robin', but third parties may add their own policies. |
||||
// This field is optional; if unset, the default behavior is to pick |
||||
// the first available backend. |
||||
// If the policy name is set via the client API, that value overrides |
||||
// the value specified here. |
||||
// |
||||
// Note that if the resolver returns at least one balancer address (as |
||||
// opposed to backend addresses), gRPC will use grpclb (see |
||||
// https://github.com/grpc/grpc/blob/master/doc/load-balancing.md), |
||||
// regardless of what LB policy is requested either here or via the |
||||
// client API. However, if the resolver returns at least one backend |
||||
// address in addition to the balancer address(es), the client may fall |
||||
// back to the requested policy if it is unable to reach any of the |
||||
// grpclb load balancers. |
||||
'loadBalancingPolicy': string, |
||||
|
||||
// Per-method configuration. Optional. |
||||
'methodConfig': [ |
||||
{ |
||||
// The names of the methods to which this method config applies. There |
||||
// must be at least one name. Each name entry must be unique across the |
||||
// entire service config. If the 'method' field is empty, then this |
||||
// method config specifies the defaults for all methods for the specified |
||||
// service. |
||||
// |
||||
// For example, let's say that the service config contains the following |
||||
// method config entries: |
||||
// |
||||
// 'methodConfig': [ |
||||
// { 'name': [ { 'service': 'MyService' } ] ... }, |
||||
// { 'name': [ { 'service': 'MyService', 'method': 'Foo' } ] ... } |
||||
// ] |
||||
// |
||||
// For a request for MyService/Foo, we will use the second entry, because |
||||
// it exactly matches the service and method name. |
||||
// For a request for MyService/Bar, we will use the first entry, because |
||||
// it provides the default for all methods of MyService. |
||||
'name': [ |
||||
{ |
||||
// RPC service name. Required. |
||||
// If using gRPC with protobuf as the IDL, then this will be of |
||||
// the form "pkg.service_name", where "pkg" is the package name |
||||
// defined in the proto file. |
||||
'service': string, |
||||
|
||||
// RPC method name. Optional (see above). |
||||
'method': string, |
||||
} |
||||
], |
||||
|
||||
// Whether RPCs sent to this method should wait until the connection is |
||||
// ready by default. If false, the RPC will abort immediately if there |
||||
// is a transient failure connecting to the server. Otherwise, gRPC will |
||||
// attempt to connect until the deadline is exceeded. |
||||
// |
||||
// The value specified via the gRPC client API will override the value |
||||
// set here. However, note that setting the value in the client API will |
||||
// also affect transient errors encountered during name resolution, |
||||
// which cannot be caught by the value here, since the service config |
||||
// is obtained by the gRPC client via name resolution. |
||||
'waitForReady': bool, |
||||
|
||||
// The default timeout in seconds for RPCs sent to this method. This can |
||||
// be overridden in code. If no reply is received in the specified amount |
||||
// of time, the request is aborted and a deadline-exceeded error status |
||||
// is returned to the caller. |
||||
// |
||||
// The actual deadline used will be the minimum of the value specified |
||||
// here and the value set by the application via the gRPC client API. |
||||
// If either one is not set, then the other will be used. |
||||
// If neither is set, then the request has no deadline. |
||||
// |
||||
// The format of the value is that of the 'Duration' type defined here: |
||||
// https://developers.google.com/protocol-buffers/docs/proto3#json |
||||
'timeout': string, |
||||
|
||||
// The maximum allowed payload size for an individual request or object |
||||
// in a stream (client->server) in bytes. The size which is measured is |
||||
// the serialized, uncompressed payload in bytes. This applies both |
||||
// to streaming and non-streaming requests. |
||||
// |
||||
// The actual value used is the minimum of the value specified here and |
||||
// the value set by the application via the gRPC client API. |
||||
// If either one is not set, then the other will be used. |
||||
// If neither is set, then the built-in default is used. |
||||
// |
||||
// If a client attempts to send an object larger than this value, it |
||||
// will not be sent and the client will see an error. |
||||
// Note that 0 is a valid value, meaning that the request message must |
||||
// be empty. |
||||
'maxRequestMessageBytes': number, |
||||
|
||||
// The maximum allowed payload size for an individual response or object |
||||
// in a stream (server->client) in bytes. The size which is measured is |
||||
// the serialized, uncompressed payload in bytes. This applies both |
||||
// to streaming and non-streaming requests. |
||||
// |
||||
// The actual value used is the minimum of the value specified here and |
||||
// the value set by the application via the gRPC client API. |
||||
// If either one is not set, then the other will be used. |
||||
// If neither is set, then the built-in default is used. |
||||
// |
||||
// If a server attempts to send an object larger than this value, it |
||||
// will not be sent, and the client will see an error. |
||||
// Note that 0 is a valid value, meaning that the response message must |
||||
// be empty. |
||||
'maxResponseMessageBytes': number |
||||
} |
||||
] |
||||
} |
||||
``` |
||||
|
||||
Note that new per-method parameters may be added in the future as new |
||||
functionality is introduced. |
||||
|
||||
# Architecture |
||||
|
||||
A service config is associated with a server name. The [name resolver](naming.md) |
||||
plugin, when asked to resolve a particular server |
||||
name, will return both the resolved addresses and the service config. |
||||
|
||||
TODO(roth): Design how the service config will be encoded in DNS. |
||||
|
||||
# APIs |
||||
|
||||
The service config is used in the following APIs: |
||||
|
||||
- In the resolver API, used by resolver plugins to return the service |
||||
config to the gRPC client. |
||||
- In the gRPC client API, where users can query the channel to obtain |
||||
the service config associated with the channel (for debugging |
||||
purposes). |
||||
- In the gRPC client API, where users can set the service config |
||||
explicitly. This is intended for use in unit tests. |
@ -0,0 +1,16 @@ |
||||
Ordering Status and Reads in the gRPC API |
||||
----------------------------------------- |
||||
|
||||
Rules for implementors: |
||||
1. Reads and Writes Must not succeed after Status has been delivered. |
||||
2. OK Status is only delivered after all buffered messages are read. |
||||
3. Reads May continue to succeed after a failing write. |
||||
However, once a write fails, all subsequent writes Must fail, |
||||
and similarly, once a read fails, all subsequent reads Must fail. |
||||
4. When an error status is known to the library, if the user asks for status, |
||||
the library Should discard messages received in the library but not delivered |
||||
to the user and then deliver the status. If the user does not ask for status |
||||
but continues reading, the library Should deliver buffered messages before |
||||
delivering status. The library MAY choose to implement the stricter version |
||||
where errors cause all buffered messages to be dropped, but this is not a |
||||
requirement. |
@ -0,0 +1,175 @@ |
||||
# How to write unit tests for gRPC C client. |
||||
|
||||
tl;dr: [Example code](https://github.com/grpc/grpc/blob/master/test/cpp/end2end/mock_test.cc). |
||||
|
||||
To unit-test client-side logic via the synchronous API, gRPC provides a mocked Stub based on googletest(googlemock) that can be programmed upon and easily incorporated in the test code. |
||||
|
||||
For instance, consider an EchoService like this: |
||||
|
||||
|
||||
```proto |
||||
service EchoTestService { |
||||
rpc Echo(EchoRequest) returns (EchoResponse); |
||||
rpc BidiStream(stream EchoRequest) returns (stream EchoResponse); |
||||
} |
||||
``` |
||||
|
||||
The code generated would look something like this: |
||||
|
||||
```c |
||||
class EchoTestService final { |
||||
public: |
||||
class StubInterface { |
||||
virtual ::grpc::Status Echo(::grpc::ClientContext* context, const ::grpc::testing::EchoRequest& request, ::grpc::testing::EchoResponse* response) = 0; |
||||
… |
||||
std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::EchoRequest, ::grpc::testing::EchoResponse>> BidiStream(::grpc::ClientContext* context) { |
||||
return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::testing::EchoRequest, ::grpc::testing::EchoResponse>>(BidiStreamRaw(context)); |
||||
} |
||||
… |
||||
private: |
||||
virtual ::grpc::ClientReaderWriterInterface< ::grpc::testing::EchoRequest, ::grpc::testing::EchoResponse>* BidiStreamRaw(::grpc::ClientContext* context) = 0; |
||||
… |
||||
} // End StubInterface |
||||
… |
||||
} // End EchoTestService |
||||
``` |
||||
|
||||
|
||||
If we mock the StubInterface and set expectations on the pure-virtual methods we can test client-side logic without having to make any rpcs. |
||||
|
||||
A mock for this StubInterface will look like this: |
||||
|
||||
|
||||
```c |
||||
class MockEchoTestServiceStub : public EchoTestService::StubInterface { |
||||
public: |
||||
MOCK_METHOD3(Echo, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::EchoRequest& request, ::grpc::testing::EchoResponse* response)); |
||||
MOCK_METHOD1(BidiStreamRaw, ::grpc::ClientReaderWriterInterface< ::grpc::testing::EchoRequest, ::grpc::testing::EchoResponse>*(::grpc::ClientContext* context)); |
||||
}; |
||||
``` |
||||
|
||||
|
||||
**Generating mock code:** |
||||
|
||||
Such a mock can be auto-generated by: |
||||
|
||||
|
||||
|
||||
1. Setting flag(generate_mock_code=true) on grpc plugin for protoc, or |
||||
1. Setting an attribute(generate_mock) in your bazel rule. |
||||
|
||||
Protoc plugin flag: |
||||
|
||||
```sh |
||||
protoc -I . --grpc_out=generate_mock_code=true:. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` echo.proto |
||||
``` |
||||
|
||||
Bazel rule: |
||||
|
||||
```py |
||||
grpc_proto_library( |
||||
name = "echo_proto", |
||||
srcs = ["echo.proto"], |
||||
generate_mock = True, |
||||
) |
||||
``` |
||||
|
||||
|
||||
By adding such a flag now a header file `echo_mock.grpc.pb.h` containing the mocked stub will also be generated. |
||||
|
||||
This header file can then be included in test files along with a gmock dependency. |
||||
|
||||
**Writing tests with mocked Stub.** |
||||
|
||||
Consider the following client a user might have: |
||||
|
||||
```c |
||||
class FakeClient { |
||||
public: |
||||
explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {} |
||||
|
||||
void DoEcho() { |
||||
ClientContext context; |
||||
EchoRequest request; |
||||
EchoResponse response; |
||||
request.set_message("hello world"); |
||||
Status s = stub_->Echo(&context, request, &response); |
||||
EXPECT_EQ(request.message(), response.message()); |
||||
EXPECT_TRUE(s.ok()); |
||||
} |
||||
|
||||
void DoBidiStream() { |
||||
EchoRequest request; |
||||
EchoResponse response; |
||||
ClientContext context; |
||||
grpc::string msg("hello"); |
||||
|
||||
std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>> |
||||
stream = stub_->BidiStream(&context); |
||||
|
||||
request.set_message(msg "0"); |
||||
EXPECT_TRUE(stream->Write(request)); |
||||
EXPECT_TRUE(stream->Read(&response)); |
||||
EXPECT_EQ(response.message(), request.message()); |
||||
|
||||
request.set_message(msg "1"); |
||||
EXPECT_TRUE(stream->Write(request)); |
||||
EXPECT_TRUE(stream->Read(&response)); |
||||
EXPECT_EQ(response.message(), request.message()); |
||||
|
||||
request.set_message(msg "2"); |
||||
EXPECT_TRUE(stream->Write(request)); |
||||
EXPECT_TRUE(stream->Read(&response)); |
||||
EXPECT_EQ(response.message(), request.message()); |
||||
|
||||
stream->WritesDone(); |
||||
EXPECT_FALSE(stream->Read(&response)); |
||||
|
||||
Status s = stream->Finish(); |
||||
EXPECT_TRUE(s.ok()); |
||||
} |
||||
|
||||
void ResetStub(EchoTestService::StubInterface* stub) { stub_ = stub; } |
||||
|
||||
private: |
||||
EchoTestService::StubInterface* stub_; |
||||
}; |
||||
``` |
||||
|
||||
A test could initialize this FakeClient with a mocked stub having set expectations on it: |
||||
|
||||
Unary RPC: |
||||
|
||||
```c |
||||
MockEchoTestServiceStub stub; |
||||
EchoResponse resp; |
||||
resp.set_message("hello world"); |
||||
Expect_CALL(stub, Echo(_,_,_)).Times(Atleast(1)).WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK))); |
||||
FakeClient client(stub); |
||||
client.DoEcho(); |
||||
``` |
||||
|
||||
Streaming RPC: |
||||
|
||||
```c |
||||
ACTION_P(copy, msg) { |
||||
arg0->set_message(msg->message()); |
||||
} |
||||
|
||||
|
||||
auto rw = new MockClientReaderWriter<EchoRequest, EchoResponse>(); |
||||
EchoRequest msg; |
||||
EXPECT_CALL(*rw, Write(_, _)).Times(3).WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true))); |
||||
EXPECT_CALL(*rw, Read(_)). |
||||
WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true))). |
||||
WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true))). |
||||
WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true))). |
||||
WillOnce(Return(false)); |
||||
|
||||
MockEchoTestServiceStub stub; |
||||
EXPECT_CALL(stub, BidiStreamRaw(_)).Times(AtLeast(1)).WillOnce(Return(rw)); |
||||
|
||||
FakeClient client(stub); |
||||
client.DoBidiStream(); |
||||
``` |
||||
|
@ -0,0 +1,19 @@ |
||||
# gRPC Server Backward Compatibility Issues and Workarounds Manageent |
||||
|
||||
## Introduction |
||||
This document lists the workarounds implemented on gRPC servers for record and reference when users need to enable a certain workaround. |
||||
|
||||
## Workaround List |
||||
|
||||
### Cronet Compression |
||||
|
||||
**Workaround ID:** WORKAROUND\_ID\_CRONET\_COMPRESSION |
||||
|
||||
**Date added:** May 06, 2017 |
||||
|
||||
**Status:** Implemented in C core and C++ |
||||
|
||||
**Issue:** Before version v1.3.0-dev, gRPC iOS client's Cronet transport did not implement compression. However the clients still claim to support compression. As a result, a client fails to parse received message when the message is compressed. |
||||
The problem above was resolved in gRPC v1.3.0-dev. For backward compatibility, a server must forcingly disable compression for gRPC clients of version lower than or equal to v1.3.0-dev. |
||||
|
||||
**Workaround Description:** Implemented as a server channel filter in C core. The filter identifies the version of peer client with incoming `user-agent` header of each call. If the client's gRPC version is lower that or equal to v1.3.x, a flag GRPC_WRITE_NO_COMPRESS is marked for all send_message ops which prevents compression of the messages to be sent out. |
@ -0,0 +1,53 @@ |
||||
# Copyright 2017 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
licenses(["notice"]) # 3-clause BSD |
||||
|
||||
package(default_visibility = ["//visibility:public"]) |
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_proto_library") |
||||
|
||||
grpc_proto_library( |
||||
name = "auth_sample", |
||||
srcs = ["protos/auth_sample.proto"], |
||||
) |
||||
|
||||
grpc_proto_library( |
||||
name = "hellostreamingworld", |
||||
srcs = ["protos/hellostreamingworld.proto"], |
||||
) |
||||
|
||||
grpc_proto_library( |
||||
name = "helloworld", |
||||
srcs = ["protos/helloworld.proto"], |
||||
) |
||||
|
||||
grpc_proto_library( |
||||
name = "route_guide", |
||||
srcs = ["protos/route_guide.proto"], |
||||
) |
||||
|
||||
cc_binary( |
||||
name = "greeter_client", |
||||
srcs = ["cpp/helloworld/greeter_client.cc"], |
||||
defines = ["BAZEL_BUILD"], |
||||
deps = [":helloworld"], |
||||
) |
||||
|
||||
cc_binary( |
||||
name = "greeter_server", |
||||
srcs = ["cpp/helloworld/greeter_server.cc"], |
||||
defines = ["BAZEL_BUILD"], |
||||
deps = [":helloworld"], |
||||
) |
@ -1,31 +0,0 @@ |
||||
{ |
||||
"title": "Greeter", |
||||
"version": "1.0.0-*", |
||||
"buildOptions": { |
||||
"debugType": "portable", |
||||
}, |
||||
"dependencies": { |
||||
"Google.Protobuf": "3.0.0", |
||||
"Grpc": "1.0.1", |
||||
}, |
||||
"frameworks": { |
||||
"net45": { |
||||
"frameworkAssemblies": { |
||||
"System.Runtime": "", |
||||
"System.IO": "" |
||||
}, |
||||
"dependencies": { |
||||
"Microsoft.NETCore.Platforms": "1.0.1" |
||||
} |
||||
}, |
||||
"netcoreapp1.0": { |
||||
"dependencies": { |
||||
"Microsoft.NETCore.App": { |
||||
"type": "platform", |
||||
"version": "1.0.1" |
||||
} |
||||
}, |
||||
"imports": "dnxcore50" |
||||
} |
||||
} |
||||
} |
@ -1,35 +0,0 @@ |
||||
{ |
||||
"title": "GreeterClient", |
||||
"version": "1.0.0-*", |
||||
"buildOptions": { |
||||
"debugType": "portable", |
||||
"emitEntryPoint": "true" |
||||
}, |
||||
"dependencies": { |
||||
"Google.Protobuf": "3.0.0", |
||||
"Grpc": "1.0.1", |
||||
"Greeter": { |
||||
"target": "project" |
||||
} |
||||
}, |
||||
"frameworks": { |
||||
"net45": { |
||||
"frameworkAssemblies": { |
||||
"System.Runtime": "", |
||||
"System.IO": "" |
||||
}, |
||||
"dependencies": { |
||||
"Microsoft.NETCore.Platforms": "1.0.1" |
||||
} |
||||
}, |
||||
"netcoreapp1.0": { |
||||
"dependencies": { |
||||
"Microsoft.NETCore.App": { |
||||
"type": "platform", |
||||
"version": "1.0.1" |
||||
} |
||||
}, |
||||
"imports": "dnxcore50" |
||||
} |
||||
} |
||||
} |
@ -1,35 +0,0 @@ |
||||
{ |
||||
"title": "GreeterServer", |
||||
"version": "1.0.0-*", |
||||
"buildOptions": { |
||||
"debugType": "portable", |
||||
"emitEntryPoint": "true" |
||||
}, |
||||
"dependencies": { |
||||
"Google.Protobuf": "3.0.0", |
||||
"Grpc": "1.0.1", |
||||
"Greeter": { |
||||
"target": "project" |
||||
} |
||||
}, |
||||
"frameworks": { |
||||
"net45": { |
||||
"frameworkAssemblies": { |
||||
"System.Runtime": "", |
||||
"System.IO": "" |
||||
}, |
||||
"dependencies": { |
||||
"Microsoft.NETCore.Platforms": "1.0.1" |
||||
} |
||||
}, |
||||
"netcoreapp1.0": { |
||||
"dependencies": { |
||||
"Microsoft.NETCore.App": { |
||||
"type": "platform", |
||||
"version": "1.0.1" |
||||
} |
||||
}, |
||||
"imports": "dnxcore50" |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,27 @@ |
||||
@rem Copyright 2016 gRPC authors. |
||||
@rem |
||||
@rem Licensed under the Apache License, Version 2.0 (the "License"); |
||||
@rem you may not use this file except in compliance with the License. |
||||
@rem You may obtain a copy of the License at |
||||
@rem |
||||
@rem http://www.apache.org/licenses/LICENSE-2.0 |
||||
@rem |
||||
@rem Unless required by applicable law or agreed to in writing, software |
||||
@rem distributed under the License is distributed on an "AS IS" BASIS, |
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
@rem See the License for the specific language governing permissions and |
||||
@rem limitations under the License. |
||||
|
||||
@rem Generate the C# code for .proto files |
||||
|
||||
setlocal |
||||
|
||||
@rem enter this directory |
||||
cd /d %~dp0 |
||||
|
||||
set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.2.0\tools\windows_x64\protoc.exe |
||||
set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.2.2\tools\windows_x64\grpc_csharp_plugin.exe |
||||
|
||||
%PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN% |
||||
|
||||
endlocal |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue