grpc 0.14.1 → 0.15.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 (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1398 -817
  3. data/include/grpc/compression.h +2 -1
  4. data/include/grpc/grpc.h +10 -1
  5. data/include/grpc/grpc_cronet.h +51 -0
  6. data/include/grpc/grpc_posix.h +70 -0
  7. data/include/grpc/impl/codegen/atm.h +2 -2
  8. data/include/grpc/impl/codegen/{atm_win32.h → atm_windows.h} +3 -3
  9. data/include/grpc/impl/codegen/compression_types.h +39 -5
  10. data/include/grpc/impl/codegen/connectivity_state.h +1 -1
  11. data/include/grpc/impl/codegen/grpc_types.h +10 -0
  12. data/include/grpc/impl/codegen/log.h +2 -1
  13. data/include/grpc/impl/codegen/port_platform.h +30 -12
  14. data/include/grpc/impl/codegen/slice_buffer.h +2 -3
  15. data/include/grpc/impl/codegen/sync.h +2 -2
  16. data/include/grpc/impl/codegen/{sync_win32.h → sync_windows.h} +3 -3
  17. data/include/grpc/support/{sync_win32.h → atm_windows.h} +4 -4
  18. data/include/grpc/support/avl.h +5 -0
  19. data/include/grpc/support/{log_win32.h → log_windows.h} +3 -3
  20. data/include/grpc/support/string_util.h +2 -1
  21. data/include/grpc/support/{atm_win32.h → sync_windows.h} +4 -4
  22. data/src/core/ext/census/gen/census.pb.c +179 -0
  23. data/src/core/ext/census/gen/census.pb.h +294 -0
  24. data/src/core/ext/census/grpc_filter.c +11 -7
  25. data/src/core/ext/client_config/channel_connectivity.c +28 -14
  26. data/src/core/ext/client_config/client_channel.c +77 -53
  27. data/src/core/ext/client_config/connector.h +1 -1
  28. data/src/core/ext/client_config/lb_policy.c +9 -6
  29. data/src/core/ext/client_config/lb_policy.h +9 -5
  30. data/src/core/ext/client_config/subchannel.c +58 -39
  31. data/src/core/ext/client_config/subchannel.h +3 -2
  32. data/src/core/ext/client_config/subchannel_call_holder.c +34 -19
  33. data/src/core/ext/client_config/subchannel_call_holder.h +2 -1
  34. data/src/core/ext/client_config/subchannel_index.c +20 -9
  35. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +7 -7
  36. data/src/core/ext/lb_policy/grpclb/load_balancer_api.h +5 -5
  37. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/{v0 → v1}/load_balancer.pb.c +29 -30
  38. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +178 -0
  39. data/src/core/ext/lb_policy/pick_first/pick_first.c +65 -45
  40. data/src/core/ext/lb_policy/round_robin/round_robin.c +84 -43
  41. data/src/core/ext/load_reporting/load_reporting.c +133 -0
  42. data/src/core/ext/load_reporting/load_reporting.h +75 -0
  43. data/src/core/ext/load_reporting/load_reporting_filter.c +151 -0
  44. data/src/core/ext/load_reporting/load_reporting_filter.h +41 -0
  45. data/src/core/ext/resolver/dns/native/dns_resolver.c +22 -8
  46. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +2 -2
  47. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +4 -4
  48. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +95 -0
  49. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +14 -18
  50. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +49 -24
  51. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +82 -0
  52. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +104 -60
  53. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +232 -0
  54. data/src/{ruby/ext/grpc/rb_signal.c → core/ext/transport/chttp2/transport/bin_decoder.h} +27 -31
  55. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +481 -260
  56. data/src/core/ext/transport/chttp2/transport/frame.h +1 -7
  57. data/src/core/ext/transport/chttp2/transport/frame_data.c +44 -27
  58. data/src/core/ext/transport/chttp2/transport/frame_data.h +6 -5
  59. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +23 -17
  60. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +2 -2
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.c +12 -7
  62. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -3
  63. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +25 -12
  64. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -2
  65. data/src/core/ext/transport/chttp2/transport/frame_settings.c +23 -21
  66. data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -2
  67. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +17 -9
  68. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +2 -2
  69. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +365 -287
  70. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -6
  71. data/src/core/ext/transport/chttp2/transport/hpack_table.c +24 -20
  72. data/src/core/ext/transport/chttp2/transport/hpack_table.h +5 -4
  73. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +1 -0
  74. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +1 -0
  75. data/src/core/ext/transport/chttp2/transport/internal.h +34 -32
  76. data/src/core/ext/transport/chttp2/transport/parsing.c +296 -212
  77. data/src/core/ext/transport/chttp2/transport/writing.c +12 -9
  78. data/src/core/lib/channel/channel_args.c +26 -12
  79. data/src/core/lib/channel/channel_args.h +1 -1
  80. data/src/core/lib/channel/channel_stack.c +12 -8
  81. data/src/core/lib/channel/channel_stack.h +27 -11
  82. data/src/core/lib/channel/channel_stack_builder.c +2 -2
  83. data/src/core/lib/channel/compress_filter.c +26 -31
  84. data/src/core/lib/channel/compress_filter.h +4 -4
  85. data/src/core/lib/channel/connected_channel.c +7 -5
  86. data/src/core/lib/channel/http_client_filter.c +34 -8
  87. data/src/core/lib/channel/http_client_filter.h +1 -1
  88. data/src/core/lib/channel/http_server_filter.c +21 -12
  89. data/src/core/lib/compression/{compression_algorithm.c → compression.c} +22 -21
  90. data/src/core/lib/http/httpcli.c +81 -59
  91. data/src/core/lib/http/httpcli.h +11 -15
  92. data/src/core/lib/http/httpcli_security_connector.c +5 -3
  93. data/src/core/lib/http/parser.c +127 -118
  94. data/src/core/lib/http/parser.h +11 -6
  95. data/src/core/lib/iomgr/closure.c +20 -16
  96. data/src/core/lib/iomgr/closure.h +19 -15
  97. data/src/core/lib/iomgr/endpoint.h +1 -1
  98. data/src/core/lib/iomgr/endpoint_pair_posix.c +2 -2
  99. data/src/core/lib/iomgr/error.c +535 -0
  100. data/src/core/lib/iomgr/error.h +192 -0
  101. data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +190 -83
  102. data/src/core/lib/iomgr/ev_poll_posix.c +1267 -0
  103. data/src/{ruby/ext/grpc/rb_signal.h → core/lib/iomgr/ev_poll_posix.h} +7 -5
  104. data/src/core/lib/iomgr/ev_posix.c +104 -14
  105. data/src/core/lib/iomgr/ev_posix.h +17 -7
  106. data/src/core/lib/iomgr/exec_ctx.c +25 -7
  107. data/src/core/lib/iomgr/exec_ctx.h +27 -8
  108. data/src/core/lib/iomgr/executor.c +2 -2
  109. data/src/core/lib/iomgr/executor.h +1 -1
  110. data/src/core/lib/iomgr/iocp_windows.c +2 -41
  111. data/src/core/lib/iomgr/iocp_windows.h +0 -8
  112. data/src/core/lib/iomgr/iomgr.c +5 -4
  113. data/src/core/lib/iomgr/iomgr_posix.c +5 -1
  114. data/src/core/lib/iomgr/iomgr_windows.c +1 -1
  115. data/src/core/lib/{support → iomgr}/load_file.c +15 -17
  116. data/src/core/lib/{support → iomgr}/load_file.h +8 -7
  117. data/src/core/lib/iomgr/polling_entity.c +104 -0
  118. data/src/core/lib/iomgr/polling_entity.h +81 -0
  119. data/src/core/lib/iomgr/pollset.h +6 -5
  120. data/src/core/lib/iomgr/pollset_set_windows.c +4 -1
  121. data/src/core/lib/iomgr/pollset_windows.c +10 -6
  122. data/src/core/lib/iomgr/resolve_address.h +5 -9
  123. data/src/core/lib/iomgr/resolve_address_posix.c +55 -38
  124. data/src/core/lib/iomgr/resolve_address_windows.c +51 -37
  125. data/src/core/lib/iomgr/sockaddr.h +2 -2
  126. data/src/core/lib/iomgr/{sockaddr_win32.h → sockaddr_windows.h} +3 -3
  127. data/src/core/lib/iomgr/socket_utils_common_posix.c +92 -45
  128. data/src/core/lib/iomgr/socket_utils_posix.h +19 -12
  129. data/src/core/lib/iomgr/socket_windows.c +61 -2
  130. data/src/core/lib/iomgr/socket_windows.h +13 -0
  131. data/src/core/lib/iomgr/tcp_client_posix.c +54 -39
  132. data/src/core/lib/iomgr/tcp_client_windows.c +34 -34
  133. data/src/core/lib/iomgr/tcp_posix.c +43 -39
  134. data/src/core/lib/iomgr/tcp_server.h +5 -3
  135. data/src/core/lib/iomgr/tcp_server_posix.c +103 -64
  136. data/src/core/lib/iomgr/tcp_server_windows.c +114 -101
  137. data/src/core/lib/iomgr/tcp_windows.c +45 -50
  138. data/src/core/lib/iomgr/tcp_windows.h +1 -1
  139. data/src/core/lib/iomgr/timer.c +26 -13
  140. data/src/core/lib/iomgr/udp_server.c +28 -4
  141. data/src/core/lib/iomgr/udp_server.h +5 -1
  142. data/src/core/lib/iomgr/unix_sockets_posix.c +8 -7
  143. data/src/core/lib/iomgr/unix_sockets_posix.h +2 -1
  144. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +4 -2
  145. data/src/core/lib/iomgr/wakeup_fd_eventfd.c +15 -5
  146. data/src/core/lib/iomgr/wakeup_fd_pipe.c +13 -9
  147. data/src/core/lib/iomgr/wakeup_fd_posix.c +6 -6
  148. data/src/core/lib/iomgr/wakeup_fd_posix.h +9 -6
  149. data/src/core/lib/iomgr/workqueue.h +5 -4
  150. data/src/core/lib/iomgr/workqueue_posix.c +40 -26
  151. data/src/core/lib/iomgr/workqueue_windows.c +2 -2
  152. data/src/core/lib/profiling/basic_timers.c +2 -2
  153. data/src/core/lib/security/{security_context.c → context/security_context.c} +1 -1
  154. data/src/core/lib/security/{security_context.h → context/security_context.h} +4 -4
  155. data/src/core/lib/security/credentials/composite/composite_credentials.c +263 -0
  156. data/src/core/lib/security/credentials/composite/composite_credentials.h +72 -0
  157. data/src/core/lib/security/credentials/credentials.c +233 -0
  158. data/src/core/lib/security/{credentials.h → credentials/credentials.h} +19 -157
  159. data/src/core/lib/security/{credentials_metadata.c → credentials/credentials_metadata.c} +1 -1
  160. data/src/core/lib/security/credentials/fake/fake_credentials.c +139 -0
  161. data/src/core/lib/security/credentials/fake/fake_credentials.h +56 -0
  162. data/src/core/lib/security/{credentials_posix.c → credentials/google_default/credentials_posix.c} +1 -1
  163. data/src/core/lib/security/{credentials_win32.c → credentials/google_default/credentials_windows.c} +3 -3
  164. data/src/core/lib/security/{google_default_credentials.c → credentials/google_default/google_default_credentials.c} +93 -35
  165. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +46 -0
  166. data/src/core/lib/security/credentials/iam/iam_credentials.c +85 -0
  167. data/src/core/lib/security/credentials/iam/iam_credentials.h +44 -0
  168. data/src/core/lib/security/{json_token.c → credentials/jwt/json_token.c} +10 -101
  169. data/src/core/lib/security/{json_token.h → credentials/jwt/json_token.h} +3 -33
  170. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +160 -0
  171. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +62 -0
  172. data/src/core/lib/security/{jwt_verifier.c → credentials/jwt/jwt_verifier.c} +35 -15
  173. data/src/core/lib/security/{jwt_verifier.h → credentials/jwt/jwt_verifier.h} +3 -3
  174. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +433 -0
  175. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +109 -0
  176. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +129 -0
  177. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +45 -0
  178. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +240 -0
  179. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +48 -0
  180. data/src/core/lib/security/{auth_filters.h → transport/auth_filters.h} +3 -3
  181. data/src/core/lib/security/{client_auth_filter.c → transport/client_auth_filter.c} +27 -20
  182. data/src/core/lib/security/{handshake.c → transport/handshake.c} +77 -45
  183. data/src/core/lib/security/{handshake.h → transport/handshake.h} +9 -11
  184. data/src/core/lib/security/{secure_endpoint.c → transport/secure_endpoint.c} +19 -12
  185. data/src/core/lib/security/{secure_endpoint.h → transport/secure_endpoint.h} +3 -3
  186. data/src/core/lib/security/{security_connector.c → transport/security_connector.c} +26 -17
  187. data/src/core/lib/security/{security_connector.h → transport/security_connector.h} +8 -8
  188. data/src/core/lib/security/{server_auth_filter.c → transport/server_auth_filter.c} +24 -16
  189. data/src/core/lib/security/transport/tsi_error.c +40 -0
  190. data/src/core/lib/security/transport/tsi_error.h +42 -0
  191. data/src/core/lib/security/{b64.c → util/b64.c} +1 -1
  192. data/src/core/lib/security/{b64.h → util/b64.h} +3 -3
  193. data/src/core/lib/security/util/json_util.c +61 -0
  194. data/src/core/lib/security/util/json_util.h +55 -0
  195. data/src/core/lib/support/avl.c +11 -0
  196. data/src/core/lib/support/cpu_windows.c +2 -2
  197. data/src/core/lib/support/{env_win32.c → env_windows.c} +3 -3
  198. data/src/core/lib/support/log.c +3 -1
  199. data/src/core/lib/support/log_linux.c +2 -2
  200. data/src/core/lib/support/{log_win32.c → log_windows.c} +4 -4
  201. data/src/core/lib/support/murmur_hash.c +3 -5
  202. data/src/core/lib/support/string.c +10 -0
  203. data/src/core/lib/support/string.h +4 -0
  204. data/src/core/lib/support/{string_util_win32.c → string_util_windows.c} +3 -3
  205. data/src/core/lib/support/{string_win32.c → string_windows.c} +2 -2
  206. data/src/core/lib/support/{string_win32.h → string_windows.h} +5 -5
  207. data/src/core/lib/support/subprocess_windows.c +1 -1
  208. data/src/core/lib/support/{sync_win32.c → sync_windows.c} +2 -2
  209. data/src/core/lib/support/{thd_win32.c → thd_windows.c} +2 -2
  210. data/src/core/lib/support/{time_win32.c → time_windows.c} +2 -2
  211. data/src/core/lib/support/tmpfile_msys.c +1 -1
  212. data/src/core/lib/support/{tmpfile_win32.c → tmpfile_windows.c} +3 -3
  213. data/src/core/lib/surface/alarm.c +2 -2
  214. data/src/core/lib/surface/byte_buffer_reader.c +13 -6
  215. data/src/core/lib/surface/call.c +323 -123
  216. data/src/core/lib/surface/call.h +2 -0
  217. data/src/core/lib/surface/call_log_batch.c +1 -1
  218. data/src/core/lib/surface/channel.c +64 -15
  219. data/src/core/lib/surface/channel.h +9 -0
  220. data/src/core/lib/surface/channel_ping.c +3 -3
  221. data/src/core/lib/surface/completion_queue.c +75 -19
  222. data/src/core/lib/surface/completion_queue.h +7 -2
  223. data/src/core/lib/surface/init.c +2 -1
  224. data/src/core/lib/surface/init_secure.c +4 -4
  225. data/src/core/lib/surface/lame_client.c +12 -8
  226. data/src/core/lib/surface/server.c +213 -120
  227. data/src/core/lib/surface/server.h +1 -0
  228. data/src/core/lib/surface/version.c +1 -1
  229. data/src/core/lib/transport/connectivity_state.c +40 -18
  230. data/src/core/lib/transport/connectivity_state.h +4 -1
  231. data/src/core/lib/transport/metadata.c +23 -23
  232. data/src/core/lib/transport/metadata.h +4 -0
  233. data/src/core/lib/transport/metadata_batch.c +9 -0
  234. data/src/core/lib/transport/metadata_batch.h +3 -0
  235. data/src/core/lib/transport/static_metadata.c +6 -5
  236. data/src/core/lib/transport/static_metadata.h +64 -60
  237. data/src/core/lib/transport/transport.c +24 -12
  238. data/src/core/lib/transport/transport.h +6 -5
  239. data/src/core/lib/transport/transport_impl.h +4 -0
  240. data/src/core/lib/transport/transport_op_string.c +2 -2
  241. data/src/core/plugin_registry/grpc_plugin_registry.c +4 -0
  242. data/src/ruby/bin/math_services.rb +41 -2
  243. data/src/ruby/ext/grpc/rb_call.c +42 -40
  244. data/src/ruby/ext/grpc/rb_channel.c +1 -1
  245. data/src/ruby/ext/grpc/rb_completion_queue.c +59 -6
  246. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -1
  247. data/src/ruby/ext/grpc/rb_grpc.c +1 -3
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -2
  249. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +21 -5
  250. data/src/ruby/ext/grpc/rb_loader.c +1 -1
  251. data/src/ruby/ext/grpc/rb_server.c +5 -3
  252. data/src/ruby/lib/grpc.rb +0 -3
  253. data/src/ruby/lib/grpc/errors.rb +3 -2
  254. data/src/ruby/lib/grpc/generic/active_call.rb +32 -42
  255. data/src/ruby/lib/grpc/generic/bidi_call.rb +20 -0
  256. data/src/ruby/lib/grpc/generic/client_stub.rb +31 -54
  257. data/src/ruby/lib/grpc/generic/rpc_desc.rb +4 -4
  258. data/src/ruby/lib/grpc/generic/rpc_server.rb +12 -23
  259. data/src/ruby/lib/grpc/generic/service.rb +8 -8
  260. data/src/ruby/lib/grpc/version.rb +1 -1
  261. data/src/ruby/pb/grpc/health/v1/health_services.rb +30 -2
  262. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb +34 -4
  263. data/src/ruby/pb/grpc/testing/metrics_services.rb +39 -2
  264. data/src/ruby/pb/src/proto/grpc/testing/empty.rb +15 -0
  265. data/src/ruby/pb/src/proto/grpc/testing/messages.rb +84 -0
  266. data/src/ruby/pb/src/proto/grpc/testing/test.rb +14 -0
  267. data/src/ruby/pb/src/proto/grpc/testing/test_services.rb +110 -0
  268. data/src/ruby/pb/test/client.rb +5 -2
  269. data/src/ruby/spec/generic/active_call_spec.rb +3 -2
  270. data/src/ruby/spec/generic/client_stub_spec.rb +27 -24
  271. data/src/ruby/spec/generic/rpc_desc_spec.rb +11 -11
  272. data/src/ruby/spec/generic/rpc_server_spec.rb +42 -61
  273. data/src/ruby/spec/pb/health/checker_spec.rb +3 -5
  274. metadata +86 -48
  275. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h +0 -182
  276. data/src/core/lib/security/credentials.c +0 -1296
  277. data/src/ruby/lib/grpc/signals.rb +0 -69
@@ -47,9 +47,9 @@ typedef struct {
47
47
  gpr_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code,
48
48
  grpc_transport_one_way_stats *stats);
49
49
 
50
- grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_begin_frame(
50
+ grpc_error *grpc_chttp2_rst_stream_parser_begin_frame(
51
51
  grpc_chttp2_rst_stream_parser *parser, uint32_t length, uint8_t flags);
52
- grpc_chttp2_parse_error grpc_chttp2_rst_stream_parser_parse(
52
+ grpc_error *grpc_chttp2_rst_stream_parser_parse(
53
53
  grpc_exec_ctx *exec_ctx, void *parser,
54
54
  grpc_chttp2_transport_parsing *transport_parsing,
55
55
  grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
@@ -36,7 +36,9 @@
36
36
 
37
37
  #include <string.h>
38
38
 
39
+ #include <grpc/support/alloc.h>
39
40
  #include <grpc/support/log.h>
41
+ #include <grpc/support/string_util.h>
40
42
  #include <grpc/support/useful.h>
41
43
 
42
44
  #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
@@ -118,7 +120,7 @@ gpr_slice grpc_chttp2_settings_ack_create(void) {
118
120
  return output;
119
121
  }
120
122
 
121
- grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
123
+ grpc_error *grpc_chttp2_settings_parser_begin_frame(
122
124
  grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags,
123
125
  uint32_t *settings) {
124
126
  parser->target_settings = settings;
@@ -129,31 +131,29 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
129
131
  if (flags == GRPC_CHTTP2_FLAG_ACK) {
130
132
  parser->is_ack = 1;
131
133
  if (length != 0) {
132
- gpr_log(GPR_ERROR, "non-empty settings ack frame received");
133
- return GRPC_CHTTP2_CONNECTION_ERROR;
134
+ return GRPC_ERROR_CREATE("non-empty settings ack frame received");
134
135
  }
135
- return GRPC_CHTTP2_PARSE_OK;
136
+ return GRPC_ERROR_NONE;
136
137
  } else if (flags != 0) {
137
- gpr_log(GPR_ERROR, "invalid flags on settings frame");
138
- return GRPC_CHTTP2_CONNECTION_ERROR;
138
+ return GRPC_ERROR_CREATE("invalid flags on settings frame");
139
139
  } else if (length % 6 != 0) {
140
- gpr_log(GPR_ERROR, "settings frames must be a multiple of six bytes");
141
- return GRPC_CHTTP2_CONNECTION_ERROR;
140
+ return GRPC_ERROR_CREATE("settings frames must be a multiple of six bytes");
142
141
  } else {
143
- return GRPC_CHTTP2_PARSE_OK;
142
+ return GRPC_ERROR_NONE;
144
143
  }
145
144
  }
146
145
 
147
- grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
146
+ grpc_error *grpc_chttp2_settings_parser_parse(
148
147
  grpc_exec_ctx *exec_ctx, void *p,
149
148
  grpc_chttp2_transport_parsing *transport_parsing,
150
149
  grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) {
151
150
  grpc_chttp2_settings_parser *parser = p;
152
151
  const uint8_t *cur = GPR_SLICE_START_PTR(slice);
153
152
  const uint8_t *end = GPR_SLICE_END_PTR(slice);
153
+ char *msg;
154
154
 
155
155
  if (parser->is_ack) {
156
- return GRPC_CHTTP2_PARSE_OK;
156
+ return GRPC_ERROR_NONE;
157
157
  }
158
158
 
159
159
  for (;;) {
@@ -168,7 +168,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
168
168
  gpr_slice_buffer_add(&transport_parsing->qbuf,
169
169
  grpc_chttp2_settings_ack_create());
170
170
  }
171
- return GRPC_CHTTP2_PARSE_OK;
171
+ return GRPC_ERROR_NONE;
172
172
  }
173
173
  parser->id = (uint16_t)(((uint16_t)*cur) << 8);
174
174
  cur++;
@@ -176,7 +176,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
176
176
  case GRPC_CHTTP2_SPS_ID1:
177
177
  if (cur == end) {
178
178
  parser->state = GRPC_CHTTP2_SPS_ID1;
179
- return GRPC_CHTTP2_PARSE_OK;
179
+ return GRPC_ERROR_NONE;
180
180
  }
181
181
  parser->id = (uint16_t)(parser->id | (*cur));
182
182
  cur++;
@@ -184,7 +184,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
184
184
  case GRPC_CHTTP2_SPS_VAL0:
185
185
  if (cur == end) {
186
186
  parser->state = GRPC_CHTTP2_SPS_VAL0;
187
- return GRPC_CHTTP2_PARSE_OK;
187
+ return GRPC_ERROR_NONE;
188
188
  }
189
189
  parser->value = ((uint32_t)*cur) << 24;
190
190
  cur++;
@@ -192,7 +192,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
192
192
  case GRPC_CHTTP2_SPS_VAL1:
193
193
  if (cur == end) {
194
194
  parser->state = GRPC_CHTTP2_SPS_VAL1;
195
- return GRPC_CHTTP2_PARSE_OK;
195
+ return GRPC_ERROR_NONE;
196
196
  }
197
197
  parser->value |= ((uint32_t)*cur) << 16;
198
198
  cur++;
@@ -200,7 +200,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
200
200
  case GRPC_CHTTP2_SPS_VAL2:
201
201
  if (cur == end) {
202
202
  parser->state = GRPC_CHTTP2_SPS_VAL2;
203
- return GRPC_CHTTP2_PARSE_OK;
203
+ return GRPC_ERROR_NONE;
204
204
  }
205
205
  parser->value |= ((uint32_t)*cur) << 8;
206
206
  cur++;
@@ -208,7 +208,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
208
208
  case GRPC_CHTTP2_SPS_VAL3:
209
209
  if (cur == end) {
210
210
  parser->state = GRPC_CHTTP2_SPS_VAL3;
211
- return GRPC_CHTTP2_PARSE_OK;
211
+ return GRPC_ERROR_NONE;
212
212
  } else {
213
213
  parser->state = GRPC_CHTTP2_SPS_ID0;
214
214
  }
@@ -229,9 +229,11 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
229
229
  transport_parsing->last_incoming_stream_id, sp->error_value,
230
230
  gpr_slice_from_static_string("HTTP2 settings error"),
231
231
  &transport_parsing->qbuf);
232
- gpr_log(GPR_ERROR, "invalid value %u passed for %s",
233
- parser->value, sp->name);
234
- return GRPC_CHTTP2_CONNECTION_ERROR;
232
+ gpr_asprintf(&msg, "invalid value %u passed for %s",
233
+ parser->value, sp->name);
234
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
235
+ gpr_free(msg);
236
+ return err;
235
237
  }
236
238
  }
237
239
  if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
@@ -249,7 +251,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
249
251
  transport_parsing->is_client ? "CLI" : "SVR", parser->id,
250
252
  parser->value);
251
253
  }
252
- } else {
254
+ } else if (grpc_http_trace) {
253
255
  gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)",
254
256
  parser->id, parser->value);
255
257
  }
@@ -92,10 +92,10 @@ gpr_slice grpc_chttp2_settings_create(uint32_t *old, const uint32_t *new,
92
92
  /* Create an ack settings frame */
93
93
  gpr_slice grpc_chttp2_settings_ack_create(void);
94
94
 
95
- grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
95
+ grpc_error *grpc_chttp2_settings_parser_begin_frame(
96
96
  grpc_chttp2_settings_parser *parser, uint32_t length, uint8_t flags,
97
97
  uint32_t *settings);
98
- grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
98
+ grpc_error *grpc_chttp2_settings_parser_parse(
99
99
  grpc_exec_ctx *exec_ctx, void *parser,
100
100
  grpc_chttp2_transport_parsing *transport_parsing,
101
101
  grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
@@ -34,7 +34,9 @@
34
34
  #include "src/core/ext/transport/chttp2/transport/frame_window_update.h"
35
35
  #include "src/core/ext/transport/chttp2/transport/internal.h"
36
36
 
37
+ #include <grpc/support/alloc.h>
37
38
  #include <grpc/support/log.h>
39
+ #include <grpc/support/string_util.h>
38
40
 
39
41
  gpr_slice grpc_chttp2_window_update_create(
40
42
  uint32_t id, uint32_t window_update, grpc_transport_one_way_stats *stats) {
@@ -62,19 +64,22 @@ gpr_slice grpc_chttp2_window_update_create(
62
64
  return slice;
63
65
  }
64
66
 
65
- grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame(
67
+ grpc_error *grpc_chttp2_window_update_parser_begin_frame(
66
68
  grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags) {
67
69
  if (flags || length != 4) {
68
- gpr_log(GPR_ERROR, "invalid window update: length=%d, flags=%02x", length,
69
- flags);
70
- return GRPC_CHTTP2_CONNECTION_ERROR;
70
+ char *msg;
71
+ gpr_asprintf(&msg, "invalid window update: length=%d, flags=%02x", length,
72
+ flags);
73
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
74
+ gpr_free(msg);
75
+ return err;
71
76
  }
72
77
  parser->byte = 0;
73
78
  parser->amount = 0;
74
- return GRPC_CHTTP2_PARSE_OK;
79
+ return GRPC_ERROR_NONE;
75
80
  }
76
81
 
77
- grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
82
+ grpc_error *grpc_chttp2_window_update_parser_parse(
78
83
  grpc_exec_ctx *exec_ctx, void *parser,
79
84
  grpc_chttp2_transport_parsing *transport_parsing,
80
85
  grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) {
@@ -96,8 +101,11 @@ grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
96
101
  if (p->byte == 4) {
97
102
  uint32_t received_update = p->amount;
98
103
  if (received_update == 0 || (received_update & 0x80000000u)) {
99
- gpr_log(GPR_ERROR, "invalid window update bytes: %d", p->amount);
100
- return GRPC_CHTTP2_CONNECTION_ERROR;
104
+ char *msg;
105
+ gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount);
106
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
107
+ gpr_free(msg);
108
+ return err;
101
109
  }
102
110
  GPR_ASSERT(is_last);
103
111
 
@@ -115,5 +123,5 @@ grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
115
123
  }
116
124
  }
117
125
 
118
- return GRPC_CHTTP2_PARSE_OK;
126
+ return GRPC_ERROR_NONE;
119
127
  }
@@ -48,9 +48,9 @@ typedef struct {
48
48
  gpr_slice grpc_chttp2_window_update_create(uint32_t id, uint32_t window_delta,
49
49
  grpc_transport_one_way_stats *stats);
50
50
 
51
- grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame(
51
+ grpc_error *grpc_chttp2_window_update_parser_begin_frame(
52
52
  grpc_chttp2_window_update_parser *parser, uint32_t length, uint8_t flags);
53
- grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
53
+ grpc_error *grpc_chttp2_window_update_parser_parse(
54
54
  grpc_exec_ctx *exec_ctx, void *parser,
55
55
  grpc_chttp2_transport_parsing *transport_parsing,
56
56
  grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
@@ -46,6 +46,7 @@
46
46
  #include <grpc/support/alloc.h>
47
47
  #include <grpc/support/log.h>
48
48
  #include <grpc/support/port_platform.h>
49
+ #include <grpc/support/string_util.h>
49
50
  #include <grpc/support/useful.h>
50
51
 
51
52
  #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
@@ -77,63 +78,70 @@ typedef enum {
77
78
  a set of indirect jumps, and so not waste stack space. */
78
79
 
79
80
  /* forward declarations for parsing states */
80
- static int parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
81
- const uint8_t *end);
82
- static int parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
83
- const uint8_t *end);
84
- static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
85
- const uint8_t *end);
86
-
87
- static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
81
+ static grpc_error *parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
88
82
  const uint8_t *end);
89
- static int parse_key_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
90
- const uint8_t *end);
91
- static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p,
92
- const uint8_t *cur,
93
- const uint8_t *end);
94
- static int parse_value_string_with_literal_key(grpc_chttp2_hpack_parser *p,
95
- const uint8_t *cur,
96
- const uint8_t *end);
97
-
98
- static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
99
- const uint8_t *end);
100
- static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
101
- const uint8_t *end);
102
- static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
103
- const uint8_t *end);
104
- static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
105
- const uint8_t *end);
106
- static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
107
- const uint8_t *end);
108
- static int parse_value5up(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
109
- const uint8_t *end);
110
-
111
- static int parse_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
112
- const uint8_t *end);
113
- static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
114
- const uint8_t *cur, const uint8_t *end);
115
- static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
116
- const uint8_t *end);
117
- static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
118
- const uint8_t *cur, const uint8_t *end);
119
- static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
120
- const uint8_t *cur, const uint8_t *end);
121
- static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
122
- const uint8_t *end);
123
- static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
124
- const uint8_t *cur, const uint8_t *end);
125
- static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
126
- const uint8_t *cur, const uint8_t *end);
127
- static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
128
- const uint8_t *end);
129
- static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
130
- const uint8_t *cur, const uint8_t *end);
131
- static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
132
- const uint8_t *cur, const uint8_t *end);
133
- static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
134
- const uint8_t *end);
135
- static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
83
+ static grpc_error *parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
84
+ const uint8_t *end, grpc_error *error);
85
+ static grpc_error *still_parse_error(grpc_chttp2_hpack_parser *p,
86
+ const uint8_t *cur, const uint8_t *end);
87
+ static grpc_error *parse_illegal_op(grpc_chttp2_hpack_parser *p,
88
+ const uint8_t *cur, const uint8_t *end);
89
+
90
+ static grpc_error *parse_string_prefix(grpc_chttp2_hpack_parser *p,
91
+ const uint8_t *cur, const uint8_t *end);
92
+ static grpc_error *parse_key_string(grpc_chttp2_hpack_parser *p,
93
+ const uint8_t *cur, const uint8_t *end);
94
+ static grpc_error *parse_value_string_with_indexed_key(
95
+ grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end);
96
+ static grpc_error *parse_value_string_with_literal_key(
97
+ grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end);
98
+
99
+ static grpc_error *parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
100
+ const uint8_t *end);
101
+ static grpc_error *parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
102
+ const uint8_t *end);
103
+ static grpc_error *parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
104
+ const uint8_t *end);
105
+ static grpc_error *parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
106
+ const uint8_t *end);
107
+ static grpc_error *parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
136
108
  const uint8_t *end);
109
+ static grpc_error *parse_value5up(grpc_chttp2_hpack_parser *p,
110
+ const uint8_t *cur, const uint8_t *end);
111
+
112
+ static grpc_error *parse_indexed_field(grpc_chttp2_hpack_parser *p,
113
+ const uint8_t *cur, const uint8_t *end);
114
+ static grpc_error *parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
115
+ const uint8_t *cur,
116
+ const uint8_t *end);
117
+ static grpc_error *parse_lithdr_incidx(grpc_chttp2_hpack_parser *p,
118
+ const uint8_t *cur, const uint8_t *end);
119
+ static grpc_error *parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
120
+ const uint8_t *cur,
121
+ const uint8_t *end);
122
+ static grpc_error *parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
123
+ const uint8_t *cur,
124
+ const uint8_t *end);
125
+ static grpc_error *parse_lithdr_notidx(grpc_chttp2_hpack_parser *p,
126
+ const uint8_t *cur, const uint8_t *end);
127
+ static grpc_error *parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
128
+ const uint8_t *cur,
129
+ const uint8_t *end);
130
+ static grpc_error *parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
131
+ const uint8_t *cur,
132
+ const uint8_t *end);
133
+ static grpc_error *parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
134
+ const uint8_t *cur, const uint8_t *end);
135
+ static grpc_error *parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
136
+ const uint8_t *cur,
137
+ const uint8_t *end);
138
+ static grpc_error *parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
139
+ const uint8_t *cur,
140
+ const uint8_t *end);
141
+ static grpc_error *parse_max_tbl_size(grpc_chttp2_hpack_parser *p,
142
+ const uint8_t *cur, const uint8_t *end);
143
+ static grpc_error *parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p,
144
+ const uint8_t *cur, const uint8_t *end);
137
145
 
138
146
  /* we translate the first byte of a hpack field into one of these decoding
139
147
  cases, then use a lookup table to jump directly to the appropriate parser.
@@ -631,19 +639,18 @@ static const uint8_t inverse_base64[256] = {
631
639
  };
632
640
 
633
641
  /* emission helpers */
634
- static int on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md,
635
- int add_to_table) {
642
+ static grpc_error *on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md,
643
+ int add_to_table) {
636
644
  if (add_to_table) {
637
- if (!grpc_chttp2_hptbl_add(&p->table, md)) {
638
- return 0;
639
- }
645
+ grpc_error *err = grpc_chttp2_hptbl_add(&p->table, md);
646
+ if (err != GRPC_ERROR_NONE) return err;
640
647
  }
641
648
  if (p->on_header == NULL) {
642
649
  GRPC_MDELEM_UNREF(md);
643
- return 0;
650
+ return GRPC_ERROR_CREATE("on_header callback not set");
644
651
  }
645
652
  p->on_header(p->on_header_user_data, md);
646
- return 1;
653
+ return GRPC_ERROR_NONE;
647
654
  }
648
655
 
649
656
  static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p,
@@ -654,70 +661,70 @@ static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p,
654
661
  }
655
662
 
656
663
  /* jump to the next state */
657
- static int parse_next(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
658
- const uint8_t *end) {
664
+ static grpc_error *parse_next(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
665
+ const uint8_t *end) {
659
666
  p->state = *p->next_state++;
660
667
  return p->state(p, cur, end);
661
668
  }
662
669
 
663
670
  /* begin parsing a header: all functionality is encoded into lookup tables
664
671
  above */
665
- static int parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
666
- const uint8_t *end) {
672
+ static grpc_error *parse_begin(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
673
+ const uint8_t *end) {
667
674
  if (cur == end) {
668
675
  p->state = parse_begin;
669
- return 1;
676
+ return GRPC_ERROR_NONE;
670
677
  }
671
678
 
672
679
  return first_byte_action[first_byte_lut[*cur]](p, cur, end);
673
680
  }
674
681
 
675
682
  /* stream dependency and prioritization data: we just skip it */
676
- static int parse_stream_weight(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
677
- const uint8_t *end) {
683
+ static grpc_error *parse_stream_weight(grpc_chttp2_hpack_parser *p,
684
+ const uint8_t *cur, const uint8_t *end) {
678
685
  if (cur == end) {
679
686
  p->state = parse_stream_weight;
680
- return 1;
687
+ return GRPC_ERROR_NONE;
681
688
  }
682
689
 
683
690
  return p->after_prioritization(p, cur + 1, end);
684
691
  }
685
692
 
686
- static int parse_stream_dep3(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
687
- const uint8_t *end) {
693
+ static grpc_error *parse_stream_dep3(grpc_chttp2_hpack_parser *p,
694
+ const uint8_t *cur, const uint8_t *end) {
688
695
  if (cur == end) {
689
696
  p->state = parse_stream_dep3;
690
- return 1;
697
+ return GRPC_ERROR_NONE;
691
698
  }
692
699
 
693
700
  return parse_stream_weight(p, cur + 1, end);
694
701
  }
695
702
 
696
- static int parse_stream_dep2(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
697
- const uint8_t *end) {
703
+ static grpc_error *parse_stream_dep2(grpc_chttp2_hpack_parser *p,
704
+ const uint8_t *cur, const uint8_t *end) {
698
705
  if (cur == end) {
699
706
  p->state = parse_stream_dep2;
700
- return 1;
707
+ return GRPC_ERROR_NONE;
701
708
  }
702
709
 
703
710
  return parse_stream_dep3(p, cur + 1, end);
704
711
  }
705
712
 
706
- static int parse_stream_dep1(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
707
- const uint8_t *end) {
713
+ static grpc_error *parse_stream_dep1(grpc_chttp2_hpack_parser *p,
714
+ const uint8_t *cur, const uint8_t *end) {
708
715
  if (cur == end) {
709
716
  p->state = parse_stream_dep1;
710
- return 1;
717
+ return GRPC_ERROR_NONE;
711
718
  }
712
719
 
713
720
  return parse_stream_dep2(p, cur + 1, end);
714
721
  }
715
722
 
716
- static int parse_stream_dep0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
717
- const uint8_t *end) {
723
+ static grpc_error *parse_stream_dep0(grpc_chttp2_hpack_parser *p,
724
+ const uint8_t *cur, const uint8_t *end) {
718
725
  if (cur == end) {
719
726
  p->state = parse_stream_dep0;
720
- return 1;
727
+ return GRPC_ERROR_NONE;
721
728
  }
722
729
 
723
730
  return parse_stream_dep1(p, cur + 1, end);
@@ -725,30 +732,34 @@ static int parse_stream_dep0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
725
732
 
726
733
  /* emit an indexed field; for now just logs it to console; jumps to
727
734
  begin the next field on completion */
728
- static int finish_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
729
- const uint8_t *end) {
735
+ static grpc_error *finish_indexed_field(grpc_chttp2_hpack_parser *p,
736
+ const uint8_t *cur,
737
+ const uint8_t *end) {
730
738
  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
731
739
  if (md == NULL) {
732
- if (grpc_http_trace) {
733
- gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index);
734
- }
735
- return 0;
740
+ return grpc_error_set_int(
741
+ grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
742
+ GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
743
+ GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
736
744
  }
737
745
  GRPC_MDELEM_REF(md);
738
- return on_hdr(p, md, 0) && parse_begin(p, cur, end);
746
+ grpc_error *err = on_hdr(p, md, 0);
747
+ if (err != GRPC_ERROR_NONE) return err;
748
+ return parse_begin(p, cur, end);
739
749
  }
740
750
 
741
751
  /* parse an indexed field with index < 127 */
742
- static int parse_indexed_field(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
743
- const uint8_t *end) {
752
+ static grpc_error *parse_indexed_field(grpc_chttp2_hpack_parser *p,
753
+ const uint8_t *cur, const uint8_t *end) {
744
754
  p->dynamic_table_update_allowed = 0;
745
755
  p->index = (*cur) & 0x7f;
746
756
  return finish_indexed_field(p, cur + 1, end);
747
757
  }
748
758
 
749
759
  /* parse an indexed field with index >= 127 */
750
- static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
751
- const uint8_t *cur, const uint8_t *end) {
760
+ static grpc_error *parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
761
+ const uint8_t *cur,
762
+ const uint8_t *end) {
752
763
  static const grpc_chttp2_hpack_parser_state and_then[] = {
753
764
  finish_indexed_field};
754
765
  p->dynamic_table_update_allowed = 0;
@@ -760,28 +771,34 @@ static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
760
771
 
761
772
  /* finish a literal header with incremental indexing: just log, and jump to '
762
773
  begin */
763
- static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
764
- const uint8_t *end) {
774
+ static grpc_error *finish_lithdr_incidx(grpc_chttp2_hpack_parser *p,
775
+ const uint8_t *cur,
776
+ const uint8_t *end) {
765
777
  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
766
778
  GPR_ASSERT(md != NULL); /* handled in string parsing */
767
- return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
768
- take_string(p, &p->value)),
769
- 1) &&
770
- parse_begin(p, cur, end);
779
+ grpc_error *err =
780
+ on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
781
+ take_string(p, &p->value)),
782
+ 1);
783
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
784
+ return parse_begin(p, cur, end);
771
785
  }
772
786
 
773
787
  /* finish a literal header with incremental indexing with no index */
774
- static int finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
775
- const uint8_t *cur, const uint8_t *end) {
776
- return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
777
- take_string(p, &p->value)),
778
- 1) &&
779
- parse_begin(p, cur, end);
788
+ static grpc_error *finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
789
+ const uint8_t *cur,
790
+ const uint8_t *end) {
791
+ grpc_error *err =
792
+ on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
793
+ take_string(p, &p->value)),
794
+ 1);
795
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
796
+ return parse_begin(p, cur, end);
780
797
  }
781
798
 
782
799
  /* parse a literal header with incremental indexing; index < 63 */
783
- static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
784
- const uint8_t *end) {
800
+ static grpc_error *parse_lithdr_incidx(grpc_chttp2_hpack_parser *p,
801
+ const uint8_t *cur, const uint8_t *end) {
785
802
  static const grpc_chttp2_hpack_parser_state and_then[] = {
786
803
  parse_value_string_with_indexed_key, finish_lithdr_incidx};
787
804
  p->dynamic_table_update_allowed = 0;
@@ -791,8 +808,9 @@ static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
791
808
  }
792
809
 
793
810
  /* parse a literal header with incremental indexing; index >= 63 */
794
- static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
795
- const uint8_t *cur, const uint8_t *end) {
811
+ static grpc_error *parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
812
+ const uint8_t *cur,
813
+ const uint8_t *end) {
796
814
  static const grpc_chttp2_hpack_parser_state and_then[] = {
797
815
  parse_string_prefix, parse_value_string_with_indexed_key,
798
816
  finish_lithdr_incidx};
@@ -804,8 +822,9 @@ static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
804
822
  }
805
823
 
806
824
  /* parse a literal header with incremental indexing; index = 0 */
807
- static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
808
- const uint8_t *cur, const uint8_t *end) {
825
+ static grpc_error *parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
826
+ const uint8_t *cur,
827
+ const uint8_t *end) {
809
828
  static const grpc_chttp2_hpack_parser_state and_then[] = {
810
829
  parse_key_string, parse_string_prefix,
811
830
  parse_value_string_with_literal_key, finish_lithdr_incidx_v};
@@ -815,28 +834,34 @@ static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
815
834
  }
816
835
 
817
836
  /* finish a literal header without incremental indexing */
818
- static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
819
- const uint8_t *end) {
837
+ static grpc_error *finish_lithdr_notidx(grpc_chttp2_hpack_parser *p,
838
+ const uint8_t *cur,
839
+ const uint8_t *end) {
820
840
  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
821
841
  GPR_ASSERT(md != NULL); /* handled in string parsing */
822
- return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
823
- take_string(p, &p->value)),
824
- 0) &&
825
- parse_begin(p, cur, end);
842
+ grpc_error *err =
843
+ on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
844
+ take_string(p, &p->value)),
845
+ 0);
846
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
847
+ return parse_begin(p, cur, end);
826
848
  }
827
849
 
828
850
  /* finish a literal header without incremental indexing with index = 0 */
829
- static int finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
830
- const uint8_t *cur, const uint8_t *end) {
831
- return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
832
- take_string(p, &p->value)),
833
- 0) &&
834
- parse_begin(p, cur, end);
851
+ static grpc_error *finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
852
+ const uint8_t *cur,
853
+ const uint8_t *end) {
854
+ grpc_error *err =
855
+ on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
856
+ take_string(p, &p->value)),
857
+ 0);
858
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
859
+ return parse_begin(p, cur, end);
835
860
  }
836
861
 
837
862
  /* parse a literal header without incremental indexing; index < 15 */
838
- static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
839
- const uint8_t *end) {
863
+ static grpc_error *parse_lithdr_notidx(grpc_chttp2_hpack_parser *p,
864
+ const uint8_t *cur, const uint8_t *end) {
840
865
  static const grpc_chttp2_hpack_parser_state and_then[] = {
841
866
  parse_value_string_with_indexed_key, finish_lithdr_notidx};
842
867
  p->dynamic_table_update_allowed = 0;
@@ -846,8 +871,9 @@ static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
846
871
  }
847
872
 
848
873
  /* parse a literal header without incremental indexing; index >= 15 */
849
- static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
850
- const uint8_t *cur, const uint8_t *end) {
874
+ static grpc_error *parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
875
+ const uint8_t *cur,
876
+ const uint8_t *end) {
851
877
  static const grpc_chttp2_hpack_parser_state and_then[] = {
852
878
  parse_string_prefix, parse_value_string_with_indexed_key,
853
879
  finish_lithdr_notidx};
@@ -859,8 +885,9 @@ static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
859
885
  }
860
886
 
861
887
  /* parse a literal header without incremental indexing; index == 0 */
862
- static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
863
- const uint8_t *cur, const uint8_t *end) {
888
+ static grpc_error *parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
889
+ const uint8_t *cur,
890
+ const uint8_t *end) {
864
891
  static const grpc_chttp2_hpack_parser_state and_then[] = {
865
892
  parse_key_string, parse_string_prefix,
866
893
  parse_value_string_with_literal_key, finish_lithdr_notidx_v};
@@ -870,28 +897,34 @@ static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
870
897
  }
871
898
 
872
899
  /* finish a literal header that is never indexed */
873
- static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
874
- const uint8_t *end) {
900
+ static grpc_error *finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
901
+ const uint8_t *cur,
902
+ const uint8_t *end) {
875
903
  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
876
904
  GPR_ASSERT(md != NULL); /* handled in string parsing */
877
- return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
878
- take_string(p, &p->value)),
879
- 0) &&
880
- parse_begin(p, cur, end);
905
+ grpc_error *err =
906
+ on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
907
+ take_string(p, &p->value)),
908
+ 0);
909
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
910
+ return parse_begin(p, cur, end);
881
911
  }
882
912
 
883
913
  /* finish a literal header that is never indexed with an extra value */
884
- static int finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
885
- const uint8_t *cur, const uint8_t *end) {
886
- return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
887
- take_string(p, &p->value)),
888
- 0) &&
889
- parse_begin(p, cur, end);
914
+ static grpc_error *finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
915
+ const uint8_t *cur,
916
+ const uint8_t *end) {
917
+ grpc_error *err =
918
+ on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
919
+ take_string(p, &p->value)),
920
+ 0);
921
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
922
+ return parse_begin(p, cur, end);
890
923
  }
891
924
 
892
925
  /* parse a literal header that is never indexed; index < 15 */
893
- static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
894
- const uint8_t *end) {
926
+ static grpc_error *parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
927
+ const uint8_t *cur, const uint8_t *end) {
895
928
  static const grpc_chttp2_hpack_parser_state and_then[] = {
896
929
  parse_value_string_with_indexed_key, finish_lithdr_nvridx};
897
930
  p->dynamic_table_update_allowed = 0;
@@ -901,8 +934,9 @@ static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
901
934
  }
902
935
 
903
936
  /* parse a literal header that is never indexed; index >= 15 */
904
- static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
905
- const uint8_t *cur, const uint8_t *end) {
937
+ static grpc_error *parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
938
+ const uint8_t *cur,
939
+ const uint8_t *end) {
906
940
  static const grpc_chttp2_hpack_parser_state and_then[] = {
907
941
  parse_string_prefix, parse_value_string_with_indexed_key,
908
942
  finish_lithdr_nvridx};
@@ -914,8 +948,9 @@ static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
914
948
  }
915
949
 
916
950
  /* parse a literal header that is never indexed; index == 0 */
917
- static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
918
- const uint8_t *cur, const uint8_t *end) {
951
+ static grpc_error *parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
952
+ const uint8_t *cur,
953
+ const uint8_t *end) {
919
954
  static const grpc_chttp2_hpack_parser_state and_then[] = {
920
955
  parse_key_string, parse_string_prefix,
921
956
  parse_value_string_with_literal_key, finish_lithdr_nvridx_v};
@@ -925,20 +960,25 @@ static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
925
960
  }
926
961
 
927
962
  /* finish parsing a max table size change */
928
- static int finish_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
929
- const uint8_t *end) {
963
+ static grpc_error *finish_max_tbl_size(grpc_chttp2_hpack_parser *p,
964
+ const uint8_t *cur, const uint8_t *end) {
930
965
  if (grpc_http_trace) {
931
966
  gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
932
967
  }
933
- return grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index) &&
934
- parse_begin(p, cur, end);
968
+ grpc_error *err =
969
+ grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index);
970
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
971
+ return parse_begin(p, cur, end);
935
972
  }
936
973
 
937
974
  /* parse a max table size change, max size < 15 */
938
- static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
939
- const uint8_t *end) {
975
+ static grpc_error *parse_max_tbl_size(grpc_chttp2_hpack_parser *p,
976
+ const uint8_t *cur, const uint8_t *end) {
940
977
  if (p->dynamic_table_update_allowed == 0) {
941
- return 0;
978
+ return parse_error(
979
+ p, cur, end,
980
+ GRPC_ERROR_CREATE(
981
+ "More than two max table size changes in a single frame"));
942
982
  }
943
983
  p->dynamic_table_update_allowed--;
944
984
  p->index = (*cur) & 0x1f;
@@ -946,12 +986,16 @@ static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
946
986
  }
947
987
 
948
988
  /* parse a max table size change, max size >= 15 */
949
- static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
950
- const uint8_t *end) {
989
+ static grpc_error *parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p,
990
+ const uint8_t *cur,
991
+ const uint8_t *end) {
951
992
  static const grpc_chttp2_hpack_parser_state and_then[] = {
952
993
  finish_max_tbl_size};
953
994
  if (p->dynamic_table_update_allowed == 0) {
954
- return 0;
995
+ return parse_error(
996
+ p, cur, end,
997
+ GRPC_ERROR_CREATE(
998
+ "More than two max table size changes in a single frame"));
955
999
  }
956
1000
  p->dynamic_table_update_allowed--;
957
1001
  p->next_state = and_then;
@@ -961,28 +1005,38 @@ static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
961
1005
  }
962
1006
 
963
1007
  /* a parse error: jam the parse state into parse_error, and return error */
964
- static int parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
965
- const uint8_t *end) {
966
- p->state = parse_error;
967
- return 0;
1008
+ static grpc_error *parse_error(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1009
+ const uint8_t *end, grpc_error *err) {
1010
+ GPR_ASSERT(err != GRPC_ERROR_NONE);
1011
+ if (p->last_error == GRPC_ERROR_NONE) {
1012
+ p->last_error = GRPC_ERROR_REF(err);
1013
+ }
1014
+ p->state = still_parse_error;
1015
+ return err;
1016
+ }
1017
+
1018
+ static grpc_error *still_parse_error(grpc_chttp2_hpack_parser *p,
1019
+ const uint8_t *cur, const uint8_t *end) {
1020
+ return GRPC_ERROR_REF(p->last_error);
968
1021
  }
969
1022
 
970
- static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
971
- const uint8_t *end) {
1023
+ static grpc_error *parse_illegal_op(grpc_chttp2_hpack_parser *p,
1024
+ const uint8_t *cur, const uint8_t *end) {
972
1025
  GPR_ASSERT(cur != end);
973
- if (grpc_http_trace) {
974
- gpr_log(GPR_DEBUG, "Illegal hpack op code %d", *cur);
975
- }
976
- return parse_error(p, cur, end);
1026
+ char *msg;
1027
+ gpr_asprintf(&msg, "Illegal hpack op code %d", *cur);
1028
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
1029
+ gpr_free(msg);
1030
+ return parse_error(p, cur, end, err);
977
1031
  }
978
1032
 
979
1033
  /* parse the 1st byte of a varint into p->parsing.value
980
1034
  no overflow is possible */
981
- static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
982
- const uint8_t *end) {
1035
+ static grpc_error *parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1036
+ const uint8_t *end) {
983
1037
  if (cur == end) {
984
1038
  p->state = parse_value0;
985
- return 1;
1039
+ return GRPC_ERROR_NONE;
986
1040
  }
987
1041
 
988
1042
  *p->parsing.value += (*cur) & 0x7f;
@@ -996,11 +1050,11 @@ static int parse_value0(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
996
1050
 
997
1051
  /* parse the 2nd byte of a varint into p->parsing.value
998
1052
  no overflow is possible */
999
- static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1000
- const uint8_t *end) {
1053
+ static grpc_error *parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1054
+ const uint8_t *end) {
1001
1055
  if (cur == end) {
1002
1056
  p->state = parse_value1;
1003
- return 1;
1057
+ return GRPC_ERROR_NONE;
1004
1058
  }
1005
1059
 
1006
1060
  *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 7;
@@ -1014,11 +1068,11 @@ static int parse_value1(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1014
1068
 
1015
1069
  /* parse the 3rd byte of a varint into p->parsing.value
1016
1070
  no overflow is possible */
1017
- static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1018
- const uint8_t *end) {
1071
+ static grpc_error *parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1072
+ const uint8_t *end) {
1019
1073
  if (cur == end) {
1020
1074
  p->state = parse_value2;
1021
- return 1;
1075
+ return GRPC_ERROR_NONE;
1022
1076
  }
1023
1077
 
1024
1078
  *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 14;
@@ -1032,11 +1086,11 @@ static int parse_value2(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1032
1086
 
1033
1087
  /* parse the 4th byte of a varint into p->parsing.value
1034
1088
  no overflow is possible */
1035
- static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1036
- const uint8_t *end) {
1089
+ static grpc_error *parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1090
+ const uint8_t *end) {
1037
1091
  if (cur == end) {
1038
1092
  p->state = parse_value3;
1039
- return 1;
1093
+ return GRPC_ERROR_NONE;
1040
1094
  }
1041
1095
 
1042
1096
  *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 21;
@@ -1050,15 +1104,16 @@ static int parse_value3(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1050
1104
 
1051
1105
  /* parse the 5th byte of a varint into p->parsing.value
1052
1106
  depending on the byte, we may overflow, and care must be taken */
1053
- static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1054
- const uint8_t *end) {
1107
+ static grpc_error *parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1108
+ const uint8_t *end) {
1055
1109
  uint8_t c;
1056
1110
  uint32_t cur_value;
1057
1111
  uint32_t add_value;
1112
+ char *msg;
1058
1113
 
1059
1114
  if (cur == end) {
1060
1115
  p->state = parse_value4;
1061
- return 1;
1116
+ return GRPC_ERROR_NONE;
1062
1117
  }
1063
1118
 
1064
1119
  c = (*cur) & 0x7f;
@@ -1081,48 +1136,49 @@ static int parse_value4(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1081
1136
  }
1082
1137
 
1083
1138
  error:
1084
- if (grpc_http_trace) {
1085
- gpr_log(GPR_ERROR,
1086
- "integer overflow in hpack integer decoding: have 0x%08x, "
1087
- "got byte 0x%02x on byte 5",
1088
- *p->parsing.value, *cur);
1089
- }
1090
- return parse_error(p, cur, end);
1139
+ gpr_asprintf(&msg,
1140
+ "integer overflow in hpack integer decoding: have 0x%08x, "
1141
+ "got byte 0x%02x on byte 5",
1142
+ *p->parsing.value, *cur);
1143
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
1144
+ gpr_free(msg);
1145
+ return parse_error(p, cur, end, err);
1091
1146
  }
1092
1147
 
1093
1148
  /* parse any trailing bytes in a varint: it's possible to append an arbitrary
1094
1149
  number of 0x80's and not affect the value - a zero will terminate - and
1095
1150
  anything else will overflow */
1096
- static int parse_value5up(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1097
- const uint8_t *end) {
1151
+ static grpc_error *parse_value5up(grpc_chttp2_hpack_parser *p,
1152
+ const uint8_t *cur, const uint8_t *end) {
1098
1153
  while (cur != end && *cur == 0x80) {
1099
1154
  ++cur;
1100
1155
  }
1101
1156
 
1102
1157
  if (cur == end) {
1103
1158
  p->state = parse_value5up;
1104
- return 1;
1159
+ return GRPC_ERROR_NONE;
1105
1160
  }
1106
1161
 
1107
1162
  if (*cur == 0) {
1108
1163
  return parse_next(p, cur + 1, end);
1109
1164
  }
1110
1165
 
1111
- if (grpc_http_trace) {
1112
- gpr_log(GPR_ERROR,
1113
- "integer overflow in hpack integer decoding: have 0x%08x, "
1114
- "got byte 0x%02x sometime after byte 5",
1115
- *p->parsing.value, *cur);
1116
- }
1117
- return parse_error(p, cur, end);
1166
+ char *msg;
1167
+ gpr_asprintf(&msg,
1168
+ "integer overflow in hpack integer decoding: have 0x%08x, "
1169
+ "got byte 0x%02x sometime after byte 5",
1170
+ *p->parsing.value, *cur);
1171
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
1172
+ gpr_free(msg);
1173
+ return parse_error(p, cur, end, err);
1118
1174
  }
1119
1175
 
1120
1176
  /* parse a string prefix */
1121
- static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1122
- const uint8_t *end) {
1177
+ static grpc_error *parse_string_prefix(grpc_chttp2_hpack_parser *p,
1178
+ const uint8_t *cur, const uint8_t *end) {
1123
1179
  if (cur == end) {
1124
1180
  p->state = parse_string_prefix;
1125
- return 1;
1181
+ return GRPC_ERROR_NONE;
1126
1182
  }
1127
1183
 
1128
1184
  p->strlen = (*cur) & 0x7f;
@@ -1138,6 +1194,7 @@ static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1138
1194
  /* append some bytes to a string */
1139
1195
  static void append_bytes(grpc_chttp2_hpack_parser_string *str,
1140
1196
  const uint8_t *data, size_t length) {
1197
+ if (length == 0) return;
1141
1198
  if (length + str->length > str->capacity) {
1142
1199
  GPR_ASSERT(str->length + length <= UINT32_MAX);
1143
1200
  str->capacity = (uint32_t)(str->length + length);
@@ -1148,25 +1205,26 @@ static void append_bytes(grpc_chttp2_hpack_parser_string *str,
1148
1205
  str->length += (uint32_t)length;
1149
1206
  }
1150
1207
 
1151
- static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1152
- const uint8_t *end) {
1208
+ static grpc_error *append_string(grpc_chttp2_hpack_parser *p,
1209
+ const uint8_t *cur, const uint8_t *end) {
1153
1210
  grpc_chttp2_hpack_parser_string *str = p->parsing.str;
1154
1211
  uint32_t bits;
1155
1212
  uint8_t decoded[3];
1156
1213
  switch ((binary_state)p->binary) {
1157
1214
  case NOT_BINARY:
1158
1215
  append_bytes(str, cur, (size_t)(end - cur));
1159
- return 1;
1216
+ return GRPC_ERROR_NONE;
1160
1217
  b64_byte0:
1161
1218
  case B64_BYTE0:
1162
1219
  if (cur == end) {
1163
1220
  p->binary = B64_BYTE0;
1164
- return 1;
1221
+ return GRPC_ERROR_NONE;
1165
1222
  }
1166
1223
  bits = inverse_base64[*cur];
1167
1224
  ++cur;
1168
1225
  if (bits == 255)
1169
- return 0;
1226
+ return parse_error(p, cur, end,
1227
+ GRPC_ERROR_CREATE("Illegal base64 character"));
1170
1228
  else if (bits == 64)
1171
1229
  goto b64_byte0;
1172
1230
  p->base64_buffer = bits << 18;
@@ -1175,12 +1233,13 @@ static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1175
1233
  case B64_BYTE1:
1176
1234
  if (cur == end) {
1177
1235
  p->binary = B64_BYTE1;
1178
- return 1;
1236
+ return GRPC_ERROR_NONE;
1179
1237
  }
1180
1238
  bits = inverse_base64[*cur];
1181
1239
  ++cur;
1182
1240
  if (bits == 255)
1183
- return 0;
1241
+ return parse_error(p, cur, end,
1242
+ GRPC_ERROR_CREATE("Illegal base64 character"));
1184
1243
  else if (bits == 64)
1185
1244
  goto b64_byte1;
1186
1245
  p->base64_buffer |= bits << 12;
@@ -1189,12 +1248,13 @@ static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1189
1248
  case B64_BYTE2:
1190
1249
  if (cur == end) {
1191
1250
  p->binary = B64_BYTE2;
1192
- return 1;
1251
+ return GRPC_ERROR_NONE;
1193
1252
  }
1194
1253
  bits = inverse_base64[*cur];
1195
1254
  ++cur;
1196
1255
  if (bits == 255)
1197
- return 0;
1256
+ return parse_error(p, cur, end,
1257
+ GRPC_ERROR_CREATE("Illegal base64 character"));
1198
1258
  else if (bits == 64)
1199
1259
  goto b64_byte2;
1200
1260
  p->base64_buffer |= bits << 6;
@@ -1203,12 +1263,13 @@ static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1203
1263
  case B64_BYTE3:
1204
1264
  if (cur == end) {
1205
1265
  p->binary = B64_BYTE3;
1206
- return 1;
1266
+ return GRPC_ERROR_NONE;
1207
1267
  }
1208
1268
  bits = inverse_base64[*cur];
1209
1269
  ++cur;
1210
1270
  if (bits == 255)
1211
- return 0;
1271
+ return parse_error(p, cur, end,
1272
+ GRPC_ERROR_CREATE("Illegal base64 character"));
1212
1273
  else if (bits == 64)
1213
1274
  goto b64_byte3;
1214
1275
  p->base64_buffer |= bits;
@@ -1219,11 +1280,13 @@ static int append_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1219
1280
  append_bytes(str, decoded, 3);
1220
1281
  goto b64_byte0;
1221
1282
  }
1222
- GPR_UNREACHABLE_CODE(return 1);
1283
+ GPR_UNREACHABLE_CODE(return parse_error(
1284
+ p, cur, end, GRPC_ERROR_CREATE("Should never reach here")));
1223
1285
  }
1224
1286
 
1225
1287
  /* append a null terminator to a string */
1226
- static int finish_str(grpc_chttp2_hpack_parser *p) {
1288
+ static grpc_error *finish_str(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1289
+ const uint8_t *end) {
1227
1290
  uint8_t terminator = 0;
1228
1291
  uint8_t decoded[2];
1229
1292
  uint32_t bits;
@@ -1234,14 +1297,18 @@ static int finish_str(grpc_chttp2_hpack_parser *p) {
1234
1297
  case B64_BYTE0:
1235
1298
  break;
1236
1299
  case B64_BYTE1:
1237
- gpr_log(GPR_ERROR, "illegal base64 encoding");
1238
- return 0; /* illegal encoding */
1300
+ return parse_error(
1301
+ p, cur, end,
1302
+ GRPC_ERROR_CREATE("illegal base64 encoding")); /* illegal encoding */
1239
1303
  case B64_BYTE2:
1240
1304
  bits = p->base64_buffer;
1241
1305
  if (bits & 0xffff) {
1242
- gpr_log(GPR_ERROR, "trailing bits in base64 encoding: 0x%04x",
1243
- bits & 0xffff);
1244
- return 0;
1306
+ char *msg;
1307
+ gpr_asprintf(&msg, "trailing bits in base64 encoding: 0x%04x",
1308
+ bits & 0xffff);
1309
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
1310
+ gpr_free(msg);
1311
+ return parse_error(p, cur, end, err);
1245
1312
  }
1246
1313
  decoded[0] = (uint8_t)(bits >> 16);
1247
1314
  append_bytes(str, decoded, 1);
@@ -1249,9 +1316,12 @@ static int finish_str(grpc_chttp2_hpack_parser *p) {
1249
1316
  case B64_BYTE3:
1250
1317
  bits = p->base64_buffer;
1251
1318
  if (bits & 0xff) {
1252
- gpr_log(GPR_ERROR, "trailing bits in base64 encoding: 0x%02x",
1253
- bits & 0xff);
1254
- return 0;
1319
+ char *msg;
1320
+ gpr_asprintf(&msg, "trailing bits in base64 encoding: 0x%02x",
1321
+ bits & 0xff);
1322
+ grpc_error *err = GRPC_ERROR_CREATE(msg);
1323
+ gpr_free(msg);
1324
+ return parse_error(p, cur, end, err);
1255
1325
  }
1256
1326
  decoded[0] = (uint8_t)(bits >> 16);
1257
1327
  decoded[1] = (uint8_t)(bits >> 8);
@@ -1260,38 +1330,42 @@ static int finish_str(grpc_chttp2_hpack_parser *p) {
1260
1330
  }
1261
1331
  append_bytes(str, &terminator, 1);
1262
1332
  p->parsing.str->length--; /* don't actually count the null terminator */
1263
- return 1;
1333
+ return GRPC_ERROR_NONE;
1264
1334
  }
1265
1335
 
1266
1336
  /* decode a nibble from a huffman encoded stream */
1267
- static int huff_nibble(grpc_chttp2_hpack_parser *p, uint8_t nibble) {
1337
+ static grpc_error *huff_nibble(grpc_chttp2_hpack_parser *p, uint8_t nibble) {
1268
1338
  int16_t emit = emit_sub_tbl[16 * emit_tbl[p->huff_state] + nibble];
1269
1339
  int16_t next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble];
1270
1340
  if (emit != -1) {
1271
1341
  if (emit >= 0 && emit < 256) {
1272
1342
  uint8_t c = (uint8_t)emit;
1273
- if (!append_string(p, &c, (&c) + 1)) return 0;
1343
+ grpc_error *err = append_string(p, &c, (&c) + 1);
1344
+ if (err != GRPC_ERROR_NONE) return err;
1274
1345
  } else {
1275
1346
  assert(emit == 256);
1276
1347
  }
1277
1348
  }
1278
1349
  p->huff_state = next;
1279
- return 1;
1350
+ return GRPC_ERROR_NONE;
1280
1351
  }
1281
1352
 
1282
1353
  /* decode full bytes from a huffman encoded stream */
1283
- static int add_huff_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1284
- const uint8_t *end) {
1354
+ static grpc_error *add_huff_bytes(grpc_chttp2_hpack_parser *p,
1355
+ const uint8_t *cur, const uint8_t *end) {
1285
1356
  for (; cur != end; ++cur) {
1286
- if (!huff_nibble(p, *cur >> 4) || !huff_nibble(p, *cur & 0xf)) return 0;
1357
+ grpc_error *err = huff_nibble(p, *cur >> 4);
1358
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
1359
+ err = huff_nibble(p, *cur & 0xf);
1360
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
1287
1361
  }
1288
- return 1;
1362
+ return GRPC_ERROR_NONE;
1289
1363
  }
1290
1364
 
1291
1365
  /* decode some string bytes based on the current decoding mode
1292
1366
  (huffman or not) */
1293
- static int add_str_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1294
- const uint8_t *end) {
1367
+ static grpc_error *add_str_bytes(grpc_chttp2_hpack_parser *p,
1368
+ const uint8_t *cur, const uint8_t *end) {
1295
1369
  if (p->huff) {
1296
1370
  return add_huff_bytes(p, cur, end);
1297
1371
  } else {
@@ -1300,26 +1374,31 @@ static int add_str_bytes(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1300
1374
  }
1301
1375
 
1302
1376
  /* parse a string - tries to do large chunks at a time */
1303
- static int parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1304
- const uint8_t *end) {
1377
+ static grpc_error *parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1378
+ const uint8_t *end) {
1305
1379
  size_t remaining = p->strlen - p->strgot;
1306
1380
  size_t given = (size_t)(end - cur);
1307
1381
  if (remaining <= given) {
1308
- return add_str_bytes(p, cur, cur + remaining) && finish_str(p) &&
1309
- parse_next(p, cur + remaining, end);
1382
+ grpc_error *err = add_str_bytes(p, cur, cur + remaining);
1383
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
1384
+ err = finish_str(p, cur + remaining, end);
1385
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
1386
+ return parse_next(p, cur + remaining, end);
1310
1387
  } else {
1311
- if (!add_str_bytes(p, cur, cur + given)) return 0;
1388
+ grpc_error *err = add_str_bytes(p, cur, cur + given);
1389
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
1312
1390
  GPR_ASSERT(given <= UINT32_MAX - p->strgot);
1313
1391
  p->strgot += (uint32_t)given;
1314
1392
  p->state = parse_string;
1315
- return 1;
1393
+ return GRPC_ERROR_NONE;
1316
1394
  }
1317
1395
  }
1318
1396
 
1319
1397
  /* begin parsing a string - performs setup, calls parse_string */
1320
- static int begin_parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1321
- const uint8_t *end, uint8_t binary,
1322
- grpc_chttp2_hpack_parser_string *str) {
1398
+ static grpc_error *begin_parse_string(grpc_chttp2_hpack_parser *p,
1399
+ const uint8_t *cur, const uint8_t *end,
1400
+ uint8_t binary,
1401
+ grpc_chttp2_hpack_parser_string *str) {
1323
1402
  p->strgot = 0;
1324
1403
  str->length = 0;
1325
1404
  p->parsing.str = str;
@@ -1329,58 +1408,50 @@ static int begin_parse_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1329
1408
  }
1330
1409
 
1331
1410
  /* parse the key string */
1332
- static int parse_key_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1333
- const uint8_t *end) {
1411
+ static grpc_error *parse_key_string(grpc_chttp2_hpack_parser *p,
1412
+ const uint8_t *cur, const uint8_t *end) {
1334
1413
  return begin_parse_string(p, cur, end, NOT_BINARY, &p->key);
1335
1414
  }
1336
1415
 
1337
1416
  /* check if a key represents a binary header or not */
1338
- typedef enum { BINARY_HEADER, PLAINTEXT_HEADER, ERROR_HEADER } is_binary_header;
1339
1417
 
1340
- static is_binary_header is_binary_literal_header(grpc_chttp2_hpack_parser *p) {
1341
- return grpc_is_binary_header(p->key.str, p->key.length) ? BINARY_HEADER
1342
- : PLAINTEXT_HEADER;
1418
+ static bool is_binary_literal_header(grpc_chttp2_hpack_parser *p) {
1419
+ return grpc_is_binary_header(p->key.str, p->key.length);
1343
1420
  }
1344
1421
 
1345
- static is_binary_header is_binary_indexed_header(grpc_chttp2_hpack_parser *p) {
1422
+ static grpc_error *is_binary_indexed_header(grpc_chttp2_hpack_parser *p,
1423
+ bool *is) {
1346
1424
  grpc_mdelem *elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
1347
1425
  if (!elem) {
1348
- if (grpc_http_trace) {
1349
- gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index);
1350
- }
1351
- return ERROR_HEADER;
1426
+ return grpc_error_set_int(
1427
+ grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
1428
+ GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
1429
+ GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
1352
1430
  }
1353
- return grpc_is_binary_header(
1354
- (const char *)GPR_SLICE_START_PTR(elem->key->slice),
1355
- GPR_SLICE_LENGTH(elem->key->slice))
1356
- ? BINARY_HEADER
1357
- : PLAINTEXT_HEADER;
1431
+ *is =
1432
+ grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(elem->key->slice),
1433
+ GPR_SLICE_LENGTH(elem->key->slice));
1434
+ return GRPC_ERROR_NONE;
1358
1435
  }
1359
1436
 
1360
1437
  /* parse the value string */
1361
- static int parse_value_string(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
1362
- const uint8_t *end, is_binary_header type) {
1363
- switch (type) {
1364
- case BINARY_HEADER:
1365
- return begin_parse_string(p, cur, end, B64_BYTE0, &p->value);
1366
- case PLAINTEXT_HEADER:
1367
- return begin_parse_string(p, cur, end, NOT_BINARY, &p->value);
1368
- case ERROR_HEADER:
1369
- return 0;
1370
- }
1371
- /* Add code to prevent return without value error */
1372
- GPR_UNREACHABLE_CODE(return 0);
1438
+ static grpc_error *parse_value_string(grpc_chttp2_hpack_parser *p,
1439
+ const uint8_t *cur, const uint8_t *end,
1440
+ bool is_binary) {
1441
+ return begin_parse_string(p, cur, end, is_binary ? B64_BYTE0 : NOT_BINARY,
1442
+ &p->value);
1373
1443
  }
1374
1444
 
1375
- static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p,
1376
- const uint8_t *cur,
1377
- const uint8_t *end) {
1378
- return parse_value_string(p, cur, end, is_binary_indexed_header(p));
1445
+ static grpc_error *parse_value_string_with_indexed_key(
1446
+ grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) {
1447
+ bool is_binary = false;
1448
+ grpc_error *err = is_binary_indexed_header(p, &is_binary);
1449
+ if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
1450
+ return parse_value_string(p, cur, end, is_binary);
1379
1451
  }
1380
1452
 
1381
- static int parse_value_string_with_literal_key(grpc_chttp2_hpack_parser *p,
1382
- const uint8_t *cur,
1383
- const uint8_t *end) {
1453
+ static grpc_error *parse_value_string_with_literal_key(
1454
+ grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) {
1384
1455
  return parse_value_string(p, cur, end, is_binary_literal_header(p));
1385
1456
  }
1386
1457
 
@@ -1397,6 +1468,7 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
1397
1468
  p->value.capacity = 0;
1398
1469
  p->value.length = 0;
1399
1470
  p->dynamic_table_update_allowed = 2;
1471
+ p->last_error = GRPC_ERROR_NONE;
1400
1472
  grpc_chttp2_hptbl_init(&p->table);
1401
1473
  }
1402
1474
 
@@ -1407,12 +1479,14 @@ void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
1407
1479
 
1408
1480
  void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) {
1409
1481
  grpc_chttp2_hptbl_destroy(&p->table);
1482
+ GRPC_ERROR_UNREF(p->last_error);
1410
1483
  gpr_free(p->key.str);
1411
1484
  gpr_free(p->value.str);
1412
1485
  }
1413
1486
 
1414
- int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p,
1415
- const uint8_t *beg, const uint8_t *end) {
1487
+ grpc_error *grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p,
1488
+ const uint8_t *beg,
1489
+ const uint8_t *end) {
1416
1490
  /* TODO(ctiller): limit the distance of end from beg, and perform multiple
1417
1491
  steps in the event of a large chunk of data to limit
1418
1492
  stack space usage when no tail call optimization is
@@ -1420,7 +1494,7 @@ int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p,
1420
1494
  return p->state(p, beg, end);
1421
1495
  }
1422
1496
 
1423
- grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
1497
+ grpc_error *grpc_chttp2_header_parser_parse(
1424
1498
  grpc_exec_ctx *exec_ctx, void *hpack_parser,
1425
1499
  grpc_chttp2_transport_parsing *transport_parsing,
1426
1500
  grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) {
@@ -1429,22 +1503,26 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
1429
1503
  if (stream_parsing != NULL) {
1430
1504
  stream_parsing->stats.incoming.header_bytes += GPR_SLICE_LENGTH(slice);
1431
1505
  }
1432
- if (!grpc_chttp2_hpack_parser_parse(parser, GPR_SLICE_START_PTR(slice),
1433
- GPR_SLICE_END_PTR(slice))) {
1506
+ grpc_error *error = grpc_chttp2_hpack_parser_parse(
1507
+ parser, GPR_SLICE_START_PTR(slice), GPR_SLICE_END_PTR(slice));
1508
+ if (error != GRPC_ERROR_NONE) {
1434
1509
  GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
1435
- return GRPC_CHTTP2_CONNECTION_ERROR;
1510
+ return error;
1436
1511
  }
1437
1512
  if (is_last) {
1438
1513
  if (parser->is_boundary && parser->state != parse_begin) {
1439
- gpr_log(GPR_ERROR,
1440
- "end of header frame not aligned with a hpack record boundary");
1441
1514
  GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
1442
- return GRPC_CHTTP2_CONNECTION_ERROR;
1515
+ return GRPC_ERROR_CREATE(
1516
+ "end of header frame not aligned with a hpack record boundary");
1443
1517
  }
1444
1518
  /* need to check for null stream: this can occur if we receive an invalid
1445
1519
  stream id on a header */
1446
1520
  if (stream_parsing != NULL) {
1447
1521
  if (parser->is_boundary) {
1522
+ if (stream_parsing->header_frames_received ==
1523
+ GPR_ARRAY_SIZE(stream_parsing->got_metadata_on_parse)) {
1524
+ return GRPC_ERROR_CREATE("Too many trailer frames");
1525
+ }
1448
1526
  stream_parsing
1449
1527
  ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1;
1450
1528
  stream_parsing->header_frames_received++;
@@ -1462,5 +1540,5 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
1462
1540
  parser->dynamic_table_update_allowed = 2;
1463
1541
  }
1464
1542
  GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
1465
- return GRPC_CHTTP2_PARSE_OK;
1543
+ return GRPC_ERROR_NONE;
1466
1544
  }