blob: 85a2702b3f0b47f9f3f90cb1ebce1281f7517535 [file]
/*
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;