user-agent string filtering

pull/10849/head
Muxi Yan 8 years ago
parent b53fd4df37
commit f63afec89d
  1. 2
      CMakeLists.txt
  2. 2
      Makefile
  3. 1
      binding.gyp
  4. 9
      build.yaml
  5. 1
      config.m4
  6. 5
      gRPC-Core.podspec
  7. 2
      grpc.gemspec
  8. 2
      package.xml
  9. 88
      src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c
  10. 57
      src/core/ext/filters/workarounds/workaround_utils.c
  11. 54
      src/core/ext/filters/workarounds/workaround_utils.h
  12. 1
      src/python/grpcio/grpc_core_dependencies.py
  13. 2
      tools/doxygen/Doxyfile.core.internal
  14. 20
      tools/run_tests/generated/sources_and_headers.json
  15. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj
  16. 6
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  17. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  18. 6
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -1150,6 +1150,7 @@ add_library(grpc
src/core/ext/filters/max_age/max_age_filter.c
src/core/ext/filters/message_size/message_size_filter.c
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c
src/core/ext/filters/workarounds/workaround_utils.c
src/core/plugin_registry/grpc_plugin_registry.c
)
@ -2013,6 +2014,7 @@ add_library(grpc_unsecure
src/core/ext/filters/max_age/max_age_filter.c
src/core/ext/filters/message_size/message_size_filter.c
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c
src/core/ext/filters/workarounds/workaround_utils.c
src/core/plugin_registry/grpc_unsecure_plugin_registry.c
)

@ -3124,6 +3124,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/max_age/max_age_filter.c \
src/core/ext/filters/message_size/message_size_filter.c \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c \
src/core/ext/filters/workarounds/workaround_utils.c \
src/core/plugin_registry/grpc_plugin_registry.c \
PUBLIC_HEADERS_C += \
@ -3956,6 +3957,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/max_age/max_age_filter.c \
src/core/ext/filters/message_size/message_size_filter.c \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c \
src/core/ext/filters/workarounds/workaround_utils.c \
src/core/plugin_registry/grpc_unsecure_plugin_registry.c \
PUBLIC_HEADERS_C += \

@ -887,6 +887,7 @@
'src/core/ext/filters/max_age/max_age_filter.c',
'src/core/ext/filters/message_size/message_size_filter.c',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c',
'src/core/ext/filters/workarounds/workaround_utils.c',
'src/core/plugin_registry/grpc_plugin_registry.c',
],
"conditions": [

@ -634,6 +634,13 @@ filegroups:
- grpc_base
- grpc_transport_chttp2_alpn
- tsi
- name: grpc_server_backward_compatibility
headers:
- src/core/ext/filters/workarounds/workaround_utils.h
src:
- src/core/ext/filters/workarounds/workaround_utils.c
uses:
- grpc_base
- name: grpc_test_util_base
build: test
headers:
@ -1034,6 +1041,7 @@ libs:
- grpc_message_size_filter
- grpc_deadline_filter
- grpc_workaround_cronet_compression_filter
- grpc_server_backward_compatibility
generate_plugin_registry: true
secure: true
vs_packages:
@ -1134,6 +1142,7 @@ libs:
- grpc_message_size_filter
- grpc_deadline_filter
- grpc_workaround_cronet_compression_filter
- grpc_server_backward_compatibility
generate_plugin_registry: true
secure: false
vs_project_guid: '{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}'

@ -323,6 +323,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/max_age/max_age_filter.c \
src/core/ext/filters/message_size/message_size_filter.c \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c \
src/core/ext/filters/workarounds/workaround_utils.c \
src/core/plugin_registry/grpc_plugin_registry.c \
src/boringssl/err_data.c \
third_party/boringssl/crypto/aes/aes.c \

@ -460,6 +460,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h',
'src/core/lib/surface/init.c',
'src/core/lib/channel/channel_args.c',
'src/core/lib/channel/channel_stack.c',
@ -696,6 +697,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/max_age/max_age_filter.c',
'src/core/ext/filters/message_size/message_size_filter.c',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c',
'src/core/ext/filters/workarounds/workaround_utils.c',
'src/core/plugin_registry/grpc_plugin_registry.c'
ss.private_header_files = 'src/core/lib/profiling/timers.h',
@ -916,7 +918,8 @@ Pod::Spec.new do |s|
'src/core/ext/census/tracing.h',
'src/core/ext/filters/max_age/max_age_filter.h',
'src/core/ext/filters/message_size/message_size_filter.h',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h'
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h'
end
s.subspec 'Cronet-Interface' do |ss|

@ -376,6 +376,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/max_age/max_age_filter.h )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.h )
s.files += %w( src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h )
s.files += %w( src/core/ext/filters/workarounds/workaround_utils.h )
s.files += %w( src/core/lib/surface/init.c )
s.files += %w( src/core/lib/channel/channel_args.c )
s.files += %w( src/core/lib/channel/channel_stack.c )
@ -612,6 +613,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/max_age/max_age_filter.c )
s.files += %w( src/core/ext/filters/message_size/message_size_filter.c )
s.files += %w( src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c )
s.files += %w( src/core/ext/filters/workarounds/workaround_utils.c )
s.files += %w( src/core/plugin_registry/grpc_plugin_registry.c )
s.files += %w( third_party/boringssl/crypto/aes/internal.h )
s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )

@ -385,6 +385,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_utils.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/channel_args.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/channel_stack.c" role="src" />
@ -621,6 +622,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/max_age/max_age_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/message_size/message_size_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/workarounds/workaround_utils.c" role="src" />
<file baseinstalldir="/" name="src/core/plugin_registry/grpc_plugin_registry.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/aes/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/asn1_locl.h" role="src" />

@ -31,22 +31,15 @@
#include "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h"
#include <stdio.h>
#include <string.h>
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/channel/channel_stack_builder.h"
/*
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/service_config.h"
*/
#define GRPC_WORKAROUND_PRIORITY_HIGH 9999
#include "src/core/ext/filters/workarounds/workaround_utils.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/transport/metadata.h"
typedef struct call_data {
// Receive closures are chained: we inject this closure as the
@ -57,18 +50,46 @@ typedef struct call_data {
grpc_metadata_batch *recv_initial_metadata;
// Original recv_initial_metadata_ready callback, invoked after our own.
grpc_closure* next_recv_initial_metadata_ready;
// Marks whether the workaround is active
bool workaround_active;
} call_data;
typedef struct channel_data {
} channel_data;
// Find the user agent metadata element in the batch
static bool get_user_agent_mdelem(const grpc_metadata_batch *batch,
grpc_mdelem *md) {
grpc_linked_mdelem *t = batch->list.head;
while (t != NULL) {
*md = t->md;
if (grpc_slice_eq(GRPC_MDKEY(*md), GRPC_MDSTR_USER_AGENT)) {
return true;
}
t = t->next;
}
return false;
}
// Callback invoked when we receive an initial metadata.
static void recv_initial_metadata_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 (GRPC_ERROR_NONE == error) {
grpc_mdelem md;
if (get_user_agent_mdelem(calld->recv_initial_metadata, &md)) {
grpc_user_agent_md *user_agent_md = grpc_parse_user_agent(md);
if (user_agent_md->workaround_active[GRPC_WORKAROUND_ID_CRONET_COMPRESSION]) {
calld->workaround_active = true;
}
// Remove with caching
gpr_free(user_agent_md);
}
}
// Invoke the next callback.
grpc_closure_run(exec_ctx, calld->next_recv_initial_metadata_ready, GRPC_ERROR_REF(error));
@ -98,6 +119,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
const grpc_call_element_args* args) {
call_data* calld = elem->call_data;
calld->next_recv_initial_metadata_ready = NULL;
calld->workaround_active = false;
grpc_closure_init(&calld->recv_initial_metadata_ready, recv_initial_metadata_ready, elem,
grpc_schedule_on_exec_ctx);
return GRPC_ERROR_NONE;
@ -119,6 +141,44 @@ 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) {}
// Parse the user agent
static bool parse_user_agent(grpc_mdelem md) {
const char grpc_objc_specifier[] = "grpc-objc/";
const size_t grpc_objc_specifier_len = sizeof(grpc_objc_specifier) - 1;
const char cronet_specifier[] = "cronet_http";
const size_t cronet_specifier_len = sizeof(cronet_specifier) - 1;
char *user_agent_str = grpc_slice_to_c_string(GRPC_MDVALUE(md));
bool grpc_objc_specifier_seen = false;
bool cronet_specifier_seen = false;
char *major_version = user_agent_str, *minor_version;
char *head = strtok(user_agent_str, " ");
while (head != NULL) {
if (!grpc_objc_specifier_seen &&
0 == strncmp(head, grpc_objc_specifier, grpc_objc_specifier_len)) {
major_version = head + grpc_objc_specifier_len;
grpc_objc_specifier_seen = true;
} else if (grpc_objc_specifier_seen &&
0 == strncmp(head, cronet_specifier, cronet_specifier_len)) {
cronet_specifier_seen = true;
break;
}
head = strtok(NULL, " ");
}
if (grpc_objc_specifier_seen) {
major_version = strtok(major_version, ".");
minor_version = strtok(NULL, ".");
}
gpr_free(user_agent_str);
return (grpc_objc_specifier_seen &&
cronet_specifier_seen &&
(atol(major_version) < 1 ||
(atol(major_version) == 1 && atol(minor_version) <= 3)));
}
const grpc_channel_filter grpc_workaround_cronet_compression_filter = {
start_transport_stream_op_batch,
grpc_channel_next_op,
@ -136,6 +196,8 @@ const grpc_channel_filter grpc_workaround_cronet_compression_filter = {
static bool register_workaround_cronet_compression(grpc_exec_ctx* exec_ctx,
grpc_channel_stack_builder* builder,
void* arg) {
grpc_register_workaround(GRPC_WORKAROUND_ID_CRONET_COMPRESSION,
parse_user_agent);
return grpc_channel_stack_builder_prepend_filter(
builder, &grpc_workaround_cronet_compression_filter, NULL, NULL);
}

@ -0,0 +1,57 @@
//
// 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 "src/core/ext/filters/workarounds/workaround_utils.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
static user_agent_parser user_agent_parsers[GRPC_MAX_WORKAROUND_ID];
grpc_user_agent_md *grpc_parse_user_agent(grpc_mdelem md) {
grpc_user_agent_md *user_agent_md;
// USE THE CACHE WHEN ABLE
user_agent_md = gpr_malloc(sizeof(grpc_user_agent_md));
for (int i = 0; i < GRPC_MAX_WORKAROUND_ID; i++) {
if (user_agent_parsers[i]) {
user_agent_md->workaround_active[i] = user_agent_parsers[i](md);
}
}
return user_agent_md;
}
void grpc_register_workaround(uint32_t id, user_agent_parser parser) {
GPR_ASSERT(id < GRPC_MAX_WORKAROUND_ID);
user_agent_parsers[id] = parser;
}

@ -0,0 +1,54 @@
//
// 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.
//
#ifndef GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_UTILS
#define GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_UTILS
#include "src/core/lib/transport/metadata.h"
#define GRPC_WORKAROUND_PRIORITY_HIGH 9999
typedef enum {
GRPC_WORKAROUND_ID_CRONET_COMPRESSION = 0,
GRPC_MAX_WORKAROUND_ID,
} grpc_workaround_list;
typedef struct grpc_user_agent_md {
bool workaround_active[GRPC_MAX_WORKAROUND_ID];
} grpc_user_agent_md;
grpc_user_agent_md *grpc_parse_user_agent(grpc_mdelem md);
typedef bool (*user_agent_parser)(grpc_mdelem);
void grpc_register_workaround(uint32_t id, user_agent_parser parser);
#endif

@ -312,6 +312,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/max_age/max_age_filter.c',
'src/core/ext/filters/message_size/message_size_filter.c',
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c',
'src/core/ext/filters/workarounds/workaround_utils.c',
'src/core/plugin_registry/grpc_plugin_registry.c',
'src/boringssl/err_data.c',
'third_party/boringssl/crypto/aes/aes.c',

@ -973,6 +973,8 @@ src/core/ext/filters/message_size/message_size_filter.c \
src/core/ext/filters/message_size/message_size_filter.h \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c \
src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h \
src/core/ext/filters/workarounds/workaround_utils.c \
src/core/ext/filters/workarounds/workaround_utils.h \
src/core/ext/transport/README.md \
src/core/ext/transport/chttp2/README.md \
src/core/ext/transport/chttp2/alpn/alpn.c \

@ -5707,6 +5707,7 @@
"grpc_resolver_dns_native",
"grpc_resolver_sockaddr",
"grpc_secure",
"grpc_server_backward_compatibility",
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_client_secure",
"grpc_transport_chttp2_server_insecure",
@ -5812,6 +5813,7 @@
"grpc_resolver_dns_ares",
"grpc_resolver_dns_native",
"grpc_resolver_sockaddr",
"grpc_server_backward_compatibility",
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_server_insecure",
"grpc_workaround_cronet_compression_filter"
@ -8463,6 +8465,24 @@
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"gpr",
"grpc_base"
],
"headers": [
"src/core/ext/filters/workarounds/workaround_utils.h"
],
"is_filegroup": true,
"language": "c",
"name": "grpc_server_backward_compatibility",
"src": [
"src/core/ext/filters/workarounds/workaround_utils.c",
"src/core/ext/filters/workarounds/workaround_utils.h"
],
"third_party": false,
"type": "filegroup"
},
{
"deps": [
"gpr_test_util",

@ -505,6 +505,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init.c">
@ -979,6 +980,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_plugin_registry.c">
</ClCompile>
</ItemGroup>

@ -709,6 +709,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.c">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.c">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_plugin_registry.c">
<Filter>src\core\plugin_registry</Filter>
</ClCompile>
@ -1424,6 +1427,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.h">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.h">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

@ -471,6 +471,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\max_age\max_age_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\message_size\message_size_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\init.c">
@ -889,6 +890,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_unsecure_plugin_registry.c">
</ClCompile>
</ItemGroup>

@ -625,6 +625,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.c">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.c">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\plugin_registry\grpc_unsecure_plugin_registry.c">
<Filter>src\core\plugin_registry</Filter>
</ClCompile>
@ -1265,6 +1268,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_cronet_compression_filter.h">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\filters\workarounds\workaround_utils.h">
<Filter>src\core\ext\filters\workarounds</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

Loading…
Cancel
Save