mirror of
https://github.com/jupp0r/prometheus-cpp.git
synced 2026-07-21 14:33:30 +00:00
pull: Use internal base64 decoding function to avoid dependency (#417)
This commit is contained in:
@@ -34,6 +34,6 @@ esac
|
||||
|
||||
case "${BUILDSYSTEM_ARG}" in
|
||||
cmake)
|
||||
"${VCPKG_INSTALLATION_ROOT}/vcpkg" install benchmark civetweb cppcodec curl gtest zlib
|
||||
"${VCPKG_INSTALLATION_ROOT}/vcpkg" install benchmark civetweb curl gtest zlib
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if [%1] == [cmake] (
|
||||
%VCPKG_INSTALLATION_ROOT%/vcpkg install benchmark civetweb cppcodec curl gtest zlib || EXIT /B 1
|
||||
%VCPKG_INSTALLATION_ROOT%/vcpkg install benchmark civetweb curl gtest zlib || EXIT /B 1
|
||||
)
|
||||
|
||||
|
||||
@@ -4,6 +4,3 @@
|
||||
[submodule "civetweb"]
|
||||
path = 3rdparty/civetweb
|
||||
url = https://github.com/civetweb/civetweb.git
|
||||
[submodule "3rdparty/cppcodec"]
|
||||
path = 3rdparty/cppcodec
|
||||
url = https://github.com/tplgy/cppcodec.git
|
||||
|
||||
Vendored
-1
Submodule 3rdparty/cppcodec deleted from 302dc28f8f
@@ -1,6 +0,0 @@
|
||||
cc_library(
|
||||
name = "cppcodec",
|
||||
hdrs = glob(["cppcodec/**/*.hpp"]),
|
||||
includes = ["."],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -45,17 +45,6 @@ def prometheus_cpp_repositories():
|
||||
],
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "com_github_tplgy_cppcodec",
|
||||
sha256 = "0edaea2a9d9709d456aa99a1c3e17812ed130f9ef2b5c2d152c230a5cbc5c482",
|
||||
strip_prefix = "cppcodec-0.2",
|
||||
urls = [
|
||||
"https://github.com/tplgy/cppcodec/archive/v0.2.tar.gz",
|
||||
],
|
||||
build_file = "@com_github_jupp0r_prometheus_cpp//bazel:cppcodec.BUILD",
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "net_zlib_zlib",
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
find_path(CPPCODEC_INCLUDE_DIR base64_rfc4648.hpp PATH_SUFFIXES include/cppcodec)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(cppcodec DEFAULT_MSG CPPCODEC_INCLUDE_DIR)
|
||||
|
||||
if(cppcodec_FOUND)
|
||||
set(CPPCODEC_INCLUDE_DIRS "${CPPCODEC_INCLUDE_DIR}")
|
||||
endif()
|
||||
@@ -1,14 +0,0 @@
|
||||
get_filename_component(_IMPORT_PREFIX "${PROJECT_SOURCE_DIR}/3rdparty/cppcodec/" ABSOLUTE)
|
||||
|
||||
macro(set_and_check _var _file)
|
||||
set(${_var} "${_file}")
|
||||
if(NOT EXISTS "${_file}")
|
||||
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
set_and_check(CPPCODEC_INCLUDE_DIR ${_IMPORT_PREFIX})
|
||||
set(CPPCODEC_INCLUDE_DIRS "${CPPCODEC_INCLUDE_DIR}")
|
||||
|
||||
add_library(cppcodec INTERFACE)
|
||||
target_include_directories(cppcodec INTERFACE "$<BUILD_INTERFACE:${CPPCODEC_INCLUDE_DIR}>")
|
||||
+12
-1
@@ -23,7 +23,18 @@ cc_library(
|
||||
deps = [
|
||||
"//core",
|
||||
"@civetweb",
|
||||
"@com_github_tplgy_cppcodec//:cppcodec",
|
||||
"@net_zlib_zlib//:z",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "pull_internal_headers",
|
||||
hdrs = glob(
|
||||
["src/detail/*.h"],
|
||||
),
|
||||
strip_include_prefix = "src",
|
||||
visibility = ["//pull/tests:__subpackages__"],
|
||||
deps = [
|
||||
"//core",
|
||||
],
|
||||
)
|
||||
|
||||
+6
-9
@@ -5,15 +5,8 @@ if(USE_THIRDPARTY_LIBRARIES)
|
||||
TARGETS civetweb
|
||||
EXPORT ${PROJECT_NAME}-targets
|
||||
)
|
||||
find_package(cppcodec-3rdparty CONFIG REQUIRED)
|
||||
add_library(${PROJECT_NAME}::cppcodec ALIAS cppcodec)
|
||||
install(
|
||||
TARGETS cppcodec
|
||||
EXPORT ${PROJECT_NAME}-targets
|
||||
)
|
||||
else()
|
||||
find_package(civetweb CONFIG REQUIRED)
|
||||
find_package(cppcodec REQUIRED)
|
||||
|
||||
# work-around https://github.com/civetweb/civetweb/pull/918
|
||||
if(WIN32 AND NOT TARGET WINSOCK::WINSOCK)
|
||||
@@ -36,6 +29,8 @@ add_library(pull
|
||||
src/handler.h
|
||||
src/metrics_collector.cc
|
||||
src/metrics_collector.h
|
||||
|
||||
src/detail/base64.h
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME}::pull ALIAS pull)
|
||||
@@ -46,7 +41,6 @@ target_link_libraries(pull
|
||||
PRIVATE
|
||||
Threads::Threads
|
||||
$<IF:$<BOOL:${USE_THIRDPARTY_LIBRARIES}>,${PROJECT_NAME}::civetweb,civetweb::civetweb-cpp>
|
||||
$<$<BOOL:${USE_THIRDPARTY_LIBRARIES}>:${PROJECT_NAME}::cppcodec>
|
||||
$<$<AND:$<BOOL:UNIX>,$<NOT:$<BOOL:APPLE>>>:rt>
|
||||
$<$<BOOL:${ENABLE_COMPRESSION}>:ZLIB::ZLIB>
|
||||
)
|
||||
@@ -56,7 +50,6 @@ target_include_directories(pull
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
|
||||
PRIVATE
|
||||
${CPPCODEC_INCLUDE_DIRS} # needed as long as upstream cppcodec installs no config file with imported target
|
||||
${CIVETWEB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
@@ -93,5 +86,9 @@ install(
|
||||
)
|
||||
|
||||
if(ENABLE_TESTING)
|
||||
add_library(pull_internal_headers INTERFACE)
|
||||
add_library(${PROJECT_NAME}::pull_internal_headers ALIAS pull_internal_headers)
|
||||
target_include_directories(pull_internal_headers INTERFACE src)
|
||||
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#include "basic_auth.h"
|
||||
|
||||
#include <cppcodec/base64_rfc4648.hpp>
|
||||
|
||||
#include "CivetServer.h"
|
||||
#include "detail/base64.h"
|
||||
#include "prometheus/detail/future_std.h"
|
||||
|
||||
namespace prometheus {
|
||||
|
||||
using base64 = cppcodec::base64_rfc4648;
|
||||
|
||||
BasicAuthHandler::BasicAuthHandler(AuthFunc callback, std::string realm)
|
||||
: callback_(std::move(callback)), realm_(std::move(realm)) {}
|
||||
|
||||
@@ -42,7 +39,7 @@ bool BasicAuthHandler::AuthorizeInner(CivetServer*, mg_connection* conn) {
|
||||
|
||||
std::string decoded;
|
||||
try {
|
||||
decoded = base64::decode<std::string>(b64Auth.data(), b64Auth.size());
|
||||
decoded = detail::base64_decode(b64Auth);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace prometheus {
|
||||
namespace detail {
|
||||
|
||||
/*
|
||||
Copyright (C) 2019-2020 by Martin Vorbrodt <martin@vorbrodt.blog>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
https://github.com/mvorbrodt/blog/blob/master/src/base64.hpp
|
||||
*/
|
||||
|
||||
inline std::string base64_decode(const std::string& input) {
|
||||
const char kPadCharacter = '=';
|
||||
|
||||
if (input.length() % 4) {
|
||||
throw std::runtime_error("Invalid base64 length!");
|
||||
}
|
||||
|
||||
std::size_t padding = 0;
|
||||
|
||||
if (!input.empty()) {
|
||||
if (input[input.length() - 1] == kPadCharacter) padding++;
|
||||
if (input[input.length() - 2] == kPadCharacter) padding++;
|
||||
}
|
||||
|
||||
std::string decoded;
|
||||
decoded.reserve(((input.length() / 4) * 3) - padding);
|
||||
|
||||
std::uint32_t temp = 0;
|
||||
auto it = input.begin();
|
||||
|
||||
while (it < input.end()) {
|
||||
for (std::size_t i = 0; i < 4; ++i) {
|
||||
temp <<= 6;
|
||||
if (*it >= 0x41 && *it <= 0x5A) {
|
||||
temp |= *it - 0x41;
|
||||
} else if (*it >= 0x61 && *it <= 0x7A) {
|
||||
temp |= *it - 0x47;
|
||||
} else if (*it >= 0x30 && *it <= 0x39) {
|
||||
temp |= *it + 0x04;
|
||||
} else if (*it == 0x2B) {
|
||||
temp |= 0x3E;
|
||||
} else if (*it == 0x2F) {
|
||||
temp |= 0x3F;
|
||||
} else if (*it == kPadCharacter) {
|
||||
switch (input.end() - it) {
|
||||
case 1:
|
||||
decoded.push_back((temp >> 16) & 0x000000FF);
|
||||
decoded.push_back((temp >> 8) & 0x000000FF);
|
||||
return decoded;
|
||||
case 2:
|
||||
decoded.push_back((temp >> 10) & 0x000000FF);
|
||||
return decoded;
|
||||
default:
|
||||
throw std::runtime_error("Invalid padding in base64!");
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Invalid character in base64!");
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
decoded.push_back((temp >> 16) & 0x000000FF);
|
||||
decoded.push_back((temp >> 8) & 0x000000FF);
|
||||
decoded.push_back((temp)&0x000000FF);
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace prometheus
|
||||
@@ -1,2 +1,3 @@
|
||||
add_subdirectory(integration)
|
||||
add_subdirectory(internal)
|
||||
add_subdirectory(unit)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
cc_test(
|
||||
name = "internal",
|
||||
srcs = glob([
|
||||
"*.cc",
|
||||
"*.h",
|
||||
]),
|
||||
copts = ["-Iexternal/googletest/include"],
|
||||
linkstatic = True,
|
||||
deps = [
|
||||
"//pull:pull_internal_headers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
add_executable(prometheus_pull_internal_test
|
||||
base64_test.cc
|
||||
)
|
||||
|
||||
target_link_libraries(prometheus_pull_internal_test
|
||||
PRIVATE
|
||||
${PROJECT_NAME}::pull_internal_headers
|
||||
GTest::gmock_main
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME prometheus_pull_internal_test
|
||||
COMMAND prometheus_pull_internal_test
|
||||
)
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "detail/base64.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace prometheus {
|
||||
namespace {
|
||||
|
||||
struct TestVector {
|
||||
const std::string decoded;
|
||||
const std::string encoded;
|
||||
};
|
||||
|
||||
const TestVector testVector[] = {
|
||||
{"", ""},
|
||||
{"f", "Zg=="},
|
||||
{"fo", "Zm8="},
|
||||
{"foo", "Zm9v"},
|
||||
{"foob", "Zm9vYg=="},
|
||||
{"fooba", "Zm9vYmE="},
|
||||
{"foobar", "Zm9vYmFy"},
|
||||
};
|
||||
|
||||
const unsigned nVectors = sizeof(testVector) / sizeof(testVector[0]);
|
||||
|
||||
using namespace testing;
|
||||
|
||||
TEST(Base64Test, decodeTest) {
|
||||
for (unsigned i = 0; i < nVectors; ++i) {
|
||||
std::string decoded = detail::base64_decode(testVector[i].encoded);
|
||||
EXPECT_EQ(testVector[i].decoded, decoded);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Base64Test, rejectInvalidSymbols) {
|
||||
EXPECT_ANY_THROW(detail::base64_decode("...."));
|
||||
}
|
||||
|
||||
TEST(Base64Test, rejectInvalidInputSize) {
|
||||
EXPECT_ANY_THROW(detail::base64_decode("ABC"));
|
||||
}
|
||||
|
||||
TEST(Base64Test, rejectInvalidPadding) {
|
||||
EXPECT_ANY_THROW(detail::base64_decode("A==="));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace prometheus
|
||||
Reference in New Issue
Block a user