diff --git a/dlib/server/server_http.cpp b/dlib/server/server_http.cpp index ec5b45686..a5ac744e2 100644 --- a/dlib/server/server_http.cpp +++ b/dlib/server/server_http.cpp @@ -175,7 +175,7 @@ namespace dlib // Get the HTTP/1.1 - Ignore for now... read_with_limit(in, incoming.protocol); - key_value_map& incoming_headers = incoming.headers; + key_value_map_ci& incoming_headers = incoming.headers; key_value_map& cookies = incoming.cookies; std::string& path = incoming.path; std::string& content_type = incoming.content_type; @@ -333,11 +333,11 @@ namespace dlib { using namespace http_impl; key_value_map& new_cookies = outgoing.cookies; - key_value_map& response_headers = outgoing.headers; + key_value_map_ci& response_headers = outgoing.headers; // only send this header if the user hasn't told us to send another kind bool has_content_type = false, has_location = false; - for(key_value_map::const_iterator ci = response_headers.begin(); ci != response_headers.end(); ++ci ) + for(key_value_map_ci::const_iterator ci = response_headers.begin(); ci != response_headers.end(); ++ci ) { if ( !has_content_type && strings_equal_ignore_case(ci->first , "content-type") ) { @@ -364,7 +364,7 @@ namespace dlib out << "HTTP/1.0 " << outgoing.http_return << " " << outgoing.http_return_status << "\r\n"; // Set any new headers - for(key_value_map::const_iterator ci = response_headers.begin(); ci != response_headers.end(); ++ci ) + for(key_value_map_ci::const_iterator ci = response_headers.begin(); ci != response_headers.end(); ++ci ) { out << ci->first << ": " << ci->second << "\r\n"; } diff --git a/dlib/server/server_http.h b/dlib/server/server_http.h index befb0a322..35335a9d1 100644 --- a/dlib/server/server_http.h +++ b/dlib/server/server_http.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "../logger.h" #include "../string.h" @@ -39,15 +40,15 @@ namespace dlib // ---------------------------------------------------------------------------------------- - template - class constmap : public std::map + template > + class constmap : public std::map { public: const Value& operator[](const Key& k) const { static const Value dummy = Value(); - typename std::map::const_iterator ci = std::map::find(k); + typename std::map::const_iterator ci = std::map::find(k); if ( ci == this->end() ) return dummy; @@ -57,10 +58,34 @@ namespace dlib Value& operator[](const Key& k) { - return std::map::operator [](k); + return std::map::operator [](k); } }; + + class less_case_insensitive + { + public: + bool operator()(const std::string& a, const std::string& b) const + { + long i = 0; + while (i < a.size() && i < b.size()) + { + const int cha = std::tolower(a[i]); + const int chb = std::tolower(b[i]); + if (cha < chb) + return true; + else if (cha > chb) + return false; + ++i; + } + if (a.size() < b.size()) + return true; + else + return false; + } + }; + typedef constmap< std::string, std::string, less_case_insensitive > key_value_map_ci; typedef constmap< std::string, std::string > key_value_map; struct incoming_things @@ -86,7 +111,7 @@ namespace dlib key_value_map queries; key_value_map cookies; - key_value_map headers; + key_value_map_ci headers; std::string foreign_ip; unsigned short foreign_port; @@ -99,7 +124,7 @@ namespace dlib outgoing_things() : http_return(200), http_return_status("OK") { } key_value_map cookies; - key_value_map headers; + key_value_map_ci headers; unsigned short http_return; std::string http_return_status; }; diff --git a/dlib/server/server_http_abstract.h b/dlib/server/server_http_abstract.h index fd3f22c0f..0bebfb61d 100644 --- a/dlib/server/server_http_abstract.h +++ b/dlib/server/server_http_abstract.h @@ -15,9 +15,10 @@ namespace dlib template < typename Key, - typename Value + typename Value, + typename Comparer = std::less > - class constmap : public std::map + class constmap : public std::map { /*! WHAT THIS OBJECT REPRESENTS @@ -56,6 +57,10 @@ namespace dlib }; typedef constmap key_value_map; + // This version of key_value_map treats the key string as being case-insensitive. + // For example, a key string of "Content-Type" would access the same element as a key + // of "content-type". + typedef constmap key_value_map_ci; // ----------------------------------------------------------------------------------------- @@ -90,13 +95,13 @@ namespace dlib std::string protocol; std::string body; - key_value_map queries; - key_value_map cookies; - key_value_map headers; + key_value_map queries; + key_value_map cookies; + key_value_map_ci headers; - std::string foreign_ip; + std::string foreign_ip; unsigned short foreign_port; - std::string local_ip; + std::string local_ip; unsigned short local_port; }; @@ -119,10 +124,10 @@ namespace dlib - #http_return_status == "OK" !*/ - key_value_map cookies; - key_value_map headers; - unsigned short http_return; - std::string http_return_status; + key_value_map cookies; + key_value_map_ci headers; + unsigned short http_return; + std::string http_return_status; }; // -----------------------------------------------------------------------------------------