grpc 1.39.0 → 1.40.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +20 -4
- data/include/grpc/event_engine/event_engine.h +10 -14
- data/include/grpc/event_engine/slice_allocator.h +8 -33
- data/include/grpc/impl/codegen/grpc_types.h +18 -8
- data/include/grpc/impl/codegen/port_platform.h +24 -0
- data/src/core/ext/filters/client_channel/client_channel.cc +413 -247
- data/src/core/ext/filters/client_channel/client_channel.h +42 -18
- data/src/core/ext/filters/client_channel/config_selector.h +19 -6
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +7 -8
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +12 -21
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +3 -5
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +17 -38
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -15
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +3 -6
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +8 -12
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +14 -22
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +2 -9
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +5 -8
- data/src/core/ext/filters/client_channel/lb_policy.cc +1 -15
- data/src/core/ext/filters/client_channel/lb_policy.h +70 -46
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +101 -73
- data/src/core/ext/filters/client_channel/retry_filter.cc +392 -243
- data/src/core/ext/filters/client_channel/retry_service_config.cc +36 -26
- data/src/core/ext/filters/client_channel/retry_service_config.h +1 -1
- data/src/core/ext/filters/client_channel/service_config_call_data.h +45 -5
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +0 -6
- data/src/core/ext/filters/http/client/http_client_filter.cc +5 -2
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +5 -1
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +1 -1
- data/src/core/{lib/event_engine/slice_allocator.cc → ext/transport/chttp2/transport/chttp2_slice_allocator.cc} +15 -38
- data/src/core/ext/transport/chttp2/transport/chttp2_slice_allocator.h +74 -0
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -6
- data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +8 -8
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +5 -5
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +639 -752
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +190 -69
- data/src/core/ext/transport/chttp2/transport/internal.h +1 -1
- data/src/core/ext/transport/chttp2/transport/parsing.cc +70 -54
- data/src/core/ext/transport/chttp2/transport/varint.cc +6 -4
- data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c +56 -35
- data/src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.h +180 -76
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +35 -27
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +97 -48
- data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +45 -9
- data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h +67 -7
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +66 -9
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +227 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.c +46 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/resolver.upb.h +121 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c +1 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.c +35 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/udp_socket_config.upb.h +90 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +32 -24
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +120 -73
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +4 -2
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +15 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.c +48 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/quic_config.upb.h +171 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c +8 -6
- data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h +27 -19
- data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +1 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c +24 -7
- data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h +57 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +29 -17
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +72 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c +3 -2
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.h +4 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c +6 -5
- data/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h +15 -11
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +85 -43
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +274 -91
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +11 -8
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +30 -13
- data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c +33 -5
- data/src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.h +115 -0
- data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.c +60 -0
- data/src/core/ext/upb-generated/envoy/type/http/v3/path_transformation.upb.h +181 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c +1 -0
- data/src/core/ext/upb-generated/validate/validate.upb.c +82 -66
- data/src/core/ext/upb-generated/validate/validate.upb.h +220 -124
- data/src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c +15 -7
- data/src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c +53 -52
- data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +318 -277
- data/src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c +437 -410
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c +198 -170
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.h +10 -0
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c +9 -8
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c +219 -163
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.h +15 -0
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/resolver.upbdefs.c +59 -0
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/resolver.upbdefs.h +40 -0
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c +29 -25
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/udp_socket_config.upbdefs.c +52 -0
- data/src/core/ext/upbdefs-generated/envoy/config/core/v3/udp_socket_config.upbdefs.h +35 -0
- data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c +135 -125
- data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c +131 -123
- data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.c +90 -0
- data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/quic_config.upbdefs.h +35 -0
- data/src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c +32 -24
- data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c +69 -55
- data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c +684 -664
- data/src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c +13 -10
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c +13 -10
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +441 -375
- data/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h +10 -0
- data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c +122 -114
- data/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c +1 -1
- data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c +112 -79
- data/src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.h +5 -0
- data/src/core/ext/upbdefs-generated/envoy/type/http/v3/path_transformation.upbdefs.c +64 -0
- data/src/core/ext/upbdefs-generated/envoy/type/http/v3/path_transformation.upbdefs.h +50 -0
- data/src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c +35 -32
- data/src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c +4 -4
- data/src/core/ext/upbdefs-generated/validate/validate.upbdefs.c +182 -160
- data/src/core/ext/xds/certificate_provider_store.h +1 -1
- data/src/core/ext/xds/xds_api.cc +320 -121
- data/src/core/ext/xds/xds_api.h +31 -2
- data/src/core/ext/xds/xds_bootstrap.cc +4 -1
- data/src/core/ext/xds/xds_client.cc +66 -43
- data/src/core/ext/xds/xds_client.h +0 -4
- data/src/core/ext/xds/xds_http_filters.cc +3 -2
- data/src/core/ext/xds/xds_http_filters.h +3 -0
- data/src/core/lib/channel/call_tracer.h +85 -0
- data/src/core/lib/channel/channel_stack.h +1 -1
- data/src/core/lib/channel/context.h +3 -0
- data/src/core/lib/channel/status_util.h +4 -0
- data/src/core/lib/compression/stream_compression.h +1 -1
- data/src/core/lib/compression/stream_compression_gzip.h +1 -1
- data/src/core/lib/compression/stream_compression_identity.h +1 -1
- data/src/core/lib/debug/stats.h +1 -1
- data/src/core/lib/gpr/murmur_hash.cc +4 -2
- data/src/core/lib/gprpp/manual_constructor.h +1 -1
- data/src/core/lib/gprpp/orphanable.h +3 -3
- data/src/core/lib/gprpp/sync.h +2 -30
- data/src/core/lib/iomgr/buffer_list.cc +1 -1
- data/src/core/lib/iomgr/ev_apple.h +1 -1
- data/src/core/lib/iomgr/event_engine/endpoint.cc +6 -8
- data/src/core/lib/iomgr/event_engine/tcp.cc +30 -10
- data/src/core/lib/iomgr/python_util.h +1 -1
- data/src/core/lib/iomgr/resource_quota.cc +2 -0
- data/src/core/lib/iomgr/tcp_client_windows.cc +2 -0
- data/src/core/lib/iomgr/tcp_server_posix.cc +1 -0
- data/src/core/lib/iomgr/timer_manager.cc +1 -1
- data/src/core/lib/json/json_reader.cc +1 -2
- data/src/core/lib/matchers/matchers.cc +8 -20
- data/src/core/lib/matchers/matchers.h +2 -1
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +49 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +7 -0
- data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +6 -18
- data/src/core/lib/security/transport/security_handshaker.cc +12 -4
- data/src/core/lib/security/transport/server_auth_filter.cc +0 -7
- data/src/core/lib/slice/slice_internal.h +1 -0
- data/src/core/lib/surface/call.cc +5 -6
- data/src/core/lib/surface/server.cc +3 -1
- data/src/core/lib/surface/server.h +3 -3
- data/src/core/lib/surface/version.cc +1 -3
- data/src/ruby/ext/grpc/extconf.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/xxhash/xxhash.h +77 -195
- metadata +52 -35
- data/src/core/lib/gpr/arena.h +0 -47
@@ -148,7 +148,7 @@ grpc_error_handle grpc_deframe_unprocessed_incoming_frames(
|
|
148
148
|
grpc_slice_buffer_remove_first(slices);
|
149
149
|
continue;
|
150
150
|
}
|
151
|
-
|
151
|
+
ABSL_FALLTHROUGH_INTENDED;
|
152
152
|
case GRPC_CHTTP2_DATA_FH_1:
|
153
153
|
s->stats.incoming.framing_bytes++;
|
154
154
|
p->frame_size = (static_cast<uint32_t>(*cur)) << 24;
|
@@ -157,7 +157,7 @@ grpc_error_handle grpc_deframe_unprocessed_incoming_frames(
|
|
157
157
|
grpc_slice_buffer_remove_first(slices);
|
158
158
|
continue;
|
159
159
|
}
|
160
|
-
|
160
|
+
ABSL_FALLTHROUGH_INTENDED;
|
161
161
|
case GRPC_CHTTP2_DATA_FH_2:
|
162
162
|
s->stats.incoming.framing_bytes++;
|
163
163
|
p->frame_size |= (static_cast<uint32_t>(*cur)) << 16;
|
@@ -166,7 +166,7 @@ grpc_error_handle grpc_deframe_unprocessed_incoming_frames(
|
|
166
166
|
grpc_slice_buffer_remove_first(slices);
|
167
167
|
continue;
|
168
168
|
}
|
169
|
-
|
169
|
+
ABSL_FALLTHROUGH_INTENDED;
|
170
170
|
case GRPC_CHTTP2_DATA_FH_3:
|
171
171
|
s->stats.incoming.framing_bytes++;
|
172
172
|
p->frame_size |= (static_cast<uint32_t>(*cur)) << 8;
|
@@ -175,7 +175,7 @@ grpc_error_handle grpc_deframe_unprocessed_incoming_frames(
|
|
175
175
|
grpc_slice_buffer_remove_first(slices);
|
176
176
|
continue;
|
177
177
|
}
|
178
|
-
|
178
|
+
ABSL_FALLTHROUGH_INTENDED;
|
179
179
|
case GRPC_CHTTP2_DATA_FH_4:
|
180
180
|
s->stats.incoming.framing_bytes++;
|
181
181
|
GPR_ASSERT(stream_out != nullptr);
|
@@ -70,7 +70,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
70
70
|
}
|
71
71
|
p->last_stream_id = (static_cast<uint32_t>(*cur)) << 24;
|
72
72
|
++cur;
|
73
|
-
|
73
|
+
ABSL_FALLTHROUGH_INTENDED;
|
74
74
|
case GRPC_CHTTP2_GOAWAY_LSI1:
|
75
75
|
if (cur == end) {
|
76
76
|
p->state = GRPC_CHTTP2_GOAWAY_LSI1;
|
@@ -78,7 +78,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
78
78
|
}
|
79
79
|
p->last_stream_id |= (static_cast<uint32_t>(*cur)) << 16;
|
80
80
|
++cur;
|
81
|
-
|
81
|
+
ABSL_FALLTHROUGH_INTENDED;
|
82
82
|
case GRPC_CHTTP2_GOAWAY_LSI2:
|
83
83
|
if (cur == end) {
|
84
84
|
p->state = GRPC_CHTTP2_GOAWAY_LSI2;
|
@@ -86,7 +86,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
86
86
|
}
|
87
87
|
p->last_stream_id |= (static_cast<uint32_t>(*cur)) << 8;
|
88
88
|
++cur;
|
89
|
-
|
89
|
+
ABSL_FALLTHROUGH_INTENDED;
|
90
90
|
case GRPC_CHTTP2_GOAWAY_LSI3:
|
91
91
|
if (cur == end) {
|
92
92
|
p->state = GRPC_CHTTP2_GOAWAY_LSI3;
|
@@ -94,7 +94,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
94
94
|
}
|
95
95
|
p->last_stream_id |= (static_cast<uint32_t>(*cur));
|
96
96
|
++cur;
|
97
|
-
|
97
|
+
ABSL_FALLTHROUGH_INTENDED;
|
98
98
|
case GRPC_CHTTP2_GOAWAY_ERR0:
|
99
99
|
if (cur == end) {
|
100
100
|
p->state = GRPC_CHTTP2_GOAWAY_ERR0;
|
@@ -102,7 +102,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
102
102
|
}
|
103
103
|
p->error_code = (static_cast<uint32_t>(*cur)) << 24;
|
104
104
|
++cur;
|
105
|
-
|
105
|
+
ABSL_FALLTHROUGH_INTENDED;
|
106
106
|
case GRPC_CHTTP2_GOAWAY_ERR1:
|
107
107
|
if (cur == end) {
|
108
108
|
p->state = GRPC_CHTTP2_GOAWAY_ERR1;
|
@@ -110,7 +110,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
110
110
|
}
|
111
111
|
p->error_code |= (static_cast<uint32_t>(*cur)) << 16;
|
112
112
|
++cur;
|
113
|
-
|
113
|
+
ABSL_FALLTHROUGH_INTENDED;
|
114
114
|
case GRPC_CHTTP2_GOAWAY_ERR2:
|
115
115
|
if (cur == end) {
|
116
116
|
p->state = GRPC_CHTTP2_GOAWAY_ERR2;
|
@@ -118,7 +118,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
118
118
|
}
|
119
119
|
p->error_code |= (static_cast<uint32_t>(*cur)) << 8;
|
120
120
|
++cur;
|
121
|
-
|
121
|
+
ABSL_FALLTHROUGH_INTENDED;
|
122
122
|
case GRPC_CHTTP2_GOAWAY_ERR3:
|
123
123
|
if (cur == end) {
|
124
124
|
p->state = GRPC_CHTTP2_GOAWAY_ERR3;
|
@@ -126,7 +126,7 @@ grpc_error_handle grpc_chttp2_goaway_parser_parse(void* parser,
|
|
126
126
|
}
|
127
127
|
p->error_code |= (static_cast<uint32_t>(*cur));
|
128
128
|
++cur;
|
129
|
-
|
129
|
+
ABSL_FALLTHROUGH_INTENDED;
|
130
130
|
case GRPC_CHTTP2_GOAWAY_DEBUG:
|
131
131
|
if (end != cur) {
|
132
132
|
memcpy(p->debug_data + p->debug_pos, cur,
|
@@ -146,7 +146,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
|
|
146
146
|
}
|
147
147
|
parser->id = static_cast<uint16_t>((static_cast<uint16_t>(*cur)) << 8);
|
148
148
|
cur++;
|
149
|
-
|
149
|
+
ABSL_FALLTHROUGH_INTENDED;
|
150
150
|
case GRPC_CHTTP2_SPS_ID1:
|
151
151
|
if (cur == end) {
|
152
152
|
parser->state = GRPC_CHTTP2_SPS_ID1;
|
@@ -154,7 +154,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
|
|
154
154
|
}
|
155
155
|
parser->id = static_cast<uint16_t>(parser->id | (*cur));
|
156
156
|
cur++;
|
157
|
-
|
157
|
+
ABSL_FALLTHROUGH_INTENDED;
|
158
158
|
case GRPC_CHTTP2_SPS_VAL0:
|
159
159
|
if (cur == end) {
|
160
160
|
parser->state = GRPC_CHTTP2_SPS_VAL0;
|
@@ -162,7 +162,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
|
|
162
162
|
}
|
163
163
|
parser->value = (static_cast<uint32_t>(*cur)) << 24;
|
164
164
|
cur++;
|
165
|
-
|
165
|
+
ABSL_FALLTHROUGH_INTENDED;
|
166
166
|
case GRPC_CHTTP2_SPS_VAL1:
|
167
167
|
if (cur == end) {
|
168
168
|
parser->state = GRPC_CHTTP2_SPS_VAL1;
|
@@ -170,7 +170,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
|
|
170
170
|
}
|
171
171
|
parser->value |= (static_cast<uint32_t>(*cur)) << 16;
|
172
172
|
cur++;
|
173
|
-
|
173
|
+
ABSL_FALLTHROUGH_INTENDED;
|
174
174
|
case GRPC_CHTTP2_SPS_VAL2:
|
175
175
|
if (cur == end) {
|
176
176
|
parser->state = GRPC_CHTTP2_SPS_VAL2;
|
@@ -178,7 +178,7 @@ grpc_error_handle grpc_chttp2_settings_parser_parse(void* p,
|
|
178
178
|
}
|
179
179
|
parser->value |= (static_cast<uint32_t>(*cur)) << 8;
|
180
180
|
cur++;
|
181
|
-
|
181
|
+
ABSL_FALLTHROUGH_INTENDED;
|
182
182
|
case GRPC_CHTTP2_SPS_VAL3:
|
183
183
|
if (cur == end) {
|
184
184
|
parser->state = GRPC_CHTTP2_SPS_VAL3;
|
@@ -40,17 +40,17 @@
|
|
40
40
|
#include "src/core/lib/surface/validate_metadata.h"
|
41
41
|
#include "src/core/lib/transport/http2_errors.h"
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
43
|
+
#if __cplusplus > 201103L
|
44
|
+
#define GRPC_HPACK_CONSTEXPR_FN constexpr
|
45
|
+
#define GRPC_HPACK_CONSTEXPR_VALUE constexpr
|
46
|
+
#else
|
47
|
+
#define GRPC_HPACK_CONSTEXPR_FN
|
48
|
+
#define GRPC_HPACK_CONSTEXPR_VALUE const
|
49
|
+
#endif
|
50
|
+
|
51
|
+
namespace grpc_core {
|
52
|
+
|
53
|
+
DebugOnlyTraceFlag grpc_trace_chttp2_hpack_parser(false, "chttp2_hpack_parser");
|
54
54
|
|
55
55
|
/* How parsing works:
|
56
56
|
|
@@ -66,184 +66,6 @@ typedef enum {
|
|
66
66
|
It's expected that most optimizing compilers will turn this code into
|
67
67
|
a set of indirect jumps, and so not waste stack space. */
|
68
68
|
|
69
|
-
/* forward declarations for parsing states */
|
70
|
-
static grpc_error_handle parse_begin(grpc_chttp2_hpack_parser* p,
|
71
|
-
const uint8_t* cur, const uint8_t* end);
|
72
|
-
static grpc_error_handle parse_error(grpc_chttp2_hpack_parser* p,
|
73
|
-
const uint8_t* cur, const uint8_t* end,
|
74
|
-
grpc_error_handle error);
|
75
|
-
static grpc_error_handle still_parse_error(grpc_chttp2_hpack_parser* p,
|
76
|
-
const uint8_t* cur,
|
77
|
-
const uint8_t* end);
|
78
|
-
static grpc_error_handle parse_illegal_op(grpc_chttp2_hpack_parser* p,
|
79
|
-
const uint8_t* cur,
|
80
|
-
const uint8_t* end);
|
81
|
-
|
82
|
-
static grpc_error_handle parse_string_prefix(grpc_chttp2_hpack_parser* p,
|
83
|
-
const uint8_t* cur,
|
84
|
-
const uint8_t* end);
|
85
|
-
static grpc_error_handle parse_key_string(grpc_chttp2_hpack_parser* p,
|
86
|
-
const uint8_t* cur,
|
87
|
-
const uint8_t* end);
|
88
|
-
static grpc_error_handle parse_value_string_with_indexed_key(
|
89
|
-
grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end);
|
90
|
-
static grpc_error_handle parse_value_string_with_literal_key(
|
91
|
-
grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end);
|
92
|
-
|
93
|
-
static grpc_error_handle parse_value0(grpc_chttp2_hpack_parser* p,
|
94
|
-
const uint8_t* cur, const uint8_t* end);
|
95
|
-
static grpc_error_handle parse_value1(grpc_chttp2_hpack_parser* p,
|
96
|
-
const uint8_t* cur, const uint8_t* end);
|
97
|
-
static grpc_error_handle parse_value2(grpc_chttp2_hpack_parser* p,
|
98
|
-
const uint8_t* cur, const uint8_t* end);
|
99
|
-
static grpc_error_handle parse_value3(grpc_chttp2_hpack_parser* p,
|
100
|
-
const uint8_t* cur, const uint8_t* end);
|
101
|
-
static grpc_error_handle parse_value4(grpc_chttp2_hpack_parser* p,
|
102
|
-
const uint8_t* cur, const uint8_t* end);
|
103
|
-
static grpc_error_handle parse_value5up(grpc_chttp2_hpack_parser* p,
|
104
|
-
const uint8_t* cur, const uint8_t* end);
|
105
|
-
|
106
|
-
static grpc_error_handle parse_indexed_field(grpc_chttp2_hpack_parser* p,
|
107
|
-
const uint8_t* cur,
|
108
|
-
const uint8_t* end);
|
109
|
-
static grpc_error_handle parse_indexed_field_x(grpc_chttp2_hpack_parser* p,
|
110
|
-
const uint8_t* cur,
|
111
|
-
const uint8_t* end);
|
112
|
-
static grpc_error_handle parse_lithdr_incidx(grpc_chttp2_hpack_parser* p,
|
113
|
-
const uint8_t* cur,
|
114
|
-
const uint8_t* end);
|
115
|
-
static grpc_error_handle parse_lithdr_incidx_x(grpc_chttp2_hpack_parser* p,
|
116
|
-
const uint8_t* cur,
|
117
|
-
const uint8_t* end);
|
118
|
-
static grpc_error_handle parse_lithdr_incidx_v(grpc_chttp2_hpack_parser* p,
|
119
|
-
const uint8_t* cur,
|
120
|
-
const uint8_t* end);
|
121
|
-
static grpc_error_handle parse_lithdr_notidx(grpc_chttp2_hpack_parser* p,
|
122
|
-
const uint8_t* cur,
|
123
|
-
const uint8_t* end);
|
124
|
-
static grpc_error_handle parse_lithdr_notidx_x(grpc_chttp2_hpack_parser* p,
|
125
|
-
const uint8_t* cur,
|
126
|
-
const uint8_t* end);
|
127
|
-
static grpc_error_handle parse_lithdr_notidx_v(grpc_chttp2_hpack_parser* p,
|
128
|
-
const uint8_t* cur,
|
129
|
-
const uint8_t* end);
|
130
|
-
static grpc_error_handle parse_lithdr_nvridx(grpc_chttp2_hpack_parser* p,
|
131
|
-
const uint8_t* cur,
|
132
|
-
const uint8_t* end);
|
133
|
-
static grpc_error_handle parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser* p,
|
134
|
-
const uint8_t* cur,
|
135
|
-
const uint8_t* end);
|
136
|
-
static grpc_error_handle parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p,
|
137
|
-
const uint8_t* cur,
|
138
|
-
const uint8_t* end);
|
139
|
-
static grpc_error_handle parse_max_tbl_size(grpc_chttp2_hpack_parser* p,
|
140
|
-
const uint8_t* cur,
|
141
|
-
const uint8_t* end);
|
142
|
-
static grpc_error_handle parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p,
|
143
|
-
const uint8_t* cur,
|
144
|
-
const uint8_t* end);
|
145
|
-
|
146
|
-
/* we translate the first byte of a hpack field into one of these decoding
|
147
|
-
cases, then use a lookup table to jump directly to the appropriate parser.
|
148
|
-
|
149
|
-
_X => the integer index is all ones, meaning we need to do varint decoding
|
150
|
-
_V => the integer index is all zeros, meaning we need to decode an additional
|
151
|
-
string value */
|
152
|
-
typedef enum {
|
153
|
-
INDEXED_FIELD,
|
154
|
-
INDEXED_FIELD_X,
|
155
|
-
LITHDR_INCIDX,
|
156
|
-
LITHDR_INCIDX_X,
|
157
|
-
LITHDR_INCIDX_V,
|
158
|
-
LITHDR_NOTIDX,
|
159
|
-
LITHDR_NOTIDX_X,
|
160
|
-
LITHDR_NOTIDX_V,
|
161
|
-
LITHDR_NVRIDX,
|
162
|
-
LITHDR_NVRIDX_X,
|
163
|
-
LITHDR_NVRIDX_V,
|
164
|
-
MAX_TBL_SIZE,
|
165
|
-
MAX_TBL_SIZE_X,
|
166
|
-
ILLEGAL
|
167
|
-
} first_byte_type;
|
168
|
-
|
169
|
-
/* jump table of parse state functions -- order must match first_byte_type
|
170
|
-
above */
|
171
|
-
static const grpc_chttp2_hpack_parser_state first_byte_action[] = {
|
172
|
-
parse_indexed_field, parse_indexed_field_x, parse_lithdr_incidx,
|
173
|
-
parse_lithdr_incidx_x, parse_lithdr_incidx_v, parse_lithdr_notidx,
|
174
|
-
parse_lithdr_notidx_x, parse_lithdr_notidx_v, parse_lithdr_nvridx,
|
175
|
-
parse_lithdr_nvridx_x, parse_lithdr_nvridx_v, parse_max_tbl_size,
|
176
|
-
parse_max_tbl_size_x, parse_illegal_op};
|
177
|
-
|
178
|
-
/* indexes the first byte to a parse state function - generated by
|
179
|
-
gen_hpack_tables.c */
|
180
|
-
static const uint8_t first_byte_lut[256] = {
|
181
|
-
LITHDR_NOTIDX_V, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX,
|
182
|
-
LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX,
|
183
|
-
LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX,
|
184
|
-
LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX_X,
|
185
|
-
LITHDR_NVRIDX_V, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
|
186
|
-
LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
|
187
|
-
LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
|
188
|
-
LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX_X,
|
189
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
190
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
191
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
192
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
193
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
194
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
195
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE,
|
196
|
-
MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE, MAX_TBL_SIZE_X,
|
197
|
-
LITHDR_INCIDX_V, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
198
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
199
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
200
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
201
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
202
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
203
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
204
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
205
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
206
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
207
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
208
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
209
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
210
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
211
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
|
212
|
-
LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX_X,
|
213
|
-
ILLEGAL, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
214
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
215
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
216
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
217
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
218
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
219
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
220
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
221
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
222
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
223
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
224
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
225
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
226
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
227
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
228
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
229
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
230
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
231
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
232
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
233
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
234
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
235
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
236
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
237
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
238
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
239
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
240
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
241
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
242
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
243
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
|
244
|
-
INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD_X,
|
245
|
-
};
|
246
|
-
|
247
69
|
/* state table for huffman decoding: given a state, gives an index/16 into
|
248
70
|
next_sub_tbl. Taking that index and adding the value of the nibble being
|
249
71
|
considered returns the next state.
|
@@ -617,28 +439,37 @@ static const int16_t emit_sub_tbl[249 * 16] = {
|
|
617
439
|
13, 22, 22, 22, 22, 256, 256, 256, 256,
|
618
440
|
};
|
619
441
|
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
442
|
+
namespace {
|
443
|
+
// The alphabet used for base64 encoding binary metadata.
|
444
|
+
static constexpr char kBase64Alphabet[] =
|
445
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
446
|
+
|
447
|
+
// An inverted table: for each value in kBase64Alphabet, table contains the
|
448
|
+
// index with which it's stored, so we can quickly invert the encoding without
|
449
|
+
// any complicated runtime logic.
|
450
|
+
struct Base64InverseTable {
|
451
|
+
uint8_t table[256]{};
|
452
|
+
GRPC_HPACK_CONSTEXPR_FN Base64InverseTable() {
|
453
|
+
for (int i = 0; i < 256; i++) {
|
454
|
+
table[i] = 255;
|
455
|
+
}
|
456
|
+
for (const char* p = kBase64Alphabet; *p; p++) {
|
457
|
+
uint8_t idx = *p;
|
458
|
+
uint8_t ofs = p - kBase64Alphabet;
|
459
|
+
table[idx] = ofs;
|
460
|
+
}
|
461
|
+
}
|
639
462
|
};
|
640
463
|
|
641
|
-
static
|
464
|
+
static GRPC_HPACK_CONSTEXPR_VALUE Base64InverseTable kBase64InverseTable;
|
465
|
+
} // namespace
|
466
|
+
|
467
|
+
void HPackParser::FinishFrame() {
|
468
|
+
sink_ = Sink();
|
469
|
+
dynamic_table_updates_allowed_ = 2;
|
470
|
+
}
|
471
|
+
|
472
|
+
void GPR_ATTRIBUTE_NOINLINE HPackParser::LogHeader(grpc_mdelem md) {
|
642
473
|
char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
|
643
474
|
char* v = nullptr;
|
644
475
|
if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
|
@@ -657,185 +488,270 @@ static void GPR_ATTRIBUTE_NOINLINE on_hdr_log(grpc_mdelem md) {
|
|
657
488
|
}
|
658
489
|
|
659
490
|
/* emission helpers */
|
660
|
-
template <
|
661
|
-
|
491
|
+
template <HPackParser::TableAction action>
|
492
|
+
grpc_error_handle HPackParser::FinishHeader(grpc_mdelem md) {
|
662
493
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_hpack_parser)) {
|
663
|
-
|
494
|
+
LogHeader(md);
|
664
495
|
}
|
665
|
-
if (
|
496
|
+
if (action == TableAction::kAddToTable) {
|
666
497
|
GPR_DEBUG_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
|
667
498
|
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
|
668
|
-
grpc_error_handle err = grpc_chttp2_hptbl_add(&
|
499
|
+
grpc_error_handle err = grpc_chttp2_hptbl_add(&table_, md);
|
669
500
|
if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
|
670
501
|
}
|
671
|
-
return
|
502
|
+
return sink_(md);
|
672
503
|
}
|
673
504
|
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
str->data.referenced = grpc_core::UnmanagedMemorySlice();
|
505
|
+
UnmanagedMemorySlice HPackParser::String::TakeExtern() {
|
506
|
+
UnmanagedMemorySlice s;
|
507
|
+
if (!copied_) {
|
508
|
+
GPR_DEBUG_ASSERT(!grpc_slice_is_interned(data_.referenced));
|
509
|
+
s = static_cast<UnmanagedMemorySlice&>(data_.referenced);
|
510
|
+
copied_ = true;
|
511
|
+
data_.referenced = UnmanagedMemorySlice();
|
682
512
|
} else {
|
683
|
-
s =
|
684
|
-
str->data.copied.length);
|
513
|
+
s = UnmanagedMemorySlice(data_.copied.str, data_.copied.length);
|
685
514
|
}
|
686
|
-
|
515
|
+
data_.copied.length = 0;
|
687
516
|
return s;
|
688
517
|
}
|
689
518
|
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
str->data.referenced = grpc_empty_slice();
|
519
|
+
ManagedMemorySlice HPackParser::String::TakeIntern() {
|
520
|
+
ManagedMemorySlice s;
|
521
|
+
if (!copied_) {
|
522
|
+
s = ManagedMemorySlice(&data_.referenced);
|
523
|
+
grpc_slice_unref_internal(data_.referenced);
|
524
|
+
copied_ = true;
|
525
|
+
data_.referenced = grpc_empty_slice();
|
698
526
|
} else {
|
699
|
-
s =
|
700
|
-
str->data.copied.length);
|
527
|
+
s = ManagedMemorySlice(data_.copied.str, data_.copied.length);
|
701
528
|
}
|
702
|
-
|
529
|
+
data_.copied.length = 0;
|
703
530
|
return s;
|
704
531
|
}
|
705
532
|
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
return p->state(p, cur, end);
|
533
|
+
grpc_error_handle HPackParser::parse_next(const uint8_t* cur,
|
534
|
+
const uint8_t* end) {
|
535
|
+
state_ = *next_state_++;
|
536
|
+
return (this->*state_)(cur, end);
|
711
537
|
}
|
712
538
|
|
713
539
|
/* begin parsing a header: all functionality is encoded into lookup tables
|
714
540
|
above */
|
715
|
-
|
716
|
-
|
541
|
+
grpc_error_handle HPackParser::parse_begin(const uint8_t* cur,
|
542
|
+
const uint8_t* end) {
|
717
543
|
if (cur == end) {
|
718
|
-
|
544
|
+
state_ = &HPackParser::parse_begin;
|
719
545
|
return GRPC_ERROR_NONE;
|
720
546
|
}
|
721
547
|
|
722
|
-
|
548
|
+
switch (*cur >> 4) {
|
549
|
+
// Literal header not indexed.
|
550
|
+
// First byte format: 0000xxxx
|
551
|
+
// Where xxxx:
|
552
|
+
// 0000 - literal key
|
553
|
+
// 1111 - indexed key, varint encoded index
|
554
|
+
// other - indexed key, inline encoded index
|
555
|
+
case 0:
|
556
|
+
switch (*cur & 0xf) {
|
557
|
+
case 0: // literal key
|
558
|
+
return parse_lithdr_notidx_v(cur, end);
|
559
|
+
case 0xf: // varint encoded key index
|
560
|
+
return parse_lithdr_notidx_x(cur, end);
|
561
|
+
default: // inline encoded key index
|
562
|
+
return parse_lithdr_notidx(cur, end);
|
563
|
+
}
|
564
|
+
// Literal header never indexed.
|
565
|
+
// First byte format: 0001xxxx
|
566
|
+
// Where xxxx:
|
567
|
+
// 0000 - literal key
|
568
|
+
// 1111 - indexed key, varint encoded index
|
569
|
+
// other - indexed key, inline encoded index
|
570
|
+
case 1:
|
571
|
+
switch (*cur & 0xf) {
|
572
|
+
case 0: // literal key
|
573
|
+
return parse_lithdr_nvridx_v(cur, end);
|
574
|
+
case 0xf: // varint encoded key index
|
575
|
+
return parse_lithdr_nvridx_x(cur, end);
|
576
|
+
default: // inline encoded key index
|
577
|
+
return parse_lithdr_nvridx(cur, end);
|
578
|
+
}
|
579
|
+
// Update max table size.
|
580
|
+
// First byte format: 001xxxxx
|
581
|
+
// Where xxxxx:
|
582
|
+
// 11111 - max size is varint encoded
|
583
|
+
// other - max size is stored inline
|
584
|
+
case 2:
|
585
|
+
// inline encoded max table size
|
586
|
+
return parse_max_tbl_size(cur, end);
|
587
|
+
case 3:
|
588
|
+
if (*cur == 0x3f) {
|
589
|
+
// varint encoded max table size
|
590
|
+
return parse_max_tbl_size_x(cur, end);
|
591
|
+
} else {
|
592
|
+
// inline encoded max table size
|
593
|
+
return parse_max_tbl_size(cur, end);
|
594
|
+
}
|
595
|
+
// Literal header with incremental indexing.
|
596
|
+
// First byte format: 01xxxxxx
|
597
|
+
// Where xxxxxx:
|
598
|
+
// 000000 - literal key
|
599
|
+
// 111111 - indexed key, varint encoded index
|
600
|
+
// other - indexed key, inline encoded index
|
601
|
+
case 4:
|
602
|
+
if (*cur == 0x40) {
|
603
|
+
// literal key
|
604
|
+
return parse_lithdr_incidx_v(cur, end);
|
605
|
+
}
|
606
|
+
ABSL_FALLTHROUGH_INTENDED;
|
607
|
+
case 5:
|
608
|
+
case 6:
|
609
|
+
// inline encoded key index
|
610
|
+
return parse_lithdr_incidx(cur, end);
|
611
|
+
case 7:
|
612
|
+
if (*cur == 0x7f) {
|
613
|
+
// varint encoded key index
|
614
|
+
return parse_lithdr_incidx_x(cur, end);
|
615
|
+
} else {
|
616
|
+
// inline encoded key index
|
617
|
+
return parse_lithdr_incidx(cur, end);
|
618
|
+
}
|
619
|
+
// Indexed Header Field Representation
|
620
|
+
// First byte format: 1xxxxxxx
|
621
|
+
// Where xxxxxxx:
|
622
|
+
// 0000000 - illegal
|
623
|
+
// 1111111 - varint encoded field index
|
624
|
+
// other - inline encoded field index
|
625
|
+
case 8:
|
626
|
+
if (*cur == 0x80) {
|
627
|
+
// illegal value.
|
628
|
+
return parse_illegal_op(cur, end);
|
629
|
+
}
|
630
|
+
ABSL_FALLTHROUGH_INTENDED;
|
631
|
+
case 9:
|
632
|
+
case 10:
|
633
|
+
case 11:
|
634
|
+
case 12:
|
635
|
+
case 13:
|
636
|
+
case 14:
|
637
|
+
// inline encoded field index
|
638
|
+
return parse_indexed_field(cur, end);
|
639
|
+
case 15:
|
640
|
+
if (*cur == 0xff) {
|
641
|
+
// varint encoded field index
|
642
|
+
return parse_indexed_field_x(cur, end);
|
643
|
+
} else {
|
644
|
+
// inline encoded field index
|
645
|
+
return parse_indexed_field(cur, end);
|
646
|
+
}
|
647
|
+
}
|
648
|
+
GPR_UNREACHABLE_CODE(abort());
|
723
649
|
}
|
724
650
|
|
725
651
|
/* stream dependency and prioritization data: we just skip it */
|
726
|
-
|
727
|
-
|
728
|
-
const uint8_t* end) {
|
652
|
+
grpc_error_handle HPackParser::parse_stream_weight(const uint8_t* cur,
|
653
|
+
const uint8_t* end) {
|
729
654
|
if (cur == end) {
|
730
|
-
|
655
|
+
state_ = &HPackParser::parse_stream_weight;
|
731
656
|
return GRPC_ERROR_NONE;
|
732
657
|
}
|
733
658
|
|
734
|
-
return
|
659
|
+
return (this->*after_prioritization_)(cur + 1, end);
|
735
660
|
}
|
736
661
|
|
737
|
-
|
738
|
-
|
739
|
-
const uint8_t* end) {
|
662
|
+
grpc_error_handle HPackParser::parse_stream_dep3(const uint8_t* cur,
|
663
|
+
const uint8_t* end) {
|
740
664
|
if (cur == end) {
|
741
|
-
|
665
|
+
state_ = &HPackParser::parse_stream_dep3;
|
742
666
|
return GRPC_ERROR_NONE;
|
743
667
|
}
|
744
668
|
|
745
|
-
return parse_stream_weight(
|
669
|
+
return parse_stream_weight(cur + 1, end);
|
746
670
|
}
|
747
671
|
|
748
|
-
|
749
|
-
|
750
|
-
const uint8_t* end) {
|
672
|
+
grpc_error_handle HPackParser::parse_stream_dep2(const uint8_t* cur,
|
673
|
+
const uint8_t* end) {
|
751
674
|
if (cur == end) {
|
752
|
-
|
675
|
+
state_ = &HPackParser::parse_stream_dep2;
|
753
676
|
return GRPC_ERROR_NONE;
|
754
677
|
}
|
755
678
|
|
756
|
-
return parse_stream_dep3(
|
679
|
+
return parse_stream_dep3(cur + 1, end);
|
757
680
|
}
|
758
681
|
|
759
|
-
|
760
|
-
|
761
|
-
const uint8_t* end) {
|
682
|
+
grpc_error_handle HPackParser::parse_stream_dep1(const uint8_t* cur,
|
683
|
+
const uint8_t* end) {
|
762
684
|
if (cur == end) {
|
763
|
-
|
685
|
+
state_ = &HPackParser::parse_stream_dep1;
|
764
686
|
return GRPC_ERROR_NONE;
|
765
687
|
}
|
766
688
|
|
767
|
-
return parse_stream_dep2(
|
689
|
+
return parse_stream_dep2(cur + 1, end);
|
768
690
|
}
|
769
691
|
|
770
|
-
|
771
|
-
|
772
|
-
const uint8_t* end) {
|
692
|
+
grpc_error_handle HPackParser::parse_stream_dep0(const uint8_t* cur,
|
693
|
+
const uint8_t* end) {
|
773
694
|
if (cur == end) {
|
774
|
-
|
695
|
+
state_ = &HPackParser::parse_stream_dep0;
|
775
696
|
return GRPC_ERROR_NONE;
|
776
697
|
}
|
777
698
|
|
778
|
-
return parse_stream_dep1(
|
699
|
+
return parse_stream_dep1(cur + 1, end);
|
779
700
|
}
|
780
701
|
|
781
|
-
|
782
|
-
on_invalid_hpack_idx(grpc_chttp2_hpack_parser* p) {
|
702
|
+
grpc_error_handle HPackParser::InvalidHPackIndexError() {
|
783
703
|
return grpc_error_set_int(
|
784
704
|
grpc_error_set_int(
|
785
705
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid HPACK index received"),
|
786
|
-
GRPC_ERROR_INT_INDEX, static_cast<intptr_t>(
|
787
|
-
GRPC_ERROR_INT_SIZE, static_cast<intptr_t>(
|
706
|
+
GRPC_ERROR_INT_INDEX, static_cast<intptr_t>(index_)),
|
707
|
+
GRPC_ERROR_INT_SIZE, static_cast<intptr_t>(table_.num_ents));
|
788
708
|
}
|
789
709
|
|
790
710
|
/* emit an indexed field; jumps to begin the next field on completion */
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
grpc_mdelem md = grpc_chttp2_hptbl_lookup<true>(&p->table, p->index);
|
711
|
+
grpc_error_handle HPackParser::finish_indexed_field(const uint8_t* cur,
|
712
|
+
const uint8_t* end) {
|
713
|
+
grpc_mdelem md = grpc_chttp2_hptbl_lookup<true>(&table_, index_);
|
795
714
|
if (GPR_UNLIKELY(GRPC_MDISNULL(md))) {
|
796
|
-
return
|
715
|
+
return InvalidHPackIndexError();
|
797
716
|
}
|
798
717
|
GRPC_STATS_INC_HPACK_RECV_INDEXED();
|
799
|
-
grpc_error_handle err =
|
718
|
+
grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(md);
|
800
719
|
if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
|
801
|
-
return parse_begin(
|
720
|
+
return parse_begin(cur, end);
|
802
721
|
}
|
803
722
|
|
804
723
|
/* parse an indexed field with index < 127 */
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
return finish_indexed_field(p, cur + 1, end);
|
724
|
+
grpc_error_handle HPackParser::parse_indexed_field(const uint8_t* cur,
|
725
|
+
const uint8_t* end) {
|
726
|
+
dynamic_table_updates_allowed_ = 0;
|
727
|
+
index_ = (*cur) & 0x7f;
|
728
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
729
|
+
return finish_indexed_field(cur + 1, end);
|
812
730
|
}
|
813
731
|
|
814
732
|
/* parse an indexed field with index >= 127 */
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
p->parsing.value = &p->index;
|
825
|
-
return parse_value0(p, cur + 1, end);
|
733
|
+
grpc_error_handle HPackParser::parse_indexed_field_x(const uint8_t* cur,
|
734
|
+
const uint8_t* end) {
|
735
|
+
static const State and_then[] = {&HPackParser::finish_indexed_field};
|
736
|
+
dynamic_table_updates_allowed_ = 0;
|
737
|
+
next_state_ = and_then;
|
738
|
+
index_ = 0x7f;
|
739
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
740
|
+
parsing_.value = &index_;
|
741
|
+
return parse_value0(cur + 1, end);
|
826
742
|
}
|
827
743
|
|
828
744
|
/* When finishing with a header, get the cached md element for this index.
|
829
745
|
This is set in parse_value_string(). We ensure (in debug mode) that the
|
830
746
|
cached metadata corresponds with the index we are examining. */
|
831
|
-
|
832
|
-
GPR_DEBUG_ASSERT(
|
833
|
-
GPR_DEBUG_ASSERT(static_cast<int64_t>(
|
834
|
-
grpc_mdelem md =
|
747
|
+
grpc_mdelem HPackParser::GetPrecomputedMDForIndex() {
|
748
|
+
GPR_DEBUG_ASSERT(md_for_index_.payload != 0);
|
749
|
+
GPR_DEBUG_ASSERT(static_cast<int64_t>(index_) == precomputed_md_index_);
|
750
|
+
grpc_mdelem md = md_for_index_;
|
835
751
|
GPR_DEBUG_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
|
836
|
-
|
752
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
837
753
|
#ifndef NDEBUG
|
838
|
-
|
754
|
+
precomputed_md_index_ = -1;
|
839
755
|
#endif
|
840
756
|
return md;
|
841
757
|
}
|
@@ -847,359 +763,340 @@ static const grpc_core::ManagedMemorySlice& get_indexed_key(grpc_mdelem md) {
|
|
847
763
|
}
|
848
764
|
|
849
765
|
/* finish a literal header with incremental indexing */
|
850
|
-
|
851
|
-
|
852
|
-
const uint8_t* end) {
|
766
|
+
grpc_error_handle HPackParser::finish_lithdr_incidx(const uint8_t* cur,
|
767
|
+
const uint8_t* end) {
|
853
768
|
GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX();
|
854
|
-
grpc_mdelem md =
|
855
|
-
grpc_error_handle err =
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
return parse_begin(p, cur, end);
|
769
|
+
grpc_mdelem md = GetPrecomputedMDForIndex();
|
770
|
+
grpc_error_handle err = FinishHeader<TableAction::kAddToTable>(
|
771
|
+
grpc_mdelem_from_slices(get_indexed_key(md), value_.TakeIntern()));
|
772
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
773
|
+
return parse_begin(cur, end);
|
860
774
|
}
|
861
775
|
|
862
776
|
/* finish a literal header with incremental indexing with no index */
|
863
|
-
|
864
|
-
|
865
|
-
const uint8_t* end) {
|
777
|
+
grpc_error_handle HPackParser::finish_lithdr_incidx_v(const uint8_t* cur,
|
778
|
+
const uint8_t* end) {
|
866
779
|
GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V();
|
867
|
-
grpc_error_handle err =
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
return parse_begin(p, cur, end);
|
780
|
+
grpc_error_handle err = FinishHeader<TableAction::kAddToTable>(
|
781
|
+
grpc_mdelem_from_slices(key_.TakeIntern(), value_.TakeIntern()));
|
782
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
783
|
+
return parse_begin(cur, end);
|
872
784
|
}
|
873
785
|
|
874
786
|
/* parse a literal header with incremental indexing; index < 63 */
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
return parse_string_prefix(
|
787
|
+
grpc_error_handle HPackParser::parse_lithdr_incidx(const uint8_t* cur,
|
788
|
+
const uint8_t* end) {
|
789
|
+
static const State and_then[] = {
|
790
|
+
&HPackParser::parse_value_string_with_indexed_key,
|
791
|
+
&HPackParser::finish_lithdr_incidx};
|
792
|
+
dynamic_table_updates_allowed_ = 0;
|
793
|
+
next_state_ = and_then;
|
794
|
+
index_ = (*cur) & 0x3f;
|
795
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
796
|
+
return parse_string_prefix(cur + 1, end);
|
885
797
|
}
|
886
798
|
|
887
799
|
/* parse a literal header with incremental indexing; index >= 63 */
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
finish_lithdr_incidx};
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
return parse_value0(
|
800
|
+
grpc_error_handle HPackParser::parse_lithdr_incidx_x(const uint8_t* cur,
|
801
|
+
const uint8_t* end) {
|
802
|
+
static const State and_then[] = {
|
803
|
+
&HPackParser::parse_string_prefix,
|
804
|
+
&HPackParser::parse_value_string_with_indexed_key,
|
805
|
+
&HPackParser::finish_lithdr_incidx};
|
806
|
+
dynamic_table_updates_allowed_ = 0;
|
807
|
+
next_state_ = and_then;
|
808
|
+
index_ = 0x3f;
|
809
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
810
|
+
parsing_.value = &index_;
|
811
|
+
return parse_value0(cur + 1, end);
|
900
812
|
}
|
901
813
|
|
902
814
|
/* parse a literal header with incremental indexing; index = 0 */
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
return parse_string_prefix(
|
815
|
+
grpc_error_handle HPackParser::parse_lithdr_incidx_v(const uint8_t* cur,
|
816
|
+
const uint8_t* end) {
|
817
|
+
static const State and_then[] = {
|
818
|
+
&HPackParser::parse_key_string, &HPackParser::parse_string_prefix,
|
819
|
+
&HPackParser::parse_value_string_with_literal_key,
|
820
|
+
&HPackParser::finish_lithdr_incidx_v};
|
821
|
+
dynamic_table_updates_allowed_ = 0;
|
822
|
+
next_state_ = and_then;
|
823
|
+
return parse_string_prefix(cur + 1, end);
|
912
824
|
}
|
913
825
|
|
914
826
|
/* finish a literal header without incremental indexing */
|
915
|
-
|
916
|
-
|
917
|
-
const uint8_t* end) {
|
827
|
+
grpc_error_handle HPackParser::finish_lithdr_notidx(const uint8_t* cur,
|
828
|
+
const uint8_t* end) {
|
918
829
|
GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX();
|
919
|
-
grpc_mdelem md =
|
920
|
-
grpc_error_handle err =
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
return parse_begin(p, cur, end);
|
830
|
+
grpc_mdelem md = GetPrecomputedMDForIndex();
|
831
|
+
grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
|
832
|
+
grpc_mdelem_from_slices(get_indexed_key(md), value_.TakeExtern()));
|
833
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
834
|
+
return parse_begin(cur, end);
|
925
835
|
}
|
926
836
|
|
927
837
|
/* finish a literal header without incremental indexing with index = 0 */
|
928
|
-
|
929
|
-
|
930
|
-
const uint8_t* end) {
|
838
|
+
grpc_error_handle HPackParser::finish_lithdr_notidx_v(const uint8_t* cur,
|
839
|
+
const uint8_t* end) {
|
931
840
|
GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V();
|
932
|
-
grpc_error_handle err =
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
return parse_begin(p, cur, end);
|
841
|
+
grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
|
842
|
+
grpc_mdelem_from_slices(key_.TakeIntern(), value_.TakeExtern()));
|
843
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
844
|
+
return parse_begin(cur, end);
|
937
845
|
}
|
938
846
|
|
939
847
|
/* parse a literal header without incremental indexing; index < 15 */
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
return parse_string_prefix(
|
848
|
+
grpc_error_handle HPackParser::parse_lithdr_notidx(const uint8_t* cur,
|
849
|
+
const uint8_t* end) {
|
850
|
+
static const State and_then[] = {
|
851
|
+
&HPackParser::parse_value_string_with_indexed_key,
|
852
|
+
&HPackParser::finish_lithdr_notidx};
|
853
|
+
dynamic_table_updates_allowed_ = 0;
|
854
|
+
next_state_ = and_then;
|
855
|
+
index_ = (*cur) & 0xf;
|
856
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
857
|
+
return parse_string_prefix(cur + 1, end);
|
950
858
|
}
|
951
859
|
|
952
860
|
/* parse a literal header without incremental indexing; index >= 15 */
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
finish_lithdr_notidx};
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
return parse_value0(
|
861
|
+
grpc_error_handle HPackParser::parse_lithdr_notidx_x(const uint8_t* cur,
|
862
|
+
const uint8_t* end) {
|
863
|
+
static const State and_then[] = {
|
864
|
+
&HPackParser::parse_string_prefix,
|
865
|
+
&HPackParser::parse_value_string_with_indexed_key,
|
866
|
+
&HPackParser::finish_lithdr_notidx};
|
867
|
+
dynamic_table_updates_allowed_ = 0;
|
868
|
+
next_state_ = and_then;
|
869
|
+
index_ = 0xf;
|
870
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
871
|
+
parsing_.value = &index_;
|
872
|
+
return parse_value0(cur + 1, end);
|
965
873
|
}
|
966
874
|
|
967
875
|
/* parse a literal header without incremental indexing; index == 0 */
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
return parse_string_prefix(
|
876
|
+
grpc_error_handle HPackParser::parse_lithdr_notidx_v(const uint8_t* cur,
|
877
|
+
const uint8_t* end) {
|
878
|
+
static const State and_then[] = {
|
879
|
+
&HPackParser::parse_key_string, &HPackParser::parse_string_prefix,
|
880
|
+
&HPackParser::parse_value_string_with_literal_key,
|
881
|
+
&HPackParser::finish_lithdr_notidx_v};
|
882
|
+
dynamic_table_updates_allowed_ = 0;
|
883
|
+
next_state_ = and_then;
|
884
|
+
return parse_string_prefix(cur + 1, end);
|
977
885
|
}
|
978
886
|
|
979
887
|
/* finish a literal header that is never indexed */
|
980
|
-
|
981
|
-
|
982
|
-
const uint8_t* end) {
|
888
|
+
grpc_error_handle HPackParser::finish_lithdr_nvridx(const uint8_t* cur,
|
889
|
+
const uint8_t* end) {
|
983
890
|
GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX();
|
984
|
-
grpc_mdelem md =
|
985
|
-
grpc_error_handle err =
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
return parse_begin(p, cur, end);
|
891
|
+
grpc_mdelem md = GetPrecomputedMDForIndex();
|
892
|
+
grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
|
893
|
+
grpc_mdelem_from_slices(get_indexed_key(md), value_.TakeExtern()));
|
894
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
895
|
+
return parse_begin(cur, end);
|
990
896
|
}
|
991
897
|
|
992
898
|
/* finish a literal header that is never indexed with an extra value */
|
993
|
-
|
994
|
-
|
995
|
-
const uint8_t* end) {
|
899
|
+
grpc_error_handle HPackParser::finish_lithdr_nvridx_v(const uint8_t* cur,
|
900
|
+
const uint8_t* end) {
|
996
901
|
GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V();
|
997
|
-
grpc_error_handle err =
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
return parse_begin(p, cur, end);
|
902
|
+
grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
|
903
|
+
grpc_mdelem_from_slices(key_.TakeIntern(), value_.TakeExtern()));
|
904
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
905
|
+
return parse_begin(cur, end);
|
1002
906
|
}
|
1003
907
|
|
1004
908
|
/* parse a literal header that is never indexed; index < 15 */
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
return parse_string_prefix(
|
909
|
+
grpc_error_handle HPackParser::parse_lithdr_nvridx(const uint8_t* cur,
|
910
|
+
const uint8_t* end) {
|
911
|
+
static const State and_then[] = {
|
912
|
+
&HPackParser::parse_value_string_with_indexed_key,
|
913
|
+
&HPackParser::finish_lithdr_nvridx};
|
914
|
+
dynamic_table_updates_allowed_ = 0;
|
915
|
+
next_state_ = and_then;
|
916
|
+
index_ = (*cur) & 0xf;
|
917
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
918
|
+
return parse_string_prefix(cur + 1, end);
|
1015
919
|
}
|
1016
920
|
|
1017
921
|
/* parse a literal header that is never indexed; index >= 15 */
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
finish_lithdr_nvridx};
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
return parse_value0(
|
922
|
+
grpc_error_handle HPackParser::parse_lithdr_nvridx_x(const uint8_t* cur,
|
923
|
+
const uint8_t* end) {
|
924
|
+
static const State and_then[] = {
|
925
|
+
&HPackParser::parse_string_prefix,
|
926
|
+
&HPackParser::parse_value_string_with_indexed_key,
|
927
|
+
&HPackParser::finish_lithdr_nvridx};
|
928
|
+
dynamic_table_updates_allowed_ = 0;
|
929
|
+
next_state_ = and_then;
|
930
|
+
index_ = 0xf;
|
931
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
932
|
+
parsing_.value = &index_;
|
933
|
+
return parse_value0(cur + 1, end);
|
1030
934
|
}
|
1031
935
|
|
1032
936
|
/* parse a literal header that is never indexed; index == 0 */
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
return parse_string_prefix(
|
937
|
+
grpc_error_handle HPackParser::parse_lithdr_nvridx_v(const uint8_t* cur,
|
938
|
+
const uint8_t* end) {
|
939
|
+
static const State and_then[] = {
|
940
|
+
&HPackParser::parse_key_string, &HPackParser::parse_string_prefix,
|
941
|
+
&HPackParser::parse_value_string_with_literal_key,
|
942
|
+
&HPackParser::finish_lithdr_nvridx_v};
|
943
|
+
dynamic_table_updates_allowed_ = 0;
|
944
|
+
next_state_ = and_then;
|
945
|
+
return parse_string_prefix(cur + 1, end);
|
1042
946
|
}
|
1043
947
|
|
1044
948
|
/* finish parsing a max table size change */
|
1045
|
-
|
1046
|
-
|
1047
|
-
const uint8_t* end) {
|
949
|
+
grpc_error_handle HPackParser::finish_max_tbl_size(const uint8_t* cur,
|
950
|
+
const uint8_t* end) {
|
1048
951
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_hpack_parser)) {
|
1049
|
-
gpr_log(GPR_INFO, "MAX TABLE SIZE: %d",
|
952
|
+
gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", index_);
|
1050
953
|
}
|
1051
954
|
grpc_error_handle err =
|
1052
|
-
grpc_chttp2_hptbl_set_current_table_size(&
|
1053
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1054
|
-
return parse_begin(
|
955
|
+
grpc_chttp2_hptbl_set_current_table_size(&table_, index_);
|
956
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
957
|
+
return parse_begin(cur, end);
|
1055
958
|
}
|
1056
959
|
|
1057
960
|
/* parse a max table size change, max size < 15 */
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
if (p->dynamic_table_update_allowed == 0) {
|
961
|
+
grpc_error_handle HPackParser::parse_max_tbl_size(const uint8_t* cur,
|
962
|
+
const uint8_t* end) {
|
963
|
+
if (dynamic_table_updates_allowed_ == 0) {
|
1062
964
|
return parse_error(
|
1063
|
-
|
965
|
+
cur, end,
|
1064
966
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1065
967
|
"More than two max table size changes in a single frame"));
|
1066
968
|
}
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
return finish_max_tbl_size(
|
969
|
+
dynamic_table_updates_allowed_--;
|
970
|
+
index_ = (*cur) & 0x1f;
|
971
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
972
|
+
return finish_max_tbl_size(cur + 1, end);
|
1071
973
|
}
|
1072
974
|
|
1073
975
|
/* parse a max table size change, max size >= 15 */
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
finish_max_tbl_size};
|
1079
|
-
if (p->dynamic_table_update_allowed == 0) {
|
976
|
+
grpc_error_handle HPackParser::parse_max_tbl_size_x(const uint8_t* cur,
|
977
|
+
const uint8_t* end) {
|
978
|
+
static const State and_then[] = {&HPackParser::finish_max_tbl_size};
|
979
|
+
if (dynamic_table_updates_allowed_ == 0) {
|
1080
980
|
return parse_error(
|
1081
|
-
|
981
|
+
cur, end,
|
1082
982
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1083
983
|
"More than two max table size changes in a single frame"));
|
1084
984
|
}
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
return parse_value0(
|
985
|
+
dynamic_table_updates_allowed_--;
|
986
|
+
next_state_ = and_then;
|
987
|
+
index_ = 0x1f;
|
988
|
+
md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
|
989
|
+
parsing_.value = &index_;
|
990
|
+
return parse_value0(cur + 1, end);
|
1091
991
|
}
|
1092
992
|
|
1093
993
|
/* a parse error: jam the parse state into parse_error, and return error */
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
grpc_error_handle err) {
|
994
|
+
grpc_error_handle HPackParser::parse_error(const uint8_t* /*cur*/,
|
995
|
+
const uint8_t* /*end*/,
|
996
|
+
grpc_error_handle err) {
|
1098
997
|
GPR_ASSERT(err != GRPC_ERROR_NONE);
|
1099
|
-
if (
|
1100
|
-
|
998
|
+
if (last_error_ == GRPC_ERROR_NONE) {
|
999
|
+
last_error_ = GRPC_ERROR_REF(err);
|
1101
1000
|
}
|
1102
|
-
|
1001
|
+
state_ = &HPackParser::still_parse_error;
|
1103
1002
|
return err;
|
1104
1003
|
}
|
1105
1004
|
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
return GRPC_ERROR_REF(p->last_error);
|
1005
|
+
grpc_error_handle HPackParser::still_parse_error(const uint8_t* /*cur*/,
|
1006
|
+
const uint8_t* /*end*/) {
|
1007
|
+
return GRPC_ERROR_REF(last_error_);
|
1110
1008
|
}
|
1111
1009
|
|
1112
|
-
|
1113
|
-
|
1114
|
-
const uint8_t* end) {
|
1010
|
+
grpc_error_handle HPackParser::parse_illegal_op(const uint8_t* cur,
|
1011
|
+
const uint8_t* end) {
|
1115
1012
|
GPR_ASSERT(cur != end);
|
1116
1013
|
grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
1117
1014
|
absl::StrCat("Illegal hpack op code ", *cur).c_str());
|
1118
|
-
return parse_error(
|
1015
|
+
return parse_error(cur, end, err);
|
1119
1016
|
}
|
1120
1017
|
|
1121
|
-
/* parse the 1st byte of a varint into
|
1018
|
+
/* parse the 1st byte of a varint into parsing_.value
|
1122
1019
|
no overflow is possible */
|
1123
|
-
|
1124
|
-
|
1020
|
+
grpc_error_handle HPackParser::parse_value0(const uint8_t* cur,
|
1021
|
+
const uint8_t* end) {
|
1125
1022
|
if (cur == end) {
|
1126
|
-
|
1023
|
+
state_ = &HPackParser::parse_value0;
|
1127
1024
|
return GRPC_ERROR_NONE;
|
1128
1025
|
}
|
1129
1026
|
|
1130
|
-
*
|
1027
|
+
*parsing_.value += (*cur) & 0x7f;
|
1131
1028
|
|
1132
1029
|
if ((*cur) & 0x80) {
|
1133
|
-
return parse_value1(
|
1030
|
+
return parse_value1(cur + 1, end);
|
1134
1031
|
} else {
|
1135
|
-
return parse_next(
|
1032
|
+
return parse_next(cur + 1, end);
|
1136
1033
|
}
|
1137
1034
|
}
|
1138
1035
|
|
1139
|
-
/* parse the 2nd byte of a varint into
|
1036
|
+
/* parse the 2nd byte of a varint into parsing_.value
|
1140
1037
|
no overflow is possible */
|
1141
|
-
|
1142
|
-
|
1038
|
+
grpc_error_handle HPackParser::parse_value1(const uint8_t* cur,
|
1039
|
+
const uint8_t* end) {
|
1143
1040
|
if (cur == end) {
|
1144
|
-
|
1041
|
+
state_ = &HPackParser::parse_value1;
|
1145
1042
|
return GRPC_ERROR_NONE;
|
1146
1043
|
}
|
1147
1044
|
|
1148
|
-
*
|
1045
|
+
*parsing_.value += ((static_cast<uint32_t>(*cur)) & 0x7f) << 7;
|
1149
1046
|
|
1150
1047
|
if ((*cur) & 0x80) {
|
1151
|
-
return parse_value2(
|
1048
|
+
return parse_value2(cur + 1, end);
|
1152
1049
|
} else {
|
1153
|
-
return parse_next(
|
1050
|
+
return parse_next(cur + 1, end);
|
1154
1051
|
}
|
1155
1052
|
}
|
1156
1053
|
|
1157
|
-
/* parse the 3rd byte of a varint into
|
1054
|
+
/* parse the 3rd byte of a varint into parsing_.value
|
1158
1055
|
no overflow is possible */
|
1159
|
-
|
1160
|
-
|
1056
|
+
grpc_error_handle HPackParser::parse_value2(const uint8_t* cur,
|
1057
|
+
const uint8_t* end) {
|
1161
1058
|
if (cur == end) {
|
1162
|
-
|
1059
|
+
state_ = &HPackParser::parse_value2;
|
1163
1060
|
return GRPC_ERROR_NONE;
|
1164
1061
|
}
|
1165
1062
|
|
1166
|
-
*
|
1063
|
+
*parsing_.value += ((static_cast<uint32_t>(*cur)) & 0x7f) << 14;
|
1167
1064
|
|
1168
1065
|
if ((*cur) & 0x80) {
|
1169
|
-
return parse_value3(
|
1066
|
+
return parse_value3(cur + 1, end);
|
1170
1067
|
} else {
|
1171
|
-
return parse_next(
|
1068
|
+
return parse_next(cur + 1, end);
|
1172
1069
|
}
|
1173
1070
|
}
|
1174
1071
|
|
1175
|
-
/* parse the 4th byte of a varint into
|
1072
|
+
/* parse the 4th byte of a varint into parsing_.value
|
1176
1073
|
no overflow is possible */
|
1177
|
-
|
1178
|
-
|
1074
|
+
grpc_error_handle HPackParser::parse_value3(const uint8_t* cur,
|
1075
|
+
const uint8_t* end) {
|
1179
1076
|
if (cur == end) {
|
1180
|
-
|
1077
|
+
state_ = &HPackParser::parse_value3;
|
1181
1078
|
return GRPC_ERROR_NONE;
|
1182
1079
|
}
|
1183
1080
|
|
1184
|
-
*
|
1081
|
+
*parsing_.value += ((static_cast<uint32_t>(*cur)) & 0x7f) << 21;
|
1185
1082
|
|
1186
1083
|
if ((*cur) & 0x80) {
|
1187
|
-
return parse_value4(
|
1084
|
+
return parse_value4(cur + 1, end);
|
1188
1085
|
} else {
|
1189
|
-
return parse_next(
|
1086
|
+
return parse_next(cur + 1, end);
|
1190
1087
|
}
|
1191
1088
|
}
|
1192
1089
|
|
1193
|
-
/* parse the 5th byte of a varint into
|
1090
|
+
/* parse the 5th byte of a varint into parsing_.value
|
1194
1091
|
depending on the byte, we may overflow, and care must be taken */
|
1195
|
-
|
1196
|
-
|
1092
|
+
grpc_error_handle HPackParser::parse_value4(const uint8_t* cur,
|
1093
|
+
const uint8_t* end) {
|
1197
1094
|
uint8_t c;
|
1198
1095
|
uint32_t cur_value;
|
1199
1096
|
uint32_t add_value;
|
1200
1097
|
|
1201
1098
|
if (cur == end) {
|
1202
|
-
|
1099
|
+
state_ = &HPackParser::parse_value4;
|
1203
1100
|
return GRPC_ERROR_NONE;
|
1204
1101
|
}
|
1205
1102
|
|
@@ -1208,18 +1105,18 @@ static grpc_error_handle parse_value4(grpc_chttp2_hpack_parser* p,
|
|
1208
1105
|
goto error;
|
1209
1106
|
}
|
1210
1107
|
|
1211
|
-
cur_value = *
|
1108
|
+
cur_value = *parsing_.value;
|
1212
1109
|
add_value = (static_cast<uint32_t>(c)) << 28;
|
1213
1110
|
if (add_value > 0xffffffffu - cur_value) {
|
1214
1111
|
goto error;
|
1215
1112
|
}
|
1216
1113
|
|
1217
|
-
*
|
1114
|
+
*parsing_.value = cur_value + add_value;
|
1218
1115
|
|
1219
1116
|
if ((*cur) & 0x80) {
|
1220
|
-
return parse_value5up(
|
1117
|
+
return parse_value5up(cur + 1, end);
|
1221
1118
|
} else {
|
1222
|
-
return parse_next(
|
1119
|
+
return parse_next(cur + 1, end);
|
1223
1120
|
}
|
1224
1121
|
|
1225
1122
|
error:
|
@@ -1227,354 +1124,347 @@ error:
|
|
1227
1124
|
absl::StrFormat(
|
1228
1125
|
"integer overflow in hpack integer decoding: have 0x%08x, "
|
1229
1126
|
"got byte 0x%02x on byte 5",
|
1230
|
-
*
|
1127
|
+
*parsing_.value, *cur)
|
1231
1128
|
.c_str());
|
1232
|
-
return parse_error(
|
1129
|
+
return parse_error(cur, end, err);
|
1233
1130
|
}
|
1234
1131
|
|
1235
1132
|
/* parse any trailing bytes in a varint: it's possible to append an arbitrary
|
1236
1133
|
number of 0x80's and not affect the value - a zero will terminate - and
|
1237
1134
|
anything else will overflow */
|
1238
|
-
|
1239
|
-
|
1240
|
-
const uint8_t* end) {
|
1135
|
+
grpc_error_handle HPackParser::parse_value5up(const uint8_t* cur,
|
1136
|
+
const uint8_t* end) {
|
1241
1137
|
while (cur != end && *cur == 0x80) {
|
1242
1138
|
++cur;
|
1243
1139
|
}
|
1244
1140
|
|
1245
1141
|
if (cur == end) {
|
1246
|
-
|
1142
|
+
state_ = &HPackParser::parse_value5up;
|
1247
1143
|
return GRPC_ERROR_NONE;
|
1248
1144
|
}
|
1249
1145
|
|
1250
1146
|
if (*cur == 0) {
|
1251
|
-
return parse_next(
|
1147
|
+
return parse_next(cur + 1, end);
|
1252
1148
|
}
|
1253
1149
|
|
1254
1150
|
grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
1255
1151
|
absl::StrFormat(
|
1256
1152
|
"integer overflow in hpack integer decoding: have 0x%08x, "
|
1257
1153
|
"got byte 0x%02x sometime after byte 5",
|
1258
|
-
*
|
1154
|
+
*parsing_.value, *cur)
|
1259
1155
|
.c_str());
|
1260
|
-
return parse_error(
|
1156
|
+
return parse_error(cur, end, err);
|
1261
1157
|
}
|
1262
1158
|
|
1263
1159
|
/* parse a string prefix */
|
1264
|
-
|
1265
|
-
|
1266
|
-
const uint8_t* end) {
|
1160
|
+
grpc_error_handle HPackParser::parse_string_prefix(const uint8_t* cur,
|
1161
|
+
const uint8_t* end) {
|
1267
1162
|
if (cur == end) {
|
1268
|
-
|
1163
|
+
state_ = &HPackParser::parse_string_prefix;
|
1269
1164
|
return GRPC_ERROR_NONE;
|
1270
1165
|
}
|
1271
1166
|
|
1272
|
-
|
1273
|
-
|
1274
|
-
if (
|
1275
|
-
|
1276
|
-
return parse_value0(
|
1167
|
+
strlen_ = (*cur) & 0x7f;
|
1168
|
+
huff_ = (*cur) >> 7;
|
1169
|
+
if (strlen_ == 0x7f) {
|
1170
|
+
parsing_.value = &strlen_;
|
1171
|
+
return parse_value0(cur + 1, end);
|
1277
1172
|
} else {
|
1278
|
-
return parse_next(
|
1173
|
+
return parse_next(cur + 1, end);
|
1279
1174
|
}
|
1280
1175
|
}
|
1281
1176
|
|
1282
1177
|
/* append some bytes to a string */
|
1283
|
-
|
1284
|
-
const uint8_t* data, size_t length) {
|
1178
|
+
void HPackParser::String::AppendBytes(const uint8_t* data, size_t length) {
|
1285
1179
|
if (length == 0) return;
|
1286
|
-
if (length +
|
1287
|
-
GPR_ASSERT(
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
gpr_realloc(str->data.copied.str, str->data.copied.capacity));
|
1180
|
+
if (length + data_.copied.length > data_.copied.capacity) {
|
1181
|
+
GPR_ASSERT(data_.copied.length + length <= UINT32_MAX);
|
1182
|
+
data_.copied.capacity = static_cast<uint32_t>(data_.copied.length + length);
|
1183
|
+
data_.copied.str = static_cast<char*>(
|
1184
|
+
gpr_realloc(data_.copied.str, data_.copied.capacity));
|
1292
1185
|
}
|
1293
|
-
memcpy(
|
1294
|
-
GPR_ASSERT(length <= UINT32_MAX -
|
1295
|
-
|
1186
|
+
memcpy(data_.copied.str + data_.copied.length, data, length);
|
1187
|
+
GPR_ASSERT(length <= UINT32_MAX - data_.copied.length);
|
1188
|
+
data_.copied.length += static_cast<uint32_t>(length);
|
1296
1189
|
}
|
1297
1190
|
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1191
|
+
grpc_error_handle HPackParser::AppendString(const uint8_t* cur,
|
1192
|
+
const uint8_t* end) {
|
1193
|
+
String* str = parsing_.str;
|
1301
1194
|
uint32_t bits;
|
1302
1195
|
uint8_t decoded[3];
|
1303
|
-
switch (
|
1304
|
-
case
|
1305
|
-
|
1196
|
+
switch (binary_) {
|
1197
|
+
case BinaryState::kNotBinary:
|
1198
|
+
str->AppendBytes(cur, static_cast<size_t>(end - cur));
|
1306
1199
|
return GRPC_ERROR_NONE;
|
1307
|
-
case
|
1200
|
+
case BinaryState::kBinaryBegin:
|
1308
1201
|
if (cur == end) {
|
1309
|
-
|
1202
|
+
binary_ = BinaryState::kBinaryBegin;
|
1310
1203
|
return GRPC_ERROR_NONE;
|
1311
1204
|
}
|
1312
1205
|
if (*cur == 0) {
|
1313
1206
|
/* 'true-binary' case */
|
1314
1207
|
++cur;
|
1315
|
-
|
1208
|
+
binary_ = BinaryState::kNotBinary;
|
1316
1209
|
GRPC_STATS_INC_HPACK_RECV_BINARY();
|
1317
|
-
|
1210
|
+
str->AppendBytes(cur, static_cast<size_t>(end - cur));
|
1318
1211
|
return GRPC_ERROR_NONE;
|
1319
1212
|
}
|
1320
1213
|
GRPC_STATS_INC_HPACK_RECV_BINARY_BASE64();
|
1321
|
-
/* fallthrough */
|
1322
1214
|
b64_byte0:
|
1323
|
-
|
1215
|
+
ABSL_FALLTHROUGH_INTENDED;
|
1216
|
+
case BinaryState::kBase64Byte0:
|
1324
1217
|
if (cur == end) {
|
1325
|
-
|
1218
|
+
binary_ = BinaryState::kBase64Byte0;
|
1326
1219
|
return GRPC_ERROR_NONE;
|
1327
1220
|
}
|
1328
|
-
bits =
|
1221
|
+
bits = kBase64InverseTable.table[*cur];
|
1329
1222
|
++cur;
|
1330
1223
|
if (bits == 255) {
|
1331
1224
|
return parse_error(
|
1332
|
-
|
1225
|
+
cur, end,
|
1333
1226
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
|
1334
1227
|
} else if (bits == 64) {
|
1335
1228
|
goto b64_byte0;
|
1336
1229
|
}
|
1337
|
-
|
1338
|
-
/* fallthrough */
|
1230
|
+
base64_buffer_ = bits << 18;
|
1339
1231
|
b64_byte1:
|
1340
|
-
|
1232
|
+
ABSL_FALLTHROUGH_INTENDED;
|
1233
|
+
case BinaryState::kBase64Byte1:
|
1341
1234
|
if (cur == end) {
|
1342
|
-
|
1235
|
+
binary_ = BinaryState::kBase64Byte1;
|
1343
1236
|
return GRPC_ERROR_NONE;
|
1344
1237
|
}
|
1345
|
-
bits =
|
1238
|
+
bits = kBase64InverseTable.table[*cur];
|
1346
1239
|
++cur;
|
1347
1240
|
if (bits == 255) {
|
1348
1241
|
return parse_error(
|
1349
|
-
|
1242
|
+
cur, end,
|
1350
1243
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
|
1351
1244
|
} else if (bits == 64) {
|
1352
1245
|
goto b64_byte1;
|
1353
1246
|
}
|
1354
|
-
|
1355
|
-
/* fallthrough */
|
1247
|
+
base64_buffer_ |= bits << 12;
|
1356
1248
|
b64_byte2:
|
1357
|
-
|
1249
|
+
ABSL_FALLTHROUGH_INTENDED;
|
1250
|
+
case BinaryState::kBase64Byte2:
|
1358
1251
|
if (cur == end) {
|
1359
|
-
|
1252
|
+
binary_ = BinaryState::kBase64Byte2;
|
1360
1253
|
return GRPC_ERROR_NONE;
|
1361
1254
|
}
|
1362
|
-
bits =
|
1255
|
+
bits = kBase64InverseTable.table[*cur];
|
1363
1256
|
++cur;
|
1364
1257
|
if (bits == 255) {
|
1365
1258
|
return parse_error(
|
1366
|
-
|
1259
|
+
cur, end,
|
1367
1260
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
|
1368
1261
|
} else if (bits == 64) {
|
1369
1262
|
goto b64_byte2;
|
1370
1263
|
}
|
1371
|
-
|
1372
|
-
/* fallthrough */
|
1264
|
+
base64_buffer_ |= bits << 6;
|
1373
1265
|
b64_byte3:
|
1374
|
-
|
1266
|
+
ABSL_FALLTHROUGH_INTENDED;
|
1267
|
+
case BinaryState::kBase64Byte3:
|
1375
1268
|
if (cur == end) {
|
1376
|
-
|
1269
|
+
binary_ = BinaryState::kBase64Byte3;
|
1377
1270
|
return GRPC_ERROR_NONE;
|
1378
1271
|
}
|
1379
|
-
bits =
|
1272
|
+
bits = kBase64InverseTable.table[*cur];
|
1380
1273
|
++cur;
|
1381
1274
|
if (bits == 255) {
|
1382
1275
|
return parse_error(
|
1383
|
-
|
1276
|
+
cur, end,
|
1384
1277
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
|
1385
1278
|
} else if (bits == 64) {
|
1386
1279
|
goto b64_byte3;
|
1387
1280
|
}
|
1388
|
-
|
1389
|
-
bits =
|
1281
|
+
base64_buffer_ |= bits;
|
1282
|
+
bits = base64_buffer_;
|
1390
1283
|
decoded[0] = static_cast<uint8_t>(bits >> 16);
|
1391
1284
|
decoded[1] = static_cast<uint8_t>(bits >> 8);
|
1392
1285
|
decoded[2] = static_cast<uint8_t>(bits);
|
1393
|
-
|
1286
|
+
str->AppendBytes(decoded, 3);
|
1394
1287
|
goto b64_byte0;
|
1395
1288
|
}
|
1396
1289
|
GPR_UNREACHABLE_CODE(return parse_error(
|
1397
|
-
|
1290
|
+
cur, end,
|
1398
1291
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here")));
|
1399
1292
|
}
|
1400
1293
|
|
1401
|
-
|
1402
|
-
|
1294
|
+
grpc_error_handle HPackParser::finish_str(const uint8_t* cur,
|
1295
|
+
const uint8_t* end) {
|
1403
1296
|
uint8_t decoded[2];
|
1404
1297
|
uint32_t bits;
|
1405
|
-
|
1406
|
-
switch (
|
1407
|
-
case
|
1298
|
+
String* str = parsing_.str;
|
1299
|
+
switch (binary_) {
|
1300
|
+
case BinaryState::kNotBinary:
|
1408
1301
|
break;
|
1409
|
-
case
|
1302
|
+
case BinaryState::kBinaryBegin:
|
1410
1303
|
break;
|
1411
|
-
case
|
1304
|
+
case BinaryState::kBase64Byte0:
|
1412
1305
|
break;
|
1413
|
-
case
|
1414
|
-
return parse_error(
|
1306
|
+
case BinaryState::kBase64Byte1:
|
1307
|
+
return parse_error(cur, end,
|
1415
1308
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1416
1309
|
"illegal base64 encoding")); /* illegal encoding */
|
1417
|
-
case
|
1418
|
-
bits =
|
1310
|
+
case BinaryState::kBase64Byte2:
|
1311
|
+
bits = base64_buffer_;
|
1419
1312
|
if (bits & 0xffff) {
|
1420
1313
|
grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
1421
1314
|
absl::StrFormat("trailing bits in base64 encoding: 0x%04x",
|
1422
1315
|
bits & 0xffff)
|
1423
1316
|
.c_str());
|
1424
|
-
return parse_error(
|
1317
|
+
return parse_error(cur, end, err);
|
1425
1318
|
}
|
1426
1319
|
decoded[0] = static_cast<uint8_t>(bits >> 16);
|
1427
|
-
|
1320
|
+
str->AppendBytes(decoded, 1);
|
1428
1321
|
break;
|
1429
|
-
case
|
1430
|
-
bits =
|
1322
|
+
case BinaryState::kBase64Byte3:
|
1323
|
+
bits = base64_buffer_;
|
1431
1324
|
if (bits & 0xff) {
|
1432
1325
|
grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
1433
1326
|
absl::StrFormat("trailing bits in base64 encoding: 0x%02x",
|
1434
1327
|
bits & 0xff)
|
1435
1328
|
.c_str());
|
1436
|
-
return parse_error(
|
1329
|
+
return parse_error(cur, end, err);
|
1437
1330
|
}
|
1438
1331
|
decoded[0] = static_cast<uint8_t>(bits >> 16);
|
1439
1332
|
decoded[1] = static_cast<uint8_t>(bits >> 8);
|
1440
|
-
|
1333
|
+
str->AppendBytes(decoded, 2);
|
1441
1334
|
break;
|
1442
1335
|
}
|
1443
1336
|
return GRPC_ERROR_NONE;
|
1444
1337
|
}
|
1445
1338
|
|
1446
1339
|
/* decode a nibble from a huffman encoded stream */
|
1447
|
-
|
1448
|
-
|
1449
|
-
int16_t
|
1450
|
-
int16_t next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble];
|
1340
|
+
grpc_error_handle HPackParser::AppendHuffNibble(uint8_t nibble) {
|
1341
|
+
int16_t emit = emit_sub_tbl[16 * emit_tbl[huff_state_] + nibble];
|
1342
|
+
int16_t next = next_sub_tbl[16 * next_tbl[huff_state_] + nibble];
|
1451
1343
|
if (emit != -1) {
|
1452
1344
|
if (emit >= 0 && emit < 256) {
|
1453
1345
|
uint8_t c = static_cast<uint8_t>(emit);
|
1454
|
-
grpc_error_handle err =
|
1346
|
+
grpc_error_handle err = AppendString(&c, (&c) + 1);
|
1455
1347
|
if (err != GRPC_ERROR_NONE) return err;
|
1456
1348
|
} else {
|
1457
1349
|
assert(emit == 256);
|
1458
1350
|
}
|
1459
1351
|
}
|
1460
|
-
|
1352
|
+
huff_state_ = next;
|
1461
1353
|
return GRPC_ERROR_NONE;
|
1462
1354
|
}
|
1463
1355
|
|
1464
1356
|
/* decode full bytes from a huffman encoded stream */
|
1465
|
-
|
1466
|
-
|
1467
|
-
const uint8_t* end) {
|
1357
|
+
grpc_error_handle HPackParser::AppendHuffBytes(const uint8_t* cur,
|
1358
|
+
const uint8_t* end) {
|
1468
1359
|
for (; cur != end; ++cur) {
|
1469
|
-
grpc_error_handle err =
|
1470
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1471
|
-
err =
|
1472
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1360
|
+
grpc_error_handle err = AppendHuffNibble(*cur >> 4);
|
1361
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
1362
|
+
err = AppendHuffNibble(*cur & 0xf);
|
1363
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
1473
1364
|
}
|
1474
1365
|
return GRPC_ERROR_NONE;
|
1475
1366
|
}
|
1476
1367
|
|
1477
1368
|
/* decode some string bytes based on the current decoding mode
|
1478
1369
|
(huffman or not) */
|
1479
|
-
|
1480
|
-
|
1481
|
-
if (
|
1482
|
-
return
|
1370
|
+
grpc_error_handle HPackParser::AppendStrBytes(const uint8_t* cur,
|
1371
|
+
const uint8_t* end) {
|
1372
|
+
if (huff_) {
|
1373
|
+
return AppendHuffBytes(cur, end);
|
1483
1374
|
} else {
|
1484
|
-
return
|
1375
|
+
return AppendString(cur, end);
|
1485
1376
|
}
|
1486
1377
|
}
|
1487
1378
|
|
1488
1379
|
/* parse a string - tries to do large chunks at a time */
|
1489
|
-
|
1490
|
-
|
1491
|
-
size_t remaining =
|
1380
|
+
grpc_error_handle HPackParser::parse_string(const uint8_t* cur,
|
1381
|
+
const uint8_t* end) {
|
1382
|
+
size_t remaining = strlen_ - strgot_;
|
1492
1383
|
size_t given = static_cast<size_t>(end - cur);
|
1493
1384
|
if (remaining <= given) {
|
1494
|
-
grpc_error_handle err =
|
1495
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1496
|
-
err = finish_str(
|
1497
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1498
|
-
return parse_next(
|
1385
|
+
grpc_error_handle err = AppendStrBytes(cur, cur + remaining);
|
1386
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
1387
|
+
err = finish_str(cur + remaining, end);
|
1388
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
1389
|
+
return parse_next(cur + remaining, end);
|
1499
1390
|
} else {
|
1500
|
-
grpc_error_handle err =
|
1501
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1502
|
-
GPR_ASSERT(given <= UINT32_MAX -
|
1503
|
-
|
1504
|
-
|
1391
|
+
grpc_error_handle err = AppendStrBytes(cur, cur + given);
|
1392
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
1393
|
+
GPR_ASSERT(given <= UINT32_MAX - strgot_);
|
1394
|
+
strgot_ += static_cast<uint32_t>(given);
|
1395
|
+
state_ = &HPackParser::parse_string;
|
1505
1396
|
return GRPC_ERROR_NONE;
|
1506
1397
|
}
|
1507
1398
|
}
|
1508
1399
|
|
1509
1400
|
/* begin parsing a string - performs setup, calls parse_string */
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1401
|
+
grpc_error_handle HPackParser::begin_parse_string(const uint8_t* cur,
|
1402
|
+
const uint8_t* end,
|
1403
|
+
BinaryState binary,
|
1404
|
+
HPackParser::String* str) {
|
1405
|
+
if (!huff_ && binary == BinaryState::kNotBinary &&
|
1406
|
+
static_cast<uint32_t>(end - cur) >= strlen_ &&
|
1407
|
+
current_slice_refcount_ != nullptr) {
|
1516
1408
|
GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED();
|
1517
|
-
str->
|
1518
|
-
str->
|
1519
|
-
str->
|
1520
|
-
str->
|
1521
|
-
grpc_slice_ref_internal(str->
|
1522
|
-
return parse_next(
|
1409
|
+
str->copied_ = false;
|
1410
|
+
str->data_.referenced.refcount = current_slice_refcount_;
|
1411
|
+
str->data_.referenced.data.refcounted.bytes = const_cast<uint8_t*>(cur);
|
1412
|
+
str->data_.referenced.data.refcounted.length = strlen_;
|
1413
|
+
grpc_slice_ref_internal(str->data_.referenced);
|
1414
|
+
return parse_next(cur + strlen_, end);
|
1523
1415
|
}
|
1524
|
-
|
1525
|
-
str->
|
1526
|
-
str->
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
switch (
|
1531
|
-
case
|
1532
|
-
if (
|
1416
|
+
strgot_ = 0;
|
1417
|
+
str->copied_ = true;
|
1418
|
+
str->data_.copied.length = 0;
|
1419
|
+
parsing_.str = str;
|
1420
|
+
huff_state_ = 0;
|
1421
|
+
binary_ = binary;
|
1422
|
+
switch (binary_) {
|
1423
|
+
case BinaryState::kNotBinary:
|
1424
|
+
if (huff_) {
|
1533
1425
|
GRPC_STATS_INC_HPACK_RECV_HUFFMAN();
|
1534
1426
|
} else {
|
1535
1427
|
GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED();
|
1536
1428
|
}
|
1537
1429
|
break;
|
1538
|
-
case
|
1430
|
+
case BinaryState::kBinaryBegin:
|
1539
1431
|
/* stats incremented later: don't know true binary or not */
|
1540
1432
|
break;
|
1541
1433
|
default:
|
1542
1434
|
abort();
|
1543
1435
|
}
|
1544
|
-
return parse_string(
|
1436
|
+
return parse_string(cur, end);
|
1545
1437
|
}
|
1546
1438
|
|
1547
1439
|
/* parse the key string */
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
return begin_parse_string(p, cur, end, NOT_BINARY, &p->key);
|
1440
|
+
grpc_error_handle HPackParser::parse_key_string(const uint8_t* cur,
|
1441
|
+
const uint8_t* end) {
|
1442
|
+
return begin_parse_string(cur, end, BinaryState::kNotBinary, &key_);
|
1552
1443
|
}
|
1553
1444
|
|
1554
1445
|
/* check if a key represents a binary header or not */
|
1555
1446
|
|
1556
|
-
|
1447
|
+
bool HPackParser::IsBinaryLiteralHeader() {
|
1557
1448
|
/* We know that either argument here is a reference counter slice.
|
1558
1449
|
* 1. If it is a grpc_core::StaticSlice, the refcount is set to kNoopRefcount.
|
1559
|
-
* 2. If it's
|
1450
|
+
* 2. If it's key_.data.referenced, then key_.copied was set to false,
|
1560
1451
|
* which occurs in begin_parse_string() - where the refcount is set to
|
1561
|
-
*
|
1452
|
+
* current_slice_refcount_, which is not null. */
|
1562
1453
|
return grpc_is_refcounted_slice_binary_header(
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1454
|
+
key_.copied_ ? grpc_core::ExternallyManagedSlice(key_.data_.copied.str,
|
1455
|
+
key_.data_.copied.length)
|
1456
|
+
: key_.data_.referenced);
|
1566
1457
|
}
|
1567
1458
|
|
1568
1459
|
/* Cache the metadata for the given index during initial parsing. This avoids a
|
1569
1460
|
pointless recomputation of the metadata when finishing a header. We read the
|
1570
1461
|
cached value in get_precomputed_md_for_idx(). */
|
1571
|
-
|
1572
|
-
|
1573
|
-
GPR_DEBUG_ASSERT(
|
1574
|
-
|
1575
|
-
p->md_for_index = md;
|
1462
|
+
void HPackParser::SetPrecomputedMDIndex(grpc_mdelem md) {
|
1463
|
+
GPR_DEBUG_ASSERT(md_for_index_.payload == 0);
|
1464
|
+
GPR_DEBUG_ASSERT(precomputed_md_index_ == -1);
|
1465
|
+
md_for_index_ = md;
|
1576
1466
|
#ifndef NDEBUG
|
1577
|
-
|
1467
|
+
precomputed_md_index_ = index_;
|
1578
1468
|
#endif
|
1579
1469
|
}
|
1580
1470
|
|
@@ -1582,11 +1472,10 @@ static void set_precomputed_md_idx(grpc_chttp2_hpack_parser* p,
|
|
1582
1472
|
is a binary indexed header during string parsing. We'll need to revisit this
|
1583
1473
|
metadata when we're done parsing, so we cache the metadata for this index
|
1584
1474
|
here using set_precomputed_md_idx(). */
|
1585
|
-
|
1586
|
-
|
1587
|
-
grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
|
1475
|
+
grpc_error_handle HPackParser::IsBinaryIndexedHeader(bool* is) {
|
1476
|
+
grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&table_, index_);
|
1588
1477
|
if (GPR_UNLIKELY(GRPC_MDISNULL(elem))) {
|
1589
|
-
return
|
1478
|
+
return InvalidHPackIndexError();
|
1590
1479
|
}
|
1591
1480
|
/* We know that GRPC_MDKEY(elem) points to a reference counted slice since:
|
1592
1481
|
* 1. elem was a result of grpc_chttp2_hptbl_lookup
|
@@ -1597,101 +1486,104 @@ static grpc_error_handle is_binary_indexed_header(grpc_chttp2_hpack_parser* p,
|
|
1597
1486
|
* interned.
|
1598
1487
|
* 4. Both static and interned element slices have non-null refcounts. */
|
1599
1488
|
*is = grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem));
|
1600
|
-
|
1489
|
+
SetPrecomputedMDIndex(elem);
|
1601
1490
|
return GRPC_ERROR_NONE;
|
1602
1491
|
}
|
1603
1492
|
|
1604
1493
|
/* parse the value string */
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1494
|
+
grpc_error_handle HPackParser::parse_value_string(const uint8_t* cur,
|
1495
|
+
const uint8_t* end,
|
1496
|
+
bool is_binary) {
|
1497
|
+
return begin_parse_string(
|
1498
|
+
cur, end, is_binary ? BinaryState::kBinaryBegin : BinaryState::kNotBinary,
|
1499
|
+
&value_);
|
1611
1500
|
}
|
1612
1501
|
|
1613
|
-
|
1614
|
-
|
1502
|
+
grpc_error_handle HPackParser::parse_value_string_with_indexed_key(
|
1503
|
+
const uint8_t* cur, const uint8_t* end) {
|
1615
1504
|
bool is_binary = false;
|
1616
|
-
grpc_error_handle err =
|
1617
|
-
if (err != GRPC_ERROR_NONE) return parse_error(
|
1618
|
-
return parse_value_string(
|
1619
|
-
}
|
1620
|
-
|
1621
|
-
static grpc_error_handle parse_value_string_with_literal_key(
|
1622
|
-
grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) {
|
1623
|
-
return parse_value_string(p, cur, end, is_binary_literal_header(p));
|
1505
|
+
grpc_error_handle err = IsBinaryIndexedHeader(&is_binary);
|
1506
|
+
if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
|
1507
|
+
return parse_value_string(cur, end, is_binary);
|
1624
1508
|
}
|
1625
1509
|
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
GRPC_MDELEM_UNREF(md);
|
1630
|
-
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set");
|
1510
|
+
grpc_error_handle HPackParser::parse_value_string_with_literal_key(
|
1511
|
+
const uint8_t* cur, const uint8_t* end) {
|
1512
|
+
return parse_value_string(cur, end, IsBinaryLiteralHeader());
|
1631
1513
|
}
|
1632
1514
|
|
1633
1515
|
/* PUBLIC INTERFACE */
|
1634
1516
|
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
p->value.data.copied.capacity = 0;
|
1646
|
-
p->value.data.copied.length = 0;
|
1517
|
+
HPackParser::HPackParser() {
|
1518
|
+
state_ = &HPackParser::parse_begin;
|
1519
|
+
key_.data_.referenced = grpc_empty_slice();
|
1520
|
+
key_.data_.copied.str = nullptr;
|
1521
|
+
key_.data_.copied.capacity = 0;
|
1522
|
+
key_.data_.copied.length = 0;
|
1523
|
+
value_.data_.referenced = grpc_empty_slice();
|
1524
|
+
value_.data_.copied.str = nullptr;
|
1525
|
+
value_.data_.copied.capacity = 0;
|
1526
|
+
value_.data_.copied.length = 0;
|
1647
1527
|
/* Cached metadata for the current index the parser is handling. This is set
|
1648
1528
|
to 0 initially, invalidated when the index changes, and invalidated when it
|
1649
1529
|
is read (by get_precomputed_md_for_idx()). It is set during string parsing,
|
1650
1530
|
by set_precomputed_md_idx() - which is called by parse_value_string().
|
1651
1531
|
The goal here is to avoid recomputing the metadata for the index when
|
1652
1532
|
finishing with a header as well as the initial parse. */
|
1653
|
-
|
1533
|
+
md_for_index_.payload = 0;
|
1654
1534
|
#ifndef NDEBUG
|
1655
1535
|
/* In debug mode, this ensures that the cached metadata we're reading is in
|
1656
1536
|
* fact correct for the index we are examining. */
|
1657
|
-
|
1537
|
+
precomputed_md_index_ = -1;
|
1658
1538
|
#endif
|
1659
|
-
|
1660
|
-
|
1539
|
+
dynamic_table_updates_allowed_ = 2;
|
1540
|
+
last_error_ = GRPC_ERROR_NONE;
|
1661
1541
|
}
|
1662
1542
|
|
1663
|
-
void
|
1664
|
-
|
1665
|
-
|
1543
|
+
void HPackParser::BeginFrame(Sink sink, Boundary boundary, Priority priority) {
|
1544
|
+
sink_ = std::move(sink);
|
1545
|
+
boundary_ = boundary;
|
1546
|
+
switch (priority) {
|
1547
|
+
case Priority::Included:
|
1548
|
+
after_prioritization_ = state_;
|
1549
|
+
state_ = &HPackParser::parse_stream_dep0;
|
1550
|
+
break;
|
1551
|
+
case Priority::None:
|
1552
|
+
break;
|
1553
|
+
}
|
1666
1554
|
}
|
1667
1555
|
|
1668
|
-
|
1669
|
-
grpc_chttp2_hptbl_destroy(&
|
1670
|
-
GRPC_ERROR_UNREF(
|
1671
|
-
grpc_slice_unref_internal(
|
1672
|
-
grpc_slice_unref_internal(
|
1673
|
-
gpr_free(
|
1674
|
-
gpr_free(
|
1556
|
+
HPackParser::~HPackParser() {
|
1557
|
+
grpc_chttp2_hptbl_destroy(&table_);
|
1558
|
+
GRPC_ERROR_UNREF(last_error_);
|
1559
|
+
grpc_slice_unref_internal(key_.data_.referenced);
|
1560
|
+
grpc_slice_unref_internal(value_.data_.referenced);
|
1561
|
+
gpr_free(key_.data_.copied.str);
|
1562
|
+
gpr_free(value_.data_.copied.str);
|
1675
1563
|
}
|
1676
1564
|
|
1677
|
-
grpc_error_handle
|
1678
|
-
const grpc_slice& slice) {
|
1565
|
+
grpc_error_handle HPackParser::Parse(const grpc_slice& slice) {
|
1679
1566
|
/* max number of bytes to parse at a time... limits call stack depth on
|
1680
1567
|
* compilers without TCO */
|
1681
1568
|
#define MAX_PARSE_LENGTH 1024
|
1682
|
-
|
1569
|
+
current_slice_refcount_ = slice.refcount;
|
1683
1570
|
const uint8_t* start = GRPC_SLICE_START_PTR(slice);
|
1684
1571
|
const uint8_t* end = GRPC_SLICE_END_PTR(slice);
|
1685
1572
|
grpc_error_handle error = GRPC_ERROR_NONE;
|
1686
1573
|
while (start != end && error == GRPC_ERROR_NONE) {
|
1687
1574
|
const uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start);
|
1688
|
-
error =
|
1575
|
+
error = (this->*state_)(start, target);
|
1689
1576
|
start = target;
|
1690
1577
|
}
|
1691
|
-
|
1578
|
+
current_slice_refcount_ = nullptr;
|
1692
1579
|
return error;
|
1693
1580
|
}
|
1694
1581
|
|
1582
|
+
} // namespace grpc_core
|
1583
|
+
|
1584
|
+
// TODO(ctiller): this serves as an eviction notice for the remainder of this
|
1585
|
+
// file... it belongs elsewhere!
|
1586
|
+
|
1695
1587
|
typedef void (*maybe_complete_func_type)(grpc_chttp2_transport* t,
|
1696
1588
|
grpc_chttp2_stream* s);
|
1697
1589
|
static const maybe_complete_func_type maybe_complete_funcs[] = {
|
@@ -1734,24 +1626,23 @@ grpc_error_handle grpc_chttp2_header_parser_parse(void* hpack_parser,
|
|
1734
1626
|
const grpc_slice& slice,
|
1735
1627
|
int is_last) {
|
1736
1628
|
GPR_TIMER_SCOPE("grpc_chttp2_header_parser_parse", 0);
|
1737
|
-
|
1738
|
-
static_cast<grpc_chttp2_hpack_parser*>(hpack_parser);
|
1629
|
+
auto* parser = static_cast<grpc_core::HPackParser*>(hpack_parser);
|
1739
1630
|
if (s != nullptr) {
|
1740
1631
|
s->stats.incoming.header_bytes += GRPC_SLICE_LENGTH(slice);
|
1741
1632
|
}
|
1742
|
-
grpc_error_handle error =
|
1633
|
+
grpc_error_handle error = parser->Parse(slice);
|
1743
1634
|
if (error != GRPC_ERROR_NONE) {
|
1744
1635
|
return error;
|
1745
1636
|
}
|
1746
1637
|
if (is_last) {
|
1747
|
-
if (parser->is_boundary && parser->
|
1638
|
+
if (parser->is_boundary() && !parser->is_in_begin_state()) {
|
1748
1639
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1749
1640
|
"end of header frame not aligned with a hpack record boundary");
|
1750
1641
|
}
|
1751
1642
|
/* need to check for null stream: this can occur if we receive an invalid
|
1752
1643
|
stream id on a header */
|
1753
1644
|
if (s != nullptr) {
|
1754
|
-
if (parser->is_boundary) {
|
1645
|
+
if (parser->is_boundary()) {
|
1755
1646
|
if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) {
|
1756
1647
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1757
1648
|
"Too many trailer frames");
|
@@ -1766,7 +1657,7 @@ grpc_error_handle grpc_chttp2_header_parser_parse(void* hpack_parser,
|
|
1766
1657
|
maybe_complete_funcs[s->header_frames_received](t, s);
|
1767
1658
|
s->header_frames_received++;
|
1768
1659
|
}
|
1769
|
-
if (parser->is_eof) {
|
1660
|
+
if (parser->is_eof()) {
|
1770
1661
|
if (t->is_client && !s->write_closed) {
|
1771
1662
|
/* server eof ==> complete closure; we may need to forcefully close
|
1772
1663
|
the stream. Wait until the combiner lock is ready to be released
|
@@ -1780,11 +1671,7 @@ grpc_error_handle grpc_chttp2_header_parser_parse(void* hpack_parser,
|
|
1780
1671
|
grpc_chttp2_mark_stream_closed(t, s, true, false, GRPC_ERROR_NONE);
|
1781
1672
|
}
|
1782
1673
|
}
|
1783
|
-
parser->
|
1784
|
-
parser->on_header_user_data = nullptr;
|
1785
|
-
parser->is_boundary = 0xde;
|
1786
|
-
parser->is_eof = 0xde;
|
1787
|
-
parser->dynamic_table_update_allowed = 2;
|
1674
|
+
parser->FinishFrame();
|
1788
1675
|
}
|
1789
1676
|
return GRPC_ERROR_NONE;
|
1790
1677
|
}
|