X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=parse.h;h=70b3b5ac20869850ada68d71518cd10ee08dbcb7;hp=a56b1f4230edce227ff616603c8a9550d8b70c55;hb=4c0ab81c4f1b5d0e76c5775a01819d3334cc9399;hpb=5b6002ffa927ae9987d978126fa7cc30067ac1f2 diff --git a/parse.h b/parse.h index a56b1f4..70b3b5a 100644 --- a/parse.h +++ b/parse.h @@ -4,10 +4,44 @@ // Various routines that deal with parsing; both HTTP requests and more generic text. #include -#include #include +#include +#include +#include #include +// Locale-unaware tolower(); matches RFC 2616 no matter what the locale is set to. +static inline char ascii_tolower(const char ch) +{ + if (ch >= 'A' && ch <= 'Z') { + return ch + 'a' - 'A'; + } else { + return ch; + } +} + +// Case-insensitive header comparison and hashing. +struct HTTPEqual { + bool operator() (const std::string &a, const std::string &b) const + { + return a.size() == b.size() && + std::equal( + begin(a), end(a), begin(b), + [](char a, char b) { + return ascii_tolower(a) == ascii_tolower(b); + }); + } +}; +struct HTTPHash { + size_t operator() (const std::string &s) const + { + std::string s_low = s; + for (char &ch : s_low) { ch = ascii_tolower(ch); } + return std::hash() (s_low); + } +}; +using HTTPHeaderMultimap = std::unordered_multimap; + // Split a line on whitespace, e.g. "foo bar baz" -> {"foo", "bar", "baz"}. std::vector split_tokens(const std::string &line); @@ -16,8 +50,7 @@ std::vector split_lines(const std::string &str); // Extract HTTP headers from a request or response. Ignores the first line, // where the verb or the return code is. -std::multimap extract_headers( - const std::vector &lines, const std::string &log_context); +HTTPHeaderMultimap extract_headers(const std::vector &lines, const std::string &log_context); // Add the new data to an existing string, looking for \r\n\r\n // (typical of HTTP requests and/or responses). Will return one