grpc 1.26.0 → 1.27.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +1654 -1519
- data/etc/roots.pem +44 -0
- data/include/grpc/grpc_security.h +37 -15
- data/include/grpc/grpc_security_constants.h +27 -0
- data/include/grpc/impl/codegen/grpc_types.h +14 -0
- data/include/grpc/impl/codegen/port_platform.h +1 -1
- data/src/core/ext/filters/client_channel/client_channel.cc +0 -20
- data/src/core/ext/filters/client_channel/http_proxy.cc +4 -4
- data/src/core/ext/filters/client_channel/lb_policy.cc +4 -3
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +191 -201
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +89 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +40 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +3 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +88 -121
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +28 -57
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +0 -7
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +8 -9
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +53 -34
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +18 -5
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +24 -19
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +4 -2
- data/src/core/ext/filters/client_channel/server_address.cc +6 -9
- data/src/core/ext/filters/client_channel/server_address.h +3 -10
- data/src/core/ext/filters/client_channel/xds/xds_api.cc +394 -150
- data/src/core/ext/filters/client_channel/xds/xds_api.h +75 -35
- data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +59 -22
- data/src/core/ext/filters/client_channel/xds/xds_bootstrap.h +13 -9
- data/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc +8 -6
- data/src/core/ext/filters/client_channel/xds/xds_client.cc +456 -175
- data/src/core/ext/filters/client_channel/xds/xds_client.h +33 -21
- data/src/core/ext/filters/client_channel/xds/xds_client_stats.cc +5 -8
- data/src/core/ext/filters/client_channel/xds/xds_client_stats.h +18 -24
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -2
- data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c +13 -5
- data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +34 -0
- data/src/core/lib/channel/channelz.h +11 -1
- data/src/core/lib/gpr/time_precise.cc +1 -1
- data/src/core/lib/gprpp/optional.h +26 -0
- data/src/core/lib/gprpp/string_view.h +14 -10
- data/src/core/lib/iomgr/executor.cc +1 -1
- data/src/core/lib/iomgr/fork_posix.cc +4 -0
- data/src/core/lib/iomgr/poller/eventmanager_libuv.cc +87 -0
- data/src/core/lib/iomgr/poller/eventmanager_libuv.h +88 -0
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +14 -0
- data/src/core/lib/iomgr/socket_utils_posix.h +12 -0
- data/src/core/lib/iomgr/tcp_custom.h +3 -0
- data/src/core/lib/iomgr/tcp_posix.cc +607 -56
- data/src/core/lib/iomgr/tcp_server_custom.cc +15 -2
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +8 -0
- data/src/core/lib/json/json.h +11 -1
- data/src/core/lib/json/json_reader.cc +206 -28
- data/src/core/lib/json/json_writer.cc +111 -24
- data/src/core/lib/security/credentials/composite/composite_credentials.cc +7 -0
- data/src/core/lib/security/credentials/composite/composite_credentials.h +5 -1
- data/src/core/lib/security/credentials/credentials.h +10 -1
- data/src/core/lib/security/credentials/fake/fake_credentials.h +2 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -4
- data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -1
- data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +20 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +8 -0
- data/src/core/lib/security/credentials/tls/{spiffe_credentials.cc → tls_credentials.cc} +23 -24
- data/src/core/lib/security/credentials/tls/{spiffe_credentials.h → tls_credentials.h} +9 -9
- data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +13 -0
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +22 -2
- data/src/core/lib/security/security_connector/load_system_roots_fallback.cc +2 -2
- data/src/core/lib/security/security_connector/load_system_roots_linux.cc +2 -2
- data/src/core/lib/security/security_connector/local/local_security_connector.cc +30 -3
- data/src/core/lib/security/security_connector/ssl_utils.cc +45 -3
- data/src/core/lib/security/security_connector/ssl_utils.h +12 -0
- data/src/core/lib/security/security_connector/tls/{spiffe_security_connector.cc → tls_security_connector.cc} +82 -69
- data/src/core/lib/security/security_connector/tls/{spiffe_security_connector.h → tls_security_connector.h} +17 -18
- data/src/core/lib/security/transport/client_auth_filter.cc +33 -0
- data/src/core/lib/surface/completion_queue.cc +22 -1
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +11 -1
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +1 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +3 -3
- data/src/core/tsi/fake_transport_security.cc +7 -3
- data/src/core/tsi/fake_transport_security.h +2 -0
- data/src/core/tsi/ssl_transport_security.cc +144 -8
- data/src/core/tsi/ssl_transport_security.h +15 -1
- data/src/core/tsi/transport_security.cc +13 -0
- data/src/core/tsi/transport_security_grpc.cc +2 -2
- data/src/core/tsi/transport_security_grpc.h +2 -2
- data/src/core/tsi/transport_security_interface.h +12 -0
- data/src/ruby/bin/math_pb.rb +5 -5
- data/src/ruby/ext/grpc/rb_call_credentials.c +4 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +4 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/grpc/health/v1/health_pb.rb +3 -3
- data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +1 -1
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +23 -13
- data/third_party/abseil-cpp/absl/algorithm/algorithm.h +159 -0
- data/third_party/abseil-cpp/absl/base/attributes.h +609 -0
- data/third_party/abseil-cpp/absl/base/call_once.h +226 -0
- data/third_party/abseil-cpp/absl/base/casts.h +184 -0
- data/third_party/abseil-cpp/absl/base/config.h +622 -0
- data/third_party/abseil-cpp/absl/base/const_init.h +76 -0
- data/third_party/abseil-cpp/absl/base/dynamic_annotations.cc +129 -0
- data/third_party/abseil-cpp/absl/base/dynamic_annotations.h +389 -0
- data/third_party/abseil-cpp/absl/base/internal/atomic_hook.h +179 -0
- data/third_party/abseil-cpp/absl/base/internal/bits.h +218 -0
- data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +107 -0
- data/third_party/abseil-cpp/absl/base/internal/cycleclock.h +94 -0
- data/third_party/abseil-cpp/absl/base/internal/endian.h +266 -0
- data/third_party/abseil-cpp/absl/base/internal/hide_ptr.h +51 -0
- data/third_party/abseil-cpp/absl/base/internal/identity.h +37 -0
- data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +107 -0
- data/third_party/abseil-cpp/absl/base/internal/invoke.h +187 -0
- data/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h +107 -0
- data/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h +52 -0
- data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +237 -0
- data/third_party/abseil-cpp/absl/base/internal/raw_logging.h +179 -0
- data/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h +58 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +233 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock.h +243 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc +35 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc +67 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc +46 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc +81 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h +93 -0
- data/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc +37 -0
- data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +414 -0
- data/third_party/abseil-cpp/absl/base/internal/sysinfo.h +66 -0
- data/third_party/abseil-cpp/absl/base/internal/thread_annotations.h +271 -0
- data/third_party/abseil-cpp/absl/base/internal/thread_identity.cc +140 -0
- data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +250 -0
- data/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc +108 -0
- data/third_party/abseil-cpp/absl/base/internal/throw_delegate.h +75 -0
- data/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h +66 -0
- data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +158 -0
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +103 -0
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +124 -0
- data/third_party/abseil-cpp/absl/base/log_severity.cc +27 -0
- data/third_party/abseil-cpp/absl/base/log_severity.h +121 -0
- data/third_party/abseil-cpp/absl/base/macros.h +220 -0
- data/third_party/abseil-cpp/absl/base/optimization.h +181 -0
- data/third_party/abseil-cpp/absl/base/options.h +214 -0
- data/third_party/abseil-cpp/absl/base/policy_checks.h +111 -0
- data/third_party/abseil-cpp/absl/base/port.h +26 -0
- data/third_party/abseil-cpp/absl/base/thread_annotations.h +280 -0
- data/third_party/abseil-cpp/absl/container/inlined_vector.h +848 -0
- data/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h +265 -0
- data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +892 -0
- data/third_party/abseil-cpp/absl/memory/memory.h +695 -0
- data/third_party/abseil-cpp/absl/meta/type_traits.h +759 -0
- data/third_party/abseil-cpp/absl/numeric/int128.cc +404 -0
- data/third_party/abseil-cpp/absl/numeric/int128.h +1091 -0
- data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +302 -0
- data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +308 -0
- data/third_party/abseil-cpp/absl/strings/ascii.cc +200 -0
- data/third_party/abseil-cpp/absl/strings/ascii.h +241 -0
- data/third_party/abseil-cpp/absl/strings/charconv.cc +985 -0
- data/third_party/abseil-cpp/absl/strings/charconv.h +119 -0
- data/third_party/abseil-cpp/absl/strings/escaping.cc +949 -0
- data/third_party/abseil-cpp/absl/strings/escaping.h +164 -0
- data/third_party/abseil-cpp/absl/strings/internal/char_map.h +156 -0
- data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +359 -0
- data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h +421 -0
- data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc +504 -0
- data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h +99 -0
- data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +180 -0
- data/third_party/abseil-cpp/absl/strings/internal/escaping.h +58 -0
- data/third_party/abseil-cpp/absl/strings/internal/memutil.cc +112 -0
- data/third_party/abseil-cpp/absl/strings/internal/memutil.h +148 -0
- data/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc +36 -0
- data/third_party/abseil-cpp/absl/strings/internal/ostringstream.h +89 -0
- data/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h +73 -0
- data/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h +248 -0
- data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +314 -0
- data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +455 -0
- data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +53 -0
- data/third_party/abseil-cpp/absl/strings/internal/utf8.h +50 -0
- data/third_party/abseil-cpp/absl/strings/match.cc +40 -0
- data/third_party/abseil-cpp/absl/strings/match.h +90 -0
- data/third_party/abseil-cpp/absl/strings/numbers.cc +916 -0
- data/third_party/abseil-cpp/absl/strings/numbers.h +263 -0
- data/third_party/abseil-cpp/absl/strings/str_cat.cc +246 -0
- data/third_party/abseil-cpp/absl/strings/str_cat.h +408 -0
- data/third_party/abseil-cpp/absl/strings/str_join.h +293 -0
- data/third_party/abseil-cpp/absl/strings/str_replace.cc +82 -0
- data/third_party/abseil-cpp/absl/strings/str_replace.h +219 -0
- data/third_party/abseil-cpp/absl/strings/str_split.cc +139 -0
- data/third_party/abseil-cpp/absl/strings/str_split.h +513 -0
- data/third_party/abseil-cpp/absl/strings/string_view.cc +235 -0
- data/third_party/abseil-cpp/absl/strings/string_view.h +615 -0
- data/third_party/abseil-cpp/absl/strings/strip.h +91 -0
- data/third_party/abseil-cpp/absl/strings/substitute.cc +171 -0
- data/third_party/abseil-cpp/absl/strings/substitute.h +693 -0
- data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +48 -0
- data/third_party/abseil-cpp/absl/types/bad_optional_access.h +78 -0
- data/third_party/abseil-cpp/absl/types/internal/optional.h +396 -0
- data/third_party/abseil-cpp/absl/types/internal/span.h +128 -0
- data/third_party/abseil-cpp/absl/types/optional.h +776 -0
- data/third_party/abseil-cpp/absl/types/span.h +713 -0
- data/third_party/abseil-cpp/absl/utility/utility.h +350 -0
- data/third_party/upb/upb/decode.c +4 -0
- data/third_party/upb/upb/port.c +0 -1
- data/third_party/upb/upb/port_def.inc +1 -3
- data/third_party/upb/upb/table.c +2 -1
- metadata +147 -43
- data/src/core/lib/json/json_common.h +0 -34
- data/src/core/lib/json/json_reader.h +0 -146
- data/src/core/lib/json/json_string.cc +0 -367
- data/src/core/lib/json/json_writer.h +0 -84
@@ -26,6 +26,7 @@
|
|
26
26
|
#include <grpc/support/alloc.h>
|
27
27
|
#include <grpc/support/log.h>
|
28
28
|
|
29
|
+
#include "src/core/lib/channel/channel_args.h"
|
29
30
|
#include "src/core/lib/iomgr/error.h"
|
30
31
|
#include "src/core/lib/iomgr/exec_ctx.h"
|
31
32
|
#include "src/core/lib/iomgr/iomgr_custom.h"
|
@@ -72,6 +73,7 @@ struct grpc_tcp_server {
|
|
72
73
|
grpc_closure* shutdown_complete;
|
73
74
|
|
74
75
|
bool shutdown;
|
76
|
+
bool so_reuseport;
|
75
77
|
|
76
78
|
grpc_resource_quota* resource_quota;
|
77
79
|
};
|
@@ -80,8 +82,13 @@ static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
|
|
80
82
|
const grpc_channel_args* args,
|
81
83
|
grpc_tcp_server** server) {
|
82
84
|
grpc_tcp_server* s = (grpc_tcp_server*)gpr_malloc(sizeof(grpc_tcp_server));
|
85
|
+
// Let the implementation decide if so_reuseport can be enabled or not.
|
86
|
+
s->so_reuseport = true;
|
83
87
|
s->resource_quota = grpc_resource_quota_create(nullptr);
|
84
88
|
for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
|
89
|
+
if (!grpc_channel_args_find_bool(args, GRPC_ARG_ALLOW_REUSEPORT, true)) {
|
90
|
+
s->so_reuseport = false;
|
91
|
+
}
|
85
92
|
if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
|
86
93
|
if (args->args[i].type == GRPC_ARG_POINTER) {
|
87
94
|
grpc_resource_quota_unref_internal(s->resource_quota);
|
@@ -280,9 +287,15 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s,
|
|
280
287
|
grpc_error* error;
|
281
288
|
grpc_resolved_address sockname_temp;
|
282
289
|
|
283
|
-
// The last argument
|
290
|
+
// NOTE(lidiz) The last argument is "flags" which is unused by other
|
291
|
+
// implementations. Python IO managers uses it to specify SO_REUSEPORT.
|
292
|
+
int flags = 0;
|
293
|
+
if (s->so_reuseport) {
|
294
|
+
flags |= GRPC_CUSTOM_SOCKET_OPT_SO_REUSEPORT;
|
295
|
+
}
|
296
|
+
|
284
297
|
error = grpc_custom_socket_vtable->bind(socket, (grpc_sockaddr*)addr->addr,
|
285
|
-
addr->len,
|
298
|
+
addr->len, flags);
|
286
299
|
if (error != GRPC_ERROR_NONE) {
|
287
300
|
return error;
|
288
301
|
}
|
@@ -157,6 +157,14 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
|
|
157
157
|
if (err != GRPC_ERROR_NONE) goto error;
|
158
158
|
}
|
159
159
|
|
160
|
+
#ifdef GRPC_LINUX_ERRQUEUE
|
161
|
+
err = grpc_set_socket_zerocopy(fd);
|
162
|
+
if (err != GRPC_ERROR_NONE) {
|
163
|
+
/* it's not fatal, so just log it. */
|
164
|
+
gpr_log(GPR_DEBUG, "Node does not support SO_ZEROCOPY, continuing.");
|
165
|
+
GRPC_ERROR_UNREF(err);
|
166
|
+
}
|
167
|
+
#endif
|
160
168
|
err = grpc_set_socket_nonblocking(fd, 1);
|
161
169
|
if (err != GRPC_ERROR_NONE) goto error;
|
162
170
|
err = grpc_set_socket_cloexec(fd, 1);
|
data/src/core/lib/json/json.h
CHANGED
@@ -24,7 +24,17 @@
|
|
24
24
|
#include <stdbool.h>
|
25
25
|
#include <stdlib.h>
|
26
26
|
|
27
|
-
|
27
|
+
/* The various json types. */
|
28
|
+
typedef enum {
|
29
|
+
GRPC_JSON_OBJECT,
|
30
|
+
GRPC_JSON_ARRAY,
|
31
|
+
GRPC_JSON_STRING,
|
32
|
+
GRPC_JSON_NUMBER,
|
33
|
+
GRPC_JSON_TRUE,
|
34
|
+
GRPC_JSON_FALSE,
|
35
|
+
GRPC_JSON_NULL,
|
36
|
+
GRPC_JSON_TOP_LEVEL
|
37
|
+
} grpc_json_type;
|
28
38
|
|
29
39
|
/* A tree-like structure to hold json values. The key and value pointers
|
30
40
|
* are not owned by it.
|
@@ -22,76 +22,227 @@
|
|
22
22
|
|
23
23
|
#include <grpc/support/log.h>
|
24
24
|
|
25
|
-
#include "src/core/lib/json/
|
25
|
+
#include "src/core/lib/json/json.h"
|
26
|
+
|
27
|
+
typedef enum {
|
28
|
+
GRPC_JSON_STATE_OBJECT_KEY_BEGIN,
|
29
|
+
GRPC_JSON_STATE_OBJECT_KEY_STRING,
|
30
|
+
GRPC_JSON_STATE_OBJECT_KEY_END,
|
31
|
+
GRPC_JSON_STATE_VALUE_BEGIN,
|
32
|
+
GRPC_JSON_STATE_VALUE_STRING,
|
33
|
+
GRPC_JSON_STATE_STRING_ESCAPE,
|
34
|
+
GRPC_JSON_STATE_STRING_ESCAPE_U1,
|
35
|
+
GRPC_JSON_STATE_STRING_ESCAPE_U2,
|
36
|
+
GRPC_JSON_STATE_STRING_ESCAPE_U3,
|
37
|
+
GRPC_JSON_STATE_STRING_ESCAPE_U4,
|
38
|
+
GRPC_JSON_STATE_VALUE_NUMBER,
|
39
|
+
GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL,
|
40
|
+
GRPC_JSON_STATE_VALUE_NUMBER_ZERO,
|
41
|
+
GRPC_JSON_STATE_VALUE_NUMBER_DOT,
|
42
|
+
GRPC_JSON_STATE_VALUE_NUMBER_E,
|
43
|
+
GRPC_JSON_STATE_VALUE_NUMBER_EPM,
|
44
|
+
GRPC_JSON_STATE_VALUE_TRUE_R,
|
45
|
+
GRPC_JSON_STATE_VALUE_TRUE_U,
|
46
|
+
GRPC_JSON_STATE_VALUE_TRUE_E,
|
47
|
+
GRPC_JSON_STATE_VALUE_FALSE_A,
|
48
|
+
GRPC_JSON_STATE_VALUE_FALSE_L,
|
49
|
+
GRPC_JSON_STATE_VALUE_FALSE_S,
|
50
|
+
GRPC_JSON_STATE_VALUE_FALSE_E,
|
51
|
+
GRPC_JSON_STATE_VALUE_NULL_U,
|
52
|
+
GRPC_JSON_STATE_VALUE_NULL_L1,
|
53
|
+
GRPC_JSON_STATE_VALUE_NULL_L2,
|
54
|
+
GRPC_JSON_STATE_VALUE_END,
|
55
|
+
GRPC_JSON_STATE_END
|
56
|
+
} grpc_json_reader_state;
|
57
|
+
|
58
|
+
enum {
|
59
|
+
/* The first non-unicode value is 0x110000. But let's pick
|
60
|
+
* a value high enough to start our error codes from. These
|
61
|
+
* values are safe to return from the read_char function.
|
62
|
+
*/
|
63
|
+
GRPC_JSON_READ_CHAR_EOF = 0x7ffffff0,
|
64
|
+
GRPC_JSON_READ_CHAR_EAGAIN,
|
65
|
+
GRPC_JSON_READ_CHAR_ERROR
|
66
|
+
};
|
67
|
+
|
68
|
+
typedef struct grpc_json_reader {
|
69
|
+
/* That structure is fully private, and initialized by grpc_json_reader_init.
|
70
|
+
* The definition is public so you can put it on your stack.
|
71
|
+
*/
|
72
|
+
|
73
|
+
int depth;
|
74
|
+
int in_object;
|
75
|
+
int in_array;
|
76
|
+
int escaped_string_was_key;
|
77
|
+
int container_just_begun;
|
78
|
+
uint16_t unicode_char, unicode_high_surrogate;
|
79
|
+
grpc_json_reader_state state;
|
80
|
+
|
81
|
+
grpc_json* top;
|
82
|
+
grpc_json* current_container;
|
83
|
+
grpc_json* current_value;
|
84
|
+
uint8_t* input;
|
85
|
+
uint8_t* key;
|
86
|
+
uint8_t* string;
|
87
|
+
uint8_t* string_ptr;
|
88
|
+
size_t remaining_input;
|
89
|
+
} grpc_json_reader;
|
90
|
+
|
91
|
+
/* The return type of the parser. */
|
92
|
+
typedef enum {
|
93
|
+
GRPC_JSON_DONE, /* The parser finished successfully. */
|
94
|
+
GRPC_JSON_EAGAIN, /* The parser yields to get more data. */
|
95
|
+
GRPC_JSON_READ_ERROR, /* The parser passes through a read error. */
|
96
|
+
GRPC_JSON_PARSE_ERROR, /* The parser found an error in the json stream. */
|
97
|
+
GRPC_JSON_INTERNAL_ERROR /* The parser got an internal error. */
|
98
|
+
} grpc_json_reader_status;
|
26
99
|
|
27
100
|
static void json_reader_string_clear(grpc_json_reader* reader) {
|
28
|
-
|
101
|
+
if (reader->string) {
|
102
|
+
GPR_ASSERT(reader->string_ptr < reader->input);
|
103
|
+
*reader->string_ptr++ = 0;
|
104
|
+
}
|
105
|
+
reader->string = reader->string_ptr;
|
29
106
|
}
|
30
107
|
|
31
108
|
static void json_reader_string_add_char(grpc_json_reader* reader, uint32_t c) {
|
32
|
-
reader->
|
109
|
+
GPR_ASSERT(reader->string_ptr < reader->input);
|
110
|
+
GPR_ASSERT(c <= 0xff);
|
111
|
+
*reader->string_ptr++ = static_cast<uint8_t>(c);
|
33
112
|
}
|
34
113
|
|
35
|
-
static void json_reader_string_add_utf32(grpc_json_reader* reader,
|
36
|
-
|
37
|
-
|
114
|
+
static void json_reader_string_add_utf32(grpc_json_reader* reader, uint32_t c) {
|
115
|
+
if (c <= 0x7f) {
|
116
|
+
json_reader_string_add_char(reader, c);
|
117
|
+
} else if (c <= 0x7ff) {
|
118
|
+
uint32_t b1 = 0xc0 | ((c >> 6) & 0x1f);
|
119
|
+
uint32_t b2 = 0x80 | (c & 0x3f);
|
120
|
+
json_reader_string_add_char(reader, b1);
|
121
|
+
json_reader_string_add_char(reader, b2);
|
122
|
+
} else if (c <= 0xffff) {
|
123
|
+
uint32_t b1 = 0xe0 | ((c >> 12) & 0x0f);
|
124
|
+
uint32_t b2 = 0x80 | ((c >> 6) & 0x3f);
|
125
|
+
uint32_t b3 = 0x80 | (c & 0x3f);
|
126
|
+
json_reader_string_add_char(reader, b1);
|
127
|
+
json_reader_string_add_char(reader, b2);
|
128
|
+
json_reader_string_add_char(reader, b3);
|
129
|
+
} else if (c <= 0x1fffff) {
|
130
|
+
uint32_t b1 = 0xf0 | ((c >> 18) & 0x07);
|
131
|
+
uint32_t b2 = 0x80 | ((c >> 12) & 0x3f);
|
132
|
+
uint32_t b3 = 0x80 | ((c >> 6) & 0x3f);
|
133
|
+
uint32_t b4 = 0x80 | (c & 0x3f);
|
134
|
+
json_reader_string_add_char(reader, b1);
|
135
|
+
json_reader_string_add_char(reader, b2);
|
136
|
+
json_reader_string_add_char(reader, b3);
|
137
|
+
json_reader_string_add_char(reader, b4);
|
138
|
+
}
|
38
139
|
}
|
39
140
|
|
40
141
|
static uint32_t grpc_json_reader_read_char(grpc_json_reader* reader) {
|
41
|
-
|
142
|
+
if (reader->remaining_input == 0) return GRPC_JSON_READ_CHAR_EOF;
|
143
|
+
uint32_t r = *reader->input++;
|
144
|
+
reader->remaining_input--;
|
145
|
+
if (r == 0) {
|
146
|
+
reader->remaining_input = 0;
|
147
|
+
return GRPC_JSON_READ_CHAR_EOF;
|
148
|
+
}
|
149
|
+
return r;
|
150
|
+
}
|
151
|
+
|
152
|
+
/* Helper function to create a new grpc_json object and link it into
|
153
|
+
* our tree-in-progress inside our opaque structure.
|
154
|
+
*/
|
155
|
+
static grpc_json* json_create_and_link(grpc_json_reader* reader,
|
156
|
+
grpc_json_type type) {
|
157
|
+
grpc_json* json = grpc_json_create(type);
|
158
|
+
json->parent = reader->current_container;
|
159
|
+
json->prev = reader->current_value;
|
160
|
+
reader->current_value = json;
|
161
|
+
if (json->prev) {
|
162
|
+
json->prev->next = json;
|
163
|
+
}
|
164
|
+
if (json->parent) {
|
165
|
+
if (!json->parent->child) {
|
166
|
+
json->parent->child = json;
|
167
|
+
}
|
168
|
+
if (json->parent->type == GRPC_JSON_OBJECT) {
|
169
|
+
json->key = reinterpret_cast<char*>(reader->key);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
if (!reader->top) {
|
173
|
+
reader->top = json;
|
174
|
+
}
|
175
|
+
return json;
|
42
176
|
}
|
43
177
|
|
44
178
|
static void json_reader_container_begins(grpc_json_reader* reader,
|
45
179
|
grpc_json_type type) {
|
46
|
-
|
180
|
+
GPR_ASSERT(type == GRPC_JSON_ARRAY || type == GRPC_JSON_OBJECT);
|
181
|
+
grpc_json* container = json_create_and_link(reader, type);
|
182
|
+
reader->current_container = container;
|
183
|
+
reader->current_value = nullptr;
|
47
184
|
}
|
48
185
|
|
49
186
|
static grpc_json_type grpc_json_reader_container_ends(
|
50
187
|
grpc_json_reader* reader) {
|
51
|
-
|
188
|
+
grpc_json_type container_type = GRPC_JSON_TOP_LEVEL;
|
189
|
+
GPR_ASSERT(reader->current_container);
|
190
|
+
reader->current_value = reader->current_container;
|
191
|
+
reader->current_container = reader->current_container->parent;
|
192
|
+
if (reader->current_container) {
|
193
|
+
container_type = reader->current_container->type;
|
194
|
+
}
|
195
|
+
return container_type;
|
52
196
|
}
|
53
197
|
|
54
198
|
static void json_reader_set_key(grpc_json_reader* reader) {
|
55
|
-
reader->
|
199
|
+
reader->key = reader->string;
|
56
200
|
}
|
57
201
|
|
58
202
|
static void json_reader_set_string(grpc_json_reader* reader) {
|
59
|
-
|
203
|
+
grpc_json* json = json_create_and_link(reader, GRPC_JSON_STRING);
|
204
|
+
json->value = reinterpret_cast<char*>(reader->string);
|
60
205
|
}
|
61
206
|
|
62
207
|
static int json_reader_set_number(grpc_json_reader* reader) {
|
63
|
-
|
208
|
+
grpc_json* json = json_create_and_link(reader, GRPC_JSON_NUMBER);
|
209
|
+
json->value = reinterpret_cast<char*>(reader->string);
|
210
|
+
return 1;
|
64
211
|
}
|
65
212
|
|
66
213
|
static void json_reader_set_true(grpc_json_reader* reader) {
|
67
|
-
|
214
|
+
json_create_and_link(reader, GRPC_JSON_TRUE);
|
68
215
|
}
|
69
216
|
|
70
217
|
static void json_reader_set_false(grpc_json_reader* reader) {
|
71
|
-
|
218
|
+
json_create_and_link(reader, GRPC_JSON_FALSE);
|
72
219
|
}
|
73
220
|
|
74
221
|
static void json_reader_set_null(grpc_json_reader* reader) {
|
75
|
-
|
76
|
-
}
|
77
|
-
|
78
|
-
/* Call this function to initialize the reader structure. */
|
79
|
-
void grpc_json_reader_init(grpc_json_reader* reader,
|
80
|
-
grpc_json_reader_vtable* vtable, void* userdata) {
|
81
|
-
memset(reader, 0, sizeof(*reader));
|
82
|
-
reader->vtable = vtable;
|
83
|
-
reader->userdata = userdata;
|
84
|
-
json_reader_string_clear(reader);
|
85
|
-
reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
|
222
|
+
json_create_and_link(reader, GRPC_JSON_NULL);
|
86
223
|
}
|
87
224
|
|
88
|
-
int
|
225
|
+
static int json_reader_is_complete(grpc_json_reader* reader) {
|
89
226
|
return ((reader->depth == 0) &&
|
90
227
|
((reader->state == GRPC_JSON_STATE_END) ||
|
91
228
|
(reader->state == GRPC_JSON_STATE_VALUE_END)));
|
92
229
|
}
|
93
230
|
|
94
|
-
|
231
|
+
/* Call this function to start parsing the input. It will return the following:
|
232
|
+
* . GRPC_JSON_DONE if the input got eof, and the parsing finished
|
233
|
+
* successfully.
|
234
|
+
* . GRPC_JSON_EAGAIN if the read_char function returned again. Call the
|
235
|
+
* parser again as needed. It is okay to call the parser in polling mode,
|
236
|
+
* although a bit dull.
|
237
|
+
* . GRPC_JSON_READ_ERROR if the read_char function returned an error. The
|
238
|
+
* state isn't broken however, and the function can be called again if the
|
239
|
+
* error has been corrected. But please use the EAGAIN feature instead for
|
240
|
+
* consistency.
|
241
|
+
* . GRPC_JSON_PARSE_ERROR if the input was somehow invalid.
|
242
|
+
* . GRPC_JSON_INTERNAL_ERROR if the parser somehow ended into an invalid
|
243
|
+
* internal state.
|
244
|
+
*/
|
245
|
+
static grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader) {
|
95
246
|
uint32_t c, success;
|
96
247
|
|
97
248
|
/* This state-machine is a strict implementation of ECMA-404 */
|
@@ -106,7 +257,7 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader) {
|
|
106
257
|
return GRPC_JSON_EAGAIN;
|
107
258
|
|
108
259
|
case GRPC_JSON_READ_CHAR_EOF:
|
109
|
-
if (
|
260
|
+
if (json_reader_is_complete(reader)) {
|
110
261
|
return GRPC_JSON_DONE;
|
111
262
|
} else {
|
112
263
|
return GRPC_JSON_PARSE_ERROR;
|
@@ -661,3 +812,30 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader) {
|
|
661
812
|
|
662
813
|
GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
|
663
814
|
}
|
815
|
+
|
816
|
+
/* And finally, let's define our public API. */
|
817
|
+
grpc_json* grpc_json_parse_string_with_len(char* input, size_t size) {
|
818
|
+
if (input == nullptr) return nullptr;
|
819
|
+
// Initialize reader.
|
820
|
+
grpc_json_reader reader;
|
821
|
+
memset(&reader, 0, sizeof(reader));
|
822
|
+
reader.string_ptr = reader.input = reinterpret_cast<uint8_t*>(input);
|
823
|
+
reader.remaining_input = size;
|
824
|
+
json_reader_string_clear(&reader);
|
825
|
+
reader.state = GRPC_JSON_STATE_VALUE_BEGIN;
|
826
|
+
// Perform read.
|
827
|
+
grpc_json_reader_status status = grpc_json_reader_run(&reader);
|
828
|
+
// Process results.
|
829
|
+
grpc_json* json = reader.top;
|
830
|
+
if ((status != GRPC_JSON_DONE) && json != nullptr) {
|
831
|
+
grpc_json_destroy(json);
|
832
|
+
json = nullptr;
|
833
|
+
}
|
834
|
+
return json;
|
835
|
+
}
|
836
|
+
|
837
|
+
#define UNBOUND_JSON_STRING_LENGTH 0x7fffffff
|
838
|
+
|
839
|
+
grpc_json* grpc_json_parse_string(char* input) {
|
840
|
+
return grpc_json_parse_string_with_len(input, UNBOUND_JSON_STRING_LENGTH);
|
841
|
+
}
|
@@ -18,31 +18,70 @@
|
|
18
18
|
|
19
19
|
#include <grpc/support/port_platform.h>
|
20
20
|
|
21
|
+
#include <stdlib.h>
|
21
22
|
#include <string.h>
|
22
23
|
|
23
|
-
#include
|
24
|
+
#include <grpc/support/alloc.h>
|
25
|
+
#include <grpc/support/log.h>
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
#include "src/core/lib/json/json.h"
|
28
|
+
|
29
|
+
/* The idea of the writer is basically symmetrical of the reader. While the
|
30
|
+
* reader emits various calls to your code, the writer takes basically the
|
31
|
+
* same calls and emit json out of it. It doesn't try to make any check on
|
32
|
+
* the order of the calls you do on it. Meaning you can theorically force
|
33
|
+
* it to generate invalid json.
|
34
|
+
*
|
35
|
+
* Also, unlike the reader, the writer expects UTF-8 encoded input strings.
|
36
|
+
* These strings will be UTF-8 validated, and any invalid character will
|
37
|
+
* cut the conversion short, before any invalid UTF-8 sequence, thus forming
|
38
|
+
* a valid UTF-8 string overall.
|
39
|
+
*/
|
40
|
+
|
41
|
+
typedef struct grpc_json_writer {
|
42
|
+
int indent;
|
43
|
+
int depth;
|
44
|
+
int container_empty;
|
45
|
+
int got_key;
|
46
|
+
char* output;
|
47
|
+
size_t free_space;
|
48
|
+
size_t string_len;
|
49
|
+
size_t allocated;
|
50
|
+
} grpc_json_writer;
|
51
|
+
|
52
|
+
/* This function checks if there's enough space left in the output buffer,
|
53
|
+
* and will enlarge it if necessary. We're only allocating chunks of 256
|
54
|
+
* bytes at a time (or multiples thereof).
|
55
|
+
*/
|
56
|
+
static void json_writer_output_check(grpc_json_writer* writer, size_t needed) {
|
57
|
+
if (writer->free_space >= needed) return;
|
58
|
+
needed -= writer->free_space;
|
59
|
+
/* Round up by 256 bytes. */
|
60
|
+
needed = (needed + 0xff) & ~0xffU;
|
61
|
+
writer->output = static_cast<char*>(
|
62
|
+
gpr_realloc(writer->output, writer->allocated + needed));
|
63
|
+
writer->free_space += needed;
|
64
|
+
writer->allocated += needed;
|
27
65
|
}
|
28
66
|
|
29
|
-
static void
|
30
|
-
|
31
|
-
writer->
|
67
|
+
static void json_writer_output_char(grpc_json_writer* writer, char c) {
|
68
|
+
json_writer_output_check(writer, 1);
|
69
|
+
writer->output[writer->string_len++] = c;
|
70
|
+
writer->free_space--;
|
32
71
|
}
|
33
72
|
|
34
73
|
static void json_writer_output_string_with_len(grpc_json_writer* writer,
|
35
74
|
const char* str, size_t len) {
|
36
|
-
|
75
|
+
json_writer_output_check(writer, len);
|
76
|
+
memcpy(writer->output + writer->string_len, str, len);
|
77
|
+
writer->string_len += len;
|
78
|
+
writer->free_space -= len;
|
37
79
|
}
|
38
80
|
|
39
|
-
void
|
40
|
-
|
41
|
-
|
42
|
-
writer
|
43
|
-
writer->indent = indent;
|
44
|
-
writer->vtable = vtable;
|
45
|
-
writer->userdata = userdata;
|
81
|
+
static void json_writer_output_string(grpc_json_writer* writer,
|
82
|
+
const char* str) {
|
83
|
+
size_t len = strlen(str);
|
84
|
+
json_writer_output_string_with_len(writer, str, len);
|
46
85
|
}
|
47
86
|
|
48
87
|
static void json_writer_output_indent(grpc_json_writer* writer) {
|
@@ -192,8 +231,8 @@ static void json_writer_escape_string(grpc_json_writer* writer,
|
|
192
231
|
json_writer_output_char(writer, '"');
|
193
232
|
}
|
194
233
|
|
195
|
-
void grpc_json_writer_container_begins(grpc_json_writer* writer,
|
196
|
-
|
234
|
+
static void grpc_json_writer_container_begins(grpc_json_writer* writer,
|
235
|
+
grpc_json_type type) {
|
197
236
|
if (!writer->got_key) json_writer_value_end(writer);
|
198
237
|
json_writer_output_indent(writer);
|
199
238
|
json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '{' : '[');
|
@@ -202,8 +241,8 @@ void grpc_json_writer_container_begins(grpc_json_writer* writer,
|
|
202
241
|
writer->depth++;
|
203
242
|
}
|
204
243
|
|
205
|
-
void grpc_json_writer_container_ends(grpc_json_writer* writer,
|
206
|
-
|
244
|
+
static void grpc_json_writer_container_ends(grpc_json_writer* writer,
|
245
|
+
grpc_json_type type) {
|
207
246
|
if (writer->indent && !writer->container_empty)
|
208
247
|
json_writer_output_char(writer, '\n');
|
209
248
|
writer->depth--;
|
@@ -213,7 +252,8 @@ void grpc_json_writer_container_ends(grpc_json_writer* writer,
|
|
213
252
|
writer->got_key = 0;
|
214
253
|
}
|
215
254
|
|
216
|
-
void grpc_json_writer_object_key(grpc_json_writer* writer,
|
255
|
+
static void grpc_json_writer_object_key(grpc_json_writer* writer,
|
256
|
+
const char* string) {
|
217
257
|
json_writer_value_end(writer);
|
218
258
|
json_writer_output_indent(writer);
|
219
259
|
json_writer_escape_string(writer, string);
|
@@ -221,25 +261,72 @@ void grpc_json_writer_object_key(grpc_json_writer* writer, const char* string) {
|
|
221
261
|
writer->got_key = 1;
|
222
262
|
}
|
223
263
|
|
224
|
-
void grpc_json_writer_value_raw(grpc_json_writer* writer,
|
264
|
+
static void grpc_json_writer_value_raw(grpc_json_writer* writer,
|
265
|
+
const char* string) {
|
225
266
|
if (!writer->got_key) json_writer_value_end(writer);
|
226
267
|
json_writer_output_indent(writer);
|
227
268
|
json_writer_output_string(writer, string);
|
228
269
|
writer->got_key = 0;
|
229
270
|
}
|
230
271
|
|
231
|
-
void grpc_json_writer_value_raw_with_len(grpc_json_writer* writer,
|
232
|
-
|
272
|
+
static void grpc_json_writer_value_raw_with_len(grpc_json_writer* writer,
|
273
|
+
const char* string,
|
274
|
+
size_t len) {
|
233
275
|
if (!writer->got_key) json_writer_value_end(writer);
|
234
276
|
json_writer_output_indent(writer);
|
235
277
|
json_writer_output_string_with_len(writer, string, len);
|
236
278
|
writer->got_key = 0;
|
237
279
|
}
|
238
280
|
|
239
|
-
void grpc_json_writer_value_string(grpc_json_writer* writer,
|
240
|
-
|
281
|
+
static void grpc_json_writer_value_string(grpc_json_writer* writer,
|
282
|
+
const char* string) {
|
241
283
|
if (!writer->got_key) json_writer_value_end(writer);
|
242
284
|
json_writer_output_indent(writer);
|
243
285
|
json_writer_escape_string(writer, string);
|
244
286
|
writer->got_key = 0;
|
245
287
|
}
|
288
|
+
|
289
|
+
static void json_dump_recursive(grpc_json_writer* writer, const grpc_json* json,
|
290
|
+
int in_object) {
|
291
|
+
while (json) {
|
292
|
+
if (in_object) grpc_json_writer_object_key(writer, json->key);
|
293
|
+
switch (json->type) {
|
294
|
+
case GRPC_JSON_OBJECT:
|
295
|
+
case GRPC_JSON_ARRAY:
|
296
|
+
grpc_json_writer_container_begins(writer, json->type);
|
297
|
+
if (json->child)
|
298
|
+
json_dump_recursive(writer, json->child,
|
299
|
+
json->type == GRPC_JSON_OBJECT);
|
300
|
+
grpc_json_writer_container_ends(writer, json->type);
|
301
|
+
break;
|
302
|
+
case GRPC_JSON_STRING:
|
303
|
+
grpc_json_writer_value_string(writer, json->value);
|
304
|
+
break;
|
305
|
+
case GRPC_JSON_NUMBER:
|
306
|
+
grpc_json_writer_value_raw(writer, json->value);
|
307
|
+
break;
|
308
|
+
case GRPC_JSON_TRUE:
|
309
|
+
grpc_json_writer_value_raw_with_len(writer, "true", 4);
|
310
|
+
break;
|
311
|
+
case GRPC_JSON_FALSE:
|
312
|
+
grpc_json_writer_value_raw_with_len(writer, "false", 5);
|
313
|
+
break;
|
314
|
+
case GRPC_JSON_NULL:
|
315
|
+
grpc_json_writer_value_raw_with_len(writer, "null", 4);
|
316
|
+
break;
|
317
|
+
default:
|
318
|
+
GPR_UNREACHABLE_CODE(abort());
|
319
|
+
}
|
320
|
+
json = json->next;
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
324
|
+
char* grpc_json_dump_to_string(const grpc_json* json, int indent) {
|
325
|
+
grpc_json_writer writer;
|
326
|
+
memset(&writer, 0, sizeof(writer));
|
327
|
+
writer.container_empty = 1;
|
328
|
+
writer.indent = indent;
|
329
|
+
json_dump_recursive(&writer, json, 0);
|
330
|
+
json_writer_output_char(&writer, 0);
|
331
|
+
return writer.output;
|
332
|
+
}
|