grpc 1.22.1 → 1.23.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.

Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +487 -649
  3. data/include/grpc/grpc_security.h +25 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +11 -2
  5. data/include/grpc/impl/codegen/port_platform.h +12 -0
  6. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
  7. data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
  8. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
  9. data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
  10. data/src/core/ext/filters/client_channel/connector.h +10 -2
  11. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
  12. data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
  13. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
  14. data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
  19. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
  20. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
  22. data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
  23. data/src/core/ext/filters/client_channel/resolver.h +3 -11
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
  31. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
  32. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
  33. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
  34. data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
  35. data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
  36. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
  37. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
  38. data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
  39. data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
  40. data/src/core/ext/filters/client_channel/subchannel.h +65 -45
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
  42. data/src/core/ext/filters/client_idle/client_idle_filter.cc +264 -0
  43. data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
  44. data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
  45. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
  46. data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
  47. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
  48. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
  49. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +41 -60
  50. data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
  51. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
  52. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
  53. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +0 -1
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +0 -8
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +0 -7
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +0 -1
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +137 -80
  59. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
  60. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
  61. data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
  62. data/src/core/ext/transport/chttp2/transport/internal.h +6 -9
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +37 -20
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +0 -1
  66. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  67. data/src/core/lib/channel/channelz.cc +80 -33
  68. data/src/core/lib/channel/channelz.h +28 -13
  69. data/src/core/lib/compression/compression.cc +1 -2
  70. data/src/core/lib/compression/compression_args.cc +13 -6
  71. data/src/core/lib/compression/compression_args.h +3 -2
  72. data/src/core/lib/compression/compression_internal.cc +1 -1
  73. data/src/core/lib/gpr/env_linux.cc +10 -21
  74. data/src/core/lib/gpr/env_posix.cc +0 -5
  75. data/src/core/lib/gpr/string.cc +7 -2
  76. data/src/core/lib/gpr/string.h +1 -0
  77. data/src/core/lib/gpr/sync_posix.cc +0 -129
  78. data/src/core/lib/gprpp/debug_location.h +3 -2
  79. data/src/core/lib/gprpp/fork.cc +14 -21
  80. data/src/core/lib/gprpp/fork.h +15 -4
  81. data/src/core/lib/gprpp/host_port.cc +118 -0
  82. data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
  83. data/src/core/lib/gprpp/map.h +25 -0
  84. data/src/core/lib/gprpp/memory.h +26 -9
  85. data/src/core/lib/gprpp/ref_counted.h +63 -21
  86. data/src/core/lib/gprpp/string_view.h +143 -0
  87. data/src/core/lib/gprpp/thd.h +10 -1
  88. data/src/core/lib/gprpp/thd_posix.cc +25 -0
  89. data/src/core/lib/gprpp/thd_windows.cc +9 -1
  90. data/src/core/lib/http/httpcli_security_connector.cc +3 -1
  91. data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
  92. data/src/core/lib/iomgr/cfstream_handle.h +8 -2
  93. data/src/core/lib/iomgr/combiner.cc +4 -4
  94. data/src/core/lib/iomgr/error.cc +18 -8
  95. data/src/core/lib/iomgr/error.h +2 -0
  96. data/src/core/lib/iomgr/ev_posix.cc +4 -2
  97. data/src/core/lib/iomgr/executor.cc +4 -1
  98. data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
  99. data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
  100. data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
  101. data/src/core/lib/iomgr/executor/threadpool.h +153 -0
  102. data/src/core/lib/iomgr/fork_posix.cc +4 -2
  103. data/src/core/lib/iomgr/iocp_windows.cc +2 -2
  104. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
  105. data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
  106. data/src/core/lib/iomgr/lockfree_event.cc +3 -3
  107. data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
  108. data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
  109. data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
  110. data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
  111. data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
  112. data/src/core/lib/iomgr/socket_windows.h +1 -1
  113. data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
  114. data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
  115. data/src/core/lib/iomgr/tcp_custom.cc +4 -0
  116. data/src/core/lib/iomgr/tcp_posix.cc +8 -2
  117. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
  118. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
  119. data/src/core/lib/iomgr/tcp_windows.cc +7 -7
  120. data/src/core/lib/iomgr/timer_custom.cc +1 -0
  121. data/src/core/lib/iomgr/timer_manager.cc +0 -29
  122. data/src/core/lib/security/credentials/credentials.cc +84 -0
  123. data/src/core/lib/security/credentials/credentials.h +58 -2
  124. data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
  125. data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
  126. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
  127. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
  128. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
  129. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
  130. data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
  131. data/src/core/lib/security/security_connector/security_connector.cc +1 -1
  132. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  133. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
  134. data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
  135. data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
  136. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
  137. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
  138. data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
  139. data/src/core/lib/security/util/json_util.cc +19 -5
  140. data/src/core/lib/security/util/json_util.h +3 -1
  141. data/src/core/lib/slice/slice.cc +69 -50
  142. data/src/core/lib/slice/slice_buffer.cc +6 -5
  143. data/src/core/lib/slice/slice_hash_table.h +3 -7
  144. data/src/core/lib/slice/slice_intern.cc +130 -39
  145. data/src/core/lib/slice/slice_internal.h +8 -0
  146. data/src/core/lib/slice/slice_utils.h +120 -0
  147. data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
  148. data/src/core/lib/surface/call.cc +8 -3
  149. data/src/core/lib/surface/channel.cc +31 -8
  150. data/src/core/lib/surface/completion_queue.cc +17 -7
  151. data/src/core/lib/surface/init_secure.cc +4 -1
  152. data/src/core/lib/surface/lame_client.cc +2 -2
  153. data/src/core/lib/surface/server.cc +34 -35
  154. data/src/core/lib/surface/server.h +8 -17
  155. data/src/core/lib/surface/version.cc +1 -1
  156. data/src/core/lib/transport/byte_stream.cc +3 -5
  157. data/src/core/lib/transport/byte_stream.h +1 -2
  158. data/src/core/lib/transport/error_utils.cc +10 -1
  159. data/src/core/lib/transport/metadata.cc +202 -35
  160. data/src/core/lib/transport/metadata.h +81 -6
  161. data/src/core/lib/transport/static_metadata.cc +1257 -465
  162. data/src/core/lib/transport/static_metadata.h +190 -347
  163. data/src/core/lib/transport/timeout_encoding.cc +7 -0
  164. data/src/core/lib/transport/timeout_encoding.h +3 -2
  165. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  166. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
  167. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
  168. data/src/core/tsi/ssl_transport_security.cc +35 -43
  169. data/src/core/tsi/ssl_transport_security.h +2 -1
  170. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  171. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  172. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  173. data/src/ruby/lib/grpc/grpc.rb +1 -1
  174. data/src/ruby/lib/grpc/version.rb +1 -1
  175. metadata +38 -32
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -245,6 +245,7 @@ static void custom_accept_callback(grpc_custom_socket* socket,
245
245
  static void custom_accept_callback(grpc_custom_socket* socket,
246
246
  grpc_custom_socket* client,
247
247
  grpc_error* error) {
248
+ grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
248
249
  grpc_core::ExecCtx exec_ctx;
249
250
  grpc_tcp_listener* sp = socket->listener;
250
251
  if (error != GRPC_ERROR_NONE) {
@@ -409,7 +409,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, SOCKET sock,
409
409
  gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
410
410
  gpr_free(utf8_message);
411
411
  closesocket(sock);
412
- return NULL;
412
+ return GRPC_ERROR_NONE;
413
413
  }
414
414
 
415
415
  error = prepare_socket(sock, addr, &port);
@@ -196,17 +196,17 @@ static void on_read(void* tcpp, grpc_error* error) {
196
196
  gpr_free(utf8_message);
197
197
  grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices);
198
198
  } else {
199
- if (info->bytes_transfered != 0 && !tcp->shutting_down) {
200
- GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length);
201
- if (static_cast<size_t>(info->bytes_transfered) !=
199
+ if (info->bytes_transferred != 0 && !tcp->shutting_down) {
200
+ GPR_ASSERT((size_t)info->bytes_transferred <= tcp->read_slices->length);
201
+ if (static_cast<size_t>(info->bytes_transferred) !=
202
202
  tcp->read_slices->length) {
203
203
  grpc_slice_buffer_trim_end(
204
204
  tcp->read_slices,
205
205
  tcp->read_slices->length -
206
- static_cast<size_t>(info->bytes_transfered),
206
+ static_cast<size_t>(info->bytes_transferred),
207
207
  &tcp->last_read_buffer);
208
208
  }
209
- GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length);
209
+ GPR_ASSERT((size_t)info->bytes_transferred == tcp->read_slices->length);
210
210
 
211
211
  if (grpc_tcp_trace.enabled()) {
212
212
  size_t i;
@@ -288,7 +288,7 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
288
288
 
289
289
  /* Did we get data immediately ? Yay. */
290
290
  if (info->wsa_error != WSAEWOULDBLOCK) {
291
- info->bytes_transfered = bytes_read;
291
+ info->bytes_transferred = bytes_read;
292
292
  GRPC_CLOSURE_SCHED(&tcp->on_read, GRPC_ERROR_NONE);
293
293
  return;
294
294
  }
@@ -333,7 +333,7 @@ static void on_write(void* tcpp, grpc_error* error) {
333
333
  if (info->wsa_error != 0) {
334
334
  error = GRPC_WSA_ERROR(info->wsa_error, "WSASend");
335
335
  } else {
336
- GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length);
336
+ GPR_ASSERT(info->bytes_transferred == tcp->write_slices->length);
337
337
  }
338
338
  }
339
339
 
@@ -32,6 +32,7 @@ static grpc_custom_timer_vtable* custom_timer_impl;
32
32
 
33
33
  void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error) {
34
34
  GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
35
+ grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
35
36
  grpc_core::ExecCtx exec_ctx;
36
37
  grpc_timer* timer = t->original;
37
38
  GPR_ASSERT(timer->pending);
@@ -61,15 +61,6 @@ static uint64_t g_timed_waiter_generation;
61
61
 
62
62
  static void timer_thread(void* completed_thread_ptr);
63
63
 
64
- // For debug of the timer manager crash only.
65
- // TODO (mxyan): remove after bug is fixed.
66
- #ifdef GRPC_DEBUG_TIMER_MANAGER
67
- extern int64_t g_timer_manager_init_count;
68
- extern int64_t g_timer_manager_shutdown_count;
69
- extern int64_t g_fork_count;
70
- extern int64_t g_next_value;
71
- #endif // GRPC_DEBUG_TIMER_MANAGER
72
-
73
64
  static void gc_completed_threads(void) {
74
65
  if (g_completed_threads != nullptr) {
75
66
  completed_thread* to_gc = g_completed_threads;
@@ -203,11 +194,6 @@ static bool wait_until(grpc_millis next) {
203
194
  gpr_log(GPR_INFO, "sleep until kicked");
204
195
  }
205
196
 
206
- // For debug of the timer manager crash only.
207
- // TODO (mxyan): remove after bug is fixed.
208
- #ifdef GRPC_DEBUG_TIMER_MANAGER
209
- g_next_value = next;
210
- #endif
211
197
  gpr_cv_wait(&g_cv_wait, &g_mu,
212
198
  grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC));
213
199
 
@@ -309,11 +295,6 @@ static void start_threads(void) {
309
295
  void grpc_timer_manager_init(void) {
310
296
  gpr_mu_init(&g_mu);
311
297
  gpr_cv_init(&g_cv_wait);
312
- #ifdef GRPC_DEBUG_TIMER_MANAGER
313
- // For debug of the timer manager crash only.
314
- // TODO (mxyan): remove after bug is fixed.
315
- g_timer_manager_init_count++;
316
- #endif
317
298
  gpr_cv_init(&g_cv_shutdown);
318
299
  g_threaded = false;
319
300
  g_thread_count = 0;
@@ -349,11 +330,6 @@ static void stop_threads(void) {
349
330
  }
350
331
 
351
332
  void grpc_timer_manager_shutdown(void) {
352
- #ifdef GRPC_DEBUG_TIMER_MANAGER
353
- // For debug of the timer manager crash only.
354
- // TODO (mxyan): remove after bug is fixed.
355
- g_timer_manager_shutdown_count++;
356
- #endif
357
333
  stop_threads();
358
334
 
359
335
  gpr_mu_destroy(&g_mu);
@@ -362,11 +338,6 @@ void grpc_timer_manager_shutdown(void) {
362
338
  }
363
339
 
364
340
  void grpc_timer_manager_set_threading(bool threaded) {
365
- #ifdef GRPC_DEBUG_TIMER_MANAGER
366
- // For debug of the timer manager crash only.
367
- // TODO (mxyan): remove after bug is fixed.
368
- g_fork_count++;
369
- #endif
370
341
  if (threaded) {
371
342
  start_threads();
372
343
  } else {
@@ -45,6 +45,90 @@ void grpc_channel_credentials_release(grpc_channel_credentials* creds) {
45
45
  if (creds) creds->Unref();
46
46
  }
47
47
 
48
+ static grpc_core::Map<grpc_core::UniquePtr<char>,
49
+ grpc_core::RefCountedPtr<grpc_channel_credentials>,
50
+ grpc_core::StringLess>* g_grpc_control_plane_creds;
51
+ static gpr_mu g_control_plane_creds_mu;
52
+
53
+ static void do_control_plane_creds_init() {
54
+ gpr_mu_init(&g_control_plane_creds_mu);
55
+ GPR_ASSERT(g_grpc_control_plane_creds == nullptr);
56
+ g_grpc_control_plane_creds = grpc_core::New<
57
+ grpc_core::Map<grpc_core::UniquePtr<char>,
58
+ grpc_core::RefCountedPtr<grpc_channel_credentials>,
59
+ grpc_core::StringLess>>();
60
+ }
61
+
62
+ void grpc_control_plane_credentials_init() {
63
+ static gpr_once once_init_control_plane_creds = GPR_ONCE_INIT;
64
+ gpr_once_init(&once_init_control_plane_creds, do_control_plane_creds_init);
65
+ }
66
+
67
+ void grpc_test_only_control_plane_credentials_destroy() {
68
+ grpc_core::Delete(g_grpc_control_plane_creds);
69
+ g_grpc_control_plane_creds = nullptr;
70
+ gpr_mu_destroy(&g_control_plane_creds_mu);
71
+ }
72
+
73
+ void grpc_test_only_control_plane_credentials_force_init() {
74
+ if (g_grpc_control_plane_creds == nullptr) {
75
+ do_control_plane_creds_init();
76
+ }
77
+ }
78
+
79
+ bool grpc_channel_credentials_attach_credentials(
80
+ grpc_channel_credentials* credentials, const char* authority,
81
+ grpc_channel_credentials* control_plane_creds) {
82
+ grpc_core::ExecCtx exec_ctx;
83
+ return credentials->attach_credentials(authority, control_plane_creds->Ref());
84
+ }
85
+
86
+ bool grpc_control_plane_credentials_register(
87
+ const char* authority, grpc_channel_credentials* control_plane_creds) {
88
+ grpc_core::ExecCtx exec_ctx;
89
+ {
90
+ grpc_core::MutexLock lock(&g_control_plane_creds_mu);
91
+ auto key = grpc_core::UniquePtr<char>(gpr_strdup(authority));
92
+ if (g_grpc_control_plane_creds->find(key) !=
93
+ g_grpc_control_plane_creds->end()) {
94
+ return false;
95
+ }
96
+ (*g_grpc_control_plane_creds)[std::move(key)] = control_plane_creds->Ref();
97
+ }
98
+ return true;
99
+ }
100
+
101
+ bool grpc_channel_credentials::attach_credentials(
102
+ const char* authority,
103
+ grpc_core::RefCountedPtr<grpc_channel_credentials> control_plane_creds) {
104
+ auto key = grpc_core::UniquePtr<char>(gpr_strdup(authority));
105
+ if (local_control_plane_creds_.find(key) !=
106
+ local_control_plane_creds_.end()) {
107
+ return false;
108
+ }
109
+ local_control_plane_creds_[std::move(key)] = std::move(control_plane_creds);
110
+ return true;
111
+ }
112
+
113
+ grpc_core::RefCountedPtr<grpc_channel_credentials>
114
+ grpc_channel_credentials::get_control_plane_credentials(const char* authority) {
115
+ {
116
+ auto key = grpc_core::UniquePtr<char>(gpr_strdup(authority));
117
+ auto local_lookup = local_control_plane_creds_.find(key);
118
+ if (local_lookup != local_control_plane_creds_.end()) {
119
+ return local_lookup->second;
120
+ }
121
+ {
122
+ grpc_core::MutexLock lock(&g_control_plane_creds_mu);
123
+ auto global_lookup = g_grpc_control_plane_creds->find(key);
124
+ if (global_lookup != g_grpc_control_plane_creds->end()) {
125
+ return global_lookup->second;
126
+ }
127
+ }
128
+ }
129
+ return duplicate_without_call_credentials();
130
+ }
131
+
48
132
  void grpc_call_credentials_release(grpc_call_credentials* creds) {
49
133
  GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
50
134
  grpc_core::ExecCtx exec_ctx;
@@ -26,7 +26,9 @@
26
26
  #include <grpc/support/sync.h>
27
27
  #include "src/core/lib/transport/metadata_batch.h"
28
28
 
29
+ #include "src/core/lib/gprpp/map.h"
29
30
  #include "src/core/lib/gprpp/ref_counted.h"
31
+ #include "src/core/lib/gprpp/sync.h"
30
32
  #include "src/core/lib/http/httpcli.h"
31
33
  #include "src/core/lib/http/parser.h"
32
34
  #include "src/core/lib/iomgr/polling_entity.h"
@@ -64,8 +66,8 @@ typedef enum {
64
66
  #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
65
67
  "/computeMetadata/v1/instance/service-accounts/default/token"
66
68
 
67
- #define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "www.googleapis.com"
68
- #define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/oauth2/v3/token"
69
+ #define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "oauth2.googleapis.com"
70
+ #define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/token"
69
71
 
70
72
  #define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \
71
73
  "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \
@@ -131,12 +133,31 @@ struct grpc_channel_credentials
131
133
  return args;
132
134
  }
133
135
 
136
+ // Attaches control_plane_creds to the local registry, under authority,
137
+ // if no other creds are currently registered under authority. Returns
138
+ // true if registered successfully and false if not.
139
+ bool attach_credentials(
140
+ const char* authority,
141
+ grpc_core::RefCountedPtr<grpc_channel_credentials> control_plane_creds);
142
+
143
+ // Gets the control plane credentials registered under authority. This
144
+ // prefers the local control plane creds registry but falls back to the
145
+ // global registry. Lastly, this returns self but with any attached
146
+ // call credentials stripped off, in the case that neither the local
147
+ // registry nor the global registry have an entry for authority.
148
+ grpc_core::RefCountedPtr<grpc_channel_credentials>
149
+ get_control_plane_credentials(const char* authority);
150
+
134
151
  const char* type() const { return type_; }
135
152
 
136
153
  GRPC_ABSTRACT_BASE_CLASS
137
154
 
138
155
  private:
139
156
  const char* type_;
157
+ grpc_core::Map<grpc_core::UniquePtr<char>,
158
+ grpc_core::RefCountedPtr<grpc_channel_credentials>,
159
+ grpc_core::StringLess>
160
+ local_control_plane_creds_;
140
161
  };
141
162
 
142
163
  /* Util to encapsulate the channel credentials in a channel arg. */
@@ -150,6 +171,41 @@ grpc_channel_credentials* grpc_channel_credentials_from_arg(
150
171
  grpc_channel_credentials* grpc_channel_credentials_find_in_args(
151
172
  const grpc_channel_args* args);
152
173
 
174
+ /** EXPERIMENTAL. API MAY CHANGE IN THE FUTURE.
175
+ Attaches \a control_plane_creds to \a credentials
176
+ under the key \a authority. Returns false if \a authority
177
+ is already present, in which case no changes are made.
178
+ Note that this API is not thread safe. Only one thread may
179
+ attach control plane creds to a given credentials object at
180
+ any one time, and new control plane creds must not be
181
+ attached after \a credentials has been used to create a channel. */
182
+ bool grpc_channel_credentials_attach_credentials(
183
+ grpc_channel_credentials* credentials, const char* authority,
184
+ grpc_channel_credentials* control_plane_creds);
185
+
186
+ /** EXPERIMENTAL. API MAY CHANGE IN THE FUTURE.
187
+ Registers \a control_plane_creds in the global registry
188
+ under the key \a authority. Returns false if \a authority
189
+ is already present, in which case no changes are made. */
190
+ bool grpc_control_plane_credentials_register(
191
+ const char* authority, grpc_channel_credentials* control_plane_creds);
192
+
193
+ /* Initializes global control plane credentials data. */
194
+ void grpc_control_plane_credentials_init();
195
+
196
+ /* Test only: destroy global control plane credentials data.
197
+ * This API is meant for use by a few tests that need to
198
+ * satisdy grpc_core::LeakDetector. */
199
+ void grpc_test_only_control_plane_credentials_destroy();
200
+
201
+ /* Test only: force re-initialization of global control
202
+ * plane credentials data if it was previously destroyed.
203
+ * This API is meant to be used in
204
+ * tandem with the
205
+ * grpc_test_only_control_plane_credentials_destroy, for
206
+ * the few tests that need it. */
207
+ void grpc_test_only_control_plane_credentials_force_init();
208
+
153
209
  /* --- grpc_credentials_mdelem_array. --- */
154
210
 
155
211
  typedef struct {
@@ -18,6 +18,7 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
+ #include "src/core/lib/iomgr/error.h"
21
22
  #include "src/core/lib/security/credentials/jwt/json_token.h"
22
23
 
23
24
  #include <string.h>
@@ -69,6 +70,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) {
69
70
  BIO* bio = nullptr;
70
71
  const char* prop_value;
71
72
  int success = 0;
73
+ grpc_error* error = GRPC_ERROR_NONE;
72
74
 
73
75
  memset(&result, 0, sizeof(grpc_auth_json_key));
74
76
  result.type = GRPC_AUTH_JSON_TYPE_INVALID;
@@ -77,7 +79,8 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) {
77
79
  goto end;
78
80
  }
79
81
 
80
- prop_value = grpc_json_get_string_property(json, "type");
82
+ prop_value = grpc_json_get_string_property(json, "type", &error);
83
+ GRPC_LOG_IF_ERROR("JSON key parsing", error);
81
84
  if (prop_value == nullptr ||
82
85
  strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) {
83
86
  goto end;
@@ -92,7 +95,8 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) {
92
95
  goto end;
93
96
  }
94
97
 
95
- prop_value = grpc_json_get_string_property(json, "private_key");
98
+ prop_value = grpc_json_get_string_property(json, "private_key", &error);
99
+ GRPC_LOG_IF_ERROR("JSON key parsing", error);
96
100
  if (prop_value == nullptr) {
97
101
  goto end;
98
102
  }
@@ -30,7 +30,7 @@
30
30
 
31
31
  /* --- Constants. --- */
32
32
 
33
- #define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token"
33
+ #define GRPC_JWT_OAUTH2_AUDIENCE "https://oauth2.googleapis.com/token"
34
34
 
35
35
  /* --- auth_json_key parsing. --- */
36
36
 
@@ -18,18 +18,28 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
+ #include "src/core/lib/json/json.h"
21
22
  #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
22
23
 
23
24
  #include <string.h>
24
25
 
25
- #include "src/core/lib/gprpp/ref_counted_ptr.h"
26
- #include "src/core/lib/security/util/json_util.h"
27
- #include "src/core/lib/surface/api_trace.h"
28
-
26
+ #include <grpc/grpc_security.h>
27
+ #include <grpc/impl/codegen/slice.h>
28
+ #include <grpc/slice.h>
29
29
  #include <grpc/support/alloc.h>
30
30
  #include <grpc/support/log.h>
31
31
  #include <grpc/support/string_util.h>
32
32
 
33
+ #include "src/core/lib/gpr/string.h"
34
+ #include "src/core/lib/gprpp/inlined_vector.h"
35
+ #include "src/core/lib/gprpp/ref_counted_ptr.h"
36
+ #include "src/core/lib/iomgr/error.h"
37
+ #include "src/core/lib/iomgr/load_file.h"
38
+ #include "src/core/lib/security/util/json_util.h"
39
+ #include "src/core/lib/slice/slice_internal.h"
40
+ #include "src/core/lib/surface/api_trace.h"
41
+ #include "src/core/lib/uri/uri_parser.h"
42
+
33
43
  //
34
44
  // Auth Refresh Token.
35
45
  //
@@ -45,6 +55,7 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
45
55
  grpc_auth_refresh_token result;
46
56
  const char* prop_value;
47
57
  int success = 0;
58
+ grpc_error* error = GRPC_ERROR_NONE;
48
59
 
49
60
  memset(&result, 0, sizeof(grpc_auth_refresh_token));
50
61
  result.type = GRPC_AUTH_JSON_TYPE_INVALID;
@@ -53,7 +64,8 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
53
64
  goto end;
54
65
  }
55
66
 
56
- prop_value = grpc_json_get_string_property(json, "type");
67
+ prop_value = grpc_json_get_string_property(json, "type", &error);
68
+ GRPC_LOG_IF_ERROR("Parsing refresh token", error);
57
69
  if (prop_value == nullptr ||
58
70
  strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) {
59
71
  goto end;
@@ -187,8 +199,8 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
187
199
  *token_lifetime = strtol(expires_in->value, nullptr, 10) * GPR_MS_PER_SEC;
188
200
  if (!GRPC_MDISNULL(*token_md)) GRPC_MDELEM_UNREF(*token_md);
189
201
  *token_md = grpc_mdelem_from_slices(
190
- grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY),
191
- grpc_slice_from_copied_string(new_access_token));
202
+ grpc_core::ExternallyManagedSlice(GRPC_AUTHORIZATION_METADATA_KEY),
203
+ grpc_core::UnmanagedMemorySlice(new_access_token));
192
204
  status = GRPC_CREDENTIALS_OK;
193
205
  }
194
206
 
@@ -216,10 +228,12 @@ static void on_oauth2_token_fetcher_http_response(void* user_data,
216
228
  void grpc_oauth2_token_fetcher_credentials::on_http_response(
217
229
  grpc_credentials_metadata_request* r, grpc_error* error) {
218
230
  grpc_mdelem access_token_md = GRPC_MDNULL;
219
- grpc_millis token_lifetime;
231
+ grpc_millis token_lifetime = 0;
220
232
  grpc_credentials_status status =
221
- grpc_oauth2_token_fetcher_credentials_parse_server_response(
222
- &r->response, &access_token_md, &token_lifetime);
233
+ error == GRPC_ERROR_NONE
234
+ ? grpc_oauth2_token_fetcher_credentials_parse_server_response(
235
+ &r->response, &access_token_md, &token_lifetime)
236
+ : GRPC_CREDENTIALS_ERROR;
223
237
  // Update cache and grab list of pending requests.
224
238
  gpr_mu_lock(&mu_);
225
239
  token_fetch_pending_ = false;
@@ -234,14 +248,15 @@ void grpc_oauth2_token_fetcher_credentials::on_http_response(
234
248
  gpr_mu_unlock(&mu_);
235
249
  // Invoke callbacks for all pending requests.
236
250
  while (pending_request != nullptr) {
251
+ grpc_error* new_error = GRPC_ERROR_NONE;
237
252
  if (status == GRPC_CREDENTIALS_OK) {
238
253
  grpc_credentials_mdelem_array_add(pending_request->md_array,
239
254
  access_token_md);
240
255
  } else {
241
- error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
256
+ new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
242
257
  "Error occurred when fetching oauth2 token.", &error, 1);
243
258
  }
244
- GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error);
259
+ GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, new_error);
245
260
  grpc_polling_entity_del_from_pollset_set(
246
261
  pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_));
247
262
  grpc_oauth2_pending_get_request_metadata* prev = pending_request;
@@ -356,7 +371,8 @@ class grpc_compute_engine_token_fetcher_credentials
356
371
  grpc_polling_entity* pollent,
357
372
  grpc_iomgr_cb_func response_cb,
358
373
  grpc_millis deadline) override {
359
- grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"};
374
+ grpc_http_header header = {const_cast<char*>("Metadata-Flavor"),
375
+ const_cast<char*>("Google")};
360
376
  grpc_httpcli_request request;
361
377
  memset(&request, 0, sizeof(grpc_httpcli_request));
362
378
  request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST;
@@ -369,11 +385,14 @@ class grpc_compute_engine_token_fetcher_credentials
369
385
  grpc_resource_quota* resource_quota =
370
386
  grpc_resource_quota_create("oauth2_credentials");
371
387
  grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline,
372
- GRPC_CLOSURE_CREATE(response_cb, metadata_req,
373
- grpc_schedule_on_exec_ctx),
388
+ GRPC_CLOSURE_INIT(&http_get_cb_closure_, response_cb,
389
+ metadata_req, grpc_schedule_on_exec_ctx),
374
390
  &metadata_req->response);
375
391
  grpc_resource_quota_unref_internal(resource_quota);
376
392
  }
393
+
394
+ private:
395
+ grpc_closure http_get_cb_closure_;
377
396
  };
378
397
 
379
398
  } // namespace
@@ -401,8 +420,9 @@ void grpc_google_refresh_token_credentials::fetch_oauth2(
401
420
  grpc_credentials_metadata_request* metadata_req,
402
421
  grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent,
403
422
  grpc_iomgr_cb_func response_cb, grpc_millis deadline) {
404
- grpc_http_header header = {(char*)"Content-Type",
405
- (char*)"application/x-www-form-urlencoded"};
423
+ grpc_http_header header = {
424
+ const_cast<char*>("Content-Type"),
425
+ const_cast<char*>("application/x-www-form-urlencoded")};
406
426
  grpc_httpcli_request request;
407
427
  char* body = nullptr;
408
428
  gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
@@ -419,11 +439,11 @@ void grpc_google_refresh_token_credentials::fetch_oauth2(
419
439
  extreme memory pressure. */
420
440
  grpc_resource_quota* resource_quota =
421
441
  grpc_resource_quota_create("oauth2_credentials_refresh");
422
- grpc_httpcli_post(
423
- httpcli_context, pollent, resource_quota, &request, body, strlen(body),
424
- deadline,
425
- GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx),
426
- &metadata_req->response);
442
+ grpc_httpcli_post(httpcli_context, pollent, resource_quota, &request, body,
443
+ strlen(body), deadline,
444
+ GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb,
445
+ metadata_req, grpc_schedule_on_exec_ctx),
446
+ &metadata_req->response);
427
447
  grpc_resource_quota_unref_internal(resource_quota);
428
448
  gpr_free(body);
429
449
  }
@@ -472,6 +492,207 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create(
472
492
  .release();
473
493
  }
474
494
 
495
+ //
496
+ // STS credentials.
497
+ //
498
+
499
+ namespace grpc_core {
500
+
501
+ namespace {
502
+
503
+ void MaybeAddToBody(gpr_strvec* body_strvec, const char* field_name,
504
+ const char* field) {
505
+ if (field == nullptr || strlen(field) == 0) return;
506
+ char* new_query;
507
+ gpr_asprintf(&new_query, "&%s=%s", field_name, field);
508
+ gpr_strvec_add(body_strvec, new_query);
509
+ }
510
+
511
+ grpc_error* LoadTokenFile(const char* path, gpr_slice* token) {
512
+ grpc_error* err = grpc_load_file(path, 1, token);
513
+ if (err != GRPC_ERROR_NONE) return err;
514
+ if (GRPC_SLICE_LENGTH(*token) == 0) {
515
+ gpr_log(GPR_ERROR, "Token file %s is empty", path);
516
+ err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Token file is empty.");
517
+ }
518
+ return err;
519
+ }
520
+
521
+ class StsTokenFetcherCredentials
522
+ : public grpc_oauth2_token_fetcher_credentials {
523
+ public:
524
+ StsTokenFetcherCredentials(grpc_uri* sts_url, // Ownership transferred.
525
+ const grpc_sts_credentials_options* options)
526
+ : sts_url_(sts_url),
527
+ resource_(gpr_strdup(options->resource)),
528
+ audience_(gpr_strdup(options->audience)),
529
+ scope_(gpr_strdup(options->scope)),
530
+ requested_token_type_(gpr_strdup(options->requested_token_type)),
531
+ subject_token_path_(gpr_strdup(options->subject_token_path)),
532
+ subject_token_type_(gpr_strdup(options->subject_token_type)),
533
+ actor_token_path_(gpr_strdup(options->actor_token_path)),
534
+ actor_token_type_(gpr_strdup(options->actor_token_type)) {}
535
+
536
+ ~StsTokenFetcherCredentials() override { grpc_uri_destroy(sts_url_); }
537
+
538
+ private:
539
+ void fetch_oauth2(grpc_credentials_metadata_request* metadata_req,
540
+ grpc_httpcli_context* http_context,
541
+ grpc_polling_entity* pollent,
542
+ grpc_iomgr_cb_func response_cb,
543
+ grpc_millis deadline) override {
544
+ char* body = nullptr;
545
+ size_t body_length = 0;
546
+ grpc_error* err = FillBody(&body, &body_length);
547
+ if (err != GRPC_ERROR_NONE) {
548
+ response_cb(metadata_req, err);
549
+ GRPC_ERROR_UNREF(err);
550
+ return;
551
+ }
552
+ grpc_http_header header = {
553
+ const_cast<char*>("Content-Type"),
554
+ const_cast<char*>("application/x-www-form-urlencoded")};
555
+ grpc_httpcli_request request;
556
+ memset(&request, 0, sizeof(grpc_httpcli_request));
557
+ request.host = (char*)sts_url_->authority;
558
+ request.http.path = (char*)sts_url_->path;
559
+ request.http.hdr_count = 1;
560
+ request.http.hdrs = &header;
561
+ request.handshaker = (strcmp(sts_url_->scheme, "https") == 0)
562
+ ? &grpc_httpcli_ssl
563
+ : &grpc_httpcli_plaintext;
564
+ /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
565
+ channel. This would allow us to cancel an authentication query when under
566
+ extreme memory pressure. */
567
+ grpc_resource_quota* resource_quota =
568
+ grpc_resource_quota_create("oauth2_credentials_refresh");
569
+ grpc_httpcli_post(
570
+ http_context, pollent, resource_quota, &request, body, body_length,
571
+ deadline,
572
+ GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, metadata_req,
573
+ grpc_schedule_on_exec_ctx),
574
+ &metadata_req->response);
575
+ grpc_resource_quota_unref_internal(resource_quota);
576
+ gpr_free(body);
577
+ }
578
+
579
+ grpc_error* FillBody(char** body, size_t* body_length) {
580
+ *body = nullptr;
581
+ gpr_strvec body_strvec;
582
+ gpr_strvec_init(&body_strvec);
583
+ grpc_slice subject_token = grpc_empty_slice();
584
+ grpc_slice actor_token = grpc_empty_slice();
585
+ grpc_error* err = GRPC_ERROR_NONE;
586
+
587
+ auto cleanup = [&body, &body_length, &body_strvec, &subject_token,
588
+ &actor_token, &err]() {
589
+ if (err == GRPC_ERROR_NONE) {
590
+ *body = gpr_strvec_flatten(&body_strvec, body_length);
591
+ } else {
592
+ gpr_free(*body);
593
+ }
594
+ gpr_strvec_destroy(&body_strvec);
595
+ grpc_slice_unref_internal(subject_token);
596
+ grpc_slice_unref_internal(actor_token);
597
+ return err;
598
+ };
599
+
600
+ err = LoadTokenFile(subject_token_path_.get(), &subject_token);
601
+ if (err != GRPC_ERROR_NONE) return cleanup();
602
+ gpr_asprintf(
603
+ body, GRPC_STS_POST_MINIMAL_BODY_FORMAT_STRING,
604
+ reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(subject_token)),
605
+ subject_token_type_.get());
606
+ gpr_strvec_add(&body_strvec, *body);
607
+ MaybeAddToBody(&body_strvec, "resource", resource_.get());
608
+ MaybeAddToBody(&body_strvec, "audience", audience_.get());
609
+ MaybeAddToBody(&body_strvec, "scope", scope_.get());
610
+ MaybeAddToBody(&body_strvec, "requested_token_type",
611
+ requested_token_type_.get());
612
+ if (actor_token_path_ != nullptr) {
613
+ err = LoadTokenFile(actor_token_path_.get(), &actor_token);
614
+ if (err != GRPC_ERROR_NONE) return cleanup();
615
+ MaybeAddToBody(
616
+ &body_strvec, "actor_token",
617
+ reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(subject_token)));
618
+ MaybeAddToBody(&body_strvec, "actor_token_type", actor_token_type_.get());
619
+ }
620
+ return cleanup();
621
+ }
622
+
623
+ grpc_uri* sts_url_;
624
+ grpc_closure http_post_cb_closure_;
625
+ grpc_core::UniquePtr<char> resource_;
626
+ grpc_core::UniquePtr<char> audience_;
627
+ grpc_core::UniquePtr<char> scope_;
628
+ grpc_core::UniquePtr<char> requested_token_type_;
629
+ grpc_core::UniquePtr<char> subject_token_path_;
630
+ grpc_core::UniquePtr<char> subject_token_type_;
631
+ grpc_core::UniquePtr<char> actor_token_path_;
632
+ grpc_core::UniquePtr<char> actor_token_type_;
633
+ };
634
+
635
+ } // namespace
636
+
637
+ grpc_error* ValidateStsCredentialsOptions(
638
+ const grpc_sts_credentials_options* options, grpc_uri** sts_url_out) {
639
+ struct GrpcUriDeleter {
640
+ void operator()(grpc_uri* uri) { grpc_uri_destroy(uri); }
641
+ };
642
+ *sts_url_out = nullptr;
643
+ InlinedVector<grpc_error*, 3> error_list;
644
+ UniquePtr<grpc_uri, GrpcUriDeleter> sts_url(
645
+ options->token_exchange_service_uri != nullptr
646
+ ? grpc_uri_parse(options->token_exchange_service_uri, false)
647
+ : nullptr);
648
+ if (sts_url == nullptr) {
649
+ error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
650
+ "Invalid or missing STS endpoint URL"));
651
+ } else {
652
+ if (strcmp(sts_url->scheme, "https") != 0 &&
653
+ strcmp(sts_url->scheme, "http") != 0) {
654
+ error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
655
+ "Invalid URI scheme, must be https to http."));
656
+ }
657
+ }
658
+ if (options->subject_token_path == nullptr ||
659
+ strlen(options->subject_token_path) == 0) {
660
+ error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
661
+ "subject_token needs to be specified"));
662
+ }
663
+ if (options->subject_token_type == nullptr ||
664
+ strlen(options->subject_token_type) == 0) {
665
+ error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
666
+ "subject_token_type needs to be specified"));
667
+ }
668
+ if (error_list.empty()) {
669
+ *sts_url_out = sts_url.release();
670
+ return GRPC_ERROR_NONE;
671
+ } else {
672
+ return GRPC_ERROR_CREATE_FROM_VECTOR("Invalid STS Credentials Options",
673
+ &error_list);
674
+ }
675
+ }
676
+
677
+ } // namespace grpc_core
678
+
679
+ grpc_call_credentials* grpc_sts_credentials_create(
680
+ const grpc_sts_credentials_options* options, void* reserved) {
681
+ GPR_ASSERT(reserved == nullptr);
682
+ grpc_uri* sts_url;
683
+ grpc_error* error =
684
+ grpc_core::ValidateStsCredentialsOptions(options, &sts_url);
685
+ if (error != GRPC_ERROR_NONE) {
686
+ gpr_log(GPR_ERROR, "STS Credentials creation failed. Error: %s.",
687
+ grpc_error_string(error));
688
+ GRPC_ERROR_UNREF(error);
689
+ return nullptr;
690
+ }
691
+ return grpc_core::MakeRefCounted<grpc_core::StsTokenFetcherCredentials>(
692
+ sts_url, options)
693
+ .release();
694
+ }
695
+
475
696
  //
476
697
  // Oauth2 Access Token credentials.
477
698
  //
@@ -500,8 +721,8 @@ grpc_access_token_credentials::grpc_access_token_credentials(
500
721
  gpr_asprintf(&token_md_value, "Bearer %s", access_token);
501
722
  grpc_core::ExecCtx exec_ctx;
502
723
  access_token_md_ = grpc_mdelem_from_slices(
503
- grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY),
504
- grpc_slice_from_copied_string(token_md_value));
724
+ grpc_core::ExternallyManagedSlice(GRPC_AUTHORIZATION_METADATA_KEY),
725
+ grpc_core::UnmanagedMemorySlice(token_md_value));
505
726
  gpr_free(token_md_value);
506
727
  }
507
728