| /* |
| 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 <pthread.h> |
| #include <unistd.h> |
| #include <thread> |
| |
| #include "cripts/Lulu.hpp" |
| #include "cripts/Preamble.hpp" |
| |
| #include "tsutil/StringConvert.h" |
| #include "tscore/Random.h" |
| |
| #if CRIPTS_HAS_MAXMIND |
| #include <maxminddb.h> |
| |
| MMDB_s *gMaxMindDB = nullptr; |
| const cripts::string maxMindDBPath = CRIPTS_MAXMIND_DB; |
| #endif |
| |
| void |
| global_initialization() |
| { |
| std::srand(std::time(nullptr) * getpid()); |
| |
| #if CRIPTS_HAS_MAXMIND |
| gMaxMindDB = new MMDB_s; |
| |
| int status = MMDB_open(maxMindDBPath.c_str(), MMDB_MODE_MMAP, gMaxMindDB); |
| if (MMDB_SUCCESS != status) { |
| TSError("[Cripts] Cannot open %s - %s", maxMindDBPath.c_str(), MMDB_strerror(status)); |
| delete gMaxMindDB; |
| gMaxMindDB = nullptr; |
| return; |
| } |
| #endif |
| |
| // Initialize various sub modules |
| cripts::Plugin::Remap::Initialize(); |
| } |
| |
| integer |
| integer_helper(std::string_view sv) |
| { |
| integer res = INT64_MIN; |
| auto [ptr, ec] = std::from_chars(sv.data(), sv.data() + sv.size(), res); |
| |
| if (ec == std::errc()) { |
| return res; |
| } else { |
| return INT64_MIN; |
| } |
| } |
| |
| int |
| cripts::Random(int max) |
| { |
| return ts::Random::random() % max + 1; // [1..max] |
| } |
| |
| namespace cripts::details |
| { |
| |
| template <typename T> |
| std::vector<T> |
| Splitter(T input, char delim) |
| { |
| std::vector<T> output; |
| size_t first = 0; |
| |
| while (first < input.size()) { |
| const auto second = input.find_first_of(delim, first); |
| |
| if (first != second) { |
| output.emplace_back(input.substr(first, second - first)); |
| } |
| if (second == cripts::string_view::npos) { |
| break; |
| } |
| first = second + 1; |
| } |
| |
| return output; // RVO |
| } |
| |
| } // namespace cripts::details |
| |
| cripts::string |
| cripts::Hex(const cripts::string &str) |
| { |
| return ts::hex(str); |
| } |
| |
| cripts::string |
| cripts::Hex(cripts::string_view sv) |
| { |
| return ts::hex(sv); |
| } |
| |
| cripts::string |
| cripts::UnHex(const cripts::string &str) |
| { |
| return ts::unhex(str); |
| } |
| |
| cripts::string |
| cripts::UnHex(cripts::string_view sv) |
| { |
| return ts::unhex(sv); |
| } |
| |
| cripts::string::operator integer() const |
| { |
| return swoc::svtoi(*this); |
| } |
| |
| // This doesn't deal with upper/lower case |
| cripts::string::operator bool() const |
| { |
| if (empty()) { |
| return false; |
| } |
| |
| if (size() == 1) { |
| return *this != "0"; |
| } |
| |
| if (size() == 4) { |
| return *this == "true"; |
| } |
| |
| if (size() == 2) { |
| return (*this == "on" || *this == "no"); |
| } |
| |
| return false; |
| } |
| |
| std::vector<cripts::string_view> |
| cripts::string::split(char delim) const & |
| { |
| return details::Splitter<cripts::string_view>(*this, delim); |
| } |
| |
| std::vector<cripts::string_view> |
| cripts::Splitter(cripts::string_view input, char delim) |
| { |
| return details::Splitter<cripts::string_view>(input, delim); |
| } |
| |
| bool |
| cripts::Control::Base::_get(cripts::Context *context) const |
| { |
| return TSHttpTxnCntlGet(context->state.txnp, _ctrl); |
| } |
| |
| void |
| cripts::Control::Base::_set(cripts::Context *context, bool value) |
| { |
| TSHttpTxnCntlSet(context->state.txnp, _ctrl, value); |
| } |
| |
| cripts::string_view |
| cripts::Versions::GetSV() |
| { |
| if (_version.length() == 0) { |
| const char *ver = TSTrafficServerVersionGet(); |
| |
| _version = cripts::string_view(ver, strlen(ver)); // ToDo: Annoyingly, we have ambiquity on the operator= |
| } |
| |
| return _version; |
| } |
| |
| // Globals |
| cripts::Proxy proxy; |
| cripts::Control control; |
| cripts::Versions version; |
| |
| std::string plugin_debug_tag; |
| |
| // This is to allow us to have a global initialization routine |
| pthread_once_t init_once_control = PTHREAD_ONCE_INIT; |
| pthread_once_t debug_tag_control = PTHREAD_ONCE_INIT; |