Added Steven Van Ingelgem's patch to the HTTP server which makes

operations on HTTP headers case-insensitive.
This commit is contained in:
Davis King 2013-08-07 13:08:20 -04:00
parent 9fa2cc573d
commit 4cc14d2663
3 changed files with 51 additions and 21 deletions

View File

@ -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";
}

View File

@ -8,6 +8,7 @@
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
#include <map>
#include "../logger.h"
#include "../string.h"
@ -39,15 +40,15 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <typename Key, typename Value>
class constmap : public std::map<Key, Value>
template <typename Key, typename Value, typename Comparer = std::less<Key> >
class constmap : public std::map<Key, Value, Comparer>
{
public:
const Value& operator[](const Key& k) const
{
static const Value dummy = Value();
typename std::map<Key, Value>::const_iterator ci = std::map<Key, Value>::find(k);
typename std::map<Key, Value, Comparer>::const_iterator ci = std::map<Key, Value, Comparer>::find(k);
if ( ci == this->end() )
return dummy;
@ -57,10 +58,34 @@ namespace dlib
Value& operator[](const Key& k)
{
return std::map<Key, Value>::operator [](k);
return std::map<Key, Value, Comparer>::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;
};

View File

@ -15,9 +15,10 @@ namespace dlib
template <
typename Key,
typename Value
typename Value,
typename Comparer = std::less<Key>
>
class constmap : public std::map<Key, Value>
class constmap : public std::map<Key, Value, Comparer>
{
/*!
WHAT THIS OBJECT REPRESENTS
@ -56,6 +57,10 @@ namespace dlib
};
typedef constmap<std::string, std::string> 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<std::string, std::string, less_case_insensitive> 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;
};
// -----------------------------------------------------------------------------------------