Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / src / core / ext / filters / client_channel / resolver_registry.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include <grpc/support/port_platform.h>
20
21 #include "src/core/ext/filters/client_channel/resolver_registry.h"
22
23 #include <string.h>
24
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/string_util.h>
28
29 namespace grpc_core {
30
31 namespace {
32
33 class RegistryState {
34  public:
35   RegistryState() : default_prefix_(gpr_strdup("dns:///")) {}
36
37   void SetDefaultPrefix(const char* default_resolver_prefix) {
38     GPR_ASSERT(default_resolver_prefix != nullptr);
39     GPR_ASSERT(*default_resolver_prefix != '\0');
40     default_prefix_.reset(gpr_strdup(default_resolver_prefix));
41   }
42
43   void RegisterResolverFactory(UniquePtr<ResolverFactory> factory) {
44     for (size_t i = 0; i < factories_.size(); ++i) {
45       GPR_ASSERT(strcmp(factories_[i]->scheme(), factory->scheme()) != 0);
46     }
47     factories_.push_back(std::move(factory));
48   }
49
50   ResolverFactory* LookupResolverFactory(const char* scheme) const {
51     for (size_t i = 0; i < factories_.size(); ++i) {
52       if (strcmp(scheme, factories_[i]->scheme()) == 0) {
53         return factories_[i].get();
54       }
55     }
56     return nullptr;
57   }
58
59   // Returns the factory for the scheme of \a target.  If \a target does
60   // not parse as a URI, prepends \a default_prefix_ and tries again.
61   // If URI parsing is successful (in either attempt), sets \a uri to
62   // point to the parsed URI.
63   // If \a default_prefix_ needs to be prepended, sets \a canonical_target
64   // to the canonical target string.
65   ResolverFactory* FindResolverFactory(const char* target, grpc_uri** uri,
66                                        char** canonical_target) const {
67     GPR_ASSERT(uri != nullptr);
68     *uri = grpc_uri_parse(target, 1);
69     ResolverFactory* factory =
70         *uri == nullptr ? nullptr : LookupResolverFactory((*uri)->scheme);
71     if (factory == nullptr) {
72       grpc_uri_destroy(*uri);
73       gpr_asprintf(canonical_target, "%s%s", default_prefix_.get(), target);
74       *uri = grpc_uri_parse(*canonical_target, 1);
75       factory =
76           *uri == nullptr ? nullptr : LookupResolverFactory((*uri)->scheme);
77       if (factory == nullptr) {
78         grpc_uri_destroy(grpc_uri_parse(target, 0));
79         grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0));
80         gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
81                 *canonical_target);
82       }
83     }
84     return factory;
85   }
86
87  private:
88   // We currently support 10 factories without doing additional
89   // allocation.  This number could be raised if there is a case where
90   // more factories are needed and the additional allocations are
91   // hurting performance (which is unlikely, since these allocations
92   // only occur at gRPC initialization time).
93   InlinedVector<UniquePtr<ResolverFactory>, 10> factories_;
94   UniquePtr<char> default_prefix_;
95 };
96
97 static RegistryState* g_state = nullptr;
98
99 }  // namespace
100
101 //
102 // ResolverRegistry::Builder
103 //
104
105 void ResolverRegistry::Builder::InitRegistry() {
106   if (g_state == nullptr) g_state = New<RegistryState>();
107 }
108
109 void ResolverRegistry::Builder::ShutdownRegistry() {
110   Delete(g_state);
111   g_state = nullptr;
112 }
113
114 void ResolverRegistry::Builder::SetDefaultPrefix(
115     const char* default_resolver_prefix) {
116   InitRegistry();
117   g_state->SetDefaultPrefix(default_resolver_prefix);
118 }
119
120 void ResolverRegistry::Builder::RegisterResolverFactory(
121     UniquePtr<ResolverFactory> factory) {
122   InitRegistry();
123   g_state->RegisterResolverFactory(std::move(factory));
124 }
125
126 //
127 // ResolverRegistry
128 //
129
130 ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) {
131   GPR_ASSERT(g_state != nullptr);
132   return g_state->LookupResolverFactory(scheme);
133 }
134
135 bool ResolverRegistry::IsValidTarget(const char* target) {
136   grpc_uri* uri = nullptr;
137   char* canonical_target = nullptr;
138   ResolverFactory* factory =
139       g_state->FindResolverFactory(target, &uri, &canonical_target);
140   bool result = factory == nullptr ? false : factory->IsValidUri(uri);
141   grpc_uri_destroy(uri);
142   gpr_free(canonical_target);
143   return result;
144 }
145
146 OrphanablePtr<Resolver> ResolverRegistry::CreateResolver(
147     const char* target, const grpc_channel_args* args,
148     grpc_pollset_set* pollset_set, grpc_combiner* combiner,
149     UniquePtr<Resolver::ResultHandler> result_handler) {
150   GPR_ASSERT(g_state != nullptr);
151   grpc_uri* uri = nullptr;
152   char* canonical_target = nullptr;
153   ResolverFactory* factory =
154       g_state->FindResolverFactory(target, &uri, &canonical_target);
155   ResolverArgs resolver_args;
156   resolver_args.uri = uri;
157   resolver_args.args = args;
158   resolver_args.pollset_set = pollset_set;
159   resolver_args.combiner = combiner;
160   resolver_args.result_handler = std::move(result_handler);
161   OrphanablePtr<Resolver> resolver =
162       factory == nullptr ? nullptr
163                          : factory->CreateResolver(std::move(resolver_args));
164   grpc_uri_destroy(uri);
165   gpr_free(canonical_target);
166   return resolver;
167 }
168
169 UniquePtr<char> ResolverRegistry::GetDefaultAuthority(const char* target) {
170   GPR_ASSERT(g_state != nullptr);
171   grpc_uri* uri = nullptr;
172   char* canonical_target = nullptr;
173   ResolverFactory* factory =
174       g_state->FindResolverFactory(target, &uri, &canonical_target);
175   UniquePtr<char> authority =
176       factory == nullptr ? nullptr : factory->GetDefaultAuthority(uri);
177   grpc_uri_destroy(uri);
178   gpr_free(canonical_target);
179   return authority;
180 }
181
182 UniquePtr<char> ResolverRegistry::AddDefaultPrefixIfNeeded(const char* target) {
183   GPR_ASSERT(g_state != nullptr);
184   grpc_uri* uri = nullptr;
185   char* canonical_target = nullptr;
186   g_state->FindResolverFactory(target, &uri, &canonical_target);
187   grpc_uri_destroy(uri);
188   return UniquePtr<char>(canonical_target == nullptr ? gpr_strdup(target)
189                                                      : canonical_target);
190 }
191
192 }  // namespace grpc_core