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)
find_package(CURL 7.52 REQUIRED)
find_package(Boost 1.54 REQUIRED COMPONENTS regex)
add_subdirectory(src)

View File

@ -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 "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>")

View File

@ -16,25 +16,33 @@
#include "types.hpp"
#include <boost/regex.hpp>
#include <algorithm>
#include <cctype>
#include <string>
#include <string_view>
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<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 {};

View File

@ -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

View File

@ -3,6 +3,7 @@
#include <catch.hpp>
#include <exception>
#include <iostream>
#include <locale>
#include <string>
@ -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