<commit_before>#pragma once
/*
HTTPS Server class

Copyright (c) 2017 <NAME> <<EMAIL>>
License: MIT, see License.txt
*/
#ifdef HTTPS_ENABLED

#include "server.h"

// This is needed to link against pre-built OpenSSL from https://slproweb.com/products/Win32OpenSSL.html
#if _MSC_VER && _MSC_VER >= 1900
FILE _iob[] = { *stdin, *stdout, *stderr };
extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
#endif // end _MSC_VER

#include <boost/asio/ssl.hpp>

namespace wsgi_boost
{
	template<class socket_p>
	class HttpsServer : public BaseServer<socket_p> {};

	typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket_t;
	typedef std::shared_ptr<ssl_socket_t> ssl_socket_ptr;


	// HTTPS server class
	template<>
	class HttpsServer<ssl_socket_ptr> : public BaseServer<ssl_socket_ptr>
	{
	protected:
		boost::asio::ssl::context m_context;
		boost::asio::ip::tcp::acceptor m_redirector;

		void accept()
		{
			io_service_ptr io_service = m_io_service_pool.get_io_service();
			ssl_socket_ptr socket = std::make_shared<ssl_socket_t>(*io_service, m_context);
			m_acceptor.async_accept(socket->lowest_layer(),
				[this, io_service, socket](const boost::system::error_code& ec)
			{
				if (ec != boost::asio::error::operation_aborted)
					accept();
				if (!ec)
				{
					socket->lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true));
					auto timer = std::make_shared<boost::asio::deadline_timer>(*io_service);
					timer->expires_from_now(boost::posix_time::seconds(header_timeout));
					timer->async_wait([socket](const boost::system::error_code& ec)
					{
						if (ec != boost::asio::error::operation_aborted)
						{
							socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
							socket->lowest_layer().close();
						}
					});
					socket->async_handshake(boost::asio::ssl::stream_base::server,
						[this, socket, timer](boost::system::error_code ec)
					{
						timer->cancel();
						if (!ec)
							process_request(socket);
					});

				}
			});
		}

		void accept_redirect()
		{
			socket_ptr socket = std::make_shared<socket_t>(*m_io_service_pool.get_io_service());
			m_redirector.async_accept(*socket, [this, socket](const boost::system::error_code& ec)
			{
				if (ec != boost::asio::error::operation_aborted)
					accept_redirect();
				if (!ec)
				{
					socket->set_option(boost::asio::ip::tcp::no_delay(true));
					boost::asio::spawn(socket->get_io_service(), [this, socket](boost::asio::yield_context yc)
					{
						Connection<socket_ptr> connection{ socket, yc, header_timeout, content_timeout };
						Request<Connection<socket_ptr>> request{ connection };
						Response<Connection<socket_ptr>> response{ connection };
						parse_result res = request.parse_header();
						if (!res)
						{
							std::string host = request.get_header("Host");
							if (host.empty())
							{
								response.send_mesage("400 Bad Request", "'Host' header is required!");
								return;
							}
							size_t pos = host.find(":");
							if (pos != std::string::npos)
								host = host.substr(0, pos);
							std::string https_port;
							if (m_port != 443)
								https_port = ':' + std::to_string(m_port);
							std::string location{ "https://" + host + https_port + request.path };
							std::string message{ "Redirected to " + location };
							response.http_version = request.http_version;
							response.keep_alive = false;
							out_headers_t out_headers;
							out_headers.emplace_back("Location", location);
							out_headers.emplace_back("Content-Length", std::to_string(message.length()));
							out_headers.emplace_back("Content-Type", "text/plain");
							response.send_header("301 Moved Permanently", out_headers);
							response.send_data(message);
						}
					});
				}
			});
		}

	public:
		bool redirect_http = false;
		unsigned short redirect_http_port = 80;

		HttpsServer(std::string cert_chain, const std::string private_key, std::string dh = std::string(),
			std::string address = std::string(), unsigned short port = 4443, unsigned int threads = 0) :
			// sslv23 is an universal option. Deprecated protocols need to be disabled by set_options()
			// More info: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_new.html
			m_context{ boost::asio::ssl::context::sslv23_server }, m_redirector{ *m_io_service_pool.get_io_service() },
			BaseServer<ssl_socket_ptr>{ address, port, threads }
		{
			url_scheme = "https";
			m_context.set_options(boost::asio::ssl::context::default_workarounds
				| boost::asio::ssl::context::no_sslv2
				| boost::asio::ssl::context::no_sslv3
				| boost::asio::ssl::context::single_dh_use);
			m_context.set_password_callback([](size_t, boost::asio::ssl::context::password_purpose)
			{<commit_msg>Minor method change<commit_after>#pragma once
/*
HTTPS Server class

Copyright (c) 2017 <NAME> <<EMAIL>>
License: MIT, see License.txt
*/
#ifdef HTTPS_ENABLED

#include "server.h"

// This is needed to link against pre-built OpenSSL from https://slproweb.com/products/Win32OpenSSL.html
#if _MSC_VER && _MSC_VER >= 1900
FILE _iob[] = { *stdin, *stdout, *stderr };
extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
#endif // end _MSC_VER

#include <boost/asio/ssl.hpp>

namespace wsgi_boost
{
	template<class socket_p>
	class HttpsServer : public BaseServer<socket_p> {};

	typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket_t;
	typedef std::shared_ptr<ssl_socket_t> ssl_socket_ptr;


	// HTTPS server class
	template<>
	class HttpsServer<ssl_socket_ptr> : public BaseServer<ssl_socket_ptr>
	{
	protected:
		boost::asio::ssl::context m_context;
		boost::asio::ip::tcp::acceptor m_redirector;

		void accept()
		{
			io_service_ptr io_service = m_io_service_pool.get_io_service();
			ssl_socket_ptr socket = std::make_shared<ssl_socket_t>(*io_service, m_context);
			m_acceptor.async_accept(socket->lowest_layer(),
				[this, io_service, socket](const boost::system::error_code& ec)
			{
				if (ec != boost::asio::error::operation_aborted)
					accept();
				if (!ec)
				{
					socket->lowest_layer().set_option(boost::asio::ip::tcp::no_delay(true));
					auto timer = std::make_shared<boost::asio::deadline_timer>(*io_service);
					timer->expires_from_now(boost::posix_time::seconds(header_timeout));
					timer->async_wait([socket](const boost::system::error_code& ec)
					{
						if (ec != boost::asio::error::operation_aborted)
						{
							socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
							socket->lowest_layer().close();
						}
					});
					socket->async_handshake(boost::asio::ssl::stream_base::server,
						[this, socket, timer](boost::system::error_code ec)
					{
						timer->cancel();
						if (!ec)
							process_request(socket);
					});

				}
			});
		}

		void accept_redirect()
		{
			socket_ptr socket = std::make_shared<socket_t>(*m_io_service_pool.get_io_service());
			m_redirector.async_accept(*socket, [this, socket](const boost::system::error_code& ec)
			{
				if (ec != boost::asio::error::operation_aborted)
					accept_redirect();
				if (!ec)
				{
					socket->set_option(boost::asio::ip::tcp::no_delay(true));
					boost::asio::spawn(socket->get_io_service(), [this, socket](boost::asio::yield_context yc)
					{
						Connection<socket_ptr> connection{ socket, yc, header_timeout, content_timeout };
						Request<Connection<socket_ptr>> request{ connection };
						Response<Connection<socket_ptr>> response{ connection };
						parse_result res = request.parse_header();
						if (!res)
						{
							std::string host = request.get_header("Host");
							if (host.empty())
							{
								response.send_mesage("400 Bad Request", "'Host' header is required!");
								return;
							}
							size_t pos = host.find(":");
							if (pos != std::string::npos)
								host = host.substr(0, pos);
							std::string https_port;
							if (m_port != 443)
								https_port = ':' + std::to_string(m_port);
							std::string location{ "https://" + host + https_port + request.path };
							std::string message{ "Redirected to " + location };
							response.http_version = request.http_version;
							response.keep_alive = false;
							out_headers_t out_headers;
							out_headers.emplace_back("Location", location);
							out_headers.emplace_back("Content-Length", std::to_string(message.length()));
							out_headers.emplace_back("Content-Type", "text/plain");
							response.send_header("301 Moved Permanently", out_headers);
							response.send_data(message);
						}
					});
				}
			});
		}

	public:
		bool redirect_http = false;
		unsigned short redirect_http_port = 80;

		HttpsServer(std::string cert_chain, const std::string private_key, std::string dh = std::string(),
			std::string address = std::string(), unsigned short port = 4443, unsigned int threads = 0) :
			// sslv23 is an universal option. Deprecated protocols need to be disabled by set_options()
			// More info: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_new.html
			m_context{ boost::asio::ssl::context::sslv23_server }, m_redirector{ *m_io_service_pool.get_io_service() },
			BaseServer<ssl_socket_ptr>{ address, port, threads }
		{
			url_scheme.assign("https");
			m_context.set_options(boost::asio::ssl::context::default_workarounds
				| boost::asio::ssl::context::no_sslv2
				| boost::asio::ssl::context::no_sslv3
				| boost::asio::ssl::context::single_dh_use);
			m_context.set_password_callback([](size_t, boost::asio::ssl::context::password_purpose)
			{
{'fraction_non_alphanumeric': 0.15101869355177483, 'fraction_numerical': 0.007561436672967864, 'mean_word_length': 4.181175190424375, 'pattern_counts': {'":': 2, '<': 43, '<?xml version=': 0, '>': 65, 'https://': 6, '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': '88895', 'n_tokens_mistral': 3975, 'n_tokens_neox': 3116, 'n_words': 547}