| /** @file |
| Virtual Host configuration |
| @section license License |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| http://www.apache.org/licenses/LICENSE-2.0 |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <atomic> |
| #include <memory> |
| #include <string> |
| #include <string_view> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include "iocore/eventsystem/ConfigProcessor.h" |
| #include "mgmt/config/ConfigContext.h" |
| #include "proxy/http/remap/UrlRewrite.h" |
| #include "tscore/Ptr.h" |
| |
| class VirtualHostPluginReload; |
| |
| class VirtualHostConfig : public ConfigInfo |
| { |
| public: |
| VirtualHostConfig() = default; |
| VirtualHostConfig(const VirtualHostConfig &other) |
| : _entries(other._entries), |
| _exact_domains_to_id(other._exact_domains_to_id), |
| _wildcard_domains_to_id(other._wildcard_domains_to_id) |
| { |
| } |
| VirtualHostConfig & |
| operator=(const VirtualHostConfig &other) |
| { |
| if (this != &other) { |
| _entries = other._entries; |
| _exact_domains_to_id = other._exact_domains_to_id; |
| _wildcard_domains_to_id = other._wildcard_domains_to_id; |
| } |
| return *this; |
| } |
| ~VirtualHostConfig() = default; |
| |
| struct Entry : public RefCountObjInHeap { |
| std::string id; |
| std::vector<std::string> exact_domains; |
| std::vector<std::string> wildcard_domains; |
| std::shared_ptr<UrlRewrite> remap_table; |
| |
| std::string get_id() const; |
| }; |
| |
| /** Load every entry from the configuration file into this (empty) config. |
| |
| @param initial_load Set only for the load performed by @c VirtualHost::startup(). An absent |
| or empty file is a supported "no virtualhosts configured" state there, but on a reload it is |
| an error: reporting success would publish an empty config over a live routing table, silently |
| dropping every per-domain remap table. |
| */ |
| bool load(ConfigContext ctx = {}, bool initial_load = false, VirtualHostPluginReload *plugin_reload = nullptr); |
| bool set_entry(std::string_view id, Ptr<Entry> &entry, ConfigContext ctx = {}); |
| static bool load_entry(std::string_view id, Ptr<Entry> &entry, ConfigContext ctx = {}, |
| VirtualHostPluginReload *plugin_reload = nullptr); |
| Ptr<Entry> find_by_id(std::string_view id) const; |
| Ptr<Entry> find_by_domain(std::string_view domain) const; |
| |
| /// Add the remap plugins instantiated by every entry's remap table to @a used. |
| void collect_used_plugins(std::unordered_map<PluginDso *, int> &used) const; |
| |
| size_t |
| entry_count() const |
| { |
| return _entries.size(); |
| } |
| |
| private: |
| using entry_map = std::unordered_map<std::string, Ptr<Entry>>; |
| using name_map = std::unordered_map<std::string, std::string>; |
| |
| entry_map _entries; |
| name_map _exact_domains_to_id; |
| name_map _wildcard_domains_to_id; |
| }; |
| |
| /** Sends one remap plugin reload notification pair for a whole virtualhost rebuild. |
| |
| The pre/post callbacks go to every loaded remap plugin, not just the ones a table uses, so |
| notifying per table would repeat them for each entry and report plugins used only by earlier |
| tables as unused. The pre notification is sent lazily, before the first remap table is built, so |
| a rebuild with no remap tables sends nothing. If @c finish() is never reached, the destructor |
| reports the reload as failed. |
| */ |
| class VirtualHostPluginReload |
| { |
| public: |
| VirtualHostPluginReload() = default; |
| VirtualHostPluginReload(const VirtualHostPluginReload &) = delete; |
| VirtualHostPluginReload &operator=(const VirtualHostPluginReload &) = delete; |
| ~VirtualHostPluginReload(); |
| |
| /// Call before building a remap table. |
| void begin(); |
| /// Report success, with @a config as the full set of tables that will be live. |
| void finish(VirtualHostConfig const &config); |
| |
| private: |
| bool _started = false; |
| }; |
| |
| class VirtualHost |
| { |
| public: |
| using scoped_config = ConfigProcessor::scoped_config<VirtualHost, VirtualHostConfig>; |
| |
| static void startup(); |
| static int reconfigure(ConfigContext ctx = {}, bool initial_load = false); |
| static int reconfigure(std::string_view id, ConfigContext ctx = {}); |
| static VirtualHostConfig *acquire(); |
| static void release(VirtualHostConfig *config); |
| |
| private: |
| static std::atomic<int> _configid; |
| }; |