<commit_before>
/*
 * Rosetta web server, copyright(c) 2016, <NAME>, <EMAIL>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "common/include/date.hpp"
#include "server/include/server.hpp"
#include "server/include/connection/request.hpp"
#include "server/include/connection/connection.hpp"
#include "server/include/exceptions/request_exception.hpp"

// Including all HTTP handlers we support.
#include "server/include/connection/handlers/head_handler.hpp"
#include "server/include/connection/handlers/error_handler.hpp"
#include "server/include/connection/handlers/trace_handler.hpp"
#include "server/include/connection/handlers/request_handler.hpp"
#include "server/include/connection/handlers/redirect_handler.hpp"
#include "server/include/connection/handlers/static_file_handler.hpp"

namespace rosetta {
namespace server {

using std::string;
using namespace boost::asio;
using namespace rosetta::common;


request_handler_ptr request_handler::create (class connection * connection, class request * request, int status_code)
{
  // Checking if we can accept User-Agent according whitelist and blacklist definitions.
  if (!in_whitelist (connection, request) || in_blacklist (connection, request)) {

    // User-Agent not accepted!
    return request_handler_ptr (new error_handler (connection, request, 403));
  }

  // Checking request type, and other parameters, deciding which type of request handler we should create.
  if (status_code >= 400) {

    // Some sort of error.
    return request_handler_ptr (new error_handler (connection, request, status_code));

  } else if (should_upgrade_insecure_requests (connection, request)) {

    // Both configuration, and client, prefers secure requests, and current connection is not secure, hence we upgrade.
    return upgrade_insecure_request (connection, request);

  } else if (request->envelope().type() == "TRACE") {

    // Returning a TRACE handler.
    return create_trace_handler (connection, request);

  } else if (request->envelope().type() == "HEAD") {

    // Returning a HEAD handler.
    return create_head_handler (connection, request);

  } else if (request->envelope().type() == "GET") {

    // Returning a GET handler.
    return create_get_handler (connection, request);

  } else {

    // Unsupported method.
    return request_handler_ptr (new error_handler (connection, request, 405));
  }
}


bool request_handler::should_upgrade_insecure_requests (const class connection * connection, const class request * request)
{
  // Retrieving configuration settings for whether or not we should upgrade insecure requests.
  const bool upgrade = connection->server()->configuration().get <bool> ("upgrade-insecure-requests", false);

  // We only upgrade if configuration settings says so, and the current connection is insecure.
  return upgrade && !connection->is_secure();
}
<commit_msg>More robust logic for upgrading of insecure requests.<commit_after>
/*
 * Rosetta web server, copyright(c) 2016, <NAME>, <EMAIL>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "common/include/date.hpp"
#include "server/include/server.hpp"
#include "server/include/connection/request.hpp"
#include "server/include/connection/connection.hpp"
#include "server/include/exceptions/request_exception.hpp"

// Including all HTTP handlers we support.
#include "server/include/connection/handlers/head_handler.hpp"
#include "server/include/connection/handlers/error_handler.hpp"
#include "server/include/connection/handlers/trace_handler.hpp"
#include "server/include/connection/handlers/request_handler.hpp"
#include "server/include/connection/handlers/redirect_handler.hpp"
#include "server/include/connection/handlers/static_file_handler.hpp"

namespace rosetta {
namespace server {

using std::string;
using namespace boost::asio;
using namespace rosetta::common;


request_handler_ptr request_handler::create (class connection * connection, class request * request, int status_code)
{
  // Checking if we can accept User-Agent according whitelist and blacklist definitions.
  if (!in_whitelist (connection, request) || in_blacklist (connection, request)) {

    // User-Agent not accepted!
    return request_handler_ptr (new error_handler (connection, request, 403));
  }

  // Checking request type, and other parameters, deciding which type of request handler we should create.
  if (status_code >= 400) {

    // Some sort of error.
    return request_handler_ptr (new error_handler (connection, request, status_code));

  } else if (should_upgrade_insecure_requests (connection, request)) {

    // Both configuration, and client, prefers secure requests, and current connection is not secure, hence we upgrade.
    return upgrade_insecure_request (connection, request);

  } else if (request->envelope().type() == "TRACE") {

    // Returning a TRACE handler.
    return create_trace_handler (connection, request);

  } else if (request->envelope().type() == "HEAD") {

    // Returning a HEAD handler.
    return create_head_handler (connection, request);

  } else if (request->envelope().type() == "GET") {

    // Returning a GET handler.
    return create_get_handler (connection, request);

  } else {

    // Unsupported method.
    return request_handler_ptr (new error_handler (connection, request, 405));
  }
}


bool request_handler::should_upgrade_insecure_requests (const class connection * connection, const class request * request)
{
  // Checking if current request is secured already.
  if (!connection->is_secure()) {

    // Checking if server is configured to allow for automatic upgrading of insecure requests.
    if (connection->server()->configuration().get <bool> ("upgrade-insecure-requests", false)) {

      // Checking if server is configure with, and has a root certificate and a private key.
      const string & certificate = connection->server()->configuration().get<string> ("ssl-certificate", "");
      const string & key = connection->server()->configuration().get<string> ("ssl-private-key", "");

      // Checking if neither of the above values are empty.
      if (certificate.size() > 0 && key.size() > 0) {

        // Checking if certificate file and key file actually exists on disc.
        if (boost::filesystem::exists (certificate) && boost::filesystem::exists (key)) {

          // We can safely upgrade the current request!
          return true;
        }
      }
    }
  }

  // This request should not be upgraded for some reasons.
  return false;
}

{'fraction_non_alphanumeric': 0.10499359795134443, 'fraction_numerical': 0.0038412291933418692, 'mean_word_length': 4.277702702702703, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3948974', 'n_tokens_mistral': 2150, 'n_tokens_neox': 2055, 'n_words': 731}