diff options
Diffstat (limited to 'ml/dlib/dlib/server')
-rw-r--r-- | ml/dlib/dlib/server/server_http.cpp | 409 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_http.h | 242 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_http_abstract.h | 390 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_iostream.cpp | 14 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_iostream.h | 155 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_iostream_abstract.h | 84 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_kernel.cpp | 595 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_kernel.h | 234 | ||||
-rw-r--r-- | ml/dlib/dlib/server/server_kernel_abstract.h | 310 |
9 files changed, 0 insertions, 2433 deletions
diff --git a/ml/dlib/dlib/server/server_http.cpp b/ml/dlib/dlib/server/server_http.cpp deleted file mode 100644 index 9e3051a43..000000000 --- a/ml/dlib/dlib/server/server_http.cpp +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright (C) 2003 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#ifndef DLIB_SERVER_HTTP_CPp_ -#define DLIB_SERVER_HTTP_CPp_ - -#include "server_http.h" - -namespace dlib -{ - -// ---------------------------------------------------------------------------------------- - - namespace http_impl - { - inline unsigned char to_hex( unsigned char x ) - { - return x + (x > 9 ? ('A'-10) : '0'); - } - - const std::string urlencode( const std::string& s ) - { - std::ostringstream os; - - for ( std::string::const_iterator ci = s.begin(); ci != s.end(); ++ci ) - { - if ( (*ci >= 'a' && *ci <= 'z') || - (*ci >= 'A' && *ci <= 'Z') || - (*ci >= '0' && *ci <= '9') ) - { // allowed - os << *ci; - } - else if ( *ci == ' ') - { - os << '+'; - } - else - { - os << '%' << to_hex(*ci >> 4) << to_hex(*ci % 16); - } - } - - return os.str(); - } - - inline unsigned char from_hex ( - unsigned char ch - ) - { - if (ch <= '9' && ch >= '0') - ch -= '0'; - else if (ch <= 'f' && ch >= 'a') - ch -= 'a' - 10; - else if (ch <= 'F' && ch >= 'A') - ch -= 'A' - 10; - else - ch = 0; - return ch; - } - - const std::string urldecode ( - const std::string& str - ) - { - using namespace std; - string result; - string::size_type i; - for (i = 0; i < str.size(); ++i) - { - if (str[i] == '+') - { - result += ' '; - } - else if (str[i] == '%' && str.size() > i+2) - { - const unsigned char ch1 = from_hex(str[i+1]); - const unsigned char ch2 = from_hex(str[i+2]); - const unsigned char ch = (ch1 << 4) | ch2; - result += ch; - i += 2; - } - else - { - result += str[i]; - } - } - return result; - } - - void parse_url( - std::string word, - key_value_map& queries - ) - /*! - Parses the query string of a URL. word should be the stuff that comes - after the ? in the query URL. - !*/ - { - std::string::size_type pos; - - for (pos = 0; pos < word.size(); ++pos) - { - if (word[pos] == '&') - word[pos] = ' '; - } - - std::istringstream sin(word); - sin >> word; - while (sin) - { - pos = word.find_first_of("="); - if (pos != std::string::npos) - { - std::string key = urldecode(word.substr(0,pos)); - std::string value = urldecode(word.substr(pos+1)); - - queries[key] = value; - } - sin >> word; - } - } - - void read_with_limit( - std::istream& in, - std::string& buffer, - int delim = '\n' - ) - { - using namespace std; - const size_t max = 64*1024; - buffer.clear(); - buffer.reserve(300); - - while (in.peek() != delim && in.peek() != '\n' && in.peek() != EOF && buffer.size() < max) - { - buffer += (char)in.get(); - } - - // if we quit the loop because the data is longer than expected or we hit EOF - if (in.peek() == EOF) - throw http_parse_error("HTTP field from client terminated incorrectly", 414); - if (buffer.size() == max) - throw http_parse_error("HTTP field from client is too long", 414); - - in.get(); - // eat any remaining whitespace - if (delim == ' ') - { - while (in.peek() == ' ') - in.get(); - } - } - } - -// ---------------------------------------------------------------------------------------- - - unsigned long parse_http_request ( - std::istream& in, - incoming_things& incoming, - unsigned long max_content_length - ) - { - using namespace std; - using namespace http_impl; - read_with_limit(in, incoming.request_type, ' '); - - // get the path - read_with_limit(in, incoming.path, ' '); - - // Get the HTTP/1.1 - Ignore for now... - read_with_limit(in, incoming.protocol); - - 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; - unsigned long content_length = 0; - - string line; - read_with_limit(in, line); - string first_part_of_header; - string::size_type position_of_double_point; - // now loop over all the incoming_headers - while (line != "\r") - { - position_of_double_point = line.find_first_of(':'); - if ( position_of_double_point != string::npos ) - { - first_part_of_header = dlib::trim(line.substr(0, position_of_double_point)); - - if ( !incoming_headers[first_part_of_header].empty() ) - incoming_headers[ first_part_of_header ] += " "; - incoming_headers[first_part_of_header] += dlib::trim(line.substr(position_of_double_point+1)); - - // look for Content-Type: - if (line.size() > 14 && strings_equal_ignore_case(line, "Content-Type:", 13)) - { - content_type = line.substr(14); - if (content_type[content_type.size()-1] == '\r') - content_type.erase(content_type.size()-1); - } - // look for Content-Length: - else if (line.size() > 16 && strings_equal_ignore_case(line, "Content-Length:", 15)) - { - istringstream sin(line.substr(16)); - sin >> content_length; - if (!sin) - { - throw http_parse_error("Invalid Content-Length of '" + line.substr(16) + "'", 411); - } - - if (content_length > max_content_length) - { - std::ostringstream sout; - sout << "Content-Length of post back is too large. It must be less than " << max_content_length; - throw http_parse_error(sout.str(), 413); - } - } - // look for any cookies - else if (line.size() > 6 && strings_equal_ignore_case(line, "Cookie:", 7)) - { - string::size_type pos = 6; - string key, value; - bool seen_key_start = false; - bool seen_equal_sign = false; - while (pos + 1 < line.size()) - { - ++pos; - // ignore whitespace between cookies - if (!seen_key_start && line[pos] == ' ') - continue; - - seen_key_start = true; - if (!seen_equal_sign) - { - if (line[pos] == '=') - { - seen_equal_sign = true; - } - else - { - key += line[pos]; - } - } - else - { - if (line[pos] == ';') - { - cookies[urldecode(key)] = urldecode(value); - seen_equal_sign = false; - seen_key_start = false; - key.clear(); - value.clear(); - } - else - { - value += line[pos]; - } - } - } - if (key.size() > 0) - { - cookies[urldecode(key)] = urldecode(value); - key.clear(); - value.clear(); - } - } - } // no ':' in it! - read_with_limit(in, line); - } // while (line != "\r") - - - // If there is data being posted back to us as a query string then - // pick out the queries using parse_url. - if ((strings_equal_ignore_case(incoming.request_type, "POST") || - strings_equal_ignore_case(incoming.request_type, "PUT")) && - strings_equal_ignore_case(left_substr(content_type,";"), "application/x-www-form-urlencoded")) - { - if (content_length > 0) - { - incoming.body.resize(content_length); - in.read(&incoming.body[0],content_length); - } - parse_url(incoming.body, incoming.queries); - } - - string::size_type pos = path.find_first_of("?"); - if (pos != string::npos) - { - parse_url(path.substr(pos+1), incoming.queries); - } - - - if (!in) - throw http_parse_error("Error parsing HTTP request", 500); - - return content_length; - } - -// ---------------------------------------------------------------------------------------- - - void read_body ( - std::istream& in, - incoming_things& incoming - ) - { - // if the body hasn't already been loaded and there is data to load - if (incoming.body.size() == 0 && - incoming.headers.count("Content-Length") != 0) - { - const unsigned long content_length = string_cast<unsigned long>(incoming.headers["Content-Length"]); - - incoming.body.resize(content_length); - if (content_length > 0) - { - in.read(&incoming.body[0],content_length); - } - } - } - -// ---------------------------------------------------------------------------------------- - - void write_http_response ( - std::ostream& out, - outgoing_things outgoing, - const std::string& result - ) - { - using namespace http_impl; - key_value_map& new_cookies = outgoing.cookies; - 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_ci::const_iterator ci = response_headers.begin(); ci != response_headers.end(); ++ci ) - { - if ( !has_content_type && strings_equal_ignore_case(ci->first , "content-type") ) - { - has_content_type = true; - } - else if ( !has_location && strings_equal_ignore_case(ci->first , "location") ) - { - has_location = true; - } - } - - if ( has_location ) - { - outgoing.http_return = 302; - } - - if ( !has_content_type ) - { - response_headers["Content-Type"] = "text/html"; - } - - response_headers["Content-Length"] = cast_to_string(result.size()); - - out << "HTTP/1.0 " << outgoing.http_return << " " << outgoing.http_return_status << "\r\n"; - - // Set any new headers - for(key_value_map_ci::const_iterator ci = response_headers.begin(); ci != response_headers.end(); ++ci ) - { - out << ci->first << ": " << ci->second << "\r\n"; - } - - // set any cookies - for(key_value_map::const_iterator ci = new_cookies.begin(); ci != new_cookies.end(); ++ci ) - { - out << "Set-Cookie: " << urlencode(ci->first) << '=' << urlencode(ci->second) << "\r\n"; - } - out << "\r\n" << result; - } - -// ---------------------------------------------------------------------------------------- - - void write_http_response ( - std::ostream& out, - const http_parse_error& e - ) - { - outgoing_things outgoing; - outgoing.http_return = e.http_error_code; - outgoing.http_return_status = e.what(); - write_http_response(out, outgoing, std::string("Error processing request: ") + e.what()); - } - -// ---------------------------------------------------------------------------------------- - - void write_http_response ( - std::ostream& out, - const std::exception& e - ) - { - outgoing_things outgoing; - outgoing.http_return = 500; - outgoing.http_return_status = e.what(); - write_http_response(out, outgoing, std::string("Error processing request: ") + e.what()); - } - -// ---------------------------------------------------------------------------------------- - - const logger server_http::dlog("dlib.server_http"); - -// ---------------------------------------------------------------------------------------- - -} - -#endif // DLIB_SERVER_HTTP_CPp_ - diff --git a/ml/dlib/dlib/server/server_http.h b/ml/dlib/dlib/server/server_http.h deleted file mode 100644 index 4e95f679f..000000000 --- a/ml/dlib/dlib/server/server_http.h +++ /dev/null @@ -1,242 +0,0 @@ -// 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_ - diff --git a/ml/dlib/dlib/server/server_http_abstract.h b/ml/dlib/dlib/server/server_http_abstract.h deleted file mode 100644 index 0bebfb61d..000000000 --- a/ml/dlib/dlib/server/server_http_abstract.h +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (C) 2006 Davis E. King (davis@dlib.net), Steven Van Ingelgem -// License: Boost Software License See LICENSE.txt for the full license. -#undef DLIB_SERVER_HTTp_ABSTRACT_ -#ifdef DLIB_SERVER_HTTp_ABSTRACT_ - -#include "server_iostream_abstract.h" -#include <iostream> -#include <string> -#include <map> - -namespace dlib -{ - -// ----------------------------------------------------------------------------------------- - - template < - typename Key, - typename Value, - typename Comparer = std::less<Key> - > - class constmap : public std::map<Key, Value, Comparer> - { - /*! - WHAT THIS OBJECT REPRESENTS - This is simply an extension to the std::map that allows you - to use the operator[] accessor with a constant map. - !*/ - public: - - const Value& operator[]( - const Key& k - ) const; - /*! - ensures - - if (this->find(k) != this->end()) then - - This map contains the given key - - return the value associated with the given key - - else - - return a default initialized Value object - !*/ - - Value& operator[]( - const Key& k - ) { return std::map<Key, Value>::operator [](k); } - /*! - ensures - - This function does the same thing as the normal std::map operator[] - function. - - if (this->find(k) != this->end()) then - - This map contains the given key - - return the value associated with the given key - - else - - Adds a new entry into the map that is associated with the - given key. The new entry will be default initialized and - this function returns a reference to it. - !*/ - }; - - 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; - -// ----------------------------------------------------------------------------------------- - - struct incoming_things - { - /*! - WHAT THIS OBJECT REPRESENTS - This object contains all the various bits of information that describe a - HTTP request that comes into a web server. - - For a detailed discussion of the fields of this object, see the - server_http::on_request() method defined later in this file. - !*/ - - incoming_things ( - const std::string& foreign_ip_, - const std::string& local_ip_, - unsigned short foreign_port_, - unsigned short local_port_ - ); - /*! - ensures - - #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 - { - /*! - WHAT THIS OBJECT REPRESENTS - This object contains all the various bits of information that describe a - HTTP response from a web server. - - For a detailed discussion of the fields of this object, see the - server_http::on_request() method defined later in this file. - !*/ - - outgoing_things( - ); - /*! - ensures - - #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; - }; - -// ----------------------------------------------------------------------------------------- - - class http_parse_error : public error - { - /*! - WHAT THIS OBJECT REPRESENTS - This is an exception thrown by the parse_http_request() routine if - there is a problem. - !*/ - }; - -// ----------------------------------------------------------------------------------------- - - unsigned long parse_http_request ( - std::istream& in, - incoming_things& incoming, - unsigned long max_content_length - ); - /*! - ensures - - Attempts to read a HTTP GET, POST, or PUT request from the given input - stream. - - Reads all headers of the request and puts them into #incoming. In particular, - this function populates the following fields: - - #incoming.path - - #incoming.request_type - - #incoming.content_type - - #incoming.protocol - - #incoming.queries - - #incoming.cookies - - #incoming.headers - - This function also populates the #incoming.body field if and only if the - Content-Type field is equal to "application/x-www-form-urlencoded". - Otherwise, the content is not read from the stream. - throws - - http_parse_error - This exception is thrown if the Content-Length coming from the web - browser is greater than max_content_length or if any other problem - is detected with the request. - !*/ - - void read_body ( - std::istream& in, - incoming_things& incoming - ); - /*! - requires - - parse_http_request(in,incoming,max_content_length) has already been called - and therefore populated the fields of incoming. - ensures - - if (incoming.body has already been populated with the content of an HTTP - request) then - - this function does nothing - - else - - reads the body of the HTTP request into #incoming.body. - !*/ - - void write_http_response ( - std::ostream& out, - outgoing_things outgoing, - const std::string& result - ); - /*! - ensures - - Writes an HTTP response, defined by the data in outgoing, to the given output - stream. - - The result variable is written out as the content of the response. - !*/ - - void write_http_response ( - std::ostream& out, - const http_parse_error& e - ); - /*! - ensures - - Writes an HTTP error response based on the information in the exception - object e. - !*/ - - void write_http_response ( - std::ostream& out, - const std::exception& e - ); - /*! - ensures - - Writes an HTTP error response based on the information in the exception - object e. - !*/ - -// ----------------------------------------------------------------------------------------- -// ----------------------------------------------------------------------------------------- - - class server_http : public server_iostream - { - - /*! - WHAT THIS EXTENSION DOES FOR server_iostream - This extension turns the server object into a simple HTTP server. It only - handles HTTP GET, PUT and POST requests and each incoming request triggers - the on_request() callback. - - COOKIE STRINGS - The strings returned in the cookies key_value_map should be of the following form: - key: cookie_name - value: cookie contents; expires=Fri, 31-Dec-2010 23:59:59 GMT; path=/; domain=.example.net - - You don't have to supply all the extra cookie arguments. So if you just want to - set a cookie that will expire when the client's browser is closed you can - just say something like incoming.cookies["cookie_name"] = "cookie contents"; - - HTTP HEADERS - The HTTP headers in the incoming.headers and outgoing.headers are the name/value pairs - of HTTP headers. For example, the HTTP header "Content-Type: text/html" would be - encoded such that outgoing.headers["Content-Type"] == "text/html". - - Also note that if you wish to change the content type of your response to the - client you may do so by setting the "Content-Type" header to whatever you like. - However, setting this field manually is not necessary as it will default to - "text/html" if you don't explicitly set it to something. - !*/ - - public: - - server_http ( - ); - /*! - ensures - - #get_max_content_length() == 10*1024*1024 - !*/ - - unsigned long get_max_content_length ( - ) const; - /*! - ensures - - returns the max allowable content length, in bytes, of the post back to - the web server. If a client attempts to send more data than this then an - error number 413 is returned back to the client and the request is not - processed by the web server. - !*/ - - void set_max_content_length ( - unsigned long max_length - ); - /*! - ensures - - #get_max_content_length() == max_length - !*/ - - private: - - virtual const std::string on_request ( - const incoming_things& incoming, - outgoing_things& outgoing - ) = 0; - /*! - requires - - on_request() is called when there is an HTTP GET or POST request to be serviced - - on_request() is run in its own thread - - is_running() == true - - the number of current on_request() functions running < get_max_connection() - - in incoming: - - incoming.path == the path being requested by this request - - incoming.request_type == the type of request, GET or POST - - incoming.content_type == the content type associated with this request - - incoming.protocol == The protocol being used by the web browser (e.g. HTTP/1.1) - - incoming.body == a string that contains the data that was posted back to the - web server by the client (e.g. The string has the length specified by the - Content-Length header). - - incoming.body.size() < get_max_content_length() - - incoming.queries == a map that contains all the key/value pairs in the query - string of this request. The key and value strings of the query string will - have been decoded back into their original form before being sent to this - function (i.e. '+' decoded back to ' ' and "%hh" into its corresponding - ascii value. So the URL-encoding is decoded automatically) - - incoming.cookies == The set of cookies that came from the client along with - this request. The cookies will have been decoded back to normal form - from the URL-encoding. - - incoming.headers == a map that contains all the incoming HTTP headers - from the client web browser. - - incoming.foreign_ip == the foreign ip address for this request - - incoming.foreign_port == the foreign port number for this request - - incoming.local_ip == the IP of the local interface this request is coming in on - - incoming.local_port == the local port number this request is coming in on - - in outgoing: - - outgoing.cookies.size() == 0 - - outgoing.headers.size() == 0 - - outgoing.http_return == 200 - - outgoing.http_return_status == "OK" - ensures - - This function returns the HTML page to be displayed as the response to this request. - - this function will not call clear() - - #outgoing.cookies == a set of new cookies to pass back to the client along - with the result of this request. (Note that URL-encoding is automatically applied - so you don't have to do it yourself) - - #outgoing.headers == a set of additional headers you wish to appear in the - HTTP response to this request. (This may be empty, the minimum needed headers - will be added automatically if you don't set them) - - outgoing.http_return and outgoing.http_return_status may be set to override the - default HTTP return code of 200 OK - throws - - throws only exceptions derived from std::exception. If an exception is thrown - then the error string from the exception is returned to the web browser. - !*/ - - - // ----------------------------------------------------------------------- - // Implementation Notes - // ----------------------------------------------------------------------- - - 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 - ) - /*! - on_connect() is the function defined by server_iostream which is overloaded by - server_http. In particular, the server_http's implementation is shown below. - In it you can see how the server_http parses the incoming http request, gets a - response by calling on_request(), and sends it back using the helper routines - defined at the top of this file. - - Therefore, if you want to modify the behavior of the HTTP server, for example, - to do some more complex data streaming requiring direct access to the - iostreams, then you can do so by defining your own on_connect() routine. In - particular, the default implementation shown below is a good starting point. - !*/ - { - 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) - { - write_http_response(out, e); - } - catch (std::exception& e) - { - write_http_response(out, e); - } - } - }; - -} - -#endif // DLIB_SERVER_HTTp_ABSTRACT_ - - - diff --git a/ml/dlib/dlib/server/server_iostream.cpp b/ml/dlib/dlib/server/server_iostream.cpp deleted file mode 100644 index 0fd49b67c..000000000 --- a/ml/dlib/dlib/server/server_iostream.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2003 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#ifndef DLIB_SERVER_IOSTREAM_CPp_ -#define DLIB_SERVER_IOSTREAM_CPp_ - -#include "server_iostream.h" - -namespace dlib -{ - const logger server_iostream::_dLog("dlib.server_iostream"); -} - -#endif // DLIB_SERVER_IOSTREAM_CPp_ - diff --git a/ml/dlib/dlib/server/server_iostream.h b/ml/dlib/dlib/server/server_iostream.h deleted file mode 100644 index eed349015..000000000 --- a/ml/dlib/dlib/server/server_iostream.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2006 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#ifndef DLIB_SERVER_IOSTREAm_1_ -#define DLIB_SERVER_IOSTREAm_1_ - -#include <iostream> -#include "server_iostream_abstract.h" -#include "../logger.h" -#include "../uintn.h" -#include "server_kernel.h" -#include "../sockstreambuf.h" -#include "../map.h" - - -namespace dlib -{ - - class server_iostream : public server - { - - /*! - INITIAL VALUE - - next_id == 0 - - con_map.size() == 0 - - CONVENTION - - next_id == the id of the next connection - - for all current connections - - con_map[id] == the connection object with the given id - - m == the mutex that protects the members of this object - !*/ - - typedef map<uint64,connection*,memory_manager<char>::kernel_2a>::kernel_1b id_map; - - public: - server_iostream( - ) : - next_id(0) - {} - - ~server_iostream( - ) - { - server::clear(); - } - - protected: - - void shutdown_connection ( - uint64 id - ) - { - auto_mutex M(m); - if (con_map.is_in_domain(id)) - { - con_map[id]->shutdown(); - } - } - - private: - - 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 connection_id - )=0; - - void on_connect ( - connection& con - ) - { - bool my_fault = true; - uint64 this_con_id=0; - try - { - sockstreambuf buf(&con); - std::istream in(&buf); - std::ostream out(&buf); - in.tie(&out); - - // add this connection to the con_map - { - auto_mutex M(m); - this_con_id = next_id; - connection* this_con = &con; - con_map.add(this_con_id,this_con); - this_con_id = next_id; - ++next_id; - } - - my_fault = false; - on_connect( - in, - out, - con.get_foreign_ip(), - con.get_local_ip(), - con.get_foreign_port(), - con.get_local_port(), - this_con_id - ); - - // remove this connection from the con_map - { - auto_mutex M(m); - connection* this_con; - uint64 junk; - con_map.remove(this_con_id,junk,this_con); - } - - } - catch (std::bad_alloc&) - { - // make sure we remove this connection from the con_map - { - auto_mutex M(m); - if (con_map.is_in_domain(this_con_id)) - { - connection* this_con; - uint64 junk; - con_map.remove(this_con_id,junk,this_con); - } - } - - _dLog << LERROR << "We ran out of memory in server_iostream::on_connect()"; - // if this is an escaped exception from on_connect then let it fly! - // Seriously though, this way it is obvious to the user that something bad happened - // since they probably won't have the dlib logger enabled. - if (!my_fault) - throw; - } - } - - uint64 next_id; - id_map con_map; - const static logger _dLog; - mutex m; - - - }; - - -} - -#ifdef NO_MAKEFILE -#include "server_iostream.cpp" -#endif - -#endif // DLIB_SERVER_IOSTREAm_1_ - - - diff --git a/ml/dlib/dlib/server/server_iostream_abstract.h b/ml/dlib/dlib/server/server_iostream_abstract.h deleted file mode 100644 index 86cd460bf..000000000 --- a/ml/dlib/dlib/server/server_iostream_abstract.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2006 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#undef DLIB_SERVER_IOSTREAm_ABSTRACT_ -#ifdef DLIB_SERVER_IOSTREAm_ABSTRACT_ - - -#include "server_kernel_abstract.h" -#include <iostream> -#include <string> -#include "../uintn.h" - -namespace dlib -{ - - class server_iostream : public server - { - - /*! - WHAT THIS EXTENSION DOES FOR server - This extension redefines the on_connect() function so that - instead of giving you a connection object you get an istream - and ostream object. - - THREAD SAFETY - Note that in on_connect() the input stream in is tied to the output stream - out. This means that when you read from in it will modify out and thus - it is not safe to touch in and out concurrently from different threads - unless you untie them (which you do by saying in.tie(0);) - !*/ - - protected: - - void shutdown_connection ( - uint64 id - ); - /*! - ensures - - if (there is a connection currently being serviced with the given id) then - - the specified connection is shutdown. (i.e. connection::shutdown() is - called on it so the iostreams operating on it will return EOF) - !*/ - - private: - - 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 connection_id - )=0; - /*! - requires - - on_connect() is called when there is a new TCP connection that needs - to be serviced. - - in == the input stream that reads data from the new connection - - out == the output stream that writes data to the new connection - - in.tie() == &out (i.e. when you read from in it automatically calls out.flush()) - - foreign_ip == the foreign ip address for this connection - - foreign_port == the foreign port number for this connection - - local_ip == the IP of the local interface this connection is using - - local_port == the local port number for this connection - - on_connect() is run in its own thread - - is_running() == true - - the number of current connections < get_max_connection() - - connection_id == an integer that uniquely identifies this connection. - It can be used by shutdown_connection() to terminate this connection. - ensures - - when the iostreams hit EOF on_connect() will terminate. - (because this is how clear() signals you the server is shutting down) - - this function will not call clear() - throws - - does not throw any exceptions - !*/ - - }; - -} - -#endif // DLIB_SERVER_IOSTREAm_ABSTRACT_ - - diff --git a/ml/dlib/dlib/server/server_kernel.cpp b/ml/dlib/dlib/server/server_kernel.cpp deleted file mode 100644 index 9e8130e78..000000000 --- a/ml/dlib/dlib/server/server_kernel.cpp +++ /dev/null @@ -1,595 +0,0 @@ -// Copyright (C) 2003 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#ifndef DLIB_SERVER_KERNEL_CPp_ -#define DLIB_SERVER_KERNEL_CPp_ - -#include "server_kernel.h" -#include "../string.h" - -namespace dlib -{ - -// ---------------------------------------------------------------------------------------- - - server:: - server ( - ) : - listening_port(0), - running(false), - shutting_down(false), - running_signaler(running_mutex), - thread_count(0), - thread_count_signaler(thread_count_mutex), - max_connections(1000), - thread_count_zero(thread_count_mutex), - graceful_close_timeout(500) - { - } - -// ---------------------------------------------------------------------------------------- - - server:: - ~server ( - ) - { - clear(); - } - -// ---------------------------------------------------------------------------------------- - - unsigned long server:: - get_graceful_close_timeout ( - ) const - { - auto_mutex lock(max_connections_mutex); - return graceful_close_timeout; - } - -// ---------------------------------------------------------------------------------------- - - void server:: - set_graceful_close_timeout ( - unsigned long timeout - ) - { - auto_mutex lock(max_connections_mutex); - graceful_close_timeout = timeout; - } - -// ---------------------------------------------------------------------------------------- - - - int server:: - get_max_connections ( - ) const - { - max_connections_mutex.lock(); - int temp = max_connections; - max_connections_mutex.unlock(); - return temp; - } - -// ---------------------------------------------------------------------------------------- - - void server:: - set_max_connections ( - int max - ) - { - // make sure requires clause is not broken - DLIB_CASSERT( - max >= 0 , - "\tvoid server::set_max_connections" - << "\n\tmax == " << max - << "\n\tthis: " << this - ); - - max_connections_mutex.lock(); - max_connections = max; - max_connections_mutex.unlock(); - } - -// ---------------------------------------------------------------------------------------- - - void server:: - clear ( - ) - { - // signal that we are shutting down - shutting_down_mutex.lock(); - shutting_down = true; - shutting_down_mutex.unlock(); - - - - max_connections_mutex.lock(); - listening_port_mutex.lock(); - listening_ip_mutex.lock(); - listening_ip = ""; - listening_port = 0; - max_connections = 1000; - graceful_close_timeout = 500; - listening_port_mutex.unlock(); - listening_ip_mutex.unlock(); - max_connections_mutex.unlock(); - - - // tell all the connections to shut down - cons_mutex.lock(); - connection* temp; - while (cons.size() > 0) - { - cons.remove_any(temp); - temp->shutdown(); - } - cons_mutex.unlock(); - - - // wait for all the connections to shut down - thread_count_mutex.lock(); - while (thread_count > 0) - { - thread_count_zero.wait(); - } - thread_count_mutex.unlock(); - - - - - // wait for the listener to close - running_mutex.lock(); - while (running == true) - { - running_signaler.wait(); - } - running_mutex.unlock(); - - - - // signal that the shutdown is complete - shutting_down_mutex.lock(); - shutting_down = false; - shutting_down_mutex.unlock(); - } - -// ---------------------------------------------------------------------------------------- - - void server:: - start_async_helper ( - ) - { - try - { - start_accepting_connections(); - } - catch (std::exception& e) - { - sdlog << LERROR << e.what(); - } - } - -// ---------------------------------------------------------------------------------------- - - void server:: - start_async ( - ) - { - auto_mutex lock(running_mutex); - if (running) - return; - - // Any exceptions likely to be thrown by the server are going to be - // thrown when trying to bind the port. So calling this here rather - // than in the thread we are about to make will cause start_async() - // to report errors back to the user in a very straight forward way. - open_listening_socket(); - - async_start_thread.reset(new thread_function(make_mfp(*this,&server::start_async_helper))); - } - -// ---------------------------------------------------------------------------------------- - - void server:: - open_listening_socket ( - ) - { - if (!sock) - { - int status = create_listener(sock,listening_port,listening_ip); - const int port_used = listening_port; - - // if there was an error then clear this object - if (status < 0) - { - max_connections_mutex.lock(); - listening_port_mutex.lock(); - listening_ip_mutex.lock(); - listening_ip = ""; - listening_port = 0; - max_connections = 1000; - graceful_close_timeout = 500; - listening_port_mutex.unlock(); - listening_ip_mutex.unlock(); - max_connections_mutex.unlock(); - } - - - - // throw an exception for the error - if (status == PORTINUSE) - { - throw dlib::socket_error( - EPORT_IN_USE, - "error occurred in server::start()\nport " + cast_to_string(port_used) + " already in use" - ); - } - else if (status == OTHER_ERROR) - { - throw dlib::socket_error( - "error occurred in server::start()\nunable to create listener" - ); - } - } - - running_mutex.lock(); - running = true; - running_mutex.unlock(); - } - -// ---------------------------------------------------------------------------------------- - - void server:: - start ( - ) - { - // make sure requires clause is not broken - DLIB_CASSERT( - this->is_running() == false, - "\tvoid server::start" - << "\n\tis_running() == " << this->is_running() - << "\n\tthis: " << this - ); - - start_accepting_connections(); - - } - -// ---------------------------------------------------------------------------------------- - - void server:: - start_accepting_connections ( - ) - { - open_listening_socket(); - - // determine the listening port - bool port_assigned = false; - listening_port_mutex.lock(); - if (listening_port == 0) - { - port_assigned = true; - listening_port = sock->get_listening_port(); - } - listening_port_mutex.unlock(); - if (port_assigned) - on_listening_port_assigned(); - - - - int status = 0; - - connection* client; - bool exit = false; - while ( true ) - { - - - // accept the next connection - status = sock->accept(client,1000); - - - // if there was an error then quit the loop - if (status == OTHER_ERROR) - { - break; - } - - shutting_down_mutex.lock(); - // if we are shutting down then signal that we should quit the loop - exit = shutting_down; - shutting_down_mutex.unlock(); - - - // if we should be shutting down - if (exit) - { - // if a connection was opened then close it - if (status == 0) - delete client; - break; - } - - - - // if the accept timed out - if (status == TIMEOUT) - { - continue; - } - - - - - - // add this new connection to cons - cons_mutex.lock(); - connection* client_temp = client; - try{cons.add(client_temp);} - catch(...) - { - sock.reset(); - delete client; - cons_mutex.unlock(); - - // signal that we are not running start() anymore - running_mutex.lock(); - running = false; - running_signaler.broadcast(); - running_mutex.unlock(); - - - clear(); - throw; - } - cons_mutex.unlock(); - - - // make a param structure - param* temp = 0; - try{ - temp = new param ( - *this, - *client, - get_graceful_close_timeout() - ); - } catch (...) - { - sock.reset(); - delete client; - running_mutex.lock(); - running = false; - running_signaler.broadcast(); - running_mutex.unlock(); - clear(); - throw; - } - - - // if create_new_thread failed - if (!create_new_thread(service_connection,temp)) - { - delete temp; - // close the listening socket - sock.reset(); - - // close the new connection and remove it from cons - cons_mutex.lock(); - connection* ctemp; - if (cons.is_member(client)) - { - cons.remove(client,ctemp); - } - delete client; - cons_mutex.unlock(); - - - // signal that the listener has closed - running_mutex.lock(); - running = false; - running_signaler.broadcast(); - running_mutex.unlock(); - - // make sure the object is cleared - clear(); - - // throw the exception - throw dlib::thread_error( - ECREATE_THREAD, - "error occurred in server::start()\nunable to start thread" - ); - } - // if we made the new thread then update thread_count - else - { - // increment the thread count - thread_count_mutex.lock(); - ++thread_count; - if (thread_count == 0) - thread_count_zero.broadcast(); - thread_count_mutex.unlock(); - } - - - - - // check if we have hit the maximum allowed number of connections - max_connections_mutex.lock(); - // if max_connections is zero or the loop is ending then skip this - if (max_connections != 0) - { - // wait for thread_count to be less than max_connections - thread_count_mutex.lock(); - while (thread_count >= max_connections) - { - max_connections_mutex.unlock(); - thread_count_signaler.wait(); - max_connections_mutex.lock(); - - // if we are shutting down the quit the loop - shutting_down_mutex.lock(); - exit = shutting_down; - shutting_down_mutex.unlock(); - if (exit) - break; - } - thread_count_mutex.unlock(); - } - max_connections_mutex.unlock(); - - if (exit) - { - break; - } - } //while ( true ) - - - // close the socket - sock.reset(); - - // signal that the listener has closed - running_mutex.lock(); - running = false; - running_signaler.broadcast(); - running_mutex.unlock(); - - // if there was an error with accept then throw an exception - if (status == OTHER_ERROR) - { - // make sure the object is cleared - clear(); - - // throw the exception - throw dlib::socket_error( - "error occurred in server::start()\nlistening socket returned error" - ); - } - } - -// ---------------------------------------------------------------------------------------- - - bool server:: - is_running ( - ) const - { - running_mutex.lock(); - bool temp = running; - running_mutex.unlock(); - return temp; - } - -// ---------------------------------------------------------------------------------------- - - const std::string server:: - get_listening_ip ( - ) const - { - listening_ip_mutex.lock(); - std::string ip(listening_ip); - listening_ip_mutex.unlock(); - return ip; - } - -// ---------------------------------------------------------------------------------------- - - int server:: - get_listening_port ( - ) const - { - listening_port_mutex.lock(); - int port = listening_port; - listening_port_mutex.unlock(); - return port; - } - -// ---------------------------------------------------------------------------------------- - - void server:: - set_listening_port ( - int port - ) - { - // make sure requires clause is not broken - DLIB_CASSERT( - ( port >= 0 && - this->is_running() == false ), - "\tvoid server::set_listening_port" - << "\n\tport == " << port - << "\n\tis_running() == " << this->is_running() - << "\n\tthis: " << this - ); - - listening_port_mutex.lock(); - listening_port = port; - listening_port_mutex.unlock(); - } - -// ---------------------------------------------------------------------------------------- - - void server:: - set_listening_ip ( - const std::string& ip - ) - { - // make sure requires clause is not broken - DLIB_CASSERT( - ( ( is_ip_address(ip) || ip == "" ) && - this->is_running() == false ), - "\tvoid server::set_listening_ip" - << "\n\tip == " << ip - << "\n\tis_running() == " << this->is_running() - << "\n\tthis: " << this - ); - - listening_ip_mutex.lock(); - listening_ip = ip; - listening_ip_mutex.unlock(); - } - -// ---------------------------------------------------------------------------------------- -// ---------------------------------------------------------------------------------------- - // static member function definitions -// ---------------------------------------------------------------------------------------- -// ---------------------------------------------------------------------------------------- - - const logger server::sdlog("dlib.server"); - - void server:: - service_connection( - void* item - ) - { - param& p = *static_cast<param*>(item); - - - p.the_server.on_connect(p.new_connection); - - - // remove this connection from cons and close it - p.the_server.cons_mutex.lock(); - connection* temp; - if (p.the_server.cons.is_member(&p.new_connection)) - p.the_server.cons.remove(&p.new_connection,temp); - p.the_server.cons_mutex.unlock(); - - try{ close_gracefully(&p.new_connection, p.graceful_close_timeout); } - catch (...) { sdlog << LERROR << "close_gracefully() threw"; } - - // decrement the thread count and signal if it is now zero - p.the_server.thread_count_mutex.lock(); - --p.the_server.thread_count; - p.the_server.thread_count_signaler.broadcast(); - if (p.the_server.thread_count == 0) - p.the_server.thread_count_zero.broadcast(); - p.the_server.thread_count_mutex.unlock(); - - delete &p; - - - } - -// ---------------------------------------------------------------------------------------- - -} - -#endif // DLIB_SERVER_KERNEL_CPp_ - diff --git a/ml/dlib/dlib/server/server_kernel.h b/ml/dlib/dlib/server/server_kernel.h deleted file mode 100644 index 4232ff343..000000000 --- a/ml/dlib/dlib/server/server_kernel.h +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (C) 2003 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#ifndef DLIB_SERVER_KERNEL_1_ -#define DLIB_SERVER_KERNEL_1_ - -#include "server_kernel_abstract.h" - -#include <memory> -#include <string> - -#include "../threads.h" -#include "../sockets.h" -#include "../algs.h" -#include "../set.h" -#include "../logger.h" - - -namespace dlib -{ - - // These forward declarations are here so we can use them in the typedefs in the server - // class. The reason for this is for backwards compatibility with previous versions of - // dlib. - class server_http; - class server_iostream; - - class server - { - - - /*! - INITIAL VALUE - listening_port == 0 - listening_ip == "" - running == false - shutting_down == false - cons.size() == 0 - listening_port_mutex == a mutex - listening_ip_mutex == a mutex - running_mutex == a mutex - running_signaler == a signaler associated with running_mutex - shutting_down_mutex == a mutex - cons_mutex == a mutex - thread_count == 0 - thread_count_mutex == a mutex - thread_count_signaler == a signaler associated with thread_count_mutex - thread_count_zero == a signaler associated with thread_count_mutex - max_connections == 1000 - max_connections_mutex == a mutex for max_connections and graceful_close_timeout - graceful_close_timeout == 500 - - CONVENTION - listening_port == get_listening_port() - listening_ip == get_listening_ip() - running == is_running() - shutting_down == true while clear() is running. this - bool is used to tell the thread blocked on - accept that it should terminate - cons == a set containing all open connections - listening_port_mutex == a mutex for listening_port - listening_ip_mutex == a mutex for listening_ip - running_mutex == a mutex for running - running_signaler == a signaler for running and - is associated with running_mutex. it is - used to signal when running is false - shutting_down_mutex == a mutex for shutting_down - cons_mutex == a mutex for cons - thread_count == the number of threads currently running - thread_count_mutex == a mutex for thread_count - thread_count_signaler == a signaler for thread_count and - is associated with thread_count_mutex. it - is used to signal when thread_count is - decremented - thread_count_zero == a signaler for thread_count and - is associated with thread_count_mutex. it - is used to signal when thread_count becomes - zero - max_connections == get_max_connections() - max_connections_mutex == a mutex for max_connections - !*/ - - - typedef set<connection*>::kernel_1a set_of_connections; - - // this structure is used to pass parameters to new threads - struct param - { - param ( - server& server_, - connection& new_connection_, - unsigned long graceful_close_timeout_ - ) : - the_server(server_), - new_connection(new_connection_), - graceful_close_timeout(graceful_close_timeout_) - {} - - server& the_server; - connection& new_connection; - unsigned long graceful_close_timeout; - }; - - - - public: - - // These typedefs are here for backward compatibility with previous versions of dlib - typedef server kernel_1a; - typedef server kernel_1a_c; - typedef server_iostream iostream_1a; - typedef server_iostream iostream_1a_c; - typedef server_http http_1a; - typedef server_http http_1a_c; - - server( - ); - - virtual ~server( - ); - - void clear( - ); - - void start ( - ); - - bool is_running ( - ) const; - - const std::string get_listening_ip ( - ) const; - - int get_listening_port ( - ) const; - - void set_listening_port ( - int port - ); - - void set_listening_ip ( - const std::string& ip - ); - - void set_max_connections ( - int max - ); - - int get_max_connections ( - ) const; - - void start_async ( - ); - - void set_graceful_close_timeout ( - unsigned long timeout - ); - - unsigned long get_graceful_close_timeout ( - ) const; - - private: - - void start_async_helper ( - ); - - void start_accepting_connections ( - ); - - void open_listening_socket ( - ); - - virtual void on_connect ( - connection& new_connection - )=0; - - virtual void on_listening_port_assigned ( - ) {} - - const static logger sdlog; - - static void service_connection( - void* item - ); - /*! - requires - item is a pointer to a param struct - ensures - services the new connection - will take care of closing the connection and - adding the connection to cons when it first starts and - remove the connection from cons and signal that it has - done so when it ends - !*/ - - // data members - int listening_port; - std::string listening_ip; - bool running; - bool shutting_down; - set_of_connections cons; - mutex listening_port_mutex; - mutex listening_ip_mutex; - rmutex running_mutex; - rsignaler running_signaler; - mutex shutting_down_mutex; - mutex cons_mutex; - int thread_count; - mutex thread_count_mutex; - signaler thread_count_signaler; - int max_connections; - mutex max_connections_mutex; - signaler thread_count_zero; - std::unique_ptr<thread_function> async_start_thread; - std::unique_ptr<listener> sock; - unsigned long graceful_close_timeout; - - - // restricted functions - server(server&); - server& operator= ( - server& - ); - }; - -// ---------------------------------------------------------------------------------------- - -} - -#ifdef NO_MAKEFILE -#include "server_kernel.cpp" -#endif - -#endif // DLIB_SERVER_KERNEL_1_ - diff --git a/ml/dlib/dlib/server/server_kernel_abstract.h b/ml/dlib/dlib/server/server_kernel_abstract.h deleted file mode 100644 index f7860d26c..000000000 --- a/ml/dlib/dlib/server/server_kernel_abstract.h +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (C) 2003 Davis E. King (davis@dlib.net) -// License: Boost Software License See LICENSE.txt for the full license. -#undef DLIB_SERVER_KERNEL_ABSTRACT_ -#ifdef DLIB_SERVER_KERNEL_ABSTRACT_ - -#include "../threads/threads_kernel_abstract.h" -#include "../sockets/sockets_kernel_abstract.h" -#include <string> - - -namespace dlib -{ - class server - { - - /*! - INITIAL VALUE - get_listening_ip() == "" - get_listening_port() == 0 - is_running() == false - get_max_connections() == 1000 - get_graceful_close_timeout() == 500 - - - CALLBACK FUNCTIONS - on_connect(): - To use this object inherit from it and define the pure virtual function - on_connect. Inside this function is where you will handle each new - connection. Note that the connection object passed to on_connect() should - NOT be closed, just let the function end and it will be gracefully closed - for you. Also note that each call to on_connect() is run in its own - thread. Also note that on_connect() should NOT throw any exceptions, - all exceptions must be dealt with inside on_connect() and cannot be - allowed to leave. - - on_listening_port_assigned(): - This function is called to let the client know that the operating - system has assigned a port number to the listening port. This - happens if a port number of zero was given. Note that this - function does not need to be defined. If you don't care then - don't define it and it will do nothing. Note also that this function - is NOT called in its own thread. Thus, making it block might hang the - server. - - WHAT THIS OBJECT REPRESENTS - This object represents a server that listens on a port and spawns new - threads to handle each new connection. - - Note that the clear() function does not return until all calls to - on_connect() have finished and the start() function has been shutdown. - Also note that when clear() is called all open connection objects - will be shutdown(). - - A note about get_max_connections(): when the maximum number of connections - has been reached accept() will simply not be called until the number of - open connections drops below get_max_connections(). This means connections - will just wait to be serviced, rather than being outright refused. - - THREAD SAFETY - All member functions are thread-safe. - !*/ - - public: - - server( - ); - /*! - ensures - - #*this is properly initialized - throws - - std::bad_alloc - - dlib::thread_error - !*/ - - virtual ~server( - ); - /*! - requires - - is not called from any of server's callbacks - ensures - - all resources associated with *this have been released - !*/ - - void clear( - ); - /*! - requires - - is not called from any of server's callbacks - ensures - - #*this has its initial value - - all open connection objects passed to on_connect() are shutdown() - - blocks until all calls to on_connect() have finished - - blocks until the start() function has released all its resources - throws - - std::bad_alloc - if this exception is thrown then the server object is unusable - until clear() is called and succeeds - !*/ - - void start ( - ); - /*! - requires - - is_running() == false - ensures - - starts listening on the port and ip specified by get_listening_ip() - and #get_listening_port() for new connections. - - if (get_listening_port() == 0) then - - a port to listen on will be automatically selected - - #get_listening_port() == the selected port being used - - if (get_listening_ip() == "" ) then - - all local IPs will be listened on - - blocks until clear() is called or an error occurs - throws - - dlib::socket_error - start() will throw this exception if there is some problem binding - ports and/or starting the server or if there is a problem - accepting new connections while it's running. - If this happens then - - All open connection objects passed to on_connect() are shutdown() - and the exception will not be thrown until all on_connect() calls - have terminated. - - The server will be cleared and returned to its initial value. - - dlib::thread_error - start() will throw this exception if there is a problem - creating new threads. Or it may throw this exception if there - is a problem creating threading objects. - If this happens then - - All open connection objects passed to on_connect() are shutdown() - and the exception will not be thrown until all on_connect() calls - have terminated. - - The server will be cleared and returned to its initial value. - - std::bad_alloc - start() may throw this exception and if it does then the object - will be unusable until clear() is called and succeeds - !*/ - - void start_async ( - ); - /*! - ensures - - starts listening on the port and ip specified by get_listening_ip() - and #get_listening_port() for new connections. - - if (get_listening_port() == 0) then - - a port to listen on will be automatically selected - - #get_listening_port() == the selected port being used - - if (get_listening_ip() == "" ) then - - all local IPs will be listened on - - does NOT block. That is, this function will return right away and - the server will run on a background thread until clear() or this - object's destructor is called (or until some kind of fatal error - occurs). - - if an error occurs in the background thread while the server is - running then it will shut itself down, set is_running() to false, and - log the error to a dlib::logger object. - - calling start_async() on a running server has no effect. - throws - - dlib::socket_error - start_async() will throw this exception if there is some problem binding - ports and/or starting the server. - If this happens then - - The server will be cleared and returned to its initial value. - !*/ - - bool is_running ( - ) const; - /*! - ensures - - returns true if start() is running - - returns false if start() is not running or has released all - its resources and is about to terminate - throws - - std::bad_alloc - !*/ - - int get_max_connections ( - ) const; - /*! - ensures - - returns the maximum number of connections the server will accept - at a time. - - returns 0 if the server will accept any number of connections - throws - - std::bad_alloc - !*/ - - - const std::string get_listening_ip ( - ) const; - /*! - ensures - - returns the local ip to listen for new connections on - - returns "" if ALL local ips are to be listened on - throws - - std::bad_alloc - !*/ - - int get_listening_port ( - ) const; - /*! - ensures - - returns the local port number to listen for new connections on - - returns 0 if the local port number has not yet been set - throws - - std::bad_alloc - !*/ - - void set_listening_port ( - int port - ); - /*! - requires - - port >= 0 - - is_running() == false - ensures - - #get_listening_port() == port - throws - - std::bad_alloc - !*/ - - void set_listening_ip ( - const std::string& ip - ); - /*! - requires - - is_ip_address(ip) == true or ip == "" - - is_running() == false - ensures - - #get_listening_ip() == ip - throws - - std::bad_alloc - !*/ - - void set_max_connections ( - int max - ); - /*! - requires - - max >= 0 - ensures - - #get_max_connections() == max - throws - - std::bad_alloc - !*/ - - void set_graceful_close_timeout ( - unsigned long timeout - ); - /*! - ensures - - #get_graceful_close_timeout() == timeout - !*/ - - unsigned long get_graceful_close_timeout ( - ) const; - /*! - ensures - - When on_connect() terminates, it will close the connection using - close_gracefully(). This is done so that any data still in the - operating system's output buffers gets a chance to be properly - transmitted to the remote host. Part of this involves waiting for - the remote host to close their end of the connection. Therefore, - get_graceful_close_timeout() returns the timeout, in milliseconds, - that we wait for the remote host to close their end of the - connection. This is the timeout value given to close_gracefully(). - !*/ - - private: - - virtual void on_connect ( - connection& new_connection - )=0; - /*! - requires - - on_connect() is run in its own thread - - is_running() == true - - the number of current connections < get_max_connection() - - new_connection == the new connection to the server which is - to be serviced by this call to on_connect() - ensures - - when new_connection is shutdown() on_connect() will terminate - - this function will not call clear() - throws - - does not throw any exceptions - !*/ - - // do nothing by default - virtual void on_listening_port_assigned ( - ) {} - /*! - requires - - is called if a listening port of zero was specified and - an actual port number has just been assigned to the server - ensures - - this function will not block - - this function will not call clear() - throws - - does not throw any exceptions - !*/ - - - // restricted functions - server(server&); // copy constructor - server& operator=(server&); // assignment operator - }; - -} - -#endif // DLIB_SERVER_KERNEL_ABSTRACT_ - |