LCOV - code coverage report
Current view: top level - source/extensions/router/cluster_specifiers/lua - lua_cluster_specifier.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 60 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.h"
       2             : 
       3             : #include "source/common/router/config_impl.h"
       4             : 
       5             : namespace Envoy {
       6             : namespace Extensions {
       7             : namespace Router {
       8             : namespace Lua {
       9             : 
      10             : PerLuaCodeSetup::PerLuaCodeSetup(const std::string& lua_code, ThreadLocal::SlotAllocator& tls)
      11           0 :     : lua_state_(lua_code, tls) {
      12           0 :   lua_state_.registerType<HeaderMapWrapper>();
      13           0 :   lua_state_.registerType<RouteHandleWrapper>();
      14             : 
      15           0 :   const Filters::Common::Lua::InitializerList initializers;
      16             : 
      17           0 :   cluster_function_slot_ = lua_state_.registerGlobal("envoy_on_route", initializers);
      18           0 :   if (lua_state_.getGlobalRef(cluster_function_slot_) == LUA_REFNIL) {
      19           0 :     throw EnvoyException(
      20           0 :         "envoy_on_route() function not found. Lua will not hook cluster specifier.");
      21           0 :   }
      22           0 : }
      23             : 
      24           0 : int HeaderMapWrapper::luaGet(lua_State* state) {
      25           0 :   absl::string_view key = Filters::Common::Lua::getStringViewFromLuaString(state, 2);
      26           0 :   const Envoy::Http::HeaderUtility::GetAllOfHeaderAsStringResult value =
      27           0 :       Envoy::Http::HeaderUtility::getAllOfHeaderAsString(headers_,
      28           0 :                                                          Envoy::Http::LowerCaseString(key));
      29           0 :   if (value.result().has_value()) {
      30           0 :     lua_pushlstring(state, value.result().value().data(), value.result().value().size());
      31           0 :     return 1;
      32           0 :   } else {
      33           0 :     return 0;
      34           0 :   }
      35           0 : }
      36             : 
      37           0 : int RouteHandleWrapper::luaHeaders(lua_State* state) {
      38           0 :   if (headers_wrapper_.get() != nullptr) {
      39           0 :     headers_wrapper_.pushStack();
      40           0 :   } else {
      41           0 :     headers_wrapper_.reset(HeaderMapWrapper::create(state, headers_), true);
      42           0 :   }
      43           0 :   return 1;
      44           0 : }
      45             : 
      46             : LuaClusterSpecifierConfig::LuaClusterSpecifierConfig(
      47             :     const LuaClusterSpecifierConfigProto& config,
      48             :     Server::Configuration::CommonFactoryContext& context)
      49             :     : main_thread_dispatcher_(context.mainThreadDispatcher()),
      50           0 :       default_cluster_(config.default_cluster()) {
      51           0 :   const std::string code_str = Config::DataSource::read(config.source_code(), true, context.api());
      52           0 :   per_lua_code_setup_ptr_ = std::make_unique<PerLuaCodeSetup>(code_str, context.threadLocal());
      53           0 : }
      54             : 
      55             : LuaClusterSpecifierPlugin::LuaClusterSpecifierPlugin(LuaClusterSpecifierConfigSharedPtr config)
      56             :     : config_(config),
      57             :       function_ref_(config_->perLuaCodeSetup() ? config_->perLuaCodeSetup()->clusterFunctionRef()
      58           0 :                                                : LUA_REFNIL) {}
      59             : 
      60           0 : std::string LuaClusterSpecifierPlugin::startLua(const Http::HeaderMap& headers) const {
      61           0 :   if (function_ref_ == LUA_REFNIL) {
      62           0 :     return config_->defaultCluster();
      63           0 :   }
      64           0 :   Filters::Common::Lua::CoroutinePtr coroutine = config_->perLuaCodeSetup()->createCoroutine();
      65             : 
      66           0 :   RouteHandleRef handle;
      67           0 :   handle.reset(RouteHandleWrapper::create(coroutine->luaState(), headers), true);
      68             : 
      69           0 :   TRY_NEEDS_AUDIT {
      70           0 :     coroutine->start(function_ref_, 1, []() {});
      71           0 :   }
      72           0 :   END_TRY catch (const Filters::Common::Lua::LuaException& e) {
      73           0 :     ENVOY_LOG(error, "script log: {}, use default cluster", e.what());
      74           0 :     return config_->defaultCluster();
      75           0 :   }
      76           0 :   if (!lua_isstring(coroutine->luaState(), -1)) {
      77           0 :     ENVOY_LOG(error, "script log: return value is not string, use default cluster");
      78           0 :     return config_->defaultCluster();
      79           0 :   }
      80           0 :   return std::string(Filters::Common::Lua::getStringViewFromLuaString(coroutine->luaState(), -1));
      81           0 : }
      82             : 
      83             : Envoy::Router::RouteConstSharedPtr
      84             : LuaClusterSpecifierPlugin::route(Envoy::Router::RouteConstSharedPtr parent,
      85           0 :                                  const Http::RequestHeaderMap& headers) const {
      86           0 :   return std::make_shared<Envoy::Router::RouteEntryImplBase::DynamicRouteEntry>(
      87           0 :       dynamic_cast<const Envoy::Router::RouteEntryImplBase*>(parent.get()), parent,
      88           0 :       startLua(headers));
      89           0 : }
      90             : } // namespace Lua
      91             : } // namespace Router
      92             : } // namespace Extensions
      93             : } // namespace Envoy

Generated by: LCOV version 1.15