LCOV - code coverage report
Current view: top level - model - AdminServerMatchingData.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 61 61
Test Date: 2026-04-17 17:21:26 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :  ___________________________________________
       3              : |    _     ___                        _     |
       4              : |   | |   |__ \                      | |    |
       5              : |   | |__    ) |__ _  __ _  ___ _ __ | |_   |
       6              : |   | '_ \  / // _` |/ _` |/ _ \ '_ \| __|  |  HTTP/2 AGENT FOR MOCK TESTING
       7              : |   | | | |/ /| (_| | (_| |  __/ | | | |_   |  Version 0.0.z
       8              : |   |_| |_|____\__,_|\__, |\___|_| |_|\__|  |  https://github.com/testillano/h2agent
       9              : |                     __/ |                 |
      10              : |                    |___/                  |
      11              : |___________________________________________|
      12              : 
      13              : Licensed under the MIT License <http://opensource.org/licenses/MIT>.
      14              : SPDX-License-Identifier: MIT
      15              : Copyright (c) 2021 Eduardo Ramos
      16              : 
      17              : Permission is hereby  granted, free of charge, to any  person obtaining a copy
      18              : of this software and associated  documentation files (the "Software"), to deal
      19              : in the Software  without restriction, including without  limitation the rights
      20              : to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
      21              : copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
      22              : furnished to do so, subject to the following conditions:
      23              : 
      24              : The above copyright notice and this permission notice shall be included in all
      25              : copies or substantial portions of the Software.
      26              : 
      27              : THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
      28              : IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
      29              : FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
      30              : AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
      31              : LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      32              : OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
      33              : SOFTWARE.
      34              : */
      35              : 
      36              : #include <string>
      37              : #include <regex>
      38              : 
      39              : #include <nlohmann/json.hpp>
      40              : 
      41              : #include <ert/tracing/Logger.hpp>
      42              : 
      43              : #include <AdminServerMatchingData.hpp>
      44              : 
      45              : namespace h2agent
      46              : {
      47              : namespace model
      48              : {
      49              : 
      50          307 : AdminServerMatchingData::AdminServerMatchingData() {
      51          307 :     auto cfg = std::make_shared<Config>();
      52          307 :     cfg->json["algorithm"] = "FullMatching";
      53          307 :     std::atomic_store(&config_, std::shared_ptr<const Config>(std::move(cfg)));
      54              : 
      55          307 :     server_matching_schema_.setJson(h2agent::adminSchemas::server_matching); // won't fail
      56          307 : }
      57              : 
      58          194 : AdminServerMatchingData::LoadResult AdminServerMatchingData::load(const nlohmann::json &j) {
      59              : 
      60          194 :     std::string error{};
      61          194 :     if (!server_matching_schema_.validate(j, error)) {
      62            5 :         return BadSchema;
      63              :     }
      64              : 
      65              :     // Build new immutable config on the side (no lock held)
      66          189 :     auto cfg = std::make_shared<Config>();
      67          189 :     cfg->json = j;
      68              : 
      69              :     // Mandatory
      70          189 :     auto algorithm_it = j.find("algorithm");
      71              : 
      72              :     // Optional
      73          189 :     bool hasRgx = false;
      74          189 :     bool hasFmt = false;
      75          189 :     auto rgx_it = j.find("rgx");
      76          189 :     if (rgx_it != j.end() && rgx_it->is_string()) {
      77            6 :         hasRgx = true;
      78              :         try {
      79            7 :             cfg->rgx.assign(rgx_it->get<std::string>(), std::regex::optimize);
      80              :         }
      81            1 :         catch (std::regex_error &e) {
      82            1 :             ert::tracing::Logger::error(e.what(), ERT_FILE_LOCATION);
      83            1 :             return BadContent;
      84            1 :         }
      85              :     }
      86              : 
      87          188 :     auto fmt_it = j.find("fmt");
      88          188 :     if (fmt_it != j.end() && fmt_it->is_string()) {
      89            4 :         hasFmt = true;
      90            4 :         cfg->fmt = *fmt_it;
      91              :     }
      92              : 
      93          188 :     auto uriPathQueryParameters_it = j.find("uriPathQueryParameters");
      94          188 :     if (uriPathQueryParameters_it != j.end()) {
      95            4 :         auto filter_it = (*uriPathQueryParameters_it).find("filter"); // mandatory
      96            4 :         if (filter_it->is_string()) {
      97            4 :             if (*filter_it == "Sort") {
      98            2 :                 cfg->uri_path_query_parameters_filter = Sort;
      99              :             }
     100            2 :             else if (*filter_it == "PassBy") {
     101            1 :                 cfg->uri_path_query_parameters_filter = PassBy;
     102              :             }
     103            1 :             else if (*filter_it == "Ignore") {
     104            1 :                 cfg->uri_path_query_parameters_filter = Ignore;
     105              :             }
     106              :         }
     107              : 
     108            4 :         auto separator_it = (*uriPathQueryParameters_it).find("separator"); // optional
     109            4 :         if (separator_it != (*uriPathQueryParameters_it).end() && separator_it->is_string()) {
     110            2 :             if (*separator_it == "Ampersand") {
     111            1 :                 cfg->uri_path_query_parameters_separator = Ampersand;
     112              :             }
     113            1 :             else if (*separator_it == "Semicolon") {
     114            1 :                 cfg->uri_path_query_parameters_separator = Semicolon;
     115              :             }
     116              :         }
     117              :     }
     118              : 
     119              :     // Checkings
     120          188 :     if (*algorithm_it == "FullMatching") {
     121          176 :         if (hasRgx || hasFmt) {
     122            3 :             ert::tracing::Logger::error("FullMatching does not allow rgx and/or fmt fields", ERT_FILE_LOCATION);
     123            3 :             return BadContent;
     124              :         }
     125          173 :         cfg->algorithm = FullMatching;
     126              :     }
     127           12 :     else if (*algorithm_it == "FullMatchingRegexReplace") {
     128            3 :         if (!hasRgx || !hasFmt) {
     129            1 :             ert::tracing::Logger::error("FullMatchingRegexReplace requires rgx and fmt fields", ERT_FILE_LOCATION);
     130            1 :             return BadContent;
     131              :         }
     132            2 :         cfg->algorithm = FullMatchingRegexReplace;
     133              :     }
     134            9 :     else if (*algorithm_it == "RegexMatching") {
     135            9 :         if (hasRgx || hasFmt) {
     136            2 :             ert::tracing::Logger::error("RegexMatching does not allow rgx and/or fmt fields", ERT_FILE_LOCATION);
     137            2 :             return BadContent;
     138              :         }
     139            7 :         cfg->algorithm = RegexMatching;
     140              :     }
     141              : 
     142              :     // Atomic swap — traffic threads holding the old shared_ptr are safe
     143          182 :     std::atomic_store(&config_, std::shared_ptr<const Config>(std::move(cfg)));
     144              : 
     145          182 :     return Success;
     146          194 : }
     147              : 
     148              : }
     149              : }
     150              : 
        

Generated by: LCOV version 2.0-1