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