| /** @file | |
| A brief file description | |
| @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. | |
| */ | |
| #include <dlfcn.h> | |
| #include <ts/ts.h> | |
| #include "HandlerManager.h" | |
| using std::map; | |
| using std::string; | |
| using namespace EsiLib; | |
| namespace | |
| { | |
| DbgCtl dbg_ctl{"plugin_esi_handler_mgr"}; | |
| } | |
| #define CLASS_NAME "HandlerManager" | |
| const char *const HandlerManager::FACTORY_FUNCTION_NAME = "createSpecialIncludeHandler"; | |
| void | |
| HandlerManager::loadObjects(const Utils::KeyValueMap &handlers) | |
| { | |
| ModuleHandleMap::iterator path_map_iter; | |
| for (Utils::KeyValueMap::const_iterator id_map_iter = handlers.begin(); id_map_iter != handlers.end(); ++id_map_iter) { | |
| const string &id = id_map_iter->first; | |
| const string &path = id_map_iter->second; | |
| path_map_iter = _path_to_module_map.find(path); | |
| if (path_map_iter != _path_to_module_map.end()) { | |
| // we have already loaded this object; just point id to original handle | |
| _id_to_function_map.insert(FunctionHandleMap::value_type(id, (path_map_iter->second).function)); | |
| } else { | |
| // no, we have to load this object | |
| void *obj_handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); | |
| if (!obj_handle) { | |
| TSError("[%s::%s] Could not load module [%s]. Error [%s]", CLASS_NAME, __FUNCTION__, path.c_str(), dlerror()); | |
| } else { | |
| SpecialIncludeHandlerCreator func_handle = (SpecialIncludeHandlerCreator)(dlsym(obj_handle, FACTORY_FUNCTION_NAME)); | |
| if (!func_handle) { | |
| TSError("[%s::%s] Could not find factory function [%s] in module [%s]. Error [%s]", CLASS_NAME, __FUNCTION__, | |
| FACTORY_FUNCTION_NAME, path.c_str(), dlerror()); | |
| dlclose(obj_handle); | |
| } else { | |
| _id_to_function_map.insert(FunctionHandleMap::value_type(id, func_handle)); | |
| _path_to_module_map.insert(ModuleHandleMap::value_type(path, ModuleHandles(obj_handle, func_handle))); | |
| Dbg(dbg_ctl, "[%s] Loaded handler module [%s]", __FUNCTION__, path.c_str()); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| SpecialIncludeHandler * | |
| HandlerManager::getHandler(Variables &esi_vars, Expression &esi_expr, HttpDataFetcher &fetcher, const std::string &id) const | |
| { | |
| FunctionHandleMap::const_iterator iter = _id_to_function_map.find(id); | |
| if (iter == _id_to_function_map.end()) { | |
| TSError("[%s::%s] handler id [%s] does not map to any loaded object", CLASS_NAME, __FUNCTION__, id.c_str()); | |
| return nullptr; | |
| } | |
| return (*(iter->second))(esi_vars, esi_expr, fetcher, id); | |
| } | |
| HandlerManager::~HandlerManager() | |
| { | |
| for (ModuleHandleMap::iterator map_iter = _path_to_module_map.begin(); map_iter != _path_to_module_map.end(); ++map_iter) { | |
| dlclose((map_iter->second).object); | |
| } | |
| } |