Branch data Line data Source code
1 : : /* 2 : : * Copyright (C) 2026 by Thun Lu. All rights reserved. 3 : : * Author: Thun Lu <thun.lu@zohomail.cn> 4 : : * Repo: https://github.com/thun-res/vlink 5 : : * _ __ __ _ __ 6 : : * | | / / / / (_) ____ / /__ 7 : : * | | / / / / / / / __ \ / //_/ 8 : : * | |/ / / /___ / / / / / / / ,< 9 : : * |___/ /_____/ /_/ /_/ /_/ /_/|_| 10 : : * 11 : : * Licensed under the Apache License, Version 2.0 (the "License"); 12 : : * you may not use this file except in compliance with the License. 13 : : * You may obtain a copy of the License at 14 : : * 15 : : * http://www.apache.org/licenses/LICENSE-2.0 16 : : * 17 : : * Unless required by applicable law or agreed to in writing, software 18 : : * distributed under the License is distributed on an "AS IS" BASIS, 19 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 : : * See the License for the specific language governing permissions and 21 : : * limitations under the License. 22 : : */ 23 : : 24 : : #include "./extension/url_remap.h" 25 : : 26 : : #include <filesystem> 27 : : #include <fstream> 28 : : #include <string> 29 : : #include <unordered_map> 30 : : #include <vector> 31 : : 32 : : #include "./base/helpers.h" 33 : : #include "./base/logger.h" 34 : : 35 : : // json 36 : : #include <nlohmann/json.hpp> 37 : : 38 : : namespace vlink { 39 : : 40 : : // UrlRemap 41 : 66 : UrlRemap::UrlRemap() noexcept = default; 42 : : 43 : 66 : UrlRemap::~UrlRemap() noexcept = default; 44 : : 45 : 15 : bool UrlRemap::load(const std::string& file_path) noexcept { 46 [ + + ]: 15 : if VUNLIKELY (is_valid_) { 47 : 1 : return false; 48 : : } 49 : : 50 : 14 : remap_list_.clear(); 51 : 14 : cache_map_.clear(); 52 : : 53 : 14 : std::filesystem::path target_path; 54 : : 55 : : try { 56 : : #ifdef _WIN32 57 : : target_path = std::filesystem::path(Helpers::string_to_wstring(file_path)); 58 : : #else 59 [ + - ]: 14 : target_path = std::filesystem::path(file_path); 60 : : #endif 61 : : 62 [ + - + + ]: 14 : if VUNLIKELY (!std::filesystem::exists(target_path)) { 63 [ + - ]: 2 : error_string_ = "UrlRemap file does not exist"; 64 : : 65 : 2 : is_valid_ = false; 66 : 2 : return false; 67 : : } 68 : : // LCOV_EXCL_START GCOVR_EXCL_START 69 : : } catch (std::filesystem::filesystem_error&) { 70 : : error_string_ = "UrlRemap file does not exist"; 71 : : 72 : : is_valid_ = false; 73 : : return false; 74 : : } 75 : : // LCOV_EXCL_STOP GCOVR_EXCL_STOP 76 : : 77 : : try { 78 : 12 : nlohmann::ordered_json root_json; 79 : : 80 : : { 81 [ + - ]: 12 : std::ifstream file(target_path); 82 : : 83 [ + + ]: 12 : file >> root_json; 84 : : 85 [ + - ]: 11 : file.close(); 86 : 12 : } 87 : : 88 [ + - - + : 11 : if VUNLIKELY (root_json.empty() || !root_json.is_object()) { - + ] 89 [ # # ]: 0 : error_string_ = "Wrong format"; 90 : : 91 [ # # # # ]: 0 : VLOG_W("UrlRemap: Parse error: ", error_string_, "."); 92 : : 93 : 0 : is_valid_ = false; 94 : 0 : return false; 95 : : } 96 : : 97 [ + - + - : 23 : for (const auto& [key, value] : root_json.items()) { + - + - + + ] 98 [ + - ]: 12 : remap_list_.emplace_back(key, value); 99 : 11 : } 100 [ + - - + ]: 13 : } catch (nlohmann::json::exception& e) { 101 : 1 : error_string_ = e.what(); 102 : : 103 : 2 : VLOG_W("UrlRemap: Parse error: ", error_string_, "."); 104 : : 105 : 1 : remap_list_.clear(); 106 : 1 : cache_map_.clear(); 107 : : 108 : 1 : is_valid_ = false; 109 : 1 : return false; 110 : 1 : } 111 : : 112 : 11 : error_string_.clear(); 113 : : 114 : 11 : is_valid_ = true; 115 : : 116 : 11 : return true; 117 : 14 : } 118 : : 119 : 5 : bool UrlRemap::unload() noexcept { 120 [ + + ]: 5 : if VUNLIKELY (!is_valid_) { 121 : 1 : return false; 122 : : } 123 : : 124 : 4 : remap_list_.clear(); 125 : 4 : cache_map_.clear(); 126 : : 127 : 4 : error_string_.clear(); 128 : : 129 : 4 : is_valid_ = false; 130 : : 131 : 4 : return true; 132 : : } 133 : : 134 : 2 : bool UrlRemap::reload(const std::string& file_path) noexcept { 135 : 2 : unload(); 136 : : 137 : 2 : return load(file_path); 138 : : } 139 : : 140 : 584 : const std::string& UrlRemap::convert(const std::string& url) noexcept { 141 [ + + ]: 584 : if VUNLIKELY (!is_valid_) { 142 : : // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter) 143 : 576 : return url; 144 : : } 145 : : 146 : 8 : auto iter = cache_map_.find(url); 147 : : 148 [ + + ]: 8 : if VLIKELY (iter != cache_map_.end()) { 149 : 1 : return iter->second; 150 : : } 151 : : 152 [ + + ]: 9 : for (const auto& [key, value] : remap_list_) { 153 [ + - + + : 8 : if (url != value && url.find(key) != std::string::npos) { + + ] 154 [ - + ]: 6 : if (is_enable_log_) { 155 : 0 : VLOG_I("UrlRemap: ", url, " -> ", value, "."); 156 : : } 157 : : 158 : 6 : cache_map_.try_emplace(url, value); 159 : 6 : return value; 160 : : } 161 : : } 162 : : 163 : 1 : cache_map_.try_emplace(url, url); 164 : : 165 : : // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter) 166 : 1 : return url; 167 : : } 168 : : 169 : : } // namespace vlink