summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/server/server_http.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/server/server_http.cpp')
-rw-r--r--ml/dlib/dlib/server/server_http.cpp409
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_
-