Revert to ASCII-only case insensitivity for get_header().
boost::regex doesn't respected locale.
This commit is contained in:
parent
dbfee4c2bd
commit
d57e1c5cef
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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>")
|
||||||
|
|
|
@ -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 {};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue