Revert to ASCII-only case insensitivity for get_header().

boost::regex doesn't respected locale.
This commit is contained in:
tastytea 2020-11-08 14:35:09 +01:00
parent dbfee4c2bd
commit d57e1c5cef
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 43 additions and 34 deletions

View File

@ -10,7 +10,6 @@ project(curl_wrapper
LANGUAGES CXX) LANGUAGES CXX)
find_package(CURL 7.52 REQUIRED) find_package(CURL 7.52 REQUIRED)
find_package(Boost 1.54 REQUIRED COMPONENTS regex)
add_subdirectory(src) add_subdirectory(src)

View File

@ -18,7 +18,5 @@ else()
target_link_libraries(${PROJECT_NAME} PUBLIC ${CURL_LIBRARIES}) target_link_libraries(${PROJECT_NAME} PUBLIC ${CURL_LIBRARIES})
endif() endif()
target_link_libraries(${PROJECT_NAME} PRIVATE Boost::regex)
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}
PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>") PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>")

View File

@ -16,25 +16,33 @@
#include "types.hpp" #include "types.hpp"
#include <boost/regex.hpp> #include <algorithm>
#include <cctype>
#include <string> #include <string>
#include <string_view> #include <string_view>
namespace curl_wrapper namespace curl_wrapper
{ {
std::string answer::get_header(const std::string_view field) const using std::tolower;
{
const boost::regex re_field(string("^") + field.data()
+ R"(:\s+([^\r\n]+))",
boost::regex::icase);
boost::cmatch match;
boost::regex_search(headers.c_str(), match, re_field); std::string_view answer::get_header(const std::string_view field) const
if (match[1].matched) {
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<size_t>(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 {}; return {};

View File

@ -91,13 +91,14 @@ struct answer
/*! /*!
* @brief Returns the value of a header field. * @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 * @since INSERT_VERSION
*/ */
[[nodiscard]] string get_header(string_view field) const; [[nodiscard]] string_view get_header(string_view field) const;
}; };
} // namespace curl_wrapper } // namespace curl_wrapper

View File

@ -3,6 +3,7 @@
#include <catch.hpp> #include <catch.hpp>
#include <exception> #include <exception>
#include <iostream>
#include <locale> #include <locale>
#include <string> #include <string>
@ -38,6 +39,7 @@ X-UmläÜt: 🙂
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
std::cerr << "Exception: " << e.what() << '\n';
exception = true; exception = true;
} }
@ -49,24 +51,25 @@ X-UmläÜt: 🙂
} }
} }
WHEN("We search for “X-UMLÄÜT”") // WHEN("We search for “X-UMLÄÜT”")
{ // {
try // try
{ // {
value = ret.get_header("X-UMLÄÜT"); // value = ret.get_header("X-UMLÄÜT");
} // }
catch (const std::exception &e) // catch (const std::exception &e)
{ // {
exception = true; // std::cerr << "Exception: " << e.what() << '\n';
} // exception = true;
// }
THEN("No exception is thrown") // THEN("No exception is thrown")
AND_THEN("The value is successfully extracted") // AND_THEN("The value is successfully extracted")
{ // {
REQUIRE_FALSE(exception); // REQUIRE_FALSE(exception);
REQUIRE(value == "🙂"); // REQUIRE(value == "🙂");
} // }
} // }
} }
} // namespace curl_wrapper } // namespace curl_wrapper