You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2015/06/12 21:21:58 UTC
[3/3] mesos git commit: Treat HTTP headers as case-insensitive.
Treat HTTP headers as case-insensitive.
Review: https://reviews.apache.org/r/33793
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a0811310
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a0811310
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a0811310
Branch: refs/heads/master
Commit: a0811310c82ee25644fc9a6362313ce3619e46d9
Parents: 0b7cbe8
Author: haosdent huang <ha...@gmail.com>
Authored: Fri Jun 12 12:03:27 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Fri Jun 12 12:13:39 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 49 ++++++++++++++++++++---
3rdparty/libprocess/src/encoder.hpp | 2 +-
3rdparty/libprocess/src/tests/http_tests.cpp | 27 +++++++++++++
3 files changed, 71 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a0811310/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index 51a00f5..e47cc7a 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -1,6 +1,7 @@
#ifndef __PROCESS_HTTP_HPP__
#define __PROCESS_HTTP_HPP__
+#include <ctype.h>
#include <stdint.h>
#include <atomic>
@@ -11,6 +12,8 @@
#include <string>
#include <vector>
+#include <boost/functional/hash.hpp>
+
#include <process/address.hpp>
#include <process/future.hpp>
#include <process/owned.hpp>
@@ -45,6 +48,36 @@ extern hashmap<uint16_t, std::string> statuses;
void initialize();
+struct CaseInsensitiveHash
+{
+ size_t operator () (const std::string& key) const
+ {
+ size_t seed = 0;
+ foreach (char c, key) {
+ boost::hash_combine(seed, ::tolower(c));
+ }
+ return seed;
+ }
+};
+
+
+struct CaseInsensitiveEqual
+{
+ bool operator () (const std::string& left, const std::string& right) const
+ {
+ if (left.size() != right.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < left.size(); ++i) {
+ if (::tolower(left[i]) != ::tolower(right[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+
struct Request
{
// Contains the client's address. Note that this may
@@ -52,11 +85,11 @@ struct Request
network::Address client;
// TODO(benh): Add major/minor version.
- // TODO(bmahler): Header names are not case sensitive! Either make these
- // case-insensitive, or add a variable for each header in HTTP 1.0/1.1 (like
- // we've done here with keepAlive).
- // Tracked by: https://issues.apache.org/jira/browse/MESOS-328.
- hashmap<std::string, std::string> headers;
+ hashmap<std::string,
+ std::string,
+ CaseInsensitiveHash,
+ CaseInsensitiveEqual> headers;
+
std::string method;
// TODO(benh): Replace 'url', 'path', 'query', and 'fragment' with URL.
@@ -237,7 +270,11 @@ struct Response
// TODO(benh): Add major/minor version.
std::string status;
- hashmap<std::string, std::string> headers;
+
+ hashmap<std::string,
+ std::string,
+ CaseInsensitiveHash,
+ CaseInsensitiveEqual> headers;
// Either provide a 'body', an absolute 'path' to a file, or a
// 'pipe' for streaming a response. Distinguish between the cases
http://git-wip-us.apache.org/repos/asf/mesos/blob/a0811310/3rdparty/libprocess/src/encoder.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/encoder.hpp b/3rdparty/libprocess/src/encoder.hpp
index f1b91cf..b898658 100644
--- a/3rdparty/libprocess/src/encoder.hpp
+++ b/3rdparty/libprocess/src/encoder.hpp
@@ -164,7 +164,7 @@ public:
out << "HTTP/1.1 " << response.status << "\r\n";
- hashmap<std::string, std::string> headers = response.headers;
+ auto headers = response.headers;
// HTTP 1.1 requires the "Date" header. In the future once we
// start checking the version (above) then we can conditionally
http://git-wip-us.apache.org/repos/asf/mesos/blob/a0811310/3rdparty/libprocess/src/tests/http_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/http_tests.cpp b/3rdparty/libprocess/src/tests/http_tests.cpp
index 708e331..8444b9c 100644
--- a/3rdparty/libprocess/src/tests/http_tests.cpp
+++ b/3rdparty/libprocess/src/tests/http_tests.cpp
@@ -591,6 +591,33 @@ TEST(HTTP, QueryEncodeDecode)
http::query::decode("a%26b%3Dc=d%26e%3Dfg"));
}
+
+TEST(HTTP, CaseInsensitiveHeaders)
+{
+ http::Request request;
+ request.headers["Content-Length"] = "20";
+ EXPECT_EQ("20", request.headers["Content-Length"]);
+ EXPECT_EQ("20", request.headers["CONTENT-LENGTH"]);
+ EXPECT_EQ("20", request.headers["content-length"]);
+
+ request.headers["content-length"] = "30";
+ EXPECT_EQ("30", request.headers["content-length"]);
+ EXPECT_EQ("30", request.headers["Content-Length"]);
+ EXPECT_EQ("30", request.headers["CONTENT-LENGTH"]);
+
+ http::Response response;
+ response.headers["Content-Type"] = "application/json";
+ EXPECT_EQ("application/json", response.headers["Content-Type"]);
+ EXPECT_EQ("application/json", response.headers["content-type"]);
+ EXPECT_EQ("application/json", response.headers["CONTENT-TYPE"]);
+
+ response.headers["content-type"] = "text/javascript";
+ EXPECT_EQ("text/javascript", response.headers["content-type"]);
+ EXPECT_EQ("text/javascript", response.headers["Content-Type"]);
+ EXPECT_EQ("text/javascript", response.headers["CONTENT-TYPE"]);
+}
+
+
// TODO(evelinad): Add URLTest for IPv6.
TEST(URLTest, stringification)
{