\$\begingroup\$
\$\endgroup\$
When adding header data to the response. We accept what the user is telling us and do no conversion of the data.
But: The Response object (and its stream) is going to handle the encoding/ transport. So we filter out content-length:
and transport-encoding
headers from outgoing requests as this will be added manually by the Response
object.
HeaderResponse.h
#ifndef THORSANVIL_NISSE_NISSEHTTP_HEADER_RESPONSE_H
#define THORSANVIL_NISSE_NISSEHTTP_HEADER_RESPONSE_H
#include "NisseHTTPConfig.h"
#include <string_view>
#include <string>
#include <map>
#include <iostream>
namespace ThorsAnvil::Nisse::NisseHTTP
{
inline bool ichar_equals(char a, char b)
{
return std::tolower(static_cast<unsigned char>(a)) ==
std::tolower(static_cast<unsigned char>(b));
}
class HeaderResponse
{
std::map<std::string, std::string> headers;
public:
bool empty() const;
void add(std::string_view header, std::string_view value);
friend std::ostream& operator<<(std::ostream& stream, HeaderResponse const& headersBlock)
{
for (auto header: headersBlock.headers)
{
if (std::ranges::equal(std::string_view(header.first), std::string_view("content-length"), ichar_equals)) {
continue;
}
if (std::ranges::equal(std::string_view(header.first), std::string_view("transfer-encoding"), ichar_equals)) {
continue;
}
stream << header.first << ": " << header.second << "\r\n";
}
return stream;
}
};
}
#endif
HeaderResponse.cpp
#include "HeaderResponse.h"
using namespace ThorsAnvil::Nisse::NisseHTTP;
bool HeaderResponse::empty() const
{
return headers.empty();
}
void HeaderResponse::add(std::string_view header, std::string_view value)
{
headers.emplace(header, value);
}
asked Oct 20, 2024 at 20:54
1 Answer 1
\$\begingroup\$
\$\endgroup\$
1
- Better to keep all implementation logic in source file including
operator<<
and the inline function. You may replace the inline function with a lambda function like:auto ignore_case_char_compare = [](const char a, const char b) { return std::tolower(static_cast<unsigned char>(a)) == std::tolower(static_cast<unsigned char>(b)); };
for (auto header: headersBlock.headers)
, here you can use structured bindings to separate header key and value, like:for (const auto& [headerKey, headerValue] : headersBlock.headers)
- You can combine two
if
statements inside the loop into one using||
operator.
answered Oct 25, 2024 at 7:08
-
1\$\begingroup\$ Thanks. Did one and two. I think the readability is higher as separate statements for 3. \$\endgroup\$Loki Astari– Loki Astari2024年10月26日 00:27:13 +00:00Commented Oct 26, 2024 at 0:27
lang-cpp