diff options
Diffstat (limited to 'ml/dlib/dlib/server/server_http.cpp')
-rw-r--r-- | ml/dlib/dlib/server/server_http.cpp | 409 |
1 files changed, 0 insertions, 409 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_ - |