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
@@ -0,0 +1,232 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2016, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
|
35
|
+
#include <grpc/support/alloc.h>
|
36
|
+
#include <grpc/support/log.h>
|
37
|
+
#include "src/core/lib/support/string.h"
|
38
|
+
|
39
|
+
static uint8_t decode_table[] = {
|
40
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
41
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
42
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
43
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 62, 0x40, 0x40, 0x40, 63,
|
44
|
+
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0x40, 0x40,
|
45
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0, 1, 2, 3, 4, 5, 6,
|
46
|
+
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
47
|
+
19, 20, 21, 22, 23, 24, 25, 0x40, 0x40, 0x40, 0x40, 0x40,
|
48
|
+
0x40, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
49
|
+
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
50
|
+
49, 50, 51, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
51
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
52
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
53
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
54
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
55
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
56
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
57
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
58
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
59
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
60
|
+
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
61
|
+
0x40, 0x40, 0x40, 0x40};
|
62
|
+
|
63
|
+
static const uint8_t tail_xtra[4] = {0, 0, 1, 2};
|
64
|
+
|
65
|
+
static bool input_is_valid(uint8_t *input_ptr, size_t length) {
|
66
|
+
size_t i;
|
67
|
+
|
68
|
+
for (i = 0; i < length; ++i) {
|
69
|
+
if ((decode_table[input_ptr[i]] & 0xC0) != 0) {
|
70
|
+
gpr_log(GPR_ERROR,
|
71
|
+
"Base64 decoding failed, invalid character '%c' in base64 "
|
72
|
+
"input.\n",
|
73
|
+
(char)(*input_ptr));
|
74
|
+
return false;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
return true;
|
78
|
+
}
|
79
|
+
|
80
|
+
#define COMPOSE_OUTPUT_BYTE_0(input_ptr) \
|
81
|
+
(uint8_t)((decode_table[input_ptr[0]] << 2) | \
|
82
|
+
(decode_table[input_ptr[1]] >> 4))
|
83
|
+
|
84
|
+
#define COMPOSE_OUTPUT_BYTE_1(input_ptr) \
|
85
|
+
(uint8_t)((decode_table[input_ptr[1]] << 4) | \
|
86
|
+
(decode_table[input_ptr[2]] >> 2))
|
87
|
+
|
88
|
+
#define COMPOSE_OUTPUT_BYTE_2(input_ptr) \
|
89
|
+
(uint8_t)((decode_table[input_ptr[2]] << 6) | decode_table[input_ptr[3]])
|
90
|
+
|
91
|
+
bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx) {
|
92
|
+
size_t input_tail;
|
93
|
+
|
94
|
+
if (ctx->input_cur > ctx->input_end || ctx->output_cur > ctx->output_end) {
|
95
|
+
return false;
|
96
|
+
}
|
97
|
+
|
98
|
+
// Process a block of 4 input characters and 3 output bytes
|
99
|
+
while (ctx->input_end >= ctx->input_cur + 4 &&
|
100
|
+
ctx->output_end >= ctx->output_cur + 3) {
|
101
|
+
if (!input_is_valid(ctx->input_cur, 4)) return false;
|
102
|
+
ctx->output_cur[0] = COMPOSE_OUTPUT_BYTE_0(ctx->input_cur);
|
103
|
+
ctx->output_cur[1] = COMPOSE_OUTPUT_BYTE_1(ctx->input_cur);
|
104
|
+
ctx->output_cur[2] = COMPOSE_OUTPUT_BYTE_2(ctx->input_cur);
|
105
|
+
ctx->output_cur += 3;
|
106
|
+
ctx->input_cur += 4;
|
107
|
+
}
|
108
|
+
|
109
|
+
// Process the tail of input data
|
110
|
+
input_tail = (size_t)(ctx->input_end - ctx->input_cur);
|
111
|
+
if (input_tail == 4) {
|
112
|
+
// Process the input data with pad chars
|
113
|
+
if (ctx->input_cur[3] == '=') {
|
114
|
+
if (ctx->input_cur[2] == '=' && ctx->output_end >= ctx->output_cur + 1) {
|
115
|
+
if (!input_is_valid(ctx->input_cur, 2)) return false;
|
116
|
+
*(ctx->output_cur++) = COMPOSE_OUTPUT_BYTE_0(ctx->input_cur);
|
117
|
+
ctx->input_cur += 4;
|
118
|
+
} else if (ctx->output_end >= ctx->output_cur + 2) {
|
119
|
+
if (!input_is_valid(ctx->input_cur, 3)) return false;
|
120
|
+
*(ctx->output_cur++) = COMPOSE_OUTPUT_BYTE_0(ctx->input_cur);
|
121
|
+
*(ctx->output_cur++) = COMPOSE_OUTPUT_BYTE_1(ctx->input_cur);
|
122
|
+
;
|
123
|
+
ctx->input_cur += 4;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
} else if (ctx->contains_tail && input_tail > 1) {
|
128
|
+
// Process the input data without pad chars, but constains_tail is set
|
129
|
+
if (ctx->output_end >= ctx->output_cur + tail_xtra[input_tail]) {
|
130
|
+
if (!input_is_valid(ctx->input_cur, input_tail)) return false;
|
131
|
+
switch (input_tail) {
|
132
|
+
case 3:
|
133
|
+
ctx->output_cur[1] = COMPOSE_OUTPUT_BYTE_1(ctx->input_cur);
|
134
|
+
case 2:
|
135
|
+
ctx->output_cur[0] = COMPOSE_OUTPUT_BYTE_0(ctx->input_cur);
|
136
|
+
}
|
137
|
+
ctx->output_cur += tail_xtra[input_tail];
|
138
|
+
ctx->input_cur += input_tail;
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
return true;
|
143
|
+
}
|
144
|
+
|
145
|
+
gpr_slice grpc_chttp2_base64_decode(gpr_slice input) {
|
146
|
+
size_t input_length = GPR_SLICE_LENGTH(input);
|
147
|
+
size_t output_length = input_length / 4 * 3;
|
148
|
+
struct grpc_base64_decode_context ctx;
|
149
|
+
gpr_slice output;
|
150
|
+
|
151
|
+
if (input_length % 4 != 0) {
|
152
|
+
gpr_log(GPR_ERROR,
|
153
|
+
"Base64 decoding failed, input of "
|
154
|
+
"grpc_chttp2_base64_decode has a length of %d, which is not a "
|
155
|
+
"multiple of 4.\n",
|
156
|
+
(int)input_length);
|
157
|
+
return gpr_empty_slice();
|
158
|
+
}
|
159
|
+
|
160
|
+
if (input_length > 0) {
|
161
|
+
uint8_t *input_end = GPR_SLICE_END_PTR(input);
|
162
|
+
if (*(--input_end) == '=') {
|
163
|
+
output_length--;
|
164
|
+
if (*(--input_end) == '=') {
|
165
|
+
output_length--;
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
output = gpr_slice_malloc(output_length);
|
170
|
+
|
171
|
+
ctx.input_cur = GPR_SLICE_START_PTR(input);
|
172
|
+
ctx.input_end = GPR_SLICE_END_PTR(input);
|
173
|
+
ctx.output_cur = GPR_SLICE_START_PTR(output);
|
174
|
+
ctx.output_end = GPR_SLICE_END_PTR(output);
|
175
|
+
ctx.contains_tail = false;
|
176
|
+
|
177
|
+
if (!grpc_base64_decode_partial(&ctx)) {
|
178
|
+
char *s = gpr_dump_slice(input, GPR_DUMP_ASCII);
|
179
|
+
gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
|
180
|
+
gpr_free(s);
|
181
|
+
gpr_slice_unref(output);
|
182
|
+
return gpr_empty_slice();
|
183
|
+
}
|
184
|
+
GPR_ASSERT(ctx.output_cur == GPR_SLICE_END_PTR(output));
|
185
|
+
GPR_ASSERT(ctx.input_cur == GPR_SLICE_END_PTR(input));
|
186
|
+
return output;
|
187
|
+
}
|
188
|
+
|
189
|
+
gpr_slice grpc_chttp2_base64_decode_with_length(gpr_slice input,
|
190
|
+
size_t output_length) {
|
191
|
+
size_t input_length = GPR_SLICE_LENGTH(input);
|
192
|
+
gpr_slice output = gpr_slice_malloc(output_length);
|
193
|
+
struct grpc_base64_decode_context ctx;
|
194
|
+
|
195
|
+
// The length of a base64 string cannot be 4 * n + 1
|
196
|
+
if (input_length % 4 == 1) {
|
197
|
+
gpr_log(GPR_ERROR,
|
198
|
+
"Base64 decoding failed, input of "
|
199
|
+
"grpc_chttp2_base64_decode_with_length has a length of %d, which "
|
200
|
+
"has a tail of 1 byte.\n",
|
201
|
+
(int)input_length);
|
202
|
+
gpr_slice_unref(output);
|
203
|
+
return gpr_empty_slice();
|
204
|
+
}
|
205
|
+
|
206
|
+
if (output_length > input_length / 4 * 3 + tail_xtra[input_length % 4]) {
|
207
|
+
gpr_log(GPR_ERROR,
|
208
|
+
"Base64 decoding failed, output_length %d is longer "
|
209
|
+
"than the max possible output length %d.\n",
|
210
|
+
(int)output_length,
|
211
|
+
(int)(input_length / 4 * 3 + tail_xtra[input_length % 4]));
|
212
|
+
gpr_slice_unref(output);
|
213
|
+
return gpr_empty_slice();
|
214
|
+
}
|
215
|
+
|
216
|
+
ctx.input_cur = GPR_SLICE_START_PTR(input);
|
217
|
+
ctx.input_end = GPR_SLICE_END_PTR(input);
|
218
|
+
ctx.output_cur = GPR_SLICE_START_PTR(output);
|
219
|
+
ctx.output_end = GPR_SLICE_END_PTR(output);
|
220
|
+
ctx.contains_tail = true;
|
221
|
+
|
222
|
+
if (!grpc_base64_decode_partial(&ctx)) {
|
223
|
+
char *s = gpr_dump_slice(input, GPR_DUMP_ASCII);
|
224
|
+
gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
|
225
|
+
gpr_free(s);
|
226
|
+
gpr_slice_unref(output);
|
227
|
+
return gpr_empty_slice();
|
228
|
+
}
|
229
|
+
GPR_ASSERT(ctx.output_cur == GPR_SLICE_END_PTR(output));
|
230
|
+
GPR_ASSERT(ctx.input_cur <= GPR_SLICE_END_PTR(input));
|
231
|
+
return output;
|
232
|
+
}
|
@@ -31,40 +31,36 @@
|
|
31
31
|
*
|
32
32
|
*/
|
33
33
|
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#include <stdbool.h>
|
37
|
-
|
38
|
-
#include <grpc/support/log.h>
|
34
|
+
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H
|
35
|
+
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H
|
39
36
|
|
40
|
-
#include
|
37
|
+
#include <grpc/support/slice.h>
|
38
|
+
#include <stdbool.h>
|
41
39
|
|
42
|
-
|
43
|
-
|
40
|
+
struct grpc_base64_decode_context {
|
41
|
+
/* input/output: */
|
42
|
+
uint8_t *input_cur;
|
43
|
+
uint8_t *input_end;
|
44
|
+
uint8_t *output_cur;
|
45
|
+
uint8_t *output_end;
|
46
|
+
/* Indicate if the decoder should handle the tail of input data*/
|
47
|
+
bool contains_tail;
|
48
|
+
};
|
44
49
|
|
45
|
-
|
50
|
+
/* base64 decode a grpc_base64_decode_context util either input_end is reached
|
51
|
+
or output_end is reached. When input_end is reached, (input_end - input_cur)
|
52
|
+
is less than 4. When output_end is reached, (output_end - output_cur) is less
|
53
|
+
than 3. Returns false if decoding is failed. */
|
54
|
+
bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx);
|
46
55
|
|
47
|
-
/*
|
48
|
-
|
49
|
-
|
50
|
-
* never run */
|
51
|
-
static void handle_signal(int signum) {
|
52
|
-
signal_received = true;
|
53
|
-
if (signum == SIGINT) {
|
54
|
-
old_sigint_handler(signum);
|
55
|
-
} else if (signum == SIGTERM) {
|
56
|
-
old_sigterm_handler(signum);
|
57
|
-
}
|
58
|
-
}
|
56
|
+
/* base64 decode a slice with pad chars. Returns a new slice, does not take
|
57
|
+
ownership of the input. Returns an empty slice if decoding is failed. */
|
58
|
+
gpr_slice grpc_chttp2_base64_decode(gpr_slice input);
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
/* base64 decode a slice without pad chars, data length is needed. Returns a new
|
61
|
+
slice, does not take ownership of the input. Returns an empty slice if
|
62
|
+
decoding is failed. */
|
63
|
+
gpr_slice grpc_chttp2_base64_decode_with_length(gpr_slice input,
|
64
|
+
size_t output_length);
|
64
65
|
|
65
|
-
|
66
|
-
old_sigint_handler = signal(SIGINT, handle_signal);
|
67
|
-
old_sigterm_handler = signal(SIGTERM, handle_signal);
|
68
|
-
rb_define_singleton_method(grpc_rb_mGrpcCore, "signal_received?",
|
69
|
-
grpc_rb_signal_received, 0);
|
70
|
-
}
|
66
|
+
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */
|
@@ -47,6 +47,7 @@
|
|
47
47
|
#include "src/core/ext/transport/chttp2/transport/internal.h"
|
48
48
|
#include "src/core/ext/transport/chttp2/transport/status_conversion.h"
|
49
49
|
#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h"
|
50
|
+
#include "src/core/lib/http/parser.h"
|
50
51
|
#include "src/core/lib/profiling/timers.h"
|
51
52
|
#include "src/core/lib/support/string.h"
|
52
53
|
#include "src/core/lib/transport/static_metadata.h"
|
@@ -56,6 +57,8 @@
|
|
56
57
|
#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024)
|
57
58
|
#define MAX_WINDOW 0x7fffffffu
|
58
59
|
|
60
|
+
#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
|
61
|
+
|
59
62
|
#define MAX_CLIENT_STREAM_ID 0x7fffffffu
|
60
63
|
|
61
64
|
int grpc_http_trace = 0;
|
@@ -65,8 +68,8 @@ int grpc_flowctl_trace = 0;
|
|
65
68
|
((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
|
66
69
|
writing)))
|
67
70
|
|
68
|
-
#define TRANSPORT_FROM_PARSING(
|
69
|
-
((grpc_chttp2_transport *)((char *)(
|
71
|
+
#define TRANSPORT_FROM_PARSING(tp) \
|
72
|
+
((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \
|
70
73
|
parsing)))
|
71
74
|
|
72
75
|
#define TRANSPORT_FROM_GLOBAL(tg) \
|
@@ -82,19 +85,17 @@ int grpc_flowctl_trace = 0;
|
|
82
85
|
static const grpc_transport_vtable vtable;
|
83
86
|
|
84
87
|
/* forward declarations of various callbacks that we'll build closures around */
|
85
|
-
static void writing_action(grpc_exec_ctx *exec_ctx, void *t,
|
86
|
-
|
87
|
-
static void
|
88
|
-
bool iomgr_success_ignored);
|
89
|
-
static void parsing_action(grpc_exec_ctx *exec_ctx, void *t,
|
90
|
-
bool iomgr_success_ignored);
|
88
|
+
static void writing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
89
|
+
static void reading_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
90
|
+
static void parsing_action(grpc_exec_ctx *exec_ctx, void *t, grpc_error *error);
|
91
91
|
|
92
92
|
/** Set a transport level setting, and push it to our peer */
|
93
93
|
static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id,
|
94
94
|
uint32_t value);
|
95
95
|
|
96
96
|
/** Start disconnection chain */
|
97
|
-
static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t
|
97
|
+
static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
98
|
+
grpc_error *error);
|
98
99
|
|
99
100
|
/** Perform a transport_op */
|
100
101
|
static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
@@ -105,7 +106,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
105
106
|
static void cancel_from_api(grpc_exec_ctx *exec_ctx,
|
106
107
|
grpc_chttp2_transport_global *transport_global,
|
107
108
|
grpc_chttp2_stream_global *stream_global,
|
108
|
-
grpc_status_code status
|
109
|
+
grpc_status_code status,
|
110
|
+
gpr_slice *optional_message);
|
109
111
|
|
110
112
|
static void close_from_api(grpc_exec_ctx *exec_ctx,
|
111
113
|
grpc_chttp2_transport_global *transport_global,
|
@@ -131,7 +133,7 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx,
|
|
131
133
|
|
132
134
|
static void connectivity_state_set(
|
133
135
|
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
|
134
|
-
grpc_connectivity_state state, const char *reason);
|
136
|
+
grpc_connectivity_state state, grpc_error *error, const char *reason);
|
135
137
|
|
136
138
|
static void check_read_ops(grpc_exec_ctx *exec_ctx,
|
137
139
|
grpc_chttp2_transport_global *transport_global);
|
@@ -145,7 +147,9 @@ static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
|
|
145
147
|
grpc_chttp2_stream *s,
|
146
148
|
void *byte_stream);
|
147
149
|
static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
|
148
|
-
|
150
|
+
grpc_chttp2_transport_global *transport_global,
|
151
|
+
grpc_chttp2_stream_global *stream_global,
|
152
|
+
grpc_error *error);
|
149
153
|
|
150
154
|
/*******************************************************************************
|
151
155
|
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
|
@@ -159,6 +163,8 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
|
|
159
163
|
|
160
164
|
GPR_ASSERT(t->ep == NULL);
|
161
165
|
|
166
|
+
gpr_slice_unref(t->optional_drop_message);
|
167
|
+
|
162
168
|
gpr_slice_buffer_destroy(&t->global.qbuf);
|
163
169
|
|
164
170
|
gpr_slice_buffer_destroy(&t->writing.outbuf);
|
@@ -188,7 +194,8 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
|
|
188
194
|
and maybe they hold resources that need to be freed */
|
189
195
|
while (t->global.pings.next != &t->global.pings) {
|
190
196
|
grpc_chttp2_outstanding_ping *ping = t->global.pings.next;
|
191
|
-
|
197
|
+
grpc_exec_ctx_sched(exec_ctx, ping->on_recv,
|
198
|
+
GRPC_ERROR_CREATE("Transport closed"), NULL);
|
192
199
|
ping->next->prev = ping->prev;
|
193
200
|
ping->prev->next = ping->next;
|
194
201
|
gpr_free(ping);
|
@@ -257,7 +264,9 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
257
264
|
t->parsing.is_client = is_client;
|
258
265
|
t->parsing.deframe_state =
|
259
266
|
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
|
267
|
+
t->parsing.is_first_frame = true;
|
260
268
|
t->writing.is_client = is_client;
|
269
|
+
t->optional_drop_message = gpr_empty_slice();
|
261
270
|
grpc_connectivity_state_init(
|
262
271
|
&t->channel_callback.state_tracker, GRPC_CHANNEL_READY,
|
263
272
|
is_client ? "client_transport" : "server_transport");
|
@@ -311,6 +320,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
311
320
|
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
|
312
321
|
}
|
313
322
|
push_setting(t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, DEFAULT_WINDOW);
|
323
|
+
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
324
|
+
DEFAULT_MAX_HEADER_LIST_SIZE);
|
314
325
|
|
315
326
|
if (channel_args) {
|
316
327
|
for (i = 0; i < channel_args->num_args; i++) {
|
@@ -378,6 +389,18 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
378
389
|
&t->writing.hpack_compressor,
|
379
390
|
(uint32_t)channel_args->args[i].value.integer);
|
380
391
|
}
|
392
|
+
} else if (0 == strcmp(channel_args->args[i].key,
|
393
|
+
GRPC_ARG_MAX_METADATA_SIZE)) {
|
394
|
+
if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
|
395
|
+
gpr_log(GPR_ERROR, "%s: must be an integer",
|
396
|
+
GRPC_ARG_MAX_METADATA_SIZE);
|
397
|
+
} else if (channel_args->args[i].value.integer < 0) {
|
398
|
+
gpr_log(GPR_ERROR, "%s: must be non-negative",
|
399
|
+
GRPC_ARG_MAX_METADATA_SIZE);
|
400
|
+
} else {
|
401
|
+
push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
|
402
|
+
(uint32_t)channel_args->args[i].value.integer);
|
403
|
+
}
|
381
404
|
}
|
382
405
|
}
|
383
406
|
}
|
@@ -388,7 +411,7 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
388
411
|
grpc_chttp2_stream *s_ignored,
|
389
412
|
void *arg_ignored) {
|
390
413
|
t->destroying = 1;
|
391
|
-
drop_connection(exec_ctx, t);
|
414
|
+
drop_connection(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
|
392
415
|
}
|
393
416
|
|
394
417
|
static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
|
@@ -424,12 +447,11 @@ static void destroy_endpoint(grpc_exec_ctx *exec_ctx,
|
|
424
447
|
|
425
448
|
static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
426
449
|
grpc_chttp2_transport *t,
|
427
|
-
|
428
|
-
void *arg_ignored) {
|
450
|
+
grpc_error *error) {
|
429
451
|
if (!t->closed) {
|
430
452
|
t->closed = 1;
|
431
|
-
connectivity_state_set(exec_ctx, &t->global,
|
432
|
-
"close_transport");
|
453
|
+
connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_SHUTDOWN,
|
454
|
+
GRPC_ERROR_REF(error), "close_transport");
|
433
455
|
if (t->ep) {
|
434
456
|
allow_endpoint_shutdown_locked(exec_ctx, t);
|
435
457
|
}
|
@@ -442,6 +464,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
|
|
442
464
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing");
|
443
465
|
}
|
444
466
|
}
|
467
|
+
GRPC_ERROR_UNREF(error);
|
445
468
|
}
|
446
469
|
|
447
470
|
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
|
@@ -510,7 +533,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
510
533
|
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
|
511
534
|
*t->accepting_stream = s;
|
512
535
|
grpc_chttp2_stream_map_add(&t->parsing_stream_map, s->global.id, s);
|
513
|
-
s->global.in_stream_map =
|
536
|
+
s->global.in_stream_map = true;
|
514
537
|
}
|
515
538
|
|
516
539
|
grpc_chttp2_run_with_global_lock(exec_ctx, t, s, finish_init_stream_locked,
|
@@ -530,7 +553,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx,
|
|
530
553
|
s->global.id == 0);
|
531
554
|
GPR_ASSERT(!s->global.in_stream_map);
|
532
555
|
if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
|
533
|
-
close_transport_locked(
|
556
|
+
close_transport_locked(
|
557
|
+
exec_ctx, t,
|
558
|
+
GRPC_ERROR_CREATE("Last stream closed after sending goaway"));
|
534
559
|
}
|
535
560
|
if (!t->executor.parsing_active && s->global.id) {
|
536
561
|
GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map,
|
@@ -619,12 +644,11 @@ static void finish_global_actions(grpc_exec_ctx *exec_ctx,
|
|
619
644
|
|
620
645
|
for (;;) {
|
621
646
|
if (!t->executor.writing_active && !t->closed &&
|
622
|
-
grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing
|
623
|
-
t->executor.parsing_active)) {
|
647
|
+
grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) {
|
624
648
|
t->executor.writing_active = 1;
|
625
649
|
REF_TRANSPORT(t, "writing");
|
626
650
|
prevent_endpoint_shutdown(t);
|
627
|
-
|
651
|
+
grpc_exec_ctx_sched(exec_ctx, &t->writing_action, GRPC_ERROR_NONE, NULL);
|
628
652
|
}
|
629
653
|
check_read_ops(exec_ctx, &t->global);
|
630
654
|
|
@@ -735,12 +759,12 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx,
|
|
735
759
|
grpc_chttp2_transport *t,
|
736
760
|
grpc_chttp2_stream *s_ignored,
|
737
761
|
void *a) {
|
738
|
-
|
762
|
+
grpc_error *error = a;
|
739
763
|
|
740
764
|
allow_endpoint_shutdown_locked(exec_ctx, t);
|
741
765
|
|
742
|
-
if (
|
743
|
-
drop_connection(exec_ctx, t);
|
766
|
+
if (error != GRPC_ERROR_NONE) {
|
767
|
+
drop_connection(exec_ctx, t, GRPC_ERROR_REF(error));
|
744
768
|
}
|
745
769
|
|
746
770
|
grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing);
|
@@ -748,7 +772,8 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx,
|
|
748
772
|
grpc_chttp2_stream_global *stream_global;
|
749
773
|
while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global,
|
750
774
|
&stream_global)) {
|
751
|
-
fail_pending_writes(exec_ctx, stream_global
|
775
|
+
fail_pending_writes(exec_ctx, &t->global, stream_global,
|
776
|
+
GRPC_ERROR_REF(error));
|
752
777
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes");
|
753
778
|
}
|
754
779
|
|
@@ -761,18 +786,18 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx,
|
|
761
786
|
}
|
762
787
|
|
763
788
|
UNREF_TRANSPORT(exec_ctx, t, "writing");
|
789
|
+
GRPC_ERROR_UNREF(error);
|
764
790
|
}
|
765
791
|
|
766
792
|
void grpc_chttp2_terminate_writing(grpc_exec_ctx *exec_ctx,
|
767
|
-
void *transport_writing,
|
793
|
+
void *transport_writing, grpc_error *error) {
|
768
794
|
grpc_chttp2_transport *t = TRANSPORT_FROM_WRITING(transport_writing);
|
769
|
-
grpc_chttp2_run_with_global_lock(
|
770
|
-
|
771
|
-
(void *)(uintptr_t)success, 0);
|
795
|
+
grpc_chttp2_run_with_global_lock(
|
796
|
+
exec_ctx, t, NULL, terminate_writing_with_lock, GRPC_ERROR_REF(error), 0);
|
772
797
|
}
|
773
798
|
|
774
799
|
static void writing_action(grpc_exec_ctx *exec_ctx, void *gt,
|
775
|
-
|
800
|
+
grpc_error *error) {
|
776
801
|
grpc_chttp2_transport *t = gt;
|
777
802
|
GPR_TIMER_BEGIN("writing_action", 0);
|
778
803
|
grpc_chttp2_perform_writes(exec_ctx, &t->writing, t->ep);
|
@@ -785,11 +810,19 @@ void grpc_chttp2_add_incoming_goaway(
|
|
785
810
|
char *msg = gpr_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
786
811
|
GRPC_CHTTP2_IF_TRACING(
|
787
812
|
gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
|
788
|
-
gpr_free(msg);
|
789
813
|
gpr_slice_unref(goaway_text);
|
790
814
|
transport_global->seen_goaway = 1;
|
791
|
-
|
792
|
-
|
815
|
+
/* lie: use transient failure from the transport to indicate goaway has been
|
816
|
+
* received */
|
817
|
+
connectivity_state_set(
|
818
|
+
exec_ctx, transport_global, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
819
|
+
grpc_error_set_str(
|
820
|
+
grpc_error_set_int(GRPC_ERROR_CREATE("GOAWAY received"),
|
821
|
+
GRPC_ERROR_INT_HTTP2_ERROR,
|
822
|
+
(intptr_t)goaway_error),
|
823
|
+
GRPC_ERROR_STR_RAW_BYTES, msg),
|
824
|
+
"got_goaway");
|
825
|
+
gpr_free(msg);
|
793
826
|
}
|
794
827
|
|
795
828
|
static void maybe_start_some_streams(
|
@@ -818,9 +851,9 @@ static void maybe_start_some_streams(
|
|
818
851
|
transport_global->next_stream_id += 2;
|
819
852
|
|
820
853
|
if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) {
|
821
|
-
connectivity_state_set(
|
822
|
-
|
823
|
-
|
854
|
+
connectivity_state_set(
|
855
|
+
exec_ctx, transport_global, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
856
|
+
GRPC_ERROR_CREATE("Stream IDs exhausted"), "no_more_stream_ids");
|
824
857
|
}
|
825
858
|
|
826
859
|
stream_global->outgoing_window =
|
@@ -834,7 +867,7 @@ static void maybe_start_some_streams(
|
|
834
867
|
grpc_chttp2_stream_map_add(
|
835
868
|
&TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map,
|
836
869
|
stream_global->id, STREAM_FROM_GLOBAL(stream_global));
|
837
|
-
stream_global->in_stream_map =
|
870
|
+
stream_global->in_stream_map = true;
|
838
871
|
transport_global->concurrent_stream_count++;
|
839
872
|
grpc_chttp2_become_writable(transport_global, stream_global);
|
840
873
|
}
|
@@ -843,39 +876,45 @@ static void maybe_start_some_streams(
|
|
843
876
|
grpc_chttp2_list_pop_waiting_for_concurrency(transport_global,
|
844
877
|
&stream_global)) {
|
845
878
|
cancel_from_api(exec_ctx, transport_global, stream_global,
|
846
|
-
GRPC_STATUS_UNAVAILABLE);
|
879
|
+
GRPC_STATUS_UNAVAILABLE, NULL);
|
847
880
|
}
|
848
881
|
}
|
849
882
|
|
850
883
|
#define CLOSURE_BARRIER_STATS_BIT (1 << 0)
|
851
|
-
#define CLOSURE_BARRIER_FAILURE_BIT (1 << 1)
|
852
884
|
#define CLOSURE_BARRIER_FIRST_REF_BIT (1 << 16)
|
853
885
|
|
854
886
|
static grpc_closure *add_closure_barrier(grpc_closure *closure) {
|
855
|
-
closure->
|
887
|
+
closure->next_data.scratch += CLOSURE_BARRIER_FIRST_REF_BIT;
|
856
888
|
return closure;
|
857
889
|
}
|
858
890
|
|
859
|
-
void grpc_chttp2_complete_closure_step(
|
860
|
-
|
861
|
-
|
891
|
+
void grpc_chttp2_complete_closure_step(
|
892
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
|
893
|
+
grpc_chttp2_stream_global *stream_global, grpc_closure **pclosure,
|
894
|
+
grpc_error *error) {
|
862
895
|
grpc_closure *closure = *pclosure;
|
863
896
|
if (closure == NULL) {
|
897
|
+
GRPC_ERROR_UNREF(error);
|
864
898
|
return;
|
865
899
|
}
|
866
|
-
closure->
|
867
|
-
if (
|
868
|
-
closure->
|
900
|
+
closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT;
|
901
|
+
if (error != GRPC_ERROR_NONE) {
|
902
|
+
if (closure->error == GRPC_ERROR_NONE) {
|
903
|
+
closure->error =
|
904
|
+
GRPC_ERROR_CREATE("Error in HTTP transport completing operation");
|
905
|
+
closure->error = grpc_error_set_str(
|
906
|
+
closure->error, GRPC_ERROR_STR_TARGET_ADDRESS,
|
907
|
+
TRANSPORT_FROM_GLOBAL(transport_global)->peer_string);
|
908
|
+
}
|
909
|
+
closure->error = grpc_error_add_child(closure->error, error);
|
869
910
|
}
|
870
|
-
if (closure->
|
871
|
-
if (closure->
|
911
|
+
if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) {
|
912
|
+
if (closure->next_data.scratch & CLOSURE_BARRIER_STATS_BIT) {
|
872
913
|
grpc_transport_move_stats(&stream_global->stats,
|
873
914
|
stream_global->collecting_stats);
|
874
915
|
stream_global->collecting_stats = NULL;
|
875
916
|
}
|
876
|
-
|
877
|
-
exec_ctx, closure,
|
878
|
-
(closure->final_data & CLOSURE_BARRIER_FAILURE_BIT) == 0, NULL);
|
917
|
+
grpc_exec_ctx_sched(exec_ctx, closure, closure->error, NULL);
|
879
918
|
}
|
880
919
|
*pclosure = NULL;
|
881
920
|
}
|
@@ -893,7 +932,7 @@ static int contains_non_ok_status(
|
|
893
932
|
return 0;
|
894
933
|
}
|
895
934
|
|
896
|
-
static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg,
|
935
|
+
static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
|
897
936
|
|
898
937
|
static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
899
938
|
grpc_chttp2_transport *t,
|
@@ -910,17 +949,18 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
910
949
|
}
|
911
950
|
/* use final_data as a barrier until enqueue time; the inital counter is
|
912
951
|
dropped at the end of this function */
|
913
|
-
on_complete->
|
952
|
+
on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT;
|
953
|
+
on_complete->error = GRPC_ERROR_NONE;
|
914
954
|
|
915
955
|
if (op->collect_stats != NULL) {
|
916
956
|
GPR_ASSERT(stream_global->collecting_stats == NULL);
|
917
957
|
stream_global->collecting_stats = op->collect_stats;
|
918
|
-
on_complete->
|
958
|
+
on_complete->next_data.scratch |= CLOSURE_BARRIER_STATS_BIT;
|
919
959
|
}
|
920
960
|
|
921
961
|
if (op->cancel_with_status != GRPC_STATUS_OK) {
|
922
962
|
cancel_from_api(exec_ctx, transport_global, stream_global,
|
923
|
-
op->cancel_with_status);
|
963
|
+
op->cancel_with_status, op->optional_close_message);
|
924
964
|
}
|
925
965
|
|
926
966
|
if (op->close_with_status != GRPC_STATUS_OK) {
|
@@ -933,24 +973,40 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
933
973
|
stream_global->send_initial_metadata_finished =
|
934
974
|
add_closure_barrier(on_complete);
|
935
975
|
stream_global->send_initial_metadata = op->send_initial_metadata;
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
976
|
+
const size_t metadata_size =
|
977
|
+
grpc_metadata_batch_size(op->send_initial_metadata);
|
978
|
+
const size_t metadata_peer_limit =
|
979
|
+
transport_global->settings[GRPC_PEER_SETTINGS]
|
980
|
+
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
|
981
|
+
if (metadata_size > metadata_peer_limit) {
|
982
|
+
gpr_log(GPR_DEBUG,
|
983
|
+
"to-be-sent initial metadata size exceeds peer limit "
|
984
|
+
"(%" PRIuPTR " vs. %" PRIuPTR ")",
|
985
|
+
metadata_size, metadata_peer_limit);
|
986
|
+
cancel_from_api(exec_ctx, transport_global, stream_global,
|
987
|
+
GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
|
988
|
+
} else {
|
989
|
+
if (contains_non_ok_status(transport_global, op->send_initial_metadata)) {
|
990
|
+
stream_global->seen_error = true;
|
991
|
+
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
992
|
+
}
|
993
|
+
if (!stream_global->write_closed) {
|
994
|
+
if (transport_global->is_client) {
|
995
|
+
GPR_ASSERT(stream_global->id == 0);
|
996
|
+
grpc_chttp2_list_add_waiting_for_concurrency(transport_global,
|
997
|
+
stream_global);
|
998
|
+
maybe_start_some_streams(exec_ctx, transport_global);
|
999
|
+
} else {
|
1000
|
+
GPR_ASSERT(stream_global->id != 0);
|
1001
|
+
grpc_chttp2_become_writable(transport_global, stream_global);
|
1002
|
+
}
|
946
1003
|
} else {
|
947
|
-
|
948
|
-
|
1004
|
+
grpc_chttp2_complete_closure_step(
|
1005
|
+
exec_ctx, transport_global, stream_global,
|
1006
|
+
&stream_global->send_initial_metadata_finished,
|
1007
|
+
GRPC_ERROR_CREATE(
|
1008
|
+
"Attempt to send initial metadata after stream was closed"));
|
949
1009
|
}
|
950
|
-
} else {
|
951
|
-
grpc_chttp2_complete_closure_step(
|
952
|
-
exec_ctx, stream_global,
|
953
|
-
&stream_global->send_initial_metadata_finished, 0);
|
954
1010
|
}
|
955
1011
|
}
|
956
1012
|
|
@@ -960,7 +1016,9 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
960
1016
|
stream_global->send_message_finished = add_closure_barrier(on_complete);
|
961
1017
|
if (stream_global->write_closed) {
|
962
1018
|
grpc_chttp2_complete_closure_step(
|
963
|
-
exec_ctx,
|
1019
|
+
exec_ctx, transport_global, stream_global,
|
1020
|
+
&stream_global->send_message_finished,
|
1021
|
+
GRPC_ERROR_CREATE("Attempt to send message after stream was closed"));
|
964
1022
|
} else {
|
965
1023
|
stream_global->send_message = op->send_message;
|
966
1024
|
if (stream_global->id != 0) {
|
@@ -974,19 +1032,37 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
974
1032
|
stream_global->send_trailing_metadata_finished =
|
975
1033
|
add_closure_barrier(on_complete);
|
976
1034
|
stream_global->send_trailing_metadata = op->send_trailing_metadata;
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
1035
|
+
const size_t metadata_size =
|
1036
|
+
grpc_metadata_batch_size(op->send_trailing_metadata);
|
1037
|
+
const size_t metadata_peer_limit =
|
1038
|
+
transport_global->settings[GRPC_PEER_SETTINGS]
|
1039
|
+
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
|
1040
|
+
if (metadata_size > metadata_peer_limit) {
|
1041
|
+
gpr_log(GPR_DEBUG,
|
1042
|
+
"to-be-sent trailing metadata size exceeds peer limit "
|
1043
|
+
"(%" PRIuPTR " vs. %" PRIuPTR ")",
|
1044
|
+
metadata_size, metadata_peer_limit);
|
1045
|
+
cancel_from_api(exec_ctx, transport_global, stream_global,
|
1046
|
+
GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
|
1047
|
+
} else {
|
1048
|
+
if (contains_non_ok_status(transport_global,
|
1049
|
+
op->send_trailing_metadata)) {
|
1050
|
+
stream_global->seen_error = true;
|
1051
|
+
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1052
|
+
}
|
1053
|
+
if (stream_global->write_closed) {
|
1054
|
+
grpc_chttp2_complete_closure_step(
|
1055
|
+
exec_ctx, transport_global, stream_global,
|
1056
|
+
&stream_global->send_trailing_metadata_finished,
|
1057
|
+
grpc_metadata_batch_is_empty(op->send_trailing_metadata)
|
1058
|
+
? GRPC_ERROR_NONE
|
1059
|
+
: GRPC_ERROR_CREATE("Attempt to send trailing metadata after "
|
1060
|
+
"stream was closed"));
|
1061
|
+
} else if (stream_global->id != 0) {
|
1062
|
+
/* TODO(ctiller): check if there's flow control for any outstanding
|
1063
|
+
bytes before going writable */
|
1064
|
+
grpc_chttp2_become_writable(transport_global, stream_global);
|
1065
|
+
}
|
990
1066
|
}
|
991
1067
|
}
|
992
1068
|
|
@@ -1017,10 +1093,12 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1017
1093
|
stream_global->recv_trailing_metadata_finished =
|
1018
1094
|
add_closure_barrier(on_complete);
|
1019
1095
|
stream_global->recv_trailing_metadata = op->recv_trailing_metadata;
|
1096
|
+
stream_global->final_metadata_requested = true;
|
1020
1097
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1021
1098
|
}
|
1022
1099
|
|
1023
|
-
grpc_chttp2_complete_closure_step(exec_ctx,
|
1100
|
+
grpc_chttp2_complete_closure_step(exec_ctx, transport_global, stream_global,
|
1101
|
+
&on_complete, GRPC_ERROR_NONE);
|
1024
1102
|
|
1025
1103
|
GPR_TIMER_END("perform_stream_op_locked", 0);
|
1026
1104
|
}
|
@@ -1057,7 +1135,7 @@ static void ack_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1057
1135
|
for (ping = transport_global->pings.next; ping != &transport_global->pings;
|
1058
1136
|
ping = ping->next) {
|
1059
1137
|
if (0 == memcmp(opaque_8bytes, ping->id, 8)) {
|
1060
|
-
|
1138
|
+
grpc_exec_ctx_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE, NULL);
|
1061
1139
|
ping->next->prev = ping->prev;
|
1062
1140
|
ping->prev->next = ping->next;
|
1063
1141
|
gpr_free(ping);
|
@@ -1079,7 +1157,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1079
1157
|
grpc_chttp2_stream *s_unused,
|
1080
1158
|
void *stream_op) {
|
1081
1159
|
grpc_transport_op *op = stream_op;
|
1082
|
-
|
1160
|
+
grpc_error *close_transport = op->disconnect_with_error;
|
1083
1161
|
|
1084
1162
|
/* If there's a set_accept_stream ensure that we're not parsing
|
1085
1163
|
to avoid changing things out from underneath */
|
@@ -1090,7 +1168,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1090
1168
|
return;
|
1091
1169
|
}
|
1092
1170
|
|
1093
|
-
|
1171
|
+
grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL);
|
1094
1172
|
|
1095
1173
|
if (op->on_connectivity_state_change != NULL) {
|
1096
1174
|
grpc_connectivity_state_notify_on_state_change(
|
@@ -1104,7 +1182,9 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1104
1182
|
t->global.last_incoming_stream_id,
|
1105
1183
|
(uint32_t)grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
|
1106
1184
|
gpr_slice_ref(*op->goaway_message), &t->global.qbuf);
|
1107
|
-
close_transport =
|
1185
|
+
close_transport = grpc_chttp2_has_streams(t)
|
1186
|
+
? GRPC_ERROR_NONE
|
1187
|
+
: GRPC_ERROR_CREATE("GOAWAY sent");
|
1108
1188
|
}
|
1109
1189
|
|
1110
1190
|
if (op->set_accept_stream) {
|
@@ -1125,8 +1205,8 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
|
|
1125
1205
|
send_ping_locked(t, op->send_ping);
|
1126
1206
|
}
|
1127
1207
|
|
1128
|
-
if (close_transport) {
|
1129
|
-
close_transport_locked(exec_ctx, t,
|
1208
|
+
if (close_transport != GRPC_ERROR_NONE) {
|
1209
|
+
close_transport_locked(exec_ctx, t, close_transport);
|
1130
1210
|
}
|
1131
1211
|
}
|
1132
1212
|
|
@@ -1149,15 +1229,26 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
|
|
1149
1229
|
grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) {
|
1150
1230
|
if (stream_global->recv_initial_metadata_ready != NULL &&
|
1151
1231
|
stream_global->published_initial_metadata) {
|
1232
|
+
if (stream_global->seen_error) {
|
1233
|
+
while ((bs = grpc_chttp2_incoming_frame_queue_pop(
|
1234
|
+
&stream_global->incoming_frames)) != NULL) {
|
1235
|
+
incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
|
1236
|
+
}
|
1237
|
+
if (stream_global->exceeded_metadata_size) {
|
1238
|
+
cancel_from_api(exec_ctx, transport_global, stream_global,
|
1239
|
+
GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
|
1240
|
+
}
|
1241
|
+
}
|
1152
1242
|
grpc_chttp2_incoming_metadata_buffer_publish(
|
1153
1243
|
&stream_global->received_initial_metadata,
|
1154
1244
|
stream_global->recv_initial_metadata);
|
1155
|
-
|
1156
|
-
|
1245
|
+
grpc_exec_ctx_sched(exec_ctx, stream_global->recv_initial_metadata_ready,
|
1246
|
+
GRPC_ERROR_NONE, NULL);
|
1157
1247
|
stream_global->recv_initial_metadata_ready = NULL;
|
1158
1248
|
}
|
1159
1249
|
if (stream_global->recv_message_ready != NULL) {
|
1160
|
-
while (stream_global->
|
1250
|
+
while (stream_global->final_metadata_requested &&
|
1251
|
+
stream_global->seen_error &&
|
1161
1252
|
(bs = grpc_chttp2_incoming_frame_queue_pop(
|
1162
1253
|
&stream_global->incoming_frames)) != NULL) {
|
1163
1254
|
incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
|
@@ -1166,30 +1257,35 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
|
|
1166
1257
|
*stream_global->recv_message = grpc_chttp2_incoming_frame_queue_pop(
|
1167
1258
|
&stream_global->incoming_frames);
|
1168
1259
|
GPR_ASSERT(*stream_global->recv_message != NULL);
|
1169
|
-
|
1170
|
-
|
1260
|
+
grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready,
|
1261
|
+
GRPC_ERROR_NONE, NULL);
|
1171
1262
|
stream_global->recv_message_ready = NULL;
|
1172
1263
|
} else if (stream_global->published_trailing_metadata) {
|
1173
1264
|
*stream_global->recv_message = NULL;
|
1174
|
-
|
1175
|
-
|
1265
|
+
grpc_exec_ctx_sched(exec_ctx, stream_global->recv_message_ready,
|
1266
|
+
GRPC_ERROR_NONE, NULL);
|
1176
1267
|
stream_global->recv_message_ready = NULL;
|
1177
1268
|
}
|
1178
1269
|
}
|
1179
1270
|
if (stream_global->recv_trailing_metadata_finished != NULL &&
|
1180
1271
|
stream_global->read_closed && stream_global->write_closed) {
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1272
|
+
if (stream_global->seen_error) {
|
1273
|
+
while ((bs = grpc_chttp2_incoming_frame_queue_pop(
|
1274
|
+
&stream_global->incoming_frames)) != NULL) {
|
1275
|
+
incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
|
1276
|
+
}
|
1277
|
+
if (stream_global->exceeded_metadata_size) {
|
1278
|
+
cancel_from_api(exec_ctx, transport_global, stream_global,
|
1279
|
+
GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
|
1280
|
+
}
|
1185
1281
|
}
|
1186
1282
|
if (stream_global->all_incoming_byte_streams_finished) {
|
1187
1283
|
grpc_chttp2_incoming_metadata_buffer_publish(
|
1188
1284
|
&stream_global->received_trailing_metadata,
|
1189
1285
|
stream_global->recv_trailing_metadata);
|
1190
1286
|
grpc_chttp2_complete_closure_step(
|
1191
|
-
exec_ctx, stream_global,
|
1192
|
-
&stream_global->recv_trailing_metadata_finished,
|
1287
|
+
exec_ctx, transport_global, stream_global,
|
1288
|
+
&stream_global->recv_trailing_metadata_finished, GRPC_ERROR_NONE);
|
1193
1289
|
}
|
1194
1290
|
}
|
1195
1291
|
}
|
@@ -1205,7 +1301,7 @@ static void decrement_active_streams_locked(
|
|
1205
1301
|
}
|
1206
1302
|
|
1207
1303
|
static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1208
|
-
uint32_t id) {
|
1304
|
+
uint32_t id, grpc_error *error) {
|
1209
1305
|
size_t new_stream_count;
|
1210
1306
|
grpc_chttp2_stream *s =
|
1211
1307
|
grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id);
|
@@ -1213,19 +1309,22 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1213
1309
|
s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id);
|
1214
1310
|
}
|
1215
1311
|
GPR_ASSERT(s);
|
1216
|
-
s->global.in_stream_map =
|
1312
|
+
s->global.in_stream_map = false;
|
1217
1313
|
if (t->parsing.incoming_stream == &s->parsing) {
|
1218
1314
|
t->parsing.incoming_stream = NULL;
|
1219
1315
|
grpc_chttp2_parsing_become_skip_parser(exec_ctx, &t->parsing);
|
1220
1316
|
}
|
1221
1317
|
if (s->parsing.data_parser.parsing_frame != NULL) {
|
1222
1318
|
grpc_chttp2_incoming_byte_stream_finished(
|
1223
|
-
exec_ctx, s->parsing.data_parser.parsing_frame,
|
1319
|
+
exec_ctx, s->parsing.data_parser.parsing_frame,
|
1320
|
+
GRPC_ERROR_CREATE_REFERENCING("Stream removed", &error, 1), 0);
|
1224
1321
|
s->parsing.data_parser.parsing_frame = NULL;
|
1225
1322
|
}
|
1226
1323
|
|
1227
1324
|
if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
|
1228
|
-
close_transport_locked(
|
1325
|
+
close_transport_locked(
|
1326
|
+
exec_ctx, t,
|
1327
|
+
GRPC_ERROR_CREATE("Last stream closed after sending GOAWAY"));
|
1229
1328
|
}
|
1230
1329
|
if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) {
|
1231
1330
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing");
|
@@ -1238,12 +1337,14 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1238
1337
|
t->global.concurrent_stream_count = (uint32_t)new_stream_count;
|
1239
1338
|
maybe_start_some_streams(exec_ctx, &t->global);
|
1240
1339
|
}
|
1340
|
+
GRPC_ERROR_UNREF(error);
|
1241
1341
|
}
|
1242
1342
|
|
1243
1343
|
static void cancel_from_api(grpc_exec_ctx *exec_ctx,
|
1244
1344
|
grpc_chttp2_transport_global *transport_global,
|
1245
1345
|
grpc_chttp2_stream_global *stream_global,
|
1246
|
-
grpc_status_code status
|
1346
|
+
grpc_status_code status,
|
1347
|
+
gpr_slice *optional_message) {
|
1247
1348
|
if (!stream_global->read_closed || !stream_global->write_closed) {
|
1248
1349
|
if (stream_global->id != 0) {
|
1249
1350
|
gpr_slice_buffer_add(
|
@@ -1253,15 +1354,21 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx,
|
|
1253
1354
|
(uint32_t)grpc_chttp2_grpc_status_to_http2_error(status),
|
1254
1355
|
&stream_global->stats.outgoing));
|
1255
1356
|
}
|
1357
|
+
|
1358
|
+
if (optional_message) {
|
1359
|
+
gpr_slice_ref(*optional_message);
|
1360
|
+
}
|
1256
1361
|
grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
|
1257
|
-
|
1362
|
+
optional_message);
|
1258
1363
|
}
|
1259
1364
|
if (status != GRPC_STATUS_OK && !stream_global->seen_error) {
|
1260
|
-
stream_global->seen_error =
|
1365
|
+
stream_global->seen_error = true;
|
1261
1366
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1262
1367
|
}
|
1263
|
-
grpc_chttp2_mark_stream_closed(
|
1264
|
-
|
1368
|
+
grpc_chttp2_mark_stream_closed(
|
1369
|
+
exec_ctx, transport_global, stream_global, 1, 1,
|
1370
|
+
grpc_error_set_int(GRPC_ERROR_CREATE("Cancelled"),
|
1371
|
+
GRPC_ERROR_INT_GRPC_STATUS, status));
|
1265
1372
|
}
|
1266
1373
|
|
1267
1374
|
void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
@@ -1269,7 +1376,7 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
|
1269
1376
|
grpc_chttp2_stream_global *stream_global,
|
1270
1377
|
grpc_status_code status, gpr_slice *slice) {
|
1271
1378
|
if (status != GRPC_STATUS_OK) {
|
1272
|
-
stream_global->seen_error =
|
1379
|
+
stream_global->seen_error = true;
|
1273
1380
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1274
1381
|
}
|
1275
1382
|
/* stream_global->recv_trailing_metadata_finished gives us a
|
@@ -1293,7 +1400,7 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
|
1293
1400
|
GRPC_MDSTR_GRPC_MESSAGE,
|
1294
1401
|
grpc_mdstr_from_slice(gpr_slice_ref(*slice))));
|
1295
1402
|
}
|
1296
|
-
stream_global->published_trailing_metadata =
|
1403
|
+
stream_global->published_trailing_metadata = true;
|
1297
1404
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1298
1405
|
}
|
1299
1406
|
if (slice) {
|
@@ -1302,40 +1409,45 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
|
|
1302
1409
|
}
|
1303
1410
|
|
1304
1411
|
static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
|
1305
|
-
|
1412
|
+
grpc_chttp2_transport_global *transport_global,
|
1413
|
+
grpc_chttp2_stream_global *stream_global,
|
1414
|
+
grpc_error *error) {
|
1306
1415
|
grpc_chttp2_complete_closure_step(
|
1307
|
-
exec_ctx,
|
1308
|
-
|
1416
|
+
exec_ctx, transport_global, stream_global,
|
1417
|
+
&stream_global->send_initial_metadata_finished, GRPC_ERROR_REF(error));
|
1309
1418
|
grpc_chttp2_complete_closure_step(
|
1310
|
-
exec_ctx,
|
1311
|
-
|
1312
|
-
grpc_chttp2_complete_closure_step(exec_ctx, stream_global,
|
1313
|
-
&stream_global->send_message_finished,
|
1419
|
+
exec_ctx, transport_global, stream_global,
|
1420
|
+
&stream_global->send_trailing_metadata_finished, GRPC_ERROR_REF(error));
|
1421
|
+
grpc_chttp2_complete_closure_step(exec_ctx, transport_global, stream_global,
|
1422
|
+
&stream_global->send_message_finished,
|
1423
|
+
error);
|
1314
1424
|
}
|
1315
1425
|
|
1316
1426
|
void grpc_chttp2_mark_stream_closed(
|
1317
1427
|
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
|
1318
|
-
grpc_chttp2_stream_global *stream_global, int close_reads,
|
1319
|
-
|
1428
|
+
grpc_chttp2_stream_global *stream_global, int close_reads, int close_writes,
|
1429
|
+
grpc_error *error) {
|
1320
1430
|
if (stream_global->read_closed && stream_global->write_closed) {
|
1321
1431
|
/* already closed */
|
1432
|
+
GRPC_ERROR_UNREF(error);
|
1322
1433
|
return;
|
1323
1434
|
}
|
1324
1435
|
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
|
1325
1436
|
if (close_reads && !stream_global->read_closed) {
|
1326
|
-
stream_global->read_closed =
|
1327
|
-
stream_global->published_initial_metadata =
|
1328
|
-
stream_global->published_trailing_metadata =
|
1437
|
+
stream_global->read_closed = true;
|
1438
|
+
stream_global->published_initial_metadata = true;
|
1439
|
+
stream_global->published_trailing_metadata = true;
|
1329
1440
|
decrement_active_streams_locked(exec_ctx, transport_global, stream_global);
|
1330
1441
|
}
|
1331
1442
|
if (close_writes && !stream_global->write_closed) {
|
1332
|
-
stream_global->write_closed =
|
1443
|
+
stream_global->write_closed = true;
|
1333
1444
|
if (TRANSPORT_FROM_GLOBAL(transport_global)->executor.writing_active) {
|
1334
1445
|
GRPC_CHTTP2_STREAM_REF(stream_global, "finish_writes");
|
1335
1446
|
grpc_chttp2_list_add_closed_waiting_for_writing(transport_global,
|
1336
1447
|
stream_global);
|
1337
1448
|
} else {
|
1338
|
-
fail_pending_writes(exec_ctx, stream_global
|
1449
|
+
fail_pending_writes(exec_ctx, transport_global, stream_global,
|
1450
|
+
GRPC_ERROR_REF(error));
|
1339
1451
|
}
|
1340
1452
|
}
|
1341
1453
|
if (stream_global->read_closed && stream_global->write_closed) {
|
@@ -1346,11 +1458,12 @@ void grpc_chttp2_mark_stream_closed(
|
|
1346
1458
|
} else {
|
1347
1459
|
if (stream_global->id != 0) {
|
1348
1460
|
remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global),
|
1349
|
-
stream_global->id);
|
1461
|
+
stream_global->id, GRPC_ERROR_REF(error));
|
1350
1462
|
}
|
1351
1463
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
|
1352
1464
|
}
|
1353
1465
|
}
|
1466
|
+
GRPC_ERROR_UNREF(error);
|
1354
1467
|
}
|
1355
1468
|
|
1356
1469
|
static void close_from_api(grpc_exec_ctx *exec_ctx,
|
@@ -1366,104 +1479,118 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
|
|
1366
1479
|
|
1367
1480
|
GPR_ASSERT(status >= 0 && (int)status < 100);
|
1368
1481
|
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
*p++ = 'g';
|
1382
|
-
*p++ = 'r';
|
1383
|
-
*p++ = 'p';
|
1384
|
-
*p++ = 'c';
|
1385
|
-
*p++ = '-';
|
1386
|
-
*p++ = 's';
|
1387
|
-
*p++ = 't';
|
1388
|
-
*p++ = 'a';
|
1389
|
-
*p++ = 't';
|
1390
|
-
*p++ = 'u';
|
1391
|
-
*p++ = 's';
|
1392
|
-
if (status < 10) {
|
1393
|
-
*p++ = 1;
|
1394
|
-
*p++ = (uint8_t)('0' + status);
|
1395
|
-
} else {
|
1396
|
-
*p++ = 2;
|
1397
|
-
*p++ = (uint8_t)('0' + (status / 10));
|
1398
|
-
*p++ = (uint8_t)('0' + (status % 10));
|
1399
|
-
}
|
1400
|
-
GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr));
|
1401
|
-
len += (uint32_t)GPR_SLICE_LENGTH(status_hdr);
|
1402
|
-
|
1403
|
-
if (optional_message) {
|
1404
|
-
GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127);
|
1405
|
-
message_pfx = gpr_slice_malloc(15);
|
1406
|
-
p = GPR_SLICE_START_PTR(message_pfx);
|
1407
|
-
*p++ = 0x40;
|
1408
|
-
*p++ = 12; /* len(grpc-message) */
|
1482
|
+
if (stream_global->id != 0 && !transport_global->is_client) {
|
1483
|
+
/* Hand roll a header block.
|
1484
|
+
This is unnecessarily ugly - at some point we should find a more elegant
|
1485
|
+
solution.
|
1486
|
+
It's complicated by the fact that our send machinery would be dead by the
|
1487
|
+
time we got around to sending this, so instead we ignore HPACK
|
1488
|
+
compression
|
1489
|
+
and just write the uncompressed bytes onto the wire. */
|
1490
|
+
status_hdr = gpr_slice_malloc(15 + (status >= 10));
|
1491
|
+
p = GPR_SLICE_START_PTR(status_hdr);
|
1492
|
+
*p++ = 0x40; /* literal header */
|
1493
|
+
*p++ = 11; /* len(grpc-status) */
|
1409
1494
|
*p++ = 'g';
|
1410
1495
|
*p++ = 'r';
|
1411
1496
|
*p++ = 'p';
|
1412
1497
|
*p++ = 'c';
|
1413
1498
|
*p++ = '-';
|
1414
|
-
*p++ = 'm';
|
1415
|
-
*p++ = 'e';
|
1416
|
-
*p++ = 's';
|
1417
1499
|
*p++ = 's';
|
1500
|
+
*p++ = 't';
|
1418
1501
|
*p++ = 'a';
|
1419
|
-
*p++ = '
|
1420
|
-
*p++ = '
|
1421
|
-
*p++ =
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1502
|
+
*p++ = 't';
|
1503
|
+
*p++ = 'u';
|
1504
|
+
*p++ = 's';
|
1505
|
+
if (status < 10) {
|
1506
|
+
*p++ = 1;
|
1507
|
+
*p++ = (uint8_t)('0' + status);
|
1508
|
+
} else {
|
1509
|
+
*p++ = 2;
|
1510
|
+
*p++ = (uint8_t)('0' + (status / 10));
|
1511
|
+
*p++ = (uint8_t)('0' + (status % 10));
|
1512
|
+
}
|
1513
|
+
GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr));
|
1514
|
+
len += (uint32_t)GPR_SLICE_LENGTH(status_hdr);
|
1515
|
+
|
1516
|
+
if (optional_message) {
|
1517
|
+
GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127);
|
1518
|
+
message_pfx = gpr_slice_malloc(15);
|
1519
|
+
p = GPR_SLICE_START_PTR(message_pfx);
|
1520
|
+
*p++ = 0x40;
|
1521
|
+
*p++ = 12; /* len(grpc-message) */
|
1522
|
+
*p++ = 'g';
|
1523
|
+
*p++ = 'r';
|
1524
|
+
*p++ = 'p';
|
1525
|
+
*p++ = 'c';
|
1526
|
+
*p++ = '-';
|
1527
|
+
*p++ = 'm';
|
1528
|
+
*p++ = 'e';
|
1529
|
+
*p++ = 's';
|
1530
|
+
*p++ = 's';
|
1531
|
+
*p++ = 'a';
|
1532
|
+
*p++ = 'g';
|
1533
|
+
*p++ = 'e';
|
1534
|
+
*p++ = (uint8_t)GPR_SLICE_LENGTH(*optional_message);
|
1535
|
+
GPR_ASSERT(p == GPR_SLICE_END_PTR(message_pfx));
|
1536
|
+
len += (uint32_t)GPR_SLICE_LENGTH(message_pfx);
|
1537
|
+
len += (uint32_t)GPR_SLICE_LENGTH(*optional_message);
|
1538
|
+
}
|
1447
1539
|
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1540
|
+
hdr = gpr_slice_malloc(9);
|
1541
|
+
p = GPR_SLICE_START_PTR(hdr);
|
1542
|
+
*p++ = (uint8_t)(len >> 16);
|
1543
|
+
*p++ = (uint8_t)(len >> 8);
|
1544
|
+
*p++ = (uint8_t)(len);
|
1545
|
+
*p++ = GRPC_CHTTP2_FRAME_HEADER;
|
1546
|
+
*p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS;
|
1547
|
+
*p++ = (uint8_t)(stream_global->id >> 24);
|
1548
|
+
*p++ = (uint8_t)(stream_global->id >> 16);
|
1549
|
+
*p++ = (uint8_t)(stream_global->id >> 8);
|
1550
|
+
*p++ = (uint8_t)(stream_global->id);
|
1551
|
+
GPR_ASSERT(p == GPR_SLICE_END_PTR(hdr));
|
1552
|
+
|
1553
|
+
gpr_slice_buffer_add(&transport_global->qbuf, hdr);
|
1554
|
+
gpr_slice_buffer_add(&transport_global->qbuf, status_hdr);
|
1555
|
+
if (optional_message) {
|
1556
|
+
gpr_slice_buffer_add(&transport_global->qbuf, message_pfx);
|
1557
|
+
gpr_slice_buffer_add(&transport_global->qbuf,
|
1558
|
+
gpr_slice_ref(*optional_message));
|
1559
|
+
}
|
1452
1560
|
|
1453
|
-
|
1454
|
-
|
1561
|
+
gpr_slice_buffer_add(
|
1562
|
+
&transport_global->qbuf,
|
1563
|
+
grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR,
|
1564
|
+
&stream_global->stats.outgoing));
|
1565
|
+
|
1566
|
+
if (optional_message) {
|
1567
|
+
gpr_slice_ref(*optional_message);
|
1568
|
+
}
|
1455
1569
|
}
|
1570
|
+
|
1456
1571
|
grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
|
1457
1572
|
optional_message);
|
1573
|
+
grpc_error *err = GRPC_ERROR_CREATE("Stream closed");
|
1574
|
+
err = grpc_error_set_int(err, GRPC_ERROR_INT_GRPC_STATUS, status);
|
1575
|
+
if (optional_message) {
|
1576
|
+
char *str =
|
1577
|
+
gpr_dump_slice(*optional_message, GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
1578
|
+
err = grpc_error_set_str(err, GRPC_ERROR_STR_GRPC_MESSAGE, str);
|
1579
|
+
gpr_free(str);
|
1580
|
+
}
|
1458
1581
|
grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1,
|
1459
|
-
1);
|
1582
|
+
1, err);
|
1460
1583
|
}
|
1461
1584
|
|
1462
1585
|
static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global,
|
1463
1586
|
void *user_data,
|
1464
1587
|
grpc_chttp2_stream_global *stream_global) {
|
1588
|
+
grpc_chttp2_transport *transport = TRANSPORT_FROM_GLOBAL(transport_global);
|
1465
1589
|
cancel_from_api(user_data, transport_global, stream_global,
|
1466
|
-
GRPC_STATUS_UNAVAILABLE
|
1590
|
+
GRPC_STATUS_UNAVAILABLE,
|
1591
|
+
GPR_SLICE_IS_EMPTY(transport->optional_drop_message)
|
1592
|
+
? NULL
|
1593
|
+
: &transport->optional_drop_message);
|
1467
1594
|
}
|
1468
1595
|
|
1469
1596
|
static void end_all_the_calls(grpc_exec_ctx *exec_ctx,
|
@@ -1471,8 +1598,9 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx,
|
|
1471
1598
|
grpc_chttp2_for_all_streams(&t->global, exec_ctx, cancel_stream_cb);
|
1472
1599
|
}
|
1473
1600
|
|
1474
|
-
static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t
|
1475
|
-
|
1601
|
+
static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1602
|
+
grpc_error *error) {
|
1603
|
+
close_transport_locked(exec_ctx, t, error);
|
1476
1604
|
end_all_the_calls(exec_ctx, t);
|
1477
1605
|
}
|
1478
1606
|
|
@@ -1503,20 +1631,22 @@ static void update_global_window(void *args, uint32_t id, void *stream) {
|
|
1503
1631
|
static void reading_action_locked(grpc_exec_ctx *exec_ctx,
|
1504
1632
|
grpc_chttp2_transport *t,
|
1505
1633
|
grpc_chttp2_stream *s_unused, void *arg);
|
1506
|
-
static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg,
|
1634
|
+
static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg,
|
1635
|
+
grpc_error *error);
|
1507
1636
|
static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
1508
1637
|
grpc_chttp2_transport *t,
|
1509
1638
|
grpc_chttp2_stream *s_unused, void *arg);
|
1510
1639
|
static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
1511
1640
|
grpc_chttp2_stream *s_unused, void *arg);
|
1512
1641
|
|
1513
|
-
static void reading_action(grpc_exec_ctx *exec_ctx, void *tp,
|
1642
|
+
static void reading_action(grpc_exec_ctx *exec_ctx, void *tp,
|
1643
|
+
grpc_error *error) {
|
1514
1644
|
/* Control flow:
|
1515
1645
|
reading_action_locked ->
|
1516
1646
|
(parse_unlocked -> post_parse_locked)? ->
|
1517
1647
|
post_reading_action_locked */
|
1518
1648
|
grpc_chttp2_run_with_global_lock(exec_ctx, tp, NULL, reading_action_locked,
|
1519
|
-
(
|
1649
|
+
GRPC_ERROR_REF(error), 0);
|
1520
1650
|
}
|
1521
1651
|
|
1522
1652
|
static void reading_action_locked(grpc_exec_ctx *exec_ctx,
|
@@ -1524,7 +1654,7 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1524
1654
|
grpc_chttp2_stream *s_unused, void *arg) {
|
1525
1655
|
grpc_chttp2_transport_global *transport_global = &t->global;
|
1526
1656
|
grpc_chttp2_transport_parsing *transport_parsing = &t->parsing;
|
1527
|
-
|
1657
|
+
grpc_error *error = arg;
|
1528
1658
|
|
1529
1659
|
GPR_ASSERT(!t->executor.parsing_active);
|
1530
1660
|
if (!t->closed) {
|
@@ -1533,27 +1663,73 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1533
1663
|
grpc_chttp2_stream_map_move_into(&t->new_stream_map,
|
1534
1664
|
&t->parsing_stream_map);
|
1535
1665
|
grpc_chttp2_prepare_to_read(transport_global, transport_parsing);
|
1536
|
-
|
1666
|
+
grpc_exec_ctx_sched(exec_ctx, &t->parsing_action, error, NULL);
|
1537
1667
|
} else {
|
1538
1668
|
post_reading_action_locked(exec_ctx, t, s_unused, arg);
|
1539
1669
|
}
|
1540
1670
|
}
|
1541
1671
|
|
1542
|
-
static
|
1672
|
+
static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
|
1673
|
+
grpc_chttp2_transport *t) {
|
1674
|
+
grpc_http_parser parser;
|
1675
|
+
size_t i = 0;
|
1676
|
+
grpc_error *error = GRPC_ERROR_NONE;
|
1677
|
+
grpc_http_response response;
|
1678
|
+
memset(&response, 0, sizeof(response));
|
1679
|
+
|
1680
|
+
grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
|
1681
|
+
|
1682
|
+
grpc_error *parse_error = GRPC_ERROR_NONE;
|
1683
|
+
for (; i < t->read_buffer.count && parse_error == GRPC_ERROR_NONE; i++) {
|
1684
|
+
parse_error = grpc_http_parser_parse(&parser, t->read_buffer.slices[i]);
|
1685
|
+
}
|
1686
|
+
if (parse_error == GRPC_ERROR_NONE &&
|
1687
|
+
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) {
|
1688
|
+
error = grpc_error_set_int(
|
1689
|
+
GRPC_ERROR_CREATE("Trying to connect an http1.x server"),
|
1690
|
+
GRPC_ERROR_INT_HTTP_STATUS, response.status);
|
1691
|
+
}
|
1692
|
+
GRPC_ERROR_UNREF(parse_error);
|
1693
|
+
|
1694
|
+
grpc_http_parser_destroy(&parser);
|
1695
|
+
grpc_http_response_destroy(&response);
|
1696
|
+
return error;
|
1697
|
+
}
|
1698
|
+
|
1699
|
+
static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg,
|
1700
|
+
grpc_error *error) {
|
1543
1701
|
grpc_chttp2_transport *t = arg;
|
1544
1702
|
GPR_TIMER_BEGIN("reading_action.parse", 0);
|
1545
1703
|
size_t i = 0;
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1704
|
+
grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE,
|
1705
|
+
GRPC_ERROR_NONE};
|
1706
|
+
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) {
|
1707
|
+
errors[1] = grpc_chttp2_perform_read(exec_ctx, &t->parsing,
|
1708
|
+
t->read_buffer.slices[i]);
|
1709
|
+
};
|
1551
1710
|
if (i != t->read_buffer.count) {
|
1552
|
-
|
1711
|
+
gpr_slice_unref(t->optional_drop_message);
|
1712
|
+
errors[2] = try_http_parsing(exec_ctx, t);
|
1713
|
+
if (errors[2] != GRPC_ERROR_NONE) {
|
1714
|
+
t->optional_drop_message = gpr_slice_from_copied_string(
|
1715
|
+
"Connection dropped: received http1.x response");
|
1716
|
+
} else {
|
1717
|
+
t->optional_drop_message = gpr_slice_from_copied_string(
|
1718
|
+
"Connection dropped: received unparseable response");
|
1719
|
+
}
|
1720
|
+
}
|
1721
|
+
grpc_error *err =
|
1722
|
+
errors[0] == GRPC_ERROR_NONE && errors[1] == GRPC_ERROR_NONE &&
|
1723
|
+
errors[2] == GRPC_ERROR_NONE
|
1724
|
+
? GRPC_ERROR_NONE
|
1725
|
+
: GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors,
|
1726
|
+
GPR_ARRAY_SIZE(errors));
|
1727
|
+
for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) {
|
1728
|
+
GRPC_ERROR_UNREF(errors[i]);
|
1553
1729
|
}
|
1554
1730
|
GPR_TIMER_END("reading_action.parse", 0);
|
1555
|
-
grpc_chttp2_run_with_global_lock(exec_ctx, t, NULL, post_parse_locked,
|
1556
|
-
|
1731
|
+
grpc_chttp2_run_with_global_lock(exec_ctx, t, NULL, post_parse_locked, err,
|
1732
|
+
0);
|
1557
1733
|
}
|
1558
1734
|
|
1559
1735
|
static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
@@ -1590,7 +1766,8 @@ static void post_parse_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
|
|
1590
1766
|
GPR_ASSERT(stream_global->in_stream_map);
|
1591
1767
|
GPR_ASSERT(stream_global->write_closed);
|
1592
1768
|
GPR_ASSERT(stream_global->read_closed);
|
1593
|
-
remove_stream(exec_ctx, t, stream_global->id
|
1769
|
+
remove_stream(exec_ctx, t, stream_global->id,
|
1770
|
+
GRPC_ERROR_CREATE("Stream removed"));
|
1594
1771
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
|
1595
1772
|
}
|
1596
1773
|
|
@@ -1601,10 +1778,13 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1601
1778
|
grpc_chttp2_transport *t,
|
1602
1779
|
grpc_chttp2_stream *s_unused,
|
1603
1780
|
void *arg) {
|
1604
|
-
|
1781
|
+
grpc_error *error = arg;
|
1605
1782
|
bool keep_reading = false;
|
1606
|
-
if (
|
1607
|
-
|
1783
|
+
if (error == GRPC_ERROR_NONE && t->closed) {
|
1784
|
+
error = GRPC_ERROR_CREATE("Transport closed");
|
1785
|
+
}
|
1786
|
+
if (error != GRPC_ERROR_NONE) {
|
1787
|
+
drop_connection(exec_ctx, t, GRPC_ERROR_REF(error));
|
1608
1788
|
t->endpoint_reading = 0;
|
1609
1789
|
if (!t->executor.writing_active && t->ep) {
|
1610
1790
|
grpc_endpoint_destroy(exec_ctx, t->ep);
|
@@ -1626,6 +1806,8 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1626
1806
|
} else {
|
1627
1807
|
UNREF_TRANSPORT(exec_ctx, t, "reading_action");
|
1628
1808
|
}
|
1809
|
+
|
1810
|
+
GRPC_LOG_IF_ERROR("close_transport", error);
|
1629
1811
|
}
|
1630
1812
|
|
1631
1813
|
/*******************************************************************************
|
@@ -1634,13 +1816,13 @@ static void post_reading_action_locked(grpc_exec_ctx *exec_ctx,
|
|
1634
1816
|
|
1635
1817
|
static void connectivity_state_set(
|
1636
1818
|
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
|
1637
|
-
grpc_connectivity_state state, const char *reason) {
|
1819
|
+
grpc_connectivity_state state, grpc_error *error, const char *reason) {
|
1638
1820
|
GRPC_CHTTP2_IF_TRACING(
|
1639
1821
|
gpr_log(GPR_DEBUG, "set connectivity_state=%d", state));
|
1640
1822
|
grpc_connectivity_state_set(
|
1641
1823
|
exec_ctx,
|
1642
1824
|
&TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker,
|
1643
|
-
state, reason);
|
1825
|
+
state, error, reason);
|
1644
1826
|
}
|
1645
1827
|
|
1646
1828
|
/*******************************************************************************
|
@@ -1672,6 +1854,13 @@ static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
1672
1854
|
add_to_pollset_locked, pollset, 0);
|
1673
1855
|
}
|
1674
1856
|
|
1857
|
+
static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
1858
|
+
grpc_stream *gs, grpc_pollset_set *pollset_set) {
|
1859
|
+
grpc_chttp2_run_with_global_lock(exec_ctx, (grpc_chttp2_transport *)gt,
|
1860
|
+
(grpc_chttp2_stream *)gs,
|
1861
|
+
add_to_pollset_set_locked, pollset_set, 0);
|
1862
|
+
}
|
1863
|
+
|
1675
1864
|
/*******************************************************************************
|
1676
1865
|
* BYTE STREAM
|
1677
1866
|
*/
|
@@ -1679,6 +1868,7 @@ static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
|
|
1679
1868
|
static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
|
1680
1869
|
grpc_chttp2_incoming_byte_stream *bs) {
|
1681
1870
|
if (gpr_unref(&bs->refs)) {
|
1871
|
+
GRPC_ERROR_UNREF(bs->error);
|
1682
1872
|
gpr_slice_buffer_destroy(&bs->slices);
|
1683
1873
|
gpr_free(bs);
|
1684
1874
|
}
|
@@ -1747,9 +1937,10 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
|
|
1747
1937
|
}
|
1748
1938
|
if (bs->slices.count > 0) {
|
1749
1939
|
*arg->slice = gpr_slice_buffer_take_first(&bs->slices);
|
1750
|
-
|
1751
|
-
} else if (bs->
|
1752
|
-
|
1940
|
+
grpc_exec_ctx_sched(exec_ctx, arg->on_complete, GRPC_ERROR_NONE, NULL);
|
1941
|
+
} else if (bs->error != GRPC_ERROR_NONE) {
|
1942
|
+
grpc_exec_ctx_sched(exec_ctx, arg->on_complete, GRPC_ERROR_REF(bs->error),
|
1943
|
+
NULL);
|
1753
1944
|
} else {
|
1754
1945
|
bs->on_next = arg->on_complete;
|
1755
1946
|
bs->next = arg->slice;
|
@@ -1806,7 +1997,7 @@ static void incoming_byte_stream_push_locked(grpc_exec_ctx *exec_ctx,
|
|
1806
1997
|
grpc_chttp2_incoming_byte_stream *bs = arg->byte_stream;
|
1807
1998
|
if (bs->on_next != NULL) {
|
1808
1999
|
*bs->next = arg->slice;
|
1809
|
-
|
2000
|
+
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_NONE, NULL);
|
1810
2001
|
bs->on_next = NULL;
|
1811
2002
|
} else {
|
1812
2003
|
gpr_slice_buffer_add(&bs->slices, arg->slice);
|
@@ -1824,13 +2015,30 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx,
|
|
1824
2015
|
sizeof(arg));
|
1825
2016
|
}
|
1826
2017
|
|
2018
|
+
typedef struct {
|
2019
|
+
grpc_chttp2_incoming_byte_stream *bs;
|
2020
|
+
grpc_error *error;
|
2021
|
+
} bs_fail_args;
|
2022
|
+
|
2023
|
+
static bs_fail_args *make_bs_fail_args(grpc_chttp2_incoming_byte_stream *bs,
|
2024
|
+
grpc_error *error) {
|
2025
|
+
bs_fail_args *a = gpr_malloc(sizeof(*a));
|
2026
|
+
a->bs = bs;
|
2027
|
+
a->error = error;
|
2028
|
+
return a;
|
2029
|
+
}
|
2030
|
+
|
1827
2031
|
static void incoming_byte_stream_finished_failed_locked(
|
1828
2032
|
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s,
|
1829
2033
|
void *argp) {
|
1830
|
-
|
1831
|
-
|
2034
|
+
bs_fail_args *a = argp;
|
2035
|
+
grpc_chttp2_incoming_byte_stream *bs = a->bs;
|
2036
|
+
grpc_error *error = a->error;
|
2037
|
+
gpr_free(a);
|
2038
|
+
grpc_exec_ctx_sched(exec_ctx, bs->on_next, GRPC_ERROR_REF(error), NULL);
|
1832
2039
|
bs->on_next = NULL;
|
1833
|
-
bs->
|
2040
|
+
GRPC_ERROR_UNREF(bs->error);
|
2041
|
+
bs->error = error;
|
1834
2042
|
incoming_byte_stream_unref(exec_ctx, bs);
|
1835
2043
|
}
|
1836
2044
|
|
@@ -1843,25 +2051,26 @@ static void incoming_byte_stream_finished_ok_locked(grpc_exec_ctx *exec_ctx,
|
|
1843
2051
|
}
|
1844
2052
|
|
1845
2053
|
void grpc_chttp2_incoming_byte_stream_finished(
|
1846
|
-
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
|
1847
|
-
int from_parsing_thread) {
|
2054
|
+
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs,
|
2055
|
+
grpc_error *error, int from_parsing_thread) {
|
1848
2056
|
if (from_parsing_thread) {
|
1849
|
-
if (
|
2057
|
+
if (error == GRPC_ERROR_NONE) {
|
1850
2058
|
grpc_chttp2_run_with_global_lock(exec_ctx, bs->transport, bs->stream,
|
1851
2059
|
incoming_byte_stream_finished_ok_locked,
|
1852
2060
|
bs, 0);
|
1853
2061
|
} else {
|
1854
|
-
incoming_byte_stream_finished_ok_locked(exec_ctx, bs->transport,
|
1855
|
-
bs->stream, bs);
|
1856
|
-
}
|
1857
|
-
} else {
|
1858
|
-
if (success) {
|
1859
2062
|
grpc_chttp2_run_with_global_lock(
|
1860
2063
|
exec_ctx, bs->transport, bs->stream,
|
1861
|
-
incoming_byte_stream_finished_failed_locked,
|
2064
|
+
incoming_byte_stream_finished_failed_locked,
|
2065
|
+
make_bs_fail_args(bs, error), 0);
|
2066
|
+
}
|
2067
|
+
} else {
|
2068
|
+
if (error == GRPC_ERROR_NONE) {
|
2069
|
+
incoming_byte_stream_finished_ok_locked(exec_ctx, bs->transport,
|
2070
|
+
bs->stream, bs);
|
1862
2071
|
} else {
|
1863
|
-
incoming_byte_stream_finished_failed_locked(
|
1864
|
-
|
2072
|
+
incoming_byte_stream_finished_failed_locked(
|
2073
|
+
exec_ctx, bs->transport, bs->stream, make_bs_fail_args(bs, error));
|
1865
2074
|
}
|
1866
2075
|
}
|
1867
2076
|
}
|
@@ -1884,7 +2093,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
|
|
1884
2093
|
gpr_slice_buffer_init(&incoming_byte_stream->slices);
|
1885
2094
|
incoming_byte_stream->on_next = NULL;
|
1886
2095
|
incoming_byte_stream->is_tail = 1;
|
1887
|
-
incoming_byte_stream->
|
2096
|
+
incoming_byte_stream->error = GRPC_ERROR_NONE;
|
1888
2097
|
if (add_to_queue->head == NULL) {
|
1889
2098
|
add_to_queue->head = incoming_byte_stream;
|
1890
2099
|
} else {
|
@@ -1903,10 +2112,13 @@ static char *format_flowctl_context_var(const char *context, const char *var,
|
|
1903
2112
|
int64_t val, uint32_t id,
|
1904
2113
|
char **scope) {
|
1905
2114
|
char *underscore_pos;
|
2115
|
+
char *buf;
|
1906
2116
|
char *result;
|
1907
2117
|
if (context == NULL) {
|
1908
2118
|
*scope = NULL;
|
1909
|
-
gpr_asprintf(&
|
2119
|
+
gpr_asprintf(&buf, "%s(%" PRId64 ")", var, val);
|
2120
|
+
result = gpr_leftpad(buf, ' ', 40);
|
2121
|
+
gpr_free(buf);
|
1910
2122
|
return result;
|
1911
2123
|
}
|
1912
2124
|
underscore_pos = strchr(context, '_');
|
@@ -1917,7 +2129,9 @@ static char *format_flowctl_context_var(const char *context, const char *var,
|
|
1917
2129
|
gpr_asprintf(scope, "%s[%d]", tmp, id);
|
1918
2130
|
gpr_free(tmp);
|
1919
2131
|
}
|
1920
|
-
gpr_asprintf(&
|
2132
|
+
gpr_asprintf(&buf, "%s.%s(%" PRId64 ")", underscore_pos + 1, var, val);
|
2133
|
+
result = gpr_leftpad(buf, ' ', 40);
|
2134
|
+
gpr_free(buf);
|
1921
2135
|
return result;
|
1922
2136
|
}
|
1923
2137
|
|
@@ -1938,6 +2152,8 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
1938
2152
|
uint32_t stream_id, int64_t val1, int64_t val2) {
|
1939
2153
|
char *scope1;
|
1940
2154
|
char *scope2;
|
2155
|
+
char *tmp_phase;
|
2156
|
+
char *tmp_scope1;
|
1941
2157
|
char *label1 =
|
1942
2158
|
format_flowctl_context_var(context1, var1, val1, stream_id, &scope1);
|
1943
2159
|
char *label2 =
|
@@ -1945,14 +2161,18 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
1945
2161
|
char *clisvr = is_client ? "client" : "server";
|
1946
2162
|
char *prefix;
|
1947
2163
|
|
1948
|
-
|
2164
|
+
tmp_phase = gpr_leftpad(phase, ' ', 8);
|
2165
|
+
tmp_scope1 = gpr_leftpad(scope1, ' ', 11);
|
2166
|
+
gpr_asprintf(&prefix, "FLOW %s: %s %s ", phase, clisvr, scope1);
|
2167
|
+
gpr_free(tmp_phase);
|
2168
|
+
gpr_free(tmp_scope1);
|
1949
2169
|
|
1950
2170
|
switch (op) {
|
1951
2171
|
case GRPC_CHTTP2_FLOWCTL_MOVE:
|
1952
2172
|
GPR_ASSERT(samestr(scope1, scope2));
|
1953
2173
|
if (val2 != 0) {
|
1954
2174
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
1955
|
-
"%sMOVE %
|
2175
|
+
"%sMOVE %s <- %s giving %" PRId64, prefix, label1, label2,
|
1956
2176
|
val1 + val2);
|
1957
2177
|
}
|
1958
2178
|
break;
|
@@ -1960,7 +2180,7 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
1960
2180
|
GPR_ASSERT(val2 >= 0);
|
1961
2181
|
if (val2 != 0) {
|
1962
2182
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
1963
|
-
"%sCREDIT %
|
2183
|
+
"%sCREDIT %s by %s giving %" PRId64, prefix, label1, label2,
|
1964
2184
|
val1 + val2);
|
1965
2185
|
}
|
1966
2186
|
break;
|
@@ -1968,7 +2188,7 @@ void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
|
|
1968
2188
|
GPR_ASSERT(val2 >= 0);
|
1969
2189
|
if (val2 != 0) {
|
1970
2190
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
1971
|
-
"%sDEBIT %
|
2191
|
+
"%sDEBIT %s by %s giving %" PRId64, prefix, label1, label2,
|
1972
2192
|
val1 - val2);
|
1973
2193
|
}
|
1974
2194
|
break;
|
@@ -1993,6 +2213,7 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
|
|
1993
2213
|
"chttp2",
|
1994
2214
|
init_stream,
|
1995
2215
|
set_pollset,
|
2216
|
+
set_pollset_set,
|
1996
2217
|
perform_stream_op,
|
1997
2218
|
perform_transport_op,
|
1998
2219
|
destroy_stream,
|
@@ -2013,5 +2234,5 @@ void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
|
|
2013
2234
|
grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport;
|
2014
2235
|
REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */
|
2015
2236
|
gpr_slice_buffer_addn(&t->read_buffer, slices, nslices);
|
2016
|
-
reading_action(exec_ctx, t,
|
2237
|
+
reading_action(exec_ctx, t, GRPC_ERROR_NONE);
|
2017
2238
|
}
|