grpc 1.55.3 → 1.56.0.pre3

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 (385) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +100 -70
  3. data/include/grpc/event_engine/event_engine.h +4 -3
  4. data/include/grpc/grpc_audit_logging.h +96 -0
  5. data/include/grpc/module.modulemap +2 -0
  6. data/include/grpc/support/json.h +218 -0
  7. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +5 -0
  8. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -0
  9. data/src/core/ext/filters/client_channel/channel_connectivity.cc +4 -4
  10. data/src/core/ext/filters/client_channel/client_channel.cc +82 -98
  11. data/src/core/ext/filters/client_channel/client_channel.h +4 -0
  12. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +19 -18
  13. data/src/core/ext/filters/client_channel/client_channel_internal.h +16 -21
  14. data/src/core/ext/filters/client_channel/config_selector.h +9 -24
  15. data/src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h +3 -0
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +5 -4
  17. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +455 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.h +54 -0
  19. data/src/core/ext/filters/client_channel/lb_policy/health_check_client_internal.h +186 -0
  20. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +2 -7
  21. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +52 -20
  22. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +23 -2
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +19 -6
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +1 -9
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +16 -7
  26. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +18 -1
  27. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +12 -9
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +6 -4
  29. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +36 -13
  30. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/static_stride_scheduler.cc +76 -6
  31. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +32 -39
  32. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +4 -10
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +52 -47
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +1 -9
  35. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +14 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +40 -43
  37. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +7 -12
  38. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +12 -19
  39. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +35 -33
  40. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +29 -4
  41. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc +1 -1
  42. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +28 -27
  43. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +163 -46
  44. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h +16 -1
  45. data/src/core/ext/filters/client_channel/retry_service_config.cc +1 -0
  46. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +10 -40
  47. data/src/core/ext/filters/client_channel/subchannel.cc +10 -196
  48. data/src/core/ext/filters/client_channel/subchannel.h +3 -43
  49. data/src/core/ext/filters/http/message_compress/compression_filter.cc +5 -5
  50. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +100 -6
  51. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +6 -8
  52. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -3
  53. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +16 -1
  54. data/src/core/ext/transport/chttp2/transport/flow_control.cc +46 -95
  55. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +543 -567
  56. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +9 -150
  57. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +32 -46
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +5 -18
  59. data/src/core/ext/transport/chttp2/transport/internal.h +1 -15
  60. data/src/core/ext/transport/chttp2/transport/parsing.cc +12 -12
  61. data/src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.c +11 -2
  62. data/src/core/ext/upb-generated/xds/data/orca/v3/orca_load_report.upb.h +15 -0
  63. data/src/core/ext/xds/certificate_provider_store.cc +4 -9
  64. data/src/core/ext/xds/certificate_provider_store.h +1 -1
  65. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +30 -42
  66. data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +14 -9
  67. data/src/core/ext/xds/xds_api.cc +9 -6
  68. data/src/core/ext/xds/xds_api.h +3 -2
  69. data/src/core/ext/xds/xds_audit_logger_registry.cc +122 -0
  70. data/src/core/ext/xds/xds_audit_logger_registry.h +68 -0
  71. data/src/core/ext/xds/xds_bootstrap_grpc.cc +21 -9
  72. data/src/core/ext/xds/xds_bootstrap_grpc.h +5 -0
  73. data/src/core/ext/xds/xds_client.cc +5 -4
  74. data/src/core/ext/xds/xds_client_stats.h +1 -1
  75. data/src/core/ext/xds/xds_cluster.cc +20 -19
  76. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +11 -8
  77. data/src/core/ext/xds/xds_common_types.cc +3 -1
  78. data/src/core/ext/xds/xds_http_fault_filter.cc +16 -13
  79. data/src/core/ext/xds/xds_http_fault_filter.h +2 -1
  80. data/src/core/ext/xds/xds_http_filters.h +4 -2
  81. data/src/core/ext/xds/xds_http_rbac_filter.cc +154 -67
  82. data/src/core/ext/xds/xds_http_rbac_filter.h +2 -1
  83. data/src/core/ext/xds/xds_http_stateful_session_filter.cc +15 -11
  84. data/src/core/ext/xds/xds_http_stateful_session_filter.h +2 -1
  85. data/src/core/ext/xds/xds_lb_policy_registry.cc +22 -16
  86. data/src/core/ext/xds/xds_listener.cc +1 -0
  87. data/src/core/ext/xds/xds_route_config.cc +40 -3
  88. data/src/core/ext/xds/xds_routing.cc +2 -2
  89. data/src/core/ext/xds/xds_transport_grpc.cc +3 -1
  90. data/src/core/lib/avl/avl.h +5 -0
  91. data/src/core/lib/backoff/random_early_detection.h +0 -5
  92. data/src/core/lib/channel/channel_args.cc +80 -22
  93. data/src/core/lib/channel/channel_args.h +34 -1
  94. data/src/core/lib/channel/channel_trace.cc +16 -12
  95. data/src/core/lib/channel/channelz.cc +159 -132
  96. data/src/core/lib/channel/channelz.h +42 -35
  97. data/src/core/lib/channel/channelz_registry.cc +23 -20
  98. data/src/core/lib/channel/connected_channel.cc +17 -6
  99. data/src/core/lib/channel/promise_based_filter.cc +0 -4
  100. data/src/core/lib/channel/promise_based_filter.h +2 -0
  101. data/src/core/lib/compression/compression_internal.cc +2 -5
  102. data/src/core/lib/config/config_vars.cc +20 -18
  103. data/src/core/lib/config/config_vars.h +4 -4
  104. data/src/core/lib/config/load_config.cc +13 -0
  105. data/src/core/lib/config/load_config.h +6 -0
  106. data/src/core/lib/debug/event_log.h +1 -1
  107. data/src/core/lib/debug/stats_data.h +1 -1
  108. data/src/core/lib/debug/trace.cc +24 -55
  109. data/src/core/lib/debug/trace.h +3 -1
  110. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +211 -0
  111. data/src/core/lib/event_engine/cf_engine/cf_engine.h +86 -0
  112. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +354 -0
  113. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +146 -0
  114. data/src/core/lib/event_engine/cf_engine/cftype_unique_ref.h +79 -0
  115. data/src/core/lib/event_engine/default_event_engine.cc +13 -1
  116. data/src/core/lib/event_engine/default_event_engine_factory.cc +14 -2
  117. data/src/core/lib/event_engine/poller.h +2 -2
  118. data/src/core/lib/event_engine/posix.h +4 -0
  119. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +1 -1
  120. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +7 -18
  121. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -0
  122. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +3 -2
  123. data/src/core/lib/event_engine/posix_engine/posix_engine.h +1 -2
  124. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +4 -33
  125. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +7 -11
  126. data/src/core/lib/event_engine/posix_engine/timer_manager.h +1 -1
  127. data/src/core/lib/event_engine/shim.cc +7 -1
  128. data/src/core/lib/event_engine/{thread_pool.cc → thread_pool/original_thread_pool.cc} +28 -25
  129. data/src/core/lib/event_engine/{thread_pool.h → thread_pool/original_thread_pool.h} +11 -15
  130. data/src/core/lib/event_engine/thread_pool/thread_pool.h +50 -0
  131. data/src/core/lib/event_engine/{executor/executor.h → thread_pool/thread_pool_factory.cc} +17 -15
  132. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +489 -0
  133. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +249 -0
  134. data/src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc +166 -0
  135. data/src/core/lib/event_engine/thready_event_engine/thready_event_engine.h +108 -0
  136. data/src/core/lib/event_engine/windows/iocp.cc +4 -3
  137. data/src/core/lib/event_engine/windows/iocp.h +3 -3
  138. data/src/core/lib/event_engine/windows/win_socket.cc +6 -6
  139. data/src/core/lib/event_engine/windows/win_socket.h +4 -4
  140. data/src/core/lib/event_engine/windows/windows_endpoint.cc +11 -10
  141. data/src/core/lib/event_engine/windows/windows_endpoint.h +3 -2
  142. data/src/core/lib/event_engine/windows/windows_engine.cc +19 -17
  143. data/src/core/lib/event_engine/windows/windows_engine.h +6 -6
  144. data/src/core/lib/event_engine/windows/windows_listener.cc +3 -3
  145. data/src/core/lib/event_engine/windows/windows_listener.h +3 -2
  146. data/src/core/lib/event_engine/work_queue/basic_work_queue.cc +63 -0
  147. data/src/core/lib/event_engine/work_queue/basic_work_queue.h +71 -0
  148. data/src/core/lib/event_engine/work_queue/work_queue.h +62 -0
  149. data/src/core/lib/experiments/config.cc +38 -7
  150. data/src/core/lib/experiments/config.h +16 -0
  151. data/src/core/lib/experiments/experiments.cc +67 -20
  152. data/src/core/lib/experiments/experiments.h +27 -21
  153. data/src/core/lib/gpr/log_internal.h +55 -0
  154. data/src/core/lib/gprpp/crash.cc +10 -0
  155. data/src/core/lib/gprpp/crash.h +3 -0
  156. data/src/core/lib/gprpp/per_cpu.cc +33 -0
  157. data/src/core/lib/gprpp/per_cpu.h +29 -6
  158. data/src/core/lib/gprpp/time.cc +1 -0
  159. data/src/core/lib/iomgr/cfstream_handle.cc +1 -1
  160. data/src/core/lib/iomgr/endpoint_cfstream.cc +10 -8
  161. data/src/core/lib/iomgr/ev_apple.cc +12 -12
  162. data/src/core/lib/iomgr/ev_epoll1_linux.cc +10 -3
  163. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +15 -1
  164. data/src/core/lib/iomgr/iocp_windows.cc +24 -3
  165. data/src/core/lib/iomgr/iocp_windows.h +11 -0
  166. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +1 -1
  167. data/src/core/lib/iomgr/socket_utils_common_posix.cc +4 -2
  168. data/src/core/lib/iomgr/socket_windows.cc +61 -7
  169. data/src/core/lib/iomgr/socket_windows.h +9 -2
  170. data/src/core/lib/iomgr/tcp_client_cfstream.cc +14 -3
  171. data/src/core/lib/iomgr/tcp_server_posix.cc +156 -140
  172. data/src/core/lib/iomgr/tcp_server_utils_posix.h +1 -13
  173. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +0 -21
  174. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
  175. data/src/core/lib/json/json.h +2 -166
  176. data/src/core/lib/json/json_object_loader.cc +8 -9
  177. data/src/core/lib/json/json_object_loader.h +25 -18
  178. data/src/core/lib/json/json_reader.cc +13 -6
  179. data/src/core/lib/json/json_util.cc +6 -11
  180. data/src/core/lib/json/json_writer.cc +7 -8
  181. data/src/core/lib/load_balancing/lb_policy.h +13 -0
  182. data/src/core/lib/load_balancing/lb_policy_registry.cc +2 -1
  183. data/src/core/lib/matchers/matchers.cc +3 -4
  184. data/src/core/lib/matchers/matchers.h +2 -1
  185. data/src/core/lib/promise/activity.cc +5 -0
  186. data/src/core/lib/promise/activity.h +10 -0
  187. data/src/core/lib/promise/detail/promise_factory.h +1 -1
  188. data/src/core/lib/promise/party.cc +31 -13
  189. data/src/core/lib/promise/party.h +11 -2
  190. data/src/core/lib/promise/pipe.h +9 -2
  191. data/src/core/lib/promise/prioritized_race.h +95 -0
  192. data/src/core/lib/promise/sleep.cc +2 -1
  193. data/src/core/lib/resolver/server_address.cc +0 -8
  194. data/src/core/lib/resolver/server_address.h +0 -6
  195. data/src/core/lib/resource_quota/memory_quota.cc +7 -7
  196. data/src/core/lib/resource_quota/memory_quota.h +1 -2
  197. data/src/core/lib/security/authorization/audit_logging.cc +98 -0
  198. data/src/core/lib/security/authorization/audit_logging.h +73 -0
  199. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +47 -2
  200. data/src/core/lib/security/authorization/grpc_authorization_engine.h +18 -1
  201. data/src/core/lib/security/authorization/rbac_policy.cc +36 -4
  202. data/src/core/lib/security/authorization/rbac_policy.h +19 -2
  203. data/src/core/lib/security/authorization/stdout_logger.cc +75 -0
  204. data/src/core/lib/security/authorization/stdout_logger.h +61 -0
  205. data/src/core/lib/security/certificate_provider/certificate_provider_factory.h +8 -4
  206. data/src/core/lib/security/certificate_provider/certificate_provider_registry.cc +8 -18
  207. data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +14 -8
  208. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +19 -12
  209. data/src/core/lib/security/credentials/external/external_account_credentials.cc +4 -2
  210. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +1 -0
  211. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +1 -0
  212. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +1 -0
  213. data/src/core/lib/security/credentials/jwt/json_token.cc +15 -14
  214. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +4 -2
  215. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +1 -0
  216. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -0
  217. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +1 -5
  218. data/src/core/lib/security/util/json_util.cc +1 -0
  219. data/src/core/lib/service_config/service_config_call_data.h +49 -20
  220. data/src/core/lib/service_config/service_config_impl.cc +2 -1
  221. data/src/core/lib/surface/call.cc +38 -23
  222. data/src/core/lib/surface/completion_queue.cc +6 -2
  223. data/src/core/lib/surface/validate_metadata.cc +22 -37
  224. data/src/core/lib/surface/validate_metadata.h +3 -13
  225. data/src/core/lib/surface/version.cc +2 -2
  226. data/src/core/lib/transport/batch_builder.cc +15 -12
  227. data/src/core/lib/transport/batch_builder.h +39 -35
  228. data/src/core/plugin_registry/grpc_plugin_registry.cc +0 -2
  229. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
  230. data/src/ruby/ext/grpc/extconf.rb +8 -9
  231. data/src/ruby/lib/grpc/version.rb +1 -1
  232. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_mbstr.c +9 -8
  233. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_strnid.c +1 -1
  234. data/third_party/boringssl-with-bazel/src/crypto/asn1/internal.h +3 -3
  235. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_dec.c +10 -6
  236. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.c +7 -4
  237. data/third_party/boringssl-with-bazel/src/crypto/bio/bio.c +6 -4
  238. data/third_party/boringssl-with-bazel/src/crypto/bio/fd.c +2 -1
  239. data/third_party/boringssl-with-bazel/src/crypto/bio/file.c +5 -9
  240. data/third_party/boringssl-with-bazel/src/crypto/bio/pair.c +4 -2
  241. data/third_party/boringssl-with-bazel/src/crypto/blake2/blake2.c +31 -22
  242. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/e_tls.c +29 -26
  243. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/internal.h +8 -0
  244. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/tls_cbc.c +189 -13
  245. data/third_party/boringssl-with-bazel/src/crypto/cpu_aarch64_openbsd.c +62 -0
  246. data/third_party/boringssl-with-bazel/src/crypto/cpu_arm_openbsd.c +31 -0
  247. data/third_party/boringssl-with-bazel/src/crypto/curve25519/curve25519.c +6 -4
  248. data/third_party/boringssl-with-bazel/src/crypto/curve25519/curve25519_tables.h +795 -795
  249. data/third_party/boringssl-with-bazel/src/crypto/curve25519/internal.h +1 -5
  250. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +4 -0
  251. data/third_party/boringssl-with-bazel/src/crypto/ec_extra/hash_to_curve.c +18 -6
  252. data/third_party/boringssl-with-bazel/src/crypto/ec_extra/internal.h +15 -7
  253. data/third_party/boringssl-with-bazel/src/crypto/ecdh_extra/ecdh_extra.c +1 -1
  254. data/third_party/boringssl-with-bazel/src/crypto/evp/p_rsa.c +1 -1
  255. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bcm.c +1 -0
  256. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/dh/dh.c +3 -0
  257. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec.c +24 -24
  258. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_key.c +1 -1
  259. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/ec_montgomery.c +7 -7
  260. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/internal.h +74 -74
  261. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/oct.c +1 -2
  262. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p224-64.c +11 -11
  263. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-nistz.c +12 -12
  264. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256.c +14 -15
  265. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256_table.h +1 -1
  266. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple.c +10 -10
  267. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple_mul.c +23 -23
  268. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/wnaf.c +13 -13
  269. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdh/ecdh.c +1 -1
  270. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c +2 -2
  271. data/third_party/boringssl-with-bazel/src/crypto/{hkdf → fipsmodule/hkdf}/hkdf.c +1 -1
  272. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/cbc.c +2 -10
  273. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ctr.c +1 -4
  274. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm.c +115 -133
  275. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/gcm_nohw.c +12 -14
  276. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h +57 -47
  277. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/ofb.c +1 -8
  278. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/polyval.c +27 -28
  279. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rand/urandom.c +11 -23
  280. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/internal.h +21 -16
  281. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/padding.c +5 -288
  282. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c +143 -83
  283. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c +95 -183
  284. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c +71 -0
  285. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/tls/internal.h +8 -0
  286. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/tls/kdf.c +33 -0
  287. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +162 -6
  288. data/third_party/boringssl-with-bazel/src/crypto/internal.h +18 -0
  289. data/third_party/boringssl-with-bazel/src/crypto/kyber/kyber.c +18 -11
  290. data/third_party/boringssl-with-bazel/src/crypto/obj/obj_dat.h +6 -13
  291. data/third_party/boringssl-with-bazel/src/crypto/pem/pem_lib.c +18 -14
  292. data/third_party/boringssl-with-bazel/src/crypto/{refcount_lock.c → refcount_no_threads.c} +3 -13
  293. data/third_party/boringssl-with-bazel/src/crypto/refcount_win.c +89 -0
  294. data/third_party/boringssl-with-bazel/src/crypto/rsa_extra/internal.h +77 -0
  295. data/third_party/boringssl-with-bazel/src/crypto/rsa_extra/rsa_crypt.c +568 -0
  296. data/third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h +62 -0
  297. data/third_party/boringssl-with-bazel/src/crypto/trust_token/pmbtoken.c +218 -44
  298. data/third_party/boringssl-with-bazel/src/crypto/trust_token/trust_token.c +35 -0
  299. data/third_party/boringssl-with-bazel/src/crypto/trust_token/voprf.c +588 -39
  300. data/third_party/boringssl-with-bazel/src/crypto/x509/a_sign.c +27 -18
  301. data/third_party/boringssl-with-bazel/src/crypto/x509/asn1_gen.c +1 -1
  302. data/third_party/boringssl-with-bazel/src/crypto/x509/name_print.c +17 -39
  303. data/third_party/boringssl-with-bazel/src/crypto/x509/t_x509.c +39 -48
  304. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_att.c +0 -140
  305. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_req.c +72 -23
  306. data/third_party/boringssl-with-bazel/src/crypto/x509/x509name.c +11 -14
  307. data/third_party/boringssl-with-bazel/src/crypto/x509/x509spki.c +1 -1
  308. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509a.c +2 -2
  309. data/third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h +1 -1
  310. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_conf.c +33 -46
  311. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_cpols.c +1 -0
  312. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_info.c +3 -5
  313. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_lib.c +14 -46
  314. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_prn.c +14 -26
  315. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_skey.c +17 -10
  316. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_utl.c +1 -1
  317. data/third_party/boringssl-with-bazel/src/include/openssl/aead.h +5 -7
  318. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +6 -4
  319. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +32 -1
  320. data/third_party/boringssl-with-bazel/src/include/openssl/bio.h +0 -4
  321. data/third_party/boringssl-with-bazel/src/include/openssl/blake2.h +1 -4
  322. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +3 -3
  323. data/third_party/boringssl-with-bazel/src/include/openssl/hpke.h +28 -0
  324. data/third_party/boringssl-with-bazel/src/include/openssl/nid.h +2 -11
  325. data/third_party/boringssl-with-bazel/src/include/openssl/pem.h +0 -3
  326. data/third_party/boringssl-with-bazel/src/include/openssl/rsa.h +91 -1
  327. data/third_party/boringssl-with-bazel/src/include/openssl/span.h +5 -0
  328. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +149 -20
  329. data/third_party/boringssl-with-bazel/src/include/openssl/thread.h +4 -0
  330. data/third_party/boringssl-with-bazel/src/include/openssl/tls1.h +4 -0
  331. data/third_party/boringssl-with-bazel/src/include/openssl/trust_token.h +8 -0
  332. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +774 -615
  333. data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +42 -10
  334. data/third_party/boringssl-with-bazel/src/ssl/encrypted_client_hello.cc +11 -6
  335. data/third_party/boringssl-with-bazel/src/ssl/extensions.cc +2 -4
  336. data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +24 -16
  337. data/third_party/boringssl-with-bazel/src/ssl/internal.h +65 -18
  338. data/third_party/boringssl-with-bazel/src/ssl/s3_both.cc +37 -18
  339. data/third_party/boringssl-with-bazel/src/ssl/ssl_cipher.cc +187 -193
  340. data/third_party/boringssl-with-bazel/src/ssl/ssl_key_share.cc +13 -129
  341. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +85 -10
  342. data/third_party/boringssl-with-bazel/src/ssl/ssl_privkey.cc +17 -4
  343. data/third_party/boringssl-with-bazel/src/ssl/ssl_versions.cc +27 -19
  344. data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +1 -1
  345. data/third_party/boringssl-with-bazel/src/ssl/tls13_enc.cc +5 -21
  346. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +5 -2
  347. data/third_party/boringssl-with-bazel/src/third_party/fiat/curve25519_64_msvc.h +1281 -0
  348. data/third_party/boringssl-with-bazel/src/third_party/fiat/p256_64_msvc.h +2002 -0
  349. data/third_party/cares/cares/include/ares.h +23 -1
  350. data/third_party/cares/cares/{src/lib → include}/ares_nameser.h +9 -7
  351. data/third_party/cares/cares/include/ares_rules.h +2 -2
  352. data/third_party/cares/cares/include/ares_version.h +3 -3
  353. data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +266 -0
  354. data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +240 -0
  355. data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +49 -80
  356. data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +37 -43
  357. data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +12 -4
  358. data/third_party/cares/cares/src/lib/ares_data.c +16 -0
  359. data/third_party/cares/cares/src/lib/ares_data.h +7 -0
  360. data/third_party/cares/cares/src/lib/ares_destroy.c +8 -0
  361. data/third_party/cares/cares/src/lib/ares_expand_name.c +17 -6
  362. data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +1 -0
  363. data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +156 -78
  364. data/third_party/cares/cares/src/lib/ares_gethostbyname.c +130 -326
  365. data/third_party/cares/cares/src/lib/ares_init.c +97 -485
  366. data/third_party/cares/cares/src/lib/ares_library_init.c +2 -89
  367. data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +23 -142
  368. data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +22 -142
  369. data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +184 -0
  370. data/third_party/cares/cares/src/lib/ares_private.h +30 -16
  371. data/third_party/cares/cares/src/lib/ares_process.c +55 -16
  372. data/third_party/cares/cares/src/lib/ares_query.c +1 -35
  373. data/third_party/cares/cares/src/lib/ares_rand.c +279 -0
  374. data/third_party/cares/cares/src/lib/ares_send.c +5 -7
  375. data/third_party/cares/cares/src/lib/ares_strdup.c +12 -19
  376. data/third_party/cares/cares/src/lib/ares_strsplit.c +44 -128
  377. data/third_party/cares/cares/src/lib/ares_strsplit.h +9 -10
  378. data/third_party/cares/cares/src/lib/inet_net_pton.c +78 -116
  379. data/third_party/cares/cares/src/tools/ares_getopt.h +53 -0
  380. metadata +50 -16
  381. data/src/core/ext/filters/client_channel/health/health_check_client.cc +0 -175
  382. data/src/core/ext/filters/client_channel/health/health_check_client.h +0 -43
  383. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.cc +0 -176
  384. data/src/core/ext/transport/chttp2/transport/hpack_parse_result.h +0 -325
  385. data/third_party/cares/cares/src/lib/ares_library_init.h +0 -43
@@ -24,6 +24,7 @@
24
24
  #include <stdlib.h>
25
25
 
26
26
  #include <algorithm>
27
+ #include <initializer_list>
27
28
  #include <string>
28
29
  #include <utility>
29
30
 
@@ -31,22 +32,21 @@
31
32
  #include "absl/status/status.h"
32
33
  #include "absl/strings/match.h"
33
34
  #include "absl/strings/str_cat.h"
35
+ #include "absl/strings/str_format.h"
34
36
  #include "absl/strings/string_view.h"
35
37
  #include "absl/types/optional.h"
36
38
  #include "absl/types/span.h"
37
39
  #include "absl/types/variant.h"
38
40
 
39
- #include <grpc/slice.h>
40
41
  #include <grpc/support/log.h>
41
42
 
42
43
  #include "src/core/ext/transport/chttp2/transport/decode_huff.h"
43
44
  #include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
44
- #include "src/core/ext/transport/chttp2/transport/hpack_parse_result.h"
45
- #include "src/core/ext/transport/chttp2/transport/hpack_parser_table.h"
46
45
  #include "src/core/lib/debug/stats.h"
47
46
  #include "src/core/lib/debug/stats_data.h"
48
47
  #include "src/core/lib/debug/trace.h"
49
- #include "src/core/lib/gprpp/match.h"
48
+ #include "src/core/lib/gprpp/crash.h"
49
+ #include "src/core/lib/gprpp/status_helper.h"
50
50
  #include "src/core/lib/slice/slice.h"
51
51
  #include "src/core/lib/slice/slice_refcount.h"
52
52
  #include "src/core/lib/surface/validate_metadata.h"
@@ -82,6 +82,39 @@ struct Base64InverseTable {
82
82
 
83
83
  constexpr Base64InverseTable kBase64InverseTable;
84
84
 
85
+ absl::Status EnsureStreamError(absl::Status error) {
86
+ if (error.ok()) return error;
87
+ return grpc_error_set_int(std::move(error), StatusIntProperty::kStreamId, 0);
88
+ }
89
+
90
+ bool IsStreamError(const absl::Status& status) {
91
+ intptr_t stream_id;
92
+ return grpc_error_get_int(status, StatusIntProperty::kStreamId, &stream_id);
93
+ }
94
+
95
+ class MetadataSizeLimitExceededEncoder {
96
+ public:
97
+ explicit MetadataSizeLimitExceededEncoder(std::string& summary)
98
+ : summary_(summary) {}
99
+
100
+ void Encode(const Slice& key, const Slice& value) {
101
+ AddToSummary(key.as_string_view(), value.size());
102
+ }
103
+
104
+ template <typename Key, typename Value>
105
+ void Encode(Key, const Value& value) {
106
+ AddToSummary(Key::key(), EncodedSizeOfKey(Key(), value));
107
+ }
108
+
109
+ private:
110
+ void AddToSummary(absl::string_view key,
111
+ size_t value_length) GPR_ATTRIBUTE_NOINLINE {
112
+ absl::StrAppend(&summary_, " ", key, ":",
113
+ hpack_constants::SizeForEntry(key.size(), value_length),
114
+ "B");
115
+ }
116
+ std::string& summary_;
117
+ };
85
118
  } // namespace
86
119
 
87
120
  // Input tracks the current byte through the input data and provides it
@@ -89,12 +122,11 @@ constexpr Base64InverseTable kBase64InverseTable;
89
122
  class HPackParser::Input {
90
123
  public:
91
124
  Input(grpc_slice_refcount* current_slice_refcount, const uint8_t* begin,
92
- const uint8_t* end, HpackParseResult& error)
125
+ const uint8_t* end)
93
126
  : current_slice_refcount_(current_slice_refcount),
94
127
  begin_(begin),
95
128
  end_(end),
96
- frontier_(begin),
97
- error_(error) {}
129
+ frontier_(begin) {}
98
130
 
99
131
  // If input is backed by a slice, retrieve its refcount. If not, return
100
132
  // nullptr.
@@ -124,7 +156,7 @@ class HPackParser::Input {
124
156
  // of stream
125
157
  absl::optional<uint8_t> Next() {
126
158
  if (end_of_stream()) {
127
- UnexpectedEOF(/*min_progress_size=*/1);
159
+ UnexpectedEOF();
128
160
  return absl::optional<uint8_t>();
129
161
  }
130
162
  return *begin_++;
@@ -170,16 +202,9 @@ class HPackParser::Input {
170
202
 
171
203
  // Spec weirdness: we can add an infinite stream of 0x80 at the end of a
172
204
  // varint and still end up with a correctly encoded varint.
173
- // We allow up to 16 just for kicks, but any more and we'll assume the
174
- // sender is being malicious.
175
- int num_redundant_0x80 = 0;
176
205
  do {
177
206
  cur = Next();
178
207
  if (!cur.has_value()) return {};
179
- ++num_redundant_0x80;
180
- if (num_redundant_0x80 == 16) {
181
- return ParseVarintMaliciousEncoding();
182
- }
183
208
  } while (*cur == 0x80);
184
209
 
185
210
  // BUT... the last byte needs to be 0x00 or we'll overflow dramatically!
@@ -187,6 +212,14 @@ class HPackParser::Input {
187
212
  return ParseVarintOutOfRange(value, *cur);
188
213
  }
189
214
 
215
+ // Prefix for a string
216
+ struct StringPrefix {
217
+ // Number of bytes in input for string
218
+ uint32_t length;
219
+ // Is it huffman compressed
220
+ bool huff;
221
+ };
222
+
190
223
  // Parse a string prefix
191
224
  absl::optional<StringPrefix> ParseStringPrefix() {
192
225
  auto cur = Next();
@@ -210,13 +243,17 @@ class HPackParser::Input {
210
243
  return StringPrefix{strlen, huff};
211
244
  }
212
245
 
213
- // Check if we saw an EOF
246
+ // Check if we saw an EOF.. must be verified before looking at TakeError
214
247
  bool eof_error() const {
215
- return min_progress_size_ != 0 || error_.connection_error();
248
+ return eof_error_ || (!error_.ok() && !IsStreamError(error_));
216
249
  }
217
250
 
218
- // Minimum number of bytes to unstuck the current parse
219
- size_t min_progress_size() const { return min_progress_size_; }
251
+ // Extract the parse error, leaving the current error as NONE.
252
+ grpc_error_handle TakeError() {
253
+ grpc_error_handle out = error_;
254
+ error_ = absl::OkStatus();
255
+ return out;
256
+ }
220
257
 
221
258
  bool has_error() const { return !error_.ok(); }
222
259
 
@@ -224,55 +261,31 @@ class HPackParser::Input {
224
261
  // chttp2 does not close the connection.
225
262
  // Intended for errors that are specific to a stream and recoverable.
226
263
  // Callers should ensure that any hpack table updates happen.
227
- void SetErrorAndContinueParsing(HpackParseResult error) {
228
- GPR_DEBUG_ASSERT(error.stream_error());
229
- SetError(std::move(error));
264
+ GPR_ATTRIBUTE_NOINLINE void SetErrorAndContinueParsing(
265
+ grpc_error_handle error) {
266
+ GPR_ASSERT(!error.ok());
267
+ // StreamId is used as a signal to skip this stream but keep the connection
268
+ // alive
269
+ SetError(EnsureStreamError(std::move(error)));
230
270
  }
231
271
 
232
272
  // Set the current error, and skip past remaining bytes.
233
273
  // Intended for unrecoverable errors, with the expectation that they will
234
274
  // close the connection on return to chttp2.
235
- void SetErrorAndStopParsing(HpackParseResult error) {
236
- GPR_DEBUG_ASSERT(error.connection_error());
275
+ GPR_ATTRIBUTE_NOINLINE void SetErrorAndStopParsing(grpc_error_handle error) {
276
+ GPR_ASSERT(!error.ok());
237
277
  SetError(std::move(error));
238
278
  begin_ = end_;
239
279
  }
240
280
 
241
- // Set the error to an unexpected eof.
242
- // min_progress_size: how many bytes beyond the current frontier do we need to
243
- // read prior to being able to get further in this parse.
244
- void UnexpectedEOF(size_t min_progress_size) {
245
- GPR_ASSERT(min_progress_size > 0);
246
- if (min_progress_size_ != 0 || error_.connection_error()) {
247
- GPR_DEBUG_ASSERT(eof_error());
248
- return;
249
- }
250
- // Set min progress size, taking into account bytes parsed already but not
251
- // consumed.
252
- min_progress_size_ = min_progress_size + (begin_ - frontier_);
253
- GPR_DEBUG_ASSERT(eof_error());
281
+ // Set the error to an unexpected eof
282
+ void UnexpectedEOF() {
283
+ if (!error_.ok() && !IsStreamError(error_)) return;
284
+ eof_error_ = true;
254
285
  }
255
286
 
256
287
  // Update the frontier - signifies we've successfully parsed another element
257
- void UpdateFrontier() {
258
- GPR_DEBUG_ASSERT(skip_bytes_ == 0);
259
- frontier_ = begin_;
260
- }
261
-
262
- void UpdateFrontierAndSkipBytes(size_t skip_bytes) {
263
- UpdateFrontier();
264
- size_t remaining = end_ - begin_;
265
- if (skip_bytes >= remaining) {
266
- // If we have more bytes to skip than we have remaining in this buffer
267
- // then we skip over what's there and stash that we need to skip some
268
- // more.
269
- skip_bytes_ = skip_bytes - remaining;
270
- frontier_ = end_;
271
- } else {
272
- // Otherwise we zoom through some bytes and continue parsing.
273
- frontier_ += skip_bytes_;
274
- }
275
- }
288
+ void UpdateFrontier() { frontier_ = begin_; }
276
289
 
277
290
  // Get the frontier - for buffering should we fail due to eof
278
291
  const uint8_t* frontier() const { return frontier_; }
@@ -281,23 +294,19 @@ class HPackParser::Input {
281
294
  // Helper to set the error to out of range for ParseVarint
282
295
  absl::optional<uint32_t> ParseVarintOutOfRange(uint32_t value,
283
296
  uint8_t last_byte) {
284
- SetErrorAndStopParsing(
285
- HpackParseResult::VarintOutOfRangeError(value, last_byte));
286
- return absl::optional<uint32_t>();
287
- }
288
-
289
- // Helper to set the error in the case of a malicious encoding
290
- absl::optional<uint32_t> ParseVarintMaliciousEncoding() {
291
- SetErrorAndStopParsing(HpackParseResult::MaliciousVarintEncodingError());
297
+ SetErrorAndStopParsing(absl::InternalError(absl::StrFormat(
298
+ "integer overflow in hpack integer decoding: have 0x%08x, "
299
+ "got byte 0x%02x on byte 5",
300
+ value, last_byte)));
292
301
  return absl::optional<uint32_t>();
293
302
  }
294
303
 
295
304
  // If no error is set, set it to the given error (i.e. first error wins)
296
305
  // Do not use this directly, instead use SetErrorAndContinueParsing or
297
306
  // SetErrorAndStopParsing.
298
- void SetError(HpackParseResult error) {
299
- if (!error_.ok() || min_progress_size_ > 0) {
300
- if (error.connection_error() && !error_.connection_error()) {
307
+ void SetError(grpc_error_handle error) {
308
+ if (!error_.ok() || eof_error_) {
309
+ if (!IsStreamError(error) && IsStreamError(error_)) {
301
310
  error_ = std::move(error); // connection errors dominate
302
311
  }
303
312
  return;
@@ -314,156 +323,211 @@ class HPackParser::Input {
314
323
  // Frontier denotes the first byte past successfully processed input
315
324
  const uint8_t* frontier_;
316
325
  // Current error
317
- HpackParseResult& error_;
318
- // If the error was EOF, we flag it here by noting how many more bytes would
319
- // be needed to make progress
320
- size_t min_progress_size_ = 0;
321
- // Number of bytes that should be skipped before parsing resumes.
322
- // (We've failed parsing a request for whatever reason, but we're still
323
- // continuing the connection so we need to see future opcodes after this bit).
324
- size_t skip_bytes_ = 0;
326
+ grpc_error_handle error_;
327
+ // If the error was EOF, we flag it here..
328
+ bool eof_error_ = false;
325
329
  };
326
330
 
327
- absl::string_view HPackParser::String::string_view() const {
328
- if (auto* p = absl::get_if<Slice>(&value_)) {
329
- return p->as_string_view();
330
- } else if (auto* p = absl::get_if<absl::Span<const uint8_t>>(&value_)) {
331
- return absl::string_view(reinterpret_cast<const char*>(p->data()),
332
- p->size());
333
- } else if (auto* p = absl::get_if<std::vector<uint8_t>>(&value_)) {
334
- return absl::string_view(reinterpret_cast<const char*>(p->data()),
335
- p->size());
331
+ // Helper to parse a string and turn it into a slice with appropriate memory
332
+ // management characteristics
333
+ class HPackParser::String {
334
+ public:
335
+ // ParseResult carries both a ParseStatus and the parsed string
336
+ struct ParseResult;
337
+ // Result of parsing a string
338
+ enum class ParseStatus {
339
+ // Parsed OK
340
+ kOk,
341
+ // Parse reached end of the current frame
342
+ kEof,
343
+ // Parse failed due to a huffman decode error
344
+ kParseHuffFailed,
345
+ // Parse failed due to a base64 decode error
346
+ kUnbase64Failed,
347
+ };
348
+
349
+ String() : value_(absl::Span<const uint8_t>()) {}
350
+ String(const String&) = delete;
351
+ String& operator=(const String&) = delete;
352
+ String(String&& other) noexcept : value_(std::move(other.value_)) {
353
+ other.value_ = absl::Span<const uint8_t>();
354
+ }
355
+ String& operator=(String&& other) noexcept {
356
+ value_ = std::move(other.value_);
357
+ other.value_ = absl::Span<const uint8_t>();
358
+ return *this;
336
359
  }
337
- GPR_UNREACHABLE_CODE(return absl::string_view());
338
- }
339
360
 
340
- template <typename Out>
341
- HpackParseStatus HPackParser::String::ParseHuff(Input* input, uint32_t length,
342
- Out output) {
343
- // If there's insufficient bytes remaining, return now.
344
- if (input->remaining() < length) {
345
- input->UnexpectedEOF(/*min_progress_size=*/length);
346
- return HpackParseStatus::kEof;
361
+ // Take the value and leave this empty
362
+ Slice Take();
363
+
364
+ // Return a reference to the value as a string view
365
+ absl::string_view string_view() const {
366
+ if (auto* p = absl::get_if<Slice>(&value_)) {
367
+ return p->as_string_view();
368
+ } else if (auto* p = absl::get_if<absl::Span<const uint8_t>>(&value_)) {
369
+ return absl::string_view(reinterpret_cast<const char*>(p->data()),
370
+ p->size());
371
+ } else if (auto* p = absl::get_if<std::vector<uint8_t>>(&value_)) {
372
+ return absl::string_view(reinterpret_cast<const char*>(p->data()),
373
+ p->size());
374
+ }
375
+ GPR_UNREACHABLE_CODE(return absl::string_view());
347
376
  }
348
- // Grab the byte range, and iterate through it.
349
- const uint8_t* p = input->cur_ptr();
350
- input->Advance(length);
351
- return HuffDecoder<Out>(output, p, p + length).Run()
352
- ? HpackParseStatus::kOk
353
- : HpackParseStatus::kParseHuffFailed;
354
- }
355
377
 
356
- struct HPackParser::String::StringResult {
357
- StringResult() = delete;
358
- StringResult(HpackParseStatus status, size_t wire_size, String value)
359
- : status(status), wire_size(wire_size), value(std::move(value)) {}
360
- HpackParseStatus status;
361
- size_t wire_size;
362
- String value;
363
- };
378
+ // Parse a non-binary string
379
+ static ParseResult Parse(Input* input);
364
380
 
365
- HPackParser::String::StringResult HPackParser::String::ParseUncompressed(
366
- Input* input, uint32_t length, uint32_t wire_size) {
367
- // Check there's enough bytes
368
- if (input->remaining() < length) {
369
- input->UnexpectedEOF(/*min_progress_size=*/length);
370
- GPR_DEBUG_ASSERT(input->eof_error());
371
- return StringResult{HpackParseStatus::kEof, wire_size, String{}};
372
- }
373
- auto* refcount = input->slice_refcount();
374
- auto* p = input->cur_ptr();
375
- input->Advance(length);
376
- if (refcount != nullptr) {
377
- return StringResult{HpackParseStatus::kOk, wire_size,
378
- String(refcount, p, p + length)};
379
- } else {
380
- return StringResult{HpackParseStatus::kOk, wire_size,
381
- String(absl::Span<const uint8_t>(p, length))};
382
- }
383
- }
381
+ // Parse a binary string
382
+ static ParseResult ParseBinary(Input* input);
384
383
 
385
- absl::optional<std::vector<uint8_t>> HPackParser::String::Unbase64Loop(
386
- const uint8_t* cur, const uint8_t* end) {
387
- while (cur != end && end[-1] == '=') {
388
- --end;
384
+ private:
385
+ void AppendBytes(const uint8_t* data, size_t length);
386
+ explicit String(std::vector<uint8_t> v) : value_(std::move(v)) {}
387
+ explicit String(absl::Span<const uint8_t> v) : value_(v) {}
388
+ String(grpc_slice_refcount* r, const uint8_t* begin, const uint8_t* end)
389
+ : value_(Slice::FromRefcountAndBytes(r, begin, end)) {}
390
+
391
+ // Parse some huffman encoded bytes, using output(uint8_t b) to emit each
392
+ // decoded byte.
393
+ template <typename Out>
394
+ static ParseStatus ParseHuff(Input* input, uint32_t length, Out output) {
395
+ // If there's insufficient bytes remaining, return now.
396
+ if (input->remaining() < length) {
397
+ input->UnexpectedEOF();
398
+ GPR_DEBUG_ASSERT(input->eof_error());
399
+ return ParseStatus::kEof;
400
+ }
401
+ // Grab the byte range, and iterate through it.
402
+ const uint8_t* p = input->cur_ptr();
403
+ input->Advance(length);
404
+ return HuffDecoder<Out>(output, p, p + length).Run()
405
+ ? ParseStatus::kOk
406
+ : ParseStatus::kParseHuffFailed;
389
407
  }
390
408
 
391
- std::vector<uint8_t> out;
392
- out.reserve(3 * (end - cur) / 4 + 3);
393
-
394
- // Decode 4 bytes at a time while we can
395
- while (end - cur >= 4) {
396
- uint32_t bits = kBase64InverseTable.table[*cur];
397
- if (bits > 63) return {};
398
- uint32_t buffer = bits << 18;
399
- ++cur;
400
-
401
- bits = kBase64InverseTable.table[*cur];
402
- if (bits > 63) return {};
403
- buffer |= bits << 12;
404
- ++cur;
405
-
406
- bits = kBase64InverseTable.table[*cur];
407
- if (bits > 63) return {};
408
- buffer |= bits << 6;
409
- ++cur;
410
-
411
- bits = kBase64InverseTable.table[*cur];
412
- if (bits > 63) return {};
413
- buffer |= bits;
414
- ++cur;
415
-
416
- out.insert(out.end(), {static_cast<uint8_t>(buffer >> 16),
417
- static_cast<uint8_t>(buffer >> 8),
418
- static_cast<uint8_t>(buffer)});
419
- }
420
- // Deal with the last 0, 1, 2, or 3 bytes.
421
- switch (end - cur) {
422
- case 0:
423
- return out;
424
- case 1:
425
- return {};
426
- case 2: {
427
- uint32_t bits = kBase64InverseTable.table[*cur];
428
- if (bits > 63) return {};
429
- uint32_t buffer = bits << 18;
409
+ // Parse some uncompressed string bytes.
410
+ static ParseResult ParseUncompressed(Input* input, uint32_t length,
411
+ uint32_t wire_size);
430
412
 
431
- ++cur;
432
- bits = kBase64InverseTable.table[*cur];
433
- if (bits > 63) return {};
434
- buffer |= bits << 12;
413
+ // Turn base64 encoded bytes into not base64 encoded bytes.
414
+ static ParseResult Unbase64(String s);
435
415
 
436
- if (buffer & 0xffff) return {};
437
- out.push_back(static_cast<uint8_t>(buffer >> 16));
438
- return out;
416
+ // Main loop for Unbase64
417
+ static absl::optional<std::vector<uint8_t>> Unbase64Loop(const uint8_t* cur,
418
+ const uint8_t* end) {
419
+ while (cur != end && end[-1] == '=') {
420
+ --end;
439
421
  }
440
- case 3: {
422
+
423
+ std::vector<uint8_t> out;
424
+ out.reserve(3 * (end - cur) / 4 + 3);
425
+
426
+ // Decode 4 bytes at a time while we can
427
+ while (end - cur >= 4) {
441
428
  uint32_t bits = kBase64InverseTable.table[*cur];
442
429
  if (bits > 63) return {};
443
430
  uint32_t buffer = bits << 18;
444
-
445
431
  ++cur;
432
+
446
433
  bits = kBase64InverseTable.table[*cur];
447
434
  if (bits > 63) return {};
448
435
  buffer |= bits << 12;
449
-
450
436
  ++cur;
437
+
451
438
  bits = kBase64InverseTable.table[*cur];
452
439
  if (bits > 63) return {};
453
440
  buffer |= bits << 6;
441
+ ++cur;
454
442
 
443
+ bits = kBase64InverseTable.table[*cur];
444
+ if (bits > 63) return {};
445
+ buffer |= bits;
455
446
  ++cur;
456
- if (buffer & 0xff) return {};
457
- out.push_back(static_cast<uint8_t>(buffer >> 16));
458
- out.push_back(static_cast<uint8_t>(buffer >> 8));
459
- return out;
447
+
448
+ out.insert(out.end(), {static_cast<uint8_t>(buffer >> 16),
449
+ static_cast<uint8_t>(buffer >> 8),
450
+ static_cast<uint8_t>(buffer)});
460
451
  }
452
+ // Deal with the last 0, 1, 2, or 3 bytes.
453
+ switch (end - cur) {
454
+ case 0:
455
+ return out;
456
+ case 1:
457
+ return {};
458
+ case 2: {
459
+ uint32_t bits = kBase64InverseTable.table[*cur];
460
+ if (bits > 63) return {};
461
+ uint32_t buffer = bits << 18;
462
+
463
+ ++cur;
464
+ bits = kBase64InverseTable.table[*cur];
465
+ if (bits > 63) return {};
466
+ buffer |= bits << 12;
467
+
468
+ if (buffer & 0xffff) return {};
469
+ out.push_back(static_cast<uint8_t>(buffer >> 16));
470
+ return out;
471
+ }
472
+ case 3: {
473
+ uint32_t bits = kBase64InverseTable.table[*cur];
474
+ if (bits > 63) return {};
475
+ uint32_t buffer = bits << 18;
476
+
477
+ ++cur;
478
+ bits = kBase64InverseTable.table[*cur];
479
+ if (bits > 63) return {};
480
+ buffer |= bits << 12;
481
+
482
+ ++cur;
483
+ bits = kBase64InverseTable.table[*cur];
484
+ if (bits > 63) return {};
485
+ buffer |= bits << 6;
486
+
487
+ ++cur;
488
+ if (buffer & 0xff) return {};
489
+ out.push_back(static_cast<uint8_t>(buffer >> 16));
490
+ out.push_back(static_cast<uint8_t>(buffer >> 8));
491
+ return out;
492
+ }
493
+ }
494
+
495
+ GPR_UNREACHABLE_CODE(return out;);
461
496
  }
462
497
 
463
- GPR_UNREACHABLE_CODE(return out;);
498
+ absl::variant<Slice, absl::Span<const uint8_t>, std::vector<uint8_t>> value_;
499
+ };
500
+
501
+ struct HPackParser::String::ParseResult {
502
+ ParseResult() = delete;
503
+ ParseResult(ParseStatus status, size_t wire_size, String value)
504
+ : status(status), wire_size(wire_size), value(std::move(value)) {}
505
+ ParseStatus status;
506
+ size_t wire_size;
507
+ String value;
508
+ };
509
+
510
+ HPackParser::String::ParseResult HPackParser::String::ParseUncompressed(
511
+ Input* input, uint32_t length, uint32_t wire_size) {
512
+ // Check there's enough bytes
513
+ if (input->remaining() < length) {
514
+ input->UnexpectedEOF();
515
+ GPR_DEBUG_ASSERT(input->eof_error());
516
+ return ParseResult{ParseStatus::kEof, wire_size, String{}};
517
+ }
518
+ auto* refcount = input->slice_refcount();
519
+ auto* p = input->cur_ptr();
520
+ input->Advance(length);
521
+ if (refcount != nullptr) {
522
+ return ParseResult{ParseStatus::kOk, wire_size,
523
+ String(refcount, p, p + length)};
524
+ } else {
525
+ return ParseResult{ParseStatus::kOk, wire_size,
526
+ String(absl::Span<const uint8_t>(p, length))};
527
+ }
464
528
  }
465
529
 
466
- HPackParser::String::StringResult HPackParser::String::Unbase64(String s) {
530
+ HPackParser::String::ParseResult HPackParser::String::Unbase64(String s) {
467
531
  absl::optional<std::vector<uint8_t>> result;
468
532
  if (auto* p = absl::get_if<Slice>(&s.value_)) {
469
533
  result = Unbase64Loop(p->begin(), p->end());
@@ -475,38 +539,46 @@ HPackParser::String::StringResult HPackParser::String::Unbase64(String s) {
475
539
  result = Unbase64Loop(p->data(), p->data() + p->size());
476
540
  }
477
541
  if (!result.has_value()) {
478
- return StringResult{HpackParseStatus::kUnbase64Failed,
479
- s.string_view().length(), String{}};
542
+ return ParseResult{ParseStatus::kUnbase64Failed, s.string_view().length(),
543
+ String{}};
480
544
  }
481
- return StringResult{HpackParseStatus::kOk, s.string_view().length(),
482
- String(std::move(*result))};
545
+ return ParseResult{ParseStatus::kOk, s.string_view().length(),
546
+ String(std::move(*result))};
483
547
  }
484
548
 
485
- HPackParser::String::StringResult HPackParser::String::Parse(Input* input,
486
- bool is_huff,
487
- size_t length) {
488
- if (is_huff) {
549
+ HPackParser::String::ParseResult HPackParser::String::Parse(Input* input) {
550
+ auto pfx = input->ParseStringPrefix();
551
+ if (!pfx.has_value()) {
552
+ GPR_DEBUG_ASSERT(input->eof_error());
553
+ return ParseResult{ParseStatus::kEof, 0, String{}};
554
+ }
555
+ if (pfx->huff) {
489
556
  // Huffman coded
490
557
  std::vector<uint8_t> output;
491
- HpackParseStatus sts =
492
- ParseHuff(input, length, [&output](uint8_t c) { output.push_back(c); });
558
+ ParseStatus sts = ParseHuff(input, pfx->length,
559
+ [&output](uint8_t c) { output.push_back(c); });
493
560
  size_t wire_len = output.size();
494
- return StringResult{sts, wire_len, String(std::move(output))};
561
+ return ParseResult{sts, wire_len, String(std::move(output))};
495
562
  }
496
- return ParseUncompressed(input, length, length);
563
+ return ParseUncompressed(input, pfx->length, pfx->length);
497
564
  }
498
565
 
499
- HPackParser::String::StringResult HPackParser::String::ParseBinary(
500
- Input* input, bool is_huff, size_t length) {
501
- if (!is_huff) {
502
- if (length > 0 && input->peek() == 0) {
566
+ HPackParser::String::ParseResult HPackParser::String::ParseBinary(
567
+ Input* input) {
568
+ auto pfx = input->ParseStringPrefix();
569
+ if (!pfx.has_value()) {
570
+ GPR_DEBUG_ASSERT(input->eof_error());
571
+ return ParseResult{ParseStatus::kEof, 0, String{}};
572
+ }
573
+ if (!pfx->huff) {
574
+ if (pfx->length > 0 && input->peek() == 0) {
503
575
  // 'true-binary'
504
576
  input->Advance(1);
505
- return ParseUncompressed(input, length - 1, length);
577
+ return ParseUncompressed(input, pfx->length - 1, pfx->length);
506
578
  }
507
579
  // Base64 encoded... pull out the string, then unbase64 it
508
- auto base64 = ParseUncompressed(input, length, length);
509
- if (base64.status != HpackParseStatus::kOk) return base64;
580
+ auto base64 = ParseUncompressed(input, pfx->length, pfx->length);
581
+ if (base64.status != ParseStatus::kOk) return base64;
510
582
  return Unbase64(std::move(base64.value));
511
583
  } else {
512
584
  // Huffman encoded...
@@ -515,35 +587,36 @@ HPackParser::String::StringResult HPackParser::String::ParseBinary(
515
587
  // and what is it.
516
588
  enum class State { kUnsure, kBinary, kBase64 };
517
589
  State state = State::kUnsure;
518
- auto sts = ParseHuff(input, length, [&state, &decompressed](uint8_t c) {
519
- if (state == State::kUnsure) {
520
- // First byte... if it's zero it's binary
521
- if (c == 0) {
522
- // Save the type, and skip the zero
523
- state = State::kBinary;
524
- return;
525
- } else {
526
- // Flag base64, store this value
527
- state = State::kBase64;
528
- }
529
- }
530
- // Non-first byte, or base64 first byte
531
- decompressed.push_back(c);
532
- });
533
- if (sts != HpackParseStatus::kOk) {
534
- return StringResult{sts, 0, String{}};
590
+ auto sts =
591
+ ParseHuff(input, pfx->length, [&state, &decompressed](uint8_t c) {
592
+ if (state == State::kUnsure) {
593
+ // First byte... if it's zero it's binary
594
+ if (c == 0) {
595
+ // Save the type, and skip the zero
596
+ state = State::kBinary;
597
+ return;
598
+ } else {
599
+ // Flag base64, store this value
600
+ state = State::kBase64;
601
+ }
602
+ }
603
+ // Non-first byte, or base64 first byte
604
+ decompressed.push_back(c);
605
+ });
606
+ if (sts != ParseStatus::kOk) {
607
+ return ParseResult{sts, 0, String{}};
535
608
  }
536
609
  switch (state) {
537
610
  case State::kUnsure:
538
611
  // No bytes, empty span
539
- return StringResult{HpackParseStatus::kOk, 0,
540
- String(absl::Span<const uint8_t>())};
612
+ return ParseResult{ParseStatus::kOk, 0,
613
+ String(absl::Span<const uint8_t>())};
541
614
  case State::kBinary:
542
615
  // Binary, we're done
543
616
  {
544
617
  size_t wire_len = decompressed.size();
545
- return StringResult{HpackParseStatus::kOk, wire_len,
546
- String(std::move(decompressed))};
618
+ return ParseResult{ParseStatus::kOk, wire_len,
619
+ String(std::move(decompressed))};
547
620
  }
548
621
  case State::kBase64:
549
622
  // Base64 - unpack it
@@ -556,38 +629,28 @@ HPackParser::String::StringResult HPackParser::String::ParseBinary(
556
629
  // Parser parses one key/value pair from a byte stream.
557
630
  class HPackParser::Parser {
558
631
  public:
559
- Parser(Input* input, grpc_metadata_batch*& metadata_buffer,
560
- InterSliceState& state, LogInfo log_info)
632
+ Parser(Input* input, grpc_metadata_batch* metadata_buffer, HPackTable* table,
633
+ uint8_t* dynamic_table_updates_allowed, uint32_t* frame_length,
634
+ RandomEarlyDetection* metadata_early_detection, LogInfo log_info)
561
635
  : input_(input),
562
636
  metadata_buffer_(metadata_buffer),
563
- state_(state),
637
+ table_(table),
638
+ dynamic_table_updates_allowed_(dynamic_table_updates_allowed),
639
+ frame_length_(frame_length),
640
+ metadata_early_detection_(metadata_early_detection),
564
641
  log_info_(log_info) {}
565
642
 
566
- bool Parse() {
567
- switch (state_.parse_state) {
568
- case ParseState::kTop:
569
- return ParseTop();
570
- case ParseState::kParsingKeyLength:
571
- return ParseKeyLength();
572
- case ParseState::kParsingKeyBody:
573
- return ParseKeyBody();
574
- case ParseState::kSkippingKeyBody:
575
- return SkipKeyBody();
576
- case ParseState::kParsingValueLength:
577
- return ParseValueLength();
578
- case ParseState::kParsingValueBody:
579
- return ParseValueBody();
580
- case ParseState::kSkippingValueLength:
581
- return SkipValueLength();
582
- case ParseState::kSkippingValueBody:
583
- return SkipValueBody();
643
+ // Skip any priority bits, or return false on failure
644
+ bool SkipPriority() {
645
+ if (input_->remaining() < 5) {
646
+ input_->UnexpectedEOF();
647
+ return false;
584
648
  }
585
- GPR_UNREACHABLE_CODE(return false);
649
+ input_->Advance(5);
650
+ return true;
586
651
  }
587
652
 
588
- private:
589
- bool ParseTop() {
590
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kTop);
653
+ bool Parse() {
591
654
  auto cur = *input_->Next();
592
655
  switch (cur >> 4) {
593
656
  // Literal header not indexed - First byte format: 0000xxxx
@@ -600,11 +663,11 @@ class HPackParser::Parser {
600
663
  case 1:
601
664
  switch (cur & 0xf) {
602
665
  case 0: // literal key
603
- return StartParseLiteralKey(false);
666
+ return FinishHeaderOmitFromTable(ParseLiteralKey());
604
667
  case 0xf: // varint encoded key index
605
- return StartVarIdxKey(0xf, false);
668
+ return FinishHeaderOmitFromTable(ParseVarIdxKey(0xf));
606
669
  default: // inline encoded key index
607
- return StartIdxKey(cur & 0xf, false);
670
+ return FinishHeaderOmitFromTable(ParseIdxKey(cur & 0xf));
608
671
  }
609
672
  // Update max table size.
610
673
  // First byte format: 001xxxxx
@@ -631,20 +694,20 @@ class HPackParser::Parser {
631
694
  case 4:
632
695
  if (cur == 0x40) {
633
696
  // literal key
634
- return StartParseLiteralKey(true);
697
+ return FinishHeaderAndAddToTable(ParseLiteralKey());
635
698
  }
636
699
  ABSL_FALLTHROUGH_INTENDED;
637
700
  case 5:
638
701
  case 6:
639
702
  // inline encoded key index
640
- return StartIdxKey(cur & 0x3f, true);
703
+ return FinishHeaderAndAddToTable(ParseIdxKey(cur & 0x3f));
641
704
  case 7:
642
705
  if (cur == 0x7f) {
643
706
  // varint encoded key index
644
- return StartVarIdxKey(0x3f, true);
707
+ return FinishHeaderAndAddToTable(ParseVarIdxKey(0x3f));
645
708
  } else {
646
709
  // inline encoded key index
647
- return StartIdxKey(cur & 0x3f, true);
710
+ return FinishHeaderAndAddToTable(ParseIdxKey(cur & 0x3f));
648
711
  }
649
712
  // Indexed Header Field Representation
650
713
  // First byte format: 1xxxxxxx
@@ -656,7 +719,7 @@ class HPackParser::Parser {
656
719
  if (cur == 0x80) {
657
720
  // illegal value.
658
721
  input_->SetErrorAndStopParsing(
659
- HpackParseResult::IllegalHpackOpCode());
722
+ absl::InternalError("Illegal hpack op code"));
660
723
  return false;
661
724
  }
662
725
  ABSL_FALLTHROUGH_INTENDED;
@@ -680,6 +743,7 @@ class HPackParser::Parser {
680
743
  GPR_UNREACHABLE_CODE(abort());
681
744
  }
682
745
 
746
+ private:
683
747
  void GPR_ATTRIBUTE_NOINLINE LogHeader(const HPackTable::Memento& memento) {
684
748
  const char* type;
685
749
  switch (log_info_.type) {
@@ -693,48 +757,46 @@ class HPackParser::Parser {
693
757
  type = "???";
694
758
  break;
695
759
  }
696
- gpr_log(
697
- GPR_DEBUG, "HTTP:%d:%s:%s: %s%s", log_info_.stream_id, type,
698
- log_info_.is_client ? "CLI" : "SVR", memento.md.DebugString().c_str(),
699
- memento.parse_status.ok()
700
- ? ""
701
- : absl::StrCat(" (parse error: ",
702
- memento.parse_status.Materialize().ToString(), ")")
703
- .c_str());
760
+ gpr_log(GPR_DEBUG, "HTTP:%d:%s:%s: %s%s", log_info_.stream_id, type,
761
+ log_info_.is_client ? "CLI" : "SVR",
762
+ memento.md.DebugString().c_str(),
763
+ memento.parse_status.ok()
764
+ ? ""
765
+ : absl::StrCat(
766
+ " (parse error: ", memento.parse_status.ToString(), ")")
767
+ .c_str());
704
768
  }
705
769
 
706
770
  void EmitHeader(const HPackTable::Memento& md) {
707
771
  // Pass up to the transport
708
- state_.frame_length += md.md.transport_size();
772
+ *frame_length_ += md.md.transport_size();
773
+ if (!input_->has_error() &&
774
+ metadata_early_detection_->MustReject(*frame_length_)) {
775
+ // Reject any requests above hard metadata limit.
776
+ HandleMetadataHardSizeLimitExceeded(md);
777
+ }
709
778
  if (!md.parse_status.ok()) {
710
779
  // Reject any requests with invalid metadata.
711
- input_->SetErrorAndContinueParsing(md.parse_status);
780
+ HandleMetadataParseError(md.parse_status);
712
781
  }
713
782
  if (GPR_LIKELY(metadata_buffer_ != nullptr)) {
714
783
  metadata_buffer_->Set(md.md);
715
784
  }
716
- if (state_.metadata_early_detection.MustReject(state_.frame_length)) {
717
- // Reject any requests above hard metadata limit.
718
- input_->SetErrorAndContinueParsing(
719
- HpackParseResult::HardMetadataLimitExceededError(
720
- std::exchange(metadata_buffer_, nullptr), state_.frame_length,
721
- state_.metadata_early_detection.hard_limit()));
722
- }
723
785
  }
724
786
 
725
- bool FinishHeaderAndAddToTable(HPackTable::Memento md) {
787
+ bool FinishHeaderAndAddToTable(absl::optional<HPackTable::Memento> md) {
788
+ // Allow higher code to just pass in failures ... simplifies things a bit.
789
+ if (!md.has_value()) return false;
726
790
  // Log if desired
727
791
  if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_hpack_parser)) {
728
- LogHeader(md);
792
+ LogHeader(*md);
729
793
  }
730
794
  // Emit whilst we own the metadata.
731
- EmitHeader(md);
795
+ EmitHeader(*md);
732
796
  // Add to the hpack table
733
- if (GPR_UNLIKELY(!state_.hpack_table.Add(std::move(md)))) {
734
- input_->SetErrorAndStopParsing(
735
- HpackParseResult::AddBeforeTableSizeUpdated(
736
- state_.hpack_table.current_table_bytes(),
737
- state_.hpack_table.max_bytes()));
797
+ grpc_error_handle err = table_->Add(std::move(*md));
798
+ if (GPR_UNLIKELY(!err.ok())) {
799
+ input_->SetErrorAndStopParsing(std::move(err));
738
800
  return false;
739
801
  };
740
802
  return true;
@@ -755,269 +817,136 @@ class HPackParser::Parser {
755
817
  EmitHeader(md);
756
818
  }
757
819
 
758
- // Parse an index encoded key and a string encoded value
759
- bool StartIdxKey(uint32_t index, bool add_to_table) {
760
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kTop);
761
- input_->UpdateFrontier();
762
- const auto* elem = state_.hpack_table.Lookup(index);
763
- if (GPR_UNLIKELY(elem == nullptr)) {
764
- InvalidHPackIndexError(index);
765
- return false;
766
- }
767
- state_.parse_state = ParseState::kParsingValueLength;
768
- state_.is_binary_header = elem->md.is_binary_header();
769
- state_.key.emplace<const HPackTable::Memento*>(elem);
770
- state_.add_to_table = add_to_table;
771
- return ParseValueLength();
772
- };
773
-
774
- // Parse a varint index encoded key and a string encoded value
775
- bool StartVarIdxKey(uint32_t offset, bool add_to_table) {
776
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kTop);
777
- auto index = input_->ParseVarint(offset);
778
- if (GPR_UNLIKELY(!index.has_value())) return false;
779
- return StartIdxKey(*index, add_to_table);
780
- }
781
-
782
- bool StartParseLiteralKey(bool add_to_table) {
783
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kTop);
784
- state_.add_to_table = add_to_table;
785
- state_.parse_state = ParseState::kParsingKeyLength;
786
- input_->UpdateFrontier();
787
- return ParseKeyLength();
788
- }
789
-
790
- bool ShouldSkipParsingString(uint64_t string_length) const {
791
- // We skip parsing if the string is longer than the current table size, and
792
- // if we would have to reject the string due to metadata length limits
793
- // regardless of what else was in the metadata batch.
794
- //
795
- // Why longer than the current table size? - it simplifies the logic at the
796
- // end of skipping the string (and possibly a second if this is a key).
797
- // If a key/value pair longer than the current table size is added to the
798
- // hpack table we're forced to clear the entire table - this is a
799
- // predictable operation that's easy to encode and doesn't need any state
800
- // other than "skipping" to be carried forward.
801
- // If we did not do this, we could end up in a situation where even though
802
- // the metadata would overflow the current limit, it might not overflow the
803
- // current hpack table size, and so we could not skip in on the off chance
804
- // that we'd need to add it to the hpack table *and* reject the batch as a
805
- // whole.
806
- // That would be a mess, we're not doing it.
807
- //
808
- // These rules will end up having us parse some things that ultimately get
809
- // rejected, and that's ok: the important thing is to have a bounded maximum
810
- // so we can't be forced to infinitely buffer - not to have a perfect
811
- // computation here.
812
- return string_length > state_.hpack_table.current_table_size() &&
813
- state_.metadata_early_detection.MustReject(
814
- string_length + hpack_constants::kEntryOverhead);
815
- }
816
-
817
- bool ParseKeyLength() {
818
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kParsingKeyLength);
819
- auto pfx = input_->ParseStringPrefix();
820
- if (!pfx.has_value()) return false;
821
- state_.is_string_huff_compressed = pfx->huff;
822
- state_.string_length = pfx->length;
823
- input_->UpdateFrontier();
824
- if (ShouldSkipParsingString(state_.string_length)) {
825
- input_->SetErrorAndContinueParsing(
826
- HpackParseResult::HardMetadataLimitExceededByKeyError(
827
- state_.string_length,
828
- state_.metadata_early_detection.hard_limit()));
829
- metadata_buffer_ = nullptr;
830
- state_.parse_state = ParseState::kSkippingKeyBody;
831
- return SkipKeyBody();
832
- } else {
833
- state_.parse_state = ParseState::kParsingKeyBody;
834
- return ParseKeyBody();
835
- }
836
- }
837
-
838
- bool ParseKeyBody() {
839
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kParsingKeyBody);
840
- auto key = String::Parse(input_, state_.is_string_huff_compressed,
841
- state_.string_length);
842
- switch (key.status) {
843
- case HpackParseStatus::kOk:
844
- break;
845
- case HpackParseStatus::kEof:
846
- GPR_DEBUG_ASSERT(input_->eof_error());
847
- return false;
848
- default:
849
- input_->SetErrorAndStopParsing(
850
- HpackParseResult::FromStatus(key.status));
851
- return false;
820
+ // Helper type to build a memento from a key & value, and to consolidate some
821
+ // tricky error path code.
822
+ class MementoBuilder {
823
+ public:
824
+ explicit MementoBuilder(Input* input, absl::string_view key_string,
825
+ absl::Status status = absl::OkStatus())
826
+ : input_(input), key_string_(key_string), status_(std::move(status)) {}
827
+
828
+ auto ErrorHandler() {
829
+ return [this](absl::string_view error, const Slice&) {
830
+ auto message =
831
+ absl::StrCat("Error parsing '", key_string_,
832
+ "' metadata: error=", error, " key=", key_string_);
833
+ gpr_log(GPR_ERROR, "%s", message.c_str());
834
+ if (status_.ok()) {
835
+ status_ = absl::InternalError(message);
836
+ }
837
+ };
852
838
  }
853
- input_->UpdateFrontier();
854
- state_.parse_state = ParseState::kParsingValueLength;
855
- state_.is_binary_header = absl::EndsWith(key.value.string_view(), "-bin");
856
- state_.key.emplace<Slice>(key.value.Take());
857
- return ParseValueLength();
858
- }
859
839
 
860
- bool SkipStringBody() {
861
- auto remaining = input_->remaining();
862
- if (remaining >= state_.string_length) {
863
- input_->Advance(state_.string_length);
864
- return true;
865
- } else {
866
- input_->Advance(remaining);
867
- input_->UpdateFrontier();
868
- state_.string_length -= remaining;
869
- // The default action of our outer loop is to buffer up to
870
- // min_progress_size bytes.
871
- // We know we need to do nothing up to the string length, so it would be
872
- // legal to pass that here - however that would cause a client selected
873
- // large buffer size to be accumulated, which would be an attack vector.
874
- // We could also pass 1 here, and we'd be called to parse potentially
875
- // every byte, which would give clients a way to consume substantial CPU -
876
- // again not great.
877
- // So we pick some tradeoff number - big enough to amortize wakeups, but
878
- // probably not big enough to cause excessive memory use on the receiver.
879
- input_->UnexpectedEOF(
880
- /*min_progress_size=*/std::min(state_.string_length, 1024u));
881
- return false;
840
+ HPackTable::Memento Build(ParsedMetadata<grpc_metadata_batch> memento) {
841
+ return HPackTable::Memento{std::move(memento), std::move(status_)};
882
842
  }
883
- }
884
-
885
- bool SkipKeyBody() {
886
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kSkippingKeyBody);
887
- if (!SkipStringBody()) return false;
888
- input_->UpdateFrontier();
889
- state_.parse_state = ParseState::kSkippingValueLength;
890
- return SkipValueLength();
891
- }
892
843
 
893
- bool SkipValueLength() {
894
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kSkippingValueLength);
895
- auto pfx = input_->ParseStringPrefix();
896
- if (!pfx.has_value()) return false;
897
- state_.string_length = pfx->length;
898
- input_->UpdateFrontier();
899
- state_.parse_state = ParseState::kSkippingValueBody;
900
- return SkipValueBody();
901
- }
902
-
903
- bool SkipValueBody() {
904
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kSkippingValueBody);
905
- if (!SkipStringBody()) return false;
906
- input_->UpdateFrontier();
907
- state_.parse_state = ParseState::kTop;
908
- if (state_.add_to_table) {
909
- state_.hpack_table.AddLargerThanCurrentTableSize();
844
+ // Handle the result of parsing a value.
845
+ // Returns true if parsing should continue, false if it should stop.
846
+ // Stores an error on the input if necessary.
847
+ bool HandleParseResult(String::ParseStatus status) {
848
+ auto continuable = [this](absl::string_view error) {
849
+ auto this_error = absl::InternalError(absl::StrCat(
850
+ "Error parsing '", key_string_, "' metadata: error=", error));
851
+ if (status_.ok()) status_ = this_error;
852
+ input_->SetErrorAndContinueParsing(std::move(this_error));
853
+ };
854
+ switch (status) {
855
+ case String::ParseStatus::kOk:
856
+ return true;
857
+ case String::ParseStatus::kParseHuffFailed:
858
+ input_->SetErrorAndStopParsing(
859
+ absl::InternalError("Huffman decoding failed"));
860
+ return false;
861
+ case String::ParseStatus::kUnbase64Failed:
862
+ continuable("illegal base64 encoding");
863
+ return true;
864
+ case String::ParseStatus::kEof:
865
+ GPR_DEBUG_ASSERT(input_->eof_error());
866
+ return false;
867
+ }
868
+ GPR_UNREACHABLE_CODE(return false);
910
869
  }
911
- return true;
912
- }
913
870
 
914
- bool ParseValueLength() {
915
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kParsingValueLength);
916
- auto pfx = input_->ParseStringPrefix();
917
- if (!pfx.has_value()) return false;
918
- state_.is_string_huff_compressed = pfx->huff;
919
- state_.string_length = pfx->length;
920
- input_->UpdateFrontier();
921
- if (ShouldSkipParsingString(state_.string_length)) {
922
- input_->SetErrorAndContinueParsing(
923
- HpackParseResult::HardMetadataLimitExceededByValueError(
924
- Match(
925
- state_.key, [](const Slice& s) { return s.as_string_view(); },
926
- [](const HPackTable::Memento* m) { return m->md.key(); }),
927
- state_.string_length,
928
- state_.metadata_early_detection.hard_limit()));
929
- metadata_buffer_ = nullptr;
930
- state_.parse_state = ParseState::kSkippingValueBody;
931
- return SkipValueBody();
932
- } else {
933
- state_.parse_state = ParseState::kParsingValueBody;
934
- return ParseValueBody();
935
- }
936
- }
871
+ private:
872
+ Input* input_;
873
+ absl::string_view key_string_;
874
+ absl::Status status_;
875
+ };
937
876
 
938
- bool ParseValueBody() {
939
- GPR_DEBUG_ASSERT(state_.parse_state == ParseState::kParsingValueBody);
940
- auto value =
941
- state_.is_binary_header
942
- ? String::ParseBinary(input_, state_.is_string_huff_compressed,
943
- state_.string_length)
944
- : String::Parse(input_, state_.is_string_huff_compressed,
945
- state_.string_length);
946
- HpackParseResult& status = state_.frame_error;
947
- absl::string_view key_string;
948
- if (auto* s = absl::get_if<Slice>(&state_.key)) {
949
- key_string = s->as_string_view();
950
- if (status.ok()) {
951
- auto r = ValidateKey(key_string);
952
- if (r != ValidateMetadataResult::kOk) {
953
- input_->SetErrorAndContinueParsing(
954
- HpackParseResult::InvalidMetadataError(r, key_string));
955
- }
956
- }
957
- } else {
958
- const auto* memento = absl::get<const HPackTable::Memento*>(state_.key);
959
- key_string = memento->md.key();
960
- if (status.ok() && !memento->parse_status.ok()) {
961
- input_->SetErrorAndContinueParsing(memento->parse_status);
962
- }
963
- }
964
- switch (value.status) {
965
- case HpackParseStatus::kOk:
877
+ // Parse a string encoded key and a string encoded value
878
+ absl::optional<HPackTable::Memento> ParseLiteralKey() {
879
+ auto key = String::Parse(input_);
880
+ switch (key.status) {
881
+ case String::ParseStatus::kOk:
966
882
  break;
967
- case HpackParseStatus::kEof:
883
+ case String::ParseStatus::kParseHuffFailed:
884
+ input_->SetErrorAndStopParsing(
885
+ absl::InternalError("Huffman decoding failed"));
886
+ return absl::nullopt;
887
+ case String::ParseStatus::kUnbase64Failed:
888
+ Crash("unreachable");
889
+ case String::ParseStatus::kEof:
968
890
  GPR_DEBUG_ASSERT(input_->eof_error());
969
- return false;
970
- default: {
971
- auto result =
972
- HpackParseResult::FromStatusWithKey(value.status, key_string);
973
- if (result.stream_error()) {
974
- input_->SetErrorAndContinueParsing(std::move(result));
975
- break;
976
- } else {
977
- input_->SetErrorAndStopParsing(std::move(result));
978
- return false;
979
- }
980
- }
891
+ return absl::nullopt;
981
892
  }
893
+ auto key_string = key.value.string_view();
894
+ auto value = ParseValueString(absl::EndsWith(key_string, "-bin"));
895
+ MementoBuilder builder(input_, key_string,
896
+ EnsureStreamError(ValidateKey(key_string)));
897
+ if (!builder.HandleParseResult(value.status)) return absl::nullopt;
982
898
  auto value_slice = value.value.Take();
983
899
  const auto transport_size =
984
900
  key_string.size() + value.wire_size + hpack_constants::kEntryOverhead;
985
- auto md = grpc_metadata_batch::Parse(
986
- key_string, std::move(value_slice), transport_size,
987
- [key_string, &status, this](absl::string_view message, const Slice&) {
988
- if (!status.ok()) return;
989
- input_->SetErrorAndContinueParsing(
990
- HpackParseResult::MetadataParseError(key_string));
991
- gpr_log(GPR_ERROR, "Error parsing '%s' metadata: %s",
992
- std::string(key_string).c_str(),
993
- std::string(message).c_str());
994
- });
995
- HPackTable::Memento memento{std::move(md),
996
- status.PersistentStreamErrorOrOk()};
997
- input_->UpdateFrontier();
998
- state_.parse_state = ParseState::kTop;
999
- if (state_.add_to_table) {
1000
- return FinishHeaderAndAddToTable(std::move(memento));
1001
- } else {
1002
- FinishHeaderOmitFromTable(memento);
1003
- return true;
1004
- }
901
+ return builder.Build(
902
+ grpc_metadata_batch::Parse(key_string, std::move(value_slice),
903
+ transport_size, builder.ErrorHandler()));
1005
904
  }
1006
905
 
1007
- ValidateMetadataResult ValidateKey(absl::string_view key) {
906
+ absl::Status ValidateKey(absl::string_view key) {
1008
907
  if (key == HttpSchemeMetadata::key() || key == HttpMethodMetadata::key() ||
1009
908
  key == HttpAuthorityMetadata::key() || key == HttpPathMetadata::key() ||
1010
909
  key == HttpStatusMetadata::key()) {
1011
- return ValidateMetadataResult::kOk;
910
+ return absl::OkStatus();
1012
911
  }
1013
912
  return ValidateHeaderKeyIsLegal(key);
1014
913
  }
1015
914
 
915
+ // Parse an index encoded key and a string encoded value
916
+ absl::optional<HPackTable::Memento> ParseIdxKey(uint32_t index) {
917
+ const auto* elem = table_->Lookup(index);
918
+ if (GPR_UNLIKELY(elem == nullptr)) {
919
+ InvalidHPackIndexError(index);
920
+ return absl::optional<HPackTable::Memento>();
921
+ }
922
+ MementoBuilder builder(input_, elem->md.key(), elem->parse_status);
923
+ auto value = ParseValueString(elem->md.is_binary_header());
924
+ if (!builder.HandleParseResult(value.status)) return absl::nullopt;
925
+ return builder.Build(elem->md.WithNewValue(
926
+ value.value.Take(), value.wire_size, builder.ErrorHandler()));
927
+ };
928
+
929
+ // Parse a varint index encoded key and a string encoded value
930
+ absl::optional<HPackTable::Memento> ParseVarIdxKey(uint32_t offset) {
931
+ auto index = input_->ParseVarint(offset);
932
+ if (GPR_UNLIKELY(!index.has_value())) return absl::nullopt;
933
+ return ParseIdxKey(*index);
934
+ }
935
+
936
+ // Parse a string, figuring out if it's binary or not by the key name.
937
+ String::ParseResult ParseValueString(bool is_binary) {
938
+ if (is_binary) {
939
+ return String::ParseBinary(input_);
940
+ } else {
941
+ return String::Parse(input_);
942
+ }
943
+ }
944
+
1016
945
  // Emit an indexed field
1017
946
  bool FinishIndexed(absl::optional<uint32_t> index) {
1018
- state_.dynamic_table_updates_allowed = 0;
947
+ *dynamic_table_updates_allowed_ = 0;
1019
948
  if (!index.has_value()) return false;
1020
- const auto* elem = state_.hpack_table.Lookup(*index);
949
+ const auto* elem = table_->Lookup(*index);
1021
950
  if (GPR_UNLIKELY(elem == nullptr)) {
1022
951
  InvalidHPackIndexError(*index);
1023
952
  return false;
@@ -1029,16 +958,15 @@ class HPackParser::Parser {
1029
958
  // finish parsing a max table size change
1030
959
  bool FinishMaxTableSize(absl::optional<uint32_t> size) {
1031
960
  if (!size.has_value()) return false;
1032
- if (state_.dynamic_table_updates_allowed == 0) {
1033
- input_->SetErrorAndStopParsing(
1034
- HpackParseResult::TooManyDynamicTableSizeChangesError());
961
+ if (*dynamic_table_updates_allowed_ == 0) {
962
+ input_->SetErrorAndStopParsing(absl::InternalError(
963
+ "More than two max table size changes in a single frame"));
1035
964
  return false;
1036
965
  }
1037
- state_.dynamic_table_updates_allowed--;
1038
- if (!state_.hpack_table.SetCurrentTableSize(*size)) {
1039
- input_->SetErrorAndStopParsing(
1040
- HpackParseResult::IllegalTableSizeChangeError(
1041
- *size, state_.hpack_table.max_bytes()));
966
+ (*dynamic_table_updates_allowed_)--;
967
+ grpc_error_handle err = table_->SetCurrentTableSize(*size);
968
+ if (!err.ok()) {
969
+ input_->SetErrorAndStopParsing(std::move(err));
1042
970
  return false;
1043
971
  }
1044
972
  return true;
@@ -1047,13 +975,51 @@ class HPackParser::Parser {
1047
975
  // Set an invalid hpack index error if no error has been set. Returns result
1048
976
  // unmodified.
1049
977
  void InvalidHPackIndexError(uint32_t index) {
1050
- input_->SetErrorAndStopParsing(
1051
- HpackParseResult::InvalidHpackIndexError(index));
978
+ input_->SetErrorAndStopParsing(grpc_error_set_int(
979
+ grpc_error_set_int(absl::InternalError("Invalid HPACK index received"),
980
+ StatusIntProperty::kIndex,
981
+ static_cast<intptr_t>(index)),
982
+ StatusIntProperty::kSize,
983
+ static_cast<intptr_t>(this->table_->num_entries())));
984
+ }
985
+
986
+ GPR_ATTRIBUTE_NOINLINE
987
+ void HandleMetadataParseError(const absl::Status& status) {
988
+ if (metadata_buffer_ != nullptr) {
989
+ metadata_buffer_->Clear();
990
+ metadata_buffer_ = nullptr;
991
+ }
992
+ // StreamId is used as a signal to skip this stream but keep the connection
993
+ // alive
994
+ input_->SetErrorAndContinueParsing(status);
995
+ }
996
+
997
+ GPR_ATTRIBUTE_NOINLINE
998
+ void HandleMetadataHardSizeLimitExceeded(const HPackTable::Memento& md) {
999
+ // Collect a summary of sizes so far for debugging
1000
+ // Do not collect contents, for fear of exposing PII.
1001
+ std::string summary;
1002
+ std::string error_message;
1003
+ if (metadata_buffer_ != nullptr) {
1004
+ MetadataSizeLimitExceededEncoder encoder(summary);
1005
+ metadata_buffer_->Encode(&encoder);
1006
+ }
1007
+ summary = absl::StrCat("; adding ", md.md.key(), " (length ",
1008
+ md.md.transport_size(), "B)",
1009
+ summary.empty() ? "" : " to ", summary);
1010
+ error_message = absl::StrCat(
1011
+ "received metadata size exceeds hard limit (", *frame_length_, " vs. ",
1012
+ metadata_early_detection_->hard_limit(), ")", summary);
1013
+ HandleMetadataParseError(absl::ResourceExhaustedError(error_message));
1052
1014
  }
1053
1015
 
1054
1016
  Input* const input_;
1055
- grpc_metadata_batch*& metadata_buffer_;
1056
- InterSliceState& state_;
1017
+ grpc_metadata_batch* metadata_buffer_;
1018
+ HPackTable* const table_;
1019
+ uint8_t* const dynamic_table_updates_allowed_;
1020
+ uint32_t* const frame_length_;
1021
+ // Random early detection of metadata size limits.
1022
+ RandomEarlyDetection* metadata_early_detection_;
1057
1023
  const LogInfo log_info_;
1058
1024
  };
1059
1025
 
@@ -1085,8 +1051,9 @@ void HPackParser::BeginFrame(grpc_metadata_batch* metadata_buffer,
1085
1051
  }
1086
1052
  boundary_ = boundary;
1087
1053
  priority_ = priority;
1088
- state_.dynamic_table_updates_allowed = 2;
1089
- state_.metadata_early_detection.SetLimits(
1054
+ dynamic_table_updates_allowed_ = 2;
1055
+ frame_length_ = 0;
1056
+ metadata_early_detection_ = RandomEarlyDetection(
1090
1057
  /*soft_limit=*/metadata_size_soft_limit,
1091
1058
  /*hard_limit=*/metadata_size_hard_limit);
1092
1059
  log_info_ = log_info;
@@ -1094,43 +1061,36 @@ void HPackParser::BeginFrame(grpc_metadata_batch* metadata_buffer,
1094
1061
 
1095
1062
  grpc_error_handle HPackParser::Parse(const grpc_slice& slice, bool is_last) {
1096
1063
  if (GPR_UNLIKELY(!unparsed_bytes_.empty())) {
1097
- unparsed_bytes_.insert(unparsed_bytes_.end(), GRPC_SLICE_START_PTR(slice),
1098
- GRPC_SLICE_END_PTR(slice));
1099
- if (!(is_last && is_boundary()) &&
1100
- unparsed_bytes_.size() < min_progress_size_) {
1101
- // We wouldn't make progress anyway, skip out.
1102
- return absl::OkStatus();
1103
- }
1104
1064
  std::vector<uint8_t> buffer = std::move(unparsed_bytes_);
1105
- return ParseInput(Input(nullptr, buffer.data(),
1106
- buffer.data() + buffer.size(), state_.frame_error),
1107
- is_last);
1065
+ buffer.insert(buffer.end(), GRPC_SLICE_START_PTR(slice),
1066
+ GRPC_SLICE_END_PTR(slice));
1067
+ return ParseInput(
1068
+ Input(nullptr, buffer.data(), buffer.data() + buffer.size()), is_last);
1108
1069
  }
1109
1070
  return ParseInput(Input(slice.refcount, GRPC_SLICE_START_PTR(slice),
1110
- GRPC_SLICE_END_PTR(slice), state_.frame_error),
1071
+ GRPC_SLICE_END_PTR(slice)),
1111
1072
  is_last);
1112
1073
  }
1113
1074
 
1114
1075
  grpc_error_handle HPackParser::ParseInput(Input input, bool is_last) {
1115
1076
  ParseInputInner(&input);
1116
- if (is_last && is_boundary()) {
1117
- if (state_.metadata_early_detection.Reject(state_.frame_length)) {
1077
+ if (is_last) {
1078
+ if (metadata_early_detection_.Reject(frame_length_)) {
1118
1079
  HandleMetadataSoftSizeLimitExceeded(&input);
1119
1080
  }
1120
- global_stats().IncrementHttp2MetadataSize(state_.frame_length);
1121
- if (!state_.frame_error.connection_error() &&
1122
- (input.eof_error() || state_.parse_state != ParseState::kTop)) {
1123
- state_.frame_error = HpackParseResult::IncompleteHeaderAtBoundaryError();
1124
- }
1125
- state_.frame_length = 0;
1126
- return std::exchange(state_.frame_error, HpackParseResult()).Materialize();
1127
- } else {
1128
- if (input.eof_error() && !state_.frame_error.connection_error()) {
1129
- unparsed_bytes_ = std::vector<uint8_t>(input.frontier(), input.end_ptr());
1130
- min_progress_size_ = input.min_progress_size();
1081
+ global_stats().IncrementHttp2MetadataSize(frame_length_);
1082
+ }
1083
+ if (input.eof_error()) {
1084
+ if (GPR_UNLIKELY(is_last && is_boundary())) {
1085
+ auto err = input.TakeError();
1086
+ if (!err.ok() && !IsStreamError(err)) return err;
1087
+ return absl::InternalError(
1088
+ "Incomplete header at the end of a header/continuation sequence");
1131
1089
  }
1132
- return state_.frame_error.Materialize();
1090
+ unparsed_bytes_ = std::vector<uint8_t>(input.frontier(), input.end_ptr());
1091
+ return input.TakeError();
1133
1092
  }
1093
+ return input.TakeError();
1134
1094
  }
1135
1095
 
1136
1096
  void HPackParser::ParseInputInner(Input* input) {
@@ -1139,7 +1099,7 @@ void HPackParser::ParseInputInner(Input* input) {
1139
1099
  break;
1140
1100
  case Priority::Included: {
1141
1101
  if (input->remaining() < 5) {
1142
- input->UnexpectedEOF(/*min_progress_size=*/5);
1102
+ input->UnexpectedEOF();
1143
1103
  return;
1144
1104
  }
1145
1105
  input->Advance(5);
@@ -1148,8 +1108,10 @@ void HPackParser::ParseInputInner(Input* input) {
1148
1108
  }
1149
1109
  }
1150
1110
  while (!input->end_of_stream()) {
1151
- if (GPR_UNLIKELY(
1152
- !Parser(input, metadata_buffer_, state_, log_info_).Parse())) {
1111
+ if (GPR_UNLIKELY(!Parser(input, metadata_buffer_, &table_,
1112
+ &dynamic_table_updates_allowed_, &frame_length_,
1113
+ &metadata_early_detection_, log_info_)
1114
+ .Parse())) {
1153
1115
  return;
1154
1116
  }
1155
1117
  input->UpdateFrontier();
@@ -1159,10 +1121,24 @@ void HPackParser::ParseInputInner(Input* input) {
1159
1121
  void HPackParser::FinishFrame() { metadata_buffer_ = nullptr; }
1160
1122
 
1161
1123
  void HPackParser::HandleMetadataSoftSizeLimitExceeded(Input* input) {
1124
+ // Collect a summary of sizes so far for debugging
1125
+ // Do not collect contents, for fear of exposing PII.
1126
+ std::string summary;
1127
+ std::string error_message;
1128
+ if (metadata_buffer_ != nullptr) {
1129
+ MetadataSizeLimitExceededEncoder encoder(summary);
1130
+ metadata_buffer_->Encode(&encoder);
1131
+ }
1132
+ error_message = absl::StrCat(
1133
+ "received metadata size exceeds soft limit (", frame_length_, " vs. ",
1134
+ metadata_early_detection_.soft_limit(),
1135
+ "), rejecting requests with some random probability", summary);
1136
+ if (metadata_buffer_ != nullptr) {
1137
+ metadata_buffer_->Clear();
1138
+ metadata_buffer_ = nullptr;
1139
+ }
1162
1140
  input->SetErrorAndContinueParsing(
1163
- HpackParseResult::SoftMetadataLimitExceededError(
1164
- std::exchange(metadata_buffer_, nullptr), state_.frame_length,
1165
- state_.metadata_early_detection.soft_limit()));
1141
+ absl::ResourceExhaustedError(error_message));
1166
1142
  }
1167
1143
 
1168
1144
  } // namespace grpc_core