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.
- checksums.yaml +4 -4
- data/Makefile +1398 -817
- data/include/grpc/compression.h +2 -1
- data/include/grpc/grpc.h +10 -1
- data/include/grpc/grpc_cronet.h +51 -0
- data/include/grpc/grpc_posix.h +70 -0
- data/include/grpc/impl/codegen/atm.h +2 -2
- data/include/grpc/impl/codegen/{atm_win32.h → atm_windows.h} +3 -3
- data/include/grpc/impl/codegen/compression_types.h +39 -5
- data/include/grpc/impl/codegen/connectivity_state.h +1 -1
- data/include/grpc/impl/codegen/grpc_types.h +10 -0
- data/include/grpc/impl/codegen/log.h +2 -1
- data/include/grpc/impl/codegen/port_platform.h +30 -12
- data/include/grpc/impl/codegen/slice_buffer.h +2 -3
- data/include/grpc/impl/codegen/sync.h +2 -2
- data/include/grpc/impl/codegen/{sync_win32.h → sync_windows.h} +3 -3
- data/include/grpc/support/{sync_win32.h → atm_windows.h} +4 -4
- data/include/grpc/support/avl.h +5 -0
- data/include/grpc/support/{log_win32.h → log_windows.h} +3 -3
- data/include/grpc/support/string_util.h +2 -1
- data/include/grpc/support/{atm_win32.h → sync_windows.h} +4 -4
- data/src/core/ext/census/gen/census.pb.c +179 -0
- data/src/core/ext/census/gen/census.pb.h +294 -0
- data/src/core/ext/census/grpc_filter.c +11 -7
- data/src/core/ext/client_config/channel_connectivity.c +28 -14
- data/src/core/ext/client_config/client_channel.c +77 -53
- data/src/core/ext/client_config/connector.h +1 -1
- data/src/core/ext/client_config/lb_policy.c +9 -6
- data/src/core/ext/client_config/lb_policy.h +9 -5
- data/src/core/ext/client_config/subchannel.c +58 -39
- data/src/core/ext/client_config/subchannel.h +3 -2
- data/src/core/ext/client_config/subchannel_call_holder.c +34 -19
- data/src/core/ext/client_config/subchannel_call_holder.h +2 -1
- data/src/core/ext/client_config/subchannel_index.c +20 -9
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +7 -7
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.h +5 -5
- data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/{v0 → v1}/load_balancer.pb.c +29 -30
- data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +178 -0
- data/src/core/ext/lb_policy/pick_first/pick_first.c +65 -45
- data/src/core/ext/lb_policy/round_robin/round_robin.c +84 -43
- data/src/core/ext/load_reporting/load_reporting.c +133 -0
- data/src/core/ext/load_reporting/load_reporting.h +75 -0
- data/src/core/ext/load_reporting/load_reporting_filter.c +151 -0
- data/src/core/ext/load_reporting/load_reporting_filter.h +41 -0
- data/src/core/ext/resolver/dns/native/dns_resolver.c +22 -8
- data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +2 -2
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +4 -4
- data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +95 -0
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +14 -18
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +49 -24
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +82 -0
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +104 -60
- data/src/core/ext/transport/chttp2/transport/bin_decoder.c +232 -0
- data/src/{ruby/ext/grpc/rb_signal.c → core/ext/transport/chttp2/transport/bin_decoder.h} +27 -31
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +481 -260
- data/src/core/ext/transport/chttp2/transport/frame.h +1 -7
- data/src/core/ext/transport/chttp2/transport/frame_data.c +44 -27
- data/src/core/ext/transport/chttp2/transport/frame_data.h +6 -5
- data/src/core/ext/transport/chttp2/transport/frame_goaway.c +23 -17
- data/src/core/ext/transport/chttp2/transport/frame_goaway.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +12 -7
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -3
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +25 -12
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +23 -21
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +17 -9
- data/src/core/ext/transport/chttp2/transport/frame_window_update.h +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +365 -287
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -6
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +24 -20
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +5 -4
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +1 -0
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +1 -0
- data/src/core/ext/transport/chttp2/transport/internal.h +34 -32
- data/src/core/ext/transport/chttp2/transport/parsing.c +296 -212
- data/src/core/ext/transport/chttp2/transport/writing.c +12 -9
- data/src/core/lib/channel/channel_args.c +26 -12
- data/src/core/lib/channel/channel_args.h +1 -1
- data/src/core/lib/channel/channel_stack.c +12 -8
- data/src/core/lib/channel/channel_stack.h +27 -11
- data/src/core/lib/channel/channel_stack_builder.c +2 -2
- data/src/core/lib/channel/compress_filter.c +26 -31
- data/src/core/lib/channel/compress_filter.h +4 -4
- data/src/core/lib/channel/connected_channel.c +7 -5
- data/src/core/lib/channel/http_client_filter.c +34 -8
- data/src/core/lib/channel/http_client_filter.h +1 -1
- data/src/core/lib/channel/http_server_filter.c +21 -12
- data/src/core/lib/compression/{compression_algorithm.c → compression.c} +22 -21
- data/src/core/lib/http/httpcli.c +81 -59
- data/src/core/lib/http/httpcli.h +11 -15
- data/src/core/lib/http/httpcli_security_connector.c +5 -3
- data/src/core/lib/http/parser.c +127 -118
- data/src/core/lib/http/parser.h +11 -6
- data/src/core/lib/iomgr/closure.c +20 -16
- data/src/core/lib/iomgr/closure.h +19 -15
- data/src/core/lib/iomgr/endpoint.h +1 -1
- data/src/core/lib/iomgr/endpoint_pair_posix.c +2 -2
- data/src/core/lib/iomgr/error.c +535 -0
- data/src/core/lib/iomgr/error.h +192 -0
- data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +190 -83
- data/src/core/lib/iomgr/ev_poll_posix.c +1267 -0
- data/src/{ruby/ext/grpc/rb_signal.h → core/lib/iomgr/ev_poll_posix.h} +7 -5
- data/src/core/lib/iomgr/ev_posix.c +104 -14
- data/src/core/lib/iomgr/ev_posix.h +17 -7
- data/src/core/lib/iomgr/exec_ctx.c +25 -7
- data/src/core/lib/iomgr/exec_ctx.h +27 -8
- data/src/core/lib/iomgr/executor.c +2 -2
- data/src/core/lib/iomgr/executor.h +1 -1
- data/src/core/lib/iomgr/iocp_windows.c +2 -41
- data/src/core/lib/iomgr/iocp_windows.h +0 -8
- data/src/core/lib/iomgr/iomgr.c +5 -4
- data/src/core/lib/iomgr/iomgr_posix.c +5 -1
- data/src/core/lib/iomgr/iomgr_windows.c +1 -1
- data/src/core/lib/{support → iomgr}/load_file.c +15 -17
- data/src/core/lib/{support → iomgr}/load_file.h +8 -7
- data/src/core/lib/iomgr/polling_entity.c +104 -0
- data/src/core/lib/iomgr/polling_entity.h +81 -0
- data/src/core/lib/iomgr/pollset.h +6 -5
- data/src/core/lib/iomgr/pollset_set_windows.c +4 -1
- data/src/core/lib/iomgr/pollset_windows.c +10 -6
- data/src/core/lib/iomgr/resolve_address.h +5 -9
- data/src/core/lib/iomgr/resolve_address_posix.c +55 -38
- data/src/core/lib/iomgr/resolve_address_windows.c +51 -37
- data/src/core/lib/iomgr/sockaddr.h +2 -2
- data/src/core/lib/iomgr/{sockaddr_win32.h → sockaddr_windows.h} +3 -3
- data/src/core/lib/iomgr/socket_utils_common_posix.c +92 -45
- data/src/core/lib/iomgr/socket_utils_posix.h +19 -12
- data/src/core/lib/iomgr/socket_windows.c +61 -2
- data/src/core/lib/iomgr/socket_windows.h +13 -0
- data/src/core/lib/iomgr/tcp_client_posix.c +54 -39
- data/src/core/lib/iomgr/tcp_client_windows.c +34 -34
- data/src/core/lib/iomgr/tcp_posix.c +43 -39
- data/src/core/lib/iomgr/tcp_server.h +5 -3
- data/src/core/lib/iomgr/tcp_server_posix.c +103 -64
- data/src/core/lib/iomgr/tcp_server_windows.c +114 -101
- data/src/core/lib/iomgr/tcp_windows.c +45 -50
- data/src/core/lib/iomgr/tcp_windows.h +1 -1
- data/src/core/lib/iomgr/timer.c +26 -13
- data/src/core/lib/iomgr/udp_server.c +28 -4
- data/src/core/lib/iomgr/udp_server.h +5 -1
- data/src/core/lib/iomgr/unix_sockets_posix.c +8 -7
- data/src/core/lib/iomgr/unix_sockets_posix.h +2 -1
- data/src/core/lib/iomgr/unix_sockets_posix_noop.c +4 -2
- data/src/core/lib/iomgr/wakeup_fd_eventfd.c +15 -5
- data/src/core/lib/iomgr/wakeup_fd_pipe.c +13 -9
- data/src/core/lib/iomgr/wakeup_fd_posix.c +6 -6
- data/src/core/lib/iomgr/wakeup_fd_posix.h +9 -6
- data/src/core/lib/iomgr/workqueue.h +5 -4
- data/src/core/lib/iomgr/workqueue_posix.c +40 -26
- data/src/core/lib/iomgr/workqueue_windows.c +2 -2
- data/src/core/lib/profiling/basic_timers.c +2 -2
- data/src/core/lib/security/{security_context.c → context/security_context.c} +1 -1
- data/src/core/lib/security/{security_context.h → context/security_context.h} +4 -4
- data/src/core/lib/security/credentials/composite/composite_credentials.c +263 -0
- data/src/core/lib/security/credentials/composite/composite_credentials.h +72 -0
- data/src/core/lib/security/credentials/credentials.c +233 -0
- data/src/core/lib/security/{credentials.h → credentials/credentials.h} +19 -157
- data/src/core/lib/security/{credentials_metadata.c → credentials/credentials_metadata.c} +1 -1
- data/src/core/lib/security/credentials/fake/fake_credentials.c +139 -0
- data/src/core/lib/security/credentials/fake/fake_credentials.h +56 -0
- data/src/core/lib/security/{credentials_posix.c → credentials/google_default/credentials_posix.c} +1 -1
- data/src/core/lib/security/{credentials_win32.c → credentials/google_default/credentials_windows.c} +3 -3
- data/src/core/lib/security/{google_default_credentials.c → credentials/google_default/google_default_credentials.c} +93 -35
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +46 -0
- data/src/core/lib/security/credentials/iam/iam_credentials.c +85 -0
- data/src/core/lib/security/credentials/iam/iam_credentials.h +44 -0
- data/src/core/lib/security/{json_token.c → credentials/jwt/json_token.c} +10 -101
- data/src/core/lib/security/{json_token.h → credentials/jwt/json_token.h} +3 -33
- data/src/core/lib/security/credentials/jwt/jwt_credentials.c +160 -0
- data/src/core/lib/security/credentials/jwt/jwt_credentials.h +62 -0
- data/src/core/lib/security/{jwt_verifier.c → credentials/jwt/jwt_verifier.c} +35 -15
- data/src/core/lib/security/{jwt_verifier.h → credentials/jwt/jwt_verifier.h} +3 -3
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +433 -0
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +109 -0
- data/src/core/lib/security/credentials/plugin/plugin_credentials.c +129 -0
- data/src/core/lib/security/credentials/plugin/plugin_credentials.h +45 -0
- data/src/core/lib/security/credentials/ssl/ssl_credentials.c +240 -0
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +48 -0
- data/src/core/lib/security/{auth_filters.h → transport/auth_filters.h} +3 -3
- data/src/core/lib/security/{client_auth_filter.c → transport/client_auth_filter.c} +27 -20
- data/src/core/lib/security/{handshake.c → transport/handshake.c} +77 -45
- data/src/core/lib/security/{handshake.h → transport/handshake.h} +9 -11
- data/src/core/lib/security/{secure_endpoint.c → transport/secure_endpoint.c} +19 -12
- data/src/core/lib/security/{secure_endpoint.h → transport/secure_endpoint.h} +3 -3
- data/src/core/lib/security/{security_connector.c → transport/security_connector.c} +26 -17
- data/src/core/lib/security/{security_connector.h → transport/security_connector.h} +8 -8
- data/src/core/lib/security/{server_auth_filter.c → transport/server_auth_filter.c} +24 -16
- data/src/core/lib/security/transport/tsi_error.c +40 -0
- data/src/core/lib/security/transport/tsi_error.h +42 -0
- data/src/core/lib/security/{b64.c → util/b64.c} +1 -1
- data/src/core/lib/security/{b64.h → util/b64.h} +3 -3
- data/src/core/lib/security/util/json_util.c +61 -0
- data/src/core/lib/security/util/json_util.h +55 -0
- data/src/core/lib/support/avl.c +11 -0
- data/src/core/lib/support/cpu_windows.c +2 -2
- data/src/core/lib/support/{env_win32.c → env_windows.c} +3 -3
- data/src/core/lib/support/log.c +3 -1
- data/src/core/lib/support/log_linux.c +2 -2
- data/src/core/lib/support/{log_win32.c → log_windows.c} +4 -4
- data/src/core/lib/support/murmur_hash.c +3 -5
- data/src/core/lib/support/string.c +10 -0
- data/src/core/lib/support/string.h +4 -0
- data/src/core/lib/support/{string_util_win32.c → string_util_windows.c} +3 -3
- data/src/core/lib/support/{string_win32.c → string_windows.c} +2 -2
- data/src/core/lib/support/{string_win32.h → string_windows.h} +5 -5
- data/src/core/lib/support/subprocess_windows.c +1 -1
- data/src/core/lib/support/{sync_win32.c → sync_windows.c} +2 -2
- data/src/core/lib/support/{thd_win32.c → thd_windows.c} +2 -2
- data/src/core/lib/support/{time_win32.c → time_windows.c} +2 -2
- data/src/core/lib/support/tmpfile_msys.c +1 -1
- data/src/core/lib/support/{tmpfile_win32.c → tmpfile_windows.c} +3 -3
- data/src/core/lib/surface/alarm.c +2 -2
- data/src/core/lib/surface/byte_buffer_reader.c +13 -6
- data/src/core/lib/surface/call.c +323 -123
- data/src/core/lib/surface/call.h +2 -0
- data/src/core/lib/surface/call_log_batch.c +1 -1
- data/src/core/lib/surface/channel.c +64 -15
- data/src/core/lib/surface/channel.h +9 -0
- data/src/core/lib/surface/channel_ping.c +3 -3
- data/src/core/lib/surface/completion_queue.c +75 -19
- data/src/core/lib/surface/completion_queue.h +7 -2
- data/src/core/lib/surface/init.c +2 -1
- data/src/core/lib/surface/init_secure.c +4 -4
- data/src/core/lib/surface/lame_client.c +12 -8
- data/src/core/lib/surface/server.c +213 -120
- data/src/core/lib/surface/server.h +1 -0
- data/src/core/lib/surface/version.c +1 -1
- data/src/core/lib/transport/connectivity_state.c +40 -18
- data/src/core/lib/transport/connectivity_state.h +4 -1
- data/src/core/lib/transport/metadata.c +23 -23
- data/src/core/lib/transport/metadata.h +4 -0
- data/src/core/lib/transport/metadata_batch.c +9 -0
- data/src/core/lib/transport/metadata_batch.h +3 -0
- data/src/core/lib/transport/static_metadata.c +6 -5
- data/src/core/lib/transport/static_metadata.h +64 -60
- data/src/core/lib/transport/transport.c +24 -12
- data/src/core/lib/transport/transport.h +6 -5
- data/src/core/lib/transport/transport_impl.h +4 -0
- data/src/core/lib/transport/transport_op_string.c +2 -2
- data/src/core/plugin_registry/grpc_plugin_registry.c +4 -0
- data/src/ruby/bin/math_services.rb +41 -2
- data/src/ruby/ext/grpc/rb_call.c +42 -40
- data/src/ruby/ext/grpc/rb_channel.c +1 -1
- data/src/ruby/ext/grpc/rb_completion_queue.c +59 -6
- data/src/ruby/ext/grpc/rb_completion_queue.h +1 -1
- data/src/ruby/ext/grpc/rb_grpc.c +1 -3
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +21 -5
- data/src/ruby/ext/grpc/rb_loader.c +1 -1
- data/src/ruby/ext/grpc/rb_server.c +5 -3
- data/src/ruby/lib/grpc.rb +0 -3
- data/src/ruby/lib/grpc/errors.rb +3 -2
- data/src/ruby/lib/grpc/generic/active_call.rb +32 -42
- data/src/ruby/lib/grpc/generic/bidi_call.rb +20 -0
- data/src/ruby/lib/grpc/generic/client_stub.rb +31 -54
- data/src/ruby/lib/grpc/generic/rpc_desc.rb +4 -4
- data/src/ruby/lib/grpc/generic/rpc_server.rb +12 -23
- data/src/ruby/lib/grpc/generic/service.rb +8 -8
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/grpc/health/v1/health_services.rb +30 -2
- data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb +34 -4
- data/src/ruby/pb/grpc/testing/metrics_services.rb +39 -2
- data/src/ruby/pb/src/proto/grpc/testing/empty.rb +15 -0
- data/src/ruby/pb/src/proto/grpc/testing/messages.rb +84 -0
- data/src/ruby/pb/src/proto/grpc/testing/test.rb +14 -0
- data/src/ruby/pb/src/proto/grpc/testing/test_services.rb +110 -0
- data/src/ruby/pb/test/client.rb +5 -2
- data/src/ruby/spec/generic/active_call_spec.rb +3 -2
- data/src/ruby/spec/generic/client_stub_spec.rb +27 -24
- data/src/ruby/spec/generic/rpc_desc_spec.rb +11 -11
- data/src/ruby/spec/generic/rpc_server_spec.rb +42 -61
- data/src/ruby/spec/pb/health/checker_spec.rb +3 -5
- metadata +86 -48
- data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h +0 -182
- data/src/core/lib/security/credentials.c +0 -1296
- 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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
133
|
-
return GRPC_CHTTP2_CONNECTION_ERROR;
|
134
|
+
return GRPC_ERROR_CREATE("non-empty settings ack frame received");
|
134
135
|
}
|
135
|
-
return
|
136
|
+
return GRPC_ERROR_NONE;
|
136
137
|
} else if (flags != 0) {
|
137
|
-
|
138
|
-
return GRPC_CHTTP2_CONNECTION_ERROR;
|
138
|
+
return GRPC_ERROR_CREATE("invalid flags on settings frame");
|
139
139
|
} else if (length % 6 != 0) {
|
140
|
-
|
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
|
142
|
+
return GRPC_ERROR_NONE;
|
144
143
|
}
|
145
144
|
}
|
146
145
|
|
147
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
233
|
-
|
234
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
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
|
79
|
+
return GRPC_ERROR_NONE;
|
75
80
|
}
|
76
81
|
|
77
|
-
|
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
|
-
|
100
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
90
|
-
|
91
|
-
static
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
static
|
99
|
-
|
100
|
-
static
|
101
|
-
|
102
|
-
static
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
static
|
112
|
-
|
113
|
-
static
|
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
|
635
|
-
|
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
|
-
|
638
|
-
|
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
|
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
|
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
|
658
|
-
|
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
|
666
|
-
|
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
|
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
|
677
|
-
|
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
|
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
|
687
|
-
|
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
|
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
|
697
|
-
|
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
|
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
|
707
|
-
|
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
|
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
|
717
|
-
|
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
|
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
|
729
|
-
|
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
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
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
|
-
|
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
|
743
|
-
|
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
|
751
|
-
|
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
|
764
|
-
|
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
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
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
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
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
|
784
|
-
|
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
|
795
|
-
|
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
|
808
|
-
|
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
|
819
|
-
|
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
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
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
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
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
|
839
|
-
|
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
|
850
|
-
|
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
|
863
|
-
|
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
|
874
|
-
|
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
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
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
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
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
|
894
|
-
|
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
|
905
|
-
|
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
|
918
|
-
|
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
|
929
|
-
|
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
|
-
|
934
|
-
|
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
|
939
|
-
|
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
|
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
|
950
|
-
|
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
|
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
|
965
|
-
|
966
|
-
|
967
|
-
|
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
|
971
|
-
|
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
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
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
|
982
|
-
|
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
|
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
|
1000
|
-
|
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
|
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
|
1018
|
-
|
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
|
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
|
1036
|
-
|
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
|
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
|
1054
|
-
|
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
|
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
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
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
|
1097
|
-
|
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
|
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
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
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
|
1122
|
-
|
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
|
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
|
1152
|
-
|
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
|
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
|
1221
|
+
return GRPC_ERROR_NONE;
|
1165
1222
|
}
|
1166
1223
|
bits = inverse_base64[*cur];
|
1167
1224
|
++cur;
|
1168
1225
|
if (bits == 255)
|
1169
|
-
return
|
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
|
1236
|
+
return GRPC_ERROR_NONE;
|
1179
1237
|
}
|
1180
1238
|
bits = inverse_base64[*cur];
|
1181
1239
|
++cur;
|
1182
1240
|
if (bits == 255)
|
1183
|
-
return
|
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
|
1251
|
+
return GRPC_ERROR_NONE;
|
1193
1252
|
}
|
1194
1253
|
bits = inverse_base64[*cur];
|
1195
1254
|
++cur;
|
1196
1255
|
if (bits == 255)
|
1197
|
-
return
|
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
|
1266
|
+
return GRPC_ERROR_NONE;
|
1207
1267
|
}
|
1208
1268
|
bits = inverse_base64[*cur];
|
1209
1269
|
++cur;
|
1210
1270
|
if (bits == 255)
|
1211
|
-
return
|
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
|
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
|
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
|
-
|
1238
|
-
|
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
|
-
|
1243
|
-
|
1244
|
-
|
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
|
-
|
1253
|
-
|
1254
|
-
|
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
|
1333
|
+
return GRPC_ERROR_NONE;
|
1264
1334
|
}
|
1265
1335
|
|
1266
1336
|
/* decode a nibble from a huffman encoded stream */
|
1267
|
-
static
|
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
|
-
|
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
|
1350
|
+
return GRPC_ERROR_NONE;
|
1280
1351
|
}
|
1281
1352
|
|
1282
1353
|
/* decode full bytes from a huffman encoded stream */
|
1283
|
-
static
|
1284
|
-
|
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
|
-
|
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
|
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
|
1294
|
-
|
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
|
1304
|
-
|
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
|
-
|
1309
|
-
|
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
|
-
|
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
|
1393
|
+
return GRPC_ERROR_NONE;
|
1316
1394
|
}
|
1317
1395
|
}
|
1318
1396
|
|
1319
1397
|
/* begin parsing a string - performs setup, calls parse_string */
|
1320
|
-
static
|
1321
|
-
|
1322
|
-
|
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
|
1333
|
-
|
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
|
1341
|
-
return grpc_is_binary_header(p->key.str, p->key.length)
|
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
|
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
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
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
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
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
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
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
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
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
|
1382
|
-
|
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
|
-
|
1415
|
-
|
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
|
-
|
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
|
-
|
1433
|
-
|
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
|
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
|
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
|
1543
|
+
return GRPC_ERROR_NONE;
|
1466
1544
|
}
|