From d57e1c5cef631944fdeed5e46805b3962e3324fd Mon Sep 17 00:00:00 2001 From: tastytea Date: Sun, 8 Nov 2020 14:35:09 +0100 Subject: [PATCH] Revert to ASCII-only case insensitivity for get_header(). boost::regex doesn't respected locale. --- CMakeLists.txt | 1 - src/CMakeLists.txt | 2 -- src/types.cpp | 30 +++++++++++++++++++----------- src/types.hpp | 7 ++++--- tests/test_headers.cpp | 37 ++++++++++++++++++++----------------- 5 files changed, 43 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27d8e37..9d64249 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,6 @@ project(curl_wrapper LANGUAGES CXX) find_package(CURL 7.52 REQUIRED) -find_package(Boost 1.54 REQUIRED COMPONENTS regex) add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5fd64c4..423993c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,7 +18,5 @@ else() target_link_libraries(${PROJECT_NAME} PUBLIC ${CURL_LIBRARIES}) endif() -target_link_libraries(${PROJECT_NAME} PRIVATE Boost::regex) - target_include_directories(${PROJECT_NAME} PUBLIC "$") diff --git a/src/types.cpp b/src/types.cpp index af89cfd..a59430e 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -16,25 +16,33 @@ #include "types.hpp" -#include - +#include +#include #include #include namespace curl_wrapper { -std::string answer::get_header(const std::string_view field) const -{ - const boost::regex re_field(string("^") + field.data() - + R"(:\s+([^\r\n]+))", - boost::regex::icase); - boost::cmatch match; +using std::tolower; - boost::regex_search(headers.c_str(), match, re_field); - if (match[1].matched) +std::string_view answer::get_header(const std::string_view field) const +{ + const string searchstring{string(field) += ":"}; + // clang-format off + auto it{std::search(headers.begin(), headers.end(), searchstring.begin(), + searchstring.end(), + [](unsigned char a, unsigned char b) + { return tolower(a) == tolower(b); })}; + // clang-format on + + if (it != headers.end()) { - return match[1].str(); + auto pos{static_cast(it - headers.begin())}; + pos = headers.find(':', pos) + 1; + pos = headers.find_first_not_of(' ', pos); + const auto endpos{headers.find_first_of("\r\n", pos)}; + return string_view(&headers[pos], endpos - pos); } return {}; diff --git a/src/types.hpp b/src/types.hpp index 66fd0b6..08949e0 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -91,13 +91,14 @@ struct answer /*! * @brief Returns the value of a header field. * - * @param field Case insensitive, uses default locale. + * @param field Case insensitive, ASCII only. * - * @return The value of the header field as std::string or {} if not found. + * @return A std::string_view to the value of the header field or {} if not + * found. * * @since INSERT_VERSION */ - [[nodiscard]] string get_header(string_view field) const; + [[nodiscard]] string_view get_header(string_view field) const; }; } // namespace curl_wrapper diff --git a/tests/test_headers.cpp b/tests/test_headers.cpp index 73a6822..06d279b 100644 --- a/tests/test_headers.cpp +++ b/tests/test_headers.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -38,6 +39,7 @@ X-UmläÜt: 🙂 } catch (const std::exception &e) { + std::cerr << "Exception: " << e.what() << '\n'; exception = true; } @@ -49,24 +51,25 @@ X-UmläÜt: 🙂 } } - WHEN("We search for “X-UMLÄÜT”") - { - try - { - value = ret.get_header("X-UMLÄÜT"); - } - catch (const std::exception &e) - { - exception = true; - } + // WHEN("We search for “X-UMLÄÜT”") + // { + // try + // { + // value = ret.get_header("X-UMLÄÜT"); + // } + // catch (const std::exception &e) + // { + // std::cerr << "Exception: " << e.what() << '\n'; + // exception = true; + // } - THEN("No exception is thrown") - AND_THEN("The value is successfully extracted") - { - REQUIRE_FALSE(exception); - REQUIRE(value == "🙂"); - } - } + // THEN("No exception is thrown") + // AND_THEN("The value is successfully extracted") + // { + // REQUIRE_FALSE(exception); + // REQUIRE(value == "🙂"); + // } + // } } } // namespace curl_wrapper