grpc 1.22.0 → 1.23.0

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 +262 -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 +63 -38
  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 +1 -0
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
  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 +13 -2
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
  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 +39 -33
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -622,33 +622,37 @@ static const uint8_t inverse_base64[256] = {
622
622
  255,
623
623
  };
624
624
 
625
+ static void GPR_ATTRIBUTE_NOINLINE on_hdr_log(grpc_mdelem md) {
626
+ char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
627
+ char* v = nullptr;
628
+ if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
629
+ v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
630
+ } else {
631
+ v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
632
+ }
633
+ gpr_log(
634
+ GPR_INFO,
635
+ "Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
636
+ k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
637
+ grpc_slice_is_interned(GRPC_MDKEY(md)),
638
+ grpc_slice_is_interned(GRPC_MDVALUE(md)));
639
+ gpr_free(k);
640
+ gpr_free(v);
641
+ }
642
+
625
643
  /* emission helpers */
626
- static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md,
627
- int add_to_table) {
644
+ template <bool do_add>
645
+ static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md) {
628
646
  if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
629
- char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
630
- char* v = nullptr;
631
- if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
632
- v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
633
- } else {
634
- v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
635
- }
636
- gpr_log(
637
- GPR_INFO,
638
- "Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
639
- k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
640
- grpc_slice_is_interned(GRPC_MDKEY(md)),
641
- grpc_slice_is_interned(GRPC_MDVALUE(md)));
642
- gpr_free(k);
643
- gpr_free(v);
647
+ on_hdr_log(md);
644
648
  }
645
- if (add_to_table) {
646
- GPR_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
647
- GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
649
+ if (do_add) {
650
+ GPR_DEBUG_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
651
+ GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
648
652
  grpc_error* err = grpc_chttp2_hptbl_add(&p->table, md);
649
- if (err != GRPC_ERROR_NONE) return err;
653
+ if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
650
654
  }
651
- if (p->on_header == nullptr) {
655
+ if (GPR_UNLIKELY(p->on_header == nullptr)) {
652
656
  GRPC_MDELEM_UNREF(md);
653
657
  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set");
654
658
  }
@@ -656,24 +660,32 @@ static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md,
656
660
  return GRPC_ERROR_NONE;
657
661
  }
658
662
 
659
- static grpc_slice take_string(grpc_chttp2_hpack_parser* p,
660
- grpc_chttp2_hpack_parser_string* str,
661
- bool intern) {
662
- grpc_slice s;
663
+ static grpc_core::UnmanagedMemorySlice take_string_extern(
664
+ grpc_chttp2_hpack_parser* p, grpc_chttp2_hpack_parser_string* str) {
665
+ grpc_core::UnmanagedMemorySlice s;
663
666
  if (!str->copied) {
664
- if (intern) {
665
- s = grpc_slice_intern(str->data.referenced);
666
- grpc_slice_unref_internal(str->data.referenced);
667
- } else {
668
- s = str->data.referenced;
669
- }
667
+ GPR_DEBUG_ASSERT(!grpc_slice_is_interned(str->data.referenced));
668
+ s = static_cast<grpc_core::UnmanagedMemorySlice&>(str->data.referenced);
669
+ str->copied = true;
670
+ str->data.referenced = grpc_core::UnmanagedMemorySlice();
671
+ } else {
672
+ s = grpc_core::UnmanagedMemorySlice(str->data.copied.str,
673
+ str->data.copied.length);
674
+ }
675
+ str->data.copied.length = 0;
676
+ return s;
677
+ }
678
+
679
+ static grpc_core::ManagedMemorySlice take_string_intern(
680
+ grpc_chttp2_hpack_parser* p, grpc_chttp2_hpack_parser_string* str) {
681
+ grpc_core::ManagedMemorySlice s;
682
+ if (!str->copied) {
683
+ s = grpc_core::ManagedMemorySlice(&str->data.referenced);
684
+ grpc_slice_unref_internal(str->data.referenced);
670
685
  str->copied = true;
671
686
  str->data.referenced = grpc_empty_slice();
672
- } else if (intern) {
673
- s = grpc_slice_intern(grpc_slice_from_static_buffer(
674
- str->data.copied.str, str->data.copied.length));
675
687
  } else {
676
- s = grpc_slice_from_copied_buffer(str->data.copied.str,
688
+ s = grpc_core::ManagedMemorySlice(str->data.copied.str,
677
689
  str->data.copied.length);
678
690
  }
679
691
  str->data.copied.length = 0;
@@ -765,7 +777,7 @@ static grpc_error* finish_indexed_field(grpc_chttp2_hpack_parser* p,
765
777
  }
766
778
  GRPC_MDELEM_REF(md);
767
779
  GRPC_STATS_INC_HPACK_RECV_INDEXED();
768
- grpc_error* err = on_hdr(p, md, 0);
780
+ grpc_error* err = on_hdr<false>(p, md);
769
781
  if (err != GRPC_ERROR_NONE) return err;
770
782
  return parse_begin(p, cur, end);
771
783
  }
@@ -775,6 +787,7 @@ static grpc_error* parse_indexed_field(grpc_chttp2_hpack_parser* p,
775
787
  const uint8_t* cur, const uint8_t* end) {
776
788
  p->dynamic_table_update_allowed = 0;
777
789
  p->index = (*cur) & 0x7f;
790
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
778
791
  return finish_indexed_field(p, cur + 1, end);
779
792
  }
780
793
 
@@ -787,22 +800,41 @@ static grpc_error* parse_indexed_field_x(grpc_chttp2_hpack_parser* p,
787
800
  p->dynamic_table_update_allowed = 0;
788
801
  p->next_state = and_then;
789
802
  p->index = 0x7f;
803
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
790
804
  p->parsing.value = &p->index;
791
805
  return parse_value0(p, cur + 1, end);
792
806
  }
793
807
 
808
+ /* When finishing with a header, get the cached md element for this index.
809
+ This is set in parse_value_string(). We ensure (in debug mode) that the
810
+ cached metadata corresponds with the index we are examining. */
811
+ static grpc_mdelem get_precomputed_md_for_idx(grpc_chttp2_hpack_parser* p) {
812
+ GPR_DEBUG_ASSERT(p->md_for_index.payload != 0);
813
+ GPR_DEBUG_ASSERT(static_cast<int64_t>(p->index) == p->precomputed_md_index);
814
+ grpc_mdelem md = p->md_for_index;
815
+ GPR_DEBUG_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
816
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
817
+ #ifndef NDEBUG
818
+ p->precomputed_md_index = -1;
819
+ #endif
820
+ return md;
821
+ }
822
+
823
+ static const grpc_core::ManagedMemorySlice& get_indexed_key(grpc_mdelem md) {
824
+ GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(md));
825
+ return static_cast<const grpc_core::ManagedMemorySlice&>(
826
+ grpc_slice_ref_internal(GRPC_MDKEY(md)));
827
+ }
828
+
794
829
  /* finish a literal header with incremental indexing */
795
830
  static grpc_error* finish_lithdr_incidx(grpc_chttp2_hpack_parser* p,
796
831
  const uint8_t* cur,
797
832
  const uint8_t* end) {
798
- grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
799
- GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
800
833
  GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX();
801
- grpc_error* err =
802
- on_hdr(p,
803
- grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
804
- take_string(p, &p->value, true)),
805
- 1);
834
+ grpc_mdelem md = get_precomputed_md_for_idx(p);
835
+ grpc_error* err = on_hdr<true>(
836
+ p, grpc_mdelem_from_slices(get_indexed_key(md),
837
+ take_string_intern(p, &p->value)));
806
838
  if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
807
839
  return parse_begin(p, cur, end);
808
840
  }
@@ -812,11 +844,9 @@ static grpc_error* finish_lithdr_incidx_v(grpc_chttp2_hpack_parser* p,
812
844
  const uint8_t* cur,
813
845
  const uint8_t* end) {
814
846
  GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V();
815
- grpc_error* err =
816
- on_hdr(p,
817
- grpc_mdelem_from_slices(take_string(p, &p->key, true),
818
- take_string(p, &p->value, true)),
819
- 1);
847
+ grpc_error* err = on_hdr<true>(
848
+ p, grpc_mdelem_from_slices(take_string_intern(p, &p->key),
849
+ take_string_intern(p, &p->value)));
820
850
  if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
821
851
  return parse_begin(p, cur, end);
822
852
  }
@@ -829,6 +859,7 @@ static grpc_error* parse_lithdr_incidx(grpc_chttp2_hpack_parser* p,
829
859
  p->dynamic_table_update_allowed = 0;
830
860
  p->next_state = and_then;
831
861
  p->index = (*cur) & 0x3f;
862
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
832
863
  return parse_string_prefix(p, cur + 1, end);
833
864
  }
834
865
 
@@ -842,6 +873,7 @@ static grpc_error* parse_lithdr_incidx_x(grpc_chttp2_hpack_parser* p,
842
873
  p->dynamic_table_update_allowed = 0;
843
874
  p->next_state = and_then;
844
875
  p->index = 0x3f;
876
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
845
877
  p->parsing.value = &p->index;
846
878
  return parse_value0(p, cur + 1, end);
847
879
  }
@@ -862,14 +894,11 @@ static grpc_error* parse_lithdr_incidx_v(grpc_chttp2_hpack_parser* p,
862
894
  static grpc_error* finish_lithdr_notidx(grpc_chttp2_hpack_parser* p,
863
895
  const uint8_t* cur,
864
896
  const uint8_t* end) {
865
- grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
866
- GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
867
897
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX();
868
- grpc_error* err =
869
- on_hdr(p,
870
- grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
871
- take_string(p, &p->value, false)),
872
- 0);
898
+ grpc_mdelem md = get_precomputed_md_for_idx(p);
899
+ grpc_error* err = on_hdr<false>(
900
+ p, grpc_mdelem_from_slices(get_indexed_key(md),
901
+ take_string_extern(p, &p->value)));
873
902
  if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
874
903
  return parse_begin(p, cur, end);
875
904
  }
@@ -879,11 +908,9 @@ static grpc_error* finish_lithdr_notidx_v(grpc_chttp2_hpack_parser* p,
879
908
  const uint8_t* cur,
880
909
  const uint8_t* end) {
881
910
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V();
882
- grpc_error* err =
883
- on_hdr(p,
884
- grpc_mdelem_from_slices(take_string(p, &p->key, true),
885
- take_string(p, &p->value, false)),
886
- 0);
911
+ grpc_error* err = on_hdr<false>(
912
+ p, grpc_mdelem_from_slices(take_string_intern(p, &p->key),
913
+ take_string_extern(p, &p->value)));
887
914
  if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
888
915
  return parse_begin(p, cur, end);
889
916
  }
@@ -896,6 +923,7 @@ static grpc_error* parse_lithdr_notidx(grpc_chttp2_hpack_parser* p,
896
923
  p->dynamic_table_update_allowed = 0;
897
924
  p->next_state = and_then;
898
925
  p->index = (*cur) & 0xf;
926
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
899
927
  return parse_string_prefix(p, cur + 1, end);
900
928
  }
901
929
 
@@ -909,6 +937,7 @@ static grpc_error* parse_lithdr_notidx_x(grpc_chttp2_hpack_parser* p,
909
937
  p->dynamic_table_update_allowed = 0;
910
938
  p->next_state = and_then;
911
939
  p->index = 0xf;
940
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
912
941
  p->parsing.value = &p->index;
913
942
  return parse_value0(p, cur + 1, end);
914
943
  }
@@ -929,14 +958,11 @@ static grpc_error* parse_lithdr_notidx_v(grpc_chttp2_hpack_parser* p,
929
958
  static grpc_error* finish_lithdr_nvridx(grpc_chttp2_hpack_parser* p,
930
959
  const uint8_t* cur,
931
960
  const uint8_t* end) {
932
- grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
933
- GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
934
961
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX();
935
- grpc_error* err =
936
- on_hdr(p,
937
- grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
938
- take_string(p, &p->value, false)),
939
- 0);
962
+ grpc_mdelem md = get_precomputed_md_for_idx(p);
963
+ grpc_error* err = on_hdr<false>(
964
+ p, grpc_mdelem_from_slices(get_indexed_key(md),
965
+ take_string_extern(p, &p->value)));
940
966
  if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
941
967
  return parse_begin(p, cur, end);
942
968
  }
@@ -946,11 +972,9 @@ static grpc_error* finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p,
946
972
  const uint8_t* cur,
947
973
  const uint8_t* end) {
948
974
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V();
949
- grpc_error* err =
950
- on_hdr(p,
951
- grpc_mdelem_from_slices(take_string(p, &p->key, true),
952
- take_string(p, &p->value, false)),
953
- 0);
975
+ grpc_error* err = on_hdr<false>(
976
+ p, grpc_mdelem_from_slices(take_string_intern(p, &p->key),
977
+ take_string_extern(p, &p->value)));
954
978
  if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
955
979
  return parse_begin(p, cur, end);
956
980
  }
@@ -963,6 +987,7 @@ static grpc_error* parse_lithdr_nvridx(grpc_chttp2_hpack_parser* p,
963
987
  p->dynamic_table_update_allowed = 0;
964
988
  p->next_state = and_then;
965
989
  p->index = (*cur) & 0xf;
990
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
966
991
  return parse_string_prefix(p, cur + 1, end);
967
992
  }
968
993
 
@@ -976,6 +1001,7 @@ static grpc_error* parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser* p,
976
1001
  p->dynamic_table_update_allowed = 0;
977
1002
  p->next_state = and_then;
978
1003
  p->index = 0xf;
1004
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
979
1005
  p->parsing.value = &p->index;
980
1006
  return parse_value0(p, cur + 1, end);
981
1007
  }
@@ -1015,6 +1041,7 @@ static grpc_error* parse_max_tbl_size(grpc_chttp2_hpack_parser* p,
1015
1041
  }
1016
1042
  p->dynamic_table_update_allowed--;
1017
1043
  p->index = (*cur) & 0x1f;
1044
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
1018
1045
  return finish_max_tbl_size(p, cur + 1, end);
1019
1046
  }
1020
1047
 
@@ -1033,6 +1060,7 @@ static grpc_error* parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p,
1033
1060
  p->dynamic_table_update_allowed--;
1034
1061
  p->next_state = and_then;
1035
1062
  p->index = 0x1f;
1063
+ p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */
1036
1064
  p->parsing.value = &p->index;
1037
1065
  return parse_value0(p, cur + 1, end);
1038
1066
  }
@@ -1496,17 +1524,33 @@ static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p,
1496
1524
 
1497
1525
  static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) {
1498
1526
  /* We know that either argument here is a reference counter slice.
1499
- * 1. If a result of grpc_slice_from_static_buffer, the refcount is set to
1500
- * NoopRefcount.
1527
+ * 1. If it is a grpc_core::StaticSlice, the refcount is set to kNoopRefcount.
1501
1528
  * 2. If it's p->key.data.referenced, then p->key.copied was set to false,
1502
1529
  * which occurs in begin_parse_string() - where the refcount is set to
1503
1530
  * p->current_slice_refcount, which is not null. */
1504
1531
  return grpc_is_refcounted_slice_binary_header(
1505
- p->key.copied ? grpc_slice_from_static_buffer(p->key.data.copied.str,
1506
- p->key.data.copied.length)
1532
+ p->key.copied ? grpc_core::ExternallyManagedSlice(
1533
+ p->key.data.copied.str, p->key.data.copied.length)
1507
1534
  : p->key.data.referenced);
1508
1535
  }
1509
1536
 
1537
+ /* Cache the metadata for the given index during initial parsing. This avoids a
1538
+ pointless recomputation of the metadata when finishing a header. We read the
1539
+ cached value in get_precomputed_md_for_idx(). */
1540
+ static void set_precomputed_md_idx(grpc_chttp2_hpack_parser* p,
1541
+ grpc_mdelem md) {
1542
+ GPR_DEBUG_ASSERT(p->md_for_index.payload == 0);
1543
+ GPR_DEBUG_ASSERT(p->precomputed_md_index == -1);
1544
+ p->md_for_index = md;
1545
+ #ifndef NDEBUG
1546
+ p->precomputed_md_index = p->index;
1547
+ #endif
1548
+ }
1549
+
1550
+ /* Determines if a metadata element key associated with the current parser index
1551
+ is a binary indexed header during string parsing. We'll need to revisit this
1552
+ metadata when we're done parsing, so we cache the metadata for this index
1553
+ here using set_precomputed_md_idx(). */
1510
1554
  static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p,
1511
1555
  bool* is) {
1512
1556
  grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
@@ -1527,6 +1571,7 @@ static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p,
1527
1571
  * interned.
1528
1572
  * 4. Both static and interned element slices have non-null refcounts. */
1529
1573
  *is = grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem));
1574
+ set_precomputed_md_idx(p, elem);
1530
1575
  return GRPC_ERROR_NONE;
1531
1576
  }
1532
1577
 
@@ -1565,9 +1610,20 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser* p) {
1565
1610
  p->value.data.copied.str = nullptr;
1566
1611
  p->value.data.copied.capacity = 0;
1567
1612
  p->value.data.copied.length = 0;
1613
+ /* Cached metadata for the current index the parser is handling. This is set
1614
+ to 0 initially, invalidated when the index changes, and invalidated when it
1615
+ is read (by get_precomputed_md_for_idx()). It is set during string parsing,
1616
+ by set_precomputed_md_idx() - which is called by parse_value_string().
1617
+ The goal here is to avoid recomputing the metadata for the index when
1618
+ finishing with a header as well as the initial parse. */
1619
+ p->md_for_index.payload = 0;
1620
+ #ifndef NDEBUG
1621
+ /* In debug mode, this ensures that the cached metadata we're reading is in
1622
+ * fact correct for the index we are examining. */
1623
+ p->precomputed_md_index = -1;
1624
+ #endif
1568
1625
  p->dynamic_table_update_allowed = 2;
1569
1626
  p->last_error = GRPC_ERROR_NONE;
1570
- grpc_chttp2_hptbl_init(&p->table);
1571
1627
  }
1572
1628
 
1573
1629
  void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p) {
@@ -1612,9 +1668,8 @@ static void force_client_rst_stream(void* sp, grpc_error* error) {
1612
1668
  grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>(sp);
1613
1669
  grpc_chttp2_transport* t = s->t;
1614
1670
  if (!s->write_closed) {
1615
- grpc_slice_buffer_add(
1616
- &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR,
1617
- &s->stats.outgoing));
1671
+ grpc_chttp2_add_rst_stream_to_next_write(t, s->id, GRPC_HTTP2_NO_ERROR,
1672
+ &s->stats.outgoing);
1618
1673
  grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_FORCE_RST_STREAM);
1619
1674
  grpc_chttp2_mark_stream_closed(t, s, true, true, GRPC_ERROR_NONE);
1620
1675
  }
@@ -69,6 +69,14 @@ struct grpc_chttp2_hpack_parser {
69
69
  grpc_chttp2_hpack_parser_string value;
70
70
  /* parsed index */
71
71
  uint32_t index;
72
+ /* When we parse a value string, we determine the metadata element for a
73
+ specific index, which we need again when we're finishing up with that
74
+ header. To avoid calculating the metadata element for that index a second
75
+ time at that stage, we cache (and invalidate) the element here. */
76
+ grpc_mdelem md_for_index;
77
+ #ifndef NDEBUG
78
+ int64_t precomputed_md_index;
79
+ #endif
72
80
  /* length of source bytes for the currently parsing string */
73
81
  uint32_t strlen;
74
82
  /* number of source bytes read for the currently parsing string */
@@ -29,183 +29,24 @@
29
29
 
30
30
  #include "src/core/lib/debug/trace.h"
31
31
  #include "src/core/lib/gpr/murmur_hash.h"
32
+ #include "src/core/lib/slice/slice_internal.h"
32
33
  #include "src/core/lib/surface/validate_metadata.h"
33
34
  #include "src/core/lib/transport/static_metadata.h"
34
35
 
35
36
  extern grpc_core::TraceFlag grpc_http_trace;
36
37
 
37
- static struct {
38
- const char* key;
39
- const char* value;
40
- } static_table[] = {
41
- /* 0: */
42
- {nullptr, nullptr},
43
- /* 1: */
44
- {":authority", ""},
45
- /* 2: */
46
- {":method", "GET"},
47
- /* 3: */
48
- {":method", "POST"},
49
- /* 4: */
50
- {":path", "/"},
51
- /* 5: */
52
- {":path", "/index.html"},
53
- /* 6: */
54
- {":scheme", "http"},
55
- /* 7: */
56
- {":scheme", "https"},
57
- /* 8: */
58
- {":status", "200"},
59
- /* 9: */
60
- {":status", "204"},
61
- /* 10: */
62
- {":status", "206"},
63
- /* 11: */
64
- {":status", "304"},
65
- /* 12: */
66
- {":status", "400"},
67
- /* 13: */
68
- {":status", "404"},
69
- /* 14: */
70
- {":status", "500"},
71
- /* 15: */
72
- {"accept-charset", ""},
73
- /* 16: */
74
- {"accept-encoding", "gzip, deflate"},
75
- /* 17: */
76
- {"accept-language", ""},
77
- /* 18: */
78
- {"accept-ranges", ""},
79
- /* 19: */
80
- {"accept", ""},
81
- /* 20: */
82
- {"access-control-allow-origin", ""},
83
- /* 21: */
84
- {"age", ""},
85
- /* 22: */
86
- {"allow", ""},
87
- /* 23: */
88
- {"authorization", ""},
89
- /* 24: */
90
- {"cache-control", ""},
91
- /* 25: */
92
- {"content-disposition", ""},
93
- /* 26: */
94
- {"content-encoding", ""},
95
- /* 27: */
96
- {"content-language", ""},
97
- /* 28: */
98
- {"content-length", ""},
99
- /* 29: */
100
- {"content-location", ""},
101
- /* 30: */
102
- {"content-range", ""},
103
- /* 31: */
104
- {"content-type", ""},
105
- /* 32: */
106
- {"cookie", ""},
107
- /* 33: */
108
- {"date", ""},
109
- /* 34: */
110
- {"etag", ""},
111
- /* 35: */
112
- {"expect", ""},
113
- /* 36: */
114
- {"expires", ""},
115
- /* 37: */
116
- {"from", ""},
117
- /* 38: */
118
- {"host", ""},
119
- /* 39: */
120
- {"if-match", ""},
121
- /* 40: */
122
- {"if-modified-since", ""},
123
- /* 41: */
124
- {"if-none-match", ""},
125
- /* 42: */
126
- {"if-range", ""},
127
- /* 43: */
128
- {"if-unmodified-since", ""},
129
- /* 44: */
130
- {"last-modified", ""},
131
- /* 45: */
132
- {"link", ""},
133
- /* 46: */
134
- {"location", ""},
135
- /* 47: */
136
- {"max-forwards", ""},
137
- /* 48: */
138
- {"proxy-authenticate", ""},
139
- /* 49: */
140
- {"proxy-authorization", ""},
141
- /* 50: */
142
- {"range", ""},
143
- /* 51: */
144
- {"referer", ""},
145
- /* 52: */
146
- {"refresh", ""},
147
- /* 53: */
148
- {"retry-after", ""},
149
- /* 54: */
150
- {"server", ""},
151
- /* 55: */
152
- {"set-cookie", ""},
153
- /* 56: */
154
- {"strict-transport-security", ""},
155
- /* 57: */
156
- {"transfer-encoding", ""},
157
- /* 58: */
158
- {"user-agent", ""},
159
- /* 59: */
160
- {"vary", ""},
161
- /* 60: */
162
- {"via", ""},
163
- /* 61: */
164
- {"www-authenticate", ""},
165
- };
166
-
167
- static uint32_t entries_for_bytes(uint32_t bytes) {
168
- return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) /
169
- GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
170
- }
171
-
172
- void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) {
173
- size_t i;
174
-
175
- memset(tbl, 0, sizeof(*tbl));
176
- tbl->current_table_bytes = tbl->max_bytes =
177
- GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
178
- tbl->max_entries = tbl->cap_entries =
179
- entries_for_bytes(tbl->current_table_bytes);
180
- tbl->ents = static_cast<grpc_mdelem*>(
181
- gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries));
182
- memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries);
183
- for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
184
- tbl->static_ents[i - 1] = grpc_mdelem_from_slices(
185
- grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)),
186
- grpc_slice_intern(
187
- grpc_slice_from_static_string(static_table[i].value)));
188
- }
189
- }
190
-
191
38
  void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl* tbl) {
192
39
  size_t i;
193
- for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
194
- GRPC_MDELEM_UNREF(tbl->static_ents[i]);
195
- }
196
40
  for (i = 0; i < tbl->num_ents; i++) {
197
41
  GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
198
42
  }
199
43
  gpr_free(tbl->ents);
44
+ tbl->ents = nullptr;
200
45
  }
201
46
 
202
- grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl,
203
- uint32_t tbl_index) {
204
- /* Static table comes first, just return an entry from it */
205
- if (tbl_index <= GRPC_CHTTP2_LAST_STATIC_ENTRY) {
206
- return tbl->static_ents[tbl_index - 1];
207
- }
208
- /* Otherwise, find the value in the list of valid entries */
47
+ grpc_mdelem grpc_chttp2_hptbl_lookup_dynamic_index(const grpc_chttp2_hptbl* tbl,
48
+ uint32_t tbl_index) {
49
+ /* Not static - find the value in the list of valid entries */
209
50
  tbl_index -= (GRPC_CHTTP2_LAST_STATIC_ENTRY + 1);
210
51
  if (tbl_index < tbl->num_ents) {
211
52
  uint32_t offset =
@@ -278,7 +119,7 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl,
278
119
  evict1(tbl);
279
120
  }
280
121
  tbl->current_table_bytes = bytes;
281
- tbl->max_entries = entries_for_bytes(bytes);
122
+ tbl->max_entries = grpc_chttp2_hptbl::entries_for_bytes(bytes);
282
123
  if (tbl->max_entries > tbl->cap_entries) {
283
124
  rebuild_ents(tbl, GPR_MAX(tbl->max_entries, 2 * tbl->cap_entries));
284
125
  } else if (tbl->max_entries < tbl->cap_entries / 3) {
@@ -348,7 +189,7 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
348
189
 
349
190
  /* See if the string is in the static table */
350
191
  for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
351
- grpc_mdelem ent = tbl->static_ents[i];
192
+ grpc_mdelem ent = grpc_static_mdelem_manifested[i];
352
193
  if (!grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDKEY(ent))) continue;
353
194
  r.index = i + 1u;
354
195
  r.has_value = grpc_slice_eq(GRPC_MDVALUE(md), GRPC_MDVALUE(ent));