sustaining_gazes/lib/3rdParty/dlib/include/dlib/server/server_http.h
2016-04-28 15:40:36 -04:00

242 lines
6.3 KiB
C++

// Copyright (C) 2006 Davis E. King (davis@dlib.net), Steven Van Ingelgem
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_SERVER_HTTp_1_
#define DLIB_SERVER_HTTp_1_
#include "server_http_abstract.h"
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
#include <map>
#include "../logger.h"
#include "../string.h"
#include "server_iostream.h"
#ifdef __INTEL_COMPILER
// ignore the bogus warning about hiding on_connect()
#pragma warning (disable: 1125)
#endif
#if _MSC_VER
# pragma warning( disable: 4503 )
#endif // _MSC_VER
namespace dlib
{
// ----------------------------------------------------------------------------------------
class http_parse_error : public error
{
public:
http_parse_error(const std::string& str, int http_error_code_):
error(str),http_error_code(http_error_code_) {}
const int http_error_code;
};
// ----------------------------------------------------------------------------------------
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, Comparer>::const_iterator ci = std::map<Key, Value, Comparer>::find(k);
if ( ci == this->end() )
return dummy;
else
return ci->second;
}
Value& operator[](const Key& 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
{
unsigned 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
{
incoming_things (
const std::string& foreign_ip_,
const std::string& local_ip_,
unsigned short foreign_port_,
unsigned short local_port_
):
foreign_ip(foreign_ip_),
foreign_port(foreign_port_),
local_ip(local_ip_),
local_port(local_port_)
{}
std::string path;
std::string request_type;
std::string content_type;
std::string protocol;
std::string body;
key_value_map queries;
key_value_map cookies;
key_value_map_ci headers;
std::string foreign_ip;
unsigned short foreign_port;
std::string local_ip;
unsigned short local_port;
};
struct outgoing_things
{
outgoing_things() : http_return(200), http_return_status("OK") { }
key_value_map cookies;
key_value_map_ci headers;
unsigned short http_return;
std::string http_return_status;
};
// ----------------------------------------------------------------------------------------
unsigned long parse_http_request (
std::istream& in,
incoming_things& incoming,
unsigned long max_content_length
);
void read_body (
std::istream& in,
incoming_things& incoming
);
void write_http_response (
std::ostream& out,
outgoing_things outgoing,
const std::string& result
);
void write_http_response (
std::ostream& out,
const http_parse_error& e
);
void write_http_response (
std::ostream& out,
const std::exception& e
);
// ----------------------------------------------------------------------------------------
class server_http : public server_iostream
{
public:
server_http()
{
max_content_length = 10*1024*1024; // 10MB
}
unsigned long get_max_content_length (
) const
{
auto_mutex lock(http_class_mutex);
return max_content_length;
}
void set_max_content_length (
unsigned long max_length
)
{
auto_mutex lock(http_class_mutex);
max_content_length = max_length;
}
private:
virtual const std::string on_request (
const incoming_things& incoming,
outgoing_things& outgoing
) = 0;
virtual void on_connect (
std::istream& in,
std::ostream& out,
const std::string& foreign_ip,
const std::string& local_ip,
unsigned short foreign_port,
unsigned short local_port,
uint64
)
{
try
{
incoming_things incoming(foreign_ip, local_ip, foreign_port, local_port);
outgoing_things outgoing;
parse_http_request(in, incoming, get_max_content_length());
read_body(in, incoming);
const std::string& result = on_request(incoming, outgoing);
write_http_response(out, outgoing, result);
}
catch (http_parse_error& e)
{
dlog << LERROR << "Error processing request from: " << foreign_ip << " - " << e.what();
write_http_response(out, e);
}
catch (std::exception& e)
{
dlog << LERROR << "Error processing request from: " << foreign_ip << " - " << e.what();
write_http_response(out, e);
}
}
mutex http_class_mutex;
unsigned long max_content_length;
const static logger dlog;
};
// ----------------------------------------------------------------------------------------
}
#ifdef NO_MAKEFILE
#include "server_http.cpp"
#endif
#endif // DLIB_SERVER_HTTp_1_