Skip to content

Commit a10f4e8

Browse files
authored
Merge pull request fhessel#77 from fhessel/fix/headers-case-insensitive
Normalize Case of Header Names
2 parents c0d31ae + c221d22 commit a10f4e8

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

src/HTTPHeader.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#include "HTTPHeader.hpp"
22

3+
#include <locale>
4+
#include <ostream>
5+
#include <sstream>
6+
37
namespace httpsserver {
48

59
HTTPHeader::HTTPHeader(const std::string &name, const std::string &value):
6-
_name(name),
10+
_name(normalizeHeaderName(name)),
711
_value(value) {
812

913
}
@@ -16,4 +20,24 @@ std::string HTTPHeader::print() {
1620
return _name + ": " + _value;
1721
}
1822

23+
std::string normalizeHeaderName(std::string const &name) {
24+
std::locale loc;
25+
std::stringbuf buf;
26+
std::ostream oBuf(&buf);
27+
bool upper = true;
28+
std::string::size_type len = name.length();
29+
for (std::string::size_type i = 0; i < len; ++i) {
30+
if (upper) {
31+
oBuf << std::toupper(name[i], loc);
32+
upper = false;
33+
} else {
34+
oBuf << std::tolower(name[i], loc);
35+
if (!std::isalnum(name[i], loc)) {
36+
upper=true;
37+
}
38+
}
39+
}
40+
return buf.str();
41+
}
42+
1943
} /* namespace httpsserver */

src/HTTPHeader.hpp

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ class HTTPHeader {
1818
std::string print();
1919
};
2020

21+
/**
22+
* \brief Normalizes case in header names
23+
*
24+
* It converts the first letter and every letter after a non-alnum character
25+
* to uppercase. For example, "content-length" becomes "Content-Length" and
26+
* "HOST" becomes "Host".
27+
*/
28+
std::string normalizeHeaderName(std::string const &name);
29+
2130
} /* namespace httpsserver */
2231

2332
#endif /* SRC_HTTPHEADER_HPP_ */

src/HTTPHeaders.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@ HTTPHeaders::~HTTPHeaders() {
1313
}
1414

1515
HTTPHeader * HTTPHeaders::get(std::string const &name) {
16+
std::string normalizedName = normalizeHeaderName(name);
1617
for(std::vector<HTTPHeader*>::iterator header = _headers->begin(); header != _headers->end(); ++header) {
17-
if ((*header)->_name.compare(name)==0) {
18+
if ((*header)->_name.compare(normalizedName)==0) {
1819
return (*header);
1920
}
2021
}
2122
return NULL;
2223
}
2324

2425
std::string HTTPHeaders::getValue(std::string const &name) {
26+
std::string normalizedName = normalizeHeaderName(name);
2527
for(std::vector<HTTPHeader*>::iterator header = _headers->begin(); header != _headers->end(); ++header) {
26-
if ((*header)->_name.compare(name)==0) {
28+
if ((*header)->_name.compare(normalizedName)==0) {
2729
return ((*header)->_value);
2830
}
2931
}

0 commit comments

Comments
 (0)