• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <grpc/support/port_platform.h>
18 
19 #include "src/core/ext/xds/xds_http_filters.h"
20 
21 #include "envoy/extensions/filters/http/router/v3/router.upb.h"
22 #include "envoy/extensions/filters/http/router/v3/router.upbdefs.h"
23 #include "src/core/ext/xds/xds_http_fault_filter.h"
24 
25 namespace grpc_core {
26 
27 const char* kXdsHttpRouterFilterConfigName =
28     "envoy.extensions.filters.http.router.v3.Router";
29 
30 namespace {
31 
32 class XdsHttpRouterFilter : public XdsHttpFilterImpl {
33  public:
PopulateSymtab(upb_symtab * symtab) const34   void PopulateSymtab(upb_symtab* symtab) const override {
35     envoy_extensions_filters_http_router_v3_Router_getmsgdef(symtab);
36   }
37 
GenerateFilterConfig(upb_strview serialized_filter_config,upb_arena * arena) const38   absl::StatusOr<FilterConfig> GenerateFilterConfig(
39       upb_strview serialized_filter_config, upb_arena* arena) const override {
40     if (envoy_extensions_filters_http_router_v3_Router_parse(
41             serialized_filter_config.data, serialized_filter_config.size,
42             arena) == nullptr) {
43       return absl::InvalidArgumentError("could not parse router filter config");
44     }
45     return FilterConfig{kXdsHttpRouterFilterConfigName, Json()};
46   }
47 
GenerateFilterConfigOverride(upb_strview,upb_arena *) const48   absl::StatusOr<FilterConfig> GenerateFilterConfigOverride(
49       upb_strview /*serialized_filter_config*/,
50       upb_arena* /*arena*/) const override {
51     return absl::InvalidArgumentError(
52         "router filter does not support config override");
53   }
54 
55   // No-op -- this filter is special-cased by the xds resolver.
channel_filter() const56   const grpc_channel_filter* channel_filter() const override { return nullptr; }
57 
58   // No-op -- this filter is special-cased by the xds resolver.
GenerateServiceConfig(const FilterConfig &,const FilterConfig *) const59   absl::StatusOr<ServiceConfigJsonEntry> GenerateServiceConfig(
60       const FilterConfig& /*hcm_filter_config*/,
61       const FilterConfig* /*filter_config_override*/) const override {
62     return absl::UnimplementedError("router filter should never be called");
63   }
64 
IsSupportedOnClients() const65   bool IsSupportedOnClients() const override { return true; }
66 
IsSupportedOnServers() const67   bool IsSupportedOnServers() const override { return true; }
68 };
69 
70 using FilterOwnerList = std::vector<std::unique_ptr<XdsHttpFilterImpl>>;
71 using FilterRegistryMap = std::map<absl::string_view, XdsHttpFilterImpl*>;
72 
73 FilterOwnerList* g_filters = nullptr;
74 FilterRegistryMap* g_filter_registry = nullptr;
75 
76 }  // namespace
77 
RegisterFilter(std::unique_ptr<XdsHttpFilterImpl> filter,const std::set<absl::string_view> & config_proto_type_names)78 void XdsHttpFilterRegistry::RegisterFilter(
79     std::unique_ptr<XdsHttpFilterImpl> filter,
80     const std::set<absl::string_view>& config_proto_type_names) {
81   for (auto config_proto_type_name : config_proto_type_names) {
82     (*g_filter_registry)[config_proto_type_name] = filter.get();
83   }
84   g_filters->push_back(std::move(filter));
85 }
86 
GetFilterForType(absl::string_view proto_type_name)87 const XdsHttpFilterImpl* XdsHttpFilterRegistry::GetFilterForType(
88     absl::string_view proto_type_name) {
89   auto it = g_filter_registry->find(proto_type_name);
90   if (it == g_filter_registry->end()) return nullptr;
91   return it->second;
92 }
93 
PopulateSymtab(upb_symtab * symtab)94 void XdsHttpFilterRegistry::PopulateSymtab(upb_symtab* symtab) {
95   for (const auto& filter : *g_filters) {
96     filter->PopulateSymtab(symtab);
97   }
98 }
99 
Init()100 void XdsHttpFilterRegistry::Init() {
101   g_filters = new FilterOwnerList;
102   g_filter_registry = new FilterRegistryMap;
103   RegisterFilter(absl::make_unique<XdsHttpRouterFilter>(),
104                  {kXdsHttpRouterFilterConfigName});
105   RegisterFilter(absl::make_unique<XdsHttpFaultFilter>(),
106                  {kXdsHttpFaultFilterConfigName});
107 }
108 
Shutdown()109 void XdsHttpFilterRegistry::Shutdown() {
110   delete g_filter_registry;
111   delete g_filters;
112 }
113 
114 }  // namespace grpc_core
115