From af76743e33891f269ff2404ba8a631a97f6b50c0 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 3 Apr 2017 13:54:31 -0700 Subject: Optionalize compress, gather all the http2 filter bits together in ext/ --- src/core/ext/filters/http/http_filters_plugin.c | 106 ++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/core/ext/filters/http/http_filters_plugin.c (limited to 'src/core/ext/filters/http/http_filters_plugin.c') diff --git a/src/core/ext/filters/http/http_filters_plugin.c b/src/core/ext/filters/http/http_filters_plugin.c new file mode 100644 index 0000000000..a6e35bc181 --- /dev/null +++ b/src/core/ext/filters/http/http_filters_plugin.c @@ -0,0 +1,106 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include "src/core/ext/filters/http/client/http_client_filter.h" +#include "src/core/ext/filters/http/compress/compress_filter.h" +#include "src/core/ext/filters/http/server/http_server_filter.h" +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/transport/transport_impl.h" + +typedef struct { + const grpc_channel_filter *filter; + const char *control_channel_arg; +} optional_filter; + +static optional_filter compress_filter = { + &grpc_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION}; + +static bool is_building_http_like_transport( + grpc_channel_stack_builder *builder) { + grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); + return t && strstr(t->vtable->name, "http"); +} + +static bool maybe_add_optional_filter(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, + void *arg) { + if (!is_building_http_like_transport(builder)) return true; + optional_filter *filtarg = arg; + const grpc_channel_args *channel_args = + grpc_channel_stack_builder_get_channel_arguments(builder); + bool enable = !grpc_channel_args_want_minimal_stack(channel_args); + const grpc_arg *ctlarg = + grpc_channel_args_find(channel_args, filtarg->control_channel_arg); + if (ctlarg != NULL) { + enable = !(ctlarg->type == GRPC_ARG_INTEGER && ctlarg->value.integer == 0); + } + return enable ? grpc_channel_stack_builder_prepend_filter( + builder, filtarg->filter, NULL, NULL) + : true; +} + +static bool maybe_add_required_filter(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, + void *arg) { + return is_building_http_like_transport(builder) + ? grpc_channel_stack_builder_prepend_filter( + builder, (const grpc_channel_filter *)arg, NULL, NULL) + : true; +} + +void grpc_http_filters_init(void) { + grpc_register_tracer("compression", &grpc_compression_trace); + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_optional_filter, &compress_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_optional_filter, &compress_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_optional_filter, &compress_filter); + grpc_channel_init_register_stage( + GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_required_filter, (void *)&grpc_http_client_filter); + grpc_channel_init_register_stage( + GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_required_filter, (void *)&grpc_http_client_filter); + grpc_channel_init_register_stage( + GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_required_filter, (void *)&grpc_http_server_filter); +} + +void grpc_http_filters_shutdown(void) {} -- cgit v1.2.3 From a24b971214a3d95ddb86f6c04171b84c26da2a61 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 6 Apr 2017 09:03:21 -0700 Subject: Rename compress_filter --> message_compress_filter --- BUILD | 4 +- CMakeLists.txt | 8 +- Makefile | 8 +- binding.gyp | 2 +- build.yaml | 4 +- config.m4 | 2 +- gRPC-Core.podspec | 6 +- grpc.gemspec | 4 +- package.xml | 4 +- .../ext/filters/http/compress/compress_filter.c | 353 --------------------- .../ext/filters/http/compress/compress_filter.h | 67 ---- src/core/ext/filters/http/http_filters_plugin.c | 2 +- .../message_compress/message_compress_filter.c | 353 +++++++++++++++++++++ .../message_compress/message_compress_filter.h | 67 ++++ src/python/grpcio/grpc_core_dependencies.py | 2 +- test/core/end2end/fixtures/h2_sockpair+trace.c | 2 +- test/core/end2end/fixtures/h2_sockpair.c | 2 +- test/core/end2end/fixtures/h2_sockpair_1byte.c | 2 +- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- tools/doxygen/Doxyfile.core.internal | 4 +- tools/run_tests/generated/sources_and_headers.json | 6 +- 21 files changed, 452 insertions(+), 452 deletions(-) delete mode 100644 src/core/ext/filters/http/compress/compress_filter.c delete mode 100644 src/core/ext/filters/http/compress/compress_filter.h create mode 100644 src/core/ext/filters/http/message_compress/message_compress_filter.c create mode 100644 src/core/ext/filters/http/message_compress/message_compress_filter.h (limited to 'src/core/ext/filters/http/http_filters_plugin.c') diff --git a/BUILD b/BUILD index bc4f4eb978..83cf3e651a 100644 --- a/BUILD +++ b/BUILD @@ -780,12 +780,12 @@ grpc_cc_library( grpc_cc_library( name = "grpc_http_filters", hdrs = [ - "src/core/ext/filters/http/compress/compress_filter.h", + "src/core/ext/filters/http/message_compress/message_compress_filter.h", "src/core/ext/filters/http/client/http_client_filter.h", "src/core/ext/filters/http/server/http_server_filter.h", ], srcs = [ - "src/core/ext/filters/http/compress/compress_filter.c", + "src/core/ext/filters/http/message_compress/message_compress_filter.c", "src/core/ext/filters/http/client/http_client_filter.c", "src/core/ext/filters/http/server/http_server_filter.c", "src/core/ext/filters/http/http_filters_plugin.c" diff --git a/CMakeLists.txt b/CMakeLists.txt index 089e028bff..f79d7154a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1051,7 +1051,7 @@ add_library(grpc src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c src/core/ext/filters/http/client/http_client_filter.c - src/core/ext/filters/http/compress/compress_filter.c + src/core/ext/filters/http/message_compress/message_compress_filter.c src/core/ext/filters/http/http_filters_plugin.c src/core/ext/filters/http/server/http_server_filter.c src/core/lib/http/httpcli_security_connector.c @@ -1377,7 +1377,7 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c src/core/ext/filters/http/client/http_client_filter.c - src/core/ext/filters/http/compress/compress_filter.c + src/core/ext/filters/http/message_compress/message_compress_filter.c src/core/ext/filters/http/http_filters_plugin.c src/core/ext/filters/http/server/http_server_filter.c src/core/ext/filters/client_channel/channel_connectivity.c @@ -1939,7 +1939,7 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c src/core/ext/filters/http/client/http_client_filter.c - src/core/ext/filters/http/compress/compress_filter.c + src/core/ext/filters/http/message_compress/message_compress_filter.c src/core/ext/filters/http/http_filters_plugin.c src/core/ext/filters/http/server/http_server_filter.c src/core/ext/transport/chttp2/server/chttp2_server.c @@ -2687,7 +2687,7 @@ add_library(grpc++_cronet src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c src/core/ext/filters/http/client/http_client_filter.c - src/core/ext/filters/http/compress/compress_filter.c + src/core/ext/filters/http/message_compress/message_compress_filter.c src/core/ext/filters/http/http_filters_plugin.c src/core/ext/filters/http/server/http_server_filter.c src/core/ext/filters/client_channel/channel_connectivity.c diff --git a/Makefile b/Makefile index 035e92f8e4..f2ee6901cf 100644 --- a/Makefile +++ b/Makefile @@ -2956,7 +2956,7 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/filters/http/client/http_client_filter.c \ - src/core/ext/filters/http/compress/compress_filter.c \ + src/core/ext/filters/http/message_compress/message_compress_filter.c \ src/core/ext/filters/http/http_filters_plugin.c \ src/core/ext/filters/http/server/http_server_filter.c \ src/core/lib/http/httpcli_security_connector.c \ @@ -3280,7 +3280,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/filters/http/client/http_client_filter.c \ - src/core/ext/filters/http/compress/compress_filter.c \ + src/core/ext/filters/http/message_compress/message_compress_filter.c \ src/core/ext/filters/http/http_filters_plugin.c \ src/core/ext/filters/http/server/http_server_filter.c \ src/core/ext/filters/client_channel/channel_connectivity.c \ @@ -3813,7 +3813,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/filters/http/client/http_client_filter.c \ - src/core/ext/filters/http/compress/compress_filter.c \ + src/core/ext/filters/http/message_compress/message_compress_filter.c \ src/core/ext/filters/http/http_filters_plugin.c \ src/core/ext/filters/http/server/http_server_filter.c \ src/core/ext/transport/chttp2/server/chttp2_server.c \ @@ -4546,7 +4546,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/filters/http/client/http_client_filter.c \ - src/core/ext/filters/http/compress/compress_filter.c \ + src/core/ext/filters/http/message_compress/message_compress_filter.c \ src/core/ext/filters/http/http_filters_plugin.c \ src/core/ext/filters/http/server/http_server_filter.c \ src/core/ext/filters/client_channel/channel_connectivity.c \ diff --git a/binding.gyp b/binding.gyp index ad9d7c8f28..21cd56e684 100644 --- a/binding.gyp +++ b/binding.gyp @@ -792,7 +792,7 @@ 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', 'src/core/ext/filters/http/client/http_client_filter.c', - 'src/core/ext/filters/http/compress/compress_filter.c', + 'src/core/ext/filters/http/message_compress/message_compress_filter.c', 'src/core/ext/filters/http/http_filters_plugin.c', 'src/core/ext/filters/http/server/http_server_filter.c', 'src/core/lib/http/httpcli_security_connector.c', diff --git a/build.yaml b/build.yaml index 1df62654a4..2d52b38fbf 100644 --- a/build.yaml +++ b/build.yaml @@ -472,11 +472,11 @@ filegroups: - name: grpc_http_filters headers: - src/core/ext/filters/http/client/http_client_filter.h - - src/core/ext/filters/http/compress/compress_filter.h + - src/core/ext/filters/http/message_compress/message_compress_filter.h - src/core/ext/filters/http/server/http_server_filter.h src: - src/core/ext/filters/http/client/http_client_filter.c - - src/core/ext/filters/http/compress/compress_filter.c + - src/core/ext/filters/http/message_compress/message_compress_filter.c - src/core/ext/filters/http/http_filters_plugin.c - src/core/ext/filters/http/server/http_server_filter.c plugin: grpc_http_filters diff --git a/config.m4 b/config.m4 index 85593afd3c..985de08562 100644 --- a/config.m4 +++ b/config.m4 @@ -226,7 +226,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/filters/http/client/http_client_filter.c \ - src/core/ext/filters/http/compress/compress_filter.c \ + src/core/ext/filters/http/message_compress/message_compress_filter.c \ src/core/ext/filters/http/http_filters_plugin.c \ src/core/ext/filters/http/server/http_server_filter.c \ src/core/lib/http/httpcli_security_connector.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 9cd92835ac..b79a759438 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -381,7 +381,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/ext/filters/http/client/http_client_filter.h', - 'src/core/ext/filters/http/compress/compress_filter.h', + 'src/core/ext/filters/http/message_compress/message_compress_filter.h', 'src/core/ext/filters/http/server/http_server_filter.h', 'src/core/lib/security/context/security_context.h', 'src/core/lib/security/credentials/composite/composite_credentials.h', @@ -601,7 +601,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', 'src/core/ext/filters/http/client/http_client_filter.c', - 'src/core/ext/filters/http/compress/compress_filter.c', + 'src/core/ext/filters/http/message_compress/message_compress_filter.c', 'src/core/ext/filters/http/http_filters_plugin.c', 'src/core/ext/filters/http/server/http_server_filter.c', 'src/core/lib/http/httpcli_security_connector.c', @@ -832,7 +832,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/ext/filters/http/client/http_client_filter.h', - 'src/core/ext/filters/http/compress/compress_filter.h', + 'src/core/ext/filters/http/message_compress/message_compress_filter.h', 'src/core/ext/filters/http/server/http_server_filter.h', 'src/core/lib/security/context/security_context.h', 'src/core/lib/security/credentials/composite/composite_credentials.h', diff --git a/grpc.gemspec b/grpc.gemspec index 0e4a3d6fec..2a6563f879 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -297,7 +297,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/varint.h ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h ) s.files += %w( src/core/ext/filters/http/client/http_client_filter.h ) - s.files += %w( src/core/ext/filters/http/compress/compress_filter.h ) + s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.h ) s.files += %w( src/core/ext/filters/http/server/http_server_filter.h ) s.files += %w( src/core/lib/security/context/security_context.h ) s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.h ) @@ -517,7 +517,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/writing.c ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.c ) s.files += %w( src/core/ext/filters/http/client/http_client_filter.c ) - s.files += %w( src/core/ext/filters/http/compress/compress_filter.c ) + s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.c ) s.files += %w( src/core/ext/filters/http/http_filters_plugin.c ) s.files += %w( src/core/ext/filters/http/server/http_server_filter.c ) s.files += %w( src/core/lib/http/httpcli_security_connector.c ) diff --git a/package.xml b/package.xml index 8cda68a266..0771774b4c 100644 --- a/package.xml +++ b/package.xml @@ -306,7 +306,7 @@ - + @@ -526,7 +526,7 @@ - + diff --git a/src/core/ext/filters/http/compress/compress_filter.c b/src/core/ext/filters/http/compress/compress_filter.c deleted file mode 100644 index ab6c94a153..0000000000 --- a/src/core/ext/filters/http/compress/compress_filter.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include - -#include -#include -#include -#include - -#include "src/core/ext/filters/http/compress/compress_filter.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/compression/algorithm_metadata.h" -#include "src/core/lib/compression/message_compress.h" -#include "src/core/lib/profiling/timers.h" -#include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/transport/static_metadata.h" - -int grpc_compression_trace = 0; - -typedef struct call_data { - grpc_slice_buffer slices; /**< Buffers up input slices to be compressed */ - grpc_linked_mdelem compression_algorithm_storage; - grpc_linked_mdelem accept_encoding_storage; - uint32_t remaining_slice_bytes; - /** Compression algorithm we'll try to use. It may be given by incoming - * metadata, or by the channel's default compression settings. */ - grpc_compression_algorithm compression_algorithm; - /** If true, contents of \a compression_algorithm are authoritative */ - int has_compression_algorithm; - - grpc_transport_stream_op_batch *send_op; - uint32_t send_length; - uint32_t send_flags; - grpc_slice incoming_slice; - grpc_slice_buffer_stream replacement_stream; - grpc_closure *post_send; - grpc_closure send_done; - grpc_closure got_slice; -} call_data; - -typedef struct channel_data { - /** The default, channel-level, compression algorithm */ - grpc_compression_algorithm default_compression_algorithm; - /** Bitset of enabled algorithms */ - uint32_t enabled_algorithms_bitset; - /** Supported compression algorithms */ - uint32_t supported_compression_algorithms; -} channel_data; - -static int skip_compression(grpc_call_element *elem, uint32_t flags) { - call_data *calld = elem->call_data; - channel_data *channeld = elem->channel_data; - - if (flags & (GRPC_WRITE_NO_COMPRESS | GRPC_WRITE_INTERNAL_COMPRESS)) { - return 1; - } - if (calld->has_compression_algorithm) { - if (calld->compression_algorithm == GRPC_COMPRESS_NONE) { - return 1; - } - return 0; /* we have an actual call-specific algorithm */ - } - /* no per-call compression override */ - return channeld->default_compression_algorithm == GRPC_COMPRESS_NONE; -} - -/** Filter initial metadata */ -static grpc_error *process_send_initial_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_metadata_batch *initial_metadata) GRPC_MUST_USE_RESULT; -static grpc_error *process_send_initial_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_metadata_batch *initial_metadata) { - call_data *calld = elem->call_data; - channel_data *channeld = elem->channel_data; - /* Parse incoming request for compression. If any, it'll be available - * at calld->compression_algorithm */ - if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) { - grpc_mdelem md = - initial_metadata->idx.named.grpc_internal_encoding_request->md; - if (!grpc_compression_algorithm_parse(GRPC_MDVALUE(md), - &calld->compression_algorithm)) { - char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (unknown). Ignoring.", val); - gpr_free(val); - calld->compression_algorithm = GRPC_COMPRESS_NONE; - } - if (!GPR_BITGET(channeld->enabled_algorithms_bitset, - calld->compression_algorithm)) { - char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (previously disabled). " - "Ignoring.", - val); - gpr_free(val); - calld->compression_algorithm = GRPC_COMPRESS_NONE; - } - calld->has_compression_algorithm = 1; - - grpc_metadata_batch_remove( - exec_ctx, initial_metadata, - initial_metadata->idx.named.grpc_internal_encoding_request); - } else { - /* If no algorithm was found in the metadata and we aren't - * exceptionally skipping compression, fall back to the channel - * default */ - calld->compression_algorithm = channeld->default_compression_algorithm; - calld->has_compression_algorithm = 1; /* GPR_TRUE */ - } - - grpc_error *error = GRPC_ERROR_NONE; - /* hint compression algorithm */ - if (calld->compression_algorithm != GRPC_COMPRESS_NONE) { - error = grpc_metadata_batch_add_tail( - exec_ctx, initial_metadata, &calld->compression_algorithm_storage, - grpc_compression_encoding_mdelem(calld->compression_algorithm)); - } - - if (error != GRPC_ERROR_NONE) return error; - - /* convey supported compression algorithms */ - error = grpc_metadata_batch_add_tail( - exec_ctx, initial_metadata, &calld->accept_encoding_storage, - GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS( - channeld->supported_compression_algorithms)); - - return error; -} - -static void continue_send_message(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem); - -static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { - grpc_call_element *elem = elemp; - call_data *calld = elem->call_data; - grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices); - calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error); -} - -static void finish_send_message(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *calld = elem->call_data; - int did_compress; - grpc_slice_buffer tmp; - grpc_slice_buffer_init(&tmp); - did_compress = grpc_msg_compress(exec_ctx, calld->compression_algorithm, - &calld->slices, &tmp); - if (did_compress) { - if (grpc_compression_trace) { - char *algo_name; - const size_t before_size = calld->slices.length; - const size_t after_size = tmp.length; - const float savings_ratio = 1.0f - (float)after_size / (float)before_size; - GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm, - &algo_name)); - gpr_log(GPR_DEBUG, "Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR - " bytes (%.2f%% savings)", - algo_name, before_size, after_size, 100 * savings_ratio); - } - grpc_slice_buffer_swap(&calld->slices, &tmp); - calld->send_flags |= GRPC_WRITE_INTERNAL_COMPRESS; - } else { - if (grpc_compression_trace) { - char *algo_name; - GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm, - &algo_name)); - gpr_log(GPR_DEBUG, - "Algorithm '%s' enabled but decided not to compress. Input size: " - "%" PRIuPTR, - algo_name, calld->slices.length); - } - } - - grpc_slice_buffer_destroy_internal(exec_ctx, &tmp); - - grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices, - calld->send_flags); - calld->send_op->payload->send_message.send_message = - &calld->replacement_stream.base; - calld->post_send = calld->send_op->on_complete; - calld->send_op->on_complete = &calld->send_done; - - grpc_call_next_op(exec_ctx, elem, calld->send_op); -} - -static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { - grpc_call_element *elem = elemp; - call_data *calld = elem->call_data; - grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); - if (calld->send_length == calld->slices.length) { - finish_send_message(exec_ctx, elem); - } else { - continue_send_message(exec_ctx, elem); - } -} - -static void continue_send_message(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem) { - call_data *calld = elem->call_data; - while (grpc_byte_stream_next( - exec_ctx, calld->send_op->payload->send_message.send_message, - &calld->incoming_slice, ~(size_t)0, &calld->got_slice)) { - grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); - if (calld->send_length == calld->slices.length) { - finish_send_message(exec_ctx, elem); - break; - } - } -} - -static void compress_start_transport_stream_op_batch( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op_batch *op) { - call_data *calld = elem->call_data; - - GPR_TIMER_BEGIN("compress_start_transport_stream_op_batch", 0); - - if (op->send_initial_metadata) { - grpc_error *error = process_send_initial_metadata( - exec_ctx, elem, - op->payload->send_initial_metadata.send_initial_metadata); - if (error != GRPC_ERROR_NONE) { - grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error); - return; - } - } - if (op->send_message && - !skip_compression(elem, op->payload->send_message.send_message->flags)) { - calld->send_op = op; - calld->send_length = op->payload->send_message.send_message->length; - calld->send_flags = op->payload->send_message.send_message->flags; - continue_send_message(exec_ctx, elem); - } else { - /* pass control down the stack */ - grpc_call_next_op(exec_ctx, elem, op); - } - - GPR_TIMER_END("compress_start_transport_stream_op_batch", 0); -} - -/* Constructor for call_data */ -static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - const grpc_call_element_args *args) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - - /* initialize members */ - grpc_slice_buffer_init(&calld->slices); - calld->has_compression_algorithm = 0; - grpc_closure_init(&calld->got_slice, got_slice, elem, - grpc_schedule_on_exec_ctx); - grpc_closure_init(&calld->send_done, send_done, elem, - grpc_schedule_on_exec_ctx); - - return GRPC_ERROR_NONE; -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_final_info *final_info, - grpc_closure *ignored) { - /* grab pointers to our data from the call element */ - call_data *calld = elem->call_data; - grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices); -} - -/* Constructor for channel_data */ -static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *channeld = elem->channel_data; - - channeld->enabled_algorithms_bitset = - grpc_channel_args_compression_algorithm_get_states(args->channel_args); - - channeld->default_compression_algorithm = - grpc_channel_args_get_compression_algorithm(args->channel_args); - /* Make sure the default isn't disabled. */ - if (!GPR_BITGET(channeld->enabled_algorithms_bitset, - channeld->default_compression_algorithm)) { - gpr_log(GPR_DEBUG, - "compression algorithm %d not enabled: switching to none", - channeld->default_compression_algorithm); - channeld->default_compression_algorithm = GRPC_COMPRESS_NONE; - } - - channeld->supported_compression_algorithms = 1; /* always support identity */ - for (grpc_compression_algorithm algo_idx = 1; - algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) { - /* skip disabled algorithms */ - if (!GPR_BITGET(channeld->enabled_algorithms_bitset, algo_idx)) { - continue; - } - channeld->supported_compression_algorithms |= 1u << algo_idx; - } - - GPR_ASSERT(!args->is_last); - return GRPC_ERROR_NONE; -} - -/* Destructor for channel data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) {} - -const grpc_channel_filter grpc_compress_filter = { - compress_start_transport_stream_op_batch, - grpc_channel_next_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset_or_pollset_set, - destroy_call_elem, - sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, - grpc_call_next_get_peer, - grpc_channel_next_get_info, - "compress"}; diff --git a/src/core/ext/filters/http/compress/compress_filter.h b/src/core/ext/filters/http/compress/compress_filter.h deleted file mode 100644 index 68d2b8766a..0000000000 --- a/src/core/ext/filters/http/compress/compress_filter.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_HTTP_COMPRESS_COMPRESS_FILTER_H -#define GRPC_CORE_EXT_FILTERS_HTTP_COMPRESS_COMPRESS_FILTER_H - -#include - -#include "src/core/lib/channel/channel_stack.h" - -extern int grpc_compression_trace; - -/** Compression filter for outgoing data. - * - * See for the available compression settings. - * - * Compression settings may come from: - * - Channel configuration, as established at channel creation time. - * - The metadata accompanying the outgoing data to be compressed. This is - * taken as a request only. We may choose not to honor it. The metadata key - * is given by \a GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY. - * - * Compression can be disabled for concrete messages (for instance in order to - * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in - * the BEGIN_MESSAGE flags. - * - * The attempted compression mechanism is added to the resulting initial - * metadata under the'grpc-encoding' key. - * - * If compression is actually performed, BEGIN_MESSAGE's flag is modified to - * incorporate GRPC_WRITE_INTERNAL_COMPRESS. Otherwise, and regardless of the - * aforementioned 'grpc-encoding' metadata value, data will pass through - * uncompressed. */ - -extern const grpc_channel_filter grpc_compress_filter; - -#endif /* GRPC_CORE_EXT_FILTERS_HTTP_COMPRESS_COMPRESS_FILTER_H */ diff --git a/src/core/ext/filters/http/http_filters_plugin.c b/src/core/ext/filters/http/http_filters_plugin.c index a6e35bc181..825c21cb6a 100644 --- a/src/core/ext/filters/http/http_filters_plugin.c +++ b/src/core/ext/filters/http/http_filters_plugin.c @@ -34,7 +34,7 @@ #include #include "src/core/ext/filters/http/client/http_client_filter.h" -#include "src/core/ext/filters/http/compress/compress_filter.h" +#include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/surface/channel_init.h" diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.c b/src/core/ext/filters/http/message_compress/message_compress_filter.c new file mode 100644 index 0000000000..f110e7beb6 --- /dev/null +++ b/src/core/ext/filters/http/message_compress/message_compress_filter.c @@ -0,0 +1,353 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "src/core/ext/filters/http/message_compress/message_compress_filter.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/compression/message_compress.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/static_metadata.h" + +int grpc_compression_trace = 0; + +typedef struct call_data { + grpc_slice_buffer slices; /**< Buffers up input slices to be compressed */ + grpc_linked_mdelem compression_algorithm_storage; + grpc_linked_mdelem accept_encoding_storage; + uint32_t remaining_slice_bytes; + /** Compression algorithm we'll try to use. It may be given by incoming + * metadata, or by the channel's default compression settings. */ + grpc_compression_algorithm compression_algorithm; + /** If true, contents of \a compression_algorithm are authoritative */ + int has_compression_algorithm; + + grpc_transport_stream_op_batch *send_op; + uint32_t send_length; + uint32_t send_flags; + grpc_slice incoming_slice; + grpc_slice_buffer_stream replacement_stream; + grpc_closure *post_send; + grpc_closure send_done; + grpc_closure got_slice; +} call_data; + +typedef struct channel_data { + /** The default, channel-level, compression algorithm */ + grpc_compression_algorithm default_compression_algorithm; + /** Bitset of enabled algorithms */ + uint32_t enabled_algorithms_bitset; + /** Supported compression algorithms */ + uint32_t supported_compression_algorithms; +} channel_data; + +static int skip_compression(grpc_call_element *elem, uint32_t flags) { + call_data *calld = elem->call_data; + channel_data *channeld = elem->channel_data; + + if (flags & (GRPC_WRITE_NO_COMPRESS | GRPC_WRITE_INTERNAL_COMPRESS)) { + return 1; + } + if (calld->has_compression_algorithm) { + if (calld->compression_algorithm == GRPC_COMPRESS_NONE) { + return 1; + } + return 0; /* we have an actual call-specific algorithm */ + } + /* no per-call compression override */ + return channeld->default_compression_algorithm == GRPC_COMPRESS_NONE; +} + +/** Filter initial metadata */ +static grpc_error *process_send_initial_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_metadata_batch *initial_metadata) GRPC_MUST_USE_RESULT; +static grpc_error *process_send_initial_metadata( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_metadata_batch *initial_metadata) { + call_data *calld = elem->call_data; + channel_data *channeld = elem->channel_data; + /* Parse incoming request for compression. If any, it'll be available + * at calld->compression_algorithm */ + if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) { + grpc_mdelem md = + initial_metadata->idx.named.grpc_internal_encoding_request->md; + if (!grpc_compression_algorithm_parse(GRPC_MDVALUE(md), + &calld->compression_algorithm)) { + char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + gpr_log(GPR_ERROR, + "Invalid compression algorithm: '%s' (unknown). Ignoring.", val); + gpr_free(val); + calld->compression_algorithm = GRPC_COMPRESS_NONE; + } + if (!GPR_BITGET(channeld->enabled_algorithms_bitset, + calld->compression_algorithm)) { + char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + gpr_log(GPR_ERROR, + "Invalid compression algorithm: '%s' (previously disabled). " + "Ignoring.", + val); + gpr_free(val); + calld->compression_algorithm = GRPC_COMPRESS_NONE; + } + calld->has_compression_algorithm = 1; + + grpc_metadata_batch_remove( + exec_ctx, initial_metadata, + initial_metadata->idx.named.grpc_internal_encoding_request); + } else { + /* If no algorithm was found in the metadata and we aren't + * exceptionally skipping compression, fall back to the channel + * default */ + calld->compression_algorithm = channeld->default_compression_algorithm; + calld->has_compression_algorithm = 1; /* GPR_TRUE */ + } + + grpc_error *error = GRPC_ERROR_NONE; + /* hint compression algorithm */ + if (calld->compression_algorithm != GRPC_COMPRESS_NONE) { + error = grpc_metadata_batch_add_tail( + exec_ctx, initial_metadata, &calld->compression_algorithm_storage, + grpc_compression_encoding_mdelem(calld->compression_algorithm)); + } + + if (error != GRPC_ERROR_NONE) return error; + + /* convey supported compression algorithms */ + error = grpc_metadata_batch_add_tail( + exec_ctx, initial_metadata, &calld->accept_encoding_storage, + GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS( + channeld->supported_compression_algorithms)); + + return error; +} + +static void continue_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem); + +static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { + grpc_call_element *elem = elemp; + call_data *calld = elem->call_data; + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices); + calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error); +} + +static void finish_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + int did_compress; + grpc_slice_buffer tmp; + grpc_slice_buffer_init(&tmp); + did_compress = grpc_msg_compress(exec_ctx, calld->compression_algorithm, + &calld->slices, &tmp); + if (did_compress) { + if (grpc_compression_trace) { + char *algo_name; + const size_t before_size = calld->slices.length; + const size_t after_size = tmp.length; + const float savings_ratio = 1.0f - (float)after_size / (float)before_size; + GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm, + &algo_name)); + gpr_log(GPR_DEBUG, "Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR + " bytes (%.2f%% savings)", + algo_name, before_size, after_size, 100 * savings_ratio); + } + grpc_slice_buffer_swap(&calld->slices, &tmp); + calld->send_flags |= GRPC_WRITE_INTERNAL_COMPRESS; + } else { + if (grpc_compression_trace) { + char *algo_name; + GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm, + &algo_name)); + gpr_log(GPR_DEBUG, + "Algorithm '%s' enabled but decided not to compress. Input size: " + "%" PRIuPTR, + algo_name, calld->slices.length); + } + } + + grpc_slice_buffer_destroy_internal(exec_ctx, &tmp); + + grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices, + calld->send_flags); + calld->send_op->payload->send_message.send_message = + &calld->replacement_stream.base; + calld->post_send = calld->send_op->on_complete; + calld->send_op->on_complete = &calld->send_done; + + grpc_call_next_op(exec_ctx, elem, calld->send_op); +} + +static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { + grpc_call_element *elem = elemp; + call_data *calld = elem->call_data; + grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); + if (calld->send_length == calld->slices.length) { + finish_send_message(exec_ctx, elem); + } else { + continue_send_message(exec_ctx, elem); + } +} + +static void continue_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + while (grpc_byte_stream_next( + exec_ctx, calld->send_op->payload->send_message.send_message, + &calld->incoming_slice, ~(size_t)0, &calld->got_slice)) { + grpc_slice_buffer_add(&calld->slices, calld->incoming_slice); + if (calld->send_length == calld->slices.length) { + finish_send_message(exec_ctx, elem); + break; + } + } +} + +static void compress_start_transport_stream_op_batch( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op_batch *op) { + call_data *calld = elem->call_data; + + GPR_TIMER_BEGIN("compress_start_transport_stream_op_batch", 0); + + if (op->send_initial_metadata) { + grpc_error *error = process_send_initial_metadata( + exec_ctx, elem, + op->payload->send_initial_metadata.send_initial_metadata); + if (error != GRPC_ERROR_NONE) { + grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error); + return; + } + } + if (op->send_message && + !skip_compression(elem, op->payload->send_message.send_message->flags)) { + calld->send_op = op; + calld->send_length = op->payload->send_message.send_message->length; + calld->send_flags = op->payload->send_message.send_message->flags; + continue_send_message(exec_ctx, elem); + } else { + /* pass control down the stack */ + grpc_call_next_op(exec_ctx, elem, op); + } + + GPR_TIMER_END("compress_start_transport_stream_op_batch", 0); +} + +/* Constructor for call_data */ +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + const grpc_call_element_args *args) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + + /* initialize members */ + grpc_slice_buffer_init(&calld->slices); + calld->has_compression_algorithm = 0; + grpc_closure_init(&calld->got_slice, got_slice, elem, + grpc_schedule_on_exec_ctx); + grpc_closure_init(&calld->send_done, send_done, elem, + grpc_schedule_on_exec_ctx); + + return GRPC_ERROR_NONE; +} + +/* Destructor for call_data */ +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + const grpc_call_final_info *final_info, + grpc_closure *ignored) { + /* grab pointers to our data from the call element */ + call_data *calld = elem->call_data; + grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices); +} + +/* Constructor for channel_data */ +static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *channeld = elem->channel_data; + + channeld->enabled_algorithms_bitset = + grpc_channel_args_compression_algorithm_get_states(args->channel_args); + + channeld->default_compression_algorithm = + grpc_channel_args_get_compression_algorithm(args->channel_args); + /* Make sure the default isn't disabled. */ + if (!GPR_BITGET(channeld->enabled_algorithms_bitset, + channeld->default_compression_algorithm)) { + gpr_log(GPR_DEBUG, + "compression algorithm %d not enabled: switching to none", + channeld->default_compression_algorithm); + channeld->default_compression_algorithm = GRPC_COMPRESS_NONE; + } + + channeld->supported_compression_algorithms = 1; /* always support identity */ + for (grpc_compression_algorithm algo_idx = 1; + algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) { + /* skip disabled algorithms */ + if (!GPR_BITGET(channeld->enabled_algorithms_bitset, algo_idx)) { + continue; + } + channeld->supported_compression_algorithms |= 1u << algo_idx; + } + + GPR_ASSERT(!args->is_last); + return GRPC_ERROR_NONE; +} + +/* Destructor for channel data */ +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +const grpc_channel_filter grpc_compress_filter = { + compress_start_transport_stream_op_batch, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset_or_pollset_set, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + grpc_channel_next_get_info, + "compress"}; diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.h b/src/core/ext/filters/http/message_compress/message_compress_filter.h new file mode 100644 index 0000000000..68d2b8766a --- /dev/null +++ b/src/core/ext/filters/http/message_compress/message_compress_filter.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_HTTP_COMPRESS_COMPRESS_FILTER_H +#define GRPC_CORE_EXT_FILTERS_HTTP_COMPRESS_COMPRESS_FILTER_H + +#include + +#include "src/core/lib/channel/channel_stack.h" + +extern int grpc_compression_trace; + +/** Compression filter for outgoing data. + * + * See for the available compression settings. + * + * Compression settings may come from: + * - Channel configuration, as established at channel creation time. + * - The metadata accompanying the outgoing data to be compressed. This is + * taken as a request only. We may choose not to honor it. The metadata key + * is given by \a GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY. + * + * Compression can be disabled for concrete messages (for instance in order to + * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in + * the BEGIN_MESSAGE flags. + * + * The attempted compression mechanism is added to the resulting initial + * metadata under the'grpc-encoding' key. + * + * If compression is actually performed, BEGIN_MESSAGE's flag is modified to + * incorporate GRPC_WRITE_INTERNAL_COMPRESS. Otherwise, and regardless of the + * aforementioned 'grpc-encoding' metadata value, data will pass through + * uncompressed. */ + +extern const grpc_channel_filter grpc_compress_filter; + +#endif /* GRPC_CORE_EXT_FILTERS_HTTP_COMPRESS_COMPRESS_FILTER_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c858dc9e1f..afaf2acaa4 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -220,7 +220,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', 'src/core/ext/filters/http/client/http_client_filter.c', - 'src/core/ext/filters/http/compress/compress_filter.c', + 'src/core/ext/filters/http/message_compress/message_compress_filter.c', 'src/core/ext/filters/http/http_filters_plugin.c', 'src/core/ext/filters/http/server/http_server_filter.c', 'src/core/lib/http/httpcli_security_connector.c', diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c index 5fc0e4ea73..c59b544902 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.c +++ b/test/core/end2end/fixtures/h2_sockpair+trace.c @@ -47,7 +47,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/client/http_client_filter.h" -#include "src/core/ext/filters/http/compress/compress_filter.h" +#include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c index 24ed048e7d..1cb4e70727 100644 --- a/test/core/end2end/fixtures/h2_sockpair.c +++ b/test/core/end2end/fixtures/h2_sockpair.c @@ -42,7 +42,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/client/http_client_filter.h" -#include "src/core/ext/filters/http/compress/compress_filter.h" +#include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c index fee30946c4..9cd93c234a 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.c +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c @@ -42,7 +42,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/client/http_client_filter.h" -#include "src/core/ext/filters/http/compress/compress_filter.h" +#include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index ae6041733c..7221cf5512 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -48,7 +48,7 @@ extern "C" { #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/ext/filters/http/client/http_client_filter.h" -#include "src/core/ext/filters/http/compress/compress_filter.h" +#include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/filters/load_reporting/load_reporting_filter.h" #include "src/core/ext/filters/message_size/message_size_filter.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 8bc5896e88..ca38e2fe0f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -958,8 +958,8 @@ src/core/ext/filters/deadline/deadline_filter.c \ src/core/ext/filters/deadline/deadline_filter.h \ src/core/ext/filters/http/client/http_client_filter.c \ src/core/ext/filters/http/client/http_client_filter.h \ -src/core/ext/filters/http/compress/compress_filter.c \ -src/core/ext/filters/http/compress/compress_filter.h \ +src/core/ext/filters/http/message_compress/message_compress_filter.c \ +src/core/ext/filters/http/message_compress/message_compress_filter.h \ src/core/ext/filters/http/http_filters_plugin.c \ src/core/ext/filters/http/server/http_server_filter.c \ src/core/ext/filters/http/server/http_server_filter.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6cf4494b12..63d6419146 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8013,7 +8013,7 @@ ], "headers": [ "src/core/ext/filters/http/client/http_client_filter.h", - "src/core/ext/filters/http/compress/compress_filter.h", + "src/core/ext/filters/http/message_compress/message_compress_filter.h", "src/core/ext/filters/http/server/http_server_filter.h" ], "is_filegroup": true, @@ -8022,8 +8022,8 @@ "src": [ "src/core/ext/filters/http/client/http_client_filter.c", "src/core/ext/filters/http/client/http_client_filter.h", - "src/core/ext/filters/http/compress/compress_filter.c", - "src/core/ext/filters/http/compress/compress_filter.h", + "src/core/ext/filters/http/message_compress/message_compress_filter.c", + "src/core/ext/filters/http/message_compress/message_compress_filter.h", "src/core/ext/filters/http/http_filters_plugin.c", "src/core/ext/filters/http/server/http_server_filter.c", "src/core/ext/filters/http/server/http_server_filter.h" -- cgit v1.2.3 From 3bd7a2111ed9ada00868ffc8c5175228262194e3 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 6 Apr 2017 09:04:18 -0700 Subject: Fixup code --- src/core/ext/filters/http/http_filters_plugin.c | 2 +- src/core/ext/filters/http/message_compress/message_compress_filter.c | 2 +- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/ext/filters/http/http_filters_plugin.c') diff --git a/src/core/ext/filters/http/http_filters_plugin.c b/src/core/ext/filters/http/http_filters_plugin.c index 825c21cb6a..093a8c7dce 100644 --- a/src/core/ext/filters/http/http_filters_plugin.c +++ b/src/core/ext/filters/http/http_filters_plugin.c @@ -46,7 +46,7 @@ typedef struct { } optional_filter; static optional_filter compress_filter = { - &grpc_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION}; + &grpc_message_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION}; static bool is_building_http_like_transport( grpc_channel_stack_builder *builder) { diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.c b/src/core/ext/filters/http/message_compress/message_compress_filter.c index f110e7beb6..1cbc852686 100644 --- a/src/core/ext/filters/http/message_compress/message_compress_filter.c +++ b/src/core/ext/filters/http/message_compress/message_compress_filter.c @@ -338,7 +338,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {} -const grpc_channel_filter grpc_compress_filter = { +const grpc_channel_filter grpc_message_compress_filter = { compress_start_transport_stream_op_batch, grpc_channel_next_op, sizeof(call_data), diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 7221cf5512..0acfb9402f 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -461,7 +461,7 @@ BENCHMARK_TEMPLATE(BM_IsolatedFilter, DummyFilter, NoOp); BENCHMARK_TEMPLATE(BM_IsolatedFilter, DummyFilter, SendEmptyMetadata); typedef Fixture<&grpc_client_channel_filter, 0> ClientChannelFilter; BENCHMARK_TEMPLATE(BM_IsolatedFilter, ClientChannelFilter, NoOp); -typedef Fixture<&grpc_compress_filter, CHECKS_NOT_LAST> CompressFilter; +typedef Fixture<&grpc_message_compress_filter, CHECKS_NOT_LAST> CompressFilter; BENCHMARK_TEMPLATE(BM_IsolatedFilter, CompressFilter, NoOp); BENCHMARK_TEMPLATE(BM_IsolatedFilter, CompressFilter, SendEmptyMetadata); typedef Fixture<&grpc_client_deadline_filter, CHECKS_NOT_LAST> -- cgit v1.2.3 From e376970691b972e54bf5242a7ede9305bb508f1d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 6 Apr 2017 09:13:34 -0700 Subject: Fix bool/pointer mixup --- src/core/ext/filters/http/http_filters_plugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/ext/filters/http/http_filters_plugin.c') diff --git a/src/core/ext/filters/http/http_filters_plugin.c b/src/core/ext/filters/http/http_filters_plugin.c index 093a8c7dce..a6ba194e69 100644 --- a/src/core/ext/filters/http/http_filters_plugin.c +++ b/src/core/ext/filters/http/http_filters_plugin.c @@ -51,7 +51,7 @@ static optional_filter compress_filter = { static bool is_building_http_like_transport( grpc_channel_stack_builder *builder) { grpc_transport *t = grpc_channel_stack_builder_get_transport(builder); - return t && strstr(t->vtable->name, "http"); + return t != NULL && strstr(t->vtable->name, "http"); } static bool maybe_add_optional_filter(grpc_exec_ctx *exec_ctx, -- cgit v1.2.3 From 41f2ed68c41fda998aa99e98b97ae4982233e6b8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 6 Apr 2017 09:33:48 -0700 Subject: Cleanup filter selection --- src/core/ext/filters/deadline/deadline_filter.c | 10 ++--- src/core/ext/filters/http/http_filters_plugin.c | 9 ++-- .../ext/filters/load_reporting/load_reporting.c | 10 +---- src/core/ext/filters/max_age/max_age_filter.c | 28 ++++++------- .../ext/filters/message_size/message_size_filter.c | 49 +++++++++------------- src/core/lib/channel/channel_args.c | 28 ++++++++++--- src/core/lib/channel/channel_args.h | 5 ++- 7 files changed, 69 insertions(+), 70 deletions(-) (limited to 'src/core/ext/filters/http/http_filters_plugin.c') diff --git a/src/core/ext/filters/deadline/deadline_filter.c b/src/core/ext/filters/deadline/deadline_filter.c index da12cc3e78..2e03d16bf6 100644 --- a/src/core/ext/filters/deadline/deadline_filter.c +++ b/src/core/ext/filters/deadline/deadline_filter.c @@ -346,13 +346,9 @@ const grpc_channel_filter grpc_server_deadline_filter = { }; bool grpc_deadline_checking_enabled(const grpc_channel_args* channel_args) { - bool enable = !grpc_channel_args_want_minimal_stack(channel_args); - const grpc_arg* a = - grpc_channel_args_find(channel_args, GRPC_ARG_ENABLE_DEADLINE_CHECKS); - if (a != NULL && a->type == GRPC_ARG_INTEGER && a->value.integer != 0) { - enable = true; - } - return enable; + return grpc_channel_arg_get_bool( + grpc_channel_args_find(channel_args, GRPC_ARG_ENABLE_DEADLINE_CHECKS), + !grpc_channel_args_want_minimal_stack(channel_args)); } static bool maybe_add_deadline_filter(grpc_exec_ctx* exec_ctx, diff --git a/src/core/ext/filters/http/http_filters_plugin.c b/src/core/ext/filters/http/http_filters_plugin.c index a6ba194e69..195a1a8119 100644 --- a/src/core/ext/filters/http/http_filters_plugin.c +++ b/src/core/ext/filters/http/http_filters_plugin.c @@ -61,12 +61,9 @@ static bool maybe_add_optional_filter(grpc_exec_ctx *exec_ctx, optional_filter *filtarg = arg; const grpc_channel_args *channel_args = grpc_channel_stack_builder_get_channel_arguments(builder); - bool enable = !grpc_channel_args_want_minimal_stack(channel_args); - const grpc_arg *ctlarg = - grpc_channel_args_find(channel_args, filtarg->control_channel_arg); - if (ctlarg != NULL) { - enable = !(ctlarg->type == GRPC_ARG_INTEGER && ctlarg->value.integer == 0); - } + bool enable = grpc_channel_arg_get_bool( + grpc_channel_args_find(channel_args, filtarg->control_channel_arg), + !grpc_channel_args_want_minimal_stack(channel_args)); return enable ? grpc_channel_stack_builder_prepend_filter( builder, filtarg->filter, NULL, NULL) : true; diff --git a/src/core/ext/filters/load_reporting/load_reporting.c b/src/core/ext/filters/load_reporting/load_reporting.c index 9fb33bab71..adb5e8b93b 100644 --- a/src/core/ext/filters/load_reporting/load_reporting.c +++ b/src/core/ext/filters/load_reporting/load_reporting.c @@ -63,14 +63,8 @@ void grpc_call_set_load_reporting_cost_context( } static bool is_load_reporting_enabled(const grpc_channel_args *a) { - if (a == NULL) return false; - for (size_t i = 0; i < a->num_args; i++) { - if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_LOAD_REPORTING)) { - return a->args[i].type == GRPC_ARG_INTEGER && - a->args[i].value.integer != 0; - } - } - return false; + return grpc_channel_arg_get_bool( + grpc_channel_args_find(a, GRPC_ARG_ENABLE_LOAD_REPORTING), false); } static bool maybe_add_load_reporting_filter(grpc_exec_ctx *exec_ctx, diff --git a/src/core/ext/filters/max_age/max_age_filter.c b/src/core/ext/filters/max_age/max_age_filter.c index 72c1d9174d..0ae2357276 100644 --- a/src/core/ext/filters/max_age/max_age_filter.c +++ b/src/core/ext/filters/max_age/max_age_filter.c @@ -48,6 +48,11 @@ #define DEFAULT_MAX_CONNECTION_IDLE_MS INT_MAX #define MAX_CONNECTION_AGE_JITTER 0.1 +#define MAX_CONNECTION_AGE_INTEGER_OPTIONS \ + (grpc_integer_options) { DEFAULT_MAX_CONNECTION_AGE_MS, 1, INT_MAX } +#define MAX_CONNECTION_IDLE_INTEGER_OPTIONS \ + (grpc_integer_options) { DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX } + typedef struct channel_data { /* We take a reference to the channel stack for the timer callback */ grpc_channel_stack* channel_stack; @@ -315,8 +320,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx, if (0 == strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_CONNECTION_AGE_MS)) { const int value = grpc_channel_arg_get_integer( - &args->channel_args->args[i], - (grpc_integer_options){DEFAULT_MAX_CONNECTION_AGE_MS, 1, INT_MAX}); + &args->channel_args->args[i], MAX_CONNECTION_AGE_INTEGER_OPTIONS); chand->max_connection_age = value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN) @@ -334,8 +338,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx, } else if (0 == strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_CONNECTION_IDLE_MS)) { const int value = grpc_channel_arg_get_integer( - &args->channel_args->args[i], - (grpc_integer_options){DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX}); + &args->channel_args->args[i], MAX_CONNECTION_IDLE_INTEGER_OPTIONS); chand->max_connection_idle = value == INT_MAX ? gpr_inf_future(GPR_TIMESPAN) : gpr_time_from_millis(value, GPR_TIMESPAN); @@ -412,16 +415,13 @@ static bool maybe_add_max_age_filter(grpc_exec_ctx* exec_ctx, void* arg) { const grpc_channel_args* channel_args = grpc_channel_stack_builder_get_channel_arguments(builder); - const grpc_arg* a = - grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_AGE_MS); - bool enable = false; - if (a != NULL && a->type == GRPC_ARG_INTEGER && a->value.integer != INT_MAX) { - enable = true; - } - a = grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_IDLE_MS); - if (a != NULL && a->type == GRPC_ARG_INTEGER && a->value.integer != INT_MAX) { - enable = true; - } + bool enable = + grpc_channel_arg_get_integer( + grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_AGE_MS), + MAX_CONNECTION_AGE_INTEGER_OPTIONS) != INT_MAX && + grpc_channel_arg_get_integer( + grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_IDLE_MS), + MAX_CONNECTION_IDLE_INTEGER_OPTIONS) != INT_MAX; if (enable) { return grpc_channel_stack_builder_prepend_filter( builder, &grpc_max_age_filter, NULL, NULL); diff --git a/src/core/ext/filters/message_size/message_size_filter.c b/src/core/ext/filters/message_size/message_size_filter.c index d152d82968..7cb2c346fd 100644 --- a/src/core/ext/filters/message_size/message_size_filter.c +++ b/src/core/ext/filters/message_size/message_size_filter.c @@ -91,8 +91,7 @@ static void* message_size_limits_create_from_json(const grpc_json* json) { } typedef struct call_data { - int max_send_size; - int max_recv_size; + message_size_limits limits; // Receive closures are chained: we inject this closure as the // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. @@ -104,8 +103,7 @@ typedef struct call_data { } call_data; typedef struct channel_data { - int max_send_size; - int max_recv_size; + message_size_limits limits; // Maps path names to message_size_limits structs. grpc_slice_hash_table* method_limit_table; } channel_data; @@ -116,12 +114,12 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data, grpc_error* error) { grpc_call_element* elem = user_data; call_data* calld = elem->call_data; - if (*calld->recv_message != NULL && calld->max_recv_size >= 0 && - (*calld->recv_message)->length > (size_t)calld->max_recv_size) { + if (*calld->recv_message != NULL && calld->limits.max_recv_size >= 0 && + (*calld->recv_message)->length > (size_t)calld->limits.max_recv_size) { char* message_string; gpr_asprintf(&message_string, "Received message larger than max (%u vs. %d)", - (*calld->recv_message)->length, calld->max_recv_size); + (*calld->recv_message)->length, calld->limits.max_recv_size); grpc_error* new_error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INVALID_ARGUMENT); @@ -143,13 +141,13 @@ static void start_transport_stream_op_batch( grpc_transport_stream_op_batch* op) { call_data* calld = elem->call_data; // Check max send message size. - if (op->send_message && calld->max_send_size >= 0 && + if (op->send_message && calld->limits.max_send_size >= 0 && op->payload->send_message.send_message->length > - (size_t)calld->max_send_size) { + (size_t)calld->limits.max_send_size) { char* message_string; gpr_asprintf(&message_string, "Sent message larger than max (%u vs. %d)", op->payload->send_message.send_message->length, - calld->max_send_size); + calld->limits.max_send_size); grpc_transport_stream_op_batch_finish_with_failure( exec_ctx, op, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), @@ -182,21 +180,20 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx, // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response // size to the receive limit. - calld->max_send_size = chand->max_send_size; - calld->max_recv_size = chand->max_recv_size; + calld->limits = chand->limits; if (chand->method_limit_table != NULL) { message_size_limits* limits = grpc_method_config_table_get( exec_ctx, chand->method_limit_table, args->path); if (limits != NULL) { if (limits->max_send_size >= 0 && - (limits->max_send_size < calld->max_send_size || - calld->max_send_size < 0)) { - calld->max_send_size = limits->max_send_size; + (limits->max_send_size < calld->limits.max_send_size || + calld->limits.max_send_size < 0)) { + calld->limits.max_send_size = limits->max_send_size; } if (limits->max_recv_size >= 0 && - (limits->max_recv_size < calld->max_recv_size || - calld->max_recv_size < 0)) { - calld->max_recv_size = limits->max_recv_size; + (limits->max_recv_size < calld->limits.max_recv_size || + calld->limits.max_recv_size < 0)) { + calld->limits.max_recv_size = limits->max_recv_size; } } } @@ -216,13 +213,9 @@ static int default_size(const grpc_channel_args* args, return without_minimal_stack; } -typedef struct { - int max_recv_size; - int max_send_size; -} channel_limits; - -channel_limits get_channel_limits(const grpc_channel_args* channel_args) { - channel_limits lim; +message_size_limits get_message_size_limits( + const grpc_channel_args* channel_args) { + message_size_limits lim; lim.max_send_size = default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH); lim.max_recv_size = @@ -254,9 +247,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); channel_data* chand = elem->channel_data; - channel_limits lim = get_channel_limits(args->channel_args); - chand->max_send_size = lim.max_send_size; - chand->max_recv_size = lim.max_recv_size; + chand->limits = get_message_size_limits(args->channel_args); // Get method config table from channel args. const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); @@ -302,7 +293,7 @@ static bool maybe_add_message_size_filter(grpc_exec_ctx* exec_ctx, const grpc_channel_args* channel_args = grpc_channel_stack_builder_get_channel_arguments(builder); bool enable = false; - channel_limits lim = get_channel_limits(channel_args); + message_size_limits lim = get_message_size_limits(channel_args); if (lim.max_send_size != INT_MAX || lim.max_recv_size != INT_MAX) { enable = true; } diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c index a6d124c719..3de31d99da 100644 --- a/src/core/lib/channel/channel_args.c +++ b/src/core/lib/channel/channel_args.c @@ -329,7 +329,9 @@ const grpc_arg *grpc_channel_args_find(const grpc_channel_args *args, return NULL; } -int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options) { +int grpc_channel_arg_get_integer(const grpc_arg *arg, + grpc_integer_options options) { + if (arg == NULL) return options.default_value; if (arg->type != GRPC_ARG_INTEGER) { gpr_log(GPR_ERROR, "%s ignored: it must be an integer", arg->key); return options.default_value; @@ -347,9 +349,25 @@ int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options) { return arg->value.integer; } +bool grpc_channel_arg_get_bool(const grpc_arg *arg, bool default_value) { + if (arg == NULL) return default_value; + if (arg->type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s ignored: it must be an integer", arg->key); + return default_value; + } + switch (arg->value.integer) { + case 0: + return false; + case 1: + return true; + default: + gpr_log(GPR_ERROR, "%s treated as bool but set to %d (assuming true)", + arg->key, arg->value.integer); + return true; + } +} + bool grpc_channel_args_want_minimal_stack(const grpc_channel_args *args) { - const grpc_arg *arg = grpc_channel_args_find(args, GRPC_ARG_MINIMAL_STACK); - if (arg == NULL) return false; - if (arg->type == GRPC_ARG_INTEGER && arg->value.integer == 0) return false; - return true; + return grpc_channel_arg_get_bool( + grpc_channel_args_find(args, GRPC_ARG_MINIMAL_STACK), false); } diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 158cda5b21..5ffcacb7fd 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -121,6 +121,9 @@ typedef struct grpc_integer_options { int max_value; } grpc_integer_options; /** Returns the value of \a arg, subject to the contraints in \a options. */ -int grpc_channel_arg_get_integer(grpc_arg *arg, grpc_integer_options options); +int grpc_channel_arg_get_integer(const grpc_arg *arg, + grpc_integer_options options); + +bool grpc_channel_arg_get_bool(const grpc_arg *arg, bool default_value); #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */ -- cgit v1.2.3